mirror of
https://github.com/n0-computer/noq.git
synced 2026-09-22 19:24:08 +00:00
fix(proto): congestion: avoid double-reducing CUBIC fast convergence
Quinn mistakenly applied the beta multiplier to the newly adjusted `W_max` instead of the current window. This double-reduced the window to 59.5% instead of the intended 70%. This fixes the math by snapshotting the original window for the multiplicative decrease.
This commit is contained in:
committed by
Diva Martínez
parent
a6042549b4
commit
4cfbafa4cf
@@ -199,18 +199,19 @@ impl Controller for Cubic {
|
||||
}
|
||||
|
||||
self.state.recovery_start_time = Some(now);
|
||||
let window = self.state.window as f64;
|
||||
|
||||
// Fast convergence
|
||||
if (self.state.window as f64) < self.state.w_max {
|
||||
self.state.w_max = self.state.window as f64 * (1.0 + BETA_CUBIC) / 2.0;
|
||||
// Fast convergence lowers W_max first; the 0.7 loss reduction still
|
||||
// applies to the old window, not to that already-reduced W_max.
|
||||
// https://www.rfc-editor.org/rfc/rfc9438.html#section-4.7
|
||||
// https://www.rfc-editor.org/rfc/rfc9438.html#section-4.6
|
||||
if window < self.state.w_max {
|
||||
self.state.w_max = window * (1.0 + BETA_CUBIC) / 2.0;
|
||||
} else {
|
||||
self.state.w_max = self.state.window as f64;
|
||||
self.state.w_max = window;
|
||||
}
|
||||
|
||||
self.state.ssthresh = cmp::max(
|
||||
(self.state.w_max * BETA_CUBIC) as u64,
|
||||
self.minimum_window(),
|
||||
);
|
||||
self.state.ssthresh = cmp::max((window * BETA_CUBIC) as u64, self.minimum_window());
|
||||
self.state.window = self.state.ssthresh;
|
||||
self.state.k = self.state.cubic_k(self.current_mtu);
|
||||
|
||||
@@ -300,3 +301,26 @@ impl ControllerFactory for CubicConfig {
|
||||
Box::new(Cubic::new(self, now, current_mtu))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn fast_convergence_reduces_w_max_without_double_reducing_window() {
|
||||
let now = Instant::now();
|
||||
let config = Arc::new(CubicConfig::default());
|
||||
let mut cubic = Cubic::new(config, now, BASE_DATAGRAM_SIZE as u16);
|
||||
let window = 8 * BASE_DATAGRAM_SIZE;
|
||||
|
||||
cubic.state.window = window;
|
||||
cubic.state.ssthresh = window;
|
||||
cubic.state.w_max = 12.0 * BASE_DATAGRAM_SIZE as f64;
|
||||
|
||||
cubic.on_congestion_event(now, now + Duration::from_millis(1), false, false, 0, 100);
|
||||
|
||||
assert_eq!(cubic.state.w_max, window as f64 * (1.0 + BETA_CUBIC) / 2.0);
|
||||
assert_eq!(cubic.state.ssthresh, (window as f64 * BETA_CUBIC) as u64);
|
||||
assert_eq!(cubic.state.window, cubic.state.ssthresh);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user