Skip to content

Commit eb9e2c9

Browse files
committed
sshforward: skip conn close on stream CloseSend.
The GRPC docs on RecvMsg say: > RecvMsg blocks until it receives a message into m or the stream is > done. It returns io.EOF when the client has performed a CloseSend. > On any non-EOF error, the stream is aborted and the error contains > the RPC status. So if EOF is received that just means the client won't be sending anymore data. But it may still be expecting to read data, so we shouldn't close the conn yet. This was encountered in real life when forwarding a docker socket to a container, where it appears that the docker CLI closes its write side of the connection when requesting the stdout/stderr but then expects to read data after that. Signed-off-by: Erik Sipsma <[email protected]>
1 parent c0e38e1 commit eb9e2c9

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

session/sshforward/copy.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,19 @@ type Stream interface {
1414
}
1515

1616
func Copy(ctx context.Context, conn io.ReadWriteCloser, stream Stream, closeStream func() error) error {
17+
defer conn.Close()
1718
g, ctx := errgroup.WithContext(ctx)
1819

1920
g.Go(func() (retErr error) {
2021
p := &BytesMessage{}
2122
for {
2223
if err := stream.RecvMsg(p); err != nil {
23-
conn.Close()
2424
if err == io.EOF {
25+
// indicates client performed CloseSend, but they may still be
26+
// reading data, so don't close conn yet
2527
return nil
2628
}
29+
conn.Close()
2730
return errors.WithStack(err)
2831
}
2932
select {

0 commit comments

Comments
 (0)