20031217
 - (djm) OpenBSD CVS Sync
   - markus@cvs.openbsd.org 2003/12/09 15:28:43
     [serverloop.c]
     make ClientKeepAlive work for ssh -N, too (no login shell requested).
     1) send a bogus channel request if we find a channel
     2) send a bogus global request if we don't have a channel
     ok + test beck@
diff --git a/serverloop.c b/serverloop.c
index 20255aa..bc7cd65 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.113 2003/11/18 00:40:05 dtucker Exp $");
+RCSID("$OpenBSD: serverloop.c,v 1.114 2003/12/09 15:28:43 markus Exp $");
 
 #include "xmalloc.h"
 #include "packet.h"
@@ -212,26 +212,23 @@
 static void
 client_alive_check(void)
 {
-	static int had_channel = 0;
-	int id;
-
-	id = channel_find_open();
-	if (id == -1) {
-		if (!had_channel)
-			return;
-		packet_disconnect("No open channels after timeout!");
-	}
-	had_channel = 1;
+	int channel_id;
 
 	/* timeout, check to see how many we have had */
 	if (++client_alive_timeouts > options.client_alive_count_max)
 		packet_disconnect("Timeout, your session not responding.");
 
 	/*
-	 * send a bogus channel request with "wantreply",
+	 * send a bogus global/channel request with "wantreply",
 	 * we should get back a failure
 	 */
-	channel_request_start(id, "keepalive@openssh.com", 1);
+	if ((channel_id = channel_find_open()) == -1) {
+		packet_start(SSH2_MSG_GLOBAL_REQUEST);
+		packet_put_cstring("keepalive@openssh.com");
+		packet_put_char(1);	/* boolean: want reply */
+	} else {
+		channel_request_start(channel_id, "keepalive@openssh.com", 1);
+	}
 	packet_send();
 }
 
@@ -797,9 +794,9 @@
 }
 
 static void
-server_input_channel_failure(int type, u_int32_t seq, void *ctxt)
+server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
 {
-	debug("Got CHANNEL_FAILURE for keepalive");
+	debug("Got %d/%u for keepalive", type, seq);
 	/*
 	 * reset timeout, since we got a sane answer from the client.
 	 * even if this was generated by something other than
@@ -808,7 +805,6 @@
 	client_alive_timeouts = 0;
 }
 
-
 static void
 server_input_stdin_data(int type, u_int32_t seq, void *ctxt)
 {
@@ -1048,7 +1044,9 @@
 	dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
 	dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
 	/* client_alive */
-	dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_channel_failure);
+	dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
+	dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
+	dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
 	/* rekeying */
 	dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
 }