summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2001-07-02 22:52:58 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2001-07-02 22:52:58 +0000
commitc2c8a62507aee14d78ad6f75c28e8b4a18f06b6f (patch)
tree99e0876ec60bf0c903840a1ea2c17c1b03a9c994
parent4da0c32a5ff9757b2f5a1a1261b72a11f93907d4 (diff)
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.
-rw-r--r--usr.bin/ssh/channels.c56
-rw-r--r--usr.bin/ssh/channels.h10
-rw-r--r--usr.bin/ssh/serverloop.c6
3 files changed, 59 insertions, 13 deletions
diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c
index 5fed5c95e6e..6e89bb95e56 100644
--- a/usr.bin/ssh/channels.c
+++ b/usr.bin/ssh/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.
@@ -354,6 +370,32 @@ channel_close_all()
}
/*
+ * 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/usr.bin/ssh/channels.h b/usr.bin/ssh/channels.h
index c36f66b68a0..e4146b593f4 100644
--- a/usr.bin/ssh/channels.h
+++ b/usr.bin/ssh/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/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c
index c5ef95b7061..dea4fa2f215 100644
--- a/usr.bin/ssh/serverloop.c
+++ b/usr.bin/ssh/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