noq_proto/congestion.rs
1//! Logic for controlling the rate at which data is sent
2
3use crate::connection::RttEstimator;
4use crate::{Duration, Instant};
5use std::any::Any;
6use std::sync::Arc;
7
8mod bbr3;
9mod cubic;
10mod new_reno;
11
12pub use bbr3::{Bbr3, Bbr3Config};
13pub use cubic::{Cubic, CubicConfig};
14pub use new_reno::{NewReno, NewRenoConfig};
15
16/// Common interface for different congestion controllers
17pub trait Controller: Send + Sync + std::fmt::Debug {
18 /// One or more packets were just sent
19 #[allow(unused_variables)]
20 fn on_sent(&mut self, now: Instant, bytes: u64, largest_pn: u64) {}
21
22 /// One packet was just sent
23 #[allow(unused_variables)]
24 fn on_packet_sent(&mut self, now: Instant, bytes: u16, pn: u64) {}
25
26 /// Packet deliveries were confirmed
27 ///
28 /// `app_limited` indicates whether the connection was blocked on outgoing
29 /// application data prior to receiving these acknowledgements.
30 #[allow(unused_variables)]
31 fn on_ack(
32 &mut self,
33 now: Instant,
34 sent: Instant,
35 bytes: u64,
36 pn: u64,
37 app_limited: bool,
38 rtt: &RttEstimator,
39 ) {
40 }
41
42 /// Packets are acked in batches, all with the same `now` argument. This indicates one of those
43 /// batches has completed.
44 #[allow(unused_variables)]
45 fn on_end_acks(
46 &mut self,
47 now: Instant,
48 in_flight: u64,
49 app_limited: bool,
50 largest_packet_num_acked: Option<u64>,
51 ) {
52 }
53
54 /// Packets were deemed lost or marked congested
55 ///
56 /// `in_persistent_congestion` indicates whether all packets sent within the persistent
57 /// congestion threshold period ending when the most recent packet in this batch was sent were
58 /// lost.
59 /// `lost_bytes` indicates how many bytes were lost. This value will be 0 for ECN triggers.
60 /// `largest_lost_pn` indicates the packet number of the packet with the highest packet number
61 /// in the congestion event.
62 fn on_congestion_event(
63 &mut self,
64 now: Instant,
65 sent: Instant,
66 is_persistent_congestion: bool,
67 is_ecn: bool,
68 lost_bytes: u64,
69 largest_lost_pn: u64,
70 );
71
72 /// One packet was just lost
73 #[allow(unused_variables)]
74 fn on_packet_lost(&mut self, lost_bytes: u16, pn: u64, now: Instant) {}
75
76 /// Packets were incorrectly deemed lost
77 ///
78 /// This function is called when all packets that were deemed lost (for instance because
79 /// of packet reordering) are acknowledged after the congestion event was raised.
80 fn on_spurious_congestion_event(&mut self) {}
81
82 /// The known MTU for the current network path has been updated
83 fn on_mtu_update(&mut self, new_mtu: u16);
84
85 /// The peer's ACK-frequency parameters have changed
86 ///
87 /// `ack_eliciting_threshold` is the number of ack-eliciting packets the peer may receive
88 /// before being required to send an immediate ACK (per the QUIC ACK frequency extension).
89 /// `requested_max_ack_delay` is the maximum delay we asked the peer to wait before sending
90 /// an ACK when the threshold hasn't been reached.
91 ///
92 /// Controllers can use this to refine estimates that depend on peer ACK behavior (e.g.
93 /// BBR's offload budget).
94 #[allow(unused_variables)]
95 fn on_ack_frequency_update(
96 &mut self,
97 ack_eliciting_threshold: u64,
98 requested_max_ack_delay: Duration,
99 ) {
100 }
101
102 /// Number of ack-eliciting bytes that may be in flight
103 fn window(&self) -> u64;
104
105 /// Retrieve implementation-specific metrics used to populate `qlog` traces when they are
106 /// enabled This is also used to alter the pacing of the connection with
107 /// `pacing_rate` and `send_quantum`
108 fn metrics(&self) -> ControllerMetrics {
109 ControllerMetrics {
110 congestion_window: self.window(),
111 ssthresh: None,
112 pacing_rate: None,
113 send_quantum: None,
114 }
115 }
116
117 /// Duplicate the controller's state
118 fn clone_box(&self) -> Box<dyn Controller>;
119
120 /// Initial congestion window
121 fn initial_window(&self) -> u64;
122
123 /// Returns Self for use in down-casting to extract implementation details
124 fn into_any(self: Box<Self>) -> Box<dyn Any>;
125}
126
127/// Common congestion controller metrics used both for logging purposes
128/// but also to alter the pacing of the connection with
129/// `pacing_rate` and `send_quantum`
130#[derive(Default)]
131#[non_exhaustive]
132pub struct ControllerMetrics {
133 /// Congestion window (bytes)
134 pub congestion_window: u64,
135 /// Slow start threshold (bytes)
136 pub ssthresh: Option<u64>,
137 /// Pacing rate (bytes/s)
138 pub pacing_rate: Option<u64>,
139 /// Send Quantum (bytes) used to control the size of packet bursts
140 pub send_quantum: Option<u64>,
141}
142
143/// Constructs controllers on demand
144pub trait ControllerFactory {
145 /// Construct a fresh `Controller`
146 fn build(self: Arc<Self>, now: Instant, current_mtu: u16) -> Box<dyn Controller>;
147}
148
149const BASE_DATAGRAM_SIZE: u64 = 1200;