]> source.dussan.org Git - tigervnc.git/commitdiff
Added support for terminating inactive/active/disconnected sessions. This is a port...
authorPeter Åstrand <astrand@cendio.se>
Mon, 21 Feb 2005 09:58:31 +0000 (09:58 +0000)
committerPeter Åstrand <astrand@cendio.se>
Mon, 21 Feb 2005 09:58:31 +0000 (09:58 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@203 3789f03b-4d11-0410-bbf8-ca57d06f2519

rfb/ServerCore.cxx
rfb/ServerCore.h
rfb/VNCSConnectionST.cxx
rfb/VNCServerST.cxx
rfb/VNCServerST.h

index ea1ff2762c76ee98bc0a6a5f24b409e226d669ca..fe61ecbd8b6fd1e516004c20a1df7155b6ea8022 100644 (file)
@@ -30,6 +30,19 @@ rfb::IntParameter rfb::Server::idleTimeout
 ("IdleTimeout",
  "The number of seconds after which an idle VNC connection will be dropped",
  0);
+
+rfb::IntParameter rfb::Server::maxDisconnectionTime
+("MaxDisconnectionTime",
+ "Terminate when no client has been connected for s seconds", 
+ 0);
+rfb::IntParameter rfb::Server::maxConnectionTime
+("MaxConnectionTime",
+ "Terminate when a client has been connected for s seconds", 
+ 0);
+rfb::IntParameter rfb::Server::maxIdleTime
+("MaxIdleTime",
+ "Terminate after s seconds of user inactivity", 
+ 0);
 rfb::IntParameter rfb::Server::clientWaitTimeMillis
 ("ClientWaitTimeMillis",
  "The number of milliseconds to wait for a client which is no longer "
index 74d744328bfb9f4a9c4187b659da70addf00bd56..b01fcfd9b82f070e4867313a1358b001eac28a7b 100644 (file)
@@ -33,6 +33,9 @@ namespace rfb {
   public:
 
     static IntParameter idleTimeout;
+    static IntParameter maxDisconnectionTime;
+    static IntParameter maxConnectionTime;
+    static IntParameter maxIdleTime;
     static IntParameter clientWaitTimeMillis;
     static StringParameter sec_types;
     static StringParameter rev_sec_types;
index a20ec01d60aac5d4fb01309ec3e1205ea54ce6ae..ce48b3ecca39378bbc6ec33fd2472fd5693910d9 100644 (file)
@@ -98,6 +98,10 @@ void VNCSConnectionST::close(const char* reason)
   else
     vlog.debug("second close: %s (%s)", peerEndpoint.buf, reason);
 
+  if (authenticated()) {
+      server->lastDisconnectTime = time(0);
+  }
+
   // Just shutdown the socket.  This will cause processMessages to
   // eventually fail, causing us and our socket to be deleted.
   sock->shutdown();
@@ -389,6 +393,7 @@ void VNCSConnectionST::setPixelFormat(const PixelFormat& pf)
 void VNCSConnectionST::pointerEvent(int x, int y, int buttonMask)
 {
   pointerEventTime = lastEventTime = time(0);
+  server->lastUserInputTime = lastEventTime;
   if (!(accessRights & AccessPtrEvents)) return;
   if (!rfb::Server::acceptPointerEvents) return;
   if (!server->pointerClient || server->pointerClient == this) {
@@ -421,6 +426,7 @@ public:
 // multiple down events (for autorepeat), but only allow a single up event.
 void VNCSConnectionST::keyEvent(rdr::U32 key, bool down) {
   lastEventTime = time(0);
+  server->lastUserInputTime = lastEventTime;
   if (!(accessRights & AccessKeyEvents)) return;
   if (!rfb::Server::acceptKeyEvents) return;
 
index b3f9e88e599b0765fe977b023a44686bd56c41af..9a8013e4df8ec3176ea0d5ae848faf0867863173 100644 (file)
@@ -80,8 +80,10 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_,
     name(strDup(name_)), pointerClient(0), comparer(0),
     renderedCursorInvalid(false),
     securityFactory(sf ? sf : &defaultSecurityFactory),
-    queryConnectionHandler(0), useEconomicTranslate(false)
+    queryConnectionHandler(0), useEconomicTranslate(false),
+    lastConnectionTime(0)
 {
+  lastUserInputTime = lastDisconnectTime = time(0);
   slog.debug("creating single-threaded server %s", name.buf);
 }
 
@@ -138,6 +140,10 @@ void VNCServerST::addClient(network::Socket* sock, bool reverse)
     return;
   }
 
+  if (clients.empty()) {
+    lastConnectionTime = time(0);
+  }
+
   VNCSConnectionST* client = new VNCSConnectionST(this, sock, reverse);
   client->init();
 }
@@ -179,6 +185,79 @@ int VNCServerST::checkTimeouts()
     ci_next = ci; ci_next++;
     soonestTimeout(&timeout, (*ci)->checkIdleTimeout());
   }
+
+  int timeLeft;
+  time_t now;
+
+  // Optimization: Only call time() if using any maxTime. 
+  if (rfb::Server::maxDisconnectionTime || rfb::Server::maxConnectionTime || rfb::Server::maxIdleTime) {
+    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) { // enough time has gone 
+      slog.info("MaxIdleTime reached, exiting");
+      exit(0);
+    }
+    soonestTimeout(&timeout, timeLeft * 1000);
+  }
+  
   return timeout;
 }
 
index 6655a0d6a93d4e225df18c75e12c97a873b8c215..a6939c832f11eb509d4824acf646250953bbee59 100644 (file)
@@ -225,6 +225,10 @@ namespace rfb {
     SSecurityFactory* securityFactory;
     QueryConnectionHandler* queryConnectionHandler;
     bool useEconomicTranslate;
+    
+    time_t lastUserInputTime;
+    time_t lastDisconnectTime;
+    time_t lastConnectionTime;
   };
 
 };