Commit 4cc64bd5 authored by Dave Cheney's avatar Dave Cheney Committed by Adam Langley

exp/ssh: move openChan to NewSession

openChan was only being called by NewSession, Dial has
its own version.

R=gustav.paul, agl, rsc
CC=golang-dev
https://golang.org/cl/5435071
parent 1eb7ca92
...@@ -177,35 +177,7 @@ func (c *ClientConn) kexDH(group *dhGroup, hashFunc crypto.Hash, magics *handsha ...@@ -177,35 +177,7 @@ func (c *ClientConn) kexDH(group *dhGroup, hashFunc crypto.Hash, magics *handsha
return H, K, nil return H, K, nil
} }
// openChan opens a new client channel. The most common session type is "session". // mainLoop reads incoming messages and routes channel messages
// The full set of valid session types are listed in RFC 4250 4.9.1.
func (c *ClientConn) openChan(typ string) (*clientChan, error) {
ch := c.newChan(c.transport)
if err := c.writePacket(marshal(msgChannelOpen, channelOpenMsg{
ChanType: typ,
PeersId: ch.id,
PeersWindow: 1 << 14,
MaxPacketSize: 1 << 15, // RFC 4253 6.1
})); err != nil {
c.chanlist.remove(ch.id)
return nil, err
}
// wait for response
switch msg := (<-ch.msg).(type) {
case *channelOpenConfirmMsg:
ch.peersId = msg.MyId
ch.win <- int(msg.MyWindow)
case *channelOpenFailureMsg:
c.chanlist.remove(ch.id)
return nil, errors.New(msg.Message)
default:
c.chanlist.remove(ch.id)
return nil, errors.New("Unexpected packet")
}
return ch, nil
}
// mainloop reads incoming messages and routes channel messages
// to their respective ClientChans. // to their respective ClientChans.
func (c *ClientConn) mainLoop() { func (c *ClientConn) mainLoop() {
// TODO(dfc) signal the underlying close to all channels // TODO(dfc) signal the underlying close to all channels
...@@ -271,7 +243,7 @@ func (c *ClientConn) mainLoop() { ...@@ -271,7 +243,7 @@ func (c *ClientConn) mainLoop() {
case *windowAdjustMsg: case *windowAdjustMsg:
c.getChan(msg.PeersId).win <- int(msg.AdditionalBytes) c.getChan(msg.PeersId).win <- int(msg.AdditionalBytes)
default: default:
fmt.Printf("mainLoop: unhandled %#v\n", msg) fmt.Printf("mainLoop: unhandled message %T: %v\n", msg, msg)
} }
} }
} }
...@@ -347,7 +319,7 @@ type chanlist struct { ...@@ -347,7 +319,7 @@ type chanlist struct {
// protects concurrent access to chans // protects concurrent access to chans
sync.Mutex sync.Mutex
// chans are indexed by the local id of the channel, clientChan.id. // chans are indexed by the local id of the channel, clientChan.id.
// The PeersId value of messages received by ClientConn.mainloop is // The PeersId value of messages received by ClientConn.mainLoop is
// used to locate the right local clientChan in this slice. // used to locate the right local clientChan in this slice.
chans []*clientChan chans []*clientChan
} }
......
...@@ -277,11 +277,29 @@ func (s *Session) stderr() error { ...@@ -277,11 +277,29 @@ func (s *Session) stderr() error {
// NewSession returns a new interactive session on the remote host. // NewSession returns a new interactive session on the remote host.
func (c *ClientConn) NewSession() (*Session, error) { func (c *ClientConn) NewSession() (*Session, error) {
ch, err := c.openChan("session") ch := c.newChan(c.transport)
if err != nil { if err := c.writePacket(marshal(msgChannelOpen, channelOpenMsg{
ChanType: "session",
PeersId: ch.id,
PeersWindow: 1 << 14,
MaxPacketSize: 1 << 15, // RFC 4253 6.1
})); err != nil {
c.chanlist.remove(ch.id)
return nil, err return nil, err
} }
return &Session{ // wait for response
clientChan: ch, msg := <-ch.msg
}, nil switch msg := msg.(type) {
case *channelOpenConfirmMsg:
ch.peersId = msg.MyId
ch.win <- int(msg.MyWindow)
return &Session{
clientChan: ch,
}, nil
case *channelOpenFailureMsg:
c.chanlist.remove(ch.id)
return nil, fmt.Errorf("ssh: channel open failed: %s", msg.Message)
}
c.chanlist.remove(ch.id)
return nil, fmt.Errorf("ssh: unexpected message %T: %v", msg, msg)
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment