From afc59eea198eefbc1274f610f1347b4fee87a8a2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 27 Sep 2016 10:46:27 -0700 Subject: [PATCH] grab earliest possible receive time in socket --- libraries/networking/src/udt/BasePacket.h | 7 +++++++ libraries/networking/src/udt/CongestionControl.cpp | 2 +- libraries/networking/src/udt/CongestionControl.h | 4 ++-- libraries/networking/src/udt/Connection.cpp | 4 ++-- libraries/networking/src/udt/SendQueue.cpp | 2 +- libraries/networking/src/udt/Socket.cpp | 6 ++++++ libraries/networking/src/udt/TCPVegasCC.cpp | 9 ++++----- libraries/networking/src/udt/TCPVegasCC.h | 2 +- 8 files changed, 24 insertions(+), 12 deletions(-) diff --git a/libraries/networking/src/udt/BasePacket.h b/libraries/networking/src/udt/BasePacket.h index 33b8020d3c..d9b624b595 100644 --- a/libraries/networking/src/udt/BasePacket.h +++ b/libraries/networking/src/udt/BasePacket.h @@ -18,6 +18,8 @@ #include +#include + #include "../HifiSockAddr.h" #include "Constants.h" @@ -80,6 +82,9 @@ public: qint64 writeString(const QString& string); QString readString(); + + void setReceiveTime(p_high_resolution_clock::time_point receiveTime) { _receiveTime = receiveTime; } + p_high_resolution_clock::time_point getReceiveTime() const { return _receiveTime; } template qint64 peekPrimitive(T* data); template qint64 readPrimitive(T* data); @@ -108,6 +113,8 @@ protected: qint64 _payloadSize = 0; // How much of the payload is actually used HifiSockAddr _senderSockAddr; // sender address for packet (only used on receiving end) + + p_high_resolution_clock::time_point _receiveTime; // captures the time the packet received (only used on receiving end) }; template qint64 BasePacket::peekPrimitive(T* data) { diff --git a/libraries/networking/src/udt/CongestionControl.cpp b/libraries/networking/src/udt/CongestionControl.cpp index ee0425fc89..7ade4f004f 100644 --- a/libraries/networking/src/udt/CongestionControl.cpp +++ b/libraries/networking/src/udt/CongestionControl.cpp @@ -49,7 +49,7 @@ DefaultCC::DefaultCC() : setPacketSendPeriod(1.0); } -bool DefaultCC::onACK(SequenceNumber ackNum) { +bool DefaultCC::onACK(SequenceNumber ackNum, p_high_resolution_clock::time_point receiveTime) { double increase = 0; // Note from UDT original code: diff --git a/libraries/networking/src/udt/CongestionControl.h b/libraries/networking/src/udt/CongestionControl.h index 5183c25413..81de761632 100644 --- a/libraries/networking/src/udt/CongestionControl.h +++ b/libraries/networking/src/udt/CongestionControl.h @@ -40,7 +40,7 @@ public: void setMaxBandwidth(int maxBandwidth); virtual void init() {} - virtual bool onACK(SequenceNumber ackNum) { return false; } + virtual bool onACK(SequenceNumber ackNum, p_high_resolution_clock::time_point receiveTime) { return false; } virtual void onLoss(SequenceNumber rangeStart, SequenceNumber rangeEnd) {} virtual void onTimeout() {} @@ -107,7 +107,7 @@ public: DefaultCC(); public: - virtual bool onACK(SequenceNumber ackNum) override; + virtual bool onACK(SequenceNumber ackNum, p_high_resolution_clock::time_point receiveTime) override; virtual void onLoss(SequenceNumber rangeStart, SequenceNumber rangeEnd) override; virtual void onTimeout() override; diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index c3dc7dd68a..764511408c 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -690,8 +690,8 @@ void Connection::processACK(ControlPacketPointer controlPacket) { } // give this ACK to the congestion control and update the send queue parameters - updateCongestionControlAndSendQueue([this, ack](){ - if (_congestionControl->onACK(ack)) { + updateCongestionControlAndSendQueue([this, ack, &controlPacket](){ + if (_congestionControl->onACK(ack, controlPacket->getReceiveTime())) { // the congestion control has told us it needs a fast re-transmit of ack + 1, add that now _sendQueue->fastRetransmit(ack + 1); } diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index f36167ddf2..e8f3375ba6 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -258,7 +258,7 @@ bool SendQueue::sendNewPacketAndAddToSentList(std::unique_ptr newPacket, auto payloadSize = newPacket->getPayloadSize(); auto bytesWritten = sendPacket(*newPacket); - + emit packetSent(packetSize, payloadSize, sequenceNumber, p_high_resolution_clock::now()); { diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 03a32a5fe3..01530fe94f 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -305,12 +305,16 @@ void Socket::readPendingDatagrams() { continue; } + // grab a time point we can mark as the receive time of this packet + auto receiveTime = p_high_resolution_clock::now(); + auto it = _unfilteredHandlers.find(senderSockAddr); if (it != _unfilteredHandlers.end()) { // we have a registered unfiltered handler for this HifiSockAddr - call that and return if (it->second) { auto basePacket = BasePacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr); + basePacket->setReceiveTime(receiveTime); it->second(std::move(basePacket)); } @@ -323,6 +327,7 @@ void Socket::readPendingDatagrams() { if (isControlPacket) { // setup a control packet from the data we just read auto controlPacket = ControlPacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr); + controlPacket->setReceiveTime(receiveTime); // move this control packet to the matching connection, if there is one auto connection = findOrCreateConnection(senderSockAddr); @@ -334,6 +339,7 @@ void Socket::readPendingDatagrams() { } else { // setup a Packet from the data we just read auto packet = Packet::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr); + packet->setReceiveTime(receiveTime); // call our verification operator to see if this packet is verified if (!_packetFilterOperator || _packetFilterOperator(*packet)) { diff --git a/libraries/networking/src/udt/TCPVegasCC.cpp b/libraries/networking/src/udt/TCPVegasCC.cpp index cbec63765a..d3da7e6886 100644 --- a/libraries/networking/src/udt/TCPVegasCC.cpp +++ b/libraries/networking/src/udt/TCPVegasCC.cpp @@ -24,14 +24,13 @@ TCPVegasCC::TCPVegasCC() { setAckInterval(1); // TCP sends an ACK for every packet received } -bool TCPVegasCC::onACK(SequenceNumber ack) { +bool TCPVegasCC::onACK(SequenceNumber ack, p_high_resolution_clock::time_point receiveTime) { auto it = _sentPacketTimes.find(ack); if (it != _sentPacketTimes.end()) { - // calculate the RTT (time now - time ACK sent) - auto now = p_high_resolution_clock::now(); - int lastRTT = duration_cast(now - it->second.first).count(); + // calculate the RTT (receive time - time ACK sent) + int lastRTT = duration_cast(receiveTime - it->second.first).count(); if (lastRTT < 0) { Q_ASSERT_X(false, "TCPVegasCC::onACK", "calculated an RTT that is not > 0"); @@ -61,7 +60,7 @@ bool TCPVegasCC::onACK(SequenceNumber ack) { // find the min RTT during the last RTT _currentMinRTT = std::min(_currentMinRTT, lastRTT); - auto sinceLastAdjustment = duration_cast(now - _lastAdjustmentTime).count(); + auto sinceLastAdjustment = duration_cast(p_high_resolution_clock::now() - _lastAdjustmentTime).count(); if (sinceLastAdjustment >= _ewmaRTT) { performCongestionAvoidance(ack); } diff --git a/libraries/networking/src/udt/TCPVegasCC.h b/libraries/networking/src/udt/TCPVegasCC.h index c13d590095..7dffc18702 100644 --- a/libraries/networking/src/udt/TCPVegasCC.h +++ b/libraries/networking/src/udt/TCPVegasCC.h @@ -27,7 +27,7 @@ public: TCPVegasCC(); public: - virtual bool onACK(SequenceNumber ackNum) override; + virtual bool onACK(SequenceNumber ackNum, p_high_resolution_clock::time_point receiveTime) override; virtual void onLoss(SequenceNumber rangeStart, SequenceNumber rangeEnd) override {}; virtual void onTimeout() override {};