summaryrefslogtreecommitdiffstats
path: root/usr.bin/ssh/serverloop.c
diff options
context:
space:
mode:
authordtucker <dtucker@openbsd.org>2017-08-11 03:58:36 +0000
committerdtucker <dtucker@openbsd.org>2017-08-11 03:58:36 +0000
commit290d0ffb41bcee12906f5ab7b9c1dda453376fa4 (patch)
tree1b39bfe3fd14b4ee346325e7aa587e94f236e09b /usr.bin/ssh/serverloop.c
parentnaddy@ reported confusion on why "query from" seemed to be ignored in (diff)
downloadwireguard-openbsd-290d0ffb41bcee12906f5ab7b9c1dda453376fa4.tar.xz
wireguard-openbsd-290d0ffb41bcee12906f5ab7b9c1dda453376fa4.zip
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@
Diffstat (limited to 'usr.bin/ssh/serverloop.c')
-rw-r--r--usr.bin/ssh/serverloop.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c
index f7458f07400..9d077d7b334 100644
--- a/usr.bin/ssh/serverloop.c
+++ b/usr.bin/ssh/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
@@ -198,6 +198,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,
@@ -262,8 +263,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);
}