aboutsummaryrefslogtreecommitdiffstats
path: root/common/rfb
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2018-11-09 17:28:44 +0100
committerPierre Ossman <ossman@cendio.se>2018-11-09 17:28:44 +0100
commitb85febcd752f38cc05233db628795f8fea91795f (patch)
tree10bf7d316e0d37acbd8825c4118e51384ff995c3 /common/rfb
parentf9de17665a3549e7e1eb44584ce73d6cafbd4c99 (diff)
parenta4308c9ec45b0ebcafaed2280b442d2840098e4e (diff)
downloadtigervnc-b85febcd752f38cc05233db628795f8fea91795f.tar.gz
tigervnc-b85febcd752f38cc05233db628795f8fea91795f.zip
Merge branch 'exittimer' of https://github.com/CendioOssman/tigervnc
Diffstat (limited to 'common/rfb')
-rw-r--r--common/rfb/SDesktop.h6
-rw-r--r--common/rfb/VNCSConnectionST.cxx61
-rw-r--r--common/rfb/VNCSConnectionST.h8
-rw-r--r--common/rfb/VNCServerST.cxx121
-rw-r--r--common/rfb/VNCServerST.h12
5 files changed, 63 insertions, 145 deletions
diff --git a/common/rfb/SDesktop.h b/common/rfb/SDesktop.h
index 61182469..0060aa23 100644
--- a/common/rfb/SDesktop.h
+++ b/common/rfb/SDesktop.h
@@ -75,6 +75,12 @@ namespace rfb {
virtual void queryConnection(network::Socket* sock,
const char* userName) = 0;
+ // terminate() is called by the server when it wishes to terminate
+ // itself, e.g. because it was configured to terminate when no one is
+ // using it.
+
+ virtual void terminate() = 0;
+
// setScreenLayout() requests to reconfigure the framebuffer and/or
// the layout of screens.
virtual unsigned int setScreenLayout(int __unused_attr fb_width,
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 7b261e74..8758362c 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -51,15 +51,23 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
fenceDataLen(0), fenceData(NULL), congestionTimer(this),
losslessTimer(this), server(server_), updates(false),
updateRenderedCursor(false), removeRenderedCursor(false),
- continuousUpdates(false), encodeManager(this), pointerEventTime(0),
- clientHasCursor(false)
+ continuousUpdates(false), encodeManager(this), idleTimer(this),
+ pointerEventTime(0), clientHasCursor(false)
{
setStreams(&sock->inStream(), &sock->outStream());
peerEndpoint.buf = sock->getPeerEndpoint();
// Configure the socket
setSocketTimeouts();
- lastEventTime = time(0);
+
+ // Kick off the idle timer
+ if (rfb::Server::idleTimeout) {
+ // minimum of 15 seconds while authenticating
+ if (rfb::Server::idleTimeout < 15)
+ idleTimer.start(secsToMillis(15));
+ else
+ idleTimer.start(secsToMillis(rfb::Server::idleTimeout));
+ }
}
@@ -312,36 +320,6 @@ void VNCSConnectionST::setLEDStateOrClose(unsigned int state)
}
-int VNCSConnectionST::checkIdleTimeout()
-{
- int idleTimeout = rfb::Server::idleTimeout;
- if (idleTimeout == 0) return 0;
- if (state() != RFBSTATE_NORMAL && idleTimeout < 15)
- idleTimeout = 15; // minimum of 15 seconds while authenticating
- time_t now = time(0);
- if (now < lastEventTime) {
- // Someone must have set the time backwards. Set lastEventTime so that the
- // idleTimeout will count from now.
- vlog.info("Time has gone backwards - resetting idle timeout");
- lastEventTime = now;
- }
- int timeLeft = lastEventTime + idleTimeout - now;
- if (timeLeft < -60) {
- // Our callback is over a minute late - someone must have set the time
- // forwards. Set lastEventTime so that the idleTimeout will count from
- // now.
- vlog.info("Time has gone forwards - resetting idle timeout");
- lastEventTime = now;
- return secsToMillis(idleTimeout);
- }
- if (timeLeft <= 0) {
- close("Idle timeout");
- return 0;
- }
- return secsToMillis(timeLeft);
-}
-
-
bool VNCSConnectionST::getComparerState()
{
// We interpret a low compression level as an indication that the client
@@ -412,7 +390,8 @@ void VNCSConnectionST::approveConnectionOrClose(bool accept,
void VNCSConnectionST::authSuccess()
{
- lastEventTime = time(0);
+ if (rfb::Server::idleTimeout)
+ idleTimer.start(secsToMillis(rfb::Server::idleTimeout));
// - Set the connection parameters appropriately
cp.width = server->getPixelBuffer()->width();
@@ -438,7 +417,8 @@ void VNCSConnectionST::queryConnection(const char* userName)
void VNCSConnectionST::clientInit(bool shared)
{
- lastEventTime = time(0);
+ if (rfb::Server::idleTimeout)
+ idleTimer.start(secsToMillis(rfb::Server::idleTimeout));
if (rfb::Server::alwaysShared || reverseConnection) shared = true;
if (!accessCheck(AccessNonShared)) shared = true;
if (rfb::Server::neverShared) shared = false;
@@ -457,7 +437,9 @@ void VNCSConnectionST::setPixelFormat(const PixelFormat& pf)
void VNCSConnectionST::pointerEvent(const Point& pos, int buttonMask)
{
- pointerEventTime = lastEventTime = time(0);
+ if (rfb::Server::idleTimeout)
+ idleTimer.start(secsToMillis(rfb::Server::idleTimeout));
+ pointerEventTime = time(0);
if (!accessCheck(AccessPtrEvents)) return;
if (!rfb::Server::acceptPointerEvents) return;
pointerEventPos = pos;
@@ -489,7 +471,8 @@ public:
void VNCSConnectionST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {
rdr::U32 lookup;
- lastEventTime = time(0);
+ if (rfb::Server::idleTimeout)
+ idleTimer.start(secsToMillis(rfb::Server::idleTimeout));
if (!accessCheck(AccessKeyEvents)) return;
if (!rfb::Server::acceptKeyEvents) return;
@@ -765,6 +748,9 @@ bool VNCSConnectionST::handleTimeout(Timer* t)
close(e.str());
}
+ if (t == &idleTimer)
+ close("Idle timeout");
+
return false;
}
@@ -1106,7 +1092,6 @@ void VNCSConnectionST::setLEDState(unsigned int ledstate)
void VNCSConnectionST::setSocketTimeouts()
{
int timeoutms = rfb::Server::clientWaitTimeMillis;
- soonestTimeout(&timeoutms, secsToMillis(rfb::Server::idleTimeout));
if (timeoutms == 0)
timeoutms = -1;
sock->inStream().setTimeout(timeoutms);
diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h
index 1b7d59ac..c992d145 100644
--- a/common/rfb/VNCSConnectionST.h
+++ b/common/rfb/VNCSConnectionST.h
@@ -77,11 +77,6 @@ namespace rfb {
void setLEDStateOrClose(unsigned int state);
void approveConnectionOrClose(bool accept, const char* reason);
- // checkIdleTimeout() returns the number of milliseconds left until the
- // idle timeout expires. If it has expired, the connection is closed and
- // zero is returned. Zero is also returned if there is no idle timeout.
- int checkIdleTimeout();
-
// The following methods never throw exceptions
// getComparerState() returns if this client would like the framebuffer
@@ -182,7 +177,8 @@ namespace rfb {
std::map<rdr::U32, rdr::U32> pressedKeys;
- time_t lastEventTime;
+ Timer idleTimer;
+
time_t pointerEventTime;
Point pointerEventPos;
bool clientHasCursor;
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index 038da3dc..40580b16 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;
@@ -215,89 +224,6 @@ void VNCServerST::processSocketWriteEvent(network::Socket* sock)
throw rdr::Exception("invalid Socket in VNCServerST");
}
-int VNCServerST::checkTimeouts()
-{
- int timeout = 0;
- std::list<VNCSConnectionST*>::iterator ci, ci_next;
-
- soonestTimeout(&timeout, Timer::checkTimeouts());
-
- for (ci=clients.begin();ci!=clients.end();ci=ci_next) {
- 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;
-}
-
-
// VNCServer methods
void VNCServerST::blockUpdates()
@@ -495,7 +421,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 +440,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 +556,15 @@ bool VNCServerST::handleTimeout(Timer* t)
}
return true;
+ } else if (t == &idleTimer) {
+ slog.info("MaxIdleTime reached, exiting");
+ desktop->terminate();
+ } else if (t == &disconnectTimer) {
+ slog.info("MaxDisconnectionTime reached, exiting");
+ desktop->terminate();
+ } else if (t == &connectTimer) {
+ slog.info("MaxConnectionTime reached, exiting");
+ desktop->terminate();
}
return false;
diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h
index 545b9a49..43a3bb95 100644
--- a/common/rfb/VNCServerST.h
+++ b/common/rfb/VNCServerST.h
@@ -76,12 +76,6 @@ namespace rfb {
// Flush pending data from the Socket on to the network.
virtual void processSocketWriteEvent(network::Socket* sock);
- // checkTimeouts
- // Returns the number of milliseconds left until the next idle timeout
- // expires. If any have already expired, the corresponding connections
- // are closed. Zero is returned if there is no idle timeout.
- virtual int checkTimeouts();
-
// Methods overridden from VNCServer
@@ -198,9 +192,9 @@ namespace rfb {
KeyRemapper* keyRemapper;
- time_t lastUserInputTime;
- time_t lastDisconnectTime;
- time_t lastConnectionTime;
+ Timer idleTimer;
+ Timer disconnectTimer;
+ Timer connectTimer;
Timer frameTimer;
};