mirror of
https://github.com/golang/go
synced 2024-11-25 12:37:56 -07:00
exp/ssh: messages now contain remote channel's id instead of local id
According to http://www.ietf.org/rfc/rfc4254.txt most channel messages contain the channel id of the recipient channel, not the sender id. This allows the recipient connection multiplexer to route the message to the correct channel. This changeset fixes several messages that incorrectly send the local channel id instead of the remote channel's id. While sessions were being created and closed in sequence channels in the channel pool were freed and reused on the server side of the connection at the same rate as was done on the client, so the channel local and remote channel ids always corresponded. As soon as I had concurrent sessions on the same clientConn the server started to complain of 'uknown channel id N' where N is the local channel id, which is actually paired with server channel id K. R=golang-dev, dave, rsc, agl CC=golang-dev https://golang.org/cl/5433063
This commit is contained in:
parent
557ba72e69
commit
d859d7deee
@ -338,7 +338,7 @@ func newClientChan(t *transport, id uint32) *clientChan {
|
|||||||
// Close closes the channel. This does not close the underlying connection.
|
// Close closes the channel. This does not close the underlying connection.
|
||||||
func (c *clientChan) Close() error {
|
func (c *clientChan) Close() error {
|
||||||
return c.writePacket(marshal(msgChannelClose, channelCloseMsg{
|
return c.writePacket(marshal(msgChannelClose, channelCloseMsg{
|
||||||
PeersId: c.id,
|
PeersId: c.peersId,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +384,7 @@ func (c *chanlist) remove(id uint32) {
|
|||||||
// A chanWriter represents the stdin of a remote process.
|
// A chanWriter represents the stdin of a remote process.
|
||||||
type chanWriter struct {
|
type chanWriter struct {
|
||||||
win chan int // receives window adjustments
|
win chan int // receives window adjustments
|
||||||
id uint32 // this channel's id
|
peersId uint32 // the peers id
|
||||||
rwin int // current rwin size
|
rwin int // current rwin size
|
||||||
packetWriter // for sending channelDataMsg
|
packetWriter // for sending channelDataMsg
|
||||||
}
|
}
|
||||||
@ -403,7 +403,7 @@ func (w *chanWriter) Write(data []byte) (n int, err error) {
|
|||||||
n = len(data)
|
n = len(data)
|
||||||
packet := make([]byte, 0, 9+n)
|
packet := make([]byte, 0, 9+n)
|
||||||
packet = append(packet, msgChannelData,
|
packet = append(packet, msgChannelData,
|
||||||
byte(w.id)>>24, byte(w.id)>>16, byte(w.id)>>8, byte(w.id),
|
byte(w.peersId)>>24, byte(w.peersId)>>16, byte(w.peersId)>>8, byte(w.peersId),
|
||||||
byte(n)>>24, byte(n)>>16, byte(n)>>8, byte(n))
|
byte(n)>>24, byte(n)>>16, byte(n)>>8, byte(n))
|
||||||
err = w.writePacket(append(packet, data...))
|
err = w.writePacket(append(packet, data...))
|
||||||
w.rwin -= n
|
w.rwin -= n
|
||||||
@ -413,7 +413,7 @@ func (w *chanWriter) Write(data []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *chanWriter) Close() error {
|
func (w *chanWriter) Close() error {
|
||||||
return w.writePacket(marshal(msgChannelEOF, channelEOFMsg{w.id}))
|
return w.writePacket(marshal(msgChannelEOF, channelEOFMsg{w.peersId}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// A chanReader represents stdout or stderr of a remote process.
|
// A chanReader represents stdout or stderr of a remote process.
|
||||||
@ -422,7 +422,7 @@ type chanReader struct {
|
|||||||
// If writes to this channel block, they will block mainLoop, making
|
// If writes to this channel block, they will block mainLoop, making
|
||||||
// it unable to receive new messages from the remote side.
|
// it unable to receive new messages from the remote side.
|
||||||
data chan []byte // receives data from remote
|
data chan []byte // receives data from remote
|
||||||
id uint32
|
peersId uint32 // the peers id
|
||||||
packetWriter // for sending windowAdjustMsg
|
packetWriter // for sending windowAdjustMsg
|
||||||
buf []byte
|
buf []byte
|
||||||
}
|
}
|
||||||
@ -435,7 +435,7 @@ func (r *chanReader) Read(data []byte) (int, error) {
|
|||||||
n := copy(data, r.buf)
|
n := copy(data, r.buf)
|
||||||
r.buf = r.buf[n:]
|
r.buf = r.buf[n:]
|
||||||
msg := windowAdjustMsg{
|
msg := windowAdjustMsg{
|
||||||
PeersId: r.id,
|
PeersId: r.peersId,
|
||||||
AdditionalBytes: uint32(n),
|
AdditionalBytes: uint32(n),
|
||||||
}
|
}
|
||||||
return n, r.writePacket(marshal(msgChannelWindowAdjust, msg))
|
return n, r.writePacket(marshal(msgChannelWindowAdjust, msg))
|
||||||
@ -447,7 +447,3 @@ func (r *chanReader) Read(data []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *chanReader) Close() error {
|
|
||||||
return r.writePacket(marshal(msgChannelEOF, channelEOFMsg{r.id}))
|
|
||||||
}
|
|
||||||
|
@ -53,7 +53,7 @@ type setenvRequest struct {
|
|||||||
// command executed by Shell or Exec.
|
// command executed by Shell or Exec.
|
||||||
func (s *Session) Setenv(name, value string) error {
|
func (s *Session) Setenv(name, value string) error {
|
||||||
req := setenvRequest{
|
req := setenvRequest{
|
||||||
PeersId: s.id,
|
PeersId: s.peersId,
|
||||||
Request: "env",
|
Request: "env",
|
||||||
WantReply: true,
|
WantReply: true,
|
||||||
Name: name,
|
Name: name,
|
||||||
@ -84,7 +84,7 @@ type ptyRequestMsg struct {
|
|||||||
// RequestPty requests the association of a pty with the session on the remote host.
|
// RequestPty requests the association of a pty with the session on the remote host.
|
||||||
func (s *Session) RequestPty(term string, h, w int) error {
|
func (s *Session) RequestPty(term string, h, w int) error {
|
||||||
req := ptyRequestMsg{
|
req := ptyRequestMsg{
|
||||||
PeersId: s.id,
|
PeersId: s.peersId,
|
||||||
Request: "pty-req",
|
Request: "pty-req",
|
||||||
WantReply: true,
|
WantReply: true,
|
||||||
Term: term,
|
Term: term,
|
||||||
@ -116,7 +116,7 @@ func (s *Session) Exec(cmd string) error {
|
|||||||
return errors.New("ssh: session already started")
|
return errors.New("ssh: session already started")
|
||||||
}
|
}
|
||||||
req := execMsg{
|
req := execMsg{
|
||||||
PeersId: s.id,
|
PeersId: s.peersId,
|
||||||
Request: "exec",
|
Request: "exec",
|
||||||
WantReply: true,
|
WantReply: true,
|
||||||
Command: cmd,
|
Command: cmd,
|
||||||
@ -140,7 +140,7 @@ func (s *Session) Shell() error {
|
|||||||
return errors.New("ssh: session already started")
|
return errors.New("ssh: session already started")
|
||||||
}
|
}
|
||||||
req := channelRequestMsg{
|
req := channelRequestMsg{
|
||||||
PeersId: s.id,
|
PeersId: s.peersId,
|
||||||
Request: "shell",
|
Request: "shell",
|
||||||
WantReply: true,
|
WantReply: true,
|
||||||
}
|
}
|
||||||
@ -237,7 +237,7 @@ func (s *Session) stdin() error {
|
|||||||
s.copyFuncs = append(s.copyFuncs, func() error {
|
s.copyFuncs = append(s.copyFuncs, func() error {
|
||||||
_, err := io.Copy(&chanWriter{
|
_, err := io.Copy(&chanWriter{
|
||||||
packetWriter: s,
|
packetWriter: s,
|
||||||
id: s.id,
|
peersId: s.peersId,
|
||||||
win: s.win,
|
win: s.win,
|
||||||
}, s.Stdin)
|
}, s.Stdin)
|
||||||
return err
|
return err
|
||||||
@ -252,7 +252,7 @@ func (s *Session) stdout() error {
|
|||||||
s.copyFuncs = append(s.copyFuncs, func() error {
|
s.copyFuncs = append(s.copyFuncs, func() error {
|
||||||
_, err := io.Copy(s.Stdout, &chanReader{
|
_, err := io.Copy(s.Stdout, &chanReader{
|
||||||
packetWriter: s,
|
packetWriter: s,
|
||||||
id: s.id,
|
peersId: s.peersId,
|
||||||
data: s.data,
|
data: s.data,
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
@ -267,7 +267,7 @@ func (s *Session) stderr() error {
|
|||||||
s.copyFuncs = append(s.copyFuncs, func() error {
|
s.copyFuncs = append(s.copyFuncs, func() error {
|
||||||
_, err := io.Copy(s.Stderr, &chanReader{
|
_, err := io.Copy(s.Stderr, &chanReader{
|
||||||
packetWriter: s,
|
packetWriter: s,
|
||||||
id: s.id,
|
peersId: s.peersId,
|
||||||
data: s.dataExt,
|
data: s.dataExt,
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
|
@ -86,12 +86,12 @@ func (c *ClientConn) dial(laddr string, lport int, raddr string, rport int) (*tc
|
|||||||
clientChan: ch,
|
clientChan: ch,
|
||||||
Reader: &chanReader{
|
Reader: &chanReader{
|
||||||
packetWriter: ch,
|
packetWriter: ch,
|
||||||
id: ch.id,
|
peersId: ch.peersId,
|
||||||
data: ch.data,
|
data: ch.data,
|
||||||
},
|
},
|
||||||
Writer: &chanWriter{
|
Writer: &chanWriter{
|
||||||
packetWriter: ch,
|
packetWriter: ch,
|
||||||
id: ch.id,
|
peersId: ch.peersId,
|
||||||
win: ch.win,
|
win: ch.win,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
|
Loading…
Reference in New Issue
Block a user