diff --git a/solanaceae/ngc_ft1/cca.hpp b/solanaceae/ngc_ft1/cca.hpp index cee1064..8d72023 100644 --- a/solanaceae/ngc_ft1/cca.hpp +++ b/solanaceae/ngc_ft1/cca.hpp @@ -49,6 +49,8 @@ struct CCAI { // returns current rtt/delay virtual float getCurrentDelay(void) const = 0; + virtual float getWindow(void) = 0; + // TODO: api for how much data we should send // take time since last sent into account // respect max_byterate_allowed diff --git a/solanaceae/ngc_ft1/cubic.cpp b/solanaceae/ngc_ft1/cubic.cpp index 6882dba..9c1ae5f 100644 --- a/solanaceae/ngc_ft1/cubic.cpp +++ b/solanaceae/ngc_ft1/cubic.cpp @@ -37,12 +37,17 @@ void CUBIC::onCongestion(void) { const auto tmp_old_tp = getTimeNow() - _time_point_reduction; const auto current_cwnd = getCWnD(); + const auto current_wnd = getWindow(); // respects cwnd and fwnd + _time_point_reduction = getTimeNow(); - _window_max = current_cwnd * BETA; + //_window_max = current_cwnd * BETA; + _window_max = current_wnd * BETA; _window_max = std::max(_window_max, 2.*MAXIMUM_SEGMENT_SIZE); #if 1 std::cout << "----CONGESTION!" + << " cwnd:" << current_cwnd + << " wnd:" << current_wnd << " cwnd_max:" << _window_max << " pts:" << tmp_old_tp << " rtt:" << getCurrentDelay() @@ -52,6 +57,10 @@ void CUBIC::onCongestion(void) { } } +float CUBIC::getWindow(void) { + return std::min(getCWnD(), FlowOnly::getWindow()); +} + int64_t CUBIC::canSend(void) { const auto fspace_pkgs = FlowOnly::canSend(); diff --git a/solanaceae/ngc_ft1/cubic.hpp b/solanaceae/ngc_ft1/cubic.hpp index b5ee809..9f838d7 100644 --- a/solanaceae/ngc_ft1/cubic.hpp +++ b/solanaceae/ngc_ft1/cubic.hpp @@ -33,6 +33,8 @@ struct CUBIC : public FlowOnly { public: // api CUBIC(size_t maximum_segment_data_size) : FlowOnly(maximum_segment_data_size) {} + float getWindow(void) override; + // TODO: api for how much data we should send // take time since last sent into account // respect max_byterate_allowed diff --git a/solanaceae/ngc_ft1/flow_only.cpp b/solanaceae/ngc_ft1/flow_only.cpp index ef02f39..cf1b76e 100644 --- a/solanaceae/ngc_ft1/flow_only.cpp +++ b/solanaceae/ngc_ft1/flow_only.cpp @@ -28,6 +28,11 @@ void FlowOnly::updateWindow(void) { _fwnd = std::max(_fwnd, 2.f * MAXIMUM_SEGMENT_DATA_SIZE); } +float FlowOnly::getWindow(void) { + updateWindow(); + return _fwnd; +} + int64_t FlowOnly::canSend(void) { if (_in_flight.empty()) { assert(_in_flight_bytes == 0); @@ -99,11 +104,30 @@ void FlowOnly::onAck(std::vector seqs) { if (first_it != _in_flight.cend() && it != first_it) { // not next expected seq -> skip detected - std::cout << "NGC_FT1 Flow: pkg out of order\n"; _consecutive_events++; it->ignore = true; // only handle once - if (_consecutive_events > 4) { // TODO: magic number - std::cout << "CONGESTION! NGC_FT1 flow: pkg out of order\n"; + + const auto tmp_window = getWindow(); + // packet window * 0.3 + // but atleast 4 + int32_t max_consecutive_events = std::clamp( + (tmp_window/MAXIMUM_SEGMENT_DATA_SIZE) * 0.3f, + 4, + 50 // limit TODO: fix idle/time starved algo + ); + // TODO: magic number + +#if 0 + std::cout << "NGC_FT1 Flow: pkg out of order" + << " w:" << tmp_window + << " pw:" << tmp_window/MAXIMUM_SEGMENT_DATA_SIZE + << " coe:" << _consecutive_events + << " mcoe:" << max_consecutive_events + << "\n"; +#endif + + if (_consecutive_events > max_consecutive_events) { + //std::cout << "CONGESTION! NGC_FT1 flow: pkg out of order\n"; onCongestion(); } } else { diff --git a/solanaceae/ngc_ft1/flow_only.hpp b/solanaceae/ngc_ft1/flow_only.hpp index 710b115..d46ad5b 100644 --- a/solanaceae/ngc_ft1/flow_only.hpp +++ b/solanaceae/ngc_ft1/flow_only.hpp @@ -57,6 +57,8 @@ struct FlowOnly : public CCAI { // VERY sensitive to bundling acks float getCurrentDelay(void) const override; + float getWindow(void) override; + void addRTT(float new_delay); void updateWindow(void);