1#[cfg(feature = "alloc")]
4use crate::application::ServerName;
5use crate::{
6 ack,
7 event::{api::SocketAddress, IntoEvent},
8 inet, recovery, stream,
9 transport::parameters::{
10 AckDelayExponent, ActiveConnectionIdLimit, InitialFlowControlLimits, InitialMaxData,
11 InitialMaxStreamDataBidiLocal, InitialMaxStreamDataBidiRemote, InitialMaxStreamDataUni,
12 InitialMaxStreamsBidi, InitialMaxStreamsUni, InitialStreamLimits, MaxAckDelay,
13 MaxDatagramFrameSize, MaxIdleTimeout, MigrationSupport, TransportParameters,
14 },
15};
16#[cfg(feature = "alloc")]
17use bytes::Bytes;
18use core::time::Duration;
19use s2n_codec::decoder_invariant;
20
21pub use crate::transport::parameters::ValidationError;
22
23const MAX_HANDSHAKE_DURATION_DEFAULT: Duration = Duration::from_secs(10);
24
25const MAX_KEEP_ALIVE_PERIOD_DEFAULT: Duration = Duration::from_secs(30);
34
35pub const ANTI_AMPLIFICATION_MULTIPLIER: u8 = 3;
40
41pub const DEFAULT_STREAM_BATCH_SIZE: u8 = 1;
42
43#[non_exhaustive]
44#[derive(Debug)]
45pub struct ConnectionInfo<'a> {
46 pub remote_address: SocketAddress<'a>,
47}
48
49impl<'a> ConnectionInfo<'a> {
50 #[inline]
51 #[doc(hidden)]
52 pub fn new(remote_address: &'a inet::SocketAddress) -> Self {
53 Self {
54 remote_address: remote_address.into_event(),
55 }
56 }
57}
58
59#[non_exhaustive]
60#[derive(Debug)]
61#[cfg(feature = "alloc")]
62pub struct HandshakeInfo<'a> {
63 pub remote_address: SocketAddress<'a>,
64 pub server_name: Option<&'a ServerName>,
65 pub application_protocol: &'a Bytes,
66}
67
68#[cfg(feature = "alloc")]
69impl<'a> HandshakeInfo<'a> {
70 pub fn new(
71 remote_address: &'a inet::SocketAddress,
72 server_name: Option<&'a ServerName>,
73 application_protocol: &'a Bytes,
74 ) -> HandshakeInfo<'a> {
75 Self {
76 remote_address: remote_address.into_event(),
77 server_name,
78 application_protocol,
79 }
80 }
81}
82
83#[derive(Clone, Copy, Debug)]
84pub struct Limits {
85 pub(crate) max_idle_timeout: MaxIdleTimeout,
86 pub(crate) data_window: InitialMaxData,
87 pub(crate) bidirectional_local_data_window: InitialMaxStreamDataBidiLocal,
88 pub(crate) bidirectional_remote_data_window: InitialMaxStreamDataBidiRemote,
89 pub(crate) unidirectional_data_window: InitialMaxStreamDataUni,
90 pub(crate) max_open_local_bidirectional_streams: stream::limits::LocalBidirectional,
91 pub(crate) max_open_local_unidirectional_streams: stream::limits::LocalUnidirectional,
92 pub(crate) max_open_remote_bidirectional_streams: InitialMaxStreamsBidi,
93 pub(crate) max_open_remote_unidirectional_streams: InitialMaxStreamsUni,
94 pub(crate) max_ack_delay: MaxAckDelay,
95 pub(crate) ack_delay_exponent: AckDelayExponent,
96 pub(crate) max_active_connection_ids: ActiveConnectionIdLimit,
97 pub(crate) ack_elicitation_interval: u8,
98 pub(crate) ack_ranges_limit: u8,
99 pub(crate) max_send_buffer_size: stream::limits::MaxSendBufferSize,
100 pub(crate) max_handshake_duration: Duration,
101 pub(crate) max_keep_alive_period: Duration,
102 pub(crate) max_datagram_frame_size: MaxDatagramFrameSize,
103 pub(crate) initial_round_trip_time: Duration,
104 pub(crate) migration_support: MigrationSupport,
105 pub(crate) anti_amplification_multiplier: u8,
106 pub(crate) stream_batch_size: u8,
107}
108
109impl Default for Limits {
110 fn default() -> Self {
111 Self::new()
112 }
113}
114
115macro_rules! setter {
116 ($(#[doc = $doc:literal])* $name:ident, $field:ident, $inner:ty $(, |$validate_value:ident| $validation:block)?) => {
117 $(#[doc = $doc])*
118 pub fn $name(mut self, value: $inner) -> Result<Self, ValidationError> {
119 $(
120 let $validate_value = value;
121 $validation
122 )?
123 self.$field = value.try_into()?;
124 Ok(self)
125 }
126 };
127}
128
129impl Limits {
130 pub const fn new() -> Self {
131 Self {
132 max_idle_timeout: MaxIdleTimeout::RECOMMENDED,
133 data_window: InitialMaxData::RECOMMENDED,
134 bidirectional_local_data_window: InitialMaxStreamDataBidiLocal::RECOMMENDED,
135 bidirectional_remote_data_window: InitialMaxStreamDataBidiRemote::RECOMMENDED,
136 unidirectional_data_window: InitialMaxStreamDataUni::RECOMMENDED,
137 max_open_local_bidirectional_streams: stream::limits::LocalBidirectional::RECOMMENDED,
138 max_open_local_unidirectional_streams: stream::limits::LocalUnidirectional::RECOMMENDED,
139 max_open_remote_bidirectional_streams: InitialMaxStreamsBidi::RECOMMENDED,
140 max_open_remote_unidirectional_streams: InitialMaxStreamsUni::RECOMMENDED,
141 max_ack_delay: MaxAckDelay::RECOMMENDED,
142 ack_delay_exponent: AckDelayExponent::RECOMMENDED,
143 max_active_connection_ids: ActiveConnectionIdLimit::RECOMMENDED,
144 ack_elicitation_interval: ack::Settings::RECOMMENDED.ack_elicitation_interval,
145 ack_ranges_limit: ack::Settings::RECOMMENDED.ack_ranges_limit,
146 max_send_buffer_size: stream::Limits::RECOMMENDED.max_send_buffer_size,
147 max_handshake_duration: MAX_HANDSHAKE_DURATION_DEFAULT,
148 max_keep_alive_period: MAX_KEEP_ALIVE_PERIOD_DEFAULT,
149 max_datagram_frame_size: MaxDatagramFrameSize::DEFAULT,
150 initial_round_trip_time: recovery::DEFAULT_INITIAL_RTT,
151 migration_support: MigrationSupport::RECOMMENDED,
152 anti_amplification_multiplier: ANTI_AMPLIFICATION_MULTIPLIER,
153 stream_batch_size: DEFAULT_STREAM_BATCH_SIZE,
154 }
155 }
156
157 setter!(with_data_window, data_window, u64, |validate_value| {
164 decoder_invariant!(
165 validate_value <= u32::MAX.into(),
166 "data_window must be <= u32::MAX"
167 );
168 });
169 setter!(
170 with_bidirectional_local_data_window,
171 bidirectional_local_data_window,
172 u64,
173 |validate_value| {
174 decoder_invariant!(
175 validate_value <= u32::MAX.into(),
176 "bidirectional_local_data_window must be <= u32::MAX"
177 );
178 }
179 );
180 setter!(
181 with_bidirectional_remote_data_window,
182 bidirectional_remote_data_window,
183 u64,
184 |validate_value| {
185 decoder_invariant!(
186 validate_value <= u32::MAX.into(),
187 "bidirectional_remote_data_window must be <= u32::MAX"
188 );
189 }
190 );
191 setter!(
192 with_unidirectional_data_window,
193 unidirectional_data_window,
194 u64,
195 |validate_value| {
196 decoder_invariant!(
197 validate_value <= u32::MAX.into(),
198 "unidirectional_data_window must be <= u32::MAX"
199 );
200 }
201 );
202
203 setter!(with_max_idle_timeout, max_idle_timeout, Duration);
204
205 #[deprecated(
207 note = "use with_max_open_local_bidirectional_streams and with_max_open_remote_bidirectional_streams instead"
208 )]
209 pub fn with_max_open_bidirectional_streams(
210 mut self,
211 value: u64,
212 ) -> Result<Self, ValidationError> {
213 self.max_open_local_bidirectional_streams = value.try_into()?;
214 self.max_open_remote_bidirectional_streams = value.try_into()?;
215 Ok(self)
216 }
217
218 pub fn with_max_open_local_bidirectional_streams(
222 mut self,
223 value: u64,
224 ) -> Result<Self, ValidationError> {
225 self.max_open_local_bidirectional_streams = value.try_into()?;
226 Ok(self)
227 }
228
229 pub fn with_max_open_remote_bidirectional_streams(
233 mut self,
234 value: u64,
235 ) -> Result<Self, ValidationError> {
236 self.max_open_remote_bidirectional_streams = value.try_into()?;
237 Ok(self)
238 }
239
240 setter!(
241 with_max_open_local_unidirectional_streams,
242 max_open_local_unidirectional_streams,
243 u64
244 );
245 setter!(
246 with_max_open_remote_unidirectional_streams,
247 max_open_remote_unidirectional_streams,
248 u64
249 );
250 setter!(with_max_ack_delay, max_ack_delay, Duration);
251 setter!(
252 with_max_active_connection_ids,
253 max_active_connection_ids,
254 u64
255 );
256 setter!(with_stream_batch_size, stream_batch_size, u8);
257 setter!(with_ack_elicitation_interval, ack_elicitation_interval, u8);
258 setter!(with_max_ack_ranges, ack_ranges_limit, u8);
259 setter!(
260 with_max_send_buffer_size,
272 max_send_buffer_size,
273 u32
274 );
275 setter!(
276 with_max_handshake_duration,
277 max_handshake_duration,
278 Duration
279 );
280 setter!(with_max_keep_alive_period, max_keep_alive_period, Duration);
281 pub fn with_active_connection_migration(
286 mut self,
287 enabled: bool,
288 ) -> Result<Self, ValidationError> {
289 if enabled {
290 self.migration_support = MigrationSupport::Enabled
291 } else {
292 self.migration_support = MigrationSupport::Disabled
293 }
294 Ok(self)
295 }
296
297 pub fn with_initial_round_trip_time(
303 mut self,
304 value: Duration,
305 ) -> Result<Self, ValidationError> {
306 ensure!(
307 value >= recovery::MIN_RTT,
308 Err(ValidationError(
309 "provided value must be at least 1 microsecond",
310 ))
311 );
312
313 self.initial_round_trip_time = value;
314 Ok(self)
315 }
316
317 #[cfg(feature = "unstable-limits")]
318 setter!(
319 with_anti_amplification_multiplier,
325 anti_amplification_multiplier,
326 u8
327 );
328
329 #[doc(hidden)]
332 #[inline]
333 pub fn load_peer<A, B, C, D>(&mut self, peer_parameters: &TransportParameters<A, B, C, D>) {
334 self.max_idle_timeout
335 .load_peer(&peer_parameters.max_idle_timeout);
336 }
337
338 #[doc(hidden)]
339 #[inline]
340 pub const fn ack_settings(&self) -> ack::Settings {
341 ack::Settings {
342 ack_delay_exponent: self.ack_delay_exponent.as_u8(),
343 max_ack_delay: self.max_ack_delay.as_duration(),
344 ack_ranges_limit: self.ack_ranges_limit,
345 ack_elicitation_interval: self.ack_elicitation_interval,
346 }
347 }
348
349 #[doc(hidden)]
350 #[inline]
351 pub const fn initial_flow_control_limits(&self) -> InitialFlowControlLimits {
352 InitialFlowControlLimits {
353 stream_limits: self.initial_stream_limits(),
354 max_data: self.data_window.as_varint(),
355 max_open_remote_bidirectional_streams: self
356 .max_open_remote_bidirectional_streams
357 .as_varint(),
358 max_open_remote_unidirectional_streams: self
359 .max_open_remote_unidirectional_streams
360 .as_varint(),
361 }
362 }
363
364 #[doc(hidden)]
365 #[inline]
366 pub const fn initial_stream_limits(&self) -> InitialStreamLimits {
367 InitialStreamLimits {
368 max_data_bidi_local: self.bidirectional_local_data_window.as_varint(),
369 max_data_bidi_remote: self.bidirectional_remote_data_window.as_varint(),
370 max_data_uni: self.unidirectional_data_window.as_varint(),
371 }
372 }
373
374 #[doc(hidden)]
375 #[inline]
376 pub fn stream_limits(&self) -> stream::Limits {
377 stream::Limits {
378 max_send_buffer_size: self.max_send_buffer_size,
379 max_open_local_unidirectional_streams: self.max_open_local_unidirectional_streams,
380 max_open_local_bidirectional_streams: self.max_open_local_bidirectional_streams,
381 }
382 }
383
384 #[doc(hidden)]
385 #[inline]
386 pub fn max_idle_timeout(&self) -> Option<Duration> {
387 self.max_idle_timeout.as_duration()
388 }
389
390 #[doc(hidden)]
391 #[inline]
392 pub fn max_handshake_duration(&self) -> Duration {
393 self.max_handshake_duration
394 }
395
396 #[doc(hidden)]
397 #[inline]
398 pub fn max_keep_alive_period(&self) -> Duration {
399 self.max_keep_alive_period
400 }
401
402 #[doc(hidden)]
403 #[inline]
404 pub fn initial_round_trip_time(&self) -> Duration {
405 self.initial_round_trip_time
406 }
407
408 #[doc(hidden)]
409 #[inline]
410 pub fn active_migration_enabled(&self) -> bool {
411 matches!(self.migration_support, MigrationSupport::Enabled)
412 }
413
414 #[doc(hidden)]
415 #[inline]
416 pub fn anti_amplification_multiplier(&self) -> u8 {
417 self.anti_amplification_multiplier
418 }
419
420 #[doc(hidden)]
421 #[inline]
422 pub fn stream_batch_size(&self) -> u8 {
423 self.stream_batch_size
424 }
425}
426
427#[must_use]
428#[derive(Debug)]
429pub struct UpdatableLimits<'a>(&'a mut Limits);
430
431impl<'a> UpdatableLimits<'a> {
432 pub fn new(limits: &'a mut Limits) -> UpdatableLimits<'a> {
433 UpdatableLimits(limits)
434 }
435
436 pub fn with_stream_batch_size(&mut self, size: u8) {
437 self.0.stream_batch_size = size;
438 }
439}
440
441pub trait Limiter: 'static + Send {
443 fn on_connection(&mut self, info: &ConnectionInfo) -> Limits;
444
445 #[inline]
448 #[cfg(feature = "alloc")]
449 fn on_post_handshake(&mut self, info: &HandshakeInfo, limits: &mut UpdatableLimits) {
450 let _ = info;
451 let _ = limits;
452 }
453}
454
455impl Limiter for Limits {
457 fn on_connection(&mut self, _into: &ConnectionInfo) -> Limits {
458 *self
459 }
460 #[cfg(feature = "alloc")]
461 fn on_post_handshake(&mut self, _info: &HandshakeInfo, _limits: &mut UpdatableLimits) {}
462}
463
464#[cfg(test)]
465mod tests {
466 use super::*;
467
468 #[test]
470 fn limit_validation() {
471 let mut data = u32::MAX as u64 + 1;
472 let limits = Limits::default();
473 assert!(limits.with_data_window(data).is_err());
474 assert!(limits.with_bidirectional_local_data_window(data).is_err());
475 assert!(limits.with_bidirectional_remote_data_window(data).is_err());
476 assert!(limits.with_unidirectional_data_window(data).is_err());
477
478 data = u32::MAX as u64;
479 assert!(limits.with_data_window(data).is_ok());
480 assert!(limits.with_bidirectional_local_data_window(data).is_ok());
481 assert!(limits.with_bidirectional_remote_data_window(data).is_ok());
482 assert!(limits.with_unidirectional_data_window(data).is_ok());
483 }
484
485 #[test]
487 fn updatable_limits() {
488 let mut limits = Limits::default();
489 assert_eq!(limits.stream_batch_size, 1);
490 let mut updatable_limits = UpdatableLimits::new(&mut limits);
491 let new_size = 10;
492 updatable_limits.with_stream_batch_size(new_size);
493 assert_eq!(limits.stream_batch_size, new_size);
494 }
495}