summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2015-08-03 23:05:43 +0800
committerMatt Johnston <matt@ucc.asn.au>2015-08-03 23:05:43 +0800
commit2e60d20a76f01e590e130737eeb663145b46c54c (patch)
treed35129e863ae9d2b2da45a59e4663208c8dabe8e
parentce59260ee9701d975baa4833534f1aedea6ba228 (diff)
set timeouts to time remaining rather than timeout duration
-rw-r--r--common-session.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/common-session.c b/common-session.c
index f2ccdf7..4b7e38c 100644
--- a/common-session.c
+++ b/common-session.c
@@ -532,20 +532,39 @@ static void checktimeouts() {
}
}
+static void update_timeout(long limit, long now, long last_event, long * timeout) {
+ TRACE(("update_timeout limit %ld, now %ld, last %ld, timeout %ld",
+ limit, now, last_event, *timeout))
+ if (last_event > 0 && limit > 0) {
+ *timeout = MIN(*timeout, last_event+limit-now);
+ TRACE(("update to %ld", *timeout))
+ }
+}
+
static long select_timeout() {
/* determine the minimum timeout that might be required, so
as to avoid waking when unneccessary */
- long ret = LONG_MAX;
- if (KEX_REKEY_TIMEOUT > 0)
- ret = MIN(KEX_REKEY_TIMEOUT, ret);
- /* AUTH_TIMEOUT is only relevant before authdone */
- if (ses.authstate.authdone != 1 && AUTH_TIMEOUT > 0)
- ret = MIN(AUTH_TIMEOUT, ret);
- if (opts.keepalive_secs > 0)
- ret = MIN(opts.keepalive_secs, ret);
- if (opts.idle_timeout_secs > 0)
- ret = MIN(opts.idle_timeout_secs, ret);
- return ret;
+ long timeout = LONG_MAX;
+ long now = monotonic_now();
+
+ update_timeout(KEX_REKEY_TIMEOUT, now, ses.kexstate.lastkextime, &timeout);
+
+ if (ses.authstate.authdone != 1 && IS_DROPBEAR_SERVER) {
+ /* AUTH_TIMEOUT is only relevant before authdone */
+ update_timeout(AUTH_TIMEOUT, now, ses.connect_time, &timeout);
+ }
+
+ update_timeout(opts.keepalive_secs, now,
+ MAX(ses.last_packet_time_keepalive_recv, ses.last_packet_time_keepalive_sent),
+ &timeout);
+
+ update_timeout(opts.idle_timeout_secs, now, ses.last_packet_time_idle,
+ &timeout);
+
+ TRACE(("timeout %ld", timeout))
+
+ /* clamp negative timeouts to zero - event has already triggered */
+ return MAX(timeout, 0);
}
const char* get_user_shell() {