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 TRY_CONNECT_TO_IPV4 = 0x3d7e95,
162 TRY_CONNECT_TO_IPV6 = 0x3d7e96,
163 TRY_CONNECT_TO_RESPONSE_IPV4 = 0x3d7e97,
164 TRY_CONNECT_TO_RESPONSE_IPV6 = 0x3d7e98,
165 }
167
168const STREAM_TYS: RangeInclusive<u64> = RangeInclusive::new(0x08, 0x0f);
169const DATAGRAM_TYS: RangeInclusive<u64> = RangeInclusive::new(0x30, 0x31);
170
171#[derive(Debug)]
173pub(crate) enum Frame {
174 Padding,
175 Ping,
176 Ack(Ack),
177 ResetStream(ResetStream),
178 StopSending(StopSending),
179 Crypto(Crypto),
180 NewToken(NewToken),
181 Stream(Stream),
182 MaxData(VarInt),
183 MaxStreamData { id: StreamId, offset: u64 },
184 MaxStreams { dir: Dir, count: u64 },
185 DataBlocked { offset: u64 },
186 StreamDataBlocked { id: StreamId, offset: u64 },
187 StreamsBlocked { dir: Dir, limit: u64 },
188 NewConnectionId(NewConnectionId),
189 RetireConnectionId { sequence: u64 },
190 PathChallenge(u64),
191 PathResponse(u64),
192 Close(Close),
193 Datagram(Datagram),
194 AckFrequency(AckFrequency),
195 ImmediateAck,
196 HandshakeDone,
197 AddAddress(AddAddress),
198 PunchMeNow(PunchMeNow),
199 RemoveAddress(RemoveAddress),
200 ObservedAddress(ObservedAddress),
201 TryConnectTo(TryConnectTo),
202 TryConnectToResponse(TryConnectToResponse),
203}
204
205impl Frame {
206 pub(crate) fn ty(&self) -> FrameType {
207 use Frame::*;
208 match self {
209 Padding => FrameType::PADDING,
210 ResetStream(_) => FrameType::RESET_STREAM,
211 Close(self::Close::Connection(_)) => FrameType::CONNECTION_CLOSE,
212 Close(self::Close::Application(_)) => FrameType::APPLICATION_CLOSE,
213 MaxData(_) => FrameType::MAX_DATA,
214 MaxStreamData { .. } => FrameType::MAX_STREAM_DATA,
215 MaxStreams { dir: Dir::Bi, .. } => FrameType::MAX_STREAMS_BIDI,
216 MaxStreams { dir: Dir::Uni, .. } => FrameType::MAX_STREAMS_UNI,
217 Ping => FrameType::PING,
218 DataBlocked { .. } => FrameType::DATA_BLOCKED,
219 StreamDataBlocked { .. } => FrameType::STREAM_DATA_BLOCKED,
220 StreamsBlocked { dir: Dir::Bi, .. } => FrameType::STREAMS_BLOCKED_BIDI,
221 StreamsBlocked { dir: Dir::Uni, .. } => FrameType::STREAMS_BLOCKED_UNI,
222 StopSending { .. } => FrameType::STOP_SENDING,
223 RetireConnectionId { .. } => FrameType::RETIRE_CONNECTION_ID,
224 Ack(_) => FrameType::ACK,
225 Stream(x) => {
226 let mut ty = *STREAM_TYS.start();
227 if x.fin {
228 ty |= 0x01;
229 }
230 if x.offset != 0 {
231 ty |= 0x04;
232 }
233 FrameType(ty)
234 }
235 PathChallenge(_) => FrameType::PATH_CHALLENGE,
236 PathResponse(_) => FrameType::PATH_RESPONSE,
237 NewConnectionId { .. } => FrameType::NEW_CONNECTION_ID,
238 Crypto(_) => FrameType::CRYPTO,
239 NewToken(_) => FrameType::NEW_TOKEN,
240 Datagram(_) => FrameType(*DATAGRAM_TYS.start()),
241 AckFrequency(_) => FrameType::ACK_FREQUENCY,
242 ImmediateAck => FrameType::IMMEDIATE_ACK,
243 HandshakeDone => FrameType::HANDSHAKE_DONE,
244 AddAddress(a) => match a.address {
245 SocketAddr::V4(_) => FrameType::ADD_ADDRESS_IPV4,
246 SocketAddr::V6(_) => FrameType::ADD_ADDRESS_IPV6,
247 },
248 PunchMeNow(p) => match p.address {
249 SocketAddr::V4(_) => FrameType::PUNCH_ME_NOW_IPV4,
250 SocketAddr::V6(_) => FrameType::PUNCH_ME_NOW_IPV6,
251 },
252 RemoveAddress(_) => FrameType::REMOVE_ADDRESS,
253 ObservedAddress(o) => match o.address {
254 SocketAddr::V4(_) => FrameType::OBSERVED_ADDRESS_IPV4,
255 SocketAddr::V6(_) => FrameType::OBSERVED_ADDRESS_IPV6,
256 },
257 TryConnectTo(t) => match t.target_address {
258 SocketAddr::V4(_) => FrameType::TRY_CONNECT_TO_IPV4,
259 SocketAddr::V6(_) => FrameType::TRY_CONNECT_TO_IPV6,
260 },
261 TryConnectToResponse(r) => match r.source_address {
262 SocketAddr::V4(_) => FrameType::TRY_CONNECT_TO_RESPONSE_IPV4,
263 SocketAddr::V6(_) => FrameType::TRY_CONNECT_TO_RESPONSE_IPV6,
264 },
265 }
266 }
267
268 pub(crate) fn is_ack_eliciting(&self) -> bool {
269 !matches!(*self, Self::Ack(_) | Self::Padding | Self::Close(_))
270 }
271}
272
273#[derive(Clone, Debug)]
275pub enum Close {
276 Connection(ConnectionClose),
278 Application(ApplicationClose),
280}
281
282impl Close {
283 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
284 match *self {
285 Self::Connection(ref x) => x.encode(out, max_len),
286 Self::Application(ref x) => x.encode(out, max_len),
287 }
288 }
289
290 pub(crate) fn is_transport_layer(&self) -> bool {
291 matches!(*self, Self::Connection(_))
292 }
293}
294
295impl From<TransportError> for Close {
296 fn from(x: TransportError) -> Self {
297 Self::Connection(x.into())
298 }
299}
300impl From<ConnectionClose> for Close {
301 fn from(x: ConnectionClose) -> Self {
302 Self::Connection(x)
303 }
304}
305impl From<ApplicationClose> for Close {
306 fn from(x: ApplicationClose) -> Self {
307 Self::Application(x)
308 }
309}
310
311#[derive(Debug, Clone, PartialEq, Eq)]
313pub struct ConnectionClose {
314 pub error_code: TransportErrorCode,
316 pub frame_type: Option<FrameType>,
318 pub reason: Bytes,
320}
321
322impl fmt::Display for ConnectionClose {
323 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
324 self.error_code.fmt(f)?;
325 if !self.reason.as_ref().is_empty() {
326 f.write_str(": ")?;
327 f.write_str(&String::from_utf8_lossy(&self.reason))?;
328 }
329 Ok(())
330 }
331}
332
333impl From<TransportError> for ConnectionClose {
334 fn from(x: TransportError) -> Self {
335 Self {
336 error_code: x.code,
337 frame_type: x.frame,
338 reason: x.reason.into(),
339 }
340 }
341}
342
343impl FrameStruct for ConnectionClose {
344 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
345}
346
347impl ConnectionClose {
348 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
349 out.write(FrameType::CONNECTION_CLOSE); out.write(self.error_code); let ty = self.frame_type.map_or(0, |x| x.0);
352 out.write_var(ty); let max_len = max_len
354 - 3
355 - VarInt::from_u64_bounded(ty).size()
356 - VarInt::from_u64_bounded(self.reason.len() as u64).size();
357 let actual_len = self.reason.len().min(max_len);
358 out.write_var(actual_len as u64); out.put_slice(&self.reason[0..actual_len]); }
361}
362
363#[derive(Debug, Clone, PartialEq, Eq)]
365pub struct ApplicationClose {
366 pub error_code: VarInt,
368 pub reason: Bytes,
370}
371
372impl fmt::Display for ApplicationClose {
373 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
374 if !self.reason.as_ref().is_empty() {
375 f.write_str(&String::from_utf8_lossy(&self.reason))?;
376 f.write_str(" (code ")?;
377 self.error_code.fmt(f)?;
378 f.write_str(")")?;
379 } else {
380 self.error_code.fmt(f)?;
381 }
382 Ok(())
383 }
384}
385
386impl FrameStruct for ApplicationClose {
387 const SIZE_BOUND: usize = 1 + 8 + 8;
388}
389
390impl ApplicationClose {
391 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
392 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();
395 let actual_len = self.reason.len().min(max_len);
396 out.write_var(actual_len as u64); out.put_slice(&self.reason[0..actual_len]); }
399}
400
401#[derive(Clone, Eq, PartialEq)]
402pub struct Ack {
404 pub largest: u64,
406 pub delay: u64,
408 pub additional: Bytes,
410 pub ecn: Option<EcnCounts>,
412}
413
414impl fmt::Debug for Ack {
415 #[allow(clippy::panic)]
416 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
417 let mut ranges = "[".to_string();
418 let mut first = true;
419 for range in self.iter() {
420 if !first {
421 ranges.push(',');
422 }
423 write!(ranges, "{range:?}")
424 .unwrap_or_else(|_| panic!("writing to string should not fail"));
425 first = false;
426 }
427 ranges.push(']');
428
429 f.debug_struct("Ack")
430 .field("largest", &self.largest)
431 .field("delay", &self.delay)
432 .field("ecn", &self.ecn)
433 .field("ranges", &ranges)
434 .finish()
435 }
436}
437
438impl<'a> IntoIterator for &'a Ack {
439 type Item = RangeInclusive<u64>;
440 type IntoIter = AckIter<'a>;
441
442 fn into_iter(self) -> AckIter<'a> {
443 AckIter::new(self.largest, &self.additional[..])
444 }
445}
446
447impl Ack {
448 #[allow(clippy::panic)]
450 pub fn encode<W: BufMut>(
451 delay: u64,
452 ranges: &ArrayRangeSet,
453 ecn: Option<&EcnCounts>,
454 buf: &mut W,
455 ) {
456 let mut rest = ranges.iter().rev();
457 let first = rest
458 .next()
459 .unwrap_or_else(|| panic!("ACK ranges should have at least one range"));
460 let largest = first.end - 1;
461 let first_size = first.end - first.start;
462 buf.write(if ecn.is_some() {
463 FrameType::ACK_ECN
464 } else {
465 FrameType::ACK
466 });
467 buf.write_var(largest);
468 buf.write_var(delay);
469 buf.write_var(ranges.len() as u64 - 1);
470 buf.write_var(first_size - 1);
471 let mut prev = first.start;
472 for block in rest {
473 let size = block.end - block.start;
474 buf.write_var(prev - block.end - 1);
475 buf.write_var(size - 1);
476 prev = block.start;
477 }
478 if let Some(x) = ecn {
479 x.encode(buf)
480 }
481 }
482
483 pub fn iter(&self) -> AckIter<'_> {
485 self.into_iter()
486 }
487}
488
489#[derive(Debug, Copy, Clone, Eq, PartialEq)]
490pub struct EcnCounts {
492 pub ect0: u64,
494 pub ect1: u64,
496 pub ce: u64,
498}
499
500impl std::ops::AddAssign<EcnCodepoint> for EcnCounts {
501 fn add_assign(&mut self, rhs: EcnCodepoint) {
502 match rhs {
503 EcnCodepoint::Ect0 => {
504 self.ect0 += 1;
505 }
506 EcnCodepoint::Ect1 => {
507 self.ect1 += 1;
508 }
509 EcnCodepoint::Ce => {
510 self.ce += 1;
511 }
512 }
513 }
514}
515
516impl EcnCounts {
517 pub const ZERO: Self = Self {
518 ect0: 0,
519 ect1: 0,
520 ce: 0,
521 };
522
523 pub fn encode<W: BufMut>(&self, out: &mut W) {
524 out.write_var(self.ect0);
525 out.write_var(self.ect1);
526 out.write_var(self.ce);
527 }
528}
529
530#[derive(Debug, Clone)]
531pub(crate) struct Stream {
532 pub(crate) id: StreamId,
533 pub(crate) offset: u64,
534 pub(crate) fin: bool,
535 pub(crate) data: Bytes,
536}
537
538impl FrameStruct for Stream {
539 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
540}
541
542#[derive(Debug, Clone)]
544pub(crate) struct StreamMeta {
545 pub(crate) id: StreamId,
546 pub(crate) offsets: Range<u64>,
547 pub(crate) fin: bool,
548}
549
550impl Default for StreamMeta {
552 fn default() -> Self {
553 Self {
554 id: StreamId(0),
555 offsets: 0..0,
556 fin: false,
557 }
558 }
559}
560
561impl StreamMeta {
562 pub(crate) fn encode<W: BufMut>(&self, length: bool, out: &mut W) {
563 let mut ty = *STREAM_TYS.start();
564 if self.offsets.start != 0 {
565 ty |= 0x04;
566 }
567 if length {
568 ty |= 0x02;
569 }
570 if self.fin {
571 ty |= 0x01;
572 }
573 out.write_var(ty); out.write(self.id); if self.offsets.start != 0 {
576 out.write_var(self.offsets.start); }
578 if length {
579 out.write_var(self.offsets.end - self.offsets.start); }
581 }
582}
583
584pub(crate) type StreamMetaVec = TinyVec<[StreamMeta; 1]>;
586
587#[derive(Debug, Clone)]
588pub(crate) struct Crypto {
589 pub(crate) offset: u64,
590 pub(crate) data: Bytes,
591}
592
593impl Crypto {
594 pub(crate) const SIZE_BOUND: usize = 17;
595
596 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
597 out.write(FrameType::CRYPTO);
598 out.write_var(self.offset);
599 out.write_var(self.data.len() as u64);
600 out.put_slice(&self.data);
601 }
602}
603
604#[derive(Debug, Clone)]
605pub(crate) struct NewToken {
606 pub(crate) token: Bytes,
607}
608
609impl NewToken {
610 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
611 out.write(FrameType::NEW_TOKEN);
612 out.write_var(self.token.len() as u64);
613 out.put_slice(&self.token);
614 }
615
616 pub(crate) fn size(&self) -> usize {
617 1 + VarInt::from_u64_bounded(self.token.len() as u64).size() + self.token.len()
618 }
619}
620
621pub(crate) struct Iter {
622 bytes: Bytes,
623 last_ty: Option<FrameType>,
624}
625
626impl Iter {
627 pub(crate) fn new(payload: Bytes) -> Result<Self, TransportError> {
628 if payload.is_empty() {
629 return Err(TransportError::PROTOCOL_VIOLATION(
633 "packet payload is empty",
634 ));
635 }
636
637 Ok(Self {
638 bytes: payload,
639 last_ty: None,
640 })
641 }
642
643 fn take_len(&mut self) -> Result<Bytes, UnexpectedEnd> {
644 let len = self.bytes.get_var()?;
645 if len > self.bytes.remaining() as u64 {
646 return Err(UnexpectedEnd);
647 }
648 Ok(self.bytes.split_to(len as usize))
649 }
650
651 fn try_next(&mut self) -> Result<Frame, IterErr> {
652 let ty = self.bytes.get::<FrameType>()?;
653 self.last_ty = Some(ty);
654 Ok(match ty {
655 FrameType::PADDING => Frame::Padding,
656 FrameType::RESET_STREAM => Frame::ResetStream(ResetStream {
657 id: self.bytes.get()?,
658 error_code: self.bytes.get()?,
659 final_offset: self.bytes.get()?,
660 }),
661 FrameType::CONNECTION_CLOSE => Frame::Close(Close::Connection(ConnectionClose {
662 error_code: self.bytes.get()?,
663 frame_type: {
664 let x = self.bytes.get_var()?;
665 if x == 0 { None } else { Some(FrameType(x)) }
666 },
667 reason: self.take_len()?,
668 })),
669 FrameType::APPLICATION_CLOSE => Frame::Close(Close::Application(ApplicationClose {
670 error_code: self.bytes.get()?,
671 reason: self.take_len()?,
672 })),
673 FrameType::MAX_DATA => Frame::MaxData(self.bytes.get()?),
674 FrameType::MAX_STREAM_DATA => Frame::MaxStreamData {
675 id: self.bytes.get()?,
676 offset: self.bytes.get_var()?,
677 },
678 FrameType::MAX_STREAMS_BIDI => Frame::MaxStreams {
679 dir: Dir::Bi,
680 count: self.bytes.get_var()?,
681 },
682 FrameType::MAX_STREAMS_UNI => Frame::MaxStreams {
683 dir: Dir::Uni,
684 count: self.bytes.get_var()?,
685 },
686 FrameType::PING => Frame::Ping,
687 FrameType::DATA_BLOCKED => Frame::DataBlocked {
688 offset: self.bytes.get_var()?,
689 },
690 FrameType::STREAM_DATA_BLOCKED => Frame::StreamDataBlocked {
691 id: self.bytes.get()?,
692 offset: self.bytes.get_var()?,
693 },
694 FrameType::STREAMS_BLOCKED_BIDI => Frame::StreamsBlocked {
695 dir: Dir::Bi,
696 limit: self.bytes.get_var()?,
697 },
698 FrameType::STREAMS_BLOCKED_UNI => Frame::StreamsBlocked {
699 dir: Dir::Uni,
700 limit: self.bytes.get_var()?,
701 },
702 FrameType::STOP_SENDING => Frame::StopSending(StopSending {
703 id: self.bytes.get()?,
704 error_code: self.bytes.get()?,
705 }),
706 FrameType::RETIRE_CONNECTION_ID => Frame::RetireConnectionId {
707 sequence: self.bytes.get_var()?,
708 },
709 FrameType::ACK | FrameType::ACK_ECN => {
710 let largest = self.bytes.get_var()?;
711 let delay = self.bytes.get_var()?;
712 let extra_blocks = self.bytes.get_var()? as usize;
713 let n = scan_ack_blocks(&self.bytes, largest, extra_blocks)?;
714 Frame::Ack(Ack {
715 delay,
716 largest,
717 additional: self.bytes.split_to(n),
718 ecn: if ty != FrameType::ACK_ECN {
719 None
720 } else {
721 Some(EcnCounts {
722 ect0: self.bytes.get_var()?,
723 ect1: self.bytes.get_var()?,
724 ce: self.bytes.get_var()?,
725 })
726 },
727 })
728 }
729 FrameType::PATH_CHALLENGE => Frame::PathChallenge(self.bytes.get()?),
730 FrameType::PATH_RESPONSE => Frame::PathResponse(self.bytes.get()?),
731 FrameType::NEW_CONNECTION_ID => {
732 let sequence = self.bytes.get_var()?;
733 let retire_prior_to = self.bytes.get_var()?;
734 if retire_prior_to > sequence {
735 return Err(IterErr::Malformed);
736 }
737 let length = self.bytes.get::<u8>()? as usize;
738 if length > MAX_CID_SIZE || length == 0 {
739 return Err(IterErr::Malformed);
740 }
741 if length > self.bytes.remaining() {
742 return Err(IterErr::UnexpectedEnd);
743 }
744 let mut stage = [0; MAX_CID_SIZE];
745 self.bytes.copy_to_slice(&mut stage[0..length]);
746 let id = ConnectionId::new(&stage[..length]);
747 if self.bytes.remaining() < 16 {
748 return Err(IterErr::UnexpectedEnd);
749 }
750 let mut reset_token = [0; RESET_TOKEN_SIZE];
751 self.bytes.copy_to_slice(&mut reset_token);
752 Frame::NewConnectionId(NewConnectionId {
753 sequence,
754 retire_prior_to,
755 id,
756 reset_token: reset_token.into(),
757 })
758 }
759 FrameType::CRYPTO => Frame::Crypto(Crypto {
760 offset: self.bytes.get_var()?,
761 data: self.take_len()?,
762 }),
763 FrameType::NEW_TOKEN => Frame::NewToken(NewToken {
764 token: self.take_len()?,
765 }),
766 FrameType::HANDSHAKE_DONE => Frame::HandshakeDone,
767 FrameType::ACK_FREQUENCY => Frame::AckFrequency(AckFrequency {
768 sequence: self.bytes.get()?,
769 ack_eliciting_threshold: self.bytes.get()?,
770 request_max_ack_delay: self.bytes.get()?,
771 reordering_threshold: self.bytes.get()?,
772 }),
773 FrameType::IMMEDIATE_ACK => Frame::ImmediateAck,
774 FrameType::ADD_ADDRESS_IPV4 => {
775 Frame::AddAddress(AddAddress::decode_auto(&mut self.bytes, false)?)
776 }
777 FrameType::ADD_ADDRESS_IPV6 => {
778 Frame::AddAddress(AddAddress::decode_auto(&mut self.bytes, true)?)
779 }
780 FrameType::PUNCH_ME_NOW_IPV4 => {
781 Frame::PunchMeNow(PunchMeNow::decode_auto(&mut self.bytes, false)?)
782 }
783 FrameType::PUNCH_ME_NOW_IPV6 => {
784 Frame::PunchMeNow(PunchMeNow::decode_auto(&mut self.bytes, true)?)
785 }
786 FrameType::REMOVE_ADDRESS => {
787 Frame::RemoveAddress(RemoveAddress::decode(&mut self.bytes)?)
789 }
790 FrameType::OBSERVED_ADDRESS_IPV4 => {
791 Frame::ObservedAddress(ObservedAddress::decode(&mut self.bytes, false)?)
792 }
793 FrameType::OBSERVED_ADDRESS_IPV6 => {
794 Frame::ObservedAddress(ObservedAddress::decode(&mut self.bytes, true)?)
795 }
796 FrameType::TRY_CONNECT_TO_IPV4 => {
797 Frame::TryConnectTo(TryConnectTo::decode(&mut self.bytes, false)?)
798 }
799 FrameType::TRY_CONNECT_TO_IPV6 => {
800 Frame::TryConnectTo(TryConnectTo::decode(&mut self.bytes, true)?)
801 }
802 FrameType::TRY_CONNECT_TO_RESPONSE_IPV4 => {
803 Frame::TryConnectToResponse(TryConnectToResponse::decode(&mut self.bytes, false)?)
804 }
805 FrameType::TRY_CONNECT_TO_RESPONSE_IPV6 => {
806 Frame::TryConnectToResponse(TryConnectToResponse::decode(&mut self.bytes, true)?)
807 }
808 _ => {
809 if let Some(s) = ty.stream() {
810 Frame::Stream(Stream {
811 id: self.bytes.get()?,
812 offset: if s.off() { self.bytes.get_var()? } else { 0 },
813 fin: s.fin(),
814 data: if s.len() {
815 self.take_len()?
816 } else {
817 self.take_remaining()
818 },
819 })
820 } else if let Some(d) = ty.datagram() {
821 Frame::Datagram(Datagram {
822 data: if d.len() {
823 self.take_len()?
824 } else {
825 self.take_remaining()
826 },
827 })
828 } else {
829 return Err(IterErr::InvalidFrameId);
830 }
831 }
832 })
833 }
834
835 fn take_remaining(&mut self) -> Bytes {
836 mem::take(&mut self.bytes)
837 }
838}
839
840impl Iterator for Iter {
841 type Item = Result<Frame, InvalidFrame>;
842 fn next(&mut self) -> Option<Self::Item> {
843 if !self.bytes.has_remaining() {
844 return None;
845 }
846 match self.try_next() {
847 Ok(x) => Some(Ok(x)),
848 Err(e) => {
849 self.bytes.clear();
851 Some(Err(InvalidFrame {
852 ty: self.last_ty,
853 reason: e.reason(),
854 }))
855 }
856 }
857 }
858}
859
860#[derive(Debug)]
861pub(crate) struct InvalidFrame {
862 pub(crate) ty: Option<FrameType>,
863 pub(crate) reason: &'static str,
864}
865
866impl From<InvalidFrame> for TransportError {
867 fn from(err: InvalidFrame) -> Self {
868 let mut te = Self::FRAME_ENCODING_ERROR(err.reason);
869 te.frame = err.ty;
870 te
871 }
872}
873
874fn scan_ack_blocks(mut buf: &[u8], largest: u64, n: usize) -> Result<usize, IterErr> {
876 let total_len = buf.remaining();
877 let first_block = buf.get_var()?;
878 let mut smallest = largest.checked_sub(first_block).ok_or(IterErr::Malformed)?;
879 for _ in 0..n {
880 let gap = buf.get_var()?;
881 smallest = smallest.checked_sub(gap + 2).ok_or(IterErr::Malformed)?;
882 let block = buf.get_var()?;
883 smallest = smallest.checked_sub(block).ok_or(IterErr::Malformed)?;
884 }
885 Ok(total_len - buf.remaining())
886}
887
888enum IterErr {
889 UnexpectedEnd,
890 InvalidFrameId,
891 Malformed,
892}
893
894impl IterErr {
895 fn reason(&self) -> &'static str {
896 use IterErr::*;
897 match *self {
898 UnexpectedEnd => "unexpected end",
899 InvalidFrameId => "invalid frame ID",
900 Malformed => "malformed",
901 }
902 }
903}
904
905impl From<UnexpectedEnd> for IterErr {
906 fn from(_: UnexpectedEnd) -> Self {
907 Self::UnexpectedEnd
908 }
909}
910
911#[derive(Debug, Clone)]
912pub struct AckIter<'a> {
913 largest: u64,
914 data: &'a [u8],
915}
916
917impl<'a> AckIter<'a> {
918 fn new(largest: u64, data: &'a [u8]) -> Self {
919 Self { largest, data }
920 }
921}
922
923impl Iterator for AckIter<'_> {
924 type Item = RangeInclusive<u64>;
925 fn next(&mut self) -> Option<RangeInclusive<u64>> {
926 if !self.data.has_remaining() {
927 return None;
928 }
929 let block = match self.data.get_var() {
930 Ok(block) => block,
931 Err(_) => return None,
932 };
933 let largest = self.largest;
934 if let Ok(gap) = self.data.get_var() {
935 self.largest -= block + gap + 2;
936 }
937 Some(largest - block..=largest)
938 }
939}
940
941#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
942#[derive(Debug, Copy, Clone)]
943pub struct ResetStream {
944 pub(crate) id: StreamId,
945 pub(crate) error_code: VarInt,
946 pub(crate) final_offset: VarInt,
947}
948
949impl FrameStruct for ResetStream {
950 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
951}
952
953impl ResetStream {
954 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
955 out.write(FrameType::RESET_STREAM); out.write(self.id); out.write(self.error_code); out.write(self.final_offset); }
960}
961
962#[derive(Debug, Copy, Clone)]
963pub(crate) struct StopSending {
964 pub(crate) id: StreamId,
965 pub(crate) error_code: VarInt,
966}
967
968impl FrameStruct for StopSending {
969 const SIZE_BOUND: usize = 1 + 8 + 8;
970}
971
972impl StopSending {
973 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
974 out.write(FrameType::STOP_SENDING); out.write(self.id); out.write(self.error_code) }
978}
979
980#[derive(Debug, Copy, Clone)]
981pub(crate) struct NewConnectionId {
982 pub(crate) sequence: u64,
983 pub(crate) retire_prior_to: u64,
984 pub(crate) id: ConnectionId,
985 pub(crate) reset_token: ResetToken,
986}
987
988impl NewConnectionId {
989 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
990 out.write(FrameType::NEW_CONNECTION_ID);
991 out.write_var(self.sequence);
992 out.write_var(self.retire_prior_to);
993 out.write(self.id.len() as u8);
994 out.put_slice(&self.id);
995 out.put_slice(&self.reset_token);
996 }
997}
998
999pub(crate) const RETIRE_CONNECTION_ID_SIZE_BOUND: usize = 9;
1001
1002#[derive(Debug, Clone)]
1004pub struct Datagram {
1005 pub data: Bytes,
1007}
1008
1009impl FrameStruct for Datagram {
1010 const SIZE_BOUND: usize = 1 + 8;
1011}
1012
1013impl Datagram {
1014 pub(crate) fn encode(&self, length: bool, out: &mut Vec<u8>) {
1015 out.write(FrameType(*DATAGRAM_TYS.start() | u64::from(length))); if length {
1017 out.write(VarInt::from_u64_bounded(self.data.len() as u64)); }
1020 out.extend_from_slice(&self.data);
1021 }
1022
1023 pub(crate) fn size(&self, length: bool) -> usize {
1024 1 + if length {
1025 VarInt::from_u64_bounded(self.data.len() as u64).size()
1026 } else {
1027 0
1028 } + self.data.len()
1029 }
1030}
1031
1032#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1033pub(crate) struct AckFrequency {
1034 pub(crate) sequence: VarInt,
1035 pub(crate) ack_eliciting_threshold: VarInt,
1036 pub(crate) request_max_ack_delay: VarInt,
1037 pub(crate) reordering_threshold: VarInt,
1038}
1039
1040impl AckFrequency {
1041 pub(crate) fn encode<W: BufMut>(&self, buf: &mut W) {
1042 buf.write(FrameType::ACK_FREQUENCY);
1043 buf.write(self.sequence);
1044 buf.write(self.ack_eliciting_threshold);
1045 buf.write(self.request_max_ack_delay);
1046 buf.write(self.reordering_threshold);
1047 }
1048}
1049
1050pub(crate) use nat_traversal_unified::{
1052 AddAddress, PunchMeNow, RemoveAddress, TryConnectError, TryConnectTo, TryConnectToResponse,
1053};
1054
1055#[derive(Debug, Clone, PartialEq, Eq)]
1058pub(crate) struct ObservedAddress {
1059 pub(crate) sequence_number: VarInt,
1061 pub(crate) address: SocketAddr,
1063}
1064
1065impl ObservedAddress {
1066 pub(crate) fn encode<W: BufMut>(&self, buf: &mut W) {
1067 match self.address {
1068 SocketAddr::V4(_) => buf.write(FrameType::OBSERVED_ADDRESS_IPV4),
1069 SocketAddr::V6(_) => buf.write(FrameType::OBSERVED_ADDRESS_IPV6),
1070 };
1071
1072 buf.write_var(self.sequence_number.0);
1074
1075 match self.address {
1077 SocketAddr::V4(addr) => {
1078 buf.put_slice(&addr.ip().octets());
1079 buf.put_u16(addr.port());
1080 }
1081 SocketAddr::V6(addr) => {
1082 buf.put_slice(&addr.ip().octets());
1083 buf.put_u16(addr.port());
1084 }
1085 }
1086 }
1087
1088 pub(crate) fn decode<R: Buf>(r: &mut R, is_ipv6: bool) -> Result<Self, UnexpectedEnd> {
1089 let sequence_number = VarInt::from_u64(r.get_var()?).map_err(|_| UnexpectedEnd)?;
1091
1092 let address = if is_ipv6 {
1094 if r.remaining() < 18 {
1095 return Err(UnexpectedEnd);
1096 }
1097 let mut octets = [0u8; 16];
1098 r.copy_to_slice(&mut octets);
1099 let port = r.get::<u16>()?;
1100 SocketAddr::new(octets.into(), port)
1101 } else {
1102 if r.remaining() < 6 {
1103 return Err(UnexpectedEnd);
1104 }
1105 let mut octets = [0u8; 4];
1106 r.copy_to_slice(&mut octets);
1107 let port = r.get::<u16>()?;
1108 SocketAddr::new(octets.into(), port)
1109 };
1110
1111 Ok(Self {
1112 sequence_number,
1113 address,
1114 })
1115 }
1116}
1117
1118impl FrameStruct for ObservedAddress {
1119 const SIZE_BOUND: usize = 4 + 8 + 16 + 2; }
1121
1122#[cfg(test)]
1123mod test {
1124 use super::*;
1125 use crate::coding::Codec;
1126 use assert_matches::assert_matches;
1127
1128 fn frames(buf: Vec<u8>) -> Vec<Frame> {
1129 Iter::new(Bytes::from(buf))
1130 .unwrap()
1131 .collect::<Result<Vec<_>, _>>()
1132 .unwrap()
1133 }
1134
1135 #[test]
1136 fn ack_coding() {
1137 const PACKETS: &[u64] = &[1, 2, 3, 5, 10, 11, 14];
1138 let mut ranges = ArrayRangeSet::new();
1139 for &packet in PACKETS {
1140 ranges.insert(packet..packet + 1);
1141 }
1142 let mut buf = Vec::new();
1143 const ECN: EcnCounts = EcnCounts {
1144 ect0: 42,
1145 ect1: 24,
1146 ce: 12,
1147 };
1148 Ack::encode(42, &ranges, Some(&ECN), &mut buf);
1149 let frames = frames(buf);
1150 assert_eq!(frames.len(), 1);
1151 match frames[0] {
1152 Frame::Ack(ref ack) => {
1153 let mut packets = ack.iter().flatten().collect::<Vec<_>>();
1154 packets.sort_unstable();
1155 assert_eq!(&packets[..], PACKETS);
1156 assert_eq!(ack.ecn, Some(ECN));
1157 }
1158 ref x => panic!("incorrect frame {x:?}"),
1159 }
1160 }
1161
1162 #[test]
1163 fn ack_frequency_coding() {
1164 let mut buf = Vec::new();
1165 let original = AckFrequency {
1166 sequence: VarInt(42),
1167 ack_eliciting_threshold: VarInt(20),
1168 request_max_ack_delay: VarInt(50_000),
1169 reordering_threshold: VarInt(1),
1170 };
1171 original.encode(&mut buf);
1172 let frames = frames(buf);
1173 assert_eq!(frames.len(), 1);
1174 match &frames[0] {
1175 Frame::AckFrequency(decoded) => assert_eq!(decoded, &original),
1176 x => panic!("incorrect frame {x:?}"),
1177 }
1178 }
1179
1180 #[test]
1181 fn immediate_ack_coding() {
1182 let mut buf = Vec::new();
1183 FrameType::IMMEDIATE_ACK.encode(&mut buf);
1184 let frames = frames(buf);
1185 assert_eq!(frames.len(), 1);
1186 assert_matches!(&frames[0], Frame::ImmediateAck);
1187 }
1188
1189 #[test]
1190 fn add_address_ipv4_coding() {
1191 let mut buf = Vec::new();
1192 let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
1193 let original = AddAddress {
1194 sequence: VarInt(42),
1195 address: addr,
1196 priority: VarInt(100),
1197 };
1198 original.encode_rfc(&mut buf);
1200 let frames = frames(buf);
1201 assert_eq!(frames.len(), 1);
1202 match &frames[0] {
1203 Frame::AddAddress(decoded) => {
1204 assert_eq!(decoded.sequence, original.sequence);
1205 assert_eq!(decoded.address, original.address);
1206 }
1208 x => panic!("incorrect frame {x:?}"),
1209 }
1210 }
1211
1212 #[test]
1213 fn add_address_ipv6_coding() {
1214 let mut buf = Vec::new();
1215 let addr = SocketAddr::from(([0, 0, 0, 0, 0, 0, 0, 1], 8080));
1216 let original = AddAddress {
1217 sequence: VarInt(123),
1218 address: addr,
1219 priority: VarInt(200),
1220 };
1221 original.encode_rfc(&mut buf);
1223 let frames = frames(buf);
1224 assert_eq!(frames.len(), 1);
1225 match &frames[0] {
1226 Frame::AddAddress(decoded) => {
1227 assert_eq!(decoded.sequence, original.sequence);
1228 assert_eq!(decoded.address, original.address);
1229 }
1231 x => panic!("incorrect frame {x:?}"),
1232 }
1233 }
1234
1235 #[test]
1236 fn punch_me_now_ipv4_coding() {
1237 let mut buf = Vec::new();
1238 let addr = SocketAddr::from(([192, 168, 1, 1], 9000));
1239 let original = PunchMeNow {
1240 round: VarInt(1),
1241 paired_with_sequence_number: VarInt(42),
1242 address: addr,
1243 target_peer_id: None,
1244 };
1245 original.encode_rfc(&mut buf);
1247 let frames = frames(buf);
1248 assert_eq!(frames.len(), 1);
1249 match &frames[0] {
1250 Frame::PunchMeNow(decoded) => {
1251 assert_eq!(decoded.round, original.round);
1252 assert_eq!(
1253 decoded.paired_with_sequence_number,
1254 original.paired_with_sequence_number
1255 );
1256 assert_eq!(decoded.address, original.address);
1257 }
1258 x => panic!("incorrect frame {x:?}"),
1259 }
1260 }
1261
1262 #[test]
1263 fn punch_me_now_ipv6_coding() {
1264 let mut buf = Vec::new();
1265 let addr = SocketAddr::from(([0xfe80, 0, 0, 0, 0, 0, 0, 1], 9000));
1266 let original = PunchMeNow {
1267 round: VarInt(2),
1268 paired_with_sequence_number: VarInt(100),
1269 address: addr,
1270 target_peer_id: None,
1271 };
1272 original.encode_rfc(&mut buf);
1274 let frames = frames(buf);
1275 assert_eq!(frames.len(), 1);
1276 match &frames[0] {
1277 Frame::PunchMeNow(decoded) => {
1278 assert_eq!(decoded.round, original.round);
1279 assert_eq!(
1280 decoded.paired_with_sequence_number,
1281 original.paired_with_sequence_number
1282 );
1283 assert_eq!(decoded.address, original.address);
1284 }
1285 x => panic!("incorrect frame {x:?}"),
1286 }
1287 }
1288
1289 #[test]
1290 fn remove_address_coding() {
1291 let mut buf = Vec::new();
1292 let original = RemoveAddress {
1293 sequence: VarInt(42),
1294 };
1295 original.encode(&mut buf);
1296 let frames = frames(buf);
1297 assert_eq!(frames.len(), 1);
1298 match &frames[0] {
1299 Frame::RemoveAddress(decoded) => {
1300 assert_eq!(decoded.sequence, original.sequence);
1301 }
1302 x => panic!("incorrect frame {x:?}"),
1303 }
1304 }
1305
1306 #[test]
1307 fn nat_traversal_frame_size_bounds() {
1308 let mut buf = Vec::new();
1310
1311 let addr = AddAddress {
1313 sequence: VarInt::MAX,
1314 address: SocketAddr::from(([0xffff; 8], 65535)),
1315 priority: VarInt::MAX,
1316 };
1317 addr.encode(&mut buf);
1318 assert!(buf.len() <= AddAddress::SIZE_BOUND);
1319 buf.clear();
1320
1321 let punch = PunchMeNow {
1323 round: VarInt::MAX,
1324 paired_with_sequence_number: VarInt::MAX,
1325 address: SocketAddr::from(([0xffff; 8], 65535)),
1326 target_peer_id: Some([0xff; 32]),
1327 };
1328 punch.encode(&mut buf);
1329 assert!(buf.len() <= PunchMeNow::SIZE_BOUND);
1330 buf.clear();
1331
1332 let remove = RemoveAddress {
1334 sequence: VarInt::MAX,
1335 };
1336 remove.encode(&mut buf);
1337 assert!(buf.len() <= RemoveAddress::SIZE_BOUND);
1338 }
1339
1340 #[test]
1341 fn punch_me_now_with_target_peer_id() {
1342 let mut buf = Vec::new();
1347 let target_peer_id = [0x42; 32]; let addr = SocketAddr::from(([192, 168, 1, 100], 12345));
1349 let original = PunchMeNow {
1350 round: VarInt(5),
1351 paired_with_sequence_number: VarInt(999),
1352 address: addr,
1353 target_peer_id: Some(target_peer_id),
1354 };
1355 original.encode_rfc(&mut buf);
1357 let frames = frames(buf);
1358 assert_eq!(frames.len(), 1);
1359 match &frames[0] {
1360 Frame::PunchMeNow(decoded) => {
1361 assert_eq!(decoded.round, original.round);
1362 assert_eq!(
1363 decoded.paired_with_sequence_number,
1364 original.paired_with_sequence_number
1365 );
1366 assert_eq!(decoded.address, original.address);
1367 assert_eq!(decoded.target_peer_id, None);
1369 }
1370 x => panic!("incorrect frame {x:?}"),
1371 }
1372 }
1373
1374 #[test]
1375 fn nat_traversal_frame_edge_cases() {
1376 let mut buf = Vec::new();
1378
1379 let min_addr = AddAddress {
1381 sequence: VarInt(0),
1382 address: SocketAddr::from(([0, 0, 0, 0], 0)),
1383 priority: VarInt(0),
1384 };
1385 min_addr.encode_rfc(&mut buf);
1386 let frames1 = frames(buf.clone());
1387 assert_eq!(frames1.len(), 1);
1388 buf.clear();
1389
1390 let min_punch = PunchMeNow {
1392 round: VarInt(0),
1393 paired_with_sequence_number: VarInt(0),
1394 address: SocketAddr::from(([0, 0, 0, 0], 0)),
1395 target_peer_id: None,
1396 };
1397 min_punch.encode_rfc(&mut buf);
1398 let frames2 = frames(buf.clone());
1399 assert_eq!(frames2.len(), 1);
1400 buf.clear();
1401
1402 let min_remove = RemoveAddress {
1404 sequence: VarInt(0),
1405 };
1406 min_remove.encode(&mut buf);
1407 let frames3 = frames(buf);
1408 assert_eq!(frames3.len(), 1);
1409 }
1410
1411 #[test]
1412 fn nat_traversal_frame_boundary_values() {
1413 let mut buf = Vec::new();
1415
1416 let boundary_values = [
1418 VarInt(0),
1419 VarInt(63), VarInt(64), VarInt(16383), VarInt(16384), VarInt(1073741823), VarInt(1073741824), ];
1426
1427 for &sequence in &boundary_values {
1428 for &priority in &boundary_values {
1429 let addr = AddAddress {
1430 sequence,
1431 address: SocketAddr::from(([127, 0, 0, 1], 8080)),
1432 priority,
1433 };
1434 addr.encode_rfc(&mut buf);
1435 let parsed_frames = frames(buf.clone());
1436 assert_eq!(parsed_frames.len(), 1);
1437 match &parsed_frames[0] {
1438 Frame::AddAddress(decoded) => {
1439 assert_eq!(decoded.sequence, sequence);
1440 }
1442 x => panic!("incorrect frame {x:?}"),
1443 }
1444 buf.clear();
1445 }
1446 }
1447 }
1448
1449 #[test]
1450 fn nat_traversal_frame_error_handling() {
1451 let malformed_frames = vec![
1453 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], ];
1469
1470 for malformed in malformed_frames {
1471 let result = Iter::new(Bytes::from(malformed)).unwrap().next();
1472 if let Some(frame_result) = result {
1473 match frame_result {
1476 Ok(_) => {} Err(_) => {} }
1479 }
1480 }
1481 }
1482
1483 #[test]
1484 fn nat_traversal_frame_roundtrip_consistency() {
1485 let add_test_cases = vec![
1489 AddAddress {
1490 sequence: VarInt(42),
1491 address: SocketAddr::from(([127, 0, 0, 1], 8080)),
1492 priority: VarInt(100),
1493 },
1494 AddAddress {
1495 sequence: VarInt(1000),
1496 address: SocketAddr::from(([0, 0, 0, 0, 0, 0, 0, 1], 443)),
1497 priority: VarInt(255),
1498 },
1499 ];
1500
1501 for original_add in add_test_cases {
1502 let mut buf = Vec::new();
1503 original_add.encode_rfc(&mut buf);
1504
1505 let decoded_frames = frames(buf);
1506 assert_eq!(decoded_frames.len(), 1);
1507
1508 match &decoded_frames[0] {
1509 Frame::AddAddress(decoded) => {
1510 assert_eq!(original_add.sequence, decoded.sequence);
1511 assert_eq!(original_add.address, decoded.address);
1512 }
1514 _ => panic!("Expected AddAddress frame"),
1515 }
1516 }
1517
1518 let punch_test_cases = vec![
1520 PunchMeNow {
1521 round: VarInt(1),
1522 paired_with_sequence_number: VarInt(42),
1523 address: SocketAddr::from(([192, 168, 1, 1], 9000)),
1524 target_peer_id: None,
1525 },
1526 PunchMeNow {
1527 round: VarInt(10),
1528 paired_with_sequence_number: VarInt(500),
1529 address: SocketAddr::from(([2001, 0xdb8, 0, 0, 0, 0, 0, 1], 12345)),
1530 target_peer_id: Some([0xaa; 32]),
1531 },
1532 ];
1533
1534 for original_punch in punch_test_cases {
1535 let mut buf = Vec::new();
1536 original_punch.encode_rfc(&mut buf);
1537
1538 let decoded_frames = frames(buf);
1539 assert_eq!(decoded_frames.len(), 1);
1540
1541 match &decoded_frames[0] {
1542 Frame::PunchMeNow(decoded) => {
1543 assert_eq!(original_punch.round, decoded.round);
1544 assert_eq!(
1545 original_punch.paired_with_sequence_number,
1546 decoded.paired_with_sequence_number
1547 );
1548 assert_eq!(original_punch.address, decoded.address);
1549 assert_eq!(decoded.target_peer_id, None);
1551 }
1552 _ => panic!("Expected PunchMeNow frame"),
1553 }
1554 }
1555
1556 let remove_test_cases = vec![
1558 RemoveAddress {
1559 sequence: VarInt(123),
1560 },
1561 RemoveAddress {
1562 sequence: VarInt(0),
1563 },
1564 ];
1565
1566 for original_remove in remove_test_cases {
1567 let mut buf = Vec::new();
1568 original_remove.encode(&mut buf);
1569
1570 let decoded_frames = frames(buf);
1571 assert_eq!(decoded_frames.len(), 1);
1572
1573 match &decoded_frames[0] {
1574 Frame::RemoveAddress(decoded) => {
1575 assert_eq!(original_remove.sequence, decoded.sequence);
1576 }
1577 _ => panic!("Expected RemoveAddress frame"),
1578 }
1579 }
1580 }
1581
1582 #[test]
1583 fn nat_traversal_frame_type_constants() {
1584 assert_eq!(FrameType::ADD_ADDRESS_IPV4.0, 0x3d7e90);
1586 assert_eq!(FrameType::ADD_ADDRESS_IPV6.0, 0x3d7e91);
1587 assert_eq!(FrameType::PUNCH_ME_NOW_IPV4.0, 0x3d7e92);
1588 assert_eq!(FrameType::PUNCH_ME_NOW_IPV6.0, 0x3d7e93);
1589 assert_eq!(FrameType::REMOVE_ADDRESS.0, 0x3d7e94);
1590 }
1591
1592 #[test]
1593 fn observed_address_frame_encoding() {
1594 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
1595
1596 let ipv4_cases = vec![
1598 ObservedAddress {
1599 sequence_number: VarInt::from_u32(1),
1600 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 8080),
1601 },
1602 ObservedAddress {
1603 sequence_number: VarInt::from_u32(2),
1604 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 443),
1605 },
1606 ObservedAddress {
1607 sequence_number: VarInt::from_u32(3),
1608 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 65535),
1609 },
1610 ];
1611
1612 for original in ipv4_cases {
1613 let mut buf = Vec::new();
1614 original.encode(&mut buf);
1615
1616 let decoded_frames = frames(buf);
1617 assert_eq!(decoded_frames.len(), 1);
1618
1619 match &decoded_frames[0] {
1620 Frame::ObservedAddress(decoded) => {
1621 assert_eq!(original.address, decoded.address);
1622 }
1623 _ => panic!("Expected ObservedAddress frame"),
1624 }
1625 }
1626
1627 let ipv6_cases = vec![
1629 ObservedAddress {
1630 sequence_number: VarInt::from_u32(4),
1631 address: SocketAddr::new(
1632 IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)),
1633 8080,
1634 ),
1635 },
1636 ObservedAddress {
1637 sequence_number: VarInt::from_u32(5),
1638 address: SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 443),
1639 },
1640 ObservedAddress {
1641 sequence_number: VarInt::from_u32(6),
1642 address: SocketAddr::new(
1643 IpAddr::V6(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1)),
1644 65535,
1645 ),
1646 },
1647 ];
1648
1649 for original in ipv6_cases {
1650 let mut buf = Vec::new();
1651 original.encode(&mut buf);
1652
1653 let decoded_frames = frames(buf);
1654 assert_eq!(decoded_frames.len(), 1);
1655
1656 match &decoded_frames[0] {
1657 Frame::ObservedAddress(decoded) => {
1658 assert_eq!(original.address, decoded.address);
1659 }
1660 _ => panic!("Expected ObservedAddress frame"),
1661 }
1662 }
1663 }
1664
1665 #[test]
1666 fn observed_address_malformed_frames() {
1667 use crate::coding::BufMutExt;
1668 use bytes::BufMut;
1669
1670 let mut buf = Vec::new();
1672 buf.write(FrameType::OBSERVED_ADDRESS_IPV4);
1674 let result = Iter::new(Bytes::from(buf));
1677 assert!(result.is_ok());
1678 let mut iter = result.unwrap();
1679 let frame_result = iter.next();
1680 assert!(frame_result.is_some());
1681 assert!(frame_result.unwrap().is_err());
1682
1683 let mut buf = Vec::new();
1685 buf.write(FrameType::OBSERVED_ADDRESS_IPV4);
1687 buf.put_u8(4); buf.put_slice(&[192, 168]); let result = Iter::new(Bytes::from(buf));
1691 assert!(result.is_ok());
1692 let mut iter = result.unwrap();
1693 let frame_result = iter.next();
1694 assert!(frame_result.is_some());
1695 assert!(frame_result.unwrap().is_err());
1696
1697 let mut buf = Vec::new();
1699 buf.write(FrameType::OBSERVED_ADDRESS_IPV6);
1701 buf.write_var(1); buf.put_slice(&[0x20, 0x01, 0x0d, 0xb8]); let result = Iter::new(Bytes::from(buf));
1705 assert!(result.is_ok());
1706 let mut iter = result.unwrap();
1707 let frame_result = iter.next();
1708 assert!(frame_result.is_some());
1709 assert!(frame_result.unwrap().is_err());
1710 }
1711
1712 #[test]
1713 fn observed_address_frame_type_constant() {
1714 assert_eq!(FrameType::OBSERVED_ADDRESS_IPV4.0, 0x9f81a6);
1716 assert_eq!(FrameType::OBSERVED_ADDRESS_IPV6.0, 0x9f81a7);
1717 }
1718
1719 #[test]
1720 fn observed_address_frame_serialization_edge_cases() {
1721 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
1722
1723 let frame_port_0 = ObservedAddress {
1725 sequence_number: VarInt::from_u32(100),
1726 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 0),
1727 };
1728 let mut buf = Vec::new();
1729 frame_port_0.encode(&mut buf);
1730 let decoded_frames = frames(buf);
1731 assert_eq!(decoded_frames.len(), 1);
1732 match &decoded_frames[0] {
1733 Frame::ObservedAddress(decoded) => {
1734 assert_eq!(frame_port_0.address, decoded.address);
1735 assert_eq!(decoded.address.port(), 0);
1736 }
1737 _ => panic!("Expected ObservedAddress frame"),
1738 }
1739
1740 let frame_max_port = ObservedAddress {
1742 sequence_number: VarInt::from_u32(101),
1743 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 65535),
1744 };
1745 let mut buf = Vec::new();
1746 frame_max_port.encode(&mut buf);
1747 let decoded_frames = frames(buf);
1748 assert_eq!(decoded_frames.len(), 1);
1749 match &decoded_frames[0] {
1750 Frame::ObservedAddress(decoded) => {
1751 assert_eq!(frame_max_port.address, decoded.address);
1752 assert_eq!(decoded.address.port(), 65535);
1753 }
1754 _ => panic!("Expected ObservedAddress frame"),
1755 }
1756
1757 let unspecified_v4 = ObservedAddress {
1759 sequence_number: VarInt::from_u32(102),
1760 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 8080),
1761 };
1762 let mut buf = Vec::new();
1763 unspecified_v4.encode(&mut buf);
1764 let decoded_frames = frames(buf);
1765 assert_eq!(decoded_frames.len(), 1);
1766 match &decoded_frames[0] {
1767 Frame::ObservedAddress(decoded) => {
1768 assert_eq!(unspecified_v4.address, decoded.address);
1769 assert_eq!(decoded.address.ip(), IpAddr::V4(Ipv4Addr::UNSPECIFIED));
1770 }
1771 _ => panic!("Expected ObservedAddress frame"),
1772 }
1773
1774 let unspecified_v6 = ObservedAddress {
1775 sequence_number: VarInt::from_u32(103),
1776 address: SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 443),
1777 };
1778 let mut buf = Vec::new();
1779 unspecified_v6.encode(&mut buf);
1780 let decoded_frames = frames(buf);
1781 assert_eq!(decoded_frames.len(), 1);
1782 match &decoded_frames[0] {
1783 Frame::ObservedAddress(decoded) => {
1784 assert_eq!(unspecified_v6.address, decoded.address);
1785 assert_eq!(decoded.address.ip(), IpAddr::V6(Ipv6Addr::UNSPECIFIED));
1786 }
1787 _ => panic!("Expected ObservedAddress frame"),
1788 }
1789 }
1790
1791 #[test]
1792 fn observed_address_frame_size_compliance() {
1793 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
1794
1795 let test_addresses = vec![
1797 ObservedAddress {
1798 sequence_number: VarInt::from_u32(1),
1799 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 8080),
1800 },
1801 ObservedAddress {
1802 sequence_number: VarInt::from_u32(2),
1803 address: SocketAddr::new(
1804 IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)),
1805 443,
1806 ),
1807 },
1808 ];
1809
1810 for frame in test_addresses {
1811 let mut buf = Vec::new();
1812 frame.encode(&mut buf);
1813
1814 match frame.address.ip() {
1818 IpAddr::V4(_) => {
1819 assert!(
1820 buf.len() == 11,
1821 "IPv4 frame size {} out of expected range",
1822 buf.len()
1823 );
1824 }
1825 IpAddr::V6(_) => {
1826 assert!(
1827 buf.len() == 23,
1828 "IPv6 frame size {} out of expected range",
1829 buf.len()
1830 );
1831 }
1832 }
1833 }
1834 }
1835
1836 #[test]
1837 fn observed_address_multiple_frames_in_packet() {
1838 use crate::coding::BufMutExt;
1839 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
1840
1841 let observed1 = ObservedAddress {
1843 sequence_number: VarInt::from_u32(10),
1844 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 1234),
1845 };
1846 let observed2 = ObservedAddress {
1847 sequence_number: VarInt::from_u32(11),
1848 address: SocketAddr::new(
1849 IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 2)),
1850 5678,
1851 ),
1852 };
1853
1854 let mut buf = Vec::new();
1855 observed1.encode(&mut buf);
1857 buf.write(FrameType::PING);
1859 observed2.encode(&mut buf);
1861 buf.push(0); let decoded_frames = frames(buf);
1865 assert_eq!(decoded_frames.len(), 4);
1866
1867 match &decoded_frames[0] {
1869 Frame::ObservedAddress(dec) => {
1870 assert_eq!(observed1.address, dec.address);
1871 }
1872 _ => panic!("Expected ObservedAddress at position 0"),
1873 }
1874
1875 match &decoded_frames[1] {
1876 Frame::Ping => {}
1877 _ => panic!("Expected Ping at position 1"),
1878 }
1879
1880 match &decoded_frames[2] {
1881 Frame::ObservedAddress(dec) => {
1882 assert_eq!(observed2.address, dec.address);
1883 }
1884 _ => panic!("Expected ObservedAddress at position 2"),
1885 }
1886
1887 match &decoded_frames[3] {
1888 Frame::Padding => {}
1889 _ => panic!("Expected Padding at position 3"),
1890 }
1891 }
1892
1893 #[test]
1894 fn observed_address_frame_error_recovery() {
1895 use bytes::BufMut;
1896
1897 let mut buf = Vec::new();
1899
1900 buf.put_u8(FrameType::PING.0 as u8);
1902
1903 buf.write(FrameType::OBSERVED_ADDRESS_IPV4);
1906 buf.write_var(1); buf.put_slice(&[192, 168]); buf.put_u8(FrameType::PING.0 as u8);
1911
1912 let result = Iter::new(Bytes::from(buf));
1913 assert!(result.is_ok());
1914 let mut iter = result.unwrap();
1915
1916 let frame1 = iter.next();
1918 assert!(frame1.is_some());
1919 assert!(frame1.unwrap().is_ok());
1920
1921 let frame2 = iter.next();
1923 assert!(frame2.is_some());
1924 assert!(frame2.unwrap().is_err());
1925
1926 let frame3 = iter.next();
1928 assert!(frame3.is_none());
1929 }
1930
1931 #[test]
1932 fn observed_address_frame_varint_encoding() {
1933 use std::net::{IpAddr, Ipv4Addr};
1934
1935 let frame = ObservedAddress {
1937 sequence_number: VarInt::from_u32(1000),
1938 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 80),
1939 };
1940
1941 let mut buf = Vec::new();
1942 frame.encode(&mut buf);
1943
1944 assert_eq!(buf[0], 0x80); assert_eq!(buf[1], 0x9f); assert_eq!(buf[2], 0x81); assert_eq!(buf[3], 0xa6); }
1957
1958 mod comprehensive_tests {
1960 include!("frame/tests.rs");
1961 }
1962
1963 mod sequence_edge_cases {
1965 include!("frame/sequence_edge_case_tests.rs");
1966 }
1967
1968 mod ip_version_tests {
1970 include!("frame/ip_version_encoding_tests.rs");
1971 }
1972
1973 mod observed_address_test {
1975 include!("frame/observed_address_tests.rs");
1976 }
1977
1978 mod observed_address_validation {
1980 include!("frame/observed_address_sequence_validation_tests.rs");
1981 }
1982
1983 mod nat_frame_interop {
1985 use super::*;
1986 use crate::frame::{
1987 nat_compat::*,
1988 rfc_nat_traversal::{RfcAddAddress, RfcPunchMeNow, RfcRemoveAddress},
1989 };
1990
1991 #[test]
1992 fn test_add_address_conversions() {
1993 let old_frame = AddAddress {
1994 sequence: VarInt::from_u32(100),
1995 address: "10.0.0.1:8080".parse().unwrap(),
1996 priority: VarInt::from_u32(65535),
1997 };
1998
1999 let rfc_frame = add_address_to_rfc(&old_frame);
2000 assert_eq!(rfc_frame.sequence_number, old_frame.sequence);
2001 assert_eq!(rfc_frame.address, old_frame.address);
2002
2003 let default_priority = VarInt::from_u32(100000);
2004 let converted_back = rfc_to_add_address(&rfc_frame, default_priority);
2005 assert_eq!(converted_back.sequence, old_frame.sequence);
2006 assert_eq!(converted_back.address, old_frame.address);
2007 assert_eq!(converted_back.priority, default_priority);
2008 }
2009
2010 #[test]
2011 fn test_punch_me_now_conversions() {
2012 let old_frame = PunchMeNow {
2013 round: VarInt::from_u32(5),
2014 paired_with_sequence_number: VarInt::from_u32(100),
2015 address: "192.168.1.1:5000".parse().unwrap(),
2016 target_peer_id: Some([0x42; 32]),
2017 };
2018
2019 let rfc_frame = punch_me_now_to_rfc(&old_frame);
2020 assert_eq!(rfc_frame.round, old_frame.round);
2021 assert_eq!(
2022 rfc_frame.paired_with_sequence_number,
2023 old_frame.paired_with_sequence_number
2024 );
2025 assert_eq!(rfc_frame.address, old_frame.address);
2026
2027 let converted_back = rfc_to_punch_me_now(&rfc_frame);
2028 assert_eq!(converted_back.round, old_frame.round);
2029 assert_eq!(
2030 converted_back.paired_with_sequence_number,
2031 old_frame.paired_with_sequence_number
2032 );
2033 assert_eq!(converted_back.address, old_frame.address);
2034 assert_eq!(converted_back.target_peer_id, None);
2035 }
2036
2037 #[test]
2038 fn test_priority_strategy() {
2039 let strategy = PriorityStrategy {
2040 use_ice_priority: true,
2041 default_priority: VarInt::from_u32(50000),
2042 };
2043
2044 let public_v4: SocketAddr = "8.8.8.8:53".parse().unwrap();
2045 let private_v4: SocketAddr = "192.168.1.1:80".parse().unwrap();
2046 let loopback_v4: SocketAddr = "127.0.0.1:8080".parse().unwrap();
2047
2048 let pub_priority = strategy.calculate_priority(&public_v4);
2049 let priv_priority = strategy.calculate_priority(&private_v4);
2050 let loop_priority = strategy.calculate_priority(&loopback_v4);
2051
2052 assert!(pub_priority.into_inner() > priv_priority.into_inner());
2053 assert!(priv_priority.into_inner() > loop_priority.into_inner());
2054 }
2055
2056 #[test]
2057 fn test_compat_mode_detection() {
2058 assert_eq!(detect_frame_format(0x3d7e90), FrameFormat::Rfc);
2059 assert_eq!(detect_frame_format(0x3d7e91), FrameFormat::Rfc);
2060 assert_eq!(detect_frame_format(0x12345678), FrameFormat::Legacy);
2061 }
2062 }
2063}
2064
2065pub(crate) mod rfc_nat_traversal;
2067
2068pub(crate) mod nat_compat;
2070
2071pub mod nat_traversal_unified;