iroh_quinn_proto/
congestion.rs

1//! Logic for controlling the rate at which data is sent
2
3use crate::Instant;
4use crate::connection::RttEstimator;
5use std::any::Any;
6use std::sync::Arc;
7
8mod bbr;
9mod cubic;
10mod new_reno;
11
12pub use bbr::{Bbr, BbrConfig};
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, last_packet_number: u64) {}
21
22    /// Packet deliveries were confirmed
23    ///
24    /// `app_limited` indicates whether the connection was blocked on outgoing
25    /// application data prior to receiving these acknowledgements.
26    #[allow(unused_variables)]
27    fn on_ack(
28        &mut self,
29        now: Instant,
30        sent: Instant,
31        bytes: u64,
32        app_limited: bool,
33        rtt: &RttEstimator,
34    ) {
35    }
36
37    /// Packets are acked in batches, all with the same `now` argument. This indicates one of those batches has completed.
38    #[allow(unused_variables)]
39    fn on_end_acks(
40        &mut self,
41        now: Instant,
42        in_flight: u64,
43        app_limited: bool,
44        largest_packet_num_acked: Option<u64>,
45    ) {
46    }
47
48    /// Packets were deemed lost or marked congested
49    ///
50    /// `in_persistent_congestion` indicates whether all packets sent within the persistent
51    /// congestion threshold period ending when the most recent packet in this batch was sent were
52    /// lost.
53    /// `lost_bytes` indicates how many bytes were lost. This value will be 0 for ECN triggers.
54    fn on_congestion_event(
55        &mut self,
56        now: Instant,
57        sent: Instant,
58        is_persistent_congestion: bool,
59        is_ecn: bool,
60        lost_bytes: u64,
61    );
62
63    /// Packets were incorrectly deemed lost
64    ///
65    /// This function is called when all packets that were deemed lost (for instance because
66    /// of packet reordering) are acknowledged after the congestion event was raised.
67    fn on_spurious_congestion_event(&mut self) {}
68
69    /// The known MTU for the current network path has been updated
70    fn on_mtu_update(&mut self, new_mtu: u16);
71
72    /// Number of ack-eliciting bytes that may be in flight
73    fn window(&self) -> u64;
74
75    /// Retrieve implementation-specific metrics used to populate `qlog` traces when they are enabled
76    fn metrics(&self) -> ControllerMetrics {
77        ControllerMetrics {
78            congestion_window: self.window(),
79            ssthresh: None,
80            pacing_rate: None,
81        }
82    }
83
84    /// Duplicate the controller's state
85    fn clone_box(&self) -> Box<dyn Controller>;
86
87    /// Initial congestion window
88    fn initial_window(&self) -> u64;
89
90    /// Returns Self for use in down-casting to extract implementation details
91    fn into_any(self: Box<Self>) -> Box<dyn Any>;
92}
93
94/// Common congestion controller metrics
95#[derive(Default, Debug)]
96#[non_exhaustive]
97pub struct ControllerMetrics {
98    /// Congestion window (bytes)
99    pub congestion_window: u64,
100    /// Slow start threshold (bytes)
101    pub ssthresh: Option<u64>,
102    /// Pacing rate (bits/s)
103    pub pacing_rate: Option<u64>,
104}
105
106/// Constructs controllers on demand
107pub trait ControllerFactory {
108    /// Construct a fresh `Controller`
109    fn build(self: Arc<Self>, now: Instant, current_mtu: u16) -> Box<dyn Controller>;
110}
111
112const BASE_DATAGRAM_SIZE: u64 = 1200;