From 1d162fa767151050db5ea5b84f72b9742c2f7c7d Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Mon, 1 Oct 2018 20:25:15 +0100 Subject: [PATCH] Stop sending outgoing-only EOF on SSH sockets. When PuTTY wants to cleanly close an SSH connection, my policy has been to use shutdown(SHUT_WR) (or rather, sk_write_eof, which ends up translating into that) to close just the outgoing side of the TCP connection, and then wait for the server to acknowledge that by closing its own end. Mainly the purpose of doing this rather than just immediately closing the whole socket was that I wanted to make sure any remaining outgoing packets of ours got sent before the connection was wound up. In particular, when we send SSH_MSG_DISCONNECT immediately before the close, we do want that to get through. But I now think this was a mistake, because it puts us at the mercy of the server remembering to respond by closing the other direction of the connection. It might absent-mindedly just continue to sit there holding the connection open, which would be silly, but if it did happen, we wouldn't want to sit around waiting in order to close the client application - we'd rather abandon a socket in that state and leave it to the OS's network layer to tell the server how silly it was being. So now I'm using an in-between strategy: I still wait for outgoing data to be sent before closing the socket (so the DISCONNECT should still go out), but once it's gone, I _do_ just close the whole thing instead of just sending outgoing EOF. --- ssh.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ssh.c b/ssh.c index 0e01b690..48af9e78 100644 --- a/ssh.c +++ b/ssh.c @@ -69,7 +69,7 @@ struct ssh_tag { int term_width, term_height; bufchain in_raw, out_raw, user_input; - int send_outgoing_eof; + int pending_close; IdempotentCallback ic_out_raw; PacketLogSettings pls; @@ -313,8 +313,10 @@ static void ssh_bpp_output_raw_data_callback(void *vctx) } } - if (ssh->send_outgoing_eof) - sk_write_eof(ssh->s); + if (ssh->pending_close) { + sk_close(ssh->s); + ssh->s = NULL; + } } static void ssh_shutdown_internal(Ssh ssh) @@ -368,9 +370,9 @@ static void ssh_initiate_connection_close(Ssh ssh) ssh_shutdown_internal(ssh); /* Force any remaining queued SSH packets through the BPP, and - * schedule sending of EOF on the network socket after them. */ + * schedule closing the network socket after they go out. */ ssh_bpp_handle_output(ssh->bpp); - ssh->send_outgoing_eof = TRUE; + ssh->pending_close = TRUE; /* Now we expect the other end to close the connection too in * response, so arrange that we'll receive notification of that