diff options
author | dtucker@openbsd.org <dtucker@openbsd.org> | 2017-08-11 03:58:36 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-08-12 16:47:10 +1000 |
commit | b60ff20051ef96dfb207b6bfa45c0ad6c34a542a (patch) | |
tree | 5aba8318170dd597a9805e72e152b0c70a9f9397 /serverloop.c | |
parent | 94bc1e7ffba3cbdea8c7dcdab8376bf29283128f (diff) | |
download | openssh-git-b60ff20051ef96dfb207b6bfa45c0ad6c34a542a.tar.gz |
upstream commit
Keep track of the last time we actually heard from the
client and use this to also schedule a client_alive_check(). Prevents
activity on a forwarded port from indefinitely preventing the select timeout
so that client_alive_check() will eventually (although not optimally) be
called.
Analysis by willchan at google com via bz#2756, feedback & ok djm@
Upstream-ID: c08721e0bbda55c6d18e2760f3fe1b17fb71169e
Diffstat (limited to 'serverloop.c')
-rw-r--r-- | serverloop.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/serverloop.c b/serverloop.c index b5eb3440..4b8d5ba6 100644 --- a/serverloop.c +++ b/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.193 2017/05/31 07:00:13 markus Exp $ */ +/* $OpenBSD: serverloop.c,v 1.194 2017/08/11 03:58:36 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -204,6 +204,7 @@ wait_until_can_do_something(int connection_in, int connection_out, int ret; time_t minwait_secs = 0; int client_alive_scheduled = 0; + static time_t last_client_time; /* Allocate and update select() masks for channel descriptors. */ channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, @@ -268,8 +269,19 @@ wait_until_can_do_something(int connection_in, int connection_out, memset(*writesetp, 0, *nallocp); if (errno != EINTR) error("select: %.100s", strerror(errno)); - } else if (ret == 0 && client_alive_scheduled) - client_alive_check(); + } else if (client_alive_scheduled) { + time_t now = monotime(); + + if (ret == 0) { /* timeout */ + client_alive_check(); + } else if (FD_ISSET(connection_in, *readsetp)) { + last_client_time = now; + } else if (last_client_time != 0 && last_client_time + + options.client_alive_interval < now) { + client_alive_check(); + last_client_time = now; + } + } notify_done(*readsetp); } |