From f43137c61bd19fd3a7a51833c9eb9bb9f890a904 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 26 Oct 2018 15:34:03 +0200 Subject: [PATCH] Change exit timeouts to timers This makes them more consistent with everything else, which makes things clearer and also allows them to handle some corner cases (e.g. only firing once). --- common/rfb/VNCServerST.cxx | 105 ++++++++++--------------------------- common/rfb/VNCServerST.h | 6 +-- 2 files changed, 32 insertions(+), 79 deletions(-) diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index 038da3dc..352b80f2 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -81,10 +81,16 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_) cursor(new Cursor(0, 0, Point(), NULL)), renderedCursorInvalid(false), keyRemapper(&KeyRemapper::defInstance), - lastConnectionTime(0), frameTimer(this) + idleTimer(this), disconnectTimer(this), connectTimer(this), + frameTimer(this) { - lastUserInputTime = lastDisconnectTime = time(0); slog.debug("creating single-threaded server %s", name.buf); + + // FIXME: Do we really want to kick off these right away? + if (rfb::Server::maxIdleTime) + idleTimer.start(secsToMillis(rfb::Server::maxIdleTime)); + if (rfb::Server::maxDisconnectionTime) + disconnectTimer.start(secsToMillis(rfb::Server::maxDisconnectionTime)); } VNCServerST::~VNCServerST() @@ -144,9 +150,10 @@ void VNCServerST::addSocket(network::Socket* sock, bool outgoing) name.buf = sock->getPeerEndpoint(); connectionsLog.status("accepted: %s", name.buf); - if (clients.empty()) { - lastConnectionTime = time(0); - } + // Adjust the exit timers + if (rfb::Server::maxConnectionTime && clients.empty()) + connectTimer.start(secsToMillis(rfb::Server::maxConnectionTime)); + disconnectTimer.stop(); VNCSConnectionST* client = new VNCSConnectionST(this, sock, outgoing); clients.push_front(client); @@ -164,8 +171,10 @@ void VNCServerST::removeSocket(network::Socket* sock) { if (pointerClient == *ci) pointerClient = NULL; - if ((*ci)->authenticated()) - lastDisconnectTime = time(0); + // Adjust the exit timers + connectTimer.stop(); + if (rfb::Server::maxDisconnectionTime && clients.empty()) + disconnectTimer.start(secsToMillis(rfb::Server::maxDisconnectionTime)); // - Delete the per-Socket resources delete *ci; @@ -226,73 +235,6 @@ int VNCServerST::checkTimeouts() ci_next = ci; ci_next++; soonestTimeout(&timeout, (*ci)->checkIdleTimeout()); } - - int timeLeft; - time_t now = time(0); - - // Check MaxDisconnectionTime - if (rfb::Server::maxDisconnectionTime && clients.empty()) { - if (now < lastDisconnectTime) { - // Someone must have set the time backwards. - slog.info("Time has gone backwards - resetting lastDisconnectTime"); - lastDisconnectTime = now; - } - timeLeft = lastDisconnectTime + rfb::Server::maxDisconnectionTime - now; - if (timeLeft < -60) { - // Someone must have set the time forwards. - slog.info("Time has gone forwards - resetting lastDisconnectTime"); - lastDisconnectTime = now; - timeLeft = rfb::Server::maxDisconnectionTime; - } - if (timeLeft <= 0) { - slog.info("MaxDisconnectionTime reached, exiting"); - exit(0); - } - soonestTimeout(&timeout, timeLeft * 1000); - } - - // Check MaxConnectionTime - if (rfb::Server::maxConnectionTime && lastConnectionTime && !clients.empty()) { - if (now < lastConnectionTime) { - // Someone must have set the time backwards. - slog.info("Time has gone backwards - resetting lastConnectionTime"); - lastConnectionTime = now; - } - timeLeft = lastConnectionTime + rfb::Server::maxConnectionTime - now; - if (timeLeft < -60) { - // Someone must have set the time forwards. - slog.info("Time has gone forwards - resetting lastConnectionTime"); - lastConnectionTime = now; - timeLeft = rfb::Server::maxConnectionTime; - } - if (timeLeft <= 0) { - slog.info("MaxConnectionTime reached, exiting"); - exit(0); - } - soonestTimeout(&timeout, timeLeft * 1000); - } - - - // Check MaxIdleTime - if (rfb::Server::maxIdleTime) { - if (now < lastUserInputTime) { - // Someone must have set the time backwards. - slog.info("Time has gone backwards - resetting lastUserInputTime"); - lastUserInputTime = now; - } - timeLeft = lastUserInputTime + rfb::Server::maxIdleTime - now; - if (timeLeft < -60) { - // Someone must have set the time forwards. - slog.info("Time has gone forwards - resetting lastUserInputTime"); - lastUserInputTime = now; - timeLeft = rfb::Server::maxIdleTime; - } - if (timeLeft <= 0) { - slog.info("MaxIdleTime reached, exiting"); - exit(0); - } - soonestTimeout(&timeout, timeLeft * 1000); - } return timeout; } @@ -495,7 +437,8 @@ void VNCServerST::setLEDState(unsigned int state) void VNCServerST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) { - lastUserInputTime = time(0); + if (rfb::Server::maxIdleTime) + idleTimer.start(secsToMillis(rfb::Server::maxIdleTime)); // Remap the key if required if (keyRemapper) { @@ -513,7 +456,8 @@ void VNCServerST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) void VNCServerST::pointerEvent(VNCSConnectionST* client, const Point& pos, int buttonMask) { - lastUserInputTime = time(0); + if (rfb::Server::maxIdleTime) + idleTimer.start(secsToMillis(rfb::Server::maxIdleTime)); // Let one client own the cursor whilst buttons are pressed in order // to provide a bit more sane user experience @@ -628,6 +572,15 @@ bool VNCServerST::handleTimeout(Timer* t) } return true; + } else if (t == &idleTimer) { + slog.info("MaxIdleTime reached, exiting"); + exit(0); + } else if (t == &disconnectTimer) { + slog.info("MaxDisconnectionTime reached, exiting"); + exit(0); + } else if (t == &connectTimer) { + slog.info("MaxConnectionTime reached, exiting"); + exit(0); } return false; diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h index 545b9a49..a994c942 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -198,9 +198,9 @@ namespace rfb { KeyRemapper* keyRemapper; - time_t lastUserInputTime; - time_t lastDisconnectTime; - time_t lastConnectionTime; + Timer idleTimer; + Timer disconnectTimer; + Timer connectTimer; Timer frameTimer; }; -- 2.39.5