go.crypto/ssh: cosmetic: move remaining channel code into channel.go

This CL scratches an itch by moving the remaining channel related code
into channel.go.

R=agl
CC=golang-dev
https://golang.org/cl/6454126
This commit is contained in:
Dave Cheney
2012-08-11 12:18:54 +10:00
parent f0da345629
commit 00f60517a3
2 changed files with 118 additions and 118 deletions
+118
View File
@@ -408,3 +408,121 @@ func (c *serverChan) ChannelType() string {
func (c *serverChan) ExtraData() []byte {
return c.extraData
}
// A clientChan represents a single RFC 4254 channel multiplexed
// over a SSH connection.
type clientChan struct {
channel
stdin *chanWriter
stdout *chanReader
stderr *chanReader
msg chan interface{}
}
// newClientChan returns a partially constructed *clientChan
// using the local id provided. To be usable clientChan.remoteId
// needs to be assigned once known.
func newClientChan(cc conn, id uint32) *clientChan {
c := &clientChan{
channel: channel{
conn: cc,
localId: id,
remoteWin: window{Cond: newCond()},
},
msg: make(chan interface{}, 16),
}
c.stdin = &chanWriter{
channel: &c.channel,
}
c.stdout = &chanReader{
channel: &c.channel,
buffer: newBuffer(),
}
c.stderr = &chanReader{
channel: &c.channel,
buffer: newBuffer(),
}
return c
}
// waitForChannelOpenResponse, if successful, fills out
// the remoteId and records any initial window advertisement.
func (c *clientChan) waitForChannelOpenResponse() error {
switch msg := (<-c.msg).(type) {
case *channelOpenConfirmMsg:
// fixup remoteId field
c.remoteId = msg.MyId
// TODO(dfc) asset this is < 2^31.
c.maxPacketSize = msg.MaxPacketSize
c.remoteWin.add(msg.MyWindow)
return nil
case *channelOpenFailureMsg:
return errors.New(safeString(msg.Message))
}
return errors.New("ssh: unexpected packet")
}
// Close closes the channel. This does not close the underlying connection.
func (c *clientChan) Close() error {
if !c.weClosed {
c.weClosed = true
return c.sendClose()
}
return nil
}
// A chanWriter represents the stdin of a remote process.
type chanWriter struct {
*channel
}
// Write writes data to the remote process's standard input.
func (w *chanWriter) Write(data []byte) (written int, err error) {
for len(data) > 0 {
// never send more data than maxPacketSize even if
// there is sufficent window.
n := min(int(w.maxPacketSize), len(data))
n = int(w.remoteWin.reserve(uint32(n)))
remoteId := w.remoteId
packet := []byte{
msgChannelData,
byte(remoteId >> 24), byte(remoteId >> 16), byte(remoteId >> 8), byte(remoteId),
byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n),
}
if err = w.writePacket(append(packet, data[:n]...)); err != nil {
break
}
data = data[n:]
written += n
}
return
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func (w *chanWriter) Close() error {
return w.sendEOF()
}
// A chanReader represents stdout or stderr of a remote process.
type chanReader struct {
*channel // the channel backing this reader
*buffer
}
// Read reads data from the remote process's stdout or stderr.
func (r *chanReader) Read(buf []byte) (int, error) {
n, err := r.buffer.Read(buf)
if err != nil {
if err == io.EOF {
return n, err
}
return 0, err
}
return n, r.sendWindowAdj(n)
}
-118
View File
@@ -456,68 +456,6 @@ func (c *ClientConfig) rand() io.Reader {
return c.Rand
}
// A clientChan represents a single RFC 4254 channel that is multiplexed
// over a single SSH connection.
type clientChan struct {
channel
stdin *chanWriter
stdout *chanReader
stderr *chanReader
msg chan interface{}
}
// newClientChan returns a partially constructed *clientChan
// using the local id provided. To be usable clientChan.remoteId
// needs to be assigned once known.
func newClientChan(cc conn, id uint32) *clientChan {
c := &clientChan{
channel: channel{
conn: cc,
localId: id,
remoteWin: window{Cond: newCond()},
},
msg: make(chan interface{}, 16),
}
c.stdin = &chanWriter{
channel: &c.channel,
}
c.stdout = &chanReader{
channel: &c.channel,
buffer: newBuffer(),
}
c.stderr = &chanReader{
channel: &c.channel,
buffer: newBuffer(),
}
return c
}
// waitForChannelOpenResponse, if successful, fills out
// the remoteId and records any initial window advertisement.
func (c *clientChan) waitForChannelOpenResponse() error {
switch msg := (<-c.msg).(type) {
case *channelOpenConfirmMsg:
// fixup remoteId field
c.remoteId = msg.MyId
// TODO(dfc) asset this is < 2^31.
c.maxPacketSize = msg.MaxPacketSize
c.remoteWin.add(msg.MyWindow)
return nil
case *channelOpenFailureMsg:
return errors.New(safeString(msg.Message))
}
return errors.New("ssh: unexpected packet")
}
// Close closes the channel. This does not close the underlying connection.
func (c *clientChan) Close() error {
if !c.weClosed {
c.weClosed = true
return c.sendClose()
}
return nil
}
// Thread safe channel list.
type chanList struct {
// protects concurrent access to chans
@@ -575,59 +513,3 @@ func (c *chanList) closeAll() {
close(ch.msg)
}
}
// A chanWriter represents the stdin of a remote process.
type chanWriter struct {
*channel
}
// Write writes data to the remote process's standard input.
func (w *chanWriter) Write(data []byte) (written int, err error) {
for len(data) > 0 {
// never send more data than maxPacketSize even if
// there is sufficent window.
n := min(int(w.maxPacketSize), len(data))
n = int(w.remoteWin.reserve(uint32(n)))
remoteId := w.remoteId
packet := []byte{
msgChannelData,
byte(remoteId >> 24), byte(remoteId >> 16), byte(remoteId >> 8), byte(remoteId),
byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n),
}
if err = w.writePacket(append(packet, data[:n]...)); err != nil {
break
}
data = data[n:]
written += n
}
return
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func (w *chanWriter) Close() error {
return w.sendEOF()
}
// A chanReader represents stdout or stderr of a remote process.
type chanReader struct {
*channel // the channel backing this reader
*buffer
}
// Read reads data from the remote process's stdout or stderr.
func (r *chanReader) Read(buf []byte) (int, error) {
n, err := r.buffer.Read(buf)
if err != nil {
if err == io.EOF {
return n, err
}
return 0, err
}
return n, r.sendWindowAdj(n)
}