mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-17 01:04:51 +02:00
Connetion record stats/factored send for control packets
This commit is contained in:
parent
05421aaf8a
commit
5236abe561
2 changed files with 84 additions and 74 deletions
|
@ -65,30 +65,12 @@ void Connection::sync() {
|
|||
auto now = high_resolution_clock::now();
|
||||
|
||||
if (duration_cast<microseconds>(now - _lastNAKTime).count() >= _nakInterval) {
|
||||
// construct a NAK packet that will hold all of the lost sequence numbers
|
||||
auto lossListPacket = ControlPacket::create(ControlPacket::TimeoutNAK, _lossList.getLength() * sizeof(SequenceNumber));
|
||||
|
||||
// Pack in the lost sequence numbers
|
||||
_lossList.write(*lossListPacket);
|
||||
|
||||
// have our SendQueue send off this control packet
|
||||
_sendQueue->sendPacket(*lossListPacket);
|
||||
|
||||
// record this as the last NAK time
|
||||
_lastNAKTime = high_resolution_clock::now();
|
||||
|
||||
++_totalSentTimeoutNAKs;
|
||||
// Send a timeout NAK packet
|
||||
sendTimeoutNAK();
|
||||
}
|
||||
}
|
||||
|
||||
void Connection::sendACK(bool wasCausedBySyncTimeout) {
|
||||
static const int ACK_PACKET_PAYLOAD_BYTES = sizeof(_lastSentACK) + sizeof(_currentACKSubSequenceNumber)
|
||||
+ sizeof(_rtt) + sizeof(int32_t) + sizeof(int32_t);
|
||||
|
||||
// setup the ACK packet, make it static so we can re-use it
|
||||
static auto ackPacket = ControlPacket::create(ControlPacket::ACK, ACK_PACKET_PAYLOAD_BYTES);
|
||||
ackPacket->reset(); // We need to reset it every time.
|
||||
|
||||
auto currentTime = high_resolution_clock::now();
|
||||
static high_resolution_clock::time_point lastACKSendTime;
|
||||
|
||||
|
@ -117,6 +99,12 @@ void Connection::sendACK(bool wasCausedBySyncTimeout) {
|
|||
}
|
||||
}
|
||||
|
||||
// setup the ACK packet, make it static so we can re-use it
|
||||
static const int ACK_PACKET_PAYLOAD_BYTES = sizeof(_lastSentACK) + sizeof(_currentACKSubSequenceNumber)
|
||||
+ sizeof(_rtt) + sizeof(int32_t) + sizeof(int32_t);
|
||||
static auto ackPacket = ControlPacket::create(ControlPacket::ACK, ACK_PACKET_PAYLOAD_BYTES);
|
||||
ackPacket->reset(); // We need to reset it every time.
|
||||
|
||||
// pack in the ACK sub-sequence number
|
||||
ackPacket->writePrimitive(_currentACKSubSequenceNumber++);
|
||||
|
||||
|
@ -146,14 +134,10 @@ void Connection::sendACK(bool wasCausedBySyncTimeout) {
|
|||
// reset the number of data packets received since last ACK
|
||||
_packetsSinceACK = 0;
|
||||
|
||||
++_totalSentACKs;
|
||||
_stats.recordSentACK();
|
||||
}
|
||||
|
||||
void Connection::sendLightACK() {
|
||||
// create the light ACK packet, make it static so we can re-use it
|
||||
static const int LIGHT_ACK_PACKET_PAYLOAD_BYTES = sizeof(SequenceNumber);
|
||||
static auto lightACKPacket = ControlPacket::create(ControlPacket::ACK, LIGHT_ACK_PACKET_PAYLOAD_BYTES);
|
||||
|
||||
SequenceNumber nextACKNumber = nextACK();
|
||||
|
||||
if (nextACKNumber == _lastReceivedAcknowledgedACK) {
|
||||
|
@ -161,6 +145,10 @@ void Connection::sendLightACK() {
|
|||
return;
|
||||
}
|
||||
|
||||
// create the light ACK packet, make it static so we can re-use it
|
||||
static const int LIGHT_ACK_PACKET_PAYLOAD_BYTES = sizeof(SequenceNumber);
|
||||
static auto lightACKPacket = ControlPacket::create(ControlPacket::ACK, LIGHT_ACK_PACKET_PAYLOAD_BYTES);
|
||||
|
||||
// reset the lightACKPacket before we go to write the ACK to it
|
||||
lightACKPacket->reset();
|
||||
|
||||
|
@ -170,7 +158,62 @@ void Connection::sendLightACK() {
|
|||
// have the send queue send off our packet immediately
|
||||
_sendQueue->sendPacket(*lightACKPacket);
|
||||
|
||||
++_totalSentLightACKs;
|
||||
_stats.recordSentLightACK();
|
||||
}
|
||||
|
||||
void Connection::sendACK2(SequenceNumber currentACKSubSequenceNumber) {
|
||||
// setup a static ACK2 packet we will re-use
|
||||
static const int ACK2_PAYLOAD_BYTES = sizeof(SequenceNumber);
|
||||
static auto ack2Packet = ControlPacket::create(ControlPacket::ACK2, ACK2_PAYLOAD_BYTES);
|
||||
|
||||
// reset the ACK2 Packet before writing the sub-sequence number to it
|
||||
ack2Packet->reset();
|
||||
|
||||
// write the sub sequence number for this ACK2
|
||||
ack2Packet->writePrimitive(currentACKSubSequenceNumber);
|
||||
|
||||
// update the last sent ACK2 and the last ACK2 send time
|
||||
_lastSentACK2 = currentACKSubSequenceNumber;
|
||||
|
||||
_stats.recordSentACK2();
|
||||
}
|
||||
|
||||
void Connection::sendNAK(SequenceNumber sequenceNumberRecieved) {
|
||||
// create the loss report packet, make it static so we can re-use it
|
||||
static const int NAK_PACKET_PAYLOAD_BYTES = 2 * sizeof(SequenceNumber);
|
||||
static auto lossReport = ControlPacket::create(ControlPacket::NAK, NAK_PACKET_PAYLOAD_BYTES);
|
||||
lossReport->reset(); // We need to reset it every time.
|
||||
|
||||
// pack in the loss report
|
||||
lossReport->writePrimitive(_lastReceivedSequenceNumber + 1);
|
||||
if (_lastReceivedSequenceNumber + 1 != sequenceNumberRecieved - 1) {
|
||||
lossReport->writePrimitive(sequenceNumberRecieved - 1);
|
||||
}
|
||||
|
||||
// have the send queue send off our packet immediately
|
||||
_sendQueue->sendPacket(*lossReport);
|
||||
|
||||
// record our last NAK time
|
||||
_lastNAKTime = high_resolution_clock::now();
|
||||
|
||||
_stats.recordSentNAK();
|
||||
}
|
||||
|
||||
void Connection::sendTimeoutNAK() {
|
||||
// construct a NAK packet that will hold all of the lost sequence numbers
|
||||
// TODO size is wrong, fix it.
|
||||
auto lossListPacket = ControlPacket::create(ControlPacket::TimeoutNAK, _lossList.getLength() * sizeof(SequenceNumber));
|
||||
|
||||
// Pack in the lost sequence numbers
|
||||
_lossList.write(*lossListPacket);
|
||||
|
||||
// have our SendQueue send off this control packet
|
||||
_sendQueue->sendPacket(*lossListPacket);
|
||||
|
||||
// record this as the last NAK time
|
||||
_lastNAKTime = high_resolution_clock::now();
|
||||
|
||||
_stats.recordSentTimeoutNAK();
|
||||
}
|
||||
|
||||
SequenceNumber Connection::nextACK() const {
|
||||
|
@ -200,24 +243,8 @@ void Connection::processReceivedSequenceNumber(SequenceNumber seq) {
|
|||
_lossList.append(_lastReceivedSequenceNumber + 1, seq - 1);
|
||||
}
|
||||
|
||||
// create the loss report packet, make it static so we can re-use it
|
||||
static const int NAK_PACKET_PAYLOAD_BYTES = 2 * sizeof(SequenceNumber);
|
||||
static auto lossReport = ControlPacket::create(ControlPacket::NAK, NAK_PACKET_PAYLOAD_BYTES);
|
||||
lossReport->reset(); // We need to reset it every time.
|
||||
|
||||
// pack in the loss report
|
||||
lossReport->writePrimitive(_lastReceivedSequenceNumber + 1);
|
||||
if (_lastReceivedSequenceNumber + 1 != seq - 1) {
|
||||
lossReport->writePrimitive(seq - 1);
|
||||
}
|
||||
|
||||
// have the send queue send off our packet immediately
|
||||
_sendQueue->sendPacket(*lossReport);
|
||||
|
||||
// record our last NAK time
|
||||
_lastNAKTime = high_resolution_clock::now();
|
||||
|
||||
++_totalSentNAKs;
|
||||
// Send a NAK packet
|
||||
sendNAK(seq);
|
||||
|
||||
// figure out when we should send the next loss report, if we haven't heard anything back
|
||||
_nakInterval = (_rtt + 4 * _rttVariance);
|
||||
|
@ -288,21 +315,10 @@ void Connection::processACK(std::unique_ptr<ControlPacket> controlPacket) {
|
|||
microseconds sinceLastACK2 = duration_cast<microseconds>(currentTime - lastACK2SendTime);
|
||||
|
||||
if (sinceLastACK2.count() > _synInterval || currentACKSubSequenceNumber == _lastSentACK2) {
|
||||
// setup a static ACK2 packet we will re-use
|
||||
static const int ACK2_PAYLOAD_BYTES = sizeof(SequenceNumber);
|
||||
static auto ack2Packet = ControlPacket::create(ControlPacket::ACK2, ACK2_PAYLOAD_BYTES);
|
||||
// Send ACK2 packet
|
||||
sendACK2(currentACKSubSequenceNumber);
|
||||
|
||||
// reset the ACK2 Packet before writing the sub-sequence number to it
|
||||
ack2Packet->reset();
|
||||
|
||||
// write the sub sequence number for this ACK2
|
||||
ack2Packet->writePrimitive(currentACKSubSequenceNumber);
|
||||
|
||||
// update the last sent ACK2 and the last ACK2 send time
|
||||
_lastSentACK2 = currentACKSubSequenceNumber;
|
||||
lastACK2SendTime = high_resolution_clock::now();
|
||||
|
||||
++_totalSentACK2s;
|
||||
}
|
||||
|
||||
// read the ACKed sequence number
|
||||
|
@ -368,7 +384,7 @@ void Connection::processACK(std::unique_ptr<ControlPacket> controlPacket) {
|
|||
_sendQueue->setPacketSendPeriod(_congestionControl->_packetSendPeriod);
|
||||
|
||||
// update the total count of received ACKs
|
||||
++_totalReceivedACKs;
|
||||
_stats.recordReceivedACK();
|
||||
}
|
||||
|
||||
void Connection::processLightACK(std::unique_ptr<ControlPacket> controlPacket) {
|
||||
|
@ -385,7 +401,7 @@ void Connection::processLightACK(std::unique_ptr<ControlPacket> controlPacket) {
|
|||
_lastReceivedACK = ack;
|
||||
}
|
||||
|
||||
++_totalReceivedLightACKs;
|
||||
_stats.recordReceivedLightACK();
|
||||
}
|
||||
|
||||
void Connection::processACK2(std::unique_ptr<ControlPacket> controlPacket) {
|
||||
|
@ -414,7 +430,7 @@ void Connection::processACK2(std::unique_ptr<ControlPacket> controlPacket) {
|
|||
}
|
||||
}
|
||||
|
||||
++_totalReceivedACK2s;
|
||||
_stats.recordReceivedACK2();
|
||||
}
|
||||
|
||||
void Connection::processNAK(std::unique_ptr<ControlPacket> controlPacket) {
|
||||
|
@ -436,7 +452,7 @@ void Connection::processNAK(std::unique_ptr<ControlPacket> controlPacket) {
|
|||
_congestionControl->onLoss(start, end);
|
||||
_sendQueue->setPacketSendPeriod(_congestionControl->_packetSendPeriod);
|
||||
|
||||
++_totalReceivedNAKs;
|
||||
_stats.recordReceivedNAK();
|
||||
}
|
||||
|
||||
void Connection::processTimeoutNAK(std::unique_ptr<ControlPacket> controlPacket) {
|
||||
|
@ -446,7 +462,7 @@ void Connection::processTimeoutNAK(std::unique_ptr<ControlPacket> controlPacket)
|
|||
// we don't tell the congestion control object there was loss here - this matches UDTs implementation
|
||||
// a possible improvement would be to tell it which new loss this timeout packet told us about
|
||||
|
||||
++_totalReceivedTimeoutNAKs;
|
||||
_stats.recordReceivedTimeoutNAK();
|
||||
}
|
||||
|
||||
void Connection::updateRTT(int rtt) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
#include "ConnectionStats.h"
|
||||
#include "LossList.h"
|
||||
#include "PacketTimeWindow.h"
|
||||
#include "SendQueue.h"
|
||||
|
@ -50,6 +51,9 @@ public:
|
|||
private:
|
||||
void sendACK(bool wasCausedBySyncTimeout = true);
|
||||
void sendLightACK();
|
||||
void sendACK2(SequenceNumber currentACKSubSequenceNumber);
|
||||
void sendNAK(SequenceNumber sequenceNumberRecieved);
|
||||
void sendTimeoutNAK();
|
||||
|
||||
void processACK(std::unique_ptr<ControlPacket> controlPacket);
|
||||
void processLightACK(std::unique_ptr<ControlPacket> controlPacket);
|
||||
|
@ -95,21 +99,11 @@ private:
|
|||
|
||||
std::unique_ptr<CongestionControl> _congestionControl;
|
||||
|
||||
// Control Packet stat collection
|
||||
int _totalReceivedACKs { 0 };
|
||||
int _totalSentACKs { 0 };
|
||||
int _totalSentLightACKs { 0 };
|
||||
int _totalReceivedLightACKs { 0 };
|
||||
int _totalReceivedACK2s { 0 };
|
||||
int _totalSentACK2s { 0 };
|
||||
int _totalReceivedNAKs { 0 };
|
||||
int _totalSentNAKs { 0 };
|
||||
int _totalReceivedTimeoutNAKs { 0 };
|
||||
int _totalSentTimeoutNAKs { 0 };
|
||||
|
||||
// Data packet stat collection
|
||||
int _totalReceivedDataPackets { 0 };
|
||||
int _packetsSinceACK { 0 }; // The number of packets that have been received during the current ACK interval
|
||||
|
||||
ConnectionStats _stats;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue