From 809744e9125bb96c7115922bf747dc88c60a199e Mon Sep 17 00:00:00 2001 From: Ben Lindstrom Date: Wed, 4 Jul 2001 05:26:06 +0000 Subject: [PATCH] - markus@cvs.openbsd.org 2001/07/02 22:52:57 [channels.c channels.h serverloop.c] improve cleanup/exit logic in ssh2: stop listening to channels, detach channel users (e.g. sessions). wait for children (i.e. dying sessions), send exit messages, cleanup all channels. --- ChangeLog | 8 +++++++- channels.c | 56 +++++++++++++++++++++++++++++++++++++++++++++------- channels.h | 10 ++++++---- serverloop.c | 6 ++++-- 4 files changed, 66 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 211ecb85a..aa734bcd0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -124,6 +124,12 @@ - markus@cvs.openbsd.org 2001/07/02 22:40:18 [ssh-keygen.c] update for sectok.h interface changes. + - markus@cvs.openbsd.org 2001/07/02 22:52:57 + [channels.c channels.h serverloop.c] + improve cleanup/exit logic in ssh2: + stop listening to channels, detach channel users (e.g. sessions). + wait for children (i.e. dying sessions), send exit messages, + cleanup all channels. 20010629 - (bal) Removed net_aton() since we don't use it any more @@ -5951,4 +5957,4 @@ - Wrote replacements for strlcpy and mkdtemp - Released 1.0pre1 -$Id: ChangeLog,v 1.1375 2001/07/04 05:24:27 mouring Exp $ +$Id: ChangeLog,v 1.1376 2001/07/04 05:26:06 mouring Exp $ diff --git a/channels.c b/channels.c index 18b6c468e..35edff6dc 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.130 2001/06/30 18:08:39 stevesk Exp $"); +RCSID("$OpenBSD: channels.c,v 1.131 2001/07/02 22:52:56 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -260,7 +260,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, c->cb_fn = NULL; c->cb_arg = NULL; c->cb_event = 0; - c->dettach_user = NULL; + c->detach_user = NULL; c->input_filter = NULL; debug("channel %d: new [%s]", found, remote_name); return c; @@ -310,9 +310,9 @@ channel_free(Channel *c) debug3("channel_free: status: %s", s); xfree(s); - if (c->dettach_user != NULL) { - debug("channel_free: channel %d: dettaching channel user", c->self); - c->dettach_user(c->self, NULL); + if (c->detach_user != NULL) { + debug("channel_free: channel %d: detaching channel user", c->self); + c->detach_user(c->self, NULL); } if (c->sock != -1) shutdown(c->sock, SHUT_RDWR); @@ -338,6 +338,22 @@ channel_free_all(void) channel_free(channels[i]); } +void +channel_detach_all(void) +{ + int i; + Channel *c; + + for (i = 0; i < channels_alloc; i++) { + c = channels[i]; + if (c != NULL && c->detach_user != NULL) { + debug("channel_detach_all: channel %d", c->self); + c->detach_user(c->self, NULL); + c->detach_user = NULL; + } + } +} + /* * Closes the sockets/fds of all channels. This is used to close extra file * descriptors after a fork. @@ -353,6 +369,32 @@ channel_close_all() channel_close_fds(channels[i]); } +/* + * Stop listening to channels. + */ + +void +channel_stop_listening(void) +{ + int i; + Channel *c; + + for (i = 0; i < channels_alloc; i++) { + c = channels[i]; + if (c != NULL) { + switch (c->type) { + case SSH_CHANNEL_AUTH_SOCKET: + case SSH_CHANNEL_PORT_LISTENER: + case SSH_CHANNEL_RPORT_LISTENER: + case SSH_CHANNEL_X11_LISTENER: + close(c->sock); + channel_free(c); + break; + } + } + } +} + /* * Returns true if no channel has too much buffered data, and false if one or * more channel is overfull. @@ -579,7 +621,7 @@ channel_register_cleanup(int id, channel_callback_fn *fn) log("channel_register_cleanup: %d: bad id", id); return; } - c->dettach_user = fn; + c->detach_user = fn; } void channel_cancel_cleanup(int id) @@ -589,7 +631,7 @@ channel_cancel_cleanup(int id) log("channel_cancel_cleanup: %d: bad id", id); return; } - c->dettach_user = NULL; + c->detach_user = NULL; } void channel_register_filter(int id, channel_filter_fn *fn) diff --git a/channels.h b/channels.h index c36f66b68..e4146b593 100644 --- a/channels.h +++ b/channels.h @@ -32,7 +32,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* RCSID("$OpenBSD: channels.h,v 1.43 2001/06/30 18:08:40 stevesk Exp $"); */ +/* RCSID("$OpenBSD: channels.h,v 1.44 2001/07/02 22:52:57 markus Exp $"); */ #ifndef CHANNEL_H #define CHANNEL_H @@ -102,7 +102,7 @@ struct Channel { channel_callback_fn *cb_fn; void *cb_arg; int cb_event; - channel_callback_fn *dettach_user; + channel_callback_fn *detach_user; /* filter */ channel_filter_fn *input_filter; @@ -140,8 +140,10 @@ struct Channel { Channel *channel_lookup(int); Channel *channel_new(char *, int, int, int, int, int, int, int, char *, int); void channel_set_fds(int, int, int, int, int, int); -void channel_free(Channel *); -void channel_free_all(void); +void channel_free(Channel *); +void channel_free_all(void); +void channel_detach_all(void); +void channel_stop_listening(void); void channel_send_open(int); void channel_request(int, char *, int); diff --git a/serverloop.c b/serverloop.c index 773292a94..1db1c725a 100644 --- a/serverloop.c +++ b/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.73 2001/07/02 13:59:14 markus Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.74 2001/07/02 22:52:57 markus Exp $"); #include "xmalloc.h" #include "packet.h" @@ -711,7 +711,8 @@ server_loop2(Authctxt *authctxt) * there is a race between channel_free_all() killing children and * children dying before kill() */ - channel_free_all(); + channel_detach_all(); + channel_stop_listening(); while (session_have_children()) { pid = waitpid(-1, &status, 0); @@ -722,6 +723,7 @@ server_loop2(Authctxt *authctxt) break; } } + channel_free_all(); } static void