diff --git a/libraries/networking/src/udt/Socket.h b/libraries/networking/src/udt/Socket.h index 59c3ec9cde..3f2664daea 100644 --- a/libraries/networking/src/udt/Socket.h +++ b/libraries/networking/src/udt/Socket.h @@ -24,6 +24,7 @@ #include "../HifiSockAddr.h" #include "CongestionControl.h" #include "Connection.h" +#include "TCPRenoCC.h" //#define UDT_CONNECTION_DEBUG @@ -131,7 +132,7 @@ private: int _maxBandwidth { -1 }; - std::unique_ptr _ccFactory { new CongestionControlFactory() }; + std::unique_ptr _ccFactory { new CongestionControlFactory() }; friend UDTTest; }; diff --git a/libraries/networking/src/udt/TCPRenoCC.cpp b/libraries/networking/src/udt/TCPRenoCC.cpp new file mode 100644 index 0000000000..978b862d4a --- /dev/null +++ b/libraries/networking/src/udt/TCPRenoCC.cpp @@ -0,0 +1,84 @@ +// +// TCPRenoCC.cpp +// libraries/networking/src/udt +// +// Created by Clement on 9/20/16. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "TCPRenoCC.h" + + +using namespace udt; + +void TCPRenoCC::init() { + _slowStart = true; + _issThreshold = 83333; + + _packetSendPeriod = 0.0; + _congestionWindowSize = 2.0; + + setAckInterval(2); + setRTO(1000000); +} + +void TCPRenoCC::onACK(SequenceNumber ackNum) { + if (ackNum == _lastACK) { + if (3 == ++_duplicateAckCount) { + duplicateACKAction(); + } else if (_duplicateAckCount > 3) { + _congestionWindowSize += 1.0; + } else { + ackAction(); + } + } else { + if (_duplicateAckCount >= 3) { + _congestionWindowSize = _issThreshold; + } + + _lastACK = ackNum; + _duplicateAckCount = 1; + + ackAction(); + } +} + +void TCPRenoCC::onTimeout() { + _issThreshold = seqlen(_lastACK, _sendCurrSeqNum) / 2; + if (_issThreshold < 2) { + _issThreshold = 2; + } + + _slowStart = true; + _congestionWindowSize = 2.0; +} + +void TCPRenoCC::ackAction() { + if (_slowStart) { + _congestionWindowSize += 1.0; + + if (_congestionWindowSize >= _issThreshold) { + _slowStart = false; + } + } else { + _congestionWindowSize += 1.0 / _congestionWindowSize; + } +} + +void TCPRenoCC::duplicateACKAction() { + _slowStart = false; + + _issThreshold = seqlen(_lastACK, _sendCurrSeqNum) / 2; + if (_issThreshold < 2) { + _issThreshold = 2; + } + + _congestionWindowSize = _issThreshold + 3; +} + +void TCPRenoCC::setInitialSendSequenceNumber(SequenceNumber seqNum) { + _lastACK = seqNum - 1; +} diff --git a/libraries/networking/src/udt/TCPRenoCC.h b/libraries/networking/src/udt/TCPRenoCC.h new file mode 100644 index 0000000000..79b7b6f559 --- /dev/null +++ b/libraries/networking/src/udt/TCPRenoCC.h @@ -0,0 +1,40 @@ +// +// TCPRenoCC.h +// libraries/networking/src/udt +// +// Created by Clement on 9/20/16. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_TCPRenoCC_h +#define hifi_TCPRenoCC_h + +#include "CongestionControl.h" + +namespace udt { + +class TCPRenoCC : public CongestionControl { +public: + virtual void init(); + virtual void onACK(SequenceNumber ackNum); + virtual void onTimeout(); + +protected: + virtual void ackAction(); + virtual void duplicateACKAction(); + virtual void setInitialSendSequenceNumber(SequenceNumber seqNum); + + int _issThreshold; + bool _slowStart; + + int _duplicateAckCount; + SequenceNumber _lastACK; +}; + +} + + +#endif // hifi_TCPRenoCC_h diff --git a/tests/render-perf/src/main.cpp b/tests/render-perf/src/main.cpp index 8abb9f54e5..3df36c0edf 100644 --- a/tests/render-perf/src/main.cpp +++ b/tests/render-perf/src/main.cpp @@ -18,10 +18,12 @@ #include #include #include +#include #include #include #include + #include #include #include diff --git a/tools/udt-test/src/UDTTest.cpp b/tools/udt-test/src/UDTTest.cpp index af94d2294b..633251d6c6 100644 --- a/tools/udt-test/src/UDTTest.cpp +++ b/tools/udt-test/src/UDTTest.cpp @@ -25,7 +25,7 @@ const QCommandLineOption TARGET_OPTION { "IP:PORT or HOSTNAME:PORT" }; const QCommandLineOption PACKET_SIZE { - "packet-size", "size for sent packets in bytes (defaults to " + QString(MAX_PACKET_SIZE) + ")", "bytes", + "packet-size", "size for sent packets in bytes (defaults to " + QString(udt::MAX_PACKET_SIZE) + ")", "bytes", QString(udt::MAX_PACKET_SIZE) }; const QCommandLineOption MIN_PACKET_SIZE {