Skip to content

Commit

Permalink
Merge pull request #554 from dsnet/master
Browse files Browse the repository at this point in the history
Properly handle io.EOF error conditions when reading
  • Loading branch information
puellanivis authored Aug 12, 2023
2 parents ec1c8ca + e9377c8 commit 669003c
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 2 deletions.
4 changes: 3 additions & 1 deletion conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ type conn struct {
}

// the orderID is used in server mode if the allocator is enabled.
// For the client mode just pass 0
// For the client mode just pass 0.
// It returns io.EOF if the connection is closed and
// there are no more packets to read.
func (c *conn) recvPacket(orderID uint32) (uint8, []byte, error) {
return recvPacket(c, c.alloc, orderID)
}
Expand Down
5 changes: 5 additions & 0 deletions packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,11 @@ func recvPacket(r io.Reader, alloc *allocator, orderID uint32) (uint8, []byte, e
b = make([]byte, length)
}
if _, err := io.ReadFull(r, b[:length]); err != nil {
// ReadFull only returns EOF if it has read no bytes.
// In this case, that means a partial packet, and thus unexpected.
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
debug("recv packet %d bytes: err %v", length, err)
return 0, nil, err
}
Expand Down
6 changes: 5 additions & 1 deletion server.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ func handlePacket(s *Server, p orderedRequest) error {
}

// Serve serves SFTP connections until the streams stop or the SFTP subsystem
// is stopped.
// is stopped. It returns nil if the server exits cleanly.
func (svr *Server) Serve() error {
defer func() {
if svr.pktMgr.alloc != nil {
Expand All @@ -353,6 +353,10 @@ func (svr *Server) Serve() error {
for {
pktType, pktBytes, err = svr.serverConn.recvPacket(svr.pktMgr.getNextOrderID())
if err != nil {
// Check whether the connection terminated cleanly in-between packets.
if err == io.EOF {
err = nil
}
// we don't care about releasing allocated pages here, the server will quit and the allocator freed
break
}
Expand Down

0 comments on commit 669003c

Please sign in to comment.