// Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // Congestion control use std::{ fmt::{Debug, Display}, time::{Duration, Instant}, }; use enum_map::Enum; use neqo_common::qlog::Qlog; use crate::{recovery::sent, rtt::RttEstimate, stats::CongestionControlStats, Pmtud}; mod classic_cc; mod cubic; mod new_reno; pub use classic_cc::ClassicCongestionControl; #[cfg(test)] pub use classic_cc::CWND_INITIAL_PKTS; pub use cubic::Cubic; pub use new_reno::NewReno; #[derive(Clone, Copy, PartialEq, Eq, Enum, Debug)] pub enum CongestionEvent { Loss, Ecn, Spurious, } pub trait CongestionControl: Display + Debug { fn set_qlog(&mut self, qlog: Qlog); #[must_use] fn cwnd(&self) -> usize; #[must_use] fn bytes_in_flight(&self) -> usize; #[must_use] fn cwnd_avail(&self) -> usize; #[must_use] fn cwnd_min(&self) -> usize; #[cfg(test)] #[must_use] fn cwnd_initial(&self) -> usize; #[must_use] fn pmtud(&self) -> &Pmtud; #[must_use] fn pmtud_mut(&mut self) -> &mut Pmtud; fn on_packets_acked( &mut self, acked_pkts: &[sent::Packet], rtt_est: &RttEstimate, now: Instant, cc_stats: &mut CongestionControlStats, ); /// Returns true if the congestion window was reduced. fn on_packets_lost( &mut self, first_rtt_sample_time: Option, prev_largest_acked_sent: Option, pto: Duration, lost_packets: &[sent::Packet], now: Instant, cc_stats: &mut CongestionControlStats, ) -> bool; /// Returns true if the congestion window was reduced. fn on_ecn_ce_received( &mut self, largest_acked_pkt: &sent::Packet, now: Instant, cc_stats: &mut CongestionControlStats, ) -> bool; #[must_use] fn recovery_packet(&self) -> bool; fn discard(&mut self, pkt: &sent::Packet, now: Instant); fn on_packet_sent(&mut self, pkt: &sent::Packet, now: Instant); fn discard_in_flight(&mut self, now: Instant); } #[derive(Debug, Copy, Clone, Default, PartialEq, Eq, strum::EnumString, strum::VariantNames)] #[strum(ascii_case_insensitive)] pub enum CongestionControlAlgorithm { #[strum(serialize = "newreno", serialize = "reno")] NewReno, #[strum(serialize = "cubic")] #[default] Cubic, } #[cfg(test)] #[cfg_attr(coverage_nightly, coverage(off))] mod tests;