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
//! Endpoint and transport configuration.
use crate::crypto::CryptoProvider;
use crate::packet::VERSION_1;
use std::sync::Arc;
use std::time::Duration;
/// Per-connection transport settings (sent as transport parameters where applicable).
#[derive(Clone, Debug)]
pub struct TransportConfig {
pub max_idle_timeout: Duration,
/// Largest UDP payload we accept (transport parameter `max_udp_payload_size`).
pub max_udp_payload_size: u64,
/// Largest datagram we try to send; reached by PMTU probing from 1200 bytes.
pub max_datagram_size: usize,
/// Probe for a larger path MTU after the handshake (RFC 9000 §14.3).
pub mtu_probing: bool,
pub max_data: u64,
pub stream_window_bidi_local: u64,
pub stream_window_bidi_remote: u64,
pub stream_window_uni: u64,
pub max_streams_bidi: u64,
pub max_streams_uni: u64,
/// Unacknowledged bytes buffered per send stream.
pub send_buffer: u64,
pub ack_delay_exponent: u64,
pub max_ack_delay: Duration,
/// Connection IDs we accept from the peer.
pub active_connection_id_limit: u64,
/// Connection IDs we issue at most (capped by the peer's limit).
pub max_local_cids: u64,
pub disable_active_migration: bool,
/// Out-of-order CRYPTO bytes buffered per level (RFC 9000 §7.5).
pub crypto_buffer: usize,
/// ACK ranges tracked and sent.
pub max_ack_ranges: usize,
pub pacing: bool,
/// Packets per key phase before a key update; `None` uses the AEAD limit.
pub key_update_interval: Option<u64>,
/// Ack-eliciting packets received before an ACK is sent immediately.
pub ack_eliciting_threshold: u32,
}
impl Default for TransportConfig {
fn default() -> Self {
TransportConfig {
max_idle_timeout: Duration::from_secs(30),
max_udp_payload_size: 1472,
max_datagram_size: 1452,
mtu_probing: true,
max_data: 4 << 20,
stream_window_bidi_local: 1 << 20,
stream_window_bidi_remote: 1 << 20,
stream_window_uni: 256 << 10,
max_streams_bidi: 100,
max_streams_uni: 16,
send_buffer: 1 << 20,
ack_delay_exponent: 3,
max_ack_delay: Duration::from_millis(25),
active_connection_id_limit: 4,
max_local_cids: 4,
disable_active_migration: false,
crypto_buffer: 64 << 10,
max_ack_ranges: 32,
pacing: true,
key_update_interval: None,
ack_eliciting_threshold: 2,
}
}
}
/// Endpoint-wide configuration shared by its connections.
pub struct Config {
pub provider: Arc<dyn CryptoProvider>,
pub transport: TransportConfig,
/// Key for stateless reset tokens (HMAC of the connection ID).
pub reset_key: [u8; 32],
/// Key for Retry and NEW_TOKEN address-validation tokens.
pub token_key: [u8; 32],
/// Versions accepted by a server, preferred first. A client uses the first.
pub versions: Vec<u32>,
/// Server: always validate addresses with Retry.
pub retry: bool,
/// Server: send Retry once this many connections are in the handshake.
pub retry_threshold: usize,
/// Lifetime of Retry tokens.
pub retry_token_lifetime: Duration,
/// Server: issue NEW_TOKEN after the handshake; lifetime of those tokens.
pub new_token_lifetime: Option<Duration>,
/// Length of the connection IDs this endpoint issues (4..=20).
pub cid_len: usize,
/// Server: most connections kept at once.
pub max_connections: usize,
/// Time base for token ages, set by the first time value the endpoint sees.
pub epoch: std::sync::OnceLock<std::time::Instant>,
}
impl Config {
/// A configuration with random keys from the provider and default settings.
pub fn new(provider: Arc<dyn CryptoProvider>) -> Self {
let mut reset_key = [0u8; 32];
let mut token_key = [0u8; 32];
provider.fill_random(&mut reset_key);
provider.fill_random(&mut token_key);
Config {
provider,
transport: TransportConfig::default(),
reset_key,
token_key,
versions: vec![VERSION_1],
retry: false,
retry_threshold: 1000,
retry_token_lifetime: Duration::from_secs(10),
new_token_lifetime: None,
cid_len: 8,
max_connections: 100_000,
epoch: std::sync::OnceLock::new(),
}
}
/// The stateless reset token for a connection ID (RFC 9000 §10.3.2).
pub fn reset_token(&self, cid: &[u8]) -> [u8; 16] {
let h = self.provider.hmac(&self.reset_key, &[b"reset", cid]);
h[..16].try_into().unwrap()
}
}