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, Default, PartialEq)]
1220pub struct InitialFlowControlLimits {
1221 pub stream_limits: InitialStreamLimits,
1222 pub max_data: VarInt,
1223 pub max_open_remote_bidirectional_streams: VarInt,
1224 pub max_open_remote_unidirectional_streams: VarInt,
1225}
1226
1227#[derive(Clone, Copy, Debug, Default, PartialEq)]
1229pub struct InitialStreamLimits {
1230 pub max_data_bidi_local: VarInt,
1231 pub max_data_bidi_remote: VarInt,
1232 pub max_data_uni: VarInt,
1233}
1234
1235impl InitialStreamLimits {
1236 pub fn max_data(&self, local_endpoint_type: endpoint::Type, stream_id: StreamId) -> VarInt {
1240 match (stream_id.initiator(), stream_id.stream_type()) {
1241 (endpoint_type, StreamType::Bidirectional) if endpoint_type == local_endpoint_type => {
1242 self.max_data_bidi_local
1243 }
1244 (_, StreamType::Bidirectional) => self.max_data_bidi_remote,
1245 (_, StreamType::Unidirectional) => self.max_data_uni,
1246 }
1247 }
1248}
1249
1250pub struct DatagramLimits {
1251 pub max_datagram_payload: u64,
1252}
1253
1254impl<
1255 OriginalDestinationConnectionId,
1256 StatelessResetToken,
1257 PreferredAddress,
1258 RetrySourceConnectionId,
1259 >
1260 TransportParameters<
1261 OriginalDestinationConnectionId,
1262 StatelessResetToken,
1263 PreferredAddress,
1264 RetrySourceConnectionId,
1265 >
1266{
1267 pub fn flow_control_limits(&self) -> InitialFlowControlLimits {
1269 let Self {
1270 initial_max_data,
1271 initial_max_streams_bidi,
1272 initial_max_streams_uni,
1273 ..
1274 } = self;
1275 InitialFlowControlLimits {
1276 stream_limits: self.stream_limits(),
1277 max_data: **initial_max_data,
1278 max_open_remote_bidirectional_streams: **initial_max_streams_bidi,
1279 max_open_remote_unidirectional_streams: **initial_max_streams_uni,
1280 }
1281 }
1282
1283 pub fn stream_limits(&self) -> InitialStreamLimits {
1285 let Self {
1286 initial_max_stream_data_bidi_local,
1287 initial_max_stream_data_bidi_remote,
1288 initial_max_stream_data_uni,
1289 ..
1290 } = self;
1291 InitialStreamLimits {
1292 max_data_bidi_local: **initial_max_stream_data_bidi_local,
1293 max_data_bidi_remote: **initial_max_stream_data_bidi_remote,
1294 max_data_uni: **initial_max_stream_data_uni,
1295 }
1296 }
1297
1298 pub fn ack_settings(&self) -> ack::Settings {
1300 let Self {
1301 max_ack_delay,
1302 ack_delay_exponent,
1303 ..
1304 } = self;
1305
1306 ack::Settings {
1307 max_ack_delay: max_ack_delay.as_duration(),
1308 ack_delay_exponent: **ack_delay_exponent,
1309 ..Default::default()
1310 }
1311 }
1312
1313 pub fn datagram_limits(&self) -> DatagramLimits {
1315 let max_datagram_payload = self.max_datagram_frame_size.as_u64();
1316
1317 let max_udp_payload = self.max_udp_payload_size.as_u64();
1320 DatagramLimits {
1321 max_datagram_payload: max_datagram_payload.min(max_udp_payload),
1322 }
1323 }
1324}
1325
1326mod disabled_parameter;
1334pub use disabled_parameter::DisabledParameter;
1335
1336pub type ClientTransportParameters = TransportParameters<
1338 DisabledParameter<OriginalDestinationConnectionId>,
1339 DisabledParameter<stateless_reset::Token>,
1340 DisabledParameter<PreferredAddress>,
1341 DisabledParameter<RetrySourceConnectionId>,
1342>;
1343
1344pub type ServerTransportParameters = TransportParameters<
1346 Option<OriginalDestinationConnectionId>,
1347 Option<stateless_reset::Token>,
1348 Option<PreferredAddress>,
1349 Option<RetrySourceConnectionId>,
1350>;
1351
1352impl<'a> IntoEvent<event::builder::TransportParameters<'a>> for &'a ServerTransportParameters {
1353 fn into_event(self) -> event::builder::TransportParameters<'a> {
1354 event::builder::TransportParameters {
1355 original_destination_connection_id: self
1356 .original_destination_connection_id
1357 .as_ref()
1358 .map(|cid| cid.into_event()),
1359 initial_source_connection_id: self
1360 .initial_source_connection_id
1361 .as_ref()
1362 .map(|cid| cid.into_event()),
1363 retry_source_connection_id: self
1364 .retry_source_connection_id
1365 .as_ref()
1366 .map(|cid| cid.into_event()),
1367 stateless_reset_token: self
1368 .stateless_reset_token
1369 .as_ref()
1370 .map(|token| token.as_ref()),
1371 preferred_address: self
1372 .preferred_address
1373 .as_ref()
1374 .map(|addr| addr.into_event()),
1375 migration_support: self.migration_support.into_event(),
1376 max_idle_timeout: Duration::from(self.max_idle_timeout),
1377 max_udp_payload_size: self.max_udp_payload_size.into_event(),
1378 ack_delay_exponent: self.ack_delay_exponent.into_event(),
1379 max_ack_delay: Duration::from(self.max_ack_delay),
1380 active_connection_id_limit: self.active_connection_id_limit.into_event(),
1381 initial_max_stream_data_bidi_local: self
1382 .initial_max_stream_data_bidi_local
1383 .into_event(),
1384 initial_max_stream_data_bidi_remote: self
1385 .initial_max_stream_data_bidi_remote
1386 .into_event(),
1387 initial_max_stream_data_uni: self.initial_max_stream_data_uni.into_event(),
1388 initial_max_streams_bidi: self.initial_max_streams_bidi.into_event(),
1389 initial_max_streams_uni: self.initial_max_streams_uni.into_event(),
1390 max_datagram_frame_size: self.max_datagram_frame_size.into_event(),
1391 dc_supported_versions: self.dc_supported_versions.into_event(),
1392 }
1393 }
1394}
1395
1396impl<'a> IntoEvent<event::builder::TransportParameters<'a>> for &'a ClientTransportParameters {
1397 fn into_event(self) -> event::builder::TransportParameters<'a> {
1398 event::builder::TransportParameters {
1399 original_destination_connection_id: None,
1400 initial_source_connection_id: self
1401 .initial_source_connection_id
1402 .as_ref()
1403 .map(|cid| cid.into_event()),
1404 retry_source_connection_id: None,
1405 stateless_reset_token: None,
1406 preferred_address: None,
1407 migration_support: self.migration_support.into_event(),
1408 max_idle_timeout: Duration::from(self.max_idle_timeout),
1409 max_udp_payload_size: self.max_udp_payload_size.into_event(),
1410 ack_delay_exponent: self.ack_delay_exponent.into_event(),
1411 max_ack_delay: Duration::from(self.max_ack_delay),
1412 active_connection_id_limit: self.active_connection_id_limit.into_event(),
1413 initial_max_stream_data_bidi_local: self
1414 .initial_max_stream_data_bidi_local
1415 .into_event(),
1416 initial_max_stream_data_bidi_remote: self
1417 .initial_max_stream_data_bidi_remote
1418 .into_event(),
1419 initial_max_stream_data_uni: self.initial_max_stream_data_uni.into_event(),
1420 initial_max_streams_bidi: self.initial_max_streams_bidi.into_event(),
1421 initial_max_streams_uni: self.initial_max_streams_uni.into_event(),
1422 max_datagram_frame_size: self.max_datagram_frame_size.into_event(),
1423 dc_supported_versions: self.dc_supported_versions.into_event(),
1424 }
1425 }
1426}
1427
1428macro_rules! impl_transport_parameters {
1429 (
1430 pub struct TransportParameters <
1431 $($server_param:ident),* $(,)? >
1432 { $($field:ident : $field_ty:ty),* $(,)? }
1433 ) => {
1434 #[derive(Clone, Copy, Debug, PartialEq)]
1435 pub struct TransportParameters<$($server_param),*> {
1436 $(
1437 pub $field: $field_ty
1438 ),*
1439 }
1440
1441 impl<$($server_param),*> Default for TransportParameters<$($server_param),*>
1442 where
1443 $(
1444 $server_param: TransportParameter,
1445 )*
1446 {
1447 fn default() -> Self {
1448 Self {
1449 $(
1450 $field: TransportParameter::default_value(),
1451 )*
1452 }
1453 }
1454 }
1455
1456 impl<$($server_param),*> EncoderValue for TransportParameters<$($server_param),*>
1457 where
1458 $(
1459 $server_param: TransportParameter,
1460 $server_param::CodecValue: EncoderValue,
1461 )*
1462 {
1463 fn encode<E: Encoder>(&self, buffer: &mut E) {
1464 $(
1465 buffer.encode(&TransportParameterCodec(&self.$field));
1466 )*
1467 }
1468 }
1469
1470 impl<'a, $($server_param),*> TransportParameters<$($server_param),*>
1471 where
1472 $(
1473 $server_param: TransportParameter + TransportParameterValidator,
1474 $server_param::CodecValue: DecoderValue<'a>,
1475 )*
1476 {
1477 fn decode_parameters(
1478 mut buffer: DecoderBuffer<'a>
1479 ) -> Result<TransportParameters<$($server_param),*>, DecoderError> {
1480 let mut parameters = Self::default();
1481
1482 #[derive(Default)]
1484 struct UsedFields {
1485 $(
1486 $field: bool,
1487 )*
1488 }
1489
1490 let mut used_fields = UsedFields::default();
1491
1492 while !buffer.is_empty() {
1493 let (tag, inner_buffer) = buffer.decode::<TransportParameterId>()?;
1494
1495 buffer = match tag {
1496 $(
1497 tag if tag == <$field_ty>::ID => {
1498 s2n_codec::decoder_invariant!(
1500 <$field_ty>::ENABLED,
1501 concat!(stringify!($field), " is not allowed in this context")
1502 );
1503
1504 s2n_codec::decoder_invariant!(
1508 core::mem::replace(&mut used_fields.$field, true) == false,
1509 concat!("duplicate value for ", stringify!($field))
1510 );
1511
1512 let (value, inner_buffer) =
1513 inner_buffer.decode::<TransportParameterCodec<$field_ty>>()?;
1514
1515 parameters.$field = value.0.validate()?;
1520
1521 inner_buffer
1522 }
1523 )*
1524 _ => {
1525 inner_buffer.skip_with_len_prefix::<TransportParameterLength>()?
1533 }
1534 }
1535 }
1536
1537 Ok(parameters)
1538 }
1539 }
1540 };
1541}
1542
1543impl_transport_parameters!(
1544 pub struct TransportParameters<
1545 OriginalDestinationConnectionId,
1546 StatelessResetToken,
1547 PreferredAddress,
1548 RetrySourceConnectionId,
1549 > {
1550 max_idle_timeout: MaxIdleTimeout,
1551 max_udp_payload_size: MaxUdpPayloadSize,
1552 initial_max_data: InitialMaxData,
1553 initial_max_stream_data_bidi_local: InitialMaxStreamDataBidiLocal,
1554 initial_max_stream_data_bidi_remote: InitialMaxStreamDataBidiRemote,
1555 initial_max_stream_data_uni: InitialMaxStreamDataUni,
1556 initial_max_streams_bidi: InitialMaxStreamsBidi,
1557 initial_max_streams_uni: InitialMaxStreamsUni,
1558 max_datagram_frame_size: MaxDatagramFrameSize,
1559 ack_delay_exponent: AckDelayExponent,
1560 max_ack_delay: MaxAckDelay,
1561 migration_support: MigrationSupport,
1562 active_connection_id_limit: ActiveConnectionIdLimit,
1563 original_destination_connection_id: OriginalDestinationConnectionId,
1564 stateless_reset_token: StatelessResetToken,
1565 preferred_address: PreferredAddress,
1566 initial_source_connection_id: Option<InitialSourceConnectionId>,
1567 retry_source_connection_id: RetrySourceConnectionId,
1568 dc_supported_versions: DcSupportedVersions,
1569 }
1570);
1571
1572impl<
1573 OriginalDestinationConnectionId,
1574 StatelessResetToken,
1575 PreferredAddress,
1576 RetrySourceConnectionId,
1577 >
1578 TransportParameters<
1579 OriginalDestinationConnectionId,
1580 StatelessResetToken,
1581 PreferredAddress,
1582 RetrySourceConnectionId,
1583 >
1584{
1585 pub fn load_limits(&mut self, limits: &crate::connection::limits::Limits) {
1586 macro_rules! load {
1587 ($from:ident, $to:ident) => {
1588 self.$to = limits.$from;
1589 };
1590 }
1591
1592 load!(max_idle_timeout, max_idle_timeout);
1593 load!(data_window, initial_max_data);
1594 load!(
1595 bidirectional_local_data_window,
1596 initial_max_stream_data_bidi_local
1597 );
1598 load!(
1599 bidirectional_remote_data_window,
1600 initial_max_stream_data_bidi_remote
1601 );
1602 load!(unidirectional_data_window, initial_max_stream_data_uni);
1603 load!(
1604 max_open_remote_bidirectional_streams,
1605 initial_max_streams_bidi
1606 );
1607
1608 load!(
1609 max_open_remote_unidirectional_streams,
1610 initial_max_streams_uni
1611 );
1612 load!(max_ack_delay, max_ack_delay);
1613 load!(ack_delay_exponent, ack_delay_exponent);
1614 load!(max_active_connection_ids, active_connection_id_limit);
1615 load!(max_datagram_frame_size, max_datagram_frame_size);
1616 load!(migration_support, migration_support);
1617 }
1618}