1use std::{
2 fmt::{self, Write},
3 mem,
4 net::{IpAddr, SocketAddr},
5 ops::{Range, RangeInclusive},
6};
7
8use bytes::{Buf, BufMut, Bytes};
9use tinyvec::TinyVec;
10
11use crate::{
12 Dir, MAX_CID_SIZE, RESET_TOKEN_SIZE, ResetToken, StreamId, TransportError, TransportErrorCode,
13 VarInt,
14 coding::{self, BufExt, BufMutExt, Decodable, Encodable, UnexpectedEnd},
15 connection::PathId,
16 range_set::ArrayRangeSet,
17 shared::{ConnectionId, EcnCodepoint},
18};
19
20#[cfg(feature = "arbitrary")]
21use arbitrary::Arbitrary;
22
23macro_rules! frame_types {
25 (enum_defs: [$($enum_defs: tt)*] try_from_arms: [$($try_from_arms: tt)*] to_u64_arms:[$($to_u64_arms: tt)*] $variant: ident = $value: literal, $($token: tt)*) => {
29 frame_types!{
30 enum_defs: [$($enum_defs)* $variant,]
31 try_from_arms: [$($try_from_arms)* $value => Self::$variant,]
32 to_u64_arms: [$($to_u64_arms)* FrameType::$variant => $value,]
33 $($token)*
34 }
35 };
36
37 (enum_defs: [$($enum_defs: tt)*] try_from_arms: [$($try_from_arms: tt)*] to_u64_arms:[$($to_u64_arms: tt)*] $variant: ident($inner: ident), $($token: tt)*) => {
41 frame_types!{
42 enum_defs: [$($enum_defs)* $variant($inner),]
43 try_from_arms: [$($try_from_arms)* value if <$inner>::VALUES.contains(&value) => Self::$variant($inner(value as u8)),]
44 to_u64_arms: [$($to_u64_arms)* FrameType::$variant($inner(value)) => value as u64,]
45 $($token)*
46 }
47 };
48
49 (enum_defs: [$($enum_defs: tt)+] try_from_arms: [$($try_from_arms: tt)+] to_u64_arms: [$($to_u64_arms: tt)+]) => {
51 #[derive(Copy, Clone, Eq, PartialEq, derive_more::Debug, derive_more::Display)]
53 #[display(rename_all = "SCREAMING_SNAKE_CASE")]
54 #[allow(missing_docs)]
55 pub enum FrameType {
56 $($enum_defs)*
57 }
58
59 pub struct InvalidFrameId(u64);
60
61 impl TryFrom<u64> for FrameType {
62 type Error = InvalidFrameId;
63 fn try_from(value: u64) -> Result<Self, Self::Error> {
64 Ok(match value {
65 $($try_from_arms)*
66 other => return Err(InvalidFrameId(other))
67 })
68 }
69 }
70
71 impl FrameType {
72 pub(crate) const fn to_u64(self) -> u64 {
73 match self {
74 $($to_u64_arms)*
75 }
76 }
77 }
78 };
79}
80
81frame_types! {
82 enum_defs: []
83 try_from_arms: []
84 to_u64_arms: []
85 Padding = 0x00,
86 Ping = 0x01,
87 Ack = 0x02,
88 AckEcn = 0x03,
89 ResetStream = 0x04,
90 StopSending = 0x05,
91 Crypto = 0x06,
92 NewToken = 0x07,
93 Stream(StreamInfo),
95 MaxData = 0x10,
96 MaxStreamData = 0x11,
97 MaxStreamsBidi = 0x12,
98 MaxStreamsUni = 0x13,
99 DataBlocked = 0x14,
100 StreamDataBlocked = 0x15,
101 StreamsBlockedBidi = 0x16,
102 StreamsBlockedUni = 0x17,
103 NewConnectionId = 0x18,
104 RetireConnectionId = 0x19,
105 PathChallenge = 0x1a,
106 PathResponse = 0x1b,
107 ConnectionClose = 0x1c,
108 ApplicationClose = 0x1d,
109 HandshakeDone = 0x1e,
110 AckFrequency = 0xaf,
112 ImmediateAck = 0x1f,
113 Datagram(DatagramInfo),
115 ObservedIpv4Addr = 0x9f81a6,
117 ObservedIpv6Addr = 0x9f81a7,
118 PathAck = 0x15228c00,
120 PathAckEcn = 0x15228c01,
121 PathAbandon = 0x15228c05,
122 PathStatusBackup = 0x15228c07,
123 PathStatusAvailable = 0x15228c08,
124 PathNewConnectionId = 0x15228c09,
125 PathRetireConnectionId = 0x15228c0a,
126 MaxPathId = 0x15228c0c,
127 PathsBlocked = 0x15228c0d,
128 PathCidsBlocked = 0x15228c0e,
129 AddIpv4Address = 0x3d7f90,
131 AddIpv6Address = 0x3d7f91,
132 ReachOutAtIpv4 = 0x3d7f92,
133 ReachOutAtIpv6 = 0x3d7f93,
134 RemoveAddress = 0x3d7f94,
135}
136
137impl FrameType {
138 const fn size(&self) -> usize {
140 VarInt(self.to_u64()).size()
141 }
142}
143
144impl Decodable for FrameType {
145 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
146 Self::try_from(buf.get_var()?).map_err(|_| coding::UnexpectedEnd)
147 }
148}
149
150impl Encodable for FrameType {
151 fn encode<B: BufMut>(&self, buf: &mut B) {
152 buf.write_var(self.to_u64());
153 }
154}
155
156pub(crate) trait FrameStruct {
157 const SIZE_BOUND: usize;
159}
160
161#[derive(Copy, Clone, Eq, PartialEq, derive_more::Debug, derive_more::Display)]
163pub enum MaybeFrame {
164 None,
166 #[display("UNKNOWN{:02x}", _0)]
168 #[debug("Unknown{:02x}", _0)]
169 Unknown(u64),
170 Known(FrameType),
172}
173
174impl MaybeFrame {
175 const fn size(&self) -> usize {
177 match self {
178 Self::None => VarInt(0).size(),
179 Self::Unknown(other) => VarInt(*other).size(),
180 Self::Known(frame_type) => frame_type.size(),
181 }
182 }
183}
184
185impl Decodable for MaybeFrame {
186 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
187 match FrameType::try_from(buf.get_var()?) {
188 Ok(FrameType::Padding) => Ok(Self::None),
189 Ok(other_frame) => Ok(Self::Known(other_frame)),
190 Err(InvalidFrameId(other)) => Ok(Self::Unknown(other)),
191 }
192 }
193}
194
195impl Encodable for MaybeFrame {
196 fn encode<B: BufMut>(&self, buf: &mut B) {
197 match self {
198 Self::None => buf.write(0u64),
199 Self::Unknown(frame_id) => buf.write(*frame_id),
200 Self::Known(frame_type) => buf.write(*frame_type),
201 }
202 }
203}
204
205#[derive(Debug, Copy, Clone, Eq, PartialEq, derive_more::Display)]
206#[display("STREAM")]
207pub struct StreamInfo(u8);
208
209impl StreamInfo {
210 const VALUES: RangeInclusive<u64> = RangeInclusive::new(0x08, 0x0f);
211 fn fin(self) -> bool {
212 self.0 & 0x01 != 0
213 }
214 fn len(self) -> bool {
215 self.0 & 0x02 != 0
216 }
217 fn off(self) -> bool {
218 self.0 & 0x04 != 0
219 }
220}
221
222#[derive(Debug, Copy, Clone, Eq, PartialEq, derive_more::Display)]
223#[display("DATAGRAM")]
224pub struct DatagramInfo(u8);
225
226impl DatagramInfo {
227 const VALUES: RangeInclusive<u64> = RangeInclusive::new(0x30, 0x31);
228
229 fn len(self) -> bool {
230 self.0 & 0x01 != 0
231 }
232}
233
234#[derive(Debug)]
235pub(crate) enum Frame {
236 Padding,
237 Ping,
238 Ack(Ack),
239 PathAck(PathAck),
240 ResetStream(ResetStream),
241 StopSending(StopSending),
242 Crypto(Crypto),
243 NewToken(NewToken),
244 Stream(Stream),
245 MaxData(VarInt),
246 MaxStreamData { id: StreamId, offset: u64 },
247 MaxStreams { dir: Dir, count: u64 },
248 DataBlocked { offset: u64 },
249 StreamDataBlocked { id: StreamId, offset: u64 },
250 StreamsBlocked { dir: Dir, limit: u64 },
251 NewConnectionId(NewConnectionId),
252 RetireConnectionId(RetireConnectionId),
253 PathChallenge(PathChallenge),
254 PathResponse(PathResponse),
255 Close(Close),
256 Datagram(Datagram),
257 AckFrequency(AckFrequency),
258 ImmediateAck,
259 HandshakeDone,
260 ObservedAddr(ObservedAddr),
261 PathAbandon(PathAbandon),
262 PathStatusAvailable(PathStatusAvailable),
263 PathStatusBackup(PathStatusBackup),
264 MaxPathId(MaxPathId),
265 PathsBlocked(PathsBlocked),
266 PathCidsBlocked(PathCidsBlocked),
267 AddAddress(AddAddress),
268 ReachOut(ReachOut),
269 RemoveAddress(RemoveAddress),
270}
271
272impl fmt::Display for Frame {
273 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
274 match self {
277 Self::Padding => write!(f, "PADDING"),
278 Self::Ping => write!(f, "PING"),
279 Self::PathChallenge(frame) => write!(f, "{frame}"),
280 Self::PathResponse(frame) => write!(f, "{frame}"),
281 Self::ImmediateAck => write!(f, "IMMEDIATE_ACK"),
282 Self::HandshakeDone => write!(f, "HANDSHAKE_DONE"),
283 _ => write!(f, "{self:?}"),
284 }
285 }
286}
287
288impl Frame {
289 pub(crate) fn ty(&self) -> FrameType {
290 use Frame::*;
291 match *self {
292 Padding => FrameType::Padding,
293 ResetStream(_) => FrameType::ResetStream,
294 Close(self::Close::Connection(_)) => FrameType::ConnectionClose,
295 Close(self::Close::Application(_)) => FrameType::ConnectionClose,
296 MaxData(_) => FrameType::MaxData,
297 MaxStreamData { .. } => FrameType::MaxStreamData,
298 MaxStreams { dir: Dir::Bi, .. } => FrameType::MaxStreamsBidi,
299 MaxStreams { dir: Dir::Uni, .. } => FrameType::MaxStreamsUni,
300 Ping => FrameType::Ping,
301 DataBlocked { .. } => FrameType::DataBlocked,
302 StreamDataBlocked { .. } => FrameType::StreamDataBlocked,
303 StreamsBlocked { dir: Dir::Bi, .. } => FrameType::StreamsBlockedBidi,
304 StreamsBlocked { dir: Dir::Uni, .. } => FrameType::StreamsBlockedUni,
305 StopSending { .. } => FrameType::StopSending,
306 RetireConnectionId { .. } => FrameType::RetireConnectionId,
307 Ack(_) => FrameType::Ack,
308 PathAck(_) => FrameType::PathAck,
309 Stream(ref x) => {
310 let mut ty = *StreamInfo::VALUES.start() as u8;
311 if x.fin {
312 ty |= 0x01;
313 }
314 if x.offset != 0 {
315 ty |= 0x04;
316 }
317 FrameType::Stream(StreamInfo(ty))
319 }
320 PathChallenge(_) => FrameType::PathChallenge,
321 PathResponse(_) => FrameType::PathResponse,
322 NewConnectionId(cid) => cid.get_type(),
323 Crypto(_) => FrameType::Crypto,
324 NewToken(_) => FrameType::NewToken,
325 Datagram(_) => FrameType::Datagram(DatagramInfo(*DatagramInfo::VALUES.start() as u8)),
326 AckFrequency(_) => FrameType::AckFrequency,
327 ImmediateAck => FrameType::ImmediateAck,
328 HandshakeDone => FrameType::HandshakeDone,
329 ObservedAddr(ref observed) => observed.get_type(),
330 PathAbandon(_) => FrameType::PathAbandon,
331 PathStatusAvailable(_) => FrameType::PathStatusAvailable,
332 PathStatusBackup(_) => FrameType::PathStatusBackup,
333 MaxPathId(_) => FrameType::MaxPathId,
334 PathsBlocked(_) => FrameType::PathsBlocked,
335 PathCidsBlocked(_) => FrameType::PathCidsBlocked,
336 AddAddress(ref frame) => frame.get_type(),
337 ReachOut(ref frame) => frame.get_type(),
338 RemoveAddress(_) => self::RemoveAddress::TYPE,
339 }
340 }
341
342 pub(crate) fn is_ack_eliciting(&self) -> bool {
343 !matches!(
344 *self,
345 Self::Ack(_) | Self::PathAck(_) | Self::Padding | Self::Close(_)
346 )
347 }
348
349 pub(crate) fn is_1rtt(&self) -> bool {
351 self.is_multipath_frame() || self.is_qad_frame()
357 }
358
359 fn is_qad_frame(&self) -> bool {
360 matches!(*self, Self::ObservedAddr(_))
361 }
362
363 fn is_multipath_frame(&self) -> bool {
364 matches!(
365 *self,
366 Self::PathAck(_)
367 | Self::PathAbandon(_)
368 | Self::PathStatusBackup(_)
369 | Self::PathStatusAvailable(_)
370 | Self::MaxPathId(_)
371 | Self::PathsBlocked(_)
372 | Self::PathCidsBlocked(_)
373 | Self::NewConnectionId(NewConnectionId {
374 path_id: Some(_),
375 ..
376 })
377 | Self::RetireConnectionId(RetireConnectionId {
378 path_id: Some(_),
379 ..
380 })
381 )
382 }
383}
384
385#[derive(Debug, Clone, Copy, PartialEq, Eq, derive_more::Display)]
386#[display("PATH_CHALLENGE({_0:08x})")]
387pub(crate) struct PathChallenge(pub(crate) u64);
388
389impl PathChallenge {
390 pub(crate) const SIZE_BOUND: usize = 9;
391}
392impl Decodable for PathChallenge {
393 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
394 Ok(Self(buf.get()?))
395 }
396}
397impl Encodable for PathChallenge {
398 fn encode<B: BufMut>(&self, buf: &mut B) {
399 buf.write(FrameType::PathChallenge);
400 buf.write(self.0);
401 }
402}
403
404#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, derive_more::Display)]
405#[display("PATH_RESPONSE({_0:08x})")]
406pub(crate) struct PathResponse(pub(crate) u64);
407
408impl PathResponse {
409 pub(crate) const SIZE_BOUND: usize = 9;
410}
411
412impl Decodable for PathResponse {
413 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
414 Ok(Self(buf.get()?))
415 }
416}
417impl Encodable for PathResponse {
418 fn encode<B: BufMut>(&self, buf: &mut B) {
419 buf.write(FrameType::PathResponse);
420 buf.write(self.0);
421 }
422}
423
424#[derive(Debug, PartialEq, Eq)]
425pub(crate) struct RetireConnectionId {
426 pub(crate) path_id: Option<PathId>,
427 pub(crate) sequence: u64,
428}
429
430impl RetireConnectionId {
431 pub(crate) const SIZE_BOUND: usize = {
433 let type_len = FrameType::RetireConnectionId.size();
434 let seq_max_len = 8usize;
435 type_len + seq_max_len
436 };
437
438 pub(crate) const SIZE_BOUND_MULTIPATH: usize = {
440 let type_len = FrameType::PathRetireConnectionId.size();
441 let path_id_len = VarInt::from_u32(u32::MAX).size();
442 let seq_max_len = 8usize;
443 type_len + path_id_len + seq_max_len
444 };
445
446 pub(crate) fn decode<R: Buf>(bytes: &mut R, read_path: bool) -> coding::Result<Self> {
449 Ok(Self {
450 path_id: if read_path { Some(bytes.get()?) } else { None },
451 sequence: bytes.get_var()?,
452 })
453 }
454
455 pub(crate) fn get_type(&self) -> FrameType {
457 if self.path_id.is_some() {
458 FrameType::PathRetireConnectionId
459 } else {
460 FrameType::RetireConnectionId
461 }
462 }
463
464 pub(crate) const fn size_bound(path_retire_cid: bool) -> usize {
469 match path_retire_cid {
470 true => Self::SIZE_BOUND_MULTIPATH,
471 false => Self::SIZE_BOUND,
472 }
473 }
474}
475
476impl Encodable for RetireConnectionId {
477 fn encode<W: BufMut>(&self, buf: &mut W) {
478 buf.write(self.get_type());
479 if let Some(id) = self.path_id {
480 buf.write(id);
481 }
482 buf.write_var(self.sequence);
483 }
484}
485
486#[derive(Clone, Debug)]
487pub enum Close {
488 Connection(ConnectionClose),
489 Application(ApplicationClose),
490}
491
492impl Close {
493 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
494 match *self {
495 Self::Connection(ref x) => x.encode(out, max_len),
496 Self::Application(ref x) => x.encode(out, max_len),
497 }
498 }
499
500 pub(crate) fn is_transport_layer(&self) -> bool {
501 matches!(*self, Self::Connection(_))
502 }
503}
504
505impl From<TransportError> for Close {
506 fn from(x: TransportError) -> Self {
507 Self::Connection(x.into())
508 }
509}
510impl From<ConnectionClose> for Close {
511 fn from(x: ConnectionClose) -> Self {
512 Self::Connection(x)
513 }
514}
515impl From<ApplicationClose> for Close {
516 fn from(x: ApplicationClose) -> Self {
517 Self::Application(x)
518 }
519}
520
521#[derive(Debug, Clone, PartialEq, Eq)]
523pub struct ConnectionClose {
524 pub error_code: TransportErrorCode,
526 pub frame_type: MaybeFrame,
528 pub reason: Bytes,
530}
531
532impl fmt::Display for ConnectionClose {
533 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
534 self.error_code.fmt(f)?;
535 if !self.reason.as_ref().is_empty() {
536 f.write_str(": ")?;
537 f.write_str(&String::from_utf8_lossy(&self.reason))?;
538 }
539 Ok(())
540 }
541}
542
543impl From<TransportError> for ConnectionClose {
544 fn from(x: TransportError) -> Self {
545 Self {
546 error_code: x.code,
547 frame_type: x.frame,
548 reason: x.reason.into(),
549 }
550 }
551}
552
553impl FrameStruct for ConnectionClose {
554 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
555}
556
557impl ConnectionClose {
558 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
559 out.write(FrameType::ConnectionClose); out.write(self.error_code); out.write(self.frame_type); let max_len = max_len
563 - 3
564 - self.frame_type.size()
565 - VarInt::from_u64(self.reason.len() as u64).unwrap().size();
566 let actual_len = self.reason.len().min(max_len);
567 out.write_var(actual_len as u64); out.put_slice(&self.reason[0..actual_len]); }
570}
571
572#[derive(Debug, Clone, PartialEq, Eq)]
574pub struct ApplicationClose {
575 pub error_code: VarInt,
577 pub reason: Bytes,
579}
580
581impl fmt::Display for ApplicationClose {
582 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
583 if !self.reason.as_ref().is_empty() {
584 f.write_str(&String::from_utf8_lossy(&self.reason))?;
585 f.write_str(" (code ")?;
586 self.error_code.fmt(f)?;
587 f.write_str(")")?;
588 } else {
589 self.error_code.fmt(f)?;
590 }
591 Ok(())
592 }
593}
594
595impl FrameStruct for ApplicationClose {
596 const SIZE_BOUND: usize = 1 + 8 + 8;
597}
598
599impl ApplicationClose {
600 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
601 out.write(FrameType::ApplicationClose); out.write(self.error_code); let max_len = max_len - 3 - VarInt::from_u64(self.reason.len() as u64).unwrap().size();
604 let actual_len = self.reason.len().min(max_len);
605 out.write_var(actual_len as u64); out.put_slice(&self.reason[0..actual_len]); }
608}
609
610#[derive(Clone, Eq, PartialEq)]
611pub struct PathAck {
612 pub path_id: PathId,
613 pub largest: u64,
614 pub delay: u64,
615 pub additional: Bytes,
616 pub ecn: Option<EcnCounts>,
617}
618
619impl fmt::Debug for PathAck {
620 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
621 let mut ranges = "[".to_string();
622 let mut first = true;
623 for range in self.into_iter() {
624 if !first {
625 ranges.push(',');
626 }
627 write!(ranges, "{range:?}")?;
628 first = false;
629 }
630 ranges.push(']');
631
632 f.debug_struct("PathAck")
633 .field("path_id", &self.path_id)
634 .field("largest", &self.largest)
635 .field("delay", &self.delay)
636 .field("ecn", &self.ecn)
637 .field("ranges", &ranges)
638 .finish()
639 }
640}
641
642impl<'a> IntoIterator for &'a PathAck {
643 type Item = RangeInclusive<u64>;
644 type IntoIter = AckIter<'a>;
645
646 fn into_iter(self) -> AckIter<'a> {
647 AckIter::new(self.largest, &self.additional[..])
648 }
649}
650
651impl PathAck {
652 pub fn encode<W: BufMut>(
659 path_id: PathId,
660 delay: u64,
661 ranges: &ArrayRangeSet,
662 ecn: Option<&EcnCounts>,
663 buf: &mut W,
664 ) {
665 let mut rest = ranges.iter().rev();
666 let first = rest
667 .next()
668 .expect("Caller has verified ranges is non empty");
669 let largest = first.end - 1;
670 let first_size = first.end - first.start;
671 let kind = match ecn.is_some() {
672 true => FrameType::PathAckEcn,
673 false => FrameType::PathAck,
674 };
675 buf.write(kind);
676 buf.write(path_id);
677 buf.write_var(largest);
678 buf.write_var(delay);
679 buf.write_var(ranges.len() as u64 - 1);
680 buf.write_var(first_size - 1);
681 let mut prev = first.start;
682 for block in rest {
683 let size = block.end - block.start;
684 buf.write_var(prev - block.end - 1);
685 buf.write_var(size - 1);
686 prev = block.start;
687 }
688 if let Some(x) = ecn {
689 x.encode(buf)
690 }
691 }
692
693 pub fn into_ack(self) -> (Ack, PathId) {
694 let ack = Ack {
695 largest: self.largest,
696 delay: self.delay,
697 additional: self.additional,
698 ecn: self.ecn,
699 };
700
701 (ack, self.path_id)
702 }
703}
704
705#[derive(Clone, Eq, PartialEq)]
706pub struct Ack {
707 pub largest: u64,
708 pub delay: u64,
709 pub additional: Bytes,
710 pub ecn: Option<EcnCounts>,
711}
712
713impl fmt::Debug for Ack {
714 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
715 let mut ranges = "[".to_string();
716 let mut first = true;
717 for range in self.iter() {
718 if !first {
719 ranges.push(',');
720 }
721 write!(ranges, "{range:?}").unwrap();
722 first = false;
723 }
724 ranges.push(']');
725
726 f.debug_struct("Ack")
727 .field("largest", &self.largest)
728 .field("delay", &self.delay)
729 .field("ecn", &self.ecn)
730 .field("ranges", &ranges)
731 .finish()
732 }
733}
734
735impl<'a> IntoIterator for &'a Ack {
736 type Item = RangeInclusive<u64>;
737 type IntoIter = AckIter<'a>;
738
739 fn into_iter(self) -> AckIter<'a> {
740 AckIter::new(self.largest, &self.additional[..])
741 }
742}
743
744impl Ack {
745 pub fn encode<W: BufMut>(
746 delay: u64,
747 ranges: &ArrayRangeSet,
748 ecn: Option<&EcnCounts>,
749 buf: &mut W,
750 ) {
751 let mut rest = ranges.iter().rev();
752 let first = rest.next().unwrap();
753 let largest = first.end - 1;
754 let first_size = first.end - first.start;
755 let kind = match ecn.is_some() {
756 true => FrameType::AckEcn,
757 false => FrameType::Ack,
758 };
759 buf.write(kind);
760 buf.write_var(largest);
761 buf.write_var(delay);
762 buf.write_var(ranges.len() as u64 - 1);
763 buf.write_var(first_size - 1);
764 let mut prev = first.start;
765 for block in rest {
766 let size = block.end - block.start;
767 buf.write_var(prev - block.end - 1);
768 buf.write_var(size - 1);
769 prev = block.start;
770 }
771 if let Some(x) = ecn {
772 x.encode(buf)
773 }
774 }
775
776 pub fn iter(&self) -> AckIter<'_> {
777 self.into_iter()
778 }
779}
780
781#[derive(Debug, Copy, Clone, Eq, PartialEq)]
782pub struct EcnCounts {
783 pub ect0: u64,
784 pub ect1: u64,
785 pub ce: u64,
786}
787
788impl std::ops::AddAssign<EcnCodepoint> for EcnCounts {
789 fn add_assign(&mut self, rhs: EcnCodepoint) {
790 match rhs {
791 EcnCodepoint::Ect0 => {
792 self.ect0 += 1;
793 }
794 EcnCodepoint::Ect1 => {
795 self.ect1 += 1;
796 }
797 EcnCodepoint::Ce => {
798 self.ce += 1;
799 }
800 }
801 }
802}
803
804impl EcnCounts {
805 pub const ZERO: Self = Self {
806 ect0: 0,
807 ect1: 0,
808 ce: 0,
809 };
810}
811
812impl Encodable for EcnCounts {
813 fn encode<W: BufMut>(&self, out: &mut W) {
814 out.write_var(self.ect0);
815 out.write_var(self.ect1);
816 out.write_var(self.ce);
817 }
818}
819
820#[derive(Debug, Clone)]
821pub(crate) struct Stream {
822 pub(crate) id: StreamId,
823 pub(crate) offset: u64,
824 pub(crate) fin: bool,
825 pub(crate) data: Bytes,
826}
827
828impl FrameStruct for Stream {
829 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
830}
831
832#[derive(Debug, Clone)]
834pub(crate) struct StreamMeta {
835 pub(crate) id: StreamId,
836 pub(crate) offsets: Range<u64>,
837 pub(crate) fin: bool,
838}
839
840impl Default for StreamMeta {
842 fn default() -> Self {
843 Self {
844 id: StreamId(0),
845 offsets: 0..0,
846 fin: false,
847 }
848 }
849}
850
851impl StreamMeta {
852 pub(crate) fn encode<W: BufMut>(&self, length: bool, out: &mut W) {
853 let mut ty = *StreamInfo::VALUES.start();
854 if self.offsets.start != 0 {
855 ty |= 0x04;
856 }
857 if length {
858 ty |= 0x02;
859 }
860 if self.fin {
861 ty |= 0x01;
862 }
863 out.write_var(ty); out.write(self.id); if self.offsets.start != 0 {
866 out.write_var(self.offsets.start); }
868 if length {
869 out.write_var(self.offsets.end - self.offsets.start); }
871 }
872}
873
874pub(crate) type StreamMetaVec = TinyVec<[StreamMeta; 1]>;
876
877#[derive(Debug, Clone)]
878pub(crate) struct Crypto {
879 pub(crate) offset: u64,
880 pub(crate) data: Bytes,
881}
882
883impl Crypto {
884 pub(crate) const SIZE_BOUND: usize = 17;
885}
886
887impl Encodable for Crypto {
888 fn encode<W: BufMut>(&self, out: &mut W) {
889 out.write(FrameType::Crypto);
890 out.write_var(self.offset);
891 out.write_var(self.data.len() as u64);
892 out.put_slice(&self.data);
893 }
894}
895
896#[derive(Debug, Clone)]
897pub(crate) struct NewToken {
898 pub(crate) token: Bytes,
899}
900
901impl Encodable for NewToken {
902 fn encode<W: BufMut>(&self, out: &mut W) {
903 out.write(FrameType::NewToken);
904 out.write_var(self.token.len() as u64);
905 out.put_slice(&self.token);
906 }
907}
908
909impl NewToken {
910 pub(crate) fn size(&self) -> usize {
911 1 + VarInt::from_u64(self.token.len() as u64).unwrap().size() + self.token.len()
912 }
913}
914
915#[derive(Debug, Clone)]
916pub(crate) struct MaxPathId(pub(crate) PathId);
917
918impl MaxPathId {
919 pub(crate) const SIZE_BOUND: usize =
920 FrameType::MaxPathId.size() + VarInt(u32::MAX as u64).size();
921}
922
923impl Decodable for MaxPathId {
924 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
925 Ok(Self(buf.get()?))
926 }
927}
928
929impl Encodable for MaxPathId {
930 fn encode<B: BufMut>(&self, buf: &mut B) {
931 buf.write(FrameType::MaxPathId);
932 buf.write(self.0);
933 }
934}
935
936#[derive(Debug, Clone, PartialEq, Eq)]
937pub(crate) struct PathsBlocked(pub(crate) PathId);
938
939impl PathsBlocked {
940 pub(crate) const SIZE_BOUND: usize =
941 FrameType::PathsBlocked.size() + VarInt(u32::MAX as u64).size();
942}
943
944impl Encodable for PathsBlocked {
945 fn encode<B: BufMut>(&self, buf: &mut B) {
946 buf.write(FrameType::PathsBlocked);
947 buf.write(self.0);
948 }
949}
950
951impl Decodable for PathsBlocked {
952 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
954 Ok(Self(buf.get()?))
955 }
956}
957
958#[derive(Debug, Clone, PartialEq, Eq)]
959pub(crate) struct PathCidsBlocked {
960 pub(crate) path_id: PathId,
961 pub(crate) next_seq: VarInt,
962}
963
964impl PathCidsBlocked {
965 pub(crate) const SIZE_BOUND: usize =
966 FrameType::PathCidsBlocked.size() + VarInt(u32::MAX as u64).size() + VarInt::MAX.size();
967}
968
969impl Decodable for PathCidsBlocked {
970 fn decode<R: Buf>(buf: &mut R) -> coding::Result<Self> {
971 Ok(Self {
972 path_id: buf.get()?,
973 next_seq: buf.get()?,
974 })
975 }
976}
977
978impl Encodable for PathCidsBlocked {
979 fn encode<W: BufMut>(&self, buf: &mut W) {
980 buf.write(FrameType::PathCidsBlocked);
981 buf.write(self.path_id);
982 buf.write(self.next_seq);
983 }
984}
985
986pub(crate) struct Iter {
987 bytes: Bytes,
988 last_ty: MaybeFrame,
989}
990
991impl Iter {
992 pub(crate) fn new(payload: Bytes) -> Result<Self, TransportError> {
993 if payload.is_empty() {
994 return Err(TransportError::PROTOCOL_VIOLATION(
998 "packet payload is empty",
999 ));
1000 }
1001
1002 Ok(Self {
1003 bytes: payload,
1004 last_ty: MaybeFrame::None,
1005 })
1006 }
1007
1008 fn take_len(&mut self) -> Result<Bytes, UnexpectedEnd> {
1009 let len = self.bytes.get_var()?;
1010 if len > self.bytes.remaining() as u64 {
1011 return Err(UnexpectedEnd);
1012 }
1013 Ok(self.bytes.split_to(len as usize))
1014 }
1015
1016 #[track_caller]
1017 fn try_next(&mut self) -> Result<Frame, IterErr> {
1018 self.last_ty = self.bytes.get()?;
1019
1020 let ty = match self.last_ty {
1021 MaybeFrame::None => FrameType::Padding,
1022 MaybeFrame::Unknown(_other) => return Err(IterErr::InvalidFrameId),
1023 MaybeFrame::Known(frame_type) => frame_type,
1024 };
1025 Ok(match ty {
1026 FrameType::Padding => Frame::Padding,
1027 FrameType::ResetStream => Frame::ResetStream(ResetStream {
1028 id: self.bytes.get()?,
1029 error_code: self.bytes.get()?,
1030 final_offset: self.bytes.get()?,
1031 }),
1032 FrameType::ConnectionClose => Frame::Close(Close::Connection(ConnectionClose {
1033 error_code: self.bytes.get()?,
1034 frame_type: self.bytes.get()?,
1035 reason: self.take_len()?,
1036 })),
1037 FrameType::ApplicationClose => Frame::Close(Close::Application(ApplicationClose {
1038 error_code: self.bytes.get()?,
1039 reason: self.take_len()?,
1040 })),
1041 FrameType::MaxData => Frame::MaxData(self.bytes.get()?),
1042 FrameType::MaxStreamData => Frame::MaxStreamData {
1043 id: self.bytes.get()?,
1044 offset: self.bytes.get_var()?,
1045 },
1046 FrameType::MaxStreamsBidi => Frame::MaxStreams {
1047 dir: Dir::Bi,
1048 count: self.bytes.get_var()?,
1049 },
1050 FrameType::MaxStreamsUni => Frame::MaxStreams {
1051 dir: Dir::Uni,
1052 count: self.bytes.get_var()?,
1053 },
1054 FrameType::Ping => Frame::Ping,
1055 FrameType::DataBlocked => Frame::DataBlocked {
1056 offset: self.bytes.get_var()?,
1057 },
1058 FrameType::StreamDataBlocked => Frame::StreamDataBlocked {
1059 id: self.bytes.get()?,
1060 offset: self.bytes.get_var()?,
1061 },
1062 FrameType::StreamsBlockedBidi => Frame::StreamsBlocked {
1063 dir: Dir::Bi,
1064 limit: self.bytes.get_var()?,
1065 },
1066 FrameType::StreamsBlockedUni => Frame::StreamsBlocked {
1067 dir: Dir::Uni,
1068 limit: self.bytes.get_var()?,
1069 },
1070 FrameType::StopSending => Frame::StopSending(StopSending {
1071 id: self.bytes.get()?,
1072 error_code: self.bytes.get()?,
1073 }),
1074 FrameType::RetireConnectionId | FrameType::PathRetireConnectionId => {
1075 Frame::RetireConnectionId(RetireConnectionId::decode(
1076 &mut self.bytes,
1077 ty == FrameType::PathRetireConnectionId,
1078 )?)
1079 }
1080 FrameType::Ack | FrameType::AckEcn => {
1081 let largest = self.bytes.get_var()?;
1082 let delay = self.bytes.get_var()?;
1083 let extra_blocks = self.bytes.get_var()? as usize;
1084 let n = scan_ack_blocks(&self.bytes, largest, extra_blocks)?;
1085 Frame::Ack(Ack {
1086 delay,
1087 largest,
1088 additional: self.bytes.split_to(n),
1089 ecn: if ty != FrameType::AckEcn && ty != FrameType::PathAckEcn {
1090 None
1091 } else {
1092 Some(EcnCounts {
1093 ect0: self.bytes.get_var()?,
1094 ect1: self.bytes.get_var()?,
1095 ce: self.bytes.get_var()?,
1096 })
1097 },
1098 })
1099 }
1100 FrameType::PathAck | FrameType::PathAckEcn => {
1101 let path_id = self.bytes.get()?;
1102 let largest = self.bytes.get_var()?;
1103 let delay = self.bytes.get_var()?;
1104 let extra_blocks = self.bytes.get_var()? as usize;
1105 let n = scan_ack_blocks(&self.bytes, largest, extra_blocks)?;
1106 Frame::PathAck(PathAck {
1107 path_id,
1108 delay,
1109 largest,
1110 additional: self.bytes.split_to(n),
1111 ecn: if ty != FrameType::AckEcn && ty != FrameType::PathAckEcn {
1112 None
1113 } else {
1114 Some(EcnCounts {
1115 ect0: self.bytes.get_var()?,
1116 ect1: self.bytes.get_var()?,
1117 ce: self.bytes.get_var()?,
1118 })
1119 },
1120 })
1121 }
1122 FrameType::PathChallenge => Frame::PathChallenge(self.bytes.get()?),
1123 FrameType::PathResponse => Frame::PathResponse(self.bytes.get()?),
1124 FrameType::NewConnectionId | FrameType::PathNewConnectionId => {
1125 let read_path = ty == FrameType::PathNewConnectionId;
1126 Frame::NewConnectionId(NewConnectionId::read(&mut self.bytes, read_path)?)
1127 }
1128 FrameType::Crypto => Frame::Crypto(Crypto {
1129 offset: self.bytes.get_var()?,
1130 data: self.take_len()?,
1131 }),
1132 FrameType::NewToken => Frame::NewToken(NewToken {
1133 token: self.take_len()?,
1134 }),
1135 FrameType::HandshakeDone => Frame::HandshakeDone,
1136 FrameType::AckFrequency => Frame::AckFrequency(AckFrequency {
1137 sequence: self.bytes.get()?,
1138 ack_eliciting_threshold: self.bytes.get()?,
1139 request_max_ack_delay: self.bytes.get()?,
1140 reordering_threshold: self.bytes.get()?,
1141 }),
1142 FrameType::ImmediateAck => Frame::ImmediateAck,
1143 FrameType::ObservedIpv4Addr | FrameType::ObservedIpv6Addr => {
1144 let is_ipv6 = ty == FrameType::ObservedIpv6Addr;
1145 let observed = ObservedAddr::read(&mut self.bytes, is_ipv6)?;
1146 Frame::ObservedAddr(observed)
1147 }
1148 FrameType::PathAbandon => Frame::PathAbandon(PathAbandon::decode(&mut self.bytes)?),
1149 FrameType::PathStatusAvailable => {
1150 Frame::PathStatusAvailable(PathStatusAvailable::decode(&mut self.bytes)?)
1151 }
1152 FrameType::PathStatusBackup => {
1153 Frame::PathStatusBackup(PathStatusBackup::decode(&mut self.bytes)?)
1154 }
1155 FrameType::MaxPathId => Frame::MaxPathId(MaxPathId::decode(&mut self.bytes)?),
1156 FrameType::PathsBlocked => Frame::PathsBlocked(PathsBlocked::decode(&mut self.bytes)?),
1157 FrameType::PathCidsBlocked => {
1158 Frame::PathCidsBlocked(PathCidsBlocked::decode(&mut self.bytes)?)
1159 }
1160 FrameType::AddIpv4Address | FrameType::AddIpv6Address => {
1161 let is_ipv6 = ty == FrameType::AddIpv6Address;
1162 let add_address = AddAddress::read(&mut self.bytes, is_ipv6)?;
1163 Frame::AddAddress(add_address)
1164 }
1165 FrameType::ReachOutAtIpv4 | FrameType::ReachOutAtIpv6 => {
1166 let is_ipv6 = ty == FrameType::ReachOutAtIpv6;
1167 let reach_out = ReachOut::read(&mut self.bytes, is_ipv6)?;
1168 Frame::ReachOut(reach_out)
1169 }
1170 FrameType::RemoveAddress => Frame::RemoveAddress(RemoveAddress::read(&mut self.bytes)?),
1171 FrameType::Stream(s) => Frame::Stream(Stream {
1172 id: self.bytes.get()?,
1173 offset: if s.off() { self.bytes.get_var()? } else { 0 },
1174 fin: s.fin(),
1175 data: if s.len() {
1176 self.take_len()?
1177 } else {
1178 self.take_remaining()
1179 },
1180 }),
1181 FrameType::Datagram(d) => Frame::Datagram(Datagram {
1182 data: if d.len() {
1183 self.take_len()?
1184 } else {
1185 self.take_remaining()
1186 },
1187 }),
1188 })
1189 }
1190
1191 fn take_remaining(&mut self) -> Bytes {
1192 mem::take(&mut self.bytes)
1193 }
1194}
1195
1196impl Iterator for Iter {
1197 type Item = Result<Frame, InvalidFrame>;
1198 fn next(&mut self) -> Option<Self::Item> {
1199 if !self.bytes.has_remaining() {
1200 return None;
1201 }
1202 match self.try_next() {
1203 Ok(x) => Some(Ok(x)),
1204 Err(e) => {
1205 self.bytes.clear();
1207 Some(Err(InvalidFrame {
1208 ty: self.last_ty,
1209 reason: e.reason(),
1210 }))
1211 }
1212 }
1213 }
1214}
1215
1216#[derive(Debug)]
1217pub(crate) struct InvalidFrame {
1218 pub(crate) ty: MaybeFrame,
1219 pub(crate) reason: &'static str,
1220}
1221
1222impl From<InvalidFrame> for TransportError {
1223 fn from(err: InvalidFrame) -> Self {
1224 let mut te = Self::FRAME_ENCODING_ERROR(err.reason);
1225 te.frame = err.ty;
1226 te
1227 }
1228}
1229
1230fn scan_ack_blocks(mut buf: &[u8], largest: u64, n: usize) -> Result<usize, IterErr> {
1232 let total_len = buf.remaining();
1233 let first_block = buf.get_var()?;
1234 let mut smallest = largest.checked_sub(first_block).ok_or(IterErr::Malformed)?;
1235 for _ in 0..n {
1236 let gap = buf.get_var()?;
1237 smallest = smallest.checked_sub(gap + 2).ok_or(IterErr::Malformed)?;
1238 let block = buf.get_var()?;
1239 smallest = smallest.checked_sub(block).ok_or(IterErr::Malformed)?;
1240 }
1241 Ok(total_len - buf.remaining())
1242}
1243
1244#[derive(Debug)]
1245enum IterErr {
1246 UnexpectedEnd,
1247 InvalidFrameId,
1248 Malformed,
1249}
1250
1251impl IterErr {
1252 fn reason(&self) -> &'static str {
1253 use IterErr::*;
1254 match *self {
1255 UnexpectedEnd => "unexpected end",
1256 InvalidFrameId => "invalid frame ID",
1257 Malformed => "malformed",
1258 }
1259 }
1260}
1261
1262impl From<UnexpectedEnd> for IterErr {
1263 fn from(_: UnexpectedEnd) -> Self {
1264 Self::UnexpectedEnd
1265 }
1266}
1267
1268#[derive(Debug, Clone)]
1269pub struct AckIter<'a> {
1270 largest: u64,
1271 data: &'a [u8],
1272}
1273
1274impl<'a> AckIter<'a> {
1275 fn new(largest: u64, data: &'a [u8]) -> Self {
1276 Self { largest, data }
1277 }
1278}
1279
1280impl Iterator for AckIter<'_> {
1281 type Item = RangeInclusive<u64>;
1282 fn next(&mut self) -> Option<RangeInclusive<u64>> {
1283 if !self.data.has_remaining() {
1284 return None;
1285 }
1286 let block = self.data.get_var().unwrap();
1287 let largest = self.largest;
1288 if let Ok(gap) = self.data.get_var() {
1289 self.largest -= block + gap + 2;
1290 }
1291 Some(largest - block..=largest)
1292 }
1293}
1294
1295#[allow(unreachable_pub)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1297#[derive(Debug, Copy, Clone)]
1298pub struct ResetStream {
1299 pub(crate) id: StreamId,
1300 pub(crate) error_code: VarInt,
1301 pub(crate) final_offset: VarInt,
1302}
1303
1304impl FrameStruct for ResetStream {
1305 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
1306}
1307
1308impl Encodable for ResetStream {
1309 fn encode<W: BufMut>(&self, out: &mut W) {
1310 out.write(FrameType::ResetStream); out.write(self.id); out.write(self.error_code); out.write(self.final_offset); }
1315}
1316
1317#[derive(Debug, Copy, Clone)]
1318pub(crate) struct StopSending {
1319 pub(crate) id: StreamId,
1320 pub(crate) error_code: VarInt,
1321}
1322
1323impl FrameStruct for StopSending {
1324 const SIZE_BOUND: usize = 1 + 8 + 8;
1325}
1326
1327impl Encodable for StopSending {
1328 fn encode<W: BufMut>(&self, out: &mut W) {
1329 out.write(FrameType::StopSending); out.write(self.id); out.write(self.error_code) }
1333}
1334
1335#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1336pub(crate) struct NewConnectionId {
1337 pub(crate) path_id: Option<PathId>,
1338 pub(crate) sequence: u64,
1339 pub(crate) retire_prior_to: u64,
1340 pub(crate) id: ConnectionId,
1341 pub(crate) reset_token: ResetToken,
1342}
1343
1344impl NewConnectionId {
1345 pub(crate) const SIZE_BOUND: usize = {
1347 let type_len = FrameType::NewConnectionId.size();
1348 let seq_max_len = 8usize;
1349 let retire_prior_to_max_len = 8usize;
1350 let cid_len_len = 1;
1351 let cid_len = 160;
1352 let reset_token_len = 16;
1353 type_len + seq_max_len + retire_prior_to_max_len + cid_len_len + cid_len + reset_token_len
1354 };
1355
1356 pub(crate) const SIZE_BOUND_MULTIPATH: usize = {
1358 let type_len = FrameType::PathNewConnectionId.size();
1359 let path_id_len = VarInt::from_u32(u32::MAX).size();
1360 let seq_max_len = 8usize;
1361 let retire_prior_to_max_len = 8usize;
1362 let cid_len_len = 1;
1363 let cid_len = 160;
1364 let reset_token_len = 16;
1365 type_len
1366 + path_id_len
1367 + seq_max_len
1368 + retire_prior_to_max_len
1369 + cid_len_len
1370 + cid_len
1371 + reset_token_len
1372 };
1373
1374 pub(crate) fn get_type(&self) -> FrameType {
1375 if self.path_id.is_some() {
1376 FrameType::PathNewConnectionId
1377 } else {
1378 FrameType::NewConnectionId
1379 }
1380 }
1381
1382 pub(crate) const fn size_bound(path_new_cid: bool, cid_len: usize) -> usize {
1386 let upper_bound = match path_new_cid {
1387 true => Self::SIZE_BOUND_MULTIPATH,
1388 false => Self::SIZE_BOUND,
1389 };
1390 upper_bound - 160 + cid_len
1392 }
1393
1394 fn read<R: Buf>(bytes: &mut R, read_path: bool) -> Result<Self, IterErr> {
1395 let path_id = if read_path { Some(bytes.get()?) } else { None };
1396 let sequence = bytes.get_var()?;
1397 let retire_prior_to = bytes.get_var()?;
1398 if retire_prior_to > sequence {
1399 return Err(IterErr::Malformed);
1400 }
1401 let length = bytes.get::<u8>()? as usize;
1402 if length > MAX_CID_SIZE || length == 0 {
1403 return Err(IterErr::Malformed);
1404 }
1405 if length > bytes.remaining() {
1406 return Err(IterErr::UnexpectedEnd);
1407 }
1408 let mut stage = [0; MAX_CID_SIZE];
1409 bytes.copy_to_slice(&mut stage[0..length]);
1410 let id = ConnectionId::new(&stage[..length]);
1411 if bytes.remaining() < 16 {
1412 return Err(IterErr::UnexpectedEnd);
1413 }
1414 let mut reset_token = [0; RESET_TOKEN_SIZE];
1415 bytes.copy_to_slice(&mut reset_token);
1416 Ok(Self {
1417 path_id,
1418 sequence,
1419 retire_prior_to,
1420 id,
1421 reset_token: reset_token.into(),
1422 })
1423 }
1424}
1425
1426impl Encodable for NewConnectionId {
1427 fn encode<W: BufMut>(&self, out: &mut W) {
1428 out.write(self.get_type());
1429 if let Some(id) = self.path_id {
1430 out.write(id);
1431 }
1432 out.write_var(self.sequence);
1433 out.write_var(self.retire_prior_to);
1434 out.write(self.id.len() as u8);
1435 out.put_slice(&self.id);
1436 out.put_slice(&self.reset_token);
1437 }
1438}
1439
1440impl FrameStruct for NewConnectionId {
1441 const SIZE_BOUND: usize = 1 + 8 + 8 + 1 + MAX_CID_SIZE + RESET_TOKEN_SIZE;
1442}
1443
1444#[derive(Debug, Clone)]
1446pub struct Datagram {
1447 pub data: Bytes,
1449}
1450
1451impl FrameStruct for Datagram {
1452 const SIZE_BOUND: usize = 1 + 8;
1453}
1454
1455impl Datagram {
1456 pub(crate) fn encode(&self, length: bool, out: &mut impl BufMut) {
1457 out.write(FrameType::Datagram(DatagramInfo(
1458 *DatagramInfo::VALUES.start() as u8 | u8::from(length),
1459 ))); if length {
1461 out.write(VarInt::from_u64(self.data.len() as u64).unwrap()); }
1464 out.put_slice(&self.data);
1465 }
1466
1467 pub(crate) fn size(&self, length: bool) -> usize {
1468 1 + if length {
1469 VarInt::from_u64(self.data.len() as u64).unwrap().size()
1470 } else {
1471 0
1472 } + self.data.len()
1473 }
1474}
1475
1476#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1477pub(crate) struct AckFrequency {
1478 pub(crate) sequence: VarInt,
1479 pub(crate) ack_eliciting_threshold: VarInt,
1480 pub(crate) request_max_ack_delay: VarInt,
1481 pub(crate) reordering_threshold: VarInt,
1482}
1483
1484impl Encodable for AckFrequency {
1485 fn encode<W: BufMut>(&self, buf: &mut W) {
1486 buf.write(FrameType::AckFrequency);
1487 buf.write(self.sequence);
1488 buf.write(self.ack_eliciting_threshold);
1489 buf.write(self.request_max_ack_delay);
1490 buf.write(self.reordering_threshold);
1491 }
1492}
1493
1494#[derive(Debug, PartialEq, Eq, Clone)]
1499pub(crate) struct ObservedAddr {
1500 pub(crate) seq_no: VarInt,
1502 pub(crate) ip: IpAddr,
1504 pub(crate) port: u16,
1506}
1507
1508impl ObservedAddr {
1509 pub(crate) fn new<N: Into<VarInt>>(remote: std::net::SocketAddr, seq_no: N) -> Self {
1510 Self {
1511 ip: remote.ip(),
1512 port: remote.port(),
1513 seq_no: seq_no.into(),
1514 }
1515 }
1516
1517 pub(crate) fn get_type(&self) -> FrameType {
1519 if self.ip.is_ipv6() {
1520 FrameType::ObservedIpv6Addr
1521 } else {
1522 FrameType::ObservedIpv4Addr
1523 }
1524 }
1525
1526 pub(crate) fn size(&self) -> usize {
1528 let type_size = self.get_type().size();
1529 let req_id_bytes = self.seq_no.size();
1530 let ip_bytes = if self.ip.is_ipv6() { 16 } else { 4 };
1531 let port_bytes = 2;
1532 type_size + req_id_bytes + ip_bytes + port_bytes
1533 }
1534
1535 pub(crate) fn read<R: Buf>(bytes: &mut R, is_ipv6: bool) -> coding::Result<Self> {
1540 let seq_no = bytes.get()?;
1541 let ip = if is_ipv6 {
1542 IpAddr::V6(bytes.get()?)
1543 } else {
1544 IpAddr::V4(bytes.get()?)
1545 };
1546 let port = bytes.get()?;
1547 Ok(Self { seq_no, ip, port })
1548 }
1549
1550 pub(crate) fn socket_addr(&self) -> SocketAddr {
1552 (self.ip, self.port).into()
1553 }
1554}
1555
1556impl Encodable for ObservedAddr {
1557 fn encode<W: BufMut>(&self, buf: &mut W) {
1558 buf.write(self.get_type());
1559 buf.write(self.seq_no);
1560 match self.ip {
1561 IpAddr::V4(ipv4_addr) => {
1562 buf.write(ipv4_addr);
1563 }
1564 IpAddr::V6(ipv6_addr) => {
1565 buf.write(ipv6_addr);
1566 }
1567 }
1568 buf.write::<u16>(self.port);
1569 }
1570}
1571
1572#[derive(Debug, PartialEq, Eq)]
1575pub(crate) struct PathAbandon {
1576 pub(crate) path_id: PathId,
1577 pub(crate) error_code: TransportErrorCode,
1578}
1579
1580impl PathAbandon {
1581 pub(crate) const SIZE_BOUND: usize = FrameType::PathAbandon.size() + 8 + 8;
1582}
1583
1584impl Encodable for PathAbandon {
1585 fn encode<W: BufMut>(&self, buf: &mut W) {
1586 buf.write(FrameType::PathAbandon);
1587 buf.write(self.path_id);
1588 buf.write(self.error_code);
1589 }
1590}
1591
1592impl Decodable for PathAbandon {
1593 fn decode<R: Buf>(bytes: &mut R) -> coding::Result<Self> {
1594 Ok(Self {
1595 path_id: bytes.get()?,
1596 error_code: bytes.get()?,
1597 })
1598 }
1599}
1600
1601#[derive(Debug, PartialEq, Eq)]
1602pub(crate) struct PathStatusAvailable {
1603 pub(crate) path_id: PathId,
1604 pub(crate) status_seq_no: VarInt,
1605}
1606
1607impl PathStatusAvailable {
1608 const TYPE: FrameType = FrameType::PathStatusAvailable;
1609 pub(crate) const SIZE_BOUND: usize = FrameType::PathStatusAvailable.size() + 8 + 8;
1610}
1611
1612impl Encodable for PathStatusAvailable {
1613 fn encode<W: BufMut>(&self, buf: &mut W) {
1614 buf.write(Self::TYPE);
1615 buf.write(self.path_id);
1616 buf.write(self.status_seq_no);
1617 }
1618}
1619
1620impl Decodable for PathStatusAvailable {
1621 fn decode<R: Buf>(bytes: &mut R) -> coding::Result<Self> {
1622 Ok(Self {
1623 path_id: bytes.get()?,
1624 status_seq_no: bytes.get()?,
1625 })
1626 }
1627}
1628
1629#[derive(Debug, PartialEq, Eq)]
1630pub(crate) struct PathStatusBackup {
1631 pub(crate) path_id: PathId,
1632 pub(crate) status_seq_no: VarInt,
1633}
1634
1635impl PathStatusBackup {
1636 const TYPE: FrameType = FrameType::PathStatusBackup;
1637}
1638
1639impl Encodable for PathStatusBackup {
1640 fn encode<W: BufMut>(&self, buf: &mut W) {
1641 buf.write(Self::TYPE);
1642 buf.write(self.path_id);
1643 buf.write(self.status_seq_no);
1644 }
1645}
1646
1647impl Decodable for PathStatusBackup {
1648 fn decode<R: Buf>(bytes: &mut R) -> coding::Result<Self> {
1649 Ok(Self {
1650 path_id: bytes.get()?,
1651 status_seq_no: bytes.get()?,
1652 })
1653 }
1654}
1655
1656#[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)]
1661#[allow(dead_code)]
1663pub(crate) struct AddAddress {
1664 pub(crate) seq_no: VarInt,
1667 pub(crate) ip: IpAddr,
1669 pub(crate) port: u16,
1671}
1672
1673#[allow(dead_code)]
1675impl AddAddress {
1676 pub(crate) const SIZE_BOUND: usize = Self {
1678 ip: IpAddr::V6(std::net::Ipv6Addr::LOCALHOST),
1679 port: u16::MAX,
1680 seq_no: VarInt::MAX,
1681 }
1682 .size();
1683
1684 pub(crate) const fn new((ip, port): (IpAddr, u16), seq_no: VarInt) -> Self {
1685 Self { ip, port, seq_no }
1686 }
1687
1688 pub(crate) const fn get_type(&self) -> FrameType {
1690 if self.ip.is_ipv6() {
1691 FrameType::AddIpv6Address
1692 } else {
1693 FrameType::AddIpv4Address
1694 }
1695 }
1696
1697 pub(crate) const fn size(&self) -> usize {
1699 let type_size = self.get_type().size();
1700 let seq_no_bytes = self.seq_no.size();
1701 let ip_bytes = if self.ip.is_ipv6() { 16 } else { 4 };
1702 let port_bytes = 2;
1703 type_size + seq_no_bytes + ip_bytes + port_bytes
1704 }
1705
1706 pub(crate) fn read<R: Buf>(bytes: &mut R, is_ipv6: bool) -> coding::Result<Self> {
1711 let seq_no = bytes.get()?;
1712 let ip = if is_ipv6 {
1713 IpAddr::V6(bytes.get()?)
1714 } else {
1715 IpAddr::V4(bytes.get()?)
1716 };
1717 let port = bytes.get()?;
1718 Ok(Self { seq_no, ip, port })
1719 }
1720
1721 pub(crate) fn socket_addr(&self) -> SocketAddr {
1723 self.ip_port().into()
1724 }
1725
1726 pub(crate) fn ip_port(&self) -> (IpAddr, u16) {
1727 (self.ip, self.port)
1728 }
1729}
1730
1731impl Encodable for AddAddress {
1732 fn encode<W: BufMut>(&self, buf: &mut W) {
1733 buf.write(self.get_type());
1734 buf.write(self.seq_no);
1735 match self.ip {
1736 IpAddr::V4(ipv4_addr) => {
1737 buf.write(ipv4_addr);
1738 }
1739 IpAddr::V6(ipv6_addr) => {
1740 buf.write(ipv6_addr);
1741 }
1742 }
1743 buf.write::<u16>(self.port);
1744 }
1745}
1746
1747#[derive(Debug, PartialEq, Eq, Clone)]
1750#[allow(dead_code)]
1752pub(crate) struct ReachOut {
1753 pub(crate) round: VarInt,
1755 pub(crate) ip: IpAddr,
1757 pub(crate) port: u16,
1759}
1760
1761#[allow(dead_code)]
1763impl ReachOut {
1764 pub(crate) const SIZE_BOUND: usize = Self {
1766 round: VarInt::MAX,
1767 ip: IpAddr::V6(std::net::Ipv6Addr::LOCALHOST),
1768 port: u16::MAX,
1769 }
1770 .size();
1771
1772 pub(crate) const fn new(round: VarInt, (ip, port): (IpAddr, u16)) -> Self {
1773 Self { round, ip, port }
1774 }
1775
1776 pub(crate) const fn get_type(&self) -> FrameType {
1778 if self.ip.is_ipv6() {
1779 FrameType::ReachOutAtIpv6
1780 } else {
1781 FrameType::ReachOutAtIpv4
1782 }
1783 }
1784
1785 pub(crate) const fn size(&self) -> usize {
1787 let type_size = self.get_type().size();
1788 let round_bytes = self.round.size();
1789 let ip_bytes = if self.ip.is_ipv6() { 16 } else { 4 };
1790 let port_bytes = 2;
1791 type_size + round_bytes + ip_bytes + port_bytes
1792 }
1793
1794 pub(crate) fn read<R: Buf>(bytes: &mut R, is_ipv6: bool) -> coding::Result<Self> {
1799 let round = bytes.get()?;
1800 let ip = if is_ipv6 {
1801 IpAddr::V6(bytes.get()?)
1802 } else {
1803 IpAddr::V4(bytes.get()?)
1804 };
1805 let port = bytes.get()?;
1806 Ok(Self { round, ip, port })
1807 }
1808
1809 pub(crate) fn socket_addr(&self) -> SocketAddr {
1811 (self.ip, self.port).into()
1812 }
1813}
1814
1815impl Encodable for ReachOut {
1816 fn encode<W: BufMut>(&self, buf: &mut W) {
1817 buf.write(self.get_type());
1818 buf.write(self.round);
1819 match self.ip {
1820 IpAddr::V4(ipv4_addr) => {
1821 buf.write(ipv4_addr);
1822 }
1823 IpAddr::V6(ipv6_addr) => {
1824 buf.write(ipv6_addr);
1825 }
1826 }
1827 buf.write::<u16>(self.port);
1828 }
1829}
1830
1831#[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)]
1833#[allow(dead_code)]
1835pub(crate) struct RemoveAddress {
1836 pub(crate) seq_no: VarInt,
1838}
1839
1840#[allow(dead_code)]
1842impl RemoveAddress {
1843 pub(crate) const TYPE: FrameType = FrameType::RemoveAddress;
1845
1846 pub(crate) const SIZE_BOUND: usize = Self::new(VarInt::MAX).size();
1848
1849 pub(crate) const fn new(seq_no: VarInt) -> Self {
1850 Self { seq_no }
1851 }
1852
1853 pub(crate) const fn size(&self) -> usize {
1855 let type_size = Self::TYPE.size();
1856 let seq_no_bytes = self.seq_no.size();
1857 type_size + seq_no_bytes
1858 }
1859
1860 pub(crate) fn read<R: Buf>(bytes: &mut R) -> coding::Result<Self> {
1865 Ok(Self {
1866 seq_no: bytes.get()?,
1867 })
1868 }
1869}
1870
1871impl Encodable for RemoveAddress {
1872 fn encode<W: BufMut>(&self, buf: &mut W) {
1873 buf.write(Self::TYPE);
1874 buf.write(self.seq_no);
1875 }
1876}
1877
1878#[cfg(test)]
1879mod test {
1880 use super::*;
1881 use crate::coding::Encodable;
1882 use assert_matches::assert_matches;
1883
1884 #[track_caller]
1885 fn frames(buf: Vec<u8>) -> Vec<Frame> {
1886 Iter::new(Bytes::from(buf))
1887 .unwrap()
1888 .collect::<Result<Vec<_>, _>>()
1889 .unwrap()
1890 }
1891
1892 #[test]
1893 fn ack_coding() {
1894 const PACKETS: &[u64] = &[1, 2, 3, 5, 10, 11, 14];
1895 let mut ranges = ArrayRangeSet::new();
1896 for &packet in PACKETS {
1897 ranges.insert(packet..packet + 1);
1898 }
1899 let mut buf = Vec::new();
1900 const ECN: EcnCounts = EcnCounts {
1901 ect0: 42,
1902 ect1: 24,
1903 ce: 12,
1904 };
1905 Ack::encode(42, &ranges, Some(&ECN), &mut buf);
1906 let frames = frames(buf);
1907 assert_eq!(frames.len(), 1);
1908 match frames[0] {
1909 Frame::Ack(ref ack) => {
1910 let mut packets = ack.iter().flatten().collect::<Vec<_>>();
1911 packets.sort_unstable();
1912 assert_eq!(&packets[..], PACKETS);
1913 assert_eq!(ack.ecn, Some(ECN));
1914 }
1915 ref x => panic!("incorrect frame {x:?}"),
1916 }
1917 }
1918
1919 #[test]
1920 #[allow(clippy::range_plus_one)]
1921 fn path_ack_coding() {
1922 const PACKETS: &[u64] = &[1, 2, 3, 5, 10, 11, 14];
1923 let mut ranges = ArrayRangeSet::new();
1924 for &packet in PACKETS {
1925 ranges.insert(packet..packet + 1);
1926 }
1927 let mut buf = Vec::new();
1928 const ECN: EcnCounts = EcnCounts {
1929 ect0: 42,
1930 ect1: 24,
1931 ce: 12,
1932 };
1933 const PATH_ID: PathId = PathId::MAX;
1934 PathAck::encode(PATH_ID, 42, &ranges, Some(&ECN), &mut buf);
1935 let frames = frames(buf);
1936 assert_eq!(frames.len(), 1);
1937 match frames[0] {
1938 Frame::PathAck(ref ack) => {
1939 assert_eq!(ack.path_id, PATH_ID);
1940 let mut packets = ack.into_iter().flatten().collect::<Vec<_>>();
1941 packets.sort_unstable();
1942 assert_eq!(&packets[..], PACKETS);
1943 assert_eq!(ack.ecn, Some(ECN));
1944 }
1945 ref x => panic!("incorrect frame {x:?}"),
1946 }
1947 }
1948
1949 #[test]
1950 fn ack_frequency_coding() {
1951 let mut buf = Vec::new();
1952 let original = AckFrequency {
1953 sequence: VarInt(42),
1954 ack_eliciting_threshold: VarInt(20),
1955 request_max_ack_delay: VarInt(50_000),
1956 reordering_threshold: VarInt(1),
1957 };
1958 original.encode(&mut buf);
1959 let frames = frames(buf);
1960 assert_eq!(frames.len(), 1);
1961 match &frames[0] {
1962 Frame::AckFrequency(decoded) => assert_eq!(decoded, &original),
1963 x => panic!("incorrect frame {x:?}"),
1964 }
1965 }
1966
1967 #[test]
1968 fn immediate_ack_coding() {
1969 let mut buf = Vec::new();
1970 FrameType::ImmediateAck.encode(&mut buf);
1971 let frames = frames(buf);
1972 assert_eq!(frames.len(), 1);
1973 assert_matches!(&frames[0], Frame::ImmediateAck);
1974 }
1975
1976 #[test]
1978 fn test_observed_addr_roundrip() {
1979 let observed_addr = ObservedAddr {
1980 seq_no: VarInt(42),
1981 ip: std::net::Ipv4Addr::LOCALHOST.into(),
1982 port: 4242,
1983 };
1984 let mut buf = Vec::with_capacity(observed_addr.size());
1985 observed_addr.encode(&mut buf);
1986
1987 assert_eq!(
1988 observed_addr.size(),
1989 buf.len(),
1990 "expected written bytes and actual size differ"
1991 );
1992
1993 let mut decoded = frames(buf);
1994 assert_eq!(decoded.len(), 1);
1995 match decoded.pop().expect("non empty") {
1996 Frame::ObservedAddr(decoded) => assert_eq!(decoded, observed_addr),
1997 x => panic!("incorrect frame {x:?}"),
1998 }
1999 }
2000
2001 #[test]
2002 fn test_path_abandon_roundtrip() {
2003 let abandon = PathAbandon {
2004 path_id: PathId(42),
2005 error_code: TransportErrorCode::NO_ERROR,
2006 };
2007 let mut buf = Vec::new();
2008 abandon.encode(&mut buf);
2009
2010 let mut decoded = frames(buf);
2011 assert_eq!(decoded.len(), 1);
2012 match decoded.pop().expect("non empty") {
2013 Frame::PathAbandon(decoded) => assert_eq!(decoded, abandon),
2014 x => panic!("incorrect frame {x:?}"),
2015 }
2016 }
2017
2018 #[test]
2019 fn test_path_status_available_roundtrip() {
2020 let path_status_available = PathStatusAvailable {
2021 path_id: PathId(42),
2022 status_seq_no: VarInt(73),
2023 };
2024 let mut buf = Vec::new();
2025 path_status_available.encode(&mut buf);
2026
2027 let mut decoded = frames(buf);
2028 assert_eq!(decoded.len(), 1);
2029 match decoded.pop().expect("non empty") {
2030 Frame::PathStatusAvailable(decoded) => assert_eq!(decoded, path_status_available),
2031 x => panic!("incorrect frame {x:?}"),
2032 }
2033 }
2034
2035 #[test]
2036 fn test_path_status_backup_roundtrip() {
2037 let path_status_backup = PathStatusBackup {
2038 path_id: PathId(42),
2039 status_seq_no: VarInt(73),
2040 };
2041 let mut buf = Vec::new();
2042 path_status_backup.encode(&mut buf);
2043
2044 let mut decoded = frames(buf);
2045 assert_eq!(decoded.len(), 1);
2046 match decoded.pop().expect("non empty") {
2047 Frame::PathStatusBackup(decoded) => assert_eq!(decoded, path_status_backup),
2048 x => panic!("incorrect frame {x:?}"),
2049 }
2050 }
2051
2052 #[test]
2053 fn test_path_new_connection_id_roundtrip() {
2054 let cid = NewConnectionId {
2055 path_id: Some(PathId(22)),
2056 sequence: 31,
2057 retire_prior_to: 13,
2058 id: ConnectionId::new(&[0xAB; 8]),
2059 reset_token: ResetToken::from([0xCD; crate::RESET_TOKEN_SIZE]),
2060 };
2061 let mut buf = Vec::new();
2062 cid.encode(&mut buf);
2063
2064 let mut decoded = frames(buf);
2065 assert_eq!(decoded.len(), 1);
2066 match decoded.pop().expect("non empty") {
2067 Frame::NewConnectionId(decoded) => assert_eq!(decoded, cid),
2068 x => panic!("incorrect frame {x:?}"),
2069 }
2070 }
2071
2072 #[test]
2073 fn test_path_retire_connection_id_roundtrip() {
2074 let retire_cid = RetireConnectionId {
2075 path_id: Some(PathId(22)),
2076 sequence: 31,
2077 };
2078 let mut buf = Vec::new();
2079 retire_cid.encode(&mut buf);
2080
2081 let mut decoded = frames(buf);
2082 assert_eq!(decoded.len(), 1);
2083 match decoded.pop().expect("non empty") {
2084 Frame::RetireConnectionId(decoded) => assert_eq!(decoded, retire_cid),
2085 x => panic!("incorrect frame {x:?}"),
2086 }
2087 }
2088
2089 #[test]
2090 fn test_paths_blocked_path_cids_blocked_roundtrip() {
2091 let mut buf = Vec::new();
2092
2093 let frame0 = PathsBlocked(PathId(22));
2094 frame0.encode(&mut buf);
2095 let frame1 = PathCidsBlocked {
2096 path_id: PathId(23),
2097 next_seq: VarInt(32),
2098 };
2099 frame1.encode(&mut buf);
2100
2101 let mut decoded = frames(buf);
2102 assert_eq!(decoded.len(), 2);
2103 match decoded.pop().expect("non empty") {
2104 Frame::PathCidsBlocked(decoded) => assert_eq!(decoded, frame1),
2105 x => panic!("incorrect frame {x:?}"),
2106 }
2107 match decoded.pop().expect("non empty") {
2108 Frame::PathsBlocked(decoded) => assert_eq!(decoded, frame0),
2109 x => panic!("incorrect frame {x:?}"),
2110 }
2111 }
2112
2113 #[test]
2115 fn test_add_address_roundrip() {
2116 let add_address = AddAddress {
2117 seq_no: VarInt(42),
2118 ip: std::net::Ipv4Addr::LOCALHOST.into(),
2119 port: 4242,
2120 };
2121 let mut buf = Vec::with_capacity(add_address.size());
2122 add_address.encode(&mut buf);
2123
2124 assert_eq!(
2125 add_address.size(),
2126 buf.len(),
2127 "expected written bytes and actual size differ"
2128 );
2129
2130 let mut decoded = frames(buf);
2131 assert_eq!(decoded.len(), 1);
2132 match decoded.pop().expect("non empty") {
2133 Frame::AddAddress(decoded) => assert_eq!(decoded, add_address),
2134 x => panic!("incorrect frame {x:?}"),
2135 }
2136 }
2137
2138 #[test]
2140 fn test_reach_out_roundrip() {
2141 let reach_out = ReachOut {
2142 round: VarInt(42),
2143 ip: std::net::Ipv6Addr::LOCALHOST.into(),
2144 port: 4242,
2145 };
2146 let mut buf = Vec::with_capacity(reach_out.size());
2147 reach_out.encode(&mut buf);
2148
2149 assert_eq!(
2150 reach_out.size(),
2151 buf.len(),
2152 "expected written bytes and actual size differ"
2153 );
2154
2155 let mut decoded = frames(buf);
2156 assert_eq!(decoded.len(), 1);
2157 match decoded.pop().expect("non empty") {
2158 Frame::ReachOut(decoded) => assert_eq!(decoded, reach_out),
2159 x => panic!("incorrect frame {x:?}"),
2160 }
2161 }
2162
2163 #[test]
2165 fn test_remove_address_roundrip() {
2166 let remove_addr = RemoveAddress::new(VarInt(10));
2167 let mut buf = Vec::with_capacity(remove_addr.size());
2168 remove_addr.encode(&mut buf);
2169
2170 assert_eq!(
2171 remove_addr.size(),
2172 buf.len(),
2173 "expected written bytes and actual size differ"
2174 );
2175
2176 let mut decoded = frames(buf);
2177 assert_eq!(decoded.len(), 1);
2178 match decoded.pop().expect("non empty") {
2179 Frame::RemoveAddress(decoded) => assert_eq!(decoded, remove_addr),
2180 x => panic!("incorrect frame {x:?}"),
2181 }
2182 }
2183}