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