diff --git a/solanaceae/ngc_ft1/cubic.cpp b/solanaceae/ngc_ft1/cubic.cpp index 029f6a5..ce842e8 100644 --- a/solanaceae/ngc_ft1/cubic.cpp +++ b/solanaceae/ngc_ft1/cubic.cpp @@ -76,11 +76,21 @@ int64_t CUBIC::canSend(void) { return 0u; } - const int64_t cspace_bytes = getCWnD() - _in_flight_bytes; + const auto window = getCWnD(); + int64_t cspace_bytes = window - _in_flight_bytes; if (cspace_bytes < MAXIMUM_SEGMENT_DATA_SIZE) { return 0u; } + // also limit to max sendrate per tick, which is usually smaller than window + // this is mostly to prevent spikes on empty windows + // assuming at most 20ms tick interval + // TODO: pass down actual tick interval + const auto rate = window / getCurrentDelay(); + // we dont want this limit to fall below atleast 1 segment + const int64_t max_bytes_per_tick = std::max(rate * 0.02f + 0.5f, MAXIMUM_SEGMENT_SIZE); + cspace_bytes = std::min(cspace_bytes, max_bytes_per_tick); + // limit to whole packets int64_t cspace_pkgs = (cspace_bytes / MAXIMUM_SEGMENT_DATA_SIZE) * MAXIMUM_SEGMENT_DATA_SIZE; diff --git a/solanaceae/ngc_ft1/flow_only.cpp b/solanaceae/ngc_ft1/flow_only.cpp index cf1b76e..3f058c0 100644 --- a/solanaceae/ngc_ft1/flow_only.cpp +++ b/solanaceae/ngc_ft1/flow_only.cpp @@ -41,11 +41,17 @@ int64_t FlowOnly::canSend(void) { updateWindow(); - const int64_t fspace = _fwnd - _in_flight_bytes; + int64_t fspace = _fwnd - _in_flight_bytes; if (fspace < MAXIMUM_SEGMENT_DATA_SIZE) { return 0u; } + // also limit to max sendrate per tick, which is usually smaller than window + // this is mostly to prevent spikes on empty windows + // assuming at most 20ms tick interval + // TODO: pass down actual tick interval + fspace = std::min(fspace, max_byterate_allowed * 0.02f + 0.5f); + // limit to whole packets return (fspace / MAXIMUM_SEGMENT_DATA_SIZE) * MAXIMUM_SEGMENT_DATA_SIZE; }