]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream commit
authordtucker@openbsd.org <dtucker@openbsd.org>
Fri, 11 Aug 2017 03:58:36 +0000 (03:58 +0000)
committerDamien Miller <djm@mindrot.org>
Sat, 12 Aug 2017 06:47:10 +0000 (16:47 +1000)
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

serverloop.c

index b5eb3440a2c21afb2782780e6cea9f924d0439da..4b8d5ba68d55f9dd543cad879d32c645cf6ab822 100644 (file)
@@ -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);
 }