From 27aeb03a61d7fabb37b19272122fa38f7169fedf Mon Sep 17 00:00:00 2001 From: Green Sky Date: Fri, 16 Jun 2023 02:04:00 +0200 Subject: [PATCH] make max (packet) segment size configurable --- ledbat.cpp | 32 ++++++++++++++++++-------------- ledbat.hpp | 19 ++++++++++++------- ngc_ft1.cpp | 6 ++++-- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/ledbat.cpp b/ledbat.cpp index 2b53280..5f7c5d5 100644 --- a/ledbat.cpp +++ b/ledbat.cpp @@ -15,26 +15,26 @@ inline constexpr bool PLOTTING = false; -LEDBAT::LEDBAT(void) { +LEDBAT::LEDBAT(size_t maximum_segment_data_size) : MAXIMUM_SEGMENT_DATA_SIZE(maximum_segment_data_size) { _time_start_offset = clock::now(); } size_t LEDBAT::canSend(void) const { if (_in_flight.empty()) { - return 496u; + return MAXIMUM_SEGMENT_DATA_SIZE; } const int64_t cspace = _cwnd - _in_flight_bytes; - if (cspace < 496) { + if (cspace < MAXIMUM_SEGMENT_DATA_SIZE) { return 0u; } const int64_t fspace = _fwnd - _in_flight_bytes; - if (fspace < 496) { + if (fspace < MAXIMUM_SEGMENT_DATA_SIZE) { return 0u; } - size_t space = std::ceil(std::min(cspace, fspace) / 496.f) * 496.f; + size_t space = std::ceil(std::min(cspace, fspace) / MAXIMUM_SEGMENT_DATA_SIZE) * MAXIMUM_SEGMENT_DATA_SIZE; return space; } @@ -56,14 +56,15 @@ std::vector LEDBAT::getTimeouts(void) const { void LEDBAT::onSent(SeqIDType seq, size_t data_size) { - if (false) { + if (true) { for (const auto& it : _in_flight) { assert(std::get<0>(it) != seq); } } - _in_flight.push_back({seq, getTimeNow(), data_size + segment_overhead}); - _in_flight_bytes += data_size + segment_overhead; - _recently_sent_bytes += data_size + segment_overhead; + + _in_flight.push_back({seq, getTimeNow(), data_size + SEGMENT_OVERHEAD}); + _in_flight_bytes += data_size + SEGMENT_OVERHEAD; + _recently_sent_bytes += data_size + SEGMENT_OVERHEAD; } void LEDBAT::onAck(std::vector seqs) { @@ -88,7 +89,7 @@ void LEDBAT::onAck(std::vector seqs) { most_recent = std::max(most_recent, std::get<1>(*it)); _in_flight_bytes -= std::get<2>(*it); _recently_acked_data += std::get<2>(*it); - assert(_in_flight_bytes >= 0); + assert(_in_flight_bytes >= 0); // TODO: this triggers _in_flight.erase(it); } } @@ -102,6 +103,7 @@ void LEDBAT::onAck(std::vector seqs) { void LEDBAT::onLoss(SeqIDType seq, bool discard) { auto it = std::find_if(_in_flight.begin(), _in_flight.end(), [seq](const auto& v) -> bool { + assert(!std::isnan(std::get<1>(v))); return std::get<0>(v) == seq; }); @@ -122,7 +124,9 @@ void LEDBAT::onLoss(SeqIDType seq, bool discard) { if (discard) { _in_flight_bytes -= std::get<2>(*it); assert(_in_flight_bytes >= 0); + _in_flight.erase(it); } + // TODO: reset timestamp? updateWindows(); } @@ -197,9 +201,9 @@ void LEDBAT::updateWindows(void) { if (_recently_lost_data) { _cwnd = std::clamp( - //_cwnd / 2.f, - _cwnd / 1.6f, - 2.f * maximum_segment_size, + _cwnd / 2.f, + //_cwnd / 1.6f, + 2.f * MAXIMUM_SEGMENT_SIZE, _cwnd ); } else { @@ -219,7 +223,7 @@ void LEDBAT::updateWindows(void) { ), // never drop below 2 "packets" in flight - 2.f * maximum_segment_size, + 2.f * MAXIMUM_SEGMENT_SIZE, // cap rate _fwnd diff --git a/ledbat.hpp b/ledbat.hpp index 8244305..d39e2b4 100644 --- a/ledbat.hpp +++ b/ledbat.hpp @@ -18,19 +18,24 @@ struct LEDBAT { static constexpr size_t UDP_HEADER_SIZE {8}; // TODO: tcp AND IPv6 will be different - static constexpr size_t segment_overhead { + static constexpr size_t SEGMENT_OVERHEAD { 4+ // ft overhead 46+ // tox? UDP_HEADER_SIZE+ IPV4_HEADER_SIZE }; - static constexpr size_t maximum_segment_size {496 + segment_overhead}; // tox 500 - 4 from ft - static_assert(maximum_segment_size == 574); // mesured in wireshark + // TODO: make configurable, set with tox ngc lossy packet size + //const size_t MAXIMUM_SEGMENT_DATA_SIZE {1000-4}; + const size_t MAXIMUM_SEGMENT_DATA_SIZE {500-4}; + + //static constexpr size_t maximum_segment_size {496 + segment_overhead}; // tox 500 - 4 from ft + const size_t MAXIMUM_SEGMENT_SIZE {MAXIMUM_SEGMENT_DATA_SIZE + SEGMENT_OVERHEAD}; // tox 500 - 4 from ft + //static_assert(maximum_segment_size == 574); // mesured in wireshark // ledbat++ says 60ms, we might need other values if relayed - const float target_delay {0.060f}; - //const float target_delay {0.030f}; + //const float target_delay {0.060f}; + const float target_delay {0.030f}; //const float target_delay {0.120f}; // 2x if relayed? // TODO: use a factor for multiple of rtt @@ -41,7 +46,7 @@ struct LEDBAT { float max_byterate_allowed {10*1024*1024}; // 10MiB/s public: - LEDBAT(void); + LEDBAT(size_t maximum_segment_data_size); // return the current believed window in bytes of how much data can be inflight, // without overstepping the delay requirement @@ -86,7 +91,7 @@ struct LEDBAT { private: // state //float _cto {2.f}; // congestion timeout value in seconds - float _cwnd {2.f * maximum_segment_size}; // in bytes + float _cwnd {2.f * MAXIMUM_SEGMENT_SIZE}; // in bytes float _base_delay {2.f}; // lowest mesured delay in _rtt_buffer in seconds float _last_cwnd {0.f}; // timepoint of last cwnd correction diff --git a/ngc_ft1.cpp b/ngc_ft1.cpp index 588b56f..21959bd 100644 --- a/ngc_ft1.cpp +++ b/ngc_ft1.cpp @@ -119,7 +119,7 @@ struct NGC_FT1 { struct Group { struct Peer { - LEDBAT cca; + LEDBAT cca{500-4}; // TODO: replace with tox_group_max_custom_lossy_packet_length()-4 struct RecvTransfer { uint32_t file_kind; @@ -289,7 +289,9 @@ void NGC_FT1_iterate(Tox *tox, NGC_FT1* ngc_ft1_ctx, float time_delta) { //size_t chunk_size = std::min(496u, tf.file_size - tf.file_size_current); //size_t chunk_size = std::min(can_packet_size, tf.file_size - tf.file_size_current); size_t chunk_size = std::min({ - 496u, + //496u, + //996u, + peer.cca.MAXIMUM_SEGMENT_DATA_SIZE, can_packet_size, tf.file_size - tf.file_size_current });