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 | |
parent | 94bc1e7ffba3cbdea8c7dcdab8376bf29283128f (diff) |
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
-rw-r--r-- | serverloop.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/serverloop.c b/serverloop.c index b5eb3440a..4b8d5ba68 100644 --- a/serverloop.c +++ b/serverloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: serverloop.c,v 1.193 2017/05/31 07:00:13 markus Exp $ */ | 1 | /* $OpenBSD: serverloop.c,v 1.194 2017/08/11 03:58:36 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * 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, | |||
204 | int ret; | 204 | int ret; |
205 | time_t minwait_secs = 0; | 205 | time_t minwait_secs = 0; |
206 | int client_alive_scheduled = 0; | 206 | int client_alive_scheduled = 0; |
207 | static time_t last_client_time; | ||
207 | 208 | ||
208 | /* Allocate and update select() masks for channel descriptors. */ | 209 | /* Allocate and update select() masks for channel descriptors. */ |
209 | channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, | 210 | channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, |
@@ -268,8 +269,19 @@ wait_until_can_do_something(int connection_in, int connection_out, | |||
268 | memset(*writesetp, 0, *nallocp); | 269 | memset(*writesetp, 0, *nallocp); |
269 | if (errno != EINTR) | 270 | if (errno != EINTR) |
270 | error("select: %.100s", strerror(errno)); | 271 | error("select: %.100s", strerror(errno)); |
271 | } else if (ret == 0 && client_alive_scheduled) | 272 | } else if (client_alive_scheduled) { |
272 | client_alive_check(); | 273 | time_t now = monotime(); |
274 | |||
275 | if (ret == 0) { /* timeout */ | ||
276 | client_alive_check(); | ||
277 | } else if (FD_ISSET(connection_in, *readsetp)) { | ||
278 | last_client_time = now; | ||
279 | } else if (last_client_time != 0 && last_client_time + | ||
280 | options.client_alive_interval < now) { | ||
281 | client_alive_check(); | ||
282 | last_client_time = now; | ||
283 | } | ||
284 | } | ||
273 | 285 | ||
274 | notify_done(*readsetp); | 286 | notify_done(*readsetp); |
275 | } | 287 | } |