summaryrefslogtreecommitdiff
path: root/libgo/go/exp/ssh/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/exp/ssh/server.go')
-rw-r--r--libgo/go/exp/ssh/server.go130
1 files changed, 72 insertions, 58 deletions
diff --git a/libgo/go/exp/ssh/server.go b/libgo/go/exp/ssh/server.go
index 3a640fc081e..0dd24ecd6ee 100644
--- a/libgo/go/exp/ssh/server.go
+++ b/libgo/go/exp/ssh/server.go
@@ -581,75 +581,89 @@ func (s *ServerConn) Accept() (Channel, os.Error) {
return nil, err
}
- switch msg := decode(packet).(type) {
- case *channelOpenMsg:
- c := new(channel)
- c.chanType = msg.ChanType
- c.theirId = msg.PeersId
- c.theirWindow = msg.PeersWindow
- c.maxPacketSize = msg.MaxPacketSize
- c.extraData = msg.TypeSpecificData
- c.myWindow = defaultWindowSize
- c.serverConn = s
- c.cond = sync.NewCond(&c.lock)
- c.pendingData = make([]byte, c.myWindow)
-
- s.lock.Lock()
- c.myId = s.nextChanId
- s.nextChanId++
- s.channels[c.myId] = c
- s.lock.Unlock()
- return c, nil
-
- case *channelRequestMsg:
- s.lock.Lock()
- c, ok := s.channels[msg.PeersId]
- if !ok {
- continue
+ switch packet[0] {
+ case msgChannelData:
+ if len(packet) < 9 {
+ // malformed data packet
+ return nil, ParseError{msgChannelData}
}
- c.handlePacket(msg)
- s.lock.Unlock()
-
- case *channelData:
+ peersId := uint32(packet[1])<<24 | uint32(packet[2])<<16 | uint32(packet[3])<<8 | uint32(packet[4])
s.lock.Lock()
- c, ok := s.channels[msg.PeersId]
+ c, ok := s.channels[peersId]
if !ok {
+ s.lock.Unlock()
continue
}
- c.handleData(msg.Payload)
- s.lock.Unlock()
-
- case *channelEOFMsg:
- s.lock.Lock()
- c, ok := s.channels[msg.PeersId]
- if !ok {
- continue
+ if length := int(packet[5])<<24 | int(packet[6])<<16 | int(packet[7])<<8 | int(packet[8]); length > 0 {
+ packet = packet[9:]
+ c.handleData(packet[:length])
}
- c.handlePacket(msg)
s.lock.Unlock()
+ default:
+ switch msg := decode(packet).(type) {
+ case *channelOpenMsg:
+ c := new(channel)
+ c.chanType = msg.ChanType
+ c.theirId = msg.PeersId
+ c.theirWindow = msg.PeersWindow
+ c.maxPacketSize = msg.MaxPacketSize
+ c.extraData = msg.TypeSpecificData
+ c.myWindow = defaultWindowSize
+ c.serverConn = s
+ c.cond = sync.NewCond(&c.lock)
+ c.pendingData = make([]byte, c.myWindow)
+
+ s.lock.Lock()
+ c.myId = s.nextChanId
+ s.nextChanId++
+ s.channels[c.myId] = c
+ s.lock.Unlock()
+ return c, nil
+
+ case *channelRequestMsg:
+ s.lock.Lock()
+ c, ok := s.channels[msg.PeersId]
+ if !ok {
+ s.lock.Unlock()
+ continue
+ }
+ c.handlePacket(msg)
+ s.lock.Unlock()
- case *channelCloseMsg:
- s.lock.Lock()
- c, ok := s.channels[msg.PeersId]
- if !ok {
- continue
- }
- c.handlePacket(msg)
- s.lock.Unlock()
+ case *channelEOFMsg:
+ s.lock.Lock()
+ c, ok := s.channels[msg.PeersId]
+ if !ok {
+ s.lock.Unlock()
+ continue
+ }
+ c.handlePacket(msg)
+ s.lock.Unlock()
- case *globalRequestMsg:
- if msg.WantReply {
- if err := s.writePacket([]byte{msgRequestFailure}); err != nil {
- return nil, err
+ case *channelCloseMsg:
+ s.lock.Lock()
+ c, ok := s.channels[msg.PeersId]
+ if !ok {
+ s.lock.Unlock()
+ continue
}
- }
+ c.handlePacket(msg)
+ s.lock.Unlock()
- case UnexpectedMessageError:
- return nil, msg
- case *disconnectMsg:
- return nil, os.EOF
- default:
- // Unknown message. Ignore.
+ case *globalRequestMsg:
+ if msg.WantReply {
+ if err := s.writePacket([]byte{msgRequestFailure}); err != nil {
+ return nil, err
+ }
+ }
+
+ case UnexpectedMessageError:
+ return nil, msg
+ case *disconnectMsg:
+ return nil, os.EOF
+ default:
+ // Unknown message. Ignore.
+ }
}
}