use s2n_quic_core::{
event, random,
recovery::{
bandwidth::Bandwidth, bbr::BbrCongestionController, congestion_controller::Publisher,
CongestionController, RttEstimator,
},
time::{timer, Timestamp},
};
pub type PacketInfo = <BbrCongestionController as CongestionController>::PacketInfo;
#[derive(Clone, Debug)]
pub struct Controller {
controller: BbrCongestionController,
}
impl Controller {
#[inline]
pub fn new(max_datagram_size: u16) -> Self {
Self {
controller: BbrCongestionController::new(max_datagram_size, Default::default()),
}
}
#[inline]
pub fn on_packet_sent(
&mut self,
time_sent: Timestamp,
sent_bytes: u16,
has_more_app_data: bool,
rtt_estimator: &RttEstimator,
) -> PacketInfo {
let sent_bytes = sent_bytes as usize;
let app_limited = Some(!has_more_app_data);
let publisher = &mut NoopPublisher;
self.controller
.on_packet_sent(time_sent, sent_bytes, app_limited, rtt_estimator, publisher)
}
#[inline]
pub fn on_packet_ack(
&mut self,
newest_acked_time_sent: Timestamp,
bytes_acked: usize,
newest_acked_packet_info: PacketInfo,
rtt_estimator: &RttEstimator,
random_generator: &mut dyn random::Generator,
ack_receive_time: Timestamp,
) {
let publisher = &mut NoopPublisher;
self.controller.on_ack(
newest_acked_time_sent,
bytes_acked,
newest_acked_packet_info,
rtt_estimator,
random_generator,
ack_receive_time,
publisher,
)
}
#[inline]
pub fn on_explicit_congestion(&mut self, ce_count: u64, now: Timestamp) {
let publisher = &mut NoopPublisher;
self.controller
.on_explicit_congestion(ce_count, now, publisher);
}
#[inline]
pub fn on_packet_lost(
&mut self,
bytes_lost: u32,
packet_info: PacketInfo,
random_generator: &mut dyn random::Generator,
now: Timestamp,
) {
let persistent_congestion = false;
let new_loss_burst = false;
let publisher = &mut NoopPublisher;
self.controller.on_packet_lost(
bytes_lost,
packet_info,
persistent_congestion,
new_loss_burst,
random_generator,
now,
publisher,
);
}
#[inline]
pub fn is_congestion_limited(&self) -> bool {
self.controller.is_congestion_limited()
}
#[inline]
pub fn requires_fast_retransmission(&self) -> bool {
self.controller.requires_fast_retransmission()
}
#[inline]
pub fn congestion_window(&self) -> u32 {
self.controller.congestion_window()
}
#[inline]
pub fn bytes_in_flight(&self) -> u32 {
self.controller.bytes_in_flight()
}
#[inline]
pub fn send_quantum(&self) -> usize {
self.controller.send_quantum().unwrap_or(usize::MAX)
}
#[inline]
pub fn earliest_departure_time(&self) -> Option<Timestamp> {
self.controller.earliest_departure_time()
}
#[inline]
pub fn bandwidth(&self) -> Bandwidth {
self.controller.pacing_rate()
}
}
impl timer::Provider for Controller {
#[inline]
fn timers<Q: timer::Query>(&self, query: &mut Q) -> timer::Result {
if let Some(time) = self.earliest_departure_time() {
let mut timer = timer::Timer::default();
timer.set(time);
query.on_timer(&timer)?;
}
Ok(())
}
}
struct NoopPublisher;
impl Publisher for NoopPublisher {
#[inline]
fn on_slow_start_exited(
&mut self,
_cause: event::builder::SlowStartExitCause,
_congestion_window: u32,
) {
}
#[inline]
fn on_delivery_rate_sampled(
&mut self,
_rate_sample: s2n_quic_core::recovery::bandwidth::RateSample,
) {
}
#[inline]
fn on_pacing_rate_updated(
&mut self,
_pacing_rate: s2n_quic_core::recovery::bandwidth::Bandwidth,
_burst_size: u32,
_pacing_gain: num_rational::Ratio<u64>,
) {
}
#[inline]
fn on_bbr_state_changed(&mut self, _state: event::builder::BbrState) {
}
}