Use a queue for congestion pings
This reduces the data sent, and avoids any problems with the
client corrupting it.
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index d2206f9..ef49a28 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -72,7 +72,7 @@
fenceDataLen(0), fenceData(NULL),
baseRTT(-1), congWindow(0), ackedOffset(0), sentOffset(0),
minRTT(-1), seenCongestion(false),
- pingCounter(0), congestionTimer(this),
+ congestionTimer(this),
server(server_), updates(false),
updateRenderedCursor(false), removeRenderedCursor(false),
continuousUpdates(false), encodeManager(this), pointerEventTime(0),
@@ -659,6 +659,8 @@
void VNCSConnectionST::fence(rdr::U32 flags, unsigned len, const char data[])
{
+ rdr::U8 type;
+
if (flags & fenceFlagRequest) {
if (flags & fenceFlagSyncNext) {
pendingSyncFence = true;
@@ -682,18 +684,20 @@
return;
}
- struct RTTInfo rttInfo;
+ if (len < 1)
+ vlog.error("Fence response of unexpected size received");
- switch (len) {
+ type = data[0];
+
+ switch (type) {
case 0:
// Initial dummy fence;
break;
- case sizeof(struct RTTInfo):
- memcpy(&rttInfo, data, sizeof(struct RTTInfo));
- handleRTTPong(rttInfo);
+ case 1:
+ handleRTTPong();
break;
default:
- vlog.error("Fence response of unexpected size received");
+ vlog.error("Fence response of unexpected type received");
}
}
@@ -734,7 +738,8 @@
void VNCSConnectionST::supportsFence()
{
- writer()->writeFence(fenceFlagRequest, 0, NULL);
+ char type = 0;
+ writer()->writeFence(fenceFlagRequest, sizeof(type), &type);
}
void VNCSConnectionST::supportsContinuousUpdates()
@@ -768,6 +773,7 @@
void VNCSConnectionST::writeRTTPing()
{
struct RTTInfo rttInfo;
+ char type;
if (!cp.supportsFence)
return;
@@ -778,13 +784,14 @@
rttInfo.offset = sock->outStream().length();
rttInfo.inFlight = rttInfo.offset - ackedOffset;
+ pings.push_back(rttInfo);
+
// 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.
+ type = 1;
writer()->writeFence(fenceFlagRequest | fenceFlagBlockBefore,
- sizeof(struct RTTInfo), (const char*)&rttInfo);
-
- pingCounter++;
+ sizeof(type), &type);
sentOffset = rttInfo.offset;
@@ -793,11 +800,16 @@
congestionTimer.start(__rfbmin(baseRTT * 2, 100));
}
-void VNCSConnectionST::handleRTTPong(const struct RTTInfo &rttInfo)
+void VNCSConnectionST::handleRTTPong()
{
+ struct RTTInfo rttInfo;
unsigned rtt, delay;
- pingCounter--;
+ if (pings.empty())
+ return;
+
+ rttInfo = pings.front();
+ pings.pop_front();
rtt = msSince(&rttInfo.tv);
if (rtt < 1)
@@ -881,7 +893,7 @@
// This could further clog up the tubes, but congestion control isn't
// really working properly right now anyway as the wire would otherwise
// be idle for at least RTT/2.
- if (pingCounter == 1)
+ if (pings.size() == 1)
return false;
return true;