Skip to content

Commit 669003c

Browse files
authored
Merge pull request #554 from dsnet/master
Properly handle io.EOF error conditions when reading
2 parents ec1c8ca + e9377c8 commit 669003c

File tree

3 files changed

+13
-2
lines changed

3 files changed

+13
-2
lines changed

conn.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ type conn struct {
1818
}
1919

2020
// the orderID is used in server mode if the allocator is enabled.
21-
// For the client mode just pass 0
21+
// For the client mode just pass 0.
22+
// It returns io.EOF if the connection is closed and
23+
// there are no more packets to read.
2224
func (c *conn) recvPacket(orderID uint32) (uint8, []byte, error) {
2325
return recvPacket(c, c.alloc, orderID)
2426
}

packet.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ func recvPacket(r io.Reader, alloc *allocator, orderID uint32) (uint8, []byte, e
290290
b = make([]byte, length)
291291
}
292292
if _, err := io.ReadFull(r, b[:length]); err != nil {
293+
// ReadFull only returns EOF if it has read no bytes.
294+
// In this case, that means a partial packet, and thus unexpected.
295+
if err == io.EOF {
296+
err = io.ErrUnexpectedEOF
297+
}
293298
debug("recv packet %d bytes: err %v", length, err)
294299
return 0, nil, err
295300
}

server.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ func handlePacket(s *Server, p orderedRequest) error {
327327
}
328328

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

0 commit comments

Comments
 (0)