sctp_proto/
config.rs

1use crate::util::{AssociationIdGenerator, RandomAssociationIdGenerator};
2
3use std::fmt;
4use std::sync::Arc;
5
6/// MTU for inbound packet (from DTLS)
7pub(crate) const RECEIVE_MTU: usize = 8192;
8/// initial MTU for outgoing packets (to DTLS)
9pub(crate) const INITIAL_MTU: u32 = 1228;
10pub(crate) const INITIAL_RECV_BUF_SIZE: u32 = 1024 * 1024;
11pub(crate) const COMMON_HEADER_SIZE: u32 = 12;
12pub(crate) const DATA_CHUNK_HEADER_SIZE: u32 = 16;
13pub(crate) const DEFAULT_MAX_MESSAGE_SIZE: u32 = 65536;
14
15// Default RTO values in milliseconds (RFC 4960)
16pub(crate) const RTO_INITIAL: u64 = 3000;
17pub(crate) const RTO_MIN: u64 = 1000;
18pub(crate) const RTO_MAX: u64 = 60000;
19
20// Default max retransmit value (RFC 4960 Section 15)
21const DEFAULT_MAX_INIT_RETRANS: usize = 8;
22
23/// Config collects the arguments to create_association construction into
24/// a single structure
25#[derive(Debug)]
26pub struct TransportConfig {
27    max_receive_buffer_size: u32,
28    max_message_size: u32,
29    max_num_outbound_streams: u16,
30    max_num_inbound_streams: u16,
31
32    /// Maximum number of retransmissions for INIT chunks during handshake.
33    /// Set to `None` for unlimited retries (recommended for WebRTC).
34    /// Default: Some(8)
35    max_init_retransmits: Option<usize>,
36
37    /// Maximum number of retransmissions for DATA chunks.
38    /// Set to `None` for unlimited retries (recommended for WebRTC).
39    /// Default: None (unlimited)
40    max_data_retransmits: Option<usize>,
41
42    /// Initial retransmission timeout in milliseconds.
43    /// Default: 3000
44    rto_initial_ms: u64,
45
46    /// Minimum retransmission timeout in milliseconds.
47    /// Default: 1000
48    rto_min_ms: u64,
49
50    /// Maximum retransmission timeout in milliseconds.
51    /// Default: 60000
52    rto_max_ms: u64,
53}
54
55impl Default for TransportConfig {
56    fn default() -> Self {
57        TransportConfig {
58            max_receive_buffer_size: INITIAL_RECV_BUF_SIZE,
59            max_message_size: DEFAULT_MAX_MESSAGE_SIZE,
60            max_num_outbound_streams: u16::MAX,
61            max_num_inbound_streams: u16::MAX,
62            max_init_retransmits: Some(DEFAULT_MAX_INIT_RETRANS),
63            max_data_retransmits: None,
64            rto_initial_ms: RTO_INITIAL,
65            rto_min_ms: RTO_MIN,
66            rto_max_ms: RTO_MAX,
67        }
68    }
69}
70
71impl TransportConfig {
72    pub fn with_max_receive_buffer_size(mut self, value: u32) -> Self {
73        self.max_receive_buffer_size = value;
74        self
75    }
76
77    pub fn with_max_message_size(mut self, value: u32) -> Self {
78        self.max_message_size = value;
79        self
80    }
81
82    pub fn with_max_num_outbound_streams(mut self, value: u16) -> Self {
83        self.max_num_outbound_streams = value;
84        self
85    }
86
87    pub fn with_max_num_inbound_streams(mut self, value: u16) -> Self {
88        self.max_num_inbound_streams = value;
89        self
90    }
91
92    pub(crate) fn max_receive_buffer_size(&self) -> u32 {
93        self.max_receive_buffer_size
94    }
95
96    pub(crate) fn max_message_size(&self) -> u32 {
97        self.max_message_size
98    }
99
100    pub(crate) fn max_num_outbound_streams(&self) -> u16 {
101        self.max_num_outbound_streams
102    }
103
104    pub(crate) fn max_num_inbound_streams(&self) -> u16 {
105        self.max_num_inbound_streams
106    }
107
108    /// Set maximum INIT retransmissions. `None` means unlimited.
109    pub fn with_max_init_retransmits(mut self, value: Option<usize>) -> Self {
110        self.max_init_retransmits = value;
111        self
112    }
113
114    /// Set maximum DATA retransmissions. `None` means unlimited.
115    pub fn with_max_data_retransmits(mut self, value: Option<usize>) -> Self {
116        self.max_data_retransmits = value;
117        self
118    }
119
120    /// Set initial RTO in milliseconds.
121    pub fn with_rto_initial_ms(mut self, value: u64) -> Self {
122        self.rto_initial_ms = value;
123        self
124    }
125
126    /// Set minimum RTO in milliseconds.
127    pub fn with_rto_min_ms(mut self, value: u64) -> Self {
128        self.rto_min_ms = value;
129        self
130    }
131
132    /// Set maximum RTO in milliseconds.
133    pub fn with_rto_max_ms(mut self, value: u64) -> Self {
134        self.rto_max_ms = value;
135        self
136    }
137
138    pub(crate) fn max_init_retransmits(&self) -> Option<usize> {
139        self.max_init_retransmits
140    }
141
142    pub(crate) fn max_data_retransmits(&self) -> Option<usize> {
143        self.max_data_retransmits
144    }
145
146    pub(crate) fn rto_initial_ms(&self) -> u64 {
147        self.rto_initial_ms
148    }
149
150    pub(crate) fn rto_min_ms(&self) -> u64 {
151        self.rto_min_ms
152    }
153
154    pub(crate) fn rto_max_ms(&self) -> u64 {
155        self.rto_max_ms
156    }
157}
158
159/// Global configuration for the endpoint, affecting all associations
160///
161/// Default values should be suitable for most internet applications.
162#[derive(Clone)]
163pub struct EndpointConfig {
164    pub(crate) max_payload_size: u32,
165
166    /// AID generator factory
167    ///
168    /// Create a aid generator for local aid in Endpoint struct
169    pub(crate) aid_generator_factory:
170        Arc<dyn Fn() -> Box<dyn AssociationIdGenerator> + Send + Sync>,
171}
172
173impl Default for EndpointConfig {
174    fn default() -> Self {
175        Self::new()
176    }
177}
178
179impl EndpointConfig {
180    /// Create a default config
181    pub fn new() -> Self {
182        let aid_factory: fn() -> Box<dyn AssociationIdGenerator> =
183            || Box::<RandomAssociationIdGenerator>::default();
184        Self {
185            max_payload_size: INITIAL_MTU - (COMMON_HEADER_SIZE + DATA_CHUNK_HEADER_SIZE),
186            aid_generator_factory: Arc::new(aid_factory),
187        }
188    }
189
190    /// Supply a custom Association ID generator factory
191    ///
192    /// Called once by each `Endpoint` constructed from this configuration to obtain the AID
193    /// generator which will be used to generate the AIDs used for incoming packets on all
194    /// associations involving that  `Endpoint`. A custom AID generator allows applications to embed
195    /// information in local association IDs, e.g. to support stateless packet-level load balancers.
196    ///
197    /// `EndpointConfig::new()` applies a default random AID generator factory. This functions
198    /// accepts any customized AID generator to reset AID generator factory that implements
199    /// the `AssociationIdGenerator` trait.
200    pub fn aid_generator<F: Fn() -> Box<dyn AssociationIdGenerator> + Send + Sync + 'static>(
201        &mut self,
202        factory: F,
203    ) -> &mut Self {
204        self.aid_generator_factory = Arc::new(factory);
205        self
206    }
207
208    /// Maximum payload size accepted from peers.
209    ///
210    /// The default is suitable for typical internet applications. Applications which expect to run
211    /// on networks supporting Ethernet jumbo frames or similar should set this appropriately.
212    pub fn max_payload_size(&mut self, value: u32) -> &mut Self {
213        self.max_payload_size = value;
214        self
215    }
216
217    /// Get the current value of `max_payload_size`
218    ///
219    /// While most parameters don't need to be readable, this must be exposed to allow higher-level
220    /// layers to determine how large a receive buffer to allocate to
221    /// support an externally-defined `EndpointConfig`.
222    ///
223    /// While `get_` accessors are typically unidiomatic in Rust, we favor concision for setters,
224    /// which will be used far more heavily.
225    #[doc(hidden)]
226    pub fn get_max_payload_size(&self) -> u32 {
227        self.max_payload_size
228    }
229}
230
231impl fmt::Debug for EndpointConfig {
232    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
233        fmt.debug_struct("EndpointConfig")
234            .field("max_payload_size", &self.max_payload_size)
235            .field("aid_generator_factory", &"[ elided ]")
236            .finish()
237    }
238}
239
240/// Parameters governing incoming associations
241///
242/// Default values should be suitable for most internet applications.
243#[derive(Debug, Clone)]
244pub struct ServerConfig {
245    /// Transport configuration to use for incoming associations
246    pub transport: Arc<TransportConfig>,
247
248    /// Maximum number of concurrent associations
249    pub(crate) concurrent_associations: u32,
250}
251
252impl Default for ServerConfig {
253    fn default() -> Self {
254        ServerConfig {
255            transport: Arc::new(TransportConfig::default()),
256            concurrent_associations: 100_000,
257        }
258    }
259}
260
261impl ServerConfig {
262    /// Create a default config with a particular handshake token key
263    pub fn new() -> Self {
264        ServerConfig::default()
265    }
266}
267
268/// Configuration for outgoing associations
269///
270/// Default values should be suitable for most internet applications.
271#[derive(Debug, Clone)]
272pub struct ClientConfig {
273    /// Transport configuration to use
274    pub transport: Arc<TransportConfig>,
275}
276
277impl Default for ClientConfig {
278    fn default() -> Self {
279        ClientConfig {
280            transport: Arc::new(TransportConfig::default()),
281        }
282    }
283}
284
285impl ClientConfig {
286    /// Create a default config with a particular cryptographic config
287    pub fn new() -> Self {
288        ClientConfig::default()
289    }
290}