diff options
author | Matt Johnston <matt@ucc.asn.au> | 2015-08-03 23:05:43 +0800 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2015-08-03 23:05:43 +0800 |
commit | 2e60d20a76f01e590e130737eeb663145b46c54c (patch) | |
tree | d35129e863ae9d2b2da45a59e4663208c8dabe8e | |
parent | ce59260ee9701d975baa4833534f1aedea6ba228 (diff) |
set timeouts to time remaining rather than timeout duration
-rw-r--r-- | common-session.c | 41 |
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() { |