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
262#[cfg(feature = "std")]
263impl std::error::Error for ValidationError {}
264
265macro_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 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 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 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
397macro_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 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
463connection_id_parameter!(OriginalDestinationConnectionId, InitialId, 0x00);
470optional_transport_parameter!(OriginalDestinationConnectionId);
471
472transport_parameter!(MaxIdleTimeout(VarInt), 0x01, VarInt::from_u8(0));
479
480impl MaxIdleTimeout {
481 pub const RECOMMENDED: Self = Self(VarInt::from_u32(30_000));
483
484 pub fn load_peer(&mut self, peer: &Self) {
486 match (self.as_duration(), peer.as_duration()) {
492 (Some(current_duration), Some(peer_duration)) => {
493 if current_duration > peer_duration {
495 *self = *peer;
496 }
497 }
498 (Some(_), None) => {
499 }
501 (None, Some(_)) => {
502 *self = *peer;
503 }
504 (None, None) => {
505 }
507 }
508 }
509
510 pub fn as_duration(&self) -> Option<Duration> {
512 let duration = Duration::from_millis(self.0.as_u64());
513
514 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
542optional_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
573transport_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
610varint_transport_parameter!(InitialMaxData, 0x04);
618
619pub const fn compute_data_window(mbps: u64, rtt: Duration, rtt_count: u64) -> VarInt {
621 let mut window = mbps;
623 window *= 125;
625 window *= rtt.as_millis() as u64;
627 window *= rtt_count;
629
630 VarInt::from_u32(window as u32)
631}
632
633impl InitialMaxData {
634 pub const RECOMMENDED: Self = Self(compute_data_window(150, Duration::from_millis(100), 2));
636}
637
638impl TransportParameterValidator for InitialMaxData {}
639
640varint_transport_parameter!(InitialMaxStreamDataBidiLocal, 0x05);
652
653impl InitialMaxStreamDataBidiLocal {
654 pub const RECOMMENDED: Self = Self(InitialMaxData::RECOMMENDED.0);
656}
657
658impl TransportParameterValidator for InitialMaxStreamDataBidiLocal {}
659
660varint_transport_parameter!(InitialMaxStreamDataBidiRemote, 0x06);
671
672impl InitialMaxStreamDataBidiRemote {
673 pub const RECOMMENDED: Self = Self(InitialMaxData::RECOMMENDED.0);
675}
676
677impl TransportParameterValidator for InitialMaxStreamDataBidiRemote {}
678
679varint_transport_parameter!(InitialMaxStreamDataUni, 0x07);
690
691impl InitialMaxStreamDataUni {
692 pub const RECOMMENDED: Self = Self(InitialMaxData::RECOMMENDED.0);
694}
695
696impl TransportParameterValidator for InitialMaxStreamDataUni {}
697
698varint_transport_parameter!(InitialMaxStreamsBidi, 0x08);
709
710impl InitialMaxStreamsBidi {
711 pub const RECOMMENDED: Self = Self(VarInt::from_u8(100));
713}
714
715impl TransportParameterValidator for InitialMaxStreamsBidi {
716 fn validate(self) -> Result<Self, DecoderError> {
717 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
735varint_transport_parameter!(InitialMaxStreamsUni, 0x09);
746
747impl InitialMaxStreamsUni {
748 pub const RECOMMENDED: Self = Self(VarInt::from_u8(100));
750}
751
752impl TransportParameterValidator for InitialMaxStreamsUni {
753 fn validate(self) -> Result<Self, DecoderError> {
754 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
772transport_parameter!(MaxDatagramFrameSize(VarInt), 0x20, VarInt::from_u16(0));
780
781impl MaxDatagramFrameSize {
782 pub const RECOMMENDED: u64 = 65535;
787 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
810transport_parameter!(AckDelayExponent(u8), 0x0a, 3);
818
819impl AckDelayExponent {
820 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
835duration_transport_parameter!(MaxAckDelay, 0x0b, VarInt::from_u8(25));
846
847impl MaxAckDelay {
848 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#[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
903optional_transport_parameter!(PreferredAddress);
913
914type 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
1017varint_transport_parameter!(ActiveConnectionIdLimit, 0x0e, VarInt::from_u8(2));
1033
1034impl ActiveConnectionIdLimit {
1035 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 pub fn is_default(self) -> bool {
1052 self == Self::default_value()
1053 }
1054}
1055
1056connection_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
1070connection_id_parameter!(RetrySourceConnectionId, LocalId, 0x10);
1076optional_transport_parameter!(RetrySourceConnectionId);
1077
1078#[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}
1085const DC_SUPPORTED_VERSIONS_MAX_LEN: u8 = 4;
1088
1089impl DcSupportedVersions {
1090 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 pub fn for_server(supported_version: u32) -> Self {
1111 DcSupportedVersions {
1112 len: 1,
1113 versions: [supported_version, 0, 0, 0],
1114 }
1115 }
1116
1117 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 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#[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#[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 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 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 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 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 pub fn datagram_limits(&self) -> DatagramLimits {
1316 let max_datagram_payload = self.max_datagram_frame_size.as_u64();
1317
1318 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
1327mod disabled_parameter;
1335pub use disabled_parameter::DisabledParameter;
1336
1337pub type ClientTransportParameters = TransportParameters<
1339 DisabledParameter<OriginalDestinationConnectionId>,
1340 DisabledParameter<stateless_reset::Token>,
1341 DisabledParameter<PreferredAddress>,
1342 DisabledParameter<RetrySourceConnectionId>,
1343>;
1344
1345pub 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 #[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 s2n_codec::decoder_invariant!(
1501 <$field_ty>::ENABLED,
1502 concat!(stringify!($field), " is not allowed in this context")
1503 );
1504
1505 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 parameters.$field = value.0.validate()?;
1521
1522 inner_buffer
1523 }
1524 )*
1525 _ => {
1526 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}