Skip to main content

simoom_quic/
config.rs

1//! Endpoint and transport configuration.
2
3use crate::crypto::CryptoProvider;
4use crate::packet::VERSION_1;
5use std::sync::Arc;
6use std::time::Duration;
7
8/// Per-connection transport settings (sent as transport parameters where applicable).
9#[derive(Clone, Debug)]
10pub struct TransportConfig {
11    pub max_idle_timeout: Duration,
12    /// Largest UDP payload we accept (transport parameter `max_udp_payload_size`).
13    pub max_udp_payload_size: u64,
14    /// Largest datagram we try to send; reached by PMTU probing from 1200 bytes.
15    pub max_datagram_size: usize,
16    /// Probe for a larger path MTU after the handshake (RFC 9000 §14.3).
17    pub mtu_probing: bool,
18    pub max_data: u64,
19    pub stream_window_bidi_local: u64,
20    pub stream_window_bidi_remote: u64,
21    pub stream_window_uni: u64,
22    pub max_streams_bidi: u64,
23    pub max_streams_uni: u64,
24    /// Unacknowledged bytes buffered per send stream.
25    pub send_buffer: u64,
26    pub ack_delay_exponent: u64,
27    pub max_ack_delay: Duration,
28    /// Connection IDs we accept from the peer.
29    pub active_connection_id_limit: u64,
30    /// Connection IDs we issue at most (capped by the peer's limit).
31    pub max_local_cids: u64,
32    pub disable_active_migration: bool,
33    /// Out-of-order CRYPTO bytes buffered per level (RFC 9000 §7.5).
34    pub crypto_buffer: usize,
35    /// ACK ranges tracked and sent.
36    pub max_ack_ranges: usize,
37    pub pacing: bool,
38    /// Packets per key phase before a key update; `None` uses the AEAD limit.
39    pub key_update_interval: Option<u64>,
40    /// Ack-eliciting packets received before an ACK is sent immediately.
41    pub ack_eliciting_threshold: u32,
42}
43
44impl Default for TransportConfig {
45    fn default() -> Self {
46        TransportConfig {
47            max_idle_timeout: Duration::from_secs(30),
48            max_udp_payload_size: 1472,
49            max_datagram_size: 1452,
50            mtu_probing: true,
51            max_data: 4 << 20,
52            stream_window_bidi_local: 1 << 20,
53            stream_window_bidi_remote: 1 << 20,
54            stream_window_uni: 256 << 10,
55            max_streams_bidi: 100,
56            max_streams_uni: 16,
57            send_buffer: 1 << 20,
58            ack_delay_exponent: 3,
59            max_ack_delay: Duration::from_millis(25),
60            active_connection_id_limit: 4,
61            max_local_cids: 4,
62            disable_active_migration: false,
63            crypto_buffer: 64 << 10,
64            max_ack_ranges: 32,
65            pacing: true,
66            key_update_interval: None,
67            ack_eliciting_threshold: 2,
68        }
69    }
70}
71
72/// Endpoint-wide configuration shared by its connections.
73pub struct Config {
74    pub provider: Arc<dyn CryptoProvider>,
75    pub transport: TransportConfig,
76    /// Key for stateless reset tokens (HMAC of the connection ID).
77    pub reset_key: [u8; 32],
78    /// Key for Retry and NEW_TOKEN address-validation tokens.
79    pub token_key: [u8; 32],
80    /// Versions accepted by a server, preferred first. A client uses the first.
81    pub versions: Vec<u32>,
82    /// Server: always validate addresses with Retry.
83    pub retry: bool,
84    /// Server: send Retry once this many connections are in the handshake.
85    pub retry_threshold: usize,
86    /// Lifetime of Retry tokens.
87    pub retry_token_lifetime: Duration,
88    /// Server: issue NEW_TOKEN after the handshake; lifetime of those tokens.
89    pub new_token_lifetime: Option<Duration>,
90    /// Length of the connection IDs this endpoint issues (4..=20).
91    pub cid_len: usize,
92    /// Server: most connections kept at once.
93    pub max_connections: usize,
94    /// Time base for token ages, set by the first time value the endpoint sees.
95    pub epoch: std::sync::OnceLock<std::time::Instant>,
96}
97
98impl Config {
99    /// A configuration with random keys from the provider and default settings.
100    pub fn new(provider: Arc<dyn CryptoProvider>) -> Self {
101        let mut reset_key = [0u8; 32];
102        let mut token_key = [0u8; 32];
103        provider.fill_random(&mut reset_key);
104        provider.fill_random(&mut token_key);
105        Config {
106            provider,
107            transport: TransportConfig::default(),
108            reset_key,
109            token_key,
110            versions: vec![VERSION_1],
111            retry: false,
112            retry_threshold: 1000,
113            retry_token_lifetime: Duration::from_secs(10),
114            new_token_lifetime: None,
115            cid_len: 8,
116            max_connections: 100_000,
117            epoch: std::sync::OnceLock::new(),
118        }
119    }
120
121    /// The stateless reset token for a connection ID (RFC 9000 §10.3.2).
122    pub fn reset_token(&self, cid: &[u8]) -> [u8; 16] {
123        let h = self.provider.hmac(&self.reset_key, &[b"reset", cid]);
124        h[..16].try_into().unwrap()
125    }
126}