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;