1use 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
21pub trait TransportParameter: Sized {
23 const ID: TransportParameterId;
25
26 const ENABLED: bool = true;
28
29 type CodecValue: EncoderValue;
31
32 fn from_codec_value(value: Self::CodecValue) -> Self;
34
35 fn try_into_codec_value(&self) -> Option<&Self::CodecValue>;
37
38 fn default_value() -> Self;
42
43 #[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
56pub trait TransportParameterValidator: Sized {
58 fn validate(self) -> Result<Self, DecoderError> {
60 Ok(self)
61 }
62}
63
64#[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 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 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
138decoder_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
172type TransportParameterId = VarInt;
188type TransportParameterLength = VarInt;
189
190struct 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 MAX_ENCODABLE_VALUE
259 }
260}
261
262impl core::error::Error for ValidationError {}
263
264macro_rules! transport_parameter {
266 ($name:ident($encodable_type:ty), $tag:expr) => {
267 transport_parameter!(
268 $name($encodable_type),
269 $tag,
270 <$encodable_type as Default>::default()
271 );
272 };
273 ($name:ident($encodable_type:ty), $tag:expr, $default:expr) => {
274 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord)]
275 pub struct $name($encodable_type);
276
277 impl Default for $name {
278 fn default() -> Self {
279 Self($default)
280 }
281 }
282
283 impl $name {
284 pub fn new<T: TryInto<$encodable_type>>(value: T) -> Option<Self> {
286 value
287 .try_into()
288 .ok()
289 .map(Self)
290 .and_then(|value| value.validate().ok())
291 }
292 }
293
294 impl TryFrom<$encodable_type> for $name {
295 type Error = ValidationError;
296
297 fn try_from(value: $encodable_type) -> Result<Self, Self::Error> {
298 Self(value).validate().map_err(|err| err.into())
299 }
300 }
301
302 impl TransportParameter for $name {
303 type CodecValue = $encodable_type;
304
305 const ID: TransportParameterId = TransportParameterId::from_u8($tag);
306
307 fn from_codec_value(value: Self::CodecValue) -> Self {
308 Self(value)
309 }
310
311 fn try_into_codec_value(&self) -> Option<&Self::CodecValue> {
312 if self.0 == $default {
314 None
315 } else {
316 Some(&self.0)
317 }
318 }
319
320 fn default_value() -> Self {
321 Self($default)
322 }
323 }
324
325 impl core::ops::Deref for $name {
326 type Target = $encodable_type;
327
328 fn deref(&self) -> &Self::Target {
329 &self.0
330 }
331 }
332
333 impl PartialEq<$encodable_type> for $name {
334 fn eq(&self, value: &$encodable_type) -> bool {
335 self.0.eq(value)
336 }
337 }
338
339 impl PartialOrd<$encodable_type> for $name {
340 fn partial_cmp(&self, value: &$encodable_type) -> Option<core::cmp::Ordering> {
341 self.0.partial_cmp(value)
342 }
343 }
344 };
345}
346
347macro_rules! varint_transport_parameter {
348 ($name:ident, $tag:expr $(, $default:expr)?) => {
349 transport_parameter!($name(VarInt), $tag $(, $default)?);
350
351 impl TryFrom<u64> for $name {
352 type Error = ValidationError;
353
354 fn try_from(value: u64) -> Result<Self, Self::Error> {
355 let value = VarInt::new(value)?;
356 Self::try_from(value)
357 }
358 }
359
360 impl $name {
361 pub const fn as_varint(self) -> VarInt {
362 self.0
363 }
364 }
365 };
366}
367
368macro_rules! duration_transport_parameter {
369 ($name:ident, $tag:expr $(, $default:expr)?) => {
370 transport_parameter!($name(VarInt), $tag $(, $default)?);
371
372 impl $name {
373 pub const fn as_duration(self) -> Duration {
375 Duration::from_millis(self.0.as_u64())
376 }
377 }
378
379 impl TryFrom<Duration> for $name {
380 type Error = ValidationError;
381
382 fn try_from(value: Duration) -> Result<Self, Self::Error> {
383 let value: VarInt = value.as_millis().try_into()?;
384 value.try_into()
385 }
386 }
387
388 impl From<$name> for Duration {
389 fn from(value: $name) -> Self {
390 value.as_duration()
391 }
392 }
393 };
394}
395
396macro_rules! optional_transport_parameter {
399 ($ty:ty) => {
400 impl TransportParameter for Option<$ty> {
401 type CodecValue = $ty;
402
403 const ID: TransportParameterId = <$ty as TransportParameter>::ID;
404
405 fn from_codec_value(value: Self::CodecValue) -> Self {
406 Some(value)
407 }
408
409 fn try_into_codec_value(&self) -> Option<&Self::CodecValue> {
410 self.as_ref()
411 }
412
413 fn default_value() -> Self {
414 None
415 }
416 }
417
418 impl TransportParameterValidator for Option<$ty> {
419 fn validate(self) -> Result<Self, DecoderError> {
420 if let Some(value) = self {
421 Ok(Some(value.validate()?))
422 } else {
423 Ok(None)
424 }
425 }
426 }
427 };
428}
429
430macro_rules! connection_id_parameter {
431 ($name:ident, $id_type:ident, $tag:expr) => {
432 transport_parameter!($name(connection::$id_type), $tag);
433
434 impl TransportParameterValidator for $name {}
436
437 impl TryFrom<&[u8]> for $name {
438 type Error = crate::connection::id::Error;
439
440 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
441 Ok(Self(connection::$id_type::try_from(value)?))
442 }
443 }
444
445 decoder_value!(
446 impl<'a> $name {
447 fn decode(buffer: Buffer) -> Result<Self> {
448 let (connection_id, buffer) = buffer.decode()?;
449 Ok((Self(connection_id), buffer))
450 }
451 }
452 );
453
454 impl EncoderValue for $name {
455 fn encode<E: Encoder>(&self, encoder: &mut E) {
456 self.0.encode(encoder)
457 }
458 }
459 };
460}
461
462connection_id_parameter!(OriginalDestinationConnectionId, InitialId, 0x00);
469optional_transport_parameter!(OriginalDestinationConnectionId);
470
471transport_parameter!(MaxIdleTimeout(VarInt), 0x01, VarInt::from_u8(0));
478
479impl MaxIdleTimeout {
480 pub const RECOMMENDED: Self = Self(VarInt::from_u32(30_000));
482
483 pub fn load_peer(&mut self, peer: &Self) {
485 match (self.as_duration(), peer.as_duration()) {
491 (Some(current_duration), Some(peer_duration)) => {
492 if current_duration > peer_duration {
494 *self = *peer;
495 }
496 }
497 (Some(_), None) => {
498 }
500 (None, Some(_)) => {
501 *self = *peer;
502 }
503 (None, None) => {
504 }
506 }
507 }
508
509 pub fn as_duration(&self) -> Option<Duration> {
511 let duration = Duration::from_millis(self.0.as_u64());
512
513 if duration == Duration::from_secs(0) {
517 None
518 } else {
519 Some(duration)
520 }
521 }
522}
523
524impl TransportParameterValidator for MaxIdleTimeout {}
525
526impl TryFrom<Duration> for MaxIdleTimeout {
527 type Error = ValidationError;
528
529 fn try_from(value: Duration) -> Result<Self, Self::Error> {
530 let value: VarInt = value.as_millis().try_into()?;
531 value.try_into()
532 }
533}
534
535impl From<MaxIdleTimeout> for Duration {
536 fn from(value: MaxIdleTimeout) -> Self {
537 value.as_duration().unwrap_or_default()
538 }
539}
540
541optional_transport_parameter!(stateless_reset::Token);
551
552impl TransportParameter for stateless_reset::Token {
553 type CodecValue = Self;
554
555 const ID: TransportParameterId = TransportParameterId::from_u8(0x02);
556
557 fn from_codec_value(value: Self) -> Self {
558 value
559 }
560
561 fn try_into_codec_value(&self) -> Option<&Self> {
562 Some(self)
563 }
564
565 fn default_value() -> Self {
566 Self::ZEROED
567 }
568}
569
570impl TransportParameterValidator for stateless_reset::Token {}
571
572transport_parameter!(MaxUdpPayloadSize(VarInt), 0x03, VarInt::from_u16(65527));
589
590impl TransportParameterValidator for MaxUdpPayloadSize {
591 fn validate(self) -> Result<Self, DecoderError> {
592 decoder_invariant!(
593 (1200..=65527).contains(&*self.0),
594 "max_udp_payload_size should be within 1200 and 65527 bytes"
595 );
596 Ok(self)
597 }
598}
599
600impl TryFrom<u16> for MaxUdpPayloadSize {
601 type Error = ValidationError;
602
603 fn try_from(value: u16) -> Result<Self, Self::Error> {
604 let value: VarInt = value.into();
605 value.try_into()
606 }
607}
608
609varint_transport_parameter!(InitialMaxData, 0x04);
617
618pub const fn compute_data_window(mbps: u64, rtt: Duration, rtt_count: u64) -> VarInt {
620 let mut window = mbps;
622 window *= 125;
624 window *= rtt.as_millis() as u64;
626 window *= rtt_count;
628
629 VarInt::from_u32(window as u32)
630}
631
632impl InitialMaxData {
633 pub const RECOMMENDED: Self = Self(compute_data_window(150, Duration::from_millis(100), 2));
635}
636
637impl TransportParameterValidator for InitialMaxData {}
638
639varint_transport_parameter!(InitialMaxStreamDataBidiLocal, 0x05);
651
652impl InitialMaxStreamDataBidiLocal {
653 pub const RECOMMENDED: Self = Self(InitialMaxData::RECOMMENDED.0);
655}
656
657impl TransportParameterValidator for InitialMaxStreamDataBidiLocal {}
658
659varint_transport_parameter!(InitialMaxStreamDataBidiRemote, 0x06);
670
671impl InitialMaxStreamDataBidiRemote {
672 pub const RECOMMENDED: Self = Self(InitialMaxData::RECOMMENDED.0);
674}
675
676impl TransportParameterValidator for InitialMaxStreamDataBidiRemote {}
677
678varint_transport_parameter!(InitialMaxStreamDataUni, 0x07);
689
690impl InitialMaxStreamDataUni {
691 pub const RECOMMENDED: Self = Self(InitialMaxData::RECOMMENDED.0);
693}
694
695impl TransportParameterValidator for InitialMaxStreamDataUni {}
696
697varint_transport_parameter!(InitialMaxStreamsBidi, 0x08);
708
709impl InitialMaxStreamsBidi {
710 pub const RECOMMENDED: Self = Self(VarInt::from_u8(100));
712}
713
714impl TransportParameterValidator for InitialMaxStreamsBidi {
715 fn validate(self) -> Result<Self, DecoderError> {
716 decoder_invariant!(
726 *self <= 2u64.pow(60),
727 "initial_max_streams_bidi cannot be greater than 2^60"
728 );
729
730 Ok(self)
731 }
732}
733
734varint_transport_parameter!(InitialMaxStreamsUni, 0x09);
745
746impl InitialMaxStreamsUni {
747 pub const RECOMMENDED: Self = Self(VarInt::from_u8(100));
749}
750
751impl TransportParameterValidator for InitialMaxStreamsUni {
752 fn validate(self) -> Result<Self, DecoderError> {
753 decoder_invariant!(
763 *self <= 2u64.pow(60),
764 "initial_max_streams_uni cannot be greater than 2^60"
765 );
766
767 Ok(self)
768 }
769}
770
771transport_parameter!(MaxDatagramFrameSize(VarInt), 0x20, VarInt::from_u16(0));
779
780impl MaxDatagramFrameSize {
781 pub const RECOMMENDED: u64 = 65535;
786 pub const DEFAULT: Self = Self(VarInt::from_u16(0));
792}
793
794impl TransportParameterValidator for MaxDatagramFrameSize {
795 fn validate(self) -> Result<Self, DecoderError> {
796 Ok(self)
797 }
798}
799
800impl TryFrom<u64> for MaxDatagramFrameSize {
801 type Error = ValidationError;
802
803 fn try_from(value: u64) -> Result<Self, Self::Error> {
804 let value = VarInt::new(value)?;
805 Self::try_from(value)
806 }
807}
808
809transport_parameter!(AckDelayExponent(u8), 0x0a, 3);
817
818impl AckDelayExponent {
819 pub const RECOMMENDED: Self = Self(3);
821
822 pub const fn as_u8(self) -> u8 {
823 self.0
824 }
825}
826
827impl TransportParameterValidator for AckDelayExponent {
828 fn validate(self) -> Result<Self, DecoderError> {
829 decoder_invariant!(self.0 <= 20, "ack_delay_exponent cannot be greater than 20");
830 Ok(self)
831 }
832}
833
834duration_transport_parameter!(MaxAckDelay, 0x0b, VarInt::from_u8(25));
845
846impl MaxAckDelay {
847 pub const RECOMMENDED: Self = Self(VarInt::from_u8(25));
849}
850
851impl TransportParameterValidator for MaxAckDelay {
852 fn validate(self) -> Result<Self, DecoderError> {
853 decoder_invariant!(
854 *self.0 <= 2u64.pow(14),
855 "max_ack_delay cannot be greater than 2^14"
856 );
857 Ok(self)
858 }
859}
860
861#[derive(Clone, Copy, Debug, Default, PartialEq)]
868pub enum MigrationSupport {
869 #[default]
870 Enabled,
871 Disabled,
872}
873
874impl MigrationSupport {
875 pub const RECOMMENDED: Self = Self::Enabled;
876}
877
878impl TransportParameter for MigrationSupport {
879 type CodecValue = ();
880
881 const ID: TransportParameterId = TransportParameterId::from_u8(0x0c);
882
883 fn from_codec_value(_value: ()) -> Self {
884 MigrationSupport::Disabled
885 }
886
887 fn try_into_codec_value(&self) -> Option<&()> {
888 if let MigrationSupport::Disabled = self {
889 Some(&())
890 } else {
891 None
892 }
893 }
894
895 fn default_value() -> Self {
896 Self::default()
897 }
898}
899
900impl TransportParameterValidator for MigrationSupport {}
901
902optional_transport_parameter!(PreferredAddress);
912
913type CidLength = u8;
925
926#[derive(Clone, Copy, Debug, PartialEq)]
927pub struct PreferredAddress {
928 pub ipv4_address: Option<SocketAddressV4>,
929 pub ipv6_address: Option<SocketAddressV6>,
930 pub connection_id: crate::connection::UnboundedId,
931 pub stateless_reset_token: crate::stateless_reset::Token,
932}
933
934impl Unspecified for PreferredAddress {
935 fn is_unspecified(&self) -> bool {
936 self.ipv4_address
937 .as_ref()
938 .map(Unspecified::is_unspecified)
939 .unwrap_or(true)
940 && self
941 .ipv6_address
942 .as_ref()
943 .map(Unspecified::is_unspecified)
944 .unwrap_or(true)
945 }
946}
947
948impl TransportParameter for PreferredAddress {
949 type CodecValue = Self;
950
951 const ID: TransportParameterId = TransportParameterId::from_u8(0x0d);
952
953 fn from_codec_value(value: Self) -> Self {
954 value
955 }
956
957 fn try_into_codec_value(&self) -> Option<&Self> {
958 Some(self)
959 }
960
961 fn default_value() -> Self {
962 unimplemented!(
963 "PreferredAddress is an optional transport parameter, so the default is None"
964 )
965 }
966}
967
968impl TransportParameterValidator for PreferredAddress {
969 fn validate(self) -> Result<Self, DecoderError> {
970 decoder_invariant!(
971 !self.is_unspecified(),
972 "at least one address needs to be specified"
973 );
974 Ok(self)
975 }
976}
977
978decoder_value!(
979 impl<'a> PreferredAddress {
980 fn decode(buffer: Buffer) -> Result<Self> {
981 let (ipv4_address, buffer) = buffer.decode::<SocketAddressV4>()?;
982 let ipv4_address = ipv4_address.filter_unspecified();
983 let (ipv6_address, buffer) = buffer.decode::<SocketAddressV6>()?;
984 let ipv6_address = ipv6_address.filter_unspecified();
985 let (connection_id, buffer) = buffer.decode_with_len_prefix::<CidLength, _>()?;
986 let (stateless_reset_token, buffer) = buffer.decode()?;
987 let preferred_address = Self {
988 ipv4_address,
989 ipv6_address,
990 connection_id,
991 stateless_reset_token,
992 };
993 Ok((preferred_address, buffer))
994 }
995 }
996);
997
998impl EncoderValue for PreferredAddress {
999 fn encode<E: Encoder>(&self, buffer: &mut E) {
1000 if let Some(ip) = self.ipv4_address.as_ref() {
1001 buffer.encode(ip);
1002 } else {
1003 buffer.write_repeated(size_of::<SocketAddressV4>(), 0);
1004 }
1005
1006 if let Some(ip) = self.ipv6_address.as_ref() {
1007 buffer.encode(ip);
1008 } else {
1009 buffer.write_repeated(size_of::<SocketAddressV6>(), 0);
1010 }
1011 buffer.encode_with_len_prefix::<CidLength, _>(&self.connection_id);
1012 buffer.encode(&self.stateless_reset_token);
1013 }
1014}
1015
1016varint_transport_parameter!(ActiveConnectionIdLimit, 0x0e, VarInt::from_u8(2));
1032
1033impl ActiveConnectionIdLimit {
1034 pub const RECOMMENDED: Self = Self(VarInt::from_u8(2));
1036}
1037
1038impl TransportParameterValidator for ActiveConnectionIdLimit {
1039 fn validate(self) -> Result<Self, DecoderError> {
1040 decoder_invariant!(
1041 *self.0 >= 2,
1042 "active_connection_id_limit must be at least 2"
1043 );
1044 Ok(self)
1045 }
1046}
1047
1048impl ActiveConnectionIdLimit {
1049 pub fn is_default(self) -> bool {
1051 self == Self::default_value()
1052 }
1053}
1054
1055connection_id_parameter!(InitialSourceConnectionId, UnboundedId, 0x0f);
1061optional_transport_parameter!(InitialSourceConnectionId);
1062
1063impl From<connection::id::LocalId> for InitialSourceConnectionId {
1064 fn from(id: connection::id::LocalId) -> Self {
1065 InitialSourceConnectionId(id.into())
1066 }
1067}
1068
1069connection_id_parameter!(RetrySourceConnectionId, LocalId, 0x10);
1075optional_transport_parameter!(RetrySourceConnectionId);
1076
1077#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd, Eq, Ord)]
1080pub struct DcSupportedVersions {
1081 len: u8,
1082 versions: [u32; DC_SUPPORTED_VERSIONS_MAX_LEN as usize],
1083}
1084const DC_SUPPORTED_VERSIONS_MAX_LEN: u8 = 4;
1087
1088impl DcSupportedVersions {
1089 pub fn for_client<I: IntoIterator<Item = u32>>(supported_versions: I) -> Self {
1091 let mut versions = [0; DC_SUPPORTED_VERSIONS_MAX_LEN as usize];
1092 let mut len = 0;
1093
1094 for (index, version) in supported_versions.into_iter().enumerate() {
1095 versions[index] = version;
1096 len += 1;
1097
1098 debug_assert!(
1099 len <= DC_SUPPORTED_VERSIONS_MAX_LEN,
1100 "Only {DC_SUPPORTED_VERSIONS_MAX_LEN} supported versions are supported"
1101 );
1102 ensure!(len <= DC_SUPPORTED_VERSIONS_MAX_LEN, break);
1103 }
1104
1105 DcSupportedVersions { len, versions }
1106 }
1107
1108 pub fn for_server(supported_version: u32) -> Self {
1110 DcSupportedVersions {
1111 len: 1,
1112 versions: [supported_version, 0, 0, 0],
1113 }
1114 }
1115
1116 pub fn selected_version(&self) -> Result<Option<u32>, DecoderError> {
1120 match self.len {
1121 0 => Ok(None),
1122 1 => Ok(Some(self.versions[0])),
1123 _ => Err(DecoderError::InvariantViolation(
1124 "multiple versions selected by the server",
1125 )),
1126 }
1127 }
1128}
1129
1130impl TransportParameter for DcSupportedVersions {
1131 const ID: TransportParameterId = TransportParameterId::from_u32(0xdc0000);
1132 type CodecValue = Self;
1133
1134 fn from_codec_value(value: Self::CodecValue) -> Self {
1135 value
1136 }
1137
1138 fn try_into_codec_value(&self) -> Option<&Self::CodecValue> {
1139 if *self == Self::default_value() {
1140 None
1141 } else {
1142 Some(self)
1143 }
1144 }
1145
1146 fn default_value() -> Self {
1147 Self::default()
1148 }
1149}
1150
1151impl EncoderValue for DcSupportedVersions {
1152 fn encode<E: Encoder>(&self, buffer: &mut E) {
1153 for &version in self.versions.iter().take(self.len as usize) {
1154 VarInt::from_u32(version).encode(buffer);
1155 }
1156 }
1157}
1158
1159decoder_value!(
1160 impl<'a> DcSupportedVersions {
1161 fn decode(buffer: Buffer) -> Result<Self> {
1162 let mut versions = [0; DC_SUPPORTED_VERSIONS_MAX_LEN as usize];
1163 let mut len = 0;
1164 let mut buffer = buffer;
1165 while !buffer.is_empty() {
1166 let (version, remaining) = buffer.decode::<VarInt>()?;
1167 buffer = remaining;
1168
1169 decoder_invariant!(
1170 version.as_u64() <= u32::MAX as u64,
1171 "the largest supported version is u32::MAX"
1172 );
1173 versions[len] = version.as_u64() as u32;
1174 len += 1;
1175 ensure!(len < DC_SUPPORTED_VERSIONS_MAX_LEN as usize, break);
1176 }
1177
1178 let remaining_capacity = buffer.len();
1181 let buffer = buffer.skip(remaining_capacity)?;
1182 Ok((
1183 Self {
1184 len: len as u8,
1185 versions,
1186 },
1187 buffer,
1188 ))
1189 }
1190 }
1191);
1192
1193impl TransportParameterValidator for DcSupportedVersions {}
1194
1195impl<'a> IntoIterator for &'a DcSupportedVersions {
1196 type Item = &'a u32;
1197 type IntoIter = core::slice::Iter<'a, u32>;
1198
1199 fn into_iter(self) -> Self::IntoIter {
1200 self.versions[..self.len as usize].iter()
1201 }
1202}
1203
1204impl<'a> IntoEvent<&'a [u32]> for &'a DcSupportedVersions {
1205 fn into_event(self) -> &'a [u32] {
1206 &self.versions[..self.len as usize]
1207 }
1208}
1209
1210#[derive(Clone, Copy, Debug, PartialEq, Default)]
1213pub enum MtuProbingCompleteSupport {
1214 #[default]
1215 Enabled,
1216 Disabled,
1217}
1218
1219impl MtuProbingCompleteSupport {
1220 pub const RECOMMENDED: Self = Self::Enabled;
1221}
1222
1223impl TransportParameter for MtuProbingCompleteSupport {
1224 type CodecValue = ();
1225
1226 const ID: TransportParameterId = TransportParameterId::from_u32(0xdc0001);
1227
1228 fn from_codec_value(_value: ()) -> Self {
1229 MtuProbingCompleteSupport::Disabled
1230 }
1231
1232 fn try_into_codec_value(&self) -> Option<&()> {
1233 if let MtuProbingCompleteSupport::Disabled = self {
1234 Some(&())
1235 } else {
1236 None
1237 }
1238 }
1239
1240 fn default_value() -> Self {
1241 Self::default()
1242 }
1243}
1244
1245impl TransportParameterValidator for MtuProbingCompleteSupport {}
1246
1247impl IntoEvent<bool> for MtuProbingCompleteSupport {
1248 fn into_event(self) -> bool {
1249 matches!(self, MtuProbingCompleteSupport::Enabled)
1250 }
1251}
1252
1253#[derive(Clone, Copy, Debug, Default, PartialEq)]
1263pub struct InitialFlowControlLimits {
1264 pub stream_limits: InitialStreamLimits,
1265 pub max_data: VarInt,
1266 pub max_open_remote_bidirectional_streams: VarInt,
1267 pub max_open_remote_unidirectional_streams: VarInt,
1268}
1269
1270#[derive(Clone, Copy, Debug, Default, PartialEq)]
1272pub struct InitialStreamLimits {
1273 pub max_data_bidi_local: VarInt,
1274 pub max_data_bidi_remote: VarInt,
1275 pub max_data_uni: VarInt,
1276}
1277
1278impl InitialStreamLimits {
1279 pub fn max_data(&self, local_endpoint_type: endpoint::Type, stream_id: StreamId) -> VarInt {
1283 match (stream_id.initiator(), stream_id.stream_type()) {
1284 (endpoint_type, StreamType::Bidirectional) if endpoint_type == local_endpoint_type => {
1285 self.max_data_bidi_local
1286 }
1287 (_, StreamType::Bidirectional) => self.max_data_bidi_remote,
1288 (_, StreamType::Unidirectional) => self.max_data_uni,
1289 }
1290 }
1291}
1292
1293pub struct DatagramLimits {
1294 pub max_datagram_payload: u64,
1295}
1296
1297impl<
1298 OriginalDestinationConnectionId,
1299 StatelessResetToken,
1300 PreferredAddress,
1301 RetrySourceConnectionId,
1302 >
1303 TransportParameters<
1304 OriginalDestinationConnectionId,
1305 StatelessResetToken,
1306 PreferredAddress,
1307 RetrySourceConnectionId,
1308 >
1309{
1310 pub fn flow_control_limits(&self) -> InitialFlowControlLimits {
1312 let Self {
1313 initial_max_data,
1314 initial_max_streams_bidi,
1315 initial_max_streams_uni,
1316 ..
1317 } = self;
1318 InitialFlowControlLimits {
1319 stream_limits: self.stream_limits(),
1320 max_data: **initial_max_data,
1321 max_open_remote_bidirectional_streams: **initial_max_streams_bidi,
1322 max_open_remote_unidirectional_streams: **initial_max_streams_uni,
1323 }
1324 }
1325
1326 pub fn stream_limits(&self) -> InitialStreamLimits {
1328 let Self {
1329 initial_max_stream_data_bidi_local,
1330 initial_max_stream_data_bidi_remote,
1331 initial_max_stream_data_uni,
1332 ..
1333 } = self;
1334 InitialStreamLimits {
1335 max_data_bidi_local: **initial_max_stream_data_bidi_local,
1336 max_data_bidi_remote: **initial_max_stream_data_bidi_remote,
1337 max_data_uni: **initial_max_stream_data_uni,
1338 }
1339 }
1340
1341 pub fn ack_settings(&self) -> ack::Settings {
1343 let Self {
1344 max_ack_delay,
1345 ack_delay_exponent,
1346 ..
1347 } = self;
1348
1349 ack::Settings {
1350 max_ack_delay: max_ack_delay.as_duration(),
1351 ack_delay_exponent: **ack_delay_exponent,
1352 ..Default::default()
1353 }
1354 }
1355
1356 pub fn datagram_limits(&self) -> DatagramLimits {
1358 let max_datagram_payload = self.max_datagram_frame_size.as_u64();
1359
1360 let max_udp_payload = self.max_udp_payload_size.as_u64();
1363 DatagramLimits {
1364 max_datagram_payload: max_datagram_payload.min(max_udp_payload),
1365 }
1366 }
1367}
1368
1369mod disabled_parameter;
1377pub use disabled_parameter::DisabledParameter;
1378
1379pub type ClientTransportParameters = TransportParameters<
1381 DisabledParameter<OriginalDestinationConnectionId>,
1382 DisabledParameter<stateless_reset::Token>,
1383 DisabledParameter<PreferredAddress>,
1384 DisabledParameter<RetrySourceConnectionId>,
1385>;
1386
1387pub type ServerTransportParameters = TransportParameters<
1389 Option<OriginalDestinationConnectionId>,
1390 Option<stateless_reset::Token>,
1391 Option<PreferredAddress>,
1392 Option<RetrySourceConnectionId>,
1393>;
1394
1395impl<'a> IntoEvent<event::builder::TransportParameters<'a>> for &'a ServerTransportParameters {
1396 fn into_event(self) -> event::builder::TransportParameters<'a> {
1397 event::builder::TransportParameters {
1398 original_destination_connection_id: self
1399 .original_destination_connection_id
1400 .as_ref()
1401 .map(|cid| cid.into_event()),
1402 initial_source_connection_id: self
1403 .initial_source_connection_id
1404 .as_ref()
1405 .map(|cid| cid.into_event()),
1406 retry_source_connection_id: self
1407 .retry_source_connection_id
1408 .as_ref()
1409 .map(|cid| cid.into_event()),
1410 stateless_reset_token: self
1411 .stateless_reset_token
1412 .as_ref()
1413 .map(|token| token.as_ref()),
1414 preferred_address: self
1415 .preferred_address
1416 .as_ref()
1417 .map(|addr| addr.into_event()),
1418 migration_support: self.migration_support.into_event(),
1419 max_idle_timeout: Duration::from(self.max_idle_timeout),
1420 max_udp_payload_size: self.max_udp_payload_size.into_event(),
1421 ack_delay_exponent: self.ack_delay_exponent.into_event(),
1422 max_ack_delay: Duration::from(self.max_ack_delay),
1423 active_connection_id_limit: self.active_connection_id_limit.into_event(),
1424 initial_max_stream_data_bidi_local: self
1425 .initial_max_stream_data_bidi_local
1426 .into_event(),
1427 initial_max_stream_data_bidi_remote: self
1428 .initial_max_stream_data_bidi_remote
1429 .into_event(),
1430 initial_max_stream_data_uni: self.initial_max_stream_data_uni.into_event(),
1431 initial_max_streams_bidi: self.initial_max_streams_bidi.into_event(),
1432 initial_max_streams_uni: self.initial_max_streams_uni.into_event(),
1433 max_datagram_frame_size: self.max_datagram_frame_size.into_event(),
1434 dc_supported_versions: self.dc_supported_versions.into_event(),
1435 mtu_probing_complete_support: self.mtu_probing_complete_support.into_event(),
1436 }
1437 }
1438}
1439
1440impl<'a> IntoEvent<event::builder::TransportParameters<'a>> for &'a ClientTransportParameters {
1441 fn into_event(self) -> event::builder::TransportParameters<'a> {
1442 event::builder::TransportParameters {
1443 original_destination_connection_id: None,
1444 initial_source_connection_id: self
1445 .initial_source_connection_id
1446 .as_ref()
1447 .map(|cid| cid.into_event()),
1448 retry_source_connection_id: None,
1449 stateless_reset_token: None,
1450 preferred_address: None,
1451 migration_support: self.migration_support.into_event(),
1452 max_idle_timeout: Duration::from(self.max_idle_timeout),
1453 max_udp_payload_size: self.max_udp_payload_size.into_event(),
1454 ack_delay_exponent: self.ack_delay_exponent.into_event(),
1455 max_ack_delay: Duration::from(self.max_ack_delay),
1456 active_connection_id_limit: self.active_connection_id_limit.into_event(),
1457 initial_max_stream_data_bidi_local: self
1458 .initial_max_stream_data_bidi_local
1459 .into_event(),
1460 initial_max_stream_data_bidi_remote: self
1461 .initial_max_stream_data_bidi_remote
1462 .into_event(),
1463 initial_max_stream_data_uni: self.initial_max_stream_data_uni.into_event(),
1464 initial_max_streams_bidi: self.initial_max_streams_bidi.into_event(),
1465 initial_max_streams_uni: self.initial_max_streams_uni.into_event(),
1466 max_datagram_frame_size: self.max_datagram_frame_size.into_event(),
1467 dc_supported_versions: self.dc_supported_versions.into_event(),
1468 mtu_probing_complete_support: self.mtu_probing_complete_support.into_event(),
1469 }
1470 }
1471}
1472
1473macro_rules! impl_transport_parameters {
1474 (
1475 pub struct TransportParameters <
1476 $($server_param:ident),* $(,)? >
1477 { $($field:ident : $field_ty:ty),* $(,)? }
1478 ) => {
1479 #[derive(Clone, Copy, Debug, PartialEq)]
1480 pub struct TransportParameters<$($server_param),*> {
1481 $(
1482 pub $field: $field_ty
1483 ),*
1484 }
1485
1486 impl<$($server_param),*> Default for TransportParameters<$($server_param),*>
1487 where
1488 $(
1489 $server_param: TransportParameter,
1490 )*
1491 {
1492 fn default() -> Self {
1493 Self {
1494 $(
1495 $field: TransportParameter::default_value(),
1496 )*
1497 }
1498 }
1499 }
1500
1501 impl<$($server_param),*> EncoderValue for TransportParameters<$($server_param),*>
1502 where
1503 $(
1504 $server_param: TransportParameter,
1505 $server_param::CodecValue: EncoderValue,
1506 )*
1507 {
1508 fn encode<E: Encoder>(&self, buffer: &mut E) {
1509 $(
1510 buffer.encode(&TransportParameterCodec(&self.$field));
1511 )*
1512 }
1513 }
1514
1515 impl<'a, $($server_param),*> TransportParameters<$($server_param),*>
1516 where
1517 $(
1518 $server_param: TransportParameter + TransportParameterValidator,
1519 $server_param::CodecValue: DecoderValue<'a>,
1520 )*
1521 {
1522 fn decode_parameters(
1523 mut buffer: DecoderBuffer<'a>
1524 ) -> Result<TransportParameters<$($server_param),*>, DecoderError> {
1525 let mut parameters = Self::default();
1526
1527 #[derive(Default)]
1529 struct UsedFields {
1530 $(
1531 $field: bool,
1532 )*
1533 }
1534
1535 let mut used_fields = UsedFields::default();
1536
1537 while !buffer.is_empty() {
1538 let (tag, inner_buffer) = buffer.decode::<TransportParameterId>()?;
1539
1540 buffer = match tag {
1541 $(
1542 tag if tag == <$field_ty>::ID => {
1543 s2n_codec::decoder_invariant!(
1545 <$field_ty>::ENABLED,
1546 concat!(stringify!($field), " is not allowed in this context")
1547 );
1548
1549 s2n_codec::decoder_invariant!(
1553 core::mem::replace(&mut used_fields.$field, true) == false,
1554 concat!("duplicate value for ", stringify!($field))
1555 );
1556
1557 let (value, inner_buffer) =
1558 inner_buffer.decode::<TransportParameterCodec<$field_ty>>()?;
1559
1560 parameters.$field = value.0.validate()?;
1565
1566 inner_buffer
1567 }
1568 )*
1569 _ => {
1570 inner_buffer.skip_with_len_prefix::<TransportParameterLength>()?
1578 }
1579 }
1580 }
1581
1582 Ok(parameters)
1583 }
1584 }
1585 };
1586}
1587
1588impl_transport_parameters!(
1589 pub struct TransportParameters<
1590 OriginalDestinationConnectionId,
1591 StatelessResetToken,
1592 PreferredAddress,
1593 RetrySourceConnectionId,
1594 > {
1595 max_idle_timeout: MaxIdleTimeout,
1596 max_udp_payload_size: MaxUdpPayloadSize,
1597 initial_max_data: InitialMaxData,
1598 initial_max_stream_data_bidi_local: InitialMaxStreamDataBidiLocal,
1599 initial_max_stream_data_bidi_remote: InitialMaxStreamDataBidiRemote,
1600 initial_max_stream_data_uni: InitialMaxStreamDataUni,
1601 initial_max_streams_bidi: InitialMaxStreamsBidi,
1602 initial_max_streams_uni: InitialMaxStreamsUni,
1603 max_datagram_frame_size: MaxDatagramFrameSize,
1604 ack_delay_exponent: AckDelayExponent,
1605 max_ack_delay: MaxAckDelay,
1606 migration_support: MigrationSupport,
1607 active_connection_id_limit: ActiveConnectionIdLimit,
1608 original_destination_connection_id: OriginalDestinationConnectionId,
1609 stateless_reset_token: StatelessResetToken,
1610 preferred_address: PreferredAddress,
1611 initial_source_connection_id: Option<InitialSourceConnectionId>,
1612 retry_source_connection_id: RetrySourceConnectionId,
1613 dc_supported_versions: DcSupportedVersions,
1614 mtu_probing_complete_support: MtuProbingCompleteSupport,
1615 }
1616);
1617
1618impl<
1619 OriginalDestinationConnectionId,
1620 StatelessResetToken,
1621 PreferredAddress,
1622 RetrySourceConnectionId,
1623 >
1624 TransportParameters<
1625 OriginalDestinationConnectionId,
1626 StatelessResetToken,
1627 PreferredAddress,
1628 RetrySourceConnectionId,
1629 >
1630{
1631 pub fn load_limits(&mut self, limits: &crate::connection::limits::Limits) {
1632 macro_rules! load {
1633 ($from:ident, $to:ident) => {
1634 self.$to = limits.$from;
1635 };
1636 }
1637
1638 load!(max_idle_timeout, max_idle_timeout);
1639 load!(data_window, initial_max_data);
1640 load!(
1641 bidirectional_local_data_window,
1642 initial_max_stream_data_bidi_local
1643 );
1644 load!(
1645 bidirectional_remote_data_window,
1646 initial_max_stream_data_bidi_remote
1647 );
1648 load!(unidirectional_data_window, initial_max_stream_data_uni);
1649 load!(
1650 max_open_remote_bidirectional_streams,
1651 initial_max_streams_bidi
1652 );
1653
1654 load!(
1655 max_open_remote_unidirectional_streams,
1656 initial_max_streams_uni
1657 );
1658 load!(max_ack_delay, max_ack_delay);
1659 load!(ack_delay_exponent, ack_delay_exponent);
1660 load!(max_active_connection_ids, active_connection_id_limit);
1661 load!(max_datagram_frame_size, max_datagram_frame_size);
1662 load!(migration_support, migration_support);
1663 }
1664}