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