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