s2n_quic_core/transport/parameters/
mod.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{
5    ack, connection, endpoint, event,
6    event::IntoEvent,
7    inet::{SocketAddressV4, SocketAddressV6, Unspecified},
8    stateless_reset,
9    stream::{StreamId, StreamType},
10    varint::VarInt,
11};
12use core::{mem::size_of, time::Duration};
13use s2n_codec::{
14    decoder_invariant, decoder_value, DecoderBuffer, DecoderBufferMut, DecoderBufferMutResult,
15    DecoderBufferResult, DecoderError, DecoderValue, DecoderValueMut, Encoder, EncoderValue,
16};
17
18#[cfg(test)]
19mod tests;
20
21/// Trait for an transport parameter value
22pub trait TransportParameter: Sized {
23    /// The ID or tag for the TransportParameter
24    const ID: TransportParameterId;
25
26    /// Enables/disables the TransportParameter in a certain context
27    const ENABLED: bool = true;
28
29    /// Associated type for decoding/encoding the TransportParameter
30    type CodecValue: EncoderValue;
31
32    /// Create a `TransportParameter` from the CodecValue
33    fn from_codec_value(value: Self::CodecValue) -> Self;
34
35    /// Attempts to convert the `TransportParameter` into the `CodecValue`
36    fn try_into_codec_value(&self) -> Option<&Self::CodecValue>;
37
38    /// Returns the default value for the TransportParameter
39    /// This is used instead of `Default::default` so it is
40    /// easily overridable
41    fn default_value() -> Self;
42
43    /// Appends this `TransportParameter` to the given buffer containing
44    /// already encoded TransportParameters
45    #[cfg(feature = "alloc")]
46    fn append_to_buffer(&self, buffer: &mut alloc::vec::Vec<u8>) {
47        let original_size = buffer.len();
48        let new_parameter_size = TransportParameterCodec(self).encoding_size();
49        buffer.resize(original_size + new_parameter_size, 0);
50        let mut buffer = s2n_codec::EncoderBuffer::new(buffer);
51        buffer.set_position(original_size);
52        buffer.encode(&TransportParameterCodec(self));
53    }
54}
55
56/// Trait for validating transport parameter values
57pub trait TransportParameterValidator: Sized {
58    /// Validates that the transport parameter is in a valid state
59    fn validate(self) -> Result<Self, DecoderError> {
60        Ok(self)
61    }
62}
63
64//= https://www.rfc-editor.org/rfc/rfc9000#section-7.4.1
65//# To enable 0-RTT, endpoints store the values of the server transport
66//# parameters with any session tickets it receives on the connection.
67
68//= https://www.rfc-editor.org/rfc/rfc9000#section-7.4.1
69//# *  active_connection_id_limit
70//# *  initial_max_data
71//# *  initial_max_stream_data_bidi_local
72//# *  initial_max_stream_data_bidi_remote
73//# *  initial_max_stream_data_uni
74//# *  initial_max_streams_bidi
75//# *  initial_max_streams_uni
76
77//= https://www.rfc-editor.org/rfc/rfc9000#section-7.4.1
78//# A client MUST NOT use remembered values for the following parameters:
79//# ack_delay_exponent, max_ack_delay, initial_source_connection_id,
80//# original_destination_connection_id, preferred_address,
81//# retry_source_connection_id, and stateless_reset_token.
82
83#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
84pub struct ZeroRttParameters {
85    pub active_connection_id_limit: VarInt,
86    pub initial_max_data: VarInt,
87    pub initial_max_stream_data_bidi_local: VarInt,
88    pub initial_max_stream_data_bidi_remote: VarInt,
89    pub initial_max_stream_data_uni: VarInt,
90    pub initial_max_streams_bidi: VarInt,
91    pub initial_max_streams_uni: VarInt,
92    //= https://www.rfc-editor.org/rfc/rfc9221#section-3
93    //# When clients use 0-RTT, they MAY store the value of the server's
94    //# max_datagram_frame_size transport parameter. Doing so allows the
95    //# client to send DATAGRAM frames in 0-RTT packets.
96    pub max_datagram_frame_size: VarInt,
97}
98
99impl<
100        OriginalDestinationConnectionId,
101        StatelessResetToken,
102        PreferredAddress,
103        RetrySourceConnectionId,
104    >
105    TransportParameters<
106        OriginalDestinationConnectionId,
107        StatelessResetToken,
108        PreferredAddress,
109        RetrySourceConnectionId,
110    >
111{
112    /// Returns the ZeroRTTParameters to be saved between connections
113    pub fn zero_rtt_parameters(&self) -> ZeroRttParameters {
114        let Self {
115            active_connection_id_limit,
116            initial_max_data,
117            initial_max_stream_data_bidi_local,
118            initial_max_stream_data_bidi_remote,
119            initial_max_stream_data_uni,
120            initial_max_streams_bidi,
121            initial_max_streams_uni,
122            max_datagram_frame_size,
123            ..
124        } = self;
125        ZeroRttParameters {
126            active_connection_id_limit: **active_connection_id_limit,
127            initial_max_data: **initial_max_data,
128            initial_max_stream_data_bidi_local: **initial_max_stream_data_bidi_local,
129            initial_max_stream_data_bidi_remote: **initial_max_stream_data_bidi_remote,
130            initial_max_stream_data_uni: **initial_max_stream_data_uni,
131            initial_max_streams_bidi: **initial_max_streams_bidi,
132            initial_max_streams_uni: **initial_max_streams_uni,
133            max_datagram_frame_size: **max_datagram_frame_size,
134        }
135    }
136}
137
138//= https://www.rfc-editor.org/rfc/rfc9000#section-18
139//# The extension_data field of the quic_transport_parameters extension
140//# defined in [QUIC-TLS] contains the QUIC transport parameters.  They
141//# are encoded as a sequence of transport parameters, as shown in
142//# Figure 20:
143//#
144//# Transport Parameters {
145//#   Transport Parameter (..) ...,
146//# }
147//#
148//#              Figure 20: Sequence of Transport Parameters
149
150decoder_value!(
151    impl<'a> ClientTransportParameters {
152        fn decode(buffer: Buffer) -> Result<Self> {
153            let len = buffer.len();
154            let (slice, buffer) = buffer.decode_slice(len)?;
155            let parameters = Self::decode_parameters(slice.peek())?;
156            Ok((parameters, buffer))
157        }
158    }
159);
160
161decoder_value!(
162    impl<'a> ServerTransportParameters {
163        fn decode(buffer: Buffer) -> Result<Self> {
164            let len = buffer.len();
165            let (slice, buffer) = buffer.decode_slice(len)?;
166            let parameters = Self::decode_parameters(slice.peek())?;
167            Ok((parameters, buffer))
168        }
169    }
170);
171
172//= https://www.rfc-editor.org/rfc/rfc9000#section-18
173//# Transport Parameter {
174//#    Transport Parameter ID (i),
175//#    Transport Parameter Length (i),
176//#    Transport Parameter Value (..),
177//# }
178//#
179//# Figure 21: Transport Parameter Encoding
180//#
181//# The Transport Parameter Length field contains the length of the
182//# Transport Parameter Value field in bytes.
183//#
184//# QUIC encodes transport parameters into a sequence of bytes, which is
185//# then included in the cryptographic handshake.
186
187type TransportParameterId = VarInt;
188type TransportParameterLength = VarInt;
189
190/// Utility struct for encoding and decoding transport parameters
191struct TransportParameterCodec<T>(T);
192
193impl<'a, T: TransportParameter> DecoderValue<'a> for TransportParameterCodec<T>
194where
195    T::CodecValue: DecoderValue<'a>,
196{
197    fn decode(buffer: DecoderBuffer<'a>) -> DecoderBufferResult<'a, Self> {
198        let (value, buffer) = buffer.decode_with_len_prefix::<TransportParameterLength, _>()?;
199        Ok((Self(T::from_codec_value(value)), buffer))
200    }
201}
202
203impl<'a, T: TransportParameter> DecoderValueMut<'a> for TransportParameterCodec<T>
204where
205    T::CodecValue: DecoderValueMut<'a>,
206{
207    fn decode_mut(buffer: DecoderBufferMut<'a>) -> DecoderBufferMutResult<'a, Self> {
208        let (value, buffer) = buffer.decode_with_len_prefix::<TransportParameterLength, _>()?;
209        Ok((Self(T::from_codec_value(value)), buffer))
210    }
211}
212
213impl<T: TransportParameter> EncoderValue for TransportParameterCodec<&T>
214where
215    T::CodecValue: EncoderValue,
216{
217    fn encode<E: Encoder>(&self, buffer: &mut E) {
218        if let Some(value) = self.0.try_into_codec_value() {
219            buffer.encode(&T::ID);
220            buffer.encode_with_len_prefix::<TransportParameterLength, _>(value);
221        }
222    }
223}
224
225#[derive(Copy, Clone, Debug, PartialEq)]
226pub struct ValidationError(pub(crate) &'static str);
227
228const MAX_ENCODABLE_VALUE: ValidationError =
229    ValidationError("provided value exceeds maximum encodable value");
230
231impl core::fmt::Display for ValidationError {
232    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
233        write!(f, "{}", self.0)
234    }
235}
236
237impl From<DecoderError> for ValidationError {
238    fn from(error: DecoderError) -> Self {
239        ValidationError(error.into())
240    }
241}
242
243impl From<crate::varint::VarIntError> for ValidationError {
244    fn from(_: crate::varint::VarIntError) -> Self {
245        MAX_ENCODABLE_VALUE
246    }
247}
248
249impl From<core::num::TryFromIntError> for ValidationError {
250    fn from(_: core::num::TryFromIntError) -> Self {
251        MAX_ENCODABLE_VALUE
252    }
253}
254
255impl From<core::convert::Infallible> for ValidationError {
256    fn from(_: core::convert::Infallible) -> Self {
257        // this won't ever happen since Infallible can't actually be created
258        MAX_ENCODABLE_VALUE
259    }
260}
261
262#[cfg(feature = "std")]
263impl std::error::Error for ValidationError {}
264
265/// Creates a transport parameter struct with the inner codec type
266macro_rules! transport_parameter {
267    ($name:ident($encodable_type:ty), $tag:expr) => {
268        transport_parameter!(
269            $name($encodable_type),
270            $tag,
271            <$encodable_type as Default>::default()
272        );
273    };
274    ($name:ident($encodable_type:ty), $tag:expr, $default:expr) => {
275        #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord)]
276        pub struct $name($encodable_type);
277
278        impl Default for $name {
279            fn default() -> Self {
280                Self($default)
281            }
282        }
283
284        impl $name {
285            // Create a transport parameter with the given value
286            pub fn new<T: TryInto<$encodable_type>>(value: T) -> Option<Self> {
287                value
288                    .try_into()
289                    .ok()
290                    .map(Self)
291                    .and_then(|value| value.validate().ok())
292            }
293        }
294
295        impl TryFrom<$encodable_type> for $name {
296            type Error = ValidationError;
297
298            fn try_from(value: $encodable_type) -> Result<Self, Self::Error> {
299                Self(value).validate().map_err(|err| err.into())
300            }
301        }
302
303        impl TransportParameter for $name {
304            type CodecValue = $encodable_type;
305
306            const ID: TransportParameterId = TransportParameterId::from_u8($tag);
307
308            fn from_codec_value(value: Self::CodecValue) -> Self {
309                Self(value)
310            }
311
312            fn try_into_codec_value(&self) -> Option<&Self::CodecValue> {
313                // To save bytes on the wire, don't send the value if it matches the default value
314                if self.0 == $default {
315                    None
316                } else {
317                    Some(&self.0)
318                }
319            }
320
321            fn default_value() -> Self {
322                Self($default)
323            }
324        }
325
326        impl core::ops::Deref for $name {
327            type Target = $encodable_type;
328
329            fn deref(&self) -> &Self::Target {
330                &self.0
331            }
332        }
333
334        impl PartialEq<$encodable_type> for $name {
335            fn eq(&self, value: &$encodable_type) -> bool {
336                self.0.eq(value)
337            }
338        }
339
340        impl PartialOrd<$encodable_type> for $name {
341            fn partial_cmp(&self, value: &$encodable_type) -> Option<core::cmp::Ordering> {
342                self.0.partial_cmp(value)
343            }
344        }
345    };
346}
347
348macro_rules! varint_transport_parameter {
349    ($name:ident, $tag:expr $(, $default:expr)?) => {
350        transport_parameter!($name(VarInt), $tag $(, $default)?);
351
352        impl TryFrom<u64> for $name {
353            type Error = ValidationError;
354
355            fn try_from(value: u64) -> Result<Self, Self::Error> {
356                let value = VarInt::new(value)?;
357                Self::try_from(value)
358            }
359        }
360
361        impl $name {
362            pub const fn as_varint(self) -> VarInt {
363                self.0
364            }
365        }
366    };
367}
368
369macro_rules! duration_transport_parameter {
370    ($name:ident, $tag:expr $(, $default:expr)?) => {
371        transport_parameter!($name(VarInt), $tag $(, $default)?);
372
373        impl $name {
374            /// Convert idle_timeout into a `core::time::Duration`
375            pub const fn as_duration(self) -> Duration {
376                Duration::from_millis(self.0.as_u64())
377            }
378        }
379
380        impl TryFrom<Duration> for $name {
381            type Error = ValidationError;
382
383            fn try_from(value: Duration) -> Result<Self, Self::Error> {
384                let value: VarInt = value.as_millis().try_into()?;
385                value.try_into()
386            }
387        }
388
389        impl From<$name> for Duration {
390            fn from(value: $name) -> Self {
391                value.as_duration()
392            }
393        }
394    };
395}
396
397/// Implements an optional transport parameter. Used for transport parameters
398/// that don't have a good default, like an IP address.
399macro_rules! optional_transport_parameter {
400    ($ty:ty) => {
401        impl TransportParameter for Option<$ty> {
402            type CodecValue = $ty;
403
404            const ID: TransportParameterId = <$ty as TransportParameter>::ID;
405
406            fn from_codec_value(value: Self::CodecValue) -> Self {
407                Some(value)
408            }
409
410            fn try_into_codec_value(&self) -> Option<&Self::CodecValue> {
411                self.as_ref()
412            }
413
414            fn default_value() -> Self {
415                None
416            }
417        }
418
419        impl TransportParameterValidator for Option<$ty> {
420            fn validate(self) -> Result<Self, DecoderError> {
421                if let Some(value) = self {
422                    Ok(Some(value.validate()?))
423                } else {
424                    Ok(None)
425                }
426            }
427        }
428    };
429}
430
431macro_rules! connection_id_parameter {
432    ($name:ident, $id_type:ident, $tag:expr) => {
433        transport_parameter!($name(connection::$id_type), $tag);
434
435        // The inner connection_id handles validation
436        impl TransportParameterValidator for $name {}
437
438        impl TryFrom<&[u8]> for $name {
439            type Error = crate::connection::id::Error;
440
441            fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
442                Ok(Self(connection::$id_type::try_from(value)?))
443            }
444        }
445
446        decoder_value!(
447            impl<'a> $name {
448                fn decode(buffer: Buffer) -> Result<Self> {
449                    let (connection_id, buffer) = buffer.decode()?;
450                    Ok((Self(connection_id), buffer))
451                }
452            }
453        );
454
455        impl EncoderValue for $name {
456            fn encode<E: Encoder>(&self, encoder: &mut E) {
457                self.0.encode(encoder)
458            }
459        }
460    };
461}
462
463//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
464//# original_destination_connection_id (0x00): This parameter is the value of the
465//#    Destination Connection ID field from the first Initial packet sent
466//#    by the client; see Section 7.3.  This transport parameter is only
467//#    sent by a server.
468
469connection_id_parameter!(OriginalDestinationConnectionId, InitialId, 0x00);
470optional_transport_parameter!(OriginalDestinationConnectionId);
471
472//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
473//# max_idle_timeout (0x01):  The maximum idle timeout is a value in
474//#    milliseconds that is encoded as an integer; see (Section 10.1).
475//#    Idle timeout is disabled when both endpoints omit this transport
476//#    parameter or specify a value of 0.
477
478transport_parameter!(MaxIdleTimeout(VarInt), 0x01, VarInt::from_u8(0));
479
480impl MaxIdleTimeout {
481    /// Defaults to 30 seconds
482    pub const RECOMMENDED: Self = Self(VarInt::from_u32(30_000));
483
484    /// Loads a value setting from a peer's transport parameter
485    pub fn load_peer(&mut self, peer: &Self) {
486        //= https://www.rfc-editor.org/rfc/rfc9000#section-10.1
487        //# Each endpoint advertises a max_idle_timeout, but the effective value
488        //# at an endpoint is computed as the minimum of the two advertised
489        //# values.
490
491        match (self.as_duration(), peer.as_duration()) {
492            (Some(current_duration), Some(peer_duration)) => {
493                // take the peer's value if less
494                if current_duration > peer_duration {
495                    *self = *peer;
496                }
497            }
498            (Some(_), None) => {
499                // keep self
500            }
501            (None, Some(_)) => {
502                *self = *peer;
503            }
504            (None, None) => {
505                // keep self
506            }
507        }
508    }
509
510    /// Returns the `max_idle_timeout` if set
511    pub fn as_duration(&self) -> Option<Duration> {
512        let duration = Duration::from_millis(self.0.as_u64());
513
514        //= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
515        //# Idle timeout is disabled when both endpoints omit this transport
516        //# parameter or specify a value of 0.
517        if duration == Duration::from_secs(0) {
518            None
519        } else {
520            Some(duration)
521        }
522    }
523}
524
525impl TransportParameterValidator for MaxIdleTimeout {}
526
527impl TryFrom<Duration> for MaxIdleTimeout {
528    type Error = ValidationError;
529
530    fn try_from(value: Duration) -> Result<Self, Self::Error> {
531        let value: VarInt = value.as_millis().try_into()?;
532        value.try_into()
533    }
534}
535
536impl From<MaxIdleTimeout> for Duration {
537    fn from(value: MaxIdleTimeout) -> Self {
538        value.as_duration().unwrap_or_default()
539    }
540}
541
542//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
543//# stateless_reset_token (0x02):  A stateless reset token is used in
544//#    verifying a stateless reset; see Section 10.3.  This parameter is
545//#    a sequence of 16 bytes.  This transport parameter MUST NOT be sent
546//#    by a client, but MAY be sent by a server.  A server that does not
547//#    send this transport parameter cannot use stateless reset
548//#    (Section 10.3) for the connection ID negotiated during the
549//#    handshake.
550
551optional_transport_parameter!(stateless_reset::Token);
552
553impl TransportParameter for stateless_reset::Token {
554    type CodecValue = Self;
555
556    const ID: TransportParameterId = TransportParameterId::from_u8(0x02);
557
558    fn from_codec_value(value: Self) -> Self {
559        value
560    }
561
562    fn try_into_codec_value(&self) -> Option<&Self> {
563        Some(self)
564    }
565
566    fn default_value() -> Self {
567        Self::ZEROED
568    }
569}
570
571impl TransportParameterValidator for stateless_reset::Token {}
572
573//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
574//# max_udp_payload_size (0x03):  The maximum UDP payload size parameter
575//#    is an integer value that limits the size of UDP payloads that the
576//#    endpoint is willing to receive.  UDP datagrams with payloads
577//#    larger than this limit are not likely to be processed by the
578//#    receiver.
579//#
580//#    The default for this parameter is the maximum permitted UDP
581//#    payload of 65527.  Values below 1200 are invalid.
582//#
583//#    This limit does act as an additional constraint on datagram size
584//#    in the same way as the path MTU, but it is a property of the
585//#    endpoint and not the path; see Section 14.  It is expected that
586//#    this is the space an endpoint dedicates to holding incoming
587//#    packets.
588
589transport_parameter!(MaxUdpPayloadSize(VarInt), 0x03, VarInt::from_u16(65527));
590
591impl TransportParameterValidator for MaxUdpPayloadSize {
592    fn validate(self) -> Result<Self, DecoderError> {
593        decoder_invariant!(
594            (1200..=65527).contains(&*self.0),
595            "max_udp_payload_size should be within 1200 and 65527 bytes"
596        );
597        Ok(self)
598    }
599}
600
601impl TryFrom<u16> for MaxUdpPayloadSize {
602    type Error = ValidationError;
603
604    fn try_from(value: u16) -> Result<Self, Self::Error> {
605        let value: VarInt = value.into();
606        value.try_into()
607    }
608}
609
610//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
611//# initial_max_data (0x04):  The initial maximum data parameter is an
612//#    integer value that contains the initial value for the maximum
613//#    amount of data that can be sent on the connection.  This is
614//#    equivalent to sending a MAX_DATA (Section 19.9) for the connection
615//#    immediately after completing the handshake.
616
617varint_transport_parameter!(InitialMaxData, 0x04);
618
619/// Computes a data window with the given configuration
620pub const fn compute_data_window(mbps: u64, rtt: Duration, rtt_count: u64) -> VarInt {
621    // ideal throughput in Mbps
622    let mut window = mbps;
623    // Mbit/sec * 125 -> bytes/ms
624    window *= 125;
625    // bytes/ms * ms/RTT -> bytes/RTT
626    window *= rtt.as_millis() as u64;
627    // bytes/RTT * rtt_count -> N * bytes/RTT
628    window *= rtt_count;
629
630    VarInt::from_u32(window as u32)
631}
632
633impl InitialMaxData {
634    /// Tuned for 150Mbps with a 100ms RTT
635    pub const RECOMMENDED: Self = Self(compute_data_window(150, Duration::from_millis(100), 2));
636}
637
638impl TransportParameterValidator for InitialMaxData {}
639
640//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
641//# initial_max_stream_data_bidi_local (0x05):  This parameter is an
642//#    integer value specifying the initial flow control limit for
643//#    locally-initiated bidirectional streams.  This limit applies to
644//#    newly created bidirectional streams opened by the endpoint that
645//#    sends the transport parameter.  In client transport parameters,
646//#    this applies to streams with an identifier with the least
647//#    significant two bits set to 0x00; in server transport parameters,
648//#    this applies to streams with the least significant two bits set to
649//#    0x01.
650
651varint_transport_parameter!(InitialMaxStreamDataBidiLocal, 0x05);
652
653impl InitialMaxStreamDataBidiLocal {
654    /// Tuned for 150Mbps throughput with a 100ms RTT
655    pub const RECOMMENDED: Self = Self(InitialMaxData::RECOMMENDED.0);
656}
657
658impl TransportParameterValidator for InitialMaxStreamDataBidiLocal {}
659
660//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
661//# initial_max_stream_data_bidi_remote (0x06):  This parameter is an
662//#    integer value specifying the initial flow control limit for peer-
663//#    initiated bidirectional streams.  This limit applies to newly
664//#    created bidirectional streams opened by the endpoint that receives
665//#    the transport parameter.  In client transport parameters, this
666//#    applies to streams with an identifier with the least significant
667//#    two bits set to 0x01; in server transport parameters, this applies
668//#    to streams with the least significant two bits set to 0x00.
669
670varint_transport_parameter!(InitialMaxStreamDataBidiRemote, 0x06);
671
672impl InitialMaxStreamDataBidiRemote {
673    /// Tuned for 150Mbps throughput with a 100ms RTT
674    pub const RECOMMENDED: Self = Self(InitialMaxData::RECOMMENDED.0);
675}
676
677impl TransportParameterValidator for InitialMaxStreamDataBidiRemote {}
678
679//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
680//# initial_max_stream_data_uni (0x07):  This parameter is an integer
681//#    value specifying the initial flow control limit for unidirectional
682//#    streams.  This limit applies to newly created unidirectional
683//#    streams opened by the endpoint that receives the transport
684//#    parameter.  In client transport parameters, this applies to
685//#    streams with an identifier with the least significant two bits set
686//#    to 0x03; in server transport parameters, this applies to streams
687//#    with the least significant two bits set to 0x02.
688
689varint_transport_parameter!(InitialMaxStreamDataUni, 0x07);
690
691impl InitialMaxStreamDataUni {
692    /// Tuned for 150Mbps throughput with a 100ms RTT
693    pub const RECOMMENDED: Self = Self(InitialMaxData::RECOMMENDED.0);
694}
695
696impl TransportParameterValidator for InitialMaxStreamDataUni {}
697
698//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
699//# initial_max_streams_bidi (0x08):  The initial maximum bidirectional
700//#    streams parameter is an integer value that contains the initial
701//#    maximum number of bidirectional streams the endpoint that receives
702//#    this transport parameter is permitted to initiate.  If this
703//#    parameter is absent or zero, the peer cannot open bidirectional
704//#    streams until a MAX_STREAMS frame is sent.  Setting this parameter
705//#    is equivalent to sending a MAX_STREAMS (Section 19.11) of the
706//#    corresponding type with the same value.
707
708varint_transport_parameter!(InitialMaxStreamsBidi, 0x08);
709
710impl InitialMaxStreamsBidi {
711    /// Allow up to 100 concurrent streams at any time
712    pub const RECOMMENDED: Self = Self(VarInt::from_u8(100));
713}
714
715impl TransportParameterValidator for InitialMaxStreamsBidi {
716    fn validate(self) -> Result<Self, DecoderError> {
717        //= https://www.rfc-editor.org/rfc/rfc9000#section-4.6
718        //# If a max_streams transport parameter or a MAX_STREAMS frame is
719        //# received with a value greater than 2^60, this would allow a maximum
720        //# stream ID that cannot be expressed as a variable-length integer; see
721        //# Section 16.  If either is received, the connection MUST be closed
722        //# immediately with a connection error of type TRANSPORT_PARAMETER_ERROR
723        //# if the offending value was received in a transport parameter or of
724        //# type FRAME_ENCODING_ERROR if it was received in a frame; see
725        //# Section 10.2.
726        decoder_invariant!(
727            *self <= 2u64.pow(60),
728            "initial_max_streams_bidi cannot be greater than 2^60"
729        );
730
731        Ok(self)
732    }
733}
734
735//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
736//# initial_max_streams_uni (0x09):  The initial maximum unidirectional
737//#    streams parameter is an integer value that contains the initial
738//#    maximum number of unidirectional streams the endpoint that
739//#    receives this transport parameter is permitted to initiate.  If
740//#    this parameter is absent or zero, the peer cannot open
741//#    unidirectional streams until a MAX_STREAMS frame is sent.  Setting
742//#    this parameter is equivalent to sending a MAX_STREAMS
743//#    (Section 19.11) of the corresponding type with the same value.
744
745varint_transport_parameter!(InitialMaxStreamsUni, 0x09);
746
747impl InitialMaxStreamsUni {
748    /// Allow up to 100 concurrent streams at any time
749    pub const RECOMMENDED: Self = Self(VarInt::from_u8(100));
750}
751
752impl TransportParameterValidator for InitialMaxStreamsUni {
753    fn validate(self) -> Result<Self, DecoderError> {
754        //= https://www.rfc-editor.org/rfc/rfc9000#section-4.6
755        //# If a max_streams transport parameter or a MAX_STREAMS frame is
756        //# received with a value greater than 2^60, this would allow a maximum
757        //# stream ID that cannot be expressed as a variable-length integer; see
758        //# Section 16.  If either is received, the connection MUST be closed
759        //# immediately with a connection error of type TRANSPORT_PARAMETER_ERROR
760        //# if the offending value was received in a transport parameter or of
761        //# type FRAME_ENCODING_ERROR if it was received in a frame; see
762        //# Section 10.2.
763        decoder_invariant!(
764            *self <= 2u64.pow(60),
765            "initial_max_streams_uni cannot be greater than 2^60"
766        );
767
768        Ok(self)
769    }
770}
771
772//= https://www.rfc-editor.org/rfc/rfc9221#section-3
773//# Support for receiving the DATAGRAM frame types is advertised by means
774//# of a QUIC transport parameter (name=max_datagram_frame_size, value=0x20).
775//# The max_datagram_frame_size transport parameter is an integer value
776//# (represented as a variable-length integer) that represents the maximum
777//# size of a DATAGRAM frame (including the frame type, length, and
778//# payload) the endpoint is willing to receive, in bytes.
779transport_parameter!(MaxDatagramFrameSize(VarInt), 0x20, VarInt::from_u16(0));
780
781impl MaxDatagramFrameSize {
782    //= https://www.rfc-editor.org/rfc/rfc9221#section-3
783    //# For most uses of DATAGRAM frames, it is RECOMMENDED to send a value of
784    //# 65535 in the max_datagram_frame_size transport parameter to indicate that
785    //# this endpoint will accept any DATAGRAM frame that fits inside a QUIC packet.
786    pub const RECOMMENDED: u64 = 65535;
787    //= https://www.rfc-editor.org/rfc/rfc9221#section-3
788    //# The default for this parameter is 0, which indicates that the
789    //# endpoint does not support DATAGRAM frames.  A value greater than 0
790    //# indicates that the endpoint supports the DATAGRAM frame types and is
791    //# willing to receive such frames on this connection.
792    pub const DEFAULT: Self = Self(VarInt::from_u16(0));
793}
794
795impl TransportParameterValidator for MaxDatagramFrameSize {
796    fn validate(self) -> Result<Self, DecoderError> {
797        Ok(self)
798    }
799}
800
801impl TryFrom<u64> for MaxDatagramFrameSize {
802    type Error = ValidationError;
803
804    fn try_from(value: u64) -> Result<Self, Self::Error> {
805        let value = VarInt::new(value)?;
806        Self::try_from(value)
807    }
808}
809
810//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
811//# ack_delay_exponent (0x0a):  The acknowledgement delay exponent is an
812//#    integer value indicating an exponent used to decode the ACK Delay
813//#    field in the ACK frame (Section 19.3).  If this value is absent, a
814//#    default value of 3 is assumed (indicating a multiplier of 8).
815//#    Values above 20 are invalid.
816
817transport_parameter!(AckDelayExponent(u8), 0x0a, 3);
818
819impl AckDelayExponent {
820    /// The recommended value comes from the default of 3
821    pub const RECOMMENDED: Self = Self(3);
822
823    pub const fn as_u8(self) -> u8 {
824        self.0
825    }
826}
827
828impl TransportParameterValidator for AckDelayExponent {
829    fn validate(self) -> Result<Self, DecoderError> {
830        decoder_invariant!(self.0 <= 20, "ack_delay_exponent cannot be greater than 20");
831        Ok(self)
832    }
833}
834
835//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
836//# max_ack_delay (0x0b):  The maximum acknowledgment delay is an integer
837//#    value indicating the maximum amount of time in milliseconds by
838//#    which the endpoint will delay sending acknowledgments.  This value
839//#    SHOULD include the receiver's expected delays in alarms firing.
840//#    For example, if a receiver sets a timer for 5ms and alarms
841//#    commonly fire up to 1ms late, then it should send a max_ack_delay
842//#    of 6ms.  If this value is absent, a default of 25 milliseconds is
843//#    assumed.  Values of 2^14 or greater are invalid.
844
845duration_transport_parameter!(MaxAckDelay, 0x0b, VarInt::from_u8(25));
846
847impl MaxAckDelay {
848    /// The recommended value comes from the default of 25ms
849    pub const RECOMMENDED: Self = Self(VarInt::from_u8(25));
850}
851
852impl TransportParameterValidator for MaxAckDelay {
853    fn validate(self) -> Result<Self, DecoderError> {
854        decoder_invariant!(
855            *self.0 <= 2u64.pow(14),
856            "max_ack_delay cannot be greater than 2^14"
857        );
858        Ok(self)
859    }
860}
861
862//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
863//# disable_active_migration (0x0c): The disable active migration
864//#    transport parameter is included if the endpoint does not support
865//#    active connection migration (Section 9) on the address being used
866//#    during the handshake.
867
868#[derive(Clone, Copy, Debug, Default, PartialEq)]
869pub enum MigrationSupport {
870    #[default]
871    Enabled,
872    Disabled,
873}
874
875impl MigrationSupport {
876    pub const RECOMMENDED: Self = Self::Enabled;
877}
878
879impl TransportParameter for MigrationSupport {
880    type CodecValue = ();
881
882    const ID: TransportParameterId = TransportParameterId::from_u8(0x0c);
883
884    fn from_codec_value(_value: ()) -> Self {
885        MigrationSupport::Disabled
886    }
887
888    fn try_into_codec_value(&self) -> Option<&()> {
889        if let MigrationSupport::Disabled = self {
890            Some(&())
891        } else {
892            None
893        }
894    }
895
896    fn default_value() -> Self {
897        Self::default()
898    }
899}
900
901impl TransportParameterValidator for MigrationSupport {}
902
903//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
904//# preferred_address (0x0d):  The server's preferred address is used to
905//#    effect a change in server address at the end of the handshake, as
906//#    described in Section 9.6.  This transport parameter is only sent
907//#    by a server.  Servers MAY choose to only send a preferred address
908//#    of one address family by sending an all-zero address and port
909//#    (0.0.0.0:0 or [::]:0) for the other family.  IP addresses are
910//#    encoded in network byte order.
911
912optional_transport_parameter!(PreferredAddress);
913
914//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
915//# Preferred Address {
916//#   IPv4 Address (32),
917//#   IPv4 Port (16),
918//#   IPv6 Address (128),
919//#   IPv6 Port (16),
920//#   Connection ID Length (8),
921//#   Connection ID (..),
922//#   Stateless Reset Token (128),
923//# }
924
925type CidLength = u8;
926
927#[derive(Clone, Copy, Debug, PartialEq)]
928pub struct PreferredAddress {
929    pub ipv4_address: Option<SocketAddressV4>,
930    pub ipv6_address: Option<SocketAddressV6>,
931    pub connection_id: crate::connection::UnboundedId,
932    pub stateless_reset_token: crate::stateless_reset::Token,
933}
934
935impl Unspecified for PreferredAddress {
936    fn is_unspecified(&self) -> bool {
937        self.ipv4_address
938            .as_ref()
939            .map(Unspecified::is_unspecified)
940            .unwrap_or(true)
941            && self
942                .ipv6_address
943                .as_ref()
944                .map(Unspecified::is_unspecified)
945                .unwrap_or(true)
946    }
947}
948
949impl TransportParameter for PreferredAddress {
950    type CodecValue = Self;
951
952    const ID: TransportParameterId = TransportParameterId::from_u8(0x0d);
953
954    fn from_codec_value(value: Self) -> Self {
955        value
956    }
957
958    fn try_into_codec_value(&self) -> Option<&Self> {
959        Some(self)
960    }
961
962    fn default_value() -> Self {
963        unimplemented!(
964            "PreferredAddress is an optional transport parameter, so the default is None"
965        )
966    }
967}
968
969impl TransportParameterValidator for PreferredAddress {
970    fn validate(self) -> Result<Self, DecoderError> {
971        decoder_invariant!(
972            !self.is_unspecified(),
973            "at least one address needs to be specified"
974        );
975        Ok(self)
976    }
977}
978
979decoder_value!(
980    impl<'a> PreferredAddress {
981        fn decode(buffer: Buffer) -> Result<Self> {
982            let (ipv4_address, buffer) = buffer.decode::<SocketAddressV4>()?;
983            let ipv4_address = ipv4_address.filter_unspecified();
984            let (ipv6_address, buffer) = buffer.decode::<SocketAddressV6>()?;
985            let ipv6_address = ipv6_address.filter_unspecified();
986            let (connection_id, buffer) = buffer.decode_with_len_prefix::<CidLength, _>()?;
987            let (stateless_reset_token, buffer) = buffer.decode()?;
988            let preferred_address = Self {
989                ipv4_address,
990                ipv6_address,
991                connection_id,
992                stateless_reset_token,
993            };
994            Ok((preferred_address, buffer))
995        }
996    }
997);
998
999impl EncoderValue for PreferredAddress {
1000    fn encode<E: Encoder>(&self, buffer: &mut E) {
1001        if let Some(ip) = self.ipv4_address.as_ref() {
1002            buffer.encode(ip);
1003        } else {
1004            buffer.write_repeated(size_of::<SocketAddressV4>(), 0);
1005        }
1006
1007        if let Some(ip) = self.ipv6_address.as_ref() {
1008            buffer.encode(ip);
1009        } else {
1010            buffer.write_repeated(size_of::<SocketAddressV6>(), 0);
1011        }
1012        buffer.encode_with_len_prefix::<CidLength, _>(&self.connection_id);
1013        buffer.encode(&self.stateless_reset_token);
1014    }
1015}
1016
1017//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
1018//# active_connection_id_limit (0x0e):  This is an integer value
1019//#   specifying the maximum number of connection IDs from the peer that
1020//#   an endpoint is willing to store.  This value includes the
1021//#   connection ID received during the handshake, that received in the
1022//#   preferred_address transport parameter, and those received in
1023//#   NEW_CONNECTION_ID frames.  The value of the
1024//#   active_connection_id_limit parameter MUST be at least 2.  An
1025//#   endpoint that receives a value less than 2 MUST close the
1026//#   connection with an error of type TRANSPORT_PARAMETER_ERROR.  If
1027//#   this transport parameter is absent, a default of 2 is assumed.  If
1028//#   an endpoint issues a zero-length connection ID, it will never send
1029//#   a NEW_CONNECTION_ID frame and therefore ignores the
1030//#   active_connection_id_limit value received from its peer.
1031
1032varint_transport_parameter!(ActiveConnectionIdLimit, 0x0e, VarInt::from_u8(2));
1033
1034impl ActiveConnectionIdLimit {
1035    /// The recommended value comes from the default of 2
1036    pub const RECOMMENDED: Self = Self(VarInt::from_u8(2));
1037}
1038
1039impl TransportParameterValidator for ActiveConnectionIdLimit {
1040    fn validate(self) -> Result<Self, DecoderError> {
1041        decoder_invariant!(
1042            *self.0 >= 2,
1043            "active_connection_id_limit must be at least 2"
1044        );
1045        Ok(self)
1046    }
1047}
1048
1049impl ActiveConnectionIdLimit {
1050    /// Returns true if the specified value is the default
1051    pub fn is_default(self) -> bool {
1052        self == Self::default_value()
1053    }
1054}
1055
1056//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
1057//# initial_source_connection_id (0x0f):  This is the value that the
1058//# endpoint included in the Source Connection ID field of the first
1059//# Initial packet it sends for the connection; see Section 7.3.
1060
1061connection_id_parameter!(InitialSourceConnectionId, UnboundedId, 0x0f);
1062optional_transport_parameter!(InitialSourceConnectionId);
1063
1064impl From<connection::id::LocalId> for InitialSourceConnectionId {
1065    fn from(id: connection::id::LocalId) -> Self {
1066        InitialSourceConnectionId(id.into())
1067    }
1068}
1069
1070//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
1071//# retry_source_connection_id (0x10):  This is the value that the server
1072//#    included in the Source Connection ID field of a Retry packet; see
1073//#    Section 7.3.  This transport parameter is only sent by a server.
1074
1075connection_id_parameter!(RetrySourceConnectionId, LocalId, 0x10);
1076optional_transport_parameter!(RetrySourceConnectionId);
1077
1078/// Used by the client to indicate which versions of s2n-quic-dc it supports
1079/// and by the server to indicate which version it is using
1080#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd, Eq, Ord)]
1081pub struct DcSupportedVersions {
1082    len: u8,
1083    versions: [u32; DC_SUPPORTED_VERSIONS_MAX_LEN as usize],
1084}
1085// The maximum number of supported versions that may be transmitted using
1086// the `DcSupportedVersions` transport parameter
1087const DC_SUPPORTED_VERSIONS_MAX_LEN: u8 = 4;
1088
1089impl DcSupportedVersions {
1090    /// Create a `DcSupportedVersions` for the given `supported_versions` the client supports
1091    pub fn for_client<I: IntoIterator<Item = u32>>(supported_versions: I) -> Self {
1092        let mut versions = [0; DC_SUPPORTED_VERSIONS_MAX_LEN as usize];
1093        let mut len = 0;
1094
1095        for (index, version) in supported_versions.into_iter().enumerate() {
1096            versions[index] = version;
1097            len += 1;
1098
1099            debug_assert!(
1100                len <= DC_SUPPORTED_VERSIONS_MAX_LEN,
1101                "Only {DC_SUPPORTED_VERSIONS_MAX_LEN} supported versions are supported"
1102            );
1103            ensure!(len <= DC_SUPPORTED_VERSIONS_MAX_LEN, break);
1104        }
1105
1106        DcSupportedVersions { len, versions }
1107    }
1108
1109    /// Create a `DcSupportedVersions` for the `supported_version` the server has selected
1110    pub fn for_server(supported_version: u32) -> Self {
1111        DcSupportedVersions {
1112            len: 1,
1113            versions: [supported_version, 0, 0, 0],
1114        }
1115    }
1116
1117    /// The version the server has selected
1118    ///
1119    /// Returns `None` if no version was selected
1120    pub fn selected_version(&self) -> Result<Option<u32>, DecoderError> {
1121        match self.len {
1122            0 => Ok(None),
1123            1 => Ok(Some(self.versions[0])),
1124            _ => Err(DecoderError::InvariantViolation(
1125                "multiple versions selected by the server",
1126            )),
1127        }
1128    }
1129}
1130
1131impl TransportParameter for DcSupportedVersions {
1132    const ID: TransportParameterId = TransportParameterId::from_u32(0xdc0000);
1133    type CodecValue = Self;
1134
1135    fn from_codec_value(value: Self::CodecValue) -> Self {
1136        value
1137    }
1138
1139    fn try_into_codec_value(&self) -> Option<&Self::CodecValue> {
1140        if *self == Self::default_value() {
1141            None
1142        } else {
1143            Some(self)
1144        }
1145    }
1146
1147    fn default_value() -> Self {
1148        Self::default()
1149    }
1150}
1151
1152impl EncoderValue for DcSupportedVersions {
1153    fn encode<E: Encoder>(&self, buffer: &mut E) {
1154        for &version in self.versions.iter().take(self.len as usize) {
1155            VarInt::from_u32(version).encode(buffer);
1156        }
1157    }
1158}
1159
1160decoder_value!(
1161    impl<'a> DcSupportedVersions {
1162        fn decode(buffer: Buffer) -> Result<Self> {
1163            let mut versions = [0; DC_SUPPORTED_VERSIONS_MAX_LEN as usize];
1164            let mut len = 0;
1165            let mut buffer = buffer;
1166            while !buffer.is_empty() {
1167                let (version, remaining) = buffer.decode::<VarInt>()?;
1168                buffer = remaining;
1169
1170                decoder_invariant!(
1171                    version.as_u64() <= u32::MAX as u64,
1172                    "the largest supported version is u32::MAX"
1173                );
1174                versions[len] = version.as_u64() as u32;
1175                len += 1;
1176                ensure!(len < DC_SUPPORTED_VERSIONS_MAX_LEN as usize, break);
1177            }
1178
1179            // Skip the rest of the buffer to allow for future versions of
1180            // `DcSupportedVersions` that may support more than 4 versions
1181            let remaining_capacity = buffer.len();
1182            let buffer = buffer.skip(remaining_capacity)?;
1183            Ok((
1184                Self {
1185                    len: len as u8,
1186                    versions,
1187                },
1188                buffer,
1189            ))
1190        }
1191    }
1192);
1193
1194impl TransportParameterValidator for DcSupportedVersions {}
1195
1196impl<'a> IntoIterator for &'a DcSupportedVersions {
1197    type Item = &'a u32;
1198    type IntoIter = core::slice::Iter<'a, u32>;
1199
1200    fn into_iter(self) -> Self::IntoIter {
1201        self.versions[..self.len as usize].iter()
1202    }
1203}
1204
1205impl<'a> IntoEvent<&'a [u32]> for &'a DcSupportedVersions {
1206    fn into_event(self) -> &'a [u32] {
1207        &self.versions[..self.len as usize]
1208    }
1209}
1210
1211//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
1212//# If present, transport parameters that set initial per-stream flow
1213//# control limits (initial_max_stream_data_bidi_local,
1214//# initial_max_stream_data_bidi_remote, and initial_max_stream_data_uni)
1215//# are equivalent to sending a MAX_STREAM_DATA frame (Section 19.10) on
1216//# every stream of the corresponding type immediately after opening.  If
1217//# the transport parameter is absent, streams of that type start with a
1218//# flow control limit of 0.
1219
1220#[derive(Clone, Copy, Debug, Default, PartialEq)]
1221pub struct InitialFlowControlLimits {
1222    pub stream_limits: InitialStreamLimits,
1223    pub max_data: VarInt,
1224    pub max_open_remote_bidirectional_streams: VarInt,
1225    pub max_open_remote_unidirectional_streams: VarInt,
1226}
1227
1228/// Associated flow control limits from a set of TransportParameters
1229#[derive(Clone, Copy, Debug, Default, PartialEq)]
1230pub struct InitialStreamLimits {
1231    pub max_data_bidi_local: VarInt,
1232    pub max_data_bidi_remote: VarInt,
1233    pub max_data_uni: VarInt,
1234}
1235
1236impl InitialStreamLimits {
1237    /// Returns the initial maximum data limit for a Stream based on its Stream ID
1238    /// and the information whether the "local" endpoint is referring to the Client
1239    /// or the Server.
1240    pub fn max_data(&self, local_endpoint_type: endpoint::Type, stream_id: StreamId) -> VarInt {
1241        match (stream_id.initiator(), stream_id.stream_type()) {
1242            (endpoint_type, StreamType::Bidirectional) if endpoint_type == local_endpoint_type => {
1243                self.max_data_bidi_local
1244            }
1245            (_, StreamType::Bidirectional) => self.max_data_bidi_remote,
1246            (_, StreamType::Unidirectional) => self.max_data_uni,
1247        }
1248    }
1249}
1250
1251pub struct DatagramLimits {
1252    pub max_datagram_payload: u64,
1253}
1254
1255impl<
1256        OriginalDestinationConnectionId,
1257        StatelessResetToken,
1258        PreferredAddress,
1259        RetrySourceConnectionId,
1260    >
1261    TransportParameters<
1262        OriginalDestinationConnectionId,
1263        StatelessResetToken,
1264        PreferredAddress,
1265        RetrySourceConnectionId,
1266    >
1267{
1268    /// Returns the flow control limits from a set of TransportParameters
1269    pub fn flow_control_limits(&self) -> InitialFlowControlLimits {
1270        let Self {
1271            initial_max_data,
1272            initial_max_streams_bidi,
1273            initial_max_streams_uni,
1274            ..
1275        } = self;
1276        InitialFlowControlLimits {
1277            stream_limits: self.stream_limits(),
1278            max_data: **initial_max_data,
1279            max_open_remote_bidirectional_streams: **initial_max_streams_bidi,
1280            max_open_remote_unidirectional_streams: **initial_max_streams_uni,
1281        }
1282    }
1283
1284    /// Returns the flow control limits from a set of TransportParameters
1285    pub fn stream_limits(&self) -> InitialStreamLimits {
1286        let Self {
1287            initial_max_stream_data_bidi_local,
1288            initial_max_stream_data_bidi_remote,
1289            initial_max_stream_data_uni,
1290            ..
1291        } = self;
1292        InitialStreamLimits {
1293            max_data_bidi_local: **initial_max_stream_data_bidi_local,
1294            max_data_bidi_remote: **initial_max_stream_data_bidi_remote,
1295            max_data_uni: **initial_max_stream_data_uni,
1296        }
1297    }
1298
1299    // Returns the AckSettings from a set of TransportParameters
1300    pub fn ack_settings(&self) -> ack::Settings {
1301        let Self {
1302            max_ack_delay,
1303            ack_delay_exponent,
1304            ..
1305        } = self;
1306
1307        ack::Settings {
1308            max_ack_delay: max_ack_delay.as_duration(),
1309            ack_delay_exponent: **ack_delay_exponent,
1310            ..Default::default()
1311        }
1312    }
1313
1314    // Calculates the maximum datagram payload size
1315    pub fn datagram_limits(&self) -> DatagramLimits {
1316        let max_datagram_payload = self.max_datagram_frame_size.as_u64();
1317
1318        // We factor in the received max_udp_payload_size since technically it
1319        // can be smaller than the received max_datagram_frame_size.
1320        let max_udp_payload = self.max_udp_payload_size.as_u64();
1321        DatagramLimits {
1322            max_datagram_payload: max_datagram_payload.min(max_udp_payload),
1323        }
1324    }
1325}
1326
1327//= https://www.rfc-editor.org/rfc/rfc9000#section-18.2
1328//# A client MUST NOT include any server-only transport parameter:
1329//# original_destination_connection_id, preferred_address,
1330//# retry_source_connection_id, or stateless_reset_token.  A server MUST
1331//# treat receipt of any of these transport parameters as a connection
1332//# error of type TRANSPORT_PARAMETER_ERROR.
1333
1334mod disabled_parameter;
1335pub use disabled_parameter::DisabledParameter;
1336
1337/// Specific TransportParameters sent by the client endpoint
1338pub type ClientTransportParameters = TransportParameters<
1339    DisabledParameter<OriginalDestinationConnectionId>,
1340    DisabledParameter<stateless_reset::Token>,
1341    DisabledParameter<PreferredAddress>,
1342    DisabledParameter<RetrySourceConnectionId>,
1343>;
1344
1345/// Specific TransportParameters sent by the server endpoint
1346pub type ServerTransportParameters = TransportParameters<
1347    Option<OriginalDestinationConnectionId>,
1348    Option<stateless_reset::Token>,
1349    Option<PreferredAddress>,
1350    Option<RetrySourceConnectionId>,
1351>;
1352
1353impl<'a> IntoEvent<event::builder::TransportParameters<'a>> for &'a ServerTransportParameters {
1354    fn into_event(self) -> event::builder::TransportParameters<'a> {
1355        event::builder::TransportParameters {
1356            original_destination_connection_id: self
1357                .original_destination_connection_id
1358                .as_ref()
1359                .map(|cid| cid.into_event()),
1360            initial_source_connection_id: self
1361                .initial_source_connection_id
1362                .as_ref()
1363                .map(|cid| cid.into_event()),
1364            retry_source_connection_id: self
1365                .retry_source_connection_id
1366                .as_ref()
1367                .map(|cid| cid.into_event()),
1368            stateless_reset_token: self
1369                .stateless_reset_token
1370                .as_ref()
1371                .map(|token| token.as_ref()),
1372            preferred_address: self
1373                .preferred_address
1374                .as_ref()
1375                .map(|addr| addr.into_event()),
1376            migration_support: self.migration_support.into_event(),
1377            max_idle_timeout: Duration::from(self.max_idle_timeout),
1378            max_udp_payload_size: self.max_udp_payload_size.into_event(),
1379            ack_delay_exponent: self.ack_delay_exponent.into_event(),
1380            max_ack_delay: Duration::from(self.max_ack_delay),
1381            active_connection_id_limit: self.active_connection_id_limit.into_event(),
1382            initial_max_stream_data_bidi_local: self
1383                .initial_max_stream_data_bidi_local
1384                .into_event(),
1385            initial_max_stream_data_bidi_remote: self
1386                .initial_max_stream_data_bidi_remote
1387                .into_event(),
1388            initial_max_stream_data_uni: self.initial_max_stream_data_uni.into_event(),
1389            initial_max_streams_bidi: self.initial_max_streams_bidi.into_event(),
1390            initial_max_streams_uni: self.initial_max_streams_uni.into_event(),
1391            max_datagram_frame_size: self.max_datagram_frame_size.into_event(),
1392            dc_supported_versions: self.dc_supported_versions.into_event(),
1393        }
1394    }
1395}
1396
1397impl<'a> IntoEvent<event::builder::TransportParameters<'a>> for &'a ClientTransportParameters {
1398    fn into_event(self) -> event::builder::TransportParameters<'a> {
1399        event::builder::TransportParameters {
1400            original_destination_connection_id: None,
1401            initial_source_connection_id: self
1402                .initial_source_connection_id
1403                .as_ref()
1404                .map(|cid| cid.into_event()),
1405            retry_source_connection_id: None,
1406            stateless_reset_token: None,
1407            preferred_address: None,
1408            migration_support: self.migration_support.into_event(),
1409            max_idle_timeout: Duration::from(self.max_idle_timeout),
1410            max_udp_payload_size: self.max_udp_payload_size.into_event(),
1411            ack_delay_exponent: self.ack_delay_exponent.into_event(),
1412            max_ack_delay: Duration::from(self.max_ack_delay),
1413            active_connection_id_limit: self.active_connection_id_limit.into_event(),
1414            initial_max_stream_data_bidi_local: self
1415                .initial_max_stream_data_bidi_local
1416                .into_event(),
1417            initial_max_stream_data_bidi_remote: self
1418                .initial_max_stream_data_bidi_remote
1419                .into_event(),
1420            initial_max_stream_data_uni: self.initial_max_stream_data_uni.into_event(),
1421            initial_max_streams_bidi: self.initial_max_streams_bidi.into_event(),
1422            initial_max_streams_uni: self.initial_max_streams_uni.into_event(),
1423            max_datagram_frame_size: self.max_datagram_frame_size.into_event(),
1424            dc_supported_versions: self.dc_supported_versions.into_event(),
1425        }
1426    }
1427}
1428
1429macro_rules! impl_transport_parameters {
1430    (
1431        pub struct TransportParameters <
1432        $($server_param:ident),* $(,)? >
1433        { $($field:ident : $field_ty:ty),* $(,)? }
1434    ) => {
1435        #[derive(Clone, Copy, Debug, PartialEq)]
1436        pub struct TransportParameters<$($server_param),*> {
1437            $(
1438                pub $field: $field_ty
1439            ),*
1440        }
1441
1442        impl<$($server_param),*> Default for TransportParameters<$($server_param),*>
1443        where
1444            $(
1445                $server_param: TransportParameter,
1446            )*
1447        {
1448            fn default() -> Self {
1449                Self {
1450                    $(
1451                        $field: TransportParameter::default_value(),
1452                    )*
1453                }
1454            }
1455        }
1456
1457        impl<$($server_param),*> EncoderValue for TransportParameters<$($server_param),*>
1458        where
1459            $(
1460                $server_param: TransportParameter,
1461                $server_param::CodecValue: EncoderValue,
1462            )*
1463        {
1464            fn encode<E: Encoder>(&self, buffer: &mut E) {
1465                $(
1466                    buffer.encode(&TransportParameterCodec(&self.$field));
1467                )*
1468            }
1469        }
1470
1471        impl<'a, $($server_param),*> TransportParameters<$($server_param),*>
1472        where
1473            $(
1474                $server_param: TransportParameter + TransportParameterValidator,
1475                $server_param::CodecValue: DecoderValue<'a>,
1476            )*
1477        {
1478            fn decode_parameters(
1479                mut buffer: DecoderBuffer<'a>
1480            ) -> Result<TransportParameters<$($server_param),*>, DecoderError> {
1481                let mut parameters = Self::default();
1482
1483                /// Tracks the fields for duplicates
1484                #[derive(Default)]
1485                struct UsedFields {
1486                    $(
1487                        $field: bool,
1488                    )*
1489                }
1490
1491                let mut used_fields = UsedFields::default();
1492
1493                while !buffer.is_empty() {
1494                    let (tag, inner_buffer) = buffer.decode::<TransportParameterId>()?;
1495
1496                    buffer = match tag {
1497                        $(
1498                            tag if tag == <$field_ty>::ID => {
1499                                // ensure the field is enabled in this context
1500                                s2n_codec::decoder_invariant!(
1501                                    <$field_ty>::ENABLED,
1502                                    concat!(stringify!($field), " is not allowed in this context")
1503                                );
1504
1505                                //= https://www.rfc-editor.org/rfc/rfc9000#section-7.4
1506                                //# An endpoint MUST NOT send a parameter more than once in a given
1507                                //# transport parameters extension.
1508                                s2n_codec::decoder_invariant!(
1509                                    core::mem::replace(&mut used_fields.$field, true) == false,
1510                                    concat!("duplicate value for ", stringify!($field))
1511                                );
1512
1513                                let (value, inner_buffer) =
1514                                    inner_buffer.decode::<TransportParameterCodec<$field_ty>>()?;
1515
1516                                //= https://www.rfc-editor.org/rfc/rfc9000#section-7.4
1517                                //# An endpoint MUST treat receipt of a transport parameter with an
1518                                //# invalid value as a connection error of type
1519                                //# TRANSPORT_PARAMETER_ERROR.
1520                                parameters.$field = value.0.validate()?;
1521
1522                                inner_buffer
1523                            }
1524                        )*
1525                        _ => {
1526                            //= https://www.rfc-editor.org/rfc/rfc9000#section-7.4.2
1527                            //# An endpoint MUST ignore transport parameters that it does
1528                            //# not support.
1529
1530                            // ignore transport parameters with unknown tags
1531                            // We need to skip the actual content of the parameters, which
1532                            // consists of a VarInt length field plus payload
1533                            inner_buffer.skip_with_len_prefix::<TransportParameterLength>()?
1534                        }
1535                    }
1536                }
1537
1538                Ok(parameters)
1539            }
1540        }
1541    };
1542}
1543
1544impl_transport_parameters!(
1545    pub struct TransportParameters<
1546        OriginalDestinationConnectionId,
1547        StatelessResetToken,
1548        PreferredAddress,
1549        RetrySourceConnectionId,
1550    > {
1551        max_idle_timeout: MaxIdleTimeout,
1552        max_udp_payload_size: MaxUdpPayloadSize,
1553        initial_max_data: InitialMaxData,
1554        initial_max_stream_data_bidi_local: InitialMaxStreamDataBidiLocal,
1555        initial_max_stream_data_bidi_remote: InitialMaxStreamDataBidiRemote,
1556        initial_max_stream_data_uni: InitialMaxStreamDataUni,
1557        initial_max_streams_bidi: InitialMaxStreamsBidi,
1558        initial_max_streams_uni: InitialMaxStreamsUni,
1559        max_datagram_frame_size: MaxDatagramFrameSize,
1560        ack_delay_exponent: AckDelayExponent,
1561        max_ack_delay: MaxAckDelay,
1562        migration_support: MigrationSupport,
1563        active_connection_id_limit: ActiveConnectionIdLimit,
1564        original_destination_connection_id: OriginalDestinationConnectionId,
1565        stateless_reset_token: StatelessResetToken,
1566        preferred_address: PreferredAddress,
1567        initial_source_connection_id: Option<InitialSourceConnectionId>,
1568        retry_source_connection_id: RetrySourceConnectionId,
1569        dc_supported_versions: DcSupportedVersions,
1570    }
1571);
1572
1573impl<
1574        OriginalDestinationConnectionId,
1575        StatelessResetToken,
1576        PreferredAddress,
1577        RetrySourceConnectionId,
1578    >
1579    TransportParameters<
1580        OriginalDestinationConnectionId,
1581        StatelessResetToken,
1582        PreferredAddress,
1583        RetrySourceConnectionId,
1584    >
1585{
1586    pub fn load_limits(&mut self, limits: &crate::connection::limits::Limits) {
1587        macro_rules! load {
1588            ($from:ident, $to:ident) => {
1589                self.$to = limits.$from;
1590            };
1591        }
1592
1593        load!(max_idle_timeout, max_idle_timeout);
1594        load!(data_window, initial_max_data);
1595        load!(
1596            bidirectional_local_data_window,
1597            initial_max_stream_data_bidi_local
1598        );
1599        load!(
1600            bidirectional_remote_data_window,
1601            initial_max_stream_data_bidi_remote
1602        );
1603        load!(unidirectional_data_window, initial_max_stream_data_uni);
1604        load!(
1605            max_open_remote_bidirectional_streams,
1606            initial_max_streams_bidi
1607        );
1608
1609        load!(
1610            max_open_remote_unidirectional_streams,
1611            initial_max_streams_uni
1612        );
1613        load!(max_ack_delay, max_ack_delay);
1614        load!(ack_delay_exponent, ack_delay_exponent);
1615        load!(max_active_connection_ids, active_connection_id_limit);
1616        load!(max_datagram_frame_size, max_datagram_frame_size);
1617        load!(migration_support, migration_support);
1618    }
1619}