[PATCH] Added Null packet keepalive option

Tom Rudnick tom at avatar.itc.nrcs.usda.gov
Thu Mar 15 07:13:30 EST 2001


I have attached a patch which adds null packet keepalive 
functionality to the client. This patch is made against the 
current CVS tree as of 3/14/01.

Please consider this patch for inclusion in the OpenSSH main tree.

This patch is based upon and includes code from the Chris Lightfoot 
(chris at ex-parrot.com) patch posted 2/23.

The original patch from Chris is at:

http://www.ex-parrot.com/~chris/openssh-patches/openssh-2.5.1p1-keepalives.patch

Description:

In order to keep a session active across a firewall or similar 
device that times out stateful connections, the client sends a 
SSH_MSG_NONE after X number of seconds of inactivity. Chris' 
original patch set this frequency to 3 minutes in the source. 
My patch allows this frequency to be configurable in the client.

The configuration option is named "NoopMsgFrequency", with the 
default set to "0", disabling this functionality. The name of this
option is deliberately dissimilar to "keepalive", as its function
is different than SO_KEEPALIVE.

The Windows PuTTY client implements this option in the same manner,
except the option is in minutes instead of seconds. Again, 0 turns
it off.

In my implementation, we are initiating ssh sessions across 2 L4
switches and a firewall into 3 load-balanced servers. Large Download
files are generated on the server. Timing out and initiating a new 
session potentially lands the user on a different server before the
file can be downloaded. 30 minutes for this option fits within the
L4 and firewall timeouts, and works well for us.

We have this implemented on UnixWare 2.1.3, Solaris 2.7, and Win/CygWin
platforms.

Thanks,
-Tom Rudnick

-- 
----------------/----------------------------------------------
Tom Rudnick     | USDA Natural Resources Conservation Service
Fort Collins,CO | tom at avatar.itc.nrcs.usda.gov  (970) 295-5427
** The 3rd Millennium started Jan 1, 2001. see:              **
**   http://aa.usno.navy.mil/AA/faq/docs/millennium.html     **
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-------------- next part --------------
--- readconf.h	2001/03/11 01:49:20	1.21
+++ readconf.h	2001/03/14 19:11:15
@@ -61,6 +61,10 @@
 	int     compression_level;	/* Compression level 1 (fast) to 9
 					 * (best). */
 	int     keepalives;	/* Set SO_KEEPALIVE. */
+	time_t	noop_msg_frequency;	/* Number of seconds between 
+					 * SSH_MSG_NONE packets to keep
+					 * firewall connections from 
+					 * timing out */
 	LogLevel log_level;	/* Level for logging. */
 
 	int     port;		/* Port to connect. */
--- readconf.c	2001/03/11 01:49:20	1.40
+++ readconf.c	2001/03/14 19:11:15
@@ -110,7 +110,7 @@
 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
 	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
-	oPreferredAuthentications
+	oPreferredAuthentications,oNoopMsgFrequency
 } OpCodes;
 
 /* Textual representations of the tokens. */
@@ -173,6 +173,7 @@
 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
 	{ "loglevel", oLogLevel },
 	{ "preferredauthentications", oPreferredAuthentications },
+	{ "noopmsgfrequency", oNoopMsgFrequency },
 	{ NULL, 0 }
 };
 
@@ -387,6 +388,10 @@
 		intptr = &options->keepalives;
 		goto parse_flag;
 
+	case oNoopMsgFrequency:
+		intptr = &options->noop_msg_frequency;
+		goto parse_int;
+
 	case oNumberOfPasswordPrompts:
 		intptr = &options->number_of_password_prompts;
 		goto parse_int;
@@ -707,6 +712,7 @@
 	options->strict_host_key_checking = -1;
 	options->compression = -1;
 	options->keepalives = -1;
+	options->noop_msg_frequency = -1;
 	options->compression_level = -1;
 	options->port = -1;
 	options->connection_attempts = -1;
@@ -791,6 +797,8 @@
 		options->compression = 0;
 	if (options->keepalives == -1)
 		options->keepalives = 1;
+	if (options->noop_msg_frequency == -1)
+		options->noop_msg_frequency = 0;
 	if (options->compression_level == -1)
 		options->compression_level = 6;
 	if (options->port == -1)
--- clientloop.c	2001/03/06 03:34:40	1.36
+++ clientloop.c	2001/03/14 19:11:21
@@ -365,6 +365,10 @@
 client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
     int *maxfdp)
 {
+	struct timeval tv = {0};
+	tv.tv_sec = options.noop_msg_frequency;
+	/* Send a noop message at this frequency as a keepalive. */
+	
 	/* Add any selections by the channel mechanism. */
 	channel_prepare_select(readsetp, writesetp, maxfdp);
 
@@ -403,7 +407,8 @@
 	 * SSH_MSG_IGNORE packet when the timeout expires.
 	 */
 
-	if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) {
+	switch (select((*maxfdp)+1, *readsetp, *writesetp, NULL, ((tv.tv_sec)?(&tv):NULL))) {
+            case -1: {
 		char buf[100];
 
 		/*
@@ -420,7 +425,21 @@
 		snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno));
 		buffer_append(&stderr_buffer, buf, strlen(buf));
 		quit_pending = 1;
-	}
+                
+            }
+            break;
+            
+            case 0:
+                /* Send a keepalive packet (not SSH_MSG_IGNORE as this crashes
+                 * some servers...).
+                 */
+                packet_start(SSH_MSG_NONE);
+                packet_send();
+                break;
+
+            default:
+                break;
+        }
 }
 
 void


More information about the openssh-unix-dev mailing list