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