reset the receiver's state on handshake

This commit is contained in:
Stephen Birarda 2015-08-25 18:01:37 -07:00
parent 82f5e2e04f
commit 0ce8e05f19
4 changed files with 63 additions and 11 deletions

View file

@ -40,8 +40,7 @@ Connection::Connection(Socket* parentSocket, HifiSockAddr destination, std::uniq
// setup default SYN, RTT and RTT Variance based on the SYN interval in CongestionControl object
_synInterval = _congestionControl->synInterval();
_rtt = _synInterval * 10;
_rttVariance = _rtt / 2;
resetRTT();
// set the initial RTT and flow window size on congestion control object
_congestionControl->setRTT(_rtt);
@ -64,6 +63,11 @@ Connection::~Connection() {
}
}
void Connection::resetRTT() {
_rtt = _synInterval * 10;
_rttVariance = _rtt / 2;
}
SendQueue& Connection::getSendQueue() {
if (!_sendQueue) {
// Lasily create send queue
@ -120,13 +124,15 @@ void Connection::sync() {
// we send out a periodic ACK every rate control interval
sendACK();
// check if we need to re-transmit a loss list
// we do this if it has been longer than the current nakInterval since we last sent
auto now = high_resolution_clock::now();
if (duration_cast<microseconds>(now - _lastNAKTime).count() >= _nakInterval) {
// Send a timeout NAK packet
sendTimeoutNAK();
if (_lossList.getLength() > 0) {
// check if we need to re-transmit a loss list
// we do this if it has been longer than the current nakInterval since we last sent
auto now = high_resolution_clock::now();
if (duration_cast<microseconds>(now - _lastNAKTime).count() >= _nakInterval) {
// Send a timeout NAK packet
sendTimeoutNAK();
}
}
}
}
@ -349,7 +355,7 @@ bool Connection::processReceivedSequenceNumber(SequenceNumber sequenceNumber, in
_nakInterval += (int) (_lossList.getLength() * (USECS_PER_SECOND / receivedPacketsPerSecond));
}
// the NAK interval is at least the _minNAKInterval but might be the estimated timeout
// the NAK interval is at least the _minNAKInterval but might be the value calculated above, if that is larger
_nakInterval = std::max(_nakInterval, _minNAKInterval);
}
@ -614,6 +620,9 @@ void Connection::processNAK(std::unique_ptr<ControlPacket> controlPacket) {
}
void Connection::processHandshake(std::unique_ptr<ControlPacket> controlPacket) {
// server sent us a handshake - we need to assume this means state should be reset
resetReceiveState();
// immediately respond with a handshake ACK
static auto handshakeACK = ControlPacket::create(ControlPacket::HandshakeACK, 0);
_parentSocket->writeBasePacket(*handshakeACK, _destination);
@ -640,6 +649,39 @@ void Connection::processTimeoutNAK(std::unique_ptr<ControlPacket> controlPacket)
_stats.record(ConnectionStats::Stats::ReceivedTimeoutNAK);
}
void Connection::resetReceiveState() {
// TODO: this should also reset any queued messages we might be processing
// reset all SequenceNumber member variables back to default
SequenceNumber defaultSequenceNumber;
_lastReceivedSequenceNumber = defaultSequenceNumber;
_lastReceivedAcknowledgedACK = defaultSequenceNumber;
_currentACKSubSequenceNumber = defaultSequenceNumber;
_lastSentACK = defaultSequenceNumber;
// clear the loss list and _lastNAKTime
_lossList.clear();
_lastNAKTime = high_resolution_clock::time_point();
// the _nakInterval need not be reset, that will happen on loss
// clear sync variables
_hasReceivedFirstPacket = false;
_acksDuringSYN = 1;
_lightACKsDuringSYN = 1;
_packetsSinceACK = 0;
// reset RTT to initial value
resetRTT();
// clear the intervals in the receive window
_receiveWindow.reset();
}
void Connection::updateRTT(int rtt) {
// This updates the RTT using exponential weighted moving average
// This is the Jacobson's forumla for RTT estimation

View file

@ -93,6 +93,9 @@ private:
void processHandshake(std::unique_ptr<ControlPacket> controlPacket);
void processHandshakeACK(std::unique_ptr<ControlPacket> controlPacket);
void resetReceiveState();
void resetRTT();
SendQueue& getSendQueue();
SequenceNumber nextACK() const;
void updateRTT(int rtt);
@ -103,7 +106,7 @@ private:
int _synInterval; // Periodical Rate Control Interval, in microseconds
int _nakInterval; // NAK timeout interval, in microseconds
int _nakInterval { -1 }; // NAK timeout interval, in microseconds, set on loss
int _minNAKInterval { 100000 }; // NAK timeout interval lower bound, default of 100ms
std::chrono::high_resolution_clock::time_point _lastNAKTime;

View file

@ -31,6 +31,11 @@ PacketTimeWindow::PacketTimeWindow(int numPacketIntervals, int numProbeIntervals
}
void PacketTimeWindow::reset() {
_packetIntervals.assign(_numPacketIntervals, DEFAULT_PACKET_INTERVAL_MICROSECONDS);
_probeIntervals.assign(_numProbeIntervals, DEFAULT_PROBE_INTERVAL_MICROSECONDS);
}
template <typename Iterator>
int median(Iterator begin, Iterator end) {
// use std::nth_element to grab the middle - for an even number of elements this is the upper middle

View file

@ -29,6 +29,8 @@ public:
int32_t getPacketReceiveSpeed() const;
int32_t getEstimatedBandwidth() const;
void reset();
private:
int _numPacketIntervals { 0 }; // the number of packet intervals to store
int _numProbeIntervals { 0 }; // the number of probe intervals to store