From 1bde686945326644a4ed8a9da3d6dd7edfe66f1e Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sat, 13 Oct 2018 10:30:03 +0100 Subject: [PATCH] Rename sshfwd_unclean_close to sshfwd_initiate_close. Turns out that initiation of a CHANNEL_CLOSE message before both sides have sent EOF is not only for _unclean_ closures or emergencies; it's actually a perfectly normal thing that some channel types want to do. (For example, a channel with a pty at the server end of it has no real concept of sending EOF independently in both directions: when the pty master sends EIO, the pty is no longer functioning, and you can no longer send to it any more than you can receive.) --- portfwd.c | 4 ++-- ssh1connection.c | 8 ++++---- ssh2connection.c | 8 ++++---- sshchan.h | 4 ++-- x11fwd.c | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/portfwd.c b/portfwd.c index 03c30dc2..656acf86 100644 --- a/portfwd.c +++ b/portfwd.c @@ -120,12 +120,12 @@ static void pfd_closing(Plug *plug, const char *error_msg, int error_code, * Socket error. Slam the connection instantly shut. */ if (pf->c) { - sshfwd_unclean_close(pf->c, error_msg); + sshfwd_initiate_close(pf->c, error_msg); } else { /* * We might not have an SSH channel, if a socket error * occurred during SOCKS negotiation. If not, we must - * clean ourself up without sshfwd_unclean_close's call + * clean ourself up without sshfwd_initiate_close's call * back to pfd_close. */ pfd_close(pf); diff --git a/ssh1connection.c b/ssh1connection.c index d406ea33..77bd01f7 100644 --- a/ssh1connection.c +++ b/ssh1connection.c @@ -195,7 +195,7 @@ struct ssh1_channel { static int ssh1channel_write(SshChannel *c, const void *buf, int len); static void ssh1channel_write_eof(SshChannel *c); -static void ssh1channel_unclean_close(SshChannel *c, const char *err); +static void ssh1channel_initiate_close(SshChannel *c, const char *err); static void ssh1channel_unthrottle(SshChannel *c, int bufsize); static Conf *ssh1channel_get_conf(SshChannel *c); static void ssh1channel_window_override_removed(SshChannel *c) { /* ignore */ } @@ -203,7 +203,7 @@ static void ssh1channel_window_override_removed(SshChannel *c) { /* ignore */ } static const struct SshChannelVtable ssh1channel_vtable = { ssh1channel_write, ssh1channel_write_eof, - ssh1channel_unclean_close, + ssh1channel_initiate_close, ssh1channel_unthrottle, ssh1channel_get_conf, ssh1channel_window_override_removed, @@ -937,12 +937,12 @@ static void ssh1channel_write_eof(SshChannel *sc) ssh1_channel_try_eof(c); } -static void ssh1channel_unclean_close(SshChannel *sc, const char *err) +static void ssh1channel_initiate_close(SshChannel *sc, const char *err) { struct ssh1_channel *c = container_of(sc, struct ssh1_channel, sc); char *reason; - reason = dupprintf("due to local error: %s", err); + reason = err ? dupprintf("due to local error: %s", err) : NULL; ssh1_channel_close_local(c, reason); sfree(reason); c->pending_eof = FALSE; /* this will confuse a zombie channel */ diff --git a/ssh2connection.c b/ssh2connection.c index c0b3e365..03857ea1 100644 --- a/ssh2connection.c +++ b/ssh2connection.c @@ -258,7 +258,7 @@ struct ssh2_channel { static int ssh2channel_write(SshChannel *c, const void *buf, int len); static void ssh2channel_write_eof(SshChannel *c); -static void ssh2channel_unclean_close(SshChannel *c, const char *err); +static void ssh2channel_initiate_close(SshChannel *c, const char *err); static void ssh2channel_unthrottle(SshChannel *c, int bufsize); static Conf *ssh2channel_get_conf(SshChannel *c); static void ssh2channel_window_override_removed(SshChannel *c); @@ -294,7 +294,7 @@ static void ssh2channel_hint_channel_is_simple(SshChannel *c); static const struct SshChannelVtable ssh2channel_vtable = { ssh2channel_write, ssh2channel_write_eof, - ssh2channel_unclean_close, + ssh2channel_initiate_close, ssh2channel_unthrottle, ssh2channel_get_conf, ssh2channel_window_override_removed, @@ -1442,12 +1442,12 @@ static void ssh2channel_write_eof(SshChannel *sc) ssh2_channel_try_eof(c); } -static void ssh2channel_unclean_close(SshChannel *sc, const char *err) +static void ssh2channel_initiate_close(SshChannel *sc, const char *err) { struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc); char *reason; - reason = dupprintf("due to local error: %s", err); + reason = err ? dupprintf("due to local error: %s", err) : NULL; ssh2_channel_close_local(c, reason); sfree(reason); c->pending_eof = FALSE; /* this will confuse a zombie channel */ diff --git a/sshchan.h b/sshchan.h index 7f1be259..3b221481 100644 --- a/sshchan.h +++ b/sshchan.h @@ -106,7 +106,7 @@ Channel *zombiechan_new(void); struct SshChannelVtable { int (*write)(SshChannel *c, const void *, int); void (*write_eof)(SshChannel *c); - void (*unclean_close)(SshChannel *c, const char *err); + void (*initiate_close)(SshChannel *c, const char *err); void (*unthrottle)(SshChannel *c, int bufsize); Conf *(*get_conf)(SshChannel *c); void (*window_override_removed)(SshChannel *c); @@ -162,7 +162,7 @@ struct SshChannel { #define sshfwd_write(c, buf, len) ((c)->vt->write(c, buf, len)) #define sshfwd_write_eof(c) ((c)->vt->write_eof(c)) -#define sshfwd_unclean_close(c, err) ((c)->vt->unclean_close(c, err)) +#define sshfwd_initiate_close(c, err) ((c)->vt->initiate_close(c, err)) #define sshfwd_unthrottle(c, bufsize) ((c)->vt->unthrottle(c, bufsize)) #define sshfwd_get_conf(c) ((c)->vt->get_conf(c)) #define sshfwd_window_override_removed(c) ((c)->vt->window_override_removed(c)) diff --git a/x11fwd.c b/x11fwd.c index 708f8d0e..44c9df1e 100644 --- a/x11fwd.c +++ b/x11fwd.c @@ -662,7 +662,7 @@ static void x11_closing(Plug *plug, const char *error_msg, int error_code, * Whether we did that or not, now we slam the connection * shut. */ - sshfwd_unclean_close(xconn->c, error_msg); + sshfwd_initiate_close(xconn->c, error_msg); } else { /* * Ordinary EOF received on socket. Send an EOF on the SSH