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