Idletimeout patch

Kevin Steves stevesk at pobox.com
Sat Aug 18 08:01:03 EST 2001


thanks.  here's the patch against current portable CVS with KNF and
cleanups.  i wonder if this could be shortened by eliminating
max_time_seconds and using max_time_milliseconds?

i'll also add key file support for idle-timeout later.

Index: servconf.h
===================================================================
RCS file: /var/cvs/openssh/servconf.h,v
retrieving revision 1.38
diff -u -r1.38 servconf.h
--- servconf.h	2001/07/04 18:37:21	1.38
+++ servconf.h	2001/08/17 20:24:43
@@ -129,6 +129,11 @@

 	char   *authorized_keys_file;	/* File containing public keys */
 	char   *authorized_keys_file2;
+	long	idle_timeout;		/*
+					 * If nonzero, the number of seconds
+ 					 * after which idle connections
+ 					 * will be terminated
+					 */
 	int	pam_authentication_via_kbd_int;

 }       ServerOptions;
Index: servconf.c
===================================================================
RCS file: /var/cvs/openssh/servconf.c,v
retrieving revision 1.63
diff -u -r1.63 servconf.c
--- servconf.c	2001/07/14 02:20:32	1.63
+++ servconf.c	2001/08/17 20:24:47
@@ -105,6 +105,7 @@
 	options->client_alive_count_max = -1;
 	options->authorized_keys_file = NULL;
 	options->authorized_keys_file2 = NULL;
+	options->idle_timeout = -1;
 	options->pam_authentication_via_kbd_int = -1;
 }

@@ -218,6 +219,8 @@
 		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
 	if (options->authorized_keys_file2 == NULL)
 		options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
+	if (options->idle_timeout == -1)
+		options->idle_timeout = 0;
 	if (options->pam_authentication_via_kbd_int == -1)
 		options->pam_authentication_via_kbd_int = 0;
 }
@@ -249,6 +252,7 @@
 	sBanner, sReverseMappingCheck, sHostbasedAuthentication,
 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
+ 	sIdleTimeout,
 	sPAMAuthenticationViaKbdInt
 } ServerOpCodes;

@@ -320,6 +324,7 @@
 	{ "authorizedkeysfile", sAuthorizedKeysFile },
 	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
 	{ "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt },
+	{ "idletimeout", sIdleTimeout },
 	{ NULL, 0 }
 };

@@ -846,6 +851,10 @@
 			intptr = &options->pam_authentication_via_kbd_int;
 			goto parse_flag;

+		case sIdleTimeout:
+			intptr = &options->idle_timeout;
+			goto parse_time;
+
 		default:
 			fatal("%s line %d: Missing handler for opcode %s (%d)",
 			    filename, linenum, arg, opcode);
Index: serverloop.c
===================================================================
RCS file: /var/cvs/openssh/serverloop.c,v
retrieving revision 1.75
diff -u -r1.75 serverloop.c
--- serverloop.c	2001/07/26 17:51:50	1.75
+++ serverloop.c	2001/08/17 20:24:53
@@ -80,7 +80,6 @@
 static int connection_out;	/* Connection to client (output). */
 static int connection_closed = 0;	/* Connection to client closed. */
 static u_int buffer_high;	/* "Soft" max buffer size. */
-
 /*
  * This SIGCHLD kludge is used to detect when the child exits.  The server
  * will exit after that, as soon as forwarded connections have terminated.
@@ -174,7 +173,11 @@
 	struct timeval tv, *tvp;
 	int ret;
 	int client_alive_scheduled = 0;
-
+	/* idletimeout last activity time */
+	static time_t idletime_last = 0;
+	/* time until idletimeout, zero if no idletimeout */
+	int max_time_seconds = 0;
+
 	/*
 	 * if using client_alive, set the max timeout accordingly,
 	 * and indicate that this particular timeout was for client
@@ -189,6 +192,24 @@
 		max_time_milliseconds = options.client_alive_interval * 1000;
 	}

+	if (options.idle_timeout > 0) {
+		if (idletime_last == 0)
+			time(&idletime_last);	/* Initialize */
+
+		/*
+		 * Schedule idletimeout if no other timeouts are scheduled.
+		 * Idletimeouts are the longest and it is not a big deal
+		 * if they are missed by few seconds.
+		 */
+		if (max_time_milliseconds == 0) {
+			time_t diff = time(NULL) - idletime_last;
+			if (diff >= options.idle_timeout)
+				max_time_seconds = 1;
+			else
+				max_time_seconds = options.idle_timeout - diff;
+		}
+	}
+
 	/* When select fails we restart from here. */
 retry_select:

@@ -239,10 +260,19 @@
 	if (child_terminated && packet_not_very_much_data_to_write())
 		if (max_time_milliseconds == 0 || client_alive_scheduled)
 			max_time_milliseconds = 100;
-
-	if (max_time_milliseconds == 0)
-		tvp = NULL;
-	else {
+
+	if (max_time_milliseconds == 0) {
+		/*
+		 * Use max_time_seconds only if max_time_milliseconds is
+		 * not set
+		 */
+		if (max_time_seconds > 0) {
+			tv.tv_sec = max_time_seconds;
+			tv.tv_usec = 0;
+			tvp = &tv;
+		} else
+			tvp = NULL;
+	} else {
 		tv.tv_sec = max_time_milliseconds / 1000;
 		tv.tv_usec = 1000 * (max_time_milliseconds % 1000);
 		tvp = &tv;
@@ -282,7 +312,22 @@
 				packet_disconnect(
 					"No open channels after timeout!");
 		}
-	}
+	}
+
+	if (options.idle_timeout > 0) {
+		/*
+		 * Reset idletimeout if something happened.
+		 * NOTE: events happening while there is
+		 * active client_alive_timeouts are ignored. This way
+		 * client_alive messages won't reset idletimeout counter.
+		 */
+		if (ret > 0 && client_alive_timeouts == 0)
+			time(&idletime_last);
+		/* Check if idletimeout has happened */
+		if (ret == 0 &&
+  		    time(NULL) - idletime_last > options.idle_timeout)
+			packet_disconnect("Timeout, idle time exceeded.");
+	}
 }

 /*





More information about the openssh-unix-dev mailing list