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