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 batches has completed.
43 #[allow(unused_variables)]
44 fn on_end_acks(
45 &mut self,
46 now: Instant,
47 in_flight: u64,
48 app_limited: bool,
49 largest_packet_num_acked: Option<u64>,
50 ) {
51 }
52
53 /// Packets were deemed lost or marked congested
54 ///
55 /// `in_persistent_congestion` indicates whether all packets sent within the persistent
56 /// congestion threshold period ending when the most recent packet in this batch was sent were
57 /// lost.
58 /// `lost_bytes` indicates how many bytes were lost. This value will be 0 for ECN triggers.
59 /// `largest_lost_pn` indicates the packet number of the packet with the highest packet number
60 /// in the congestion event.
61 fn on_congestion_event(
62 &mut self,
63 now: Instant,
64 sent: Instant,
65 is_persistent_congestion: bool,
66 is_ecn: bool,
67 lost_bytes: u64,
68 largest_lost_pn: u64,
69 );
70
71 /// One packet was just lost
72 #[allow(unused_variables)]
73 fn on_packet_lost(&mut self, lost_bytes: u16, pn: u64, now: Instant) {}
74
75 /// Packets were incorrectly deemed lost
76 ///
77 /// This function is called when all packets that were deemed lost (for instance because
78 /// of packet reordering) are acknowledged after the congestion event was raised.
79 fn on_spurious_congestion_event(&mut self) {}
80
81 /// The known MTU for the current network path has been updated
82 fn on_mtu_update(&mut self, new_mtu: u16);
83
84 /// The peer's ACK-frequency parameters have changed
85 ///
86 /// `ack_eliciting_threshold` is the number of ack-eliciting packets the peer may receive
87 /// before being required to send an immediate ACK (per the QUIC ACK frequency extension).
88 /// `requested_max_ack_delay` is the maximum delay we asked the peer to wait before sending
89 /// an ACK when the threshold hasn't been reached.
90 ///
91 /// Controllers can use this to refine estimates that depend on peer ACK behavior (e.g.
92 /// BBR's offload budget).
93 #[allow(unused_variables)]
94 fn on_ack_frequency_update(
95 &mut self,
96 ack_eliciting_threshold: u64,
97 requested_max_ack_delay: Duration,
98 ) {
99 }
100
101 /// Number of ack-eliciting bytes that may be in flight
102 fn window(&self) -> u64;
103
104 /// Retrieve implementation-specific metrics used to populate `qlog` traces when they are enabled
105 /// This is also used to alter the pacing of the connection with
106 /// `pacing_rate` and `send_quantum`
107 fn metrics(&self) -> ControllerMetrics {
108 ControllerMetrics {
109 congestion_window: self.window(),
110 ssthresh: None,
111 pacing_rate: None,
112 send_quantum: None,
113 }
114 }
115
116 /// Duplicate the controller's state
117 fn clone_box(&self) -> Box<dyn Controller>;
118
119 /// Initial congestion window
120 fn initial_window(&self) -> u64;
121
122 /// Returns Self for use in down-casting to extract implementation details
123 fn into_any(self: Box<Self>) -> Box<dyn Any>;
124}
125
126/// Common congestion controller metrics used both for logging purposes
127/// but also to alter the pacing of the connection with
128/// `pacing_rate` and `send_quantum`
129#[derive(Default)]
130#[non_exhaustive]
131pub struct ControllerMetrics {
132 /// Congestion window (bytes)
133 pub congestion_window: u64,
134 /// Slow start threshold (bytes)
135 pub ssthresh: Option<u64>,
136 /// Pacing rate (bytes/s)
137 pub pacing_rate: Option<u64>,
138 /// Send Quantum (bytes) used to control the size of packet bursts
139 pub send_quantum: Option<u64>,
140}
141
142/// Constructs controllers on demand
143pub trait ControllerFactory {
144 /// Construct a fresh `Controller`
145 fn build(self: Arc<Self>, now: Instant, current_mtu: u16) -> Box<dyn Controller>;
146}
147
148const BASE_DATAGRAM_SIZE: u64 = 1200;