From 64f95e633469844b86f4d62c03ae991c4b64ffee Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Wed, 19 Sep 2018 20:31:19 +0100 Subject: [PATCH] Move the zombiechan implementation into sshcommon.c. It doesn't really have to be in ssh.c sharing that file's internal data structures; it's as much an independent object implementation as any of the less trivial Channel instances. So it's another thing we can get out of that too-large source file. --- ssh.c | 67 ----------------------------------------------------- sshchan.h | 12 ++++++++++ sshcommon.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 67 deletions(-) diff --git a/ssh.c b/ssh.c index 2749f23f..17e9075d 100644 --- a/ssh.c +++ b/ssh.c @@ -1357,73 +1357,6 @@ int chan_no_eager_close(Channel *chan, int sent_local_eof, int rcvd_remote_eof) return FALSE; /* default: never proactively ask for a close */ } -/* - * Trivial channel vtable for handling 'zombie channels' - those whose - * local source of data has already been shut down or otherwise - * stopped existing - so that we don't have to give them a null - * 'Channel *' and special-case that all over the place. - */ - -static void zombiechan_free(Channel *chan); -static int zombiechan_send(Channel *chan, int is_stderr, const void *, int); -static void zombiechan_set_input_wanted(Channel *chan, int wanted); -static void zombiechan_do_nothing(Channel *chan); -static void zombiechan_open_failure(Channel *chan, const char *); -static int zombiechan_want_close(Channel *chan, int sent_eof, int rcvd_eof); -static char *zombiechan_log_close_msg(Channel *chan) { return NULL; } - -static const struct ChannelVtable zombiechan_channelvt = { - zombiechan_free, - zombiechan_do_nothing, /* open_confirmation */ - zombiechan_open_failure, - zombiechan_send, - zombiechan_do_nothing, /* send_eof */ - zombiechan_set_input_wanted, - zombiechan_log_close_msg, - zombiechan_want_close, -}; - -Channel *zombiechan_new(void) -{ - Channel *chan = snew(Channel); - chan->vt = &zombiechan_channelvt; - chan->initial_fixed_window_size = 0; - return chan; -} - -static void zombiechan_free(Channel *chan) -{ - assert(chan->vt == &zombiechan_channelvt); - sfree(chan); -} - -static void zombiechan_do_nothing(Channel *chan) -{ - assert(chan->vt == &zombiechan_channelvt); -} - -static void zombiechan_open_failure(Channel *chan, const char *errtext) -{ - assert(chan->vt == &zombiechan_channelvt); -} - -static int zombiechan_send(Channel *chan, int is_stderr, - const void *data, int length) -{ - assert(chan->vt == &zombiechan_channelvt); - return 0; -} - -static void zombiechan_set_input_wanted(Channel *chan, int enable) -{ - assert(chan->vt == &zombiechan_channelvt); -} - -static int zombiechan_want_close(Channel *chan, int sent_eof, int rcvd_eof) -{ - return TRUE; -} - static int ssh_do_close(Ssh ssh, int notify_exit) { int ret = 0; diff --git a/sshchan.h b/sshchan.h index 271cdb09..e2bc28b0 100644 --- a/sshchan.h +++ b/sshchan.h @@ -56,6 +56,18 @@ void chan_remotely_opened_failure(Channel *chan, const char *errtext); * closing until both directions have had an EOF */ int chan_no_eager_close(Channel *, int, int); +/* + * Constructor for a trivial do-nothing implementation of + * ChannelVtable. Used for 'zombie' channels, i.e. channels whose + * proper local source of data has been shut down or otherwise stopped + * existing, but the SSH side is still there and needs some kind of a + * Channel implementation to talk to. In particular, the want_close + * method for this channel always returns 'yes, please close this + * channel asap', regardless of whether local and/or remote EOF have + * been sent - indeed, even if _neither_ has. + */ +Channel *zombiechan_new(void); + /* ---------------------------------------------------------------------- * This structure is owned by an SSH connection layer, and identifies * the connection layer's end of the channel, for the Channel diff --git a/sshcommon.c b/sshcommon.c index 856a8358..8bab9beb 100644 --- a/sshcommon.c +++ b/sshcommon.c @@ -203,3 +203,67 @@ void ssh_free_pktout(PktOut *pkt) sfree(pkt->data); sfree(pkt); } +/* ---------------------------------------------------------------------- + * Implement zombiechan_new() and its trivial vtable. + */ + +static void zombiechan_free(Channel *chan); +static int zombiechan_send(Channel *chan, int is_stderr, const void *, int); +static void zombiechan_set_input_wanted(Channel *chan, int wanted); +static void zombiechan_do_nothing(Channel *chan); +static void zombiechan_open_failure(Channel *chan, const char *); +static int zombiechan_want_close(Channel *chan, int sent_eof, int rcvd_eof); +static char *zombiechan_log_close_msg(Channel *chan) { return NULL; } + +static const struct ChannelVtable zombiechan_channelvt = { + zombiechan_free, + zombiechan_do_nothing, /* open_confirmation */ + zombiechan_open_failure, + zombiechan_send, + zombiechan_do_nothing, /* send_eof */ + zombiechan_set_input_wanted, + zombiechan_log_close_msg, + zombiechan_want_close, +}; + +Channel *zombiechan_new(void) +{ + Channel *chan = snew(Channel); + chan->vt = &zombiechan_channelvt; + chan->initial_fixed_window_size = 0; + return chan; +} + +static void zombiechan_free(Channel *chan) +{ + assert(chan->vt == &zombiechan_channelvt); + sfree(chan); +} + +static void zombiechan_do_nothing(Channel *chan) +{ + assert(chan->vt == &zombiechan_channelvt); +} + +static void zombiechan_open_failure(Channel *chan, const char *errtext) +{ + assert(chan->vt == &zombiechan_channelvt); +} + +static int zombiechan_send(Channel *chan, int is_stderr, + const void *data, int length) +{ + assert(chan->vt == &zombiechan_channelvt); + return 0; +} + +static void zombiechan_set_input_wanted(Channel *chan, int enable) +{ + assert(chan->vt == &zombiechan_channelvt); +} + +static int zombiechan_want_close(Channel *chan, int sent_eof, int rcvd_eof) +{ + return TRUE; +} +