1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

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.
This commit is contained in:
Simon Tatham 2018-10-01 20:25:15 +01:00
parent fb07fccf2d
commit 1d162fa767

12
ssh.c
View File

@ -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