1#![allow(missing_docs)]
8
9use std::{
10 fmt::{self, Write},
11 mem,
12 net::SocketAddr,
13 ops::{Range, RangeInclusive},
14};
15
16use bytes::{Buf, BufMut, Bytes};
17use tinyvec::TinyVec;
18
19use crate::{
20 Dir, MAX_CID_SIZE, RESET_TOKEN_SIZE, ResetToken, StreamId, TransportError, TransportErrorCode,
21 VarInt,
22 coding::{self, BufExt, BufMutExt, UnexpectedEnd},
23 range_set::ArrayRangeSet,
24 shared::{ConnectionId, EcnCodepoint},
25};
26
27#[cfg(feature = "arbitrary")]
28use arbitrary::Arbitrary;
29
30#[derive(Copy, Clone, Eq, PartialEq)]
32pub struct FrameType(pub(crate) u64);
33
34impl FrameType {
35 pub(crate) fn stream(self) -> Option<StreamInfo> {
36 if STREAM_TYS.contains(&self.0) {
37 Some(StreamInfo(self.0 as u8))
38 } else {
39 None
40 }
41 }
42
43 #[allow(dead_code)]
45 pub(crate) fn is_stream(self) -> bool {
46 STREAM_TYS.contains(&self.0)
47 }
48 fn datagram(self) -> Option<DatagramInfo> {
49 if DATAGRAM_TYS.contains(&self.0) {
50 Some(DatagramInfo(self.0 as u8))
51 } else {
52 None
53 }
54 }
55}
56
57impl coding::Codec for FrameType {
58 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
59 Ok(Self(buf.get_var()?))
60 }
61 fn encode<B: BufMut>(&self, buf: &mut B) {
62 buf.write_var(self.0);
63 }
64}
65
66pub(crate) trait FrameStruct {
67 const SIZE_BOUND: usize;
69}
70
71macro_rules! frame_types {
72 {$($name:ident = $val:expr_2021,)*} => {
73 impl FrameType {
74 $(pub(crate) const $name: FrameType = FrameType($val);)*
75 }
76
77 impl fmt::Debug for FrameType {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 match self.0 {
80 $($val => f.write_str(stringify!($name)),)*
81 _ => write!(f, "Type({:02x})", self.0)
82 }
83 }
84 }
85
86 impl fmt::Display for FrameType {
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 match self.0 {
89 $($val => f.write_str(stringify!($name)),)*
90 x if STREAM_TYS.contains(&x) => f.write_str("STREAM"),
91 x if DATAGRAM_TYS.contains(&x) => f.write_str("DATAGRAM"),
92 _ => write!(f, "<unknown {:02x}>", self.0),
93 }
94 }
95 }
96 }
97}
98
99#[derive(Debug, Copy, Clone, Eq, PartialEq)]
100pub(crate) struct StreamInfo(u8);
101
102impl StreamInfo {
103 fn fin(self) -> bool {
104 self.0 & 0x01 != 0
105 }
106 fn len(self) -> bool {
107 self.0 & 0x02 != 0
108 }
109 fn off(self) -> bool {
110 self.0 & 0x04 != 0
111 }
112}
113
114#[derive(Debug, Copy, Clone, Eq, PartialEq)]
115struct DatagramInfo(u8);
116
117impl DatagramInfo {
118 fn len(self) -> bool {
119 self.0 & 0x01 != 0
120 }
121}
122
123frame_types! {
124 PADDING = 0x00,
125 PING = 0x01,
126 ACK = 0x02,
127 ACK_ECN = 0x03,
128 RESET_STREAM = 0x04,
129 STOP_SENDING = 0x05,
130 CRYPTO = 0x06,
131 NEW_TOKEN = 0x07,
132 MAX_DATA = 0x10,
134 MAX_STREAM_DATA = 0x11,
135 MAX_STREAMS_BIDI = 0x12,
136 MAX_STREAMS_UNI = 0x13,
137 DATA_BLOCKED = 0x14,
138 STREAM_DATA_BLOCKED = 0x15,
139 STREAMS_BLOCKED_BIDI = 0x16,
140 STREAMS_BLOCKED_UNI = 0x17,
141 NEW_CONNECTION_ID = 0x18,
142 RETIRE_CONNECTION_ID = 0x19,
143 PATH_CHALLENGE = 0x1a,
144 PATH_RESPONSE = 0x1b,
145 CONNECTION_CLOSE = 0x1c,
146 APPLICATION_CLOSE = 0x1d,
147 HANDSHAKE_DONE = 0x1e,
148 ACK_FREQUENCY = 0xaf,
150 IMMEDIATE_ACK = 0x1f,
151 ADD_ADDRESS_IPV4 = 0x3d7e90,
153 ADD_ADDRESS_IPV6 = 0x3d7e91,
154 PUNCH_ME_NOW_IPV4 = 0x3d7e92,
155 PUNCH_ME_NOW_IPV6 = 0x3d7e93,
156 REMOVE_ADDRESS = 0x3d7e94,
157 OBSERVED_ADDRESS_IPV4 = 0x9f81a6,
159 OBSERVED_ADDRESS_IPV6 = 0x9f81a7,
160 }
162
163const STREAM_TYS: RangeInclusive<u64> = RangeInclusive::new(0x08, 0x0f);
164const DATAGRAM_TYS: RangeInclusive<u64> = RangeInclusive::new(0x30, 0x31);
165
166#[derive(Debug)]
168pub(crate) enum Frame {
169 Padding,
170 Ping,
171 Ack(Ack),
172 ResetStream(ResetStream),
173 StopSending(StopSending),
174 Crypto(Crypto),
175 NewToken(NewToken),
176 Stream(Stream),
177 MaxData(VarInt),
178 MaxStreamData { id: StreamId, offset: u64 },
179 MaxStreams { dir: Dir, count: u64 },
180 DataBlocked { offset: u64 },
181 StreamDataBlocked { id: StreamId, offset: u64 },
182 StreamsBlocked { dir: Dir, limit: u64 },
183 NewConnectionId(NewConnectionId),
184 RetireConnectionId { sequence: u64 },
185 PathChallenge(u64),
186 PathResponse(u64),
187 Close(Close),
188 Datagram(Datagram),
189 AckFrequency(AckFrequency),
190 ImmediateAck,
191 HandshakeDone,
192 AddAddress(AddAddress),
193 PunchMeNow(PunchMeNow),
194 RemoveAddress(RemoveAddress),
195 ObservedAddress(ObservedAddress),
196}
197
198impl Frame {
199 pub(crate) fn ty(&self) -> FrameType {
200 use Frame::*;
201 match self {
202 Padding => FrameType::PADDING,
203 ResetStream(_) => FrameType::RESET_STREAM,
204 Close(self::Close::Connection(_)) => FrameType::CONNECTION_CLOSE,
205 Close(self::Close::Application(_)) => FrameType::APPLICATION_CLOSE,
206 MaxData(_) => FrameType::MAX_DATA,
207 MaxStreamData { .. } => FrameType::MAX_STREAM_DATA,
208 MaxStreams { dir: Dir::Bi, .. } => FrameType::MAX_STREAMS_BIDI,
209 MaxStreams { dir: Dir::Uni, .. } => FrameType::MAX_STREAMS_UNI,
210 Ping => FrameType::PING,
211 DataBlocked { .. } => FrameType::DATA_BLOCKED,
212 StreamDataBlocked { .. } => FrameType::STREAM_DATA_BLOCKED,
213 StreamsBlocked { dir: Dir::Bi, .. } => FrameType::STREAMS_BLOCKED_BIDI,
214 StreamsBlocked { dir: Dir::Uni, .. } => FrameType::STREAMS_BLOCKED_UNI,
215 StopSending { .. } => FrameType::STOP_SENDING,
216 RetireConnectionId { .. } => FrameType::RETIRE_CONNECTION_ID,
217 Ack(_) => FrameType::ACK,
218 Stream(x) => {
219 let mut ty = *STREAM_TYS.start();
220 if x.fin {
221 ty |= 0x01;
222 }
223 if x.offset != 0 {
224 ty |= 0x04;
225 }
226 FrameType(ty)
227 }
228 PathChallenge(_) => FrameType::PATH_CHALLENGE,
229 PathResponse(_) => FrameType::PATH_RESPONSE,
230 NewConnectionId { .. } => FrameType::NEW_CONNECTION_ID,
231 Crypto(_) => FrameType::CRYPTO,
232 NewToken(_) => FrameType::NEW_TOKEN,
233 Datagram(_) => FrameType(*DATAGRAM_TYS.start()),
234 AckFrequency(_) => FrameType::ACK_FREQUENCY,
235 ImmediateAck => FrameType::IMMEDIATE_ACK,
236 HandshakeDone => FrameType::HANDSHAKE_DONE,
237 AddAddress(a) => match a.address {
238 SocketAddr::V4(_) => FrameType::ADD_ADDRESS_IPV4,
239 SocketAddr::V6(_) => FrameType::ADD_ADDRESS_IPV6,
240 },
241 PunchMeNow(p) => match p.address {
242 SocketAddr::V4(_) => FrameType::PUNCH_ME_NOW_IPV4,
243 SocketAddr::V6(_) => FrameType::PUNCH_ME_NOW_IPV6,
244 },
245 RemoveAddress(_) => FrameType::REMOVE_ADDRESS,
246 ObservedAddress(o) => match o.address {
247 SocketAddr::V4(_) => FrameType::OBSERVED_ADDRESS_IPV4,
248 SocketAddr::V6(_) => FrameType::OBSERVED_ADDRESS_IPV6,
249 },
250 }
251 }
252
253 pub(crate) fn is_ack_eliciting(&self) -> bool {
254 !matches!(*self, Self::Ack(_) | Self::Padding | Self::Close(_))
255 }
256}
257
258#[derive(Clone, Debug)]
260pub enum Close {
261 Connection(ConnectionClose),
263 Application(ApplicationClose),
265}
266
267impl Close {
268 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
269 match *self {
270 Self::Connection(ref x) => x.encode(out, max_len),
271 Self::Application(ref x) => x.encode(out, max_len),
272 }
273 }
274
275 pub(crate) fn is_transport_layer(&self) -> bool {
276 matches!(*self, Self::Connection(_))
277 }
278}
279
280impl From<TransportError> for Close {
281 fn from(x: TransportError) -> Self {
282 Self::Connection(x.into())
283 }
284}
285impl From<ConnectionClose> for Close {
286 fn from(x: ConnectionClose) -> Self {
287 Self::Connection(x)
288 }
289}
290impl From<ApplicationClose> for Close {
291 fn from(x: ApplicationClose) -> Self {
292 Self::Application(x)
293 }
294}
295
296#[derive(Debug, Clone, PartialEq, Eq)]
298pub struct ConnectionClose {
299 pub error_code: TransportErrorCode,
301 pub frame_type: Option<FrameType>,
303 pub reason: Bytes,
305}
306
307impl fmt::Display for ConnectionClose {
308 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
309 self.error_code.fmt(f)?;
310 if !self.reason.as_ref().is_empty() {
311 f.write_str(": ")?;
312 f.write_str(&String::from_utf8_lossy(&self.reason))?;
313 }
314 Ok(())
315 }
316}
317
318impl From<TransportError> for ConnectionClose {
319 fn from(x: TransportError) -> Self {
320 Self {
321 error_code: x.code,
322 frame_type: x.frame,
323 reason: x.reason.into(),
324 }
325 }
326}
327
328impl FrameStruct for ConnectionClose {
329 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
330}
331
332impl ConnectionClose {
333 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
334 out.write(FrameType::CONNECTION_CLOSE); out.write(self.error_code); let ty = self.frame_type.map_or(0, |x| x.0);
337 out.write_var(ty); let max_len = max_len
339 - 3
340 - VarInt::from_u64_bounded(ty).size()
341 - VarInt::from_u64_bounded(self.reason.len() as u64).size();
342 let actual_len = self.reason.len().min(max_len);
343 out.write_var(actual_len as u64); out.put_slice(&self.reason[0..actual_len]); }
346}
347
348#[derive(Debug, Clone, PartialEq, Eq)]
350pub struct ApplicationClose {
351 pub error_code: VarInt,
353 pub reason: Bytes,
355}
356
357impl fmt::Display for ApplicationClose {
358 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
359 if !self.reason.as_ref().is_empty() {
360 f.write_str(&String::from_utf8_lossy(&self.reason))?;
361 f.write_str(" (code ")?;
362 self.error_code.fmt(f)?;
363 f.write_str(")")?;
364 } else {
365 self.error_code.fmt(f)?;
366 }
367 Ok(())
368 }
369}
370
371impl FrameStruct for ApplicationClose {
372 const SIZE_BOUND: usize = 1 + 8 + 8;
373}
374
375impl ApplicationClose {
376 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
377 out.write(FrameType::APPLICATION_CLOSE); out.write(self.error_code); let max_len = max_len - 3 - VarInt::from_u64_bounded(self.reason.len() as u64).size();
380 let actual_len = self.reason.len().min(max_len);
381 out.write_var(actual_len as u64); out.put_slice(&self.reason[0..actual_len]); }
384}
385
386#[derive(Clone, Eq, PartialEq)]
387pub struct Ack {
389 pub largest: u64,
391 pub delay: u64,
393 pub additional: Bytes,
395 pub ecn: Option<EcnCounts>,
397}
398
399impl fmt::Debug for Ack {
400 #[allow(clippy::panic)]
401 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
402 let mut ranges = "[".to_string();
403 let mut first = true;
404 for range in self.iter() {
405 if !first {
406 ranges.push(',');
407 }
408 write!(ranges, "{range:?}")
409 .unwrap_or_else(|_| panic!("writing to string should not fail"));
410 first = false;
411 }
412 ranges.push(']');
413
414 f.debug_struct("Ack")
415 .field("largest", &self.largest)
416 .field("delay", &self.delay)
417 .field("ecn", &self.ecn)
418 .field("ranges", &ranges)
419 .finish()
420 }
421}
422
423impl<'a> IntoIterator for &'a Ack {
424 type Item = RangeInclusive<u64>;
425 type IntoIter = AckIter<'a>;
426
427 fn into_iter(self) -> AckIter<'a> {
428 AckIter::new(self.largest, &self.additional[..])
429 }
430}
431
432impl Ack {
433 #[allow(clippy::panic)]
435 pub fn encode<W: BufMut>(
436 delay: u64,
437 ranges: &ArrayRangeSet,
438 ecn: Option<&EcnCounts>,
439 buf: &mut W,
440 ) {
441 let mut rest = ranges.iter().rev();
442 let first = rest
443 .next()
444 .unwrap_or_else(|| panic!("ACK ranges should have at least one range"));
445 let largest = first.end - 1;
446 let first_size = first.end - first.start;
447 buf.write(if ecn.is_some() {
448 FrameType::ACK_ECN
449 } else {
450 FrameType::ACK
451 });
452 buf.write_var(largest);
453 buf.write_var(delay);
454 buf.write_var(ranges.len() as u64 - 1);
455 buf.write_var(first_size - 1);
456 let mut prev = first.start;
457 for block in rest {
458 let size = block.end - block.start;
459 buf.write_var(prev - block.end - 1);
460 buf.write_var(size - 1);
461 prev = block.start;
462 }
463 if let Some(x) = ecn {
464 x.encode(buf)
465 }
466 }
467
468 pub fn iter(&self) -> AckIter<'_> {
470 self.into_iter()
471 }
472}
473
474#[derive(Debug, Copy, Clone, Eq, PartialEq)]
475pub struct EcnCounts {
477 pub ect0: u64,
479 pub ect1: u64,
481 pub ce: u64,
483}
484
485impl std::ops::AddAssign<EcnCodepoint> for EcnCounts {
486 fn add_assign(&mut self, rhs: EcnCodepoint) {
487 match rhs {
488 EcnCodepoint::Ect0 => {
489 self.ect0 += 1;
490 }
491 EcnCodepoint::Ect1 => {
492 self.ect1 += 1;
493 }
494 EcnCodepoint::Ce => {
495 self.ce += 1;
496 }
497 }
498 }
499}
500
501impl EcnCounts {
502 pub const ZERO: Self = Self {
503 ect0: 0,
504 ect1: 0,
505 ce: 0,
506 };
507
508 pub fn encode<W: BufMut>(&self, out: &mut W) {
509 out.write_var(self.ect0);
510 out.write_var(self.ect1);
511 out.write_var(self.ce);
512 }
513}
514
515#[derive(Debug, Clone)]
516pub(crate) struct Stream {
517 pub(crate) id: StreamId,
518 pub(crate) offset: u64,
519 pub(crate) fin: bool,
520 pub(crate) data: Bytes,
521}
522
523impl FrameStruct for Stream {
524 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
525}
526
527#[derive(Debug, Clone)]
529pub(crate) struct StreamMeta {
530 pub(crate) id: StreamId,
531 pub(crate) offsets: Range<u64>,
532 pub(crate) fin: bool,
533}
534
535impl Default for StreamMeta {
537 fn default() -> Self {
538 Self {
539 id: StreamId(0),
540 offsets: 0..0,
541 fin: false,
542 }
543 }
544}
545
546impl StreamMeta {
547 pub(crate) fn encode<W: BufMut>(&self, length: bool, out: &mut W) {
548 let mut ty = *STREAM_TYS.start();
549 if self.offsets.start != 0 {
550 ty |= 0x04;
551 }
552 if length {
553 ty |= 0x02;
554 }
555 if self.fin {
556 ty |= 0x01;
557 }
558 out.write_var(ty); out.write(self.id); if self.offsets.start != 0 {
561 out.write_var(self.offsets.start); }
563 if length {
564 out.write_var(self.offsets.end - self.offsets.start); }
566 }
567}
568
569pub(crate) type StreamMetaVec = TinyVec<[StreamMeta; 1]>;
571
572#[derive(Debug, Clone)]
573pub(crate) struct Crypto {
574 pub(crate) offset: u64,
575 pub(crate) data: Bytes,
576}
577
578impl Crypto {
579 pub(crate) const SIZE_BOUND: usize = 17;
580
581 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
582 out.write(FrameType::CRYPTO);
583 out.write_var(self.offset);
584 out.write_var(self.data.len() as u64);
585 out.put_slice(&self.data);
586 }
587}
588
589#[derive(Debug, Clone)]
590pub(crate) struct NewToken {
591 pub(crate) token: Bytes,
592}
593
594impl NewToken {
595 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
596 out.write(FrameType::NEW_TOKEN);
597 out.write_var(self.token.len() as u64);
598 out.put_slice(&self.token);
599 }
600
601 pub(crate) fn size(&self) -> usize {
602 1 + VarInt::from_u64_bounded(self.token.len() as u64).size() + self.token.len()
603 }
604}
605
606pub(crate) struct Iter {
607 bytes: Bytes,
608 last_ty: Option<FrameType>,
609}
610
611impl Iter {
612 pub(crate) fn new(payload: Bytes) -> Result<Self, TransportError> {
613 if payload.is_empty() {
614 return Err(TransportError::PROTOCOL_VIOLATION(
618 "packet payload is empty",
619 ));
620 }
621
622 Ok(Self {
623 bytes: payload,
624 last_ty: None,
625 })
626 }
627
628 fn take_len(&mut self) -> Result<Bytes, UnexpectedEnd> {
629 let len = self.bytes.get_var()?;
630 if len > self.bytes.remaining() as u64 {
631 return Err(UnexpectedEnd);
632 }
633 Ok(self.bytes.split_to(len as usize))
634 }
635
636 fn try_next(&mut self) -> Result<Frame, IterErr> {
637 let ty = self.bytes.get::<FrameType>()?;
638 self.last_ty = Some(ty);
639 Ok(match ty {
640 FrameType::PADDING => Frame::Padding,
641 FrameType::RESET_STREAM => Frame::ResetStream(ResetStream {
642 id: self.bytes.get()?,
643 error_code: self.bytes.get()?,
644 final_offset: self.bytes.get()?,
645 }),
646 FrameType::CONNECTION_CLOSE => Frame::Close(Close::Connection(ConnectionClose {
647 error_code: self.bytes.get()?,
648 frame_type: {
649 let x = self.bytes.get_var()?;
650 if x == 0 { None } else { Some(FrameType(x)) }
651 },
652 reason: self.take_len()?,
653 })),
654 FrameType::APPLICATION_CLOSE => Frame::Close(Close::Application(ApplicationClose {
655 error_code: self.bytes.get()?,
656 reason: self.take_len()?,
657 })),
658 FrameType::MAX_DATA => Frame::MaxData(self.bytes.get()?),
659 FrameType::MAX_STREAM_DATA => Frame::MaxStreamData {
660 id: self.bytes.get()?,
661 offset: self.bytes.get_var()?,
662 },
663 FrameType::MAX_STREAMS_BIDI => Frame::MaxStreams {
664 dir: Dir::Bi,
665 count: self.bytes.get_var()?,
666 },
667 FrameType::MAX_STREAMS_UNI => Frame::MaxStreams {
668 dir: Dir::Uni,
669 count: self.bytes.get_var()?,
670 },
671 FrameType::PING => Frame::Ping,
672 FrameType::DATA_BLOCKED => Frame::DataBlocked {
673 offset: self.bytes.get_var()?,
674 },
675 FrameType::STREAM_DATA_BLOCKED => Frame::StreamDataBlocked {
676 id: self.bytes.get()?,
677 offset: self.bytes.get_var()?,
678 },
679 FrameType::STREAMS_BLOCKED_BIDI => Frame::StreamsBlocked {
680 dir: Dir::Bi,
681 limit: self.bytes.get_var()?,
682 },
683 FrameType::STREAMS_BLOCKED_UNI => Frame::StreamsBlocked {
684 dir: Dir::Uni,
685 limit: self.bytes.get_var()?,
686 },
687 FrameType::STOP_SENDING => Frame::StopSending(StopSending {
688 id: self.bytes.get()?,
689 error_code: self.bytes.get()?,
690 }),
691 FrameType::RETIRE_CONNECTION_ID => Frame::RetireConnectionId {
692 sequence: self.bytes.get_var()?,
693 },
694 FrameType::ACK | FrameType::ACK_ECN => {
695 let largest = self.bytes.get_var()?;
696 let delay = self.bytes.get_var()?;
697 let extra_blocks = self.bytes.get_var()? as usize;
698 let n = scan_ack_blocks(&self.bytes, largest, extra_blocks)?;
699 Frame::Ack(Ack {
700 delay,
701 largest,
702 additional: self.bytes.split_to(n),
703 ecn: if ty != FrameType::ACK_ECN {
704 None
705 } else {
706 Some(EcnCounts {
707 ect0: self.bytes.get_var()?,
708 ect1: self.bytes.get_var()?,
709 ce: self.bytes.get_var()?,
710 })
711 },
712 })
713 }
714 FrameType::PATH_CHALLENGE => Frame::PathChallenge(self.bytes.get()?),
715 FrameType::PATH_RESPONSE => Frame::PathResponse(self.bytes.get()?),
716 FrameType::NEW_CONNECTION_ID => {
717 let sequence = self.bytes.get_var()?;
718 let retire_prior_to = self.bytes.get_var()?;
719 if retire_prior_to > sequence {
720 return Err(IterErr::Malformed);
721 }
722 let length = self.bytes.get::<u8>()? as usize;
723 if length > MAX_CID_SIZE || length == 0 {
724 return Err(IterErr::Malformed);
725 }
726 if length > self.bytes.remaining() {
727 return Err(IterErr::UnexpectedEnd);
728 }
729 let mut stage = [0; MAX_CID_SIZE];
730 self.bytes.copy_to_slice(&mut stage[0..length]);
731 let id = ConnectionId::new(&stage[..length]);
732 if self.bytes.remaining() < 16 {
733 return Err(IterErr::UnexpectedEnd);
734 }
735 let mut reset_token = [0; RESET_TOKEN_SIZE];
736 self.bytes.copy_to_slice(&mut reset_token);
737 Frame::NewConnectionId(NewConnectionId {
738 sequence,
739 retire_prior_to,
740 id,
741 reset_token: reset_token.into(),
742 })
743 }
744 FrameType::CRYPTO => Frame::Crypto(Crypto {
745 offset: self.bytes.get_var()?,
746 data: self.take_len()?,
747 }),
748 FrameType::NEW_TOKEN => Frame::NewToken(NewToken {
749 token: self.take_len()?,
750 }),
751 FrameType::HANDSHAKE_DONE => Frame::HandshakeDone,
752 FrameType::ACK_FREQUENCY => Frame::AckFrequency(AckFrequency {
753 sequence: self.bytes.get()?,
754 ack_eliciting_threshold: self.bytes.get()?,
755 request_max_ack_delay: self.bytes.get()?,
756 reordering_threshold: self.bytes.get()?,
757 }),
758 FrameType::IMMEDIATE_ACK => Frame::ImmediateAck,
759 FrameType::ADD_ADDRESS_IPV4 => {
760 Frame::AddAddress(AddAddress::decode_auto(&mut self.bytes, false)?)
761 }
762 FrameType::ADD_ADDRESS_IPV6 => {
763 Frame::AddAddress(AddAddress::decode_auto(&mut self.bytes, true)?)
764 }
765 FrameType::PUNCH_ME_NOW_IPV4 => {
766 Frame::PunchMeNow(PunchMeNow::decode_auto(&mut self.bytes, false)?)
767 }
768 FrameType::PUNCH_ME_NOW_IPV6 => {
769 Frame::PunchMeNow(PunchMeNow::decode_auto(&mut self.bytes, true)?)
770 }
771 FrameType::REMOVE_ADDRESS => {
772 Frame::RemoveAddress(RemoveAddress::decode(&mut self.bytes)?)
774 }
775 FrameType::OBSERVED_ADDRESS_IPV4 => {
776 Frame::ObservedAddress(ObservedAddress::decode(&mut self.bytes, false)?)
777 }
778 FrameType::OBSERVED_ADDRESS_IPV6 => {
779 Frame::ObservedAddress(ObservedAddress::decode(&mut self.bytes, true)?)
780 }
781 _ => {
782 if let Some(s) = ty.stream() {
783 Frame::Stream(Stream {
784 id: self.bytes.get()?,
785 offset: if s.off() { self.bytes.get_var()? } else { 0 },
786 fin: s.fin(),
787 data: if s.len() {
788 self.take_len()?
789 } else {
790 self.take_remaining()
791 },
792 })
793 } else if let Some(d) = ty.datagram() {
794 Frame::Datagram(Datagram {
795 data: if d.len() {
796 self.take_len()?
797 } else {
798 self.take_remaining()
799 },
800 })
801 } else {
802 return Err(IterErr::InvalidFrameId);
803 }
804 }
805 })
806 }
807
808 fn take_remaining(&mut self) -> Bytes {
809 mem::take(&mut self.bytes)
810 }
811}
812
813impl Iterator for Iter {
814 type Item = Result<Frame, InvalidFrame>;
815 fn next(&mut self) -> Option<Self::Item> {
816 if !self.bytes.has_remaining() {
817 return None;
818 }
819 match self.try_next() {
820 Ok(x) => Some(Ok(x)),
821 Err(e) => {
822 self.bytes.clear();
824 Some(Err(InvalidFrame {
825 ty: self.last_ty,
826 reason: e.reason(),
827 }))
828 }
829 }
830 }
831}
832
833#[derive(Debug)]
834pub(crate) struct InvalidFrame {
835 pub(crate) ty: Option<FrameType>,
836 pub(crate) reason: &'static str,
837}
838
839impl From<InvalidFrame> for TransportError {
840 fn from(err: InvalidFrame) -> Self {
841 let mut te = Self::FRAME_ENCODING_ERROR(err.reason);
842 te.frame = err.ty;
843 te
844 }
845}
846
847fn scan_ack_blocks(mut buf: &[u8], largest: u64, n: usize) -> Result<usize, IterErr> {
849 let total_len = buf.remaining();
850 let first_block = buf.get_var()?;
851 let mut smallest = largest.checked_sub(first_block).ok_or(IterErr::Malformed)?;
852 for _ in 0..n {
853 let gap = buf.get_var()?;
854 smallest = smallest.checked_sub(gap + 2).ok_or(IterErr::Malformed)?;
855 let block = buf.get_var()?;
856 smallest = smallest.checked_sub(block).ok_or(IterErr::Malformed)?;
857 }
858 Ok(total_len - buf.remaining())
859}
860
861enum IterErr {
862 UnexpectedEnd,
863 InvalidFrameId,
864 Malformed,
865}
866
867impl IterErr {
868 fn reason(&self) -> &'static str {
869 use IterErr::*;
870 match *self {
871 UnexpectedEnd => "unexpected end",
872 InvalidFrameId => "invalid frame ID",
873 Malformed => "malformed",
874 }
875 }
876}
877
878impl From<UnexpectedEnd> for IterErr {
879 fn from(_: UnexpectedEnd) -> Self {
880 Self::UnexpectedEnd
881 }
882}
883
884#[derive(Debug, Clone)]
885pub struct AckIter<'a> {
886 largest: u64,
887 data: &'a [u8],
888}
889
890impl<'a> AckIter<'a> {
891 fn new(largest: u64, data: &'a [u8]) -> Self {
892 Self { largest, data }
893 }
894}
895
896impl Iterator for AckIter<'_> {
897 type Item = RangeInclusive<u64>;
898 fn next(&mut self) -> Option<RangeInclusive<u64>> {
899 if !self.data.has_remaining() {
900 return None;
901 }
902 let block = match self.data.get_var() {
903 Ok(block) => block,
904 Err(_) => return None,
905 };
906 let largest = self.largest;
907 if let Ok(gap) = self.data.get_var() {
908 self.largest -= block + gap + 2;
909 }
910 Some(largest - block..=largest)
911 }
912}
913
914#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
915#[derive(Debug, Copy, Clone)]
916pub struct ResetStream {
917 pub(crate) id: StreamId,
918 pub(crate) error_code: VarInt,
919 pub(crate) final_offset: VarInt,
920}
921
922impl FrameStruct for ResetStream {
923 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
924}
925
926impl ResetStream {
927 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
928 out.write(FrameType::RESET_STREAM); out.write(self.id); out.write(self.error_code); out.write(self.final_offset); }
933}
934
935#[derive(Debug, Copy, Clone)]
936pub(crate) struct StopSending {
937 pub(crate) id: StreamId,
938 pub(crate) error_code: VarInt,
939}
940
941impl FrameStruct for StopSending {
942 const SIZE_BOUND: usize = 1 + 8 + 8;
943}
944
945impl StopSending {
946 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
947 out.write(FrameType::STOP_SENDING); out.write(self.id); out.write(self.error_code) }
951}
952
953#[derive(Debug, Copy, Clone)]
954pub(crate) struct NewConnectionId {
955 pub(crate) sequence: u64,
956 pub(crate) retire_prior_to: u64,
957 pub(crate) id: ConnectionId,
958 pub(crate) reset_token: ResetToken,
959}
960
961impl NewConnectionId {
962 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
963 out.write(FrameType::NEW_CONNECTION_ID);
964 out.write_var(self.sequence);
965 out.write_var(self.retire_prior_to);
966 out.write(self.id.len() as u8);
967 out.put_slice(&self.id);
968 out.put_slice(&self.reset_token);
969 }
970}
971
972pub(crate) const RETIRE_CONNECTION_ID_SIZE_BOUND: usize = 9;
974
975#[derive(Debug, Clone)]
977pub struct Datagram {
978 pub data: Bytes,
980}
981
982impl FrameStruct for Datagram {
983 const SIZE_BOUND: usize = 1 + 8;
984}
985
986impl Datagram {
987 pub(crate) fn encode(&self, length: bool, out: &mut Vec<u8>) {
988 out.write(FrameType(*DATAGRAM_TYS.start() | u64::from(length))); if length {
990 out.write(VarInt::from_u64_bounded(self.data.len() as u64)); }
993 out.extend_from_slice(&self.data);
994 }
995
996 pub(crate) fn size(&self, length: bool) -> usize {
997 1 + if length {
998 VarInt::from_u64_bounded(self.data.len() as u64).size()
999 } else {
1000 0
1001 } + self.data.len()
1002 }
1003}
1004
1005#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1006pub(crate) struct AckFrequency {
1007 pub(crate) sequence: VarInt,
1008 pub(crate) ack_eliciting_threshold: VarInt,
1009 pub(crate) request_max_ack_delay: VarInt,
1010 pub(crate) reordering_threshold: VarInt,
1011}
1012
1013impl AckFrequency {
1014 pub(crate) fn encode<W: BufMut>(&self, buf: &mut W) {
1015 buf.write(FrameType::ACK_FREQUENCY);
1016 buf.write(self.sequence);
1017 buf.write(self.ack_eliciting_threshold);
1018 buf.write(self.request_max_ack_delay);
1019 buf.write(self.reordering_threshold);
1020 }
1021}
1022
1023pub(crate) use nat_traversal_unified::{AddAddress, PunchMeNow, RemoveAddress};
1025
1026#[derive(Debug, Clone, PartialEq, Eq)]
1029pub(crate) struct ObservedAddress {
1030 pub(crate) sequence_number: VarInt,
1032 pub(crate) address: SocketAddr,
1034}
1035
1036impl ObservedAddress {
1037 pub(crate) fn encode<W: BufMut>(&self, buf: &mut W) {
1038 match self.address {
1039 SocketAddr::V4(_) => buf.write(FrameType::OBSERVED_ADDRESS_IPV4),
1040 SocketAddr::V6(_) => buf.write(FrameType::OBSERVED_ADDRESS_IPV6),
1041 };
1042
1043 buf.write_var(self.sequence_number.0);
1045
1046 match self.address {
1048 SocketAddr::V4(addr) => {
1049 buf.put_slice(&addr.ip().octets());
1050 buf.put_u16(addr.port());
1051 }
1052 SocketAddr::V6(addr) => {
1053 buf.put_slice(&addr.ip().octets());
1054 buf.put_u16(addr.port());
1055 }
1056 }
1057 }
1058
1059 pub(crate) fn decode<R: Buf>(r: &mut R, is_ipv6: bool) -> Result<Self, UnexpectedEnd> {
1060 let sequence_number = VarInt::from_u64(r.get_var()?).map_err(|_| UnexpectedEnd)?;
1062
1063 let address = if is_ipv6 {
1065 if r.remaining() < 18 {
1066 return Err(UnexpectedEnd);
1067 }
1068 let mut octets = [0u8; 16];
1069 r.copy_to_slice(&mut octets);
1070 let port = r.get::<u16>()?;
1071 SocketAddr::new(octets.into(), port)
1072 } else {
1073 if r.remaining() < 6 {
1074 return Err(UnexpectedEnd);
1075 }
1076 let mut octets = [0u8; 4];
1077 r.copy_to_slice(&mut octets);
1078 let port = r.get::<u16>()?;
1079 SocketAddr::new(octets.into(), port)
1080 };
1081
1082 Ok(Self {
1083 sequence_number,
1084 address,
1085 })
1086 }
1087}
1088
1089impl FrameStruct for ObservedAddress {
1090 const SIZE_BOUND: usize = 4 + 8 + 16 + 2; }
1092
1093#[cfg(test)]
1094mod test {
1095 use super::*;
1096 use crate::coding::Codec;
1097 use assert_matches::assert_matches;
1098
1099 fn frames(buf: Vec<u8>) -> Vec<Frame> {
1100 Iter::new(Bytes::from(buf))
1101 .unwrap()
1102 .collect::<Result<Vec<_>, _>>()
1103 .unwrap()
1104 }
1105
1106 #[test]
1107 fn ack_coding() {
1108 const PACKETS: &[u64] = &[1, 2, 3, 5, 10, 11, 14];
1109 let mut ranges = ArrayRangeSet::new();
1110 for &packet in PACKETS {
1111 ranges.insert(packet..packet + 1);
1112 }
1113 let mut buf = Vec::new();
1114 const ECN: EcnCounts = EcnCounts {
1115 ect0: 42,
1116 ect1: 24,
1117 ce: 12,
1118 };
1119 Ack::encode(42, &ranges, Some(&ECN), &mut buf);
1120 let frames = frames(buf);
1121 assert_eq!(frames.len(), 1);
1122 match frames[0] {
1123 Frame::Ack(ref ack) => {
1124 let mut packets = ack.iter().flatten().collect::<Vec<_>>();
1125 packets.sort_unstable();
1126 assert_eq!(&packets[..], PACKETS);
1127 assert_eq!(ack.ecn, Some(ECN));
1128 }
1129 ref x => panic!("incorrect frame {x:?}"),
1130 }
1131 }
1132
1133 #[test]
1134 fn ack_frequency_coding() {
1135 let mut buf = Vec::new();
1136 let original = AckFrequency {
1137 sequence: VarInt(42),
1138 ack_eliciting_threshold: VarInt(20),
1139 request_max_ack_delay: VarInt(50_000),
1140 reordering_threshold: VarInt(1),
1141 };
1142 original.encode(&mut buf);
1143 let frames = frames(buf);
1144 assert_eq!(frames.len(), 1);
1145 match &frames[0] {
1146 Frame::AckFrequency(decoded) => assert_eq!(decoded, &original),
1147 x => panic!("incorrect frame {x:?}"),
1148 }
1149 }
1150
1151 #[test]
1152 fn immediate_ack_coding() {
1153 let mut buf = Vec::new();
1154 FrameType::IMMEDIATE_ACK.encode(&mut buf);
1155 let frames = frames(buf);
1156 assert_eq!(frames.len(), 1);
1157 assert_matches!(&frames[0], Frame::ImmediateAck);
1158 }
1159
1160 #[test]
1161 fn add_address_ipv4_coding() {
1162 let mut buf = Vec::new();
1163 let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
1164 let original = AddAddress {
1165 sequence: VarInt(42),
1166 address: addr,
1167 priority: VarInt(100),
1168 };
1169 original.encode_rfc(&mut buf);
1171 let frames = frames(buf);
1172 assert_eq!(frames.len(), 1);
1173 match &frames[0] {
1174 Frame::AddAddress(decoded) => {
1175 assert_eq!(decoded.sequence, original.sequence);
1176 assert_eq!(decoded.address, original.address);
1177 }
1179 x => panic!("incorrect frame {x:?}"),
1180 }
1181 }
1182
1183 #[test]
1184 fn add_address_ipv6_coding() {
1185 let mut buf = Vec::new();
1186 let addr = SocketAddr::from(([0, 0, 0, 0, 0, 0, 0, 1], 8080));
1187 let original = AddAddress {
1188 sequence: VarInt(123),
1189 address: addr,
1190 priority: VarInt(200),
1191 };
1192 original.encode_rfc(&mut buf);
1194 let frames = frames(buf);
1195 assert_eq!(frames.len(), 1);
1196 match &frames[0] {
1197 Frame::AddAddress(decoded) => {
1198 assert_eq!(decoded.sequence, original.sequence);
1199 assert_eq!(decoded.address, original.address);
1200 }
1202 x => panic!("incorrect frame {x:?}"),
1203 }
1204 }
1205
1206 #[test]
1207 fn punch_me_now_ipv4_coding() {
1208 let mut buf = Vec::new();
1209 let addr = SocketAddr::from(([192, 168, 1, 1], 9000));
1210 let original = PunchMeNow {
1211 round: VarInt(1),
1212 paired_with_sequence_number: VarInt(42),
1213 address: addr,
1214 target_peer_id: None,
1215 };
1216 original.encode_rfc(&mut buf);
1218 let frames = frames(buf);
1219 assert_eq!(frames.len(), 1);
1220 match &frames[0] {
1221 Frame::PunchMeNow(decoded) => {
1222 assert_eq!(decoded.round, original.round);
1223 assert_eq!(
1224 decoded.paired_with_sequence_number,
1225 original.paired_with_sequence_number
1226 );
1227 assert_eq!(decoded.address, original.address);
1228 }
1229 x => panic!("incorrect frame {x:?}"),
1230 }
1231 }
1232
1233 #[test]
1234 fn punch_me_now_ipv6_coding() {
1235 let mut buf = Vec::new();
1236 let addr = SocketAddr::from(([0xfe80, 0, 0, 0, 0, 0, 0, 1], 9000));
1237 let original = PunchMeNow {
1238 round: VarInt(2),
1239 paired_with_sequence_number: VarInt(100),
1240 address: addr,
1241 target_peer_id: None,
1242 };
1243 original.encode_rfc(&mut buf);
1245 let frames = frames(buf);
1246 assert_eq!(frames.len(), 1);
1247 match &frames[0] {
1248 Frame::PunchMeNow(decoded) => {
1249 assert_eq!(decoded.round, original.round);
1250 assert_eq!(
1251 decoded.paired_with_sequence_number,
1252 original.paired_with_sequence_number
1253 );
1254 assert_eq!(decoded.address, original.address);
1255 }
1256 x => panic!("incorrect frame {x:?}"),
1257 }
1258 }
1259
1260 #[test]
1261 fn remove_address_coding() {
1262 let mut buf = Vec::new();
1263 let original = RemoveAddress {
1264 sequence: VarInt(42),
1265 };
1266 original.encode(&mut buf);
1267 let frames = frames(buf);
1268 assert_eq!(frames.len(), 1);
1269 match &frames[0] {
1270 Frame::RemoveAddress(decoded) => {
1271 assert_eq!(decoded.sequence, original.sequence);
1272 }
1273 x => panic!("incorrect frame {x:?}"),
1274 }
1275 }
1276
1277 #[test]
1278 fn nat_traversal_frame_size_bounds() {
1279 let mut buf = Vec::new();
1281
1282 let addr = AddAddress {
1284 sequence: VarInt::MAX,
1285 address: SocketAddr::from(([0xffff; 8], 65535)),
1286 priority: VarInt::MAX,
1287 };
1288 addr.encode(&mut buf);
1289 assert!(buf.len() <= AddAddress::SIZE_BOUND);
1290 buf.clear();
1291
1292 let punch = PunchMeNow {
1294 round: VarInt::MAX,
1295 paired_with_sequence_number: VarInt::MAX,
1296 address: SocketAddr::from(([0xffff; 8], 65535)),
1297 target_peer_id: Some([0xff; 32]),
1298 };
1299 punch.encode(&mut buf);
1300 assert!(buf.len() <= PunchMeNow::SIZE_BOUND);
1301 buf.clear();
1302
1303 let remove = RemoveAddress {
1305 sequence: VarInt::MAX,
1306 };
1307 remove.encode(&mut buf);
1308 assert!(buf.len() <= RemoveAddress::SIZE_BOUND);
1309 }
1310
1311 #[test]
1312 fn punch_me_now_with_target_peer_id() {
1313 let mut buf = Vec::new();
1318 let target_peer_id = [0x42; 32]; let addr = SocketAddr::from(([192, 168, 1, 100], 12345));
1320 let original = PunchMeNow {
1321 round: VarInt(5),
1322 paired_with_sequence_number: VarInt(999),
1323 address: addr,
1324 target_peer_id: Some(target_peer_id),
1325 };
1326 original.encode_rfc(&mut buf);
1328 let frames = frames(buf);
1329 assert_eq!(frames.len(), 1);
1330 match &frames[0] {
1331 Frame::PunchMeNow(decoded) => {
1332 assert_eq!(decoded.round, original.round);
1333 assert_eq!(
1334 decoded.paired_with_sequence_number,
1335 original.paired_with_sequence_number
1336 );
1337 assert_eq!(decoded.address, original.address);
1338 assert_eq!(decoded.target_peer_id, None);
1340 }
1341 x => panic!("incorrect frame {x:?}"),
1342 }
1343 }
1344
1345 #[test]
1346 fn nat_traversal_frame_edge_cases() {
1347 let mut buf = Vec::new();
1349
1350 let min_addr = AddAddress {
1352 sequence: VarInt(0),
1353 address: SocketAddr::from(([0, 0, 0, 0], 0)),
1354 priority: VarInt(0),
1355 };
1356 min_addr.encode_rfc(&mut buf);
1357 let frames1 = frames(buf.clone());
1358 assert_eq!(frames1.len(), 1);
1359 buf.clear();
1360
1361 let min_punch = PunchMeNow {
1363 round: VarInt(0),
1364 paired_with_sequence_number: VarInt(0),
1365 address: SocketAddr::from(([0, 0, 0, 0], 0)),
1366 target_peer_id: None,
1367 };
1368 min_punch.encode_rfc(&mut buf);
1369 let frames2 = frames(buf.clone());
1370 assert_eq!(frames2.len(), 1);
1371 buf.clear();
1372
1373 let min_remove = RemoveAddress {
1375 sequence: VarInt(0),
1376 };
1377 min_remove.encode(&mut buf);
1378 let frames3 = frames(buf);
1379 assert_eq!(frames3.len(), 1);
1380 }
1381
1382 #[test]
1383 fn nat_traversal_frame_boundary_values() {
1384 let mut buf = Vec::new();
1386
1387 let boundary_values = [
1389 VarInt(0),
1390 VarInt(63), VarInt(64), VarInt(16383), VarInt(16384), VarInt(1073741823), VarInt(1073741824), ];
1397
1398 for &sequence in &boundary_values {
1399 for &priority in &boundary_values {
1400 let addr = AddAddress {
1401 sequence,
1402 address: SocketAddr::from(([127, 0, 0, 1], 8080)),
1403 priority,
1404 };
1405 addr.encode_rfc(&mut buf);
1406 let parsed_frames = frames(buf.clone());
1407 assert_eq!(parsed_frames.len(), 1);
1408 match &parsed_frames[0] {
1409 Frame::AddAddress(decoded) => {
1410 assert_eq!(decoded.sequence, sequence);
1411 }
1413 x => panic!("incorrect frame {x:?}"),
1414 }
1415 buf.clear();
1416 }
1417 }
1418 }
1419
1420 #[test]
1421 fn nat_traversal_frame_error_handling() {
1422 let malformed_frames = vec![
1424 vec![0xc0, 0x90, 0xf9, 0x0f], vec![0xc0, 0x92, 0xf9, 0x0f], vec![0xc0, 0x94, 0xf9, 0x0f], vec![0xc0, 0x90, 0xf9, 0x0f, 0x01], vec![0xc0, 0x90, 0xf9, 0x0f, 0x01, 0x04], vec![0xc0, 0x92, 0xf9, 0x0f, 0x01], vec![0xc0, 0x92, 0xf9, 0x0f, 0x01, 0x02], vec![0xc0, 0x90, 0xf9, 0x0f, 0x01, 0x99, 0x01, 0x02, 0x03, 0x04], ];
1440
1441 for malformed in malformed_frames {
1442 let result = Iter::new(Bytes::from(malformed)).unwrap().next();
1443 if let Some(frame_result) = result {
1444 match frame_result {
1447 Ok(_) => {} Err(_) => {} }
1450 }
1451 }
1452 }
1453
1454 #[test]
1455 fn nat_traversal_frame_roundtrip_consistency() {
1456 let add_test_cases = vec![
1460 AddAddress {
1461 sequence: VarInt(42),
1462 address: SocketAddr::from(([127, 0, 0, 1], 8080)),
1463 priority: VarInt(100),
1464 },
1465 AddAddress {
1466 sequence: VarInt(1000),
1467 address: SocketAddr::from(([0, 0, 0, 0, 0, 0, 0, 1], 443)),
1468 priority: VarInt(255),
1469 },
1470 ];
1471
1472 for original_add in add_test_cases {
1473 let mut buf = Vec::new();
1474 original_add.encode_rfc(&mut buf);
1475
1476 let decoded_frames = frames(buf);
1477 assert_eq!(decoded_frames.len(), 1);
1478
1479 match &decoded_frames[0] {
1480 Frame::AddAddress(decoded) => {
1481 assert_eq!(original_add.sequence, decoded.sequence);
1482 assert_eq!(original_add.address, decoded.address);
1483 }
1485 _ => panic!("Expected AddAddress frame"),
1486 }
1487 }
1488
1489 let punch_test_cases = vec![
1491 PunchMeNow {
1492 round: VarInt(1),
1493 paired_with_sequence_number: VarInt(42),
1494 address: SocketAddr::from(([192, 168, 1, 1], 9000)),
1495 target_peer_id: None,
1496 },
1497 PunchMeNow {
1498 round: VarInt(10),
1499 paired_with_sequence_number: VarInt(500),
1500 address: SocketAddr::from(([2001, 0xdb8, 0, 0, 0, 0, 0, 1], 12345)),
1501 target_peer_id: Some([0xaa; 32]),
1502 },
1503 ];
1504
1505 for original_punch in punch_test_cases {
1506 let mut buf = Vec::new();
1507 original_punch.encode_rfc(&mut buf);
1508
1509 let decoded_frames = frames(buf);
1510 assert_eq!(decoded_frames.len(), 1);
1511
1512 match &decoded_frames[0] {
1513 Frame::PunchMeNow(decoded) => {
1514 assert_eq!(original_punch.round, decoded.round);
1515 assert_eq!(
1516 original_punch.paired_with_sequence_number,
1517 decoded.paired_with_sequence_number
1518 );
1519 assert_eq!(original_punch.address, decoded.address);
1520 assert_eq!(decoded.target_peer_id, None);
1522 }
1523 _ => panic!("Expected PunchMeNow frame"),
1524 }
1525 }
1526
1527 let remove_test_cases = vec![
1529 RemoveAddress {
1530 sequence: VarInt(123),
1531 },
1532 RemoveAddress {
1533 sequence: VarInt(0),
1534 },
1535 ];
1536
1537 for original_remove in remove_test_cases {
1538 let mut buf = Vec::new();
1539 original_remove.encode(&mut buf);
1540
1541 let decoded_frames = frames(buf);
1542 assert_eq!(decoded_frames.len(), 1);
1543
1544 match &decoded_frames[0] {
1545 Frame::RemoveAddress(decoded) => {
1546 assert_eq!(original_remove.sequence, decoded.sequence);
1547 }
1548 _ => panic!("Expected RemoveAddress frame"),
1549 }
1550 }
1551 }
1552
1553 #[test]
1554 fn nat_traversal_frame_type_constants() {
1555 assert_eq!(FrameType::ADD_ADDRESS_IPV4.0, 0x3d7e90);
1557 assert_eq!(FrameType::ADD_ADDRESS_IPV6.0, 0x3d7e91);
1558 assert_eq!(FrameType::PUNCH_ME_NOW_IPV4.0, 0x3d7e92);
1559 assert_eq!(FrameType::PUNCH_ME_NOW_IPV6.0, 0x3d7e93);
1560 assert_eq!(FrameType::REMOVE_ADDRESS.0, 0x3d7e94);
1561 }
1562
1563 #[test]
1564 fn observed_address_frame_encoding() {
1565 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
1566
1567 let ipv4_cases = vec![
1569 ObservedAddress {
1570 sequence_number: VarInt::from_u32(1),
1571 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 8080),
1572 },
1573 ObservedAddress {
1574 sequence_number: VarInt::from_u32(2),
1575 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 443),
1576 },
1577 ObservedAddress {
1578 sequence_number: VarInt::from_u32(3),
1579 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 65535),
1580 },
1581 ];
1582
1583 for original in ipv4_cases {
1584 let mut buf = Vec::new();
1585 original.encode(&mut buf);
1586
1587 let decoded_frames = frames(buf);
1588 assert_eq!(decoded_frames.len(), 1);
1589
1590 match &decoded_frames[0] {
1591 Frame::ObservedAddress(decoded) => {
1592 assert_eq!(original.address, decoded.address);
1593 }
1594 _ => panic!("Expected ObservedAddress frame"),
1595 }
1596 }
1597
1598 let ipv6_cases = vec![
1600 ObservedAddress {
1601 sequence_number: VarInt::from_u32(4),
1602 address: SocketAddr::new(
1603 IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)),
1604 8080,
1605 ),
1606 },
1607 ObservedAddress {
1608 sequence_number: VarInt::from_u32(5),
1609 address: SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 443),
1610 },
1611 ObservedAddress {
1612 sequence_number: VarInt::from_u32(6),
1613 address: SocketAddr::new(
1614 IpAddr::V6(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1)),
1615 65535,
1616 ),
1617 },
1618 ];
1619
1620 for original in ipv6_cases {
1621 let mut buf = Vec::new();
1622 original.encode(&mut buf);
1623
1624 let decoded_frames = frames(buf);
1625 assert_eq!(decoded_frames.len(), 1);
1626
1627 match &decoded_frames[0] {
1628 Frame::ObservedAddress(decoded) => {
1629 assert_eq!(original.address, decoded.address);
1630 }
1631 _ => panic!("Expected ObservedAddress frame"),
1632 }
1633 }
1634 }
1635
1636 #[test]
1637 fn observed_address_malformed_frames() {
1638 use crate::coding::BufMutExt;
1639 use bytes::BufMut;
1640
1641 let mut buf = Vec::new();
1643 buf.write(FrameType::OBSERVED_ADDRESS_IPV4);
1645 let result = Iter::new(Bytes::from(buf));
1648 assert!(result.is_ok());
1649 let mut iter = result.unwrap();
1650 let frame_result = iter.next();
1651 assert!(frame_result.is_some());
1652 assert!(frame_result.unwrap().is_err());
1653
1654 let mut buf = Vec::new();
1656 buf.write(FrameType::OBSERVED_ADDRESS_IPV4);
1658 buf.put_u8(4); buf.put_slice(&[192, 168]); let result = Iter::new(Bytes::from(buf));
1662 assert!(result.is_ok());
1663 let mut iter = result.unwrap();
1664 let frame_result = iter.next();
1665 assert!(frame_result.is_some());
1666 assert!(frame_result.unwrap().is_err());
1667
1668 let mut buf = Vec::new();
1670 buf.write(FrameType::OBSERVED_ADDRESS_IPV6);
1672 buf.write_var(1); buf.put_slice(&[0x20, 0x01, 0x0d, 0xb8]); let result = Iter::new(Bytes::from(buf));
1676 assert!(result.is_ok());
1677 let mut iter = result.unwrap();
1678 let frame_result = iter.next();
1679 assert!(frame_result.is_some());
1680 assert!(frame_result.unwrap().is_err());
1681 }
1682
1683 #[test]
1684 fn observed_address_frame_type_constant() {
1685 assert_eq!(FrameType::OBSERVED_ADDRESS_IPV4.0, 0x9f81a6);
1687 assert_eq!(FrameType::OBSERVED_ADDRESS_IPV6.0, 0x9f81a7);
1688 }
1689
1690 #[test]
1691 fn observed_address_frame_serialization_edge_cases() {
1692 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
1693
1694 let frame_port_0 = ObservedAddress {
1696 sequence_number: VarInt::from_u32(100),
1697 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 0),
1698 };
1699 let mut buf = Vec::new();
1700 frame_port_0.encode(&mut buf);
1701 let decoded_frames = frames(buf);
1702 assert_eq!(decoded_frames.len(), 1);
1703 match &decoded_frames[0] {
1704 Frame::ObservedAddress(decoded) => {
1705 assert_eq!(frame_port_0.address, decoded.address);
1706 assert_eq!(decoded.address.port(), 0);
1707 }
1708 _ => panic!("Expected ObservedAddress frame"),
1709 }
1710
1711 let frame_max_port = ObservedAddress {
1713 sequence_number: VarInt::from_u32(101),
1714 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 65535),
1715 };
1716 let mut buf = Vec::new();
1717 frame_max_port.encode(&mut buf);
1718 let decoded_frames = frames(buf);
1719 assert_eq!(decoded_frames.len(), 1);
1720 match &decoded_frames[0] {
1721 Frame::ObservedAddress(decoded) => {
1722 assert_eq!(frame_max_port.address, decoded.address);
1723 assert_eq!(decoded.address.port(), 65535);
1724 }
1725 _ => panic!("Expected ObservedAddress frame"),
1726 }
1727
1728 let unspecified_v4 = ObservedAddress {
1730 sequence_number: VarInt::from_u32(102),
1731 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 8080),
1732 };
1733 let mut buf = Vec::new();
1734 unspecified_v4.encode(&mut buf);
1735 let decoded_frames = frames(buf);
1736 assert_eq!(decoded_frames.len(), 1);
1737 match &decoded_frames[0] {
1738 Frame::ObservedAddress(decoded) => {
1739 assert_eq!(unspecified_v4.address, decoded.address);
1740 assert_eq!(decoded.address.ip(), IpAddr::V4(Ipv4Addr::UNSPECIFIED));
1741 }
1742 _ => panic!("Expected ObservedAddress frame"),
1743 }
1744
1745 let unspecified_v6 = ObservedAddress {
1746 sequence_number: VarInt::from_u32(103),
1747 address: SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 443),
1748 };
1749 let mut buf = Vec::new();
1750 unspecified_v6.encode(&mut buf);
1751 let decoded_frames = frames(buf);
1752 assert_eq!(decoded_frames.len(), 1);
1753 match &decoded_frames[0] {
1754 Frame::ObservedAddress(decoded) => {
1755 assert_eq!(unspecified_v6.address, decoded.address);
1756 assert_eq!(decoded.address.ip(), IpAddr::V6(Ipv6Addr::UNSPECIFIED));
1757 }
1758 _ => panic!("Expected ObservedAddress frame"),
1759 }
1760 }
1761
1762 #[test]
1763 fn observed_address_frame_size_compliance() {
1764 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
1765
1766 let test_addresses = vec![
1768 ObservedAddress {
1769 sequence_number: VarInt::from_u32(1),
1770 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 8080),
1771 },
1772 ObservedAddress {
1773 sequence_number: VarInt::from_u32(2),
1774 address: SocketAddr::new(
1775 IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)),
1776 443,
1777 ),
1778 },
1779 ];
1780
1781 for frame in test_addresses {
1782 let mut buf = Vec::new();
1783 frame.encode(&mut buf);
1784
1785 match frame.address.ip() {
1789 IpAddr::V4(_) => {
1790 assert!(
1791 buf.len() == 11,
1792 "IPv4 frame size {} out of expected range",
1793 buf.len()
1794 );
1795 }
1796 IpAddr::V6(_) => {
1797 assert!(
1798 buf.len() == 23,
1799 "IPv6 frame size {} out of expected range",
1800 buf.len()
1801 );
1802 }
1803 }
1804 }
1805 }
1806
1807 #[test]
1808 fn observed_address_multiple_frames_in_packet() {
1809 use crate::coding::BufMutExt;
1810 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
1811
1812 let observed1 = ObservedAddress {
1814 sequence_number: VarInt::from_u32(10),
1815 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 1234),
1816 };
1817 let observed2 = ObservedAddress {
1818 sequence_number: VarInt::from_u32(11),
1819 address: SocketAddr::new(
1820 IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 2)),
1821 5678,
1822 ),
1823 };
1824
1825 let mut buf = Vec::new();
1826 observed1.encode(&mut buf);
1828 buf.write(FrameType::PING);
1830 observed2.encode(&mut buf);
1832 buf.push(0); let decoded_frames = frames(buf);
1836 assert_eq!(decoded_frames.len(), 4);
1837
1838 match &decoded_frames[0] {
1840 Frame::ObservedAddress(dec) => {
1841 assert_eq!(observed1.address, dec.address);
1842 }
1843 _ => panic!("Expected ObservedAddress at position 0"),
1844 }
1845
1846 match &decoded_frames[1] {
1847 Frame::Ping => {}
1848 _ => panic!("Expected Ping at position 1"),
1849 }
1850
1851 match &decoded_frames[2] {
1852 Frame::ObservedAddress(dec) => {
1853 assert_eq!(observed2.address, dec.address);
1854 }
1855 _ => panic!("Expected ObservedAddress at position 2"),
1856 }
1857
1858 match &decoded_frames[3] {
1859 Frame::Padding => {}
1860 _ => panic!("Expected Padding at position 3"),
1861 }
1862 }
1863
1864 #[test]
1865 fn observed_address_frame_error_recovery() {
1866 use bytes::BufMut;
1867
1868 let mut buf = Vec::new();
1870
1871 buf.put_u8(FrameType::PING.0 as u8);
1873
1874 buf.write(FrameType::OBSERVED_ADDRESS_IPV4);
1877 buf.write_var(1); buf.put_slice(&[192, 168]); buf.put_u8(FrameType::PING.0 as u8);
1882
1883 let result = Iter::new(Bytes::from(buf));
1884 assert!(result.is_ok());
1885 let mut iter = result.unwrap();
1886
1887 let frame1 = iter.next();
1889 assert!(frame1.is_some());
1890 assert!(frame1.unwrap().is_ok());
1891
1892 let frame2 = iter.next();
1894 assert!(frame2.is_some());
1895 assert!(frame2.unwrap().is_err());
1896
1897 let frame3 = iter.next();
1899 assert!(frame3.is_none());
1900 }
1901
1902 #[test]
1903 fn observed_address_frame_varint_encoding() {
1904 use std::net::{IpAddr, Ipv4Addr};
1905
1906 let frame = ObservedAddress {
1908 sequence_number: VarInt::from_u32(1000),
1909 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 80),
1910 };
1911
1912 let mut buf = Vec::new();
1913 frame.encode(&mut buf);
1914
1915 assert_eq!(buf[0], 0x80); assert_eq!(buf[1], 0x9f); assert_eq!(buf[2], 0x81); assert_eq!(buf[3], 0xa6); }
1928
1929 mod comprehensive_tests {
1931 include!("frame/tests.rs");
1932 }
1933
1934 mod sequence_edge_cases {
1936 include!("frame/sequence_edge_case_tests.rs");
1937 }
1938
1939 mod ip_version_tests {
1941 include!("frame/ip_version_encoding_tests.rs");
1942 }
1943
1944 mod observed_address_test {
1946 include!("frame/observed_address_tests.rs");
1947 }
1948
1949 mod observed_address_validation {
1951 include!("frame/observed_address_sequence_validation_tests.rs");
1952 }
1953
1954 mod nat_frame_interop {
1956 use super::*;
1957 use crate::frame::{
1958 nat_compat::*,
1959 rfc_nat_traversal::{RfcAddAddress, RfcPunchMeNow, RfcRemoveAddress},
1960 };
1961
1962 #[test]
1963 fn test_add_address_conversions() {
1964 let old_frame = AddAddress {
1965 sequence: VarInt::from_u32(100),
1966 address: "10.0.0.1:8080".parse().unwrap(),
1967 priority: VarInt::from_u32(65535),
1968 };
1969
1970 let rfc_frame = add_address_to_rfc(&old_frame);
1971 assert_eq!(rfc_frame.sequence_number, old_frame.sequence);
1972 assert_eq!(rfc_frame.address, old_frame.address);
1973
1974 let default_priority = VarInt::from_u32(100000);
1975 let converted_back = rfc_to_add_address(&rfc_frame, default_priority);
1976 assert_eq!(converted_back.sequence, old_frame.sequence);
1977 assert_eq!(converted_back.address, old_frame.address);
1978 assert_eq!(converted_back.priority, default_priority);
1979 }
1980
1981 #[test]
1982 fn test_punch_me_now_conversions() {
1983 let old_frame = PunchMeNow {
1984 round: VarInt::from_u32(5),
1985 paired_with_sequence_number: VarInt::from_u32(100),
1986 address: "192.168.1.1:5000".parse().unwrap(),
1987 target_peer_id: Some([0x42; 32]),
1988 };
1989
1990 let rfc_frame = punch_me_now_to_rfc(&old_frame);
1991 assert_eq!(rfc_frame.round, old_frame.round);
1992 assert_eq!(
1993 rfc_frame.paired_with_sequence_number,
1994 old_frame.paired_with_sequence_number
1995 );
1996 assert_eq!(rfc_frame.address, old_frame.address);
1997
1998 let converted_back = rfc_to_punch_me_now(&rfc_frame);
1999 assert_eq!(converted_back.round, old_frame.round);
2000 assert_eq!(
2001 converted_back.paired_with_sequence_number,
2002 old_frame.paired_with_sequence_number
2003 );
2004 assert_eq!(converted_back.address, old_frame.address);
2005 assert_eq!(converted_back.target_peer_id, None);
2006 }
2007
2008 #[test]
2009 fn test_priority_strategy() {
2010 let strategy = PriorityStrategy {
2011 use_ice_priority: true,
2012 default_priority: VarInt::from_u32(50000),
2013 };
2014
2015 let public_v4: SocketAddr = "8.8.8.8:53".parse().unwrap();
2016 let private_v4: SocketAddr = "192.168.1.1:80".parse().unwrap();
2017 let loopback_v4: SocketAddr = "127.0.0.1:8080".parse().unwrap();
2018
2019 let pub_priority = strategy.calculate_priority(&public_v4);
2020 let priv_priority = strategy.calculate_priority(&private_v4);
2021 let loop_priority = strategy.calculate_priority(&loopback_v4);
2022
2023 assert!(pub_priority.into_inner() > priv_priority.into_inner());
2024 assert!(priv_priority.into_inner() > loop_priority.into_inner());
2025 }
2026
2027 #[test]
2028 fn test_compat_mode_detection() {
2029 assert_eq!(detect_frame_format(0x3d7e90), FrameFormat::Rfc);
2030 assert_eq!(detect_frame_format(0x3d7e91), FrameFormat::Rfc);
2031 assert_eq!(detect_frame_format(0x12345678), FrameFormat::Legacy);
2032 }
2033 }
2034}
2035
2036pub(crate) mod rfc_nat_traversal;
2038
2039pub(crate) mod nat_compat;
2041
2042pub mod nat_traversal_unified;