SSH connection hanging on logout

John Bowman bowman at math.ualberta.ca
Thu May 17 11:44:50 EST 2001


> > The third item is another type of hanging bug in Openssh, as is
> > demonstrated by the following test:
> > 
> > ssh -2 host
> > xterm -e sleep 20 &
> > exit
> > 
> > Even after the xsession terminates, the ssh session is left hanging forever.
> > The correct behaviour is to wait 20 seconds for the X application to close
> > and then exit.
> 
> this is a client bug. try this:
> 
> Index: clientloop.c
> ===================================================================
> RCS file: /home/markus/cvs/ssh/clientloop.c,v
> retrieving revision 1.70
> diff -u -r1.70 clientloop.c
> --- clientloop.c	2001/05/11 14:59:55	1.70
> +++ clientloop.c	2001/05/16 20:31:44
> @@ -346,7 +346,13 @@
>  		if (buffer_len(&stderr_buffer) > 0)
>  			FD_SET(fileno(stderr), *writesetp);
>  	} else {
> -		FD_SET(connection_in, *readsetp);
> +		/* channel_prepare_select could have closed the last channel */
> +		if (session_closed && !channel_still_open()) {
> +			if (!packet_have_data_to_write())
> +				return;
> +		} else {
> +			FD_SET(connection_in, *readsetp);
> +		}
>  	}
>  
>  	/* Select server connection if have data to write to the server. */
> 
Yes, this patch fixes the X hanging bug (test under Protocol 2 on RedHat
6.2 linux systems). Thanks!

I've incorporated it into this latest version of the hang-on-exit patch
(the latest patch will always be available from
http://www.math.ualberta.ca/imaging/snfs)

-- John Bowman

University of Alberta
http://www.math.ualberta.ca/~bowman


diff -ur openssh-2.9p1/channels.c openssh-2.9p1J/channels.c
--- openssh-2.9p1/channels.c	Tue Apr 17 12:14:35 2001
+++ openssh-2.9p1J/channels.c	Wed May 16 16:42:53 2001
@@ -1137,6 +1137,15 @@
 			continue;
 		if (ftab[c->type] == NULL)
 			continue;
+		if(c->istate == CHAN_INPUT_OPEN && c->rfd == -1) {
+			int type=c->type;
+			c->type=SSH_CHANNEL_CLOSED;
+			if(channel_find_open() == -1)
+			  	shutdown(packet_get_connection_out(),
+					 SHUT_RDWR);
+			c->type=type;
+			continue;
+		}
 		(*ftab[c->type])(c, readset, writeset);
 		if (chan_is_dead(c)) {
 			/*
diff -ur openssh-2.9p1/clientloop.c openssh-2.9p1J/clientloop.c
--- openssh-2.9p1/clientloop.c	Fri Apr 20 06:50:51 2001
+++ openssh-2.9p1J/clientloop.c	Wed May 16 18:55:58 2001
@@ -346,7 +346,13 @@
 		if (buffer_len(&stderr_buffer) > 0)
 			FD_SET(fileno(stderr), *writesetp);
 	} else {
-		FD_SET(connection_in, *readsetp);
+		/* channel_prepare_select could have closed the last channel */
+		if (session_closed && !channel_still_open()) {
+			if (!packet_have_data_to_write())
+				return;
+		} else {
+			FD_SET(connection_in, *readsetp);
+		}
 	}
 
 	/* Select server connection if have data to write to the server. */
@@ -440,9 +446,13 @@
 		len = read(connection_in, buf, sizeof(buf));
 		if (len == 0) {
 			/* Received EOF.  The remote host has closed the connection. */
-			snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n",
-				 host);
-			buffer_append(&stderr_buffer, buf, strlen(buf));
+/* 
+ * This message duplicates the one already in client_loop().
+ *
+ *			snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n",
+ *				 host);
+ *			buffer_append(&stderr_buffer, buf, strlen(buf));
+ */			
 			quit_pending = 1;
 			return;
 		}
diff -ur openssh-2.9p1/nchan.c openssh-2.9p1J/nchan.c
--- openssh-2.9p1/nchan.c	Tue Apr  3 07:02:48 2001
+++ openssh-2.9p1J/nchan.c	Wed May 16 11:29:36 2001
@@ -56,7 +56,7 @@
 
 /* helper */
 static void	chan_shutdown_write(Channel *c);
-static void	chan_shutdown_read(Channel *c);
+void		chan_shutdown_read(Channel *c);
 
 /*
  * SSH1 specific implementation of event functions
@@ -479,7 +479,7 @@
 		c->wfd = -1;
 	}
 }
-static void
+void
 chan_shutdown_read(Channel *c)
 {
 	if (compat20 && c->type == SSH_CHANNEL_LARVAL)
diff -ur openssh-2.9p1/nchan.h openssh-2.9p1J/nchan.h
--- openssh-2.9p1/nchan.h	Sun Mar  4 23:16:12 2001
+++ openssh-2.9p1J/nchan.h	Wed May 16 11:29:36 2001
@@ -88,4 +88,5 @@
 
 void    chan_init_iostates(Channel * c);
 void	chan_init(void);
+void	chan_shutdown_read(Channel *c);
 #endif
diff -ur openssh-2.9p1/session.c openssh-2.9p1J/session.c
--- openssh-2.9p1/session.c	Wed Apr 18 09:29:34 2001
+++ openssh-2.9p1J/session.c	Wed May 16 18:57:49 2001
@@ -1960,6 +1960,9 @@
 	 */
 	if (c->ostate != CHAN_OUTPUT_CLOSED)
 		chan_write_failed(c);
+	if (c->istate == CHAN_INPUT_OPEN && compat20) {
+		chan_shutdown_read(c);
+	}
 	s->chanid = -1;
 }
 



More information about the openssh-unix-dev mailing list