Improved congestion control handling
Refine the previous method by interpolating the values we need.
This reduces the effect of the problem that we cannot send enough
ping packets.
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 43eb825..b2ceb7d 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -43,7 +43,7 @@
: sock(s), reverseConnection(reverse),
queryConnectTimer(this), inProcessMessages(false),
pendingSyncFence(false), syncFence(false), fenceFlags(0),
- fenceDataLen(0), fenceData(NULL),
+ fenceDataLen(0), fenceData(NULL), congestionTimer(this),
server(server_), updates(false),
updateRenderedCursor(false), removeRenderedCursor(false),
continuousUpdates(false), encodeManager(this), pointerEventTime(0),
@@ -726,6 +726,8 @@
if (t == &queryConnectTimer) {
if (state() == RFBSTATE_QUERYING)
approveConnection(false, "The attempt to prompt the user to accept the connection failed");
+ } else if (t == &congestionTimer) {
+ writeFramebufferUpdate();
}
} catch (rdr::Exception& e) {
close(e.str());
@@ -742,6 +744,8 @@
if (!cp.supportsFence)
return;
+ congestion.updatePosition(sock->outStream().length());
+
// We need to make sure any old update are already processed by the
// time we get the response back. This allows us to reliably throttle
// back on client overload, as well as network overload.
@@ -749,11 +753,15 @@
writer()->writeFence(fenceFlagRequest | fenceFlagBlockBefore,
sizeof(type), &type);
- congestion.sentPing(sock->outStream().length());
+ congestion.sentPing();
}
bool VNCSConnectionST::isCongested()
{
+ unsigned eta;
+
+ congestionTimer.stop();
+
// Stuff still waiting in the send buffer?
sock->outStream().flush();
if (sock->outStream().bufferUsage() > 0)
@@ -762,13 +770,22 @@
if (!cp.supportsFence)
return false;
- return congestion.isCongested(sock->outStream().length(),
- sock->outStream().getIdleTime());
+ congestion.updatePosition(sock->outStream().length());
+ if (!congestion.isCongested())
+ return false;
+
+ eta = congestion.getUncongestedETA();
+ if (eta >= 0)
+ congestionTimer.start(eta);
+
+ return true;
}
void VNCSConnectionST::writeFramebufferUpdate()
{
+ congestion.updatePosition(sock->outStream().length());
+
// We're in the middle of processing a command that's supposed to be
// synchronised. Allowing an update to slip out right now might violate
// that synchronisation.
@@ -805,6 +822,8 @@
writeDataUpdate();
network::TcpSocket::cork(sock->getFd(), false);
+
+ congestion.updatePosition(sock->outStream().length());
}
void VNCSConnectionST::writeNoDataUpdate()