use std::time::Duration;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum H3Congestion {
#[default]
Cubic,
NewReno,
Bbr,
}
#[derive(Debug, Clone)]
pub struct ServerConfig {
pub drain_timeout: Duration,
pub header_read_timeout: Option<Duration>,
pub keep_alive: bool,
pub keep_alive_timeout: Option<Duration>,
pub h2_max_concurrent_streams: u32,
pub h2_max_header_list_size: u32,
pub h2_max_send_buf_size: usize,
pub h2_max_pending_accept_reset_streams: usize,
pub h2_keep_alive_interval: Option<Duration>,
pub h3_max_concurrent_bidi_streams: u32,
pub h3_max_concurrent_uni_streams: u32,
pub h3_max_idle_timeout: Option<Duration>,
pub h3_congestion: H3Congestion,
pub h3_enable_datagrams: bool,
pub h3_use_retry: bool,
pub h3_goaway_grace: Duration,
pub max_connections: Option<usize>,
pub proxy_read_timeout: Duration,
pub tls_handshake_timeout: Duration,
pub accept_backoff: AcceptBackoff,
}
impl Default for ServerConfig {
fn default() -> Self {
Self {
drain_timeout: Duration::from_secs(30),
header_read_timeout: Some(Duration::from_secs(30)),
keep_alive: true,
keep_alive_timeout: None,
h2_max_concurrent_streams: 100,
h2_max_header_list_size: 16 * 1024,
h2_max_send_buf_size: 1024 * 1024,
h2_max_pending_accept_reset_streams: 50,
h2_keep_alive_interval: None,
h3_max_concurrent_bidi_streams: 100,
h3_max_concurrent_uni_streams: 8,
h3_max_idle_timeout: Some(Duration::from_secs(30)),
h3_congestion: H3Congestion::default(),
h3_enable_datagrams: false,
h3_use_retry: false,
h3_goaway_grace: Duration::from_secs(10),
max_connections: None,
proxy_read_timeout: Duration::from_secs(10),
tls_handshake_timeout: Duration::from_secs(10),
accept_backoff: AcceptBackoff::new(),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct AcceptBackoff {
current: Duration,
max: Duration,
}
impl Default for AcceptBackoff {
fn default() -> Self {
Self::new()
}
}
impl AcceptBackoff {
#[must_use]
pub const fn new() -> Self {
Self {
current: Duration::from_millis(5),
max: Duration::from_secs(1),
}
}
#[inline]
pub fn reset(&mut self) {
self.current = Duration::from_millis(5);
}
pub async fn sleep_and_grow(&mut self) {
let d = self.current_and_grow();
tokio::time::sleep(d).await;
}
pub fn current_and_grow(&mut self) -> Duration {
let d = self.current;
self.current = (self.current * 2).min(self.max);
d
}
}