ant_quic/
frame.rs

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/// A QUIC frame type
23#[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    /// Check if this is a STREAM frame type
36    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    /// Smallest number of bytes this type of frame is guaranteed to fit within.
59    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    // STREAM
124    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
140    ACK_FREQUENCY = 0xaf,
141    IMMEDIATE_ACK = 0x1f,
142    // NAT Traversal Extension - draft-seemann-quic-nat-traversal-02
143    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    // Address Discovery Extension - draft-ietf-quic-address-discovery-00
149    OBSERVED_ADDRESS_IPV4 = 0x9f81a6,
150    OBSERVED_ADDRESS_IPV6 = 0x9f81a7,
151    // DATAGRAM
152}
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/// Reason given by the transport for closing the connection
284#[derive(Debug, Clone, PartialEq, Eq)]
285pub struct ConnectionClose {
286    /// Class of error as encoded in the specification
287    pub error_code: TransportErrorCode,
288    /// Type of frame that caused the close
289    pub frame_type: Option<FrameType>,
290    /// Human-readable reason for the close
291    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); // 1 byte
322        out.write(self.error_code); // <= 8 bytes
323        let ty = self.frame_type.map_or(0, |x| x.0);
324        out.write_var(ty); // <= 8 bytes
325        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); // <= 8 bytes
331        out.put_slice(&self.reason[0..actual_len]); // whatever's left
332    }
333}
334
335/// Reason given by an application for closing the connection
336#[derive(Debug, Clone, PartialEq, Eq)]
337pub struct ApplicationClose {
338    /// Application-specific reason code
339    pub error_code: VarInt,
340    /// Human-readable reason for the close
341    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); // 1 byte
365        out.write(self.error_code); // <= 8 bytes
366        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); // <= 8 bytes
369        out.put_slice(&self.reason[0..actual_len]); // whatever's left
370    }
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/// Metadata from a stream frame
499#[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
506// This manual implementation exists because `Default` is not implemented for `StreamId`
507impl 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); // 1 byte
530        out.write(self.id); // <=8 bytes
531        if self.offsets.start != 0 {
532            out.write_var(self.offsets.start); // <=8 bytes
533        }
534        if length {
535            out.write_var(self.offsets.end - self.offsets.start); // <=8 bytes
536        }
537    }
538}
539
540/// A vector of [`StreamMeta`] with optimization for the single element case
541pub(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            // "An endpoint MUST treat receipt of a packet containing no frames as a
586            // connection error of type PROTOCOL_VIOLATION."
587            // https://www.rfc-editor.org/rfc/rfc9000.html#name-frames-and-frame-types
588            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                // RemoveAddress doesn't have auto decode, uses same format for both
744                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                // Corrupt frame, skip it and everything that follows
794                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
818/// Validate exactly `n` ACK ranges in `buf` and return the number of bytes they cover
819fn 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); // 1 byte
897        out.write(self.id); // <= 8 bytes
898        out.write(self.error_code); // <= 8 bytes
899        out.write(self.final_offset); // <= 8 bytes
900    }
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); // 1 byte
916        out.write(self.id); // <= 8 bytes
917        out.write(self.error_code) // <= 8 bytes
918    }
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
940/// Smallest number of bytes this type of frame is guaranteed to fit within.
941pub(crate) const RETIRE_CONNECTION_ID_SIZE_BOUND: usize = 9;
942
943/// An unreliable datagram
944#[derive(Debug, Clone)]
945pub struct Datagram {
946    /// Payload
947    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))); // 1 byte
957        if length {
958            // Safe to unwrap because we check length sanity before queueing datagrams
959            out.write(VarInt::from_u64_bounded(self.data.len() as u64)); // <= 8 bytes
960        }
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
991// Re-export unified NAT traversal frames
992pub(crate) use nat_traversal_unified::{AddAddress, PunchMeNow, RemoveAddress};
993
994/// Address Discovery frame for informing peers of their observed address
995/// draft-ietf-quic-address-discovery-00
996#[derive(Debug, Clone, PartialEq, Eq)]
997pub(crate) struct ObservedAddress {
998    /// Monotonically increasing sequence number
999    pub(crate) sequence_number: VarInt,
1000    /// The socket address observed by the sender
1001    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        // Write sequence number as varint
1012        buf.write_var(self.sequence_number.0);
1013
1014        // Write address and port directly (no IP version byte needed)
1015        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        // Read sequence number first
1029        let sequence_number = VarInt::from_u64(r.get_var()?).map_err(|_| UnexpectedEnd)?;
1030
1031        // Decode address based on frame type (no IP version byte)
1032        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; // frame type (4) + sequence (8) + IPv6 + port
1059}
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        // Use RFC encoding to match the decoder expectations
1138        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                // Priority is not encoded in RFC format
1146            }
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        // Use RFC encoding to match the decoder expectations
1161        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                // Priority is not encoded in RFC format
1169            }
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        // Use RFC encoding to match the decoder expectations
1185        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        // Use RFC encoding to match the decoder expectations
1212        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        // Test that the SIZE_BOUND constants are correct
1248        let mut buf = Vec::new();
1249
1250        // AddAddress with IPv6 (worst case)
1251        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        // PunchMeNow with IPv6 (worst case)
1261        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        // RemoveAddress
1272        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        // Note: target_peer_id is only supported in legacy format, not RFC format
1282        // This test verifies the legacy format can be encoded, but when decoded
1283        // through the standard frame decoder, target_peer_id won't be preserved
1284        // (as it's not part of the RFC format)
1285        let mut buf = Vec::new();
1286        let target_peer_id = [0x42; 32]; // Test peer ID
1287        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        // Use RFC encoding which doesn't include target_peer_id
1295        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                // RFC format doesn't support target_peer_id
1307                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        // Test minimum values
1316        let mut buf = Vec::new();
1317
1318        // AddAddress with minimum values
1319        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        // PunchMeNow with minimum values
1330        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        // RemoveAddress with minimum values
1342        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        // Test VarInt boundary values
1353        let mut buf = Vec::new();
1354
1355        // Test VarInt boundary values for AddAddress
1356        let boundary_values = [
1357            VarInt(0),
1358            VarInt(63),         // Maximum 1-byte VarInt
1359            VarInt(64),         // Minimum 2-byte VarInt
1360            VarInt(16383),      // Maximum 2-byte VarInt
1361            VarInt(16384),      // Minimum 4-byte VarInt
1362            VarInt(1073741823), // Maximum 4-byte VarInt
1363            VarInt(1073741824), // Minimum 8-byte VarInt
1364        ];
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                        // Priority not encoded in RFC format
1380                    }
1381                    x => panic!("incorrect frame {x:?}"),
1382                }
1383                buf.clear();
1384            }
1385        }
1386    }
1387
1388    #[test]
1389    fn nat_traversal_frame_error_handling() {
1390        // Test malformed frame data
1391        let malformed_frames = vec![
1392            // Too short for any NAT traversal frame (4-byte frame types)
1393            vec![0xc0, 0x90, 0xf9, 0x0f], // Just ADD_ADDRESS_IPV4 frame type, no data
1394            vec![0xc0, 0x92, 0xf9, 0x0f], // Just PUNCH_ME_NOW_IPV4 frame type, no data
1395            vec![0xc0, 0x94, 0xf9, 0x0f], // Just REMOVE_ADDRESS frame type, no data
1396            // Incomplete AddAddress frames
1397            vec![0xc0, 0x90, 0xf9, 0x0f, 0x01], // Frame type + partial sequence
1398            vec![0xc0, 0x90, 0xf9, 0x0f, 0x01, 0x04], // Frame type + sequence + incomplete
1399            // Incomplete PunchMeNow frames
1400            vec![0xc0, 0x92, 0xf9, 0x0f, 0x01], // Frame type + partial round
1401            vec![0xc0, 0x92, 0xf9, 0x0f, 0x01, 0x02], // Frame type + round + partial
1402            // Incomplete RemoveAddress frames
1403            // RemoveAddress is actually hard to make malformed since it only has sequence
1404
1405            // Invalid IP address types
1406            vec![0xc0, 0x90, 0xf9, 0x0f, 0x01, 0x99, 0x01, 0x02, 0x03, 0x04], // Invalid
1407        ];
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                // Should either parse successfully (for valid but incomplete data)
1413                // or return an error (for truly malformed data)
1414                match frame_result {
1415                    Ok(_) => {}  // Valid frame parsed
1416                    Err(_) => {} // Expected error for malformed data
1417                }
1418            }
1419        }
1420    }
1421
1422    #[test]
1423    fn nat_traversal_frame_roundtrip_consistency() {
1424        // Test that encoding and then decoding produces identical frames
1425
1426        // Test AddAddress frames
1427        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                    // Priority not encoded in RFC format
1452                }
1453                _ => panic!("Expected AddAddress frame"),
1454            }
1455        }
1456
1457        // Test PunchMeNow frames
1458        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                    // RFC format doesn't support target_peer_id, so it should always be None
1489                    assert_eq!(decoded.target_peer_id, None);
1490                }
1491                _ => panic!("Expected PunchMeNow frame"),
1492            }
1493        }
1494
1495        // Test RemoveAddress frames
1496        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        // Verify that the frame type constants match the NAT traversal draft specification
1524        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        // Test IPv4 address encoding/decoding
1536        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        // Test IPv6 address encoding/decoding
1567        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        // Test truncated sequence number
1610        let mut buf = Vec::new();
1611        // Use IPv4 variant for test
1612        buf.write(FrameType::OBSERVED_ADDRESS_IPV4);
1613        // No sequence number, just go straight to address - this is invalid
1614
1615        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        // Test truncated IPv4 address
1623        let mut buf = Vec::new();
1624        // Use IPv4 variant for test
1625        buf.write(FrameType::OBSERVED_ADDRESS_IPV4);
1626        buf.put_u8(4); // IPv4
1627        buf.put_slice(&[192, 168]); // Only 2 bytes instead of 4
1628
1629        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        // Test truncated IPv6 address
1637        let mut buf = Vec::new();
1638        // Use IPv6 variant for test
1639        buf.write(FrameType::OBSERVED_ADDRESS_IPV6);
1640        buf.write_var(1); // sequence number
1641        buf.put_slice(&[0x20, 0x01, 0x0d, 0xb8]); // Only 4 bytes instead of 16
1642
1643        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        // Verify that the frame type constant matches the address discovery draft
1654        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        // Test with port 0
1663        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        // Test with maximum port
1680        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        // Test with unspecified addresses
1697        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        // Test that frame sizes are reasonable and within expected bounds
1735        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            // Frame type (4 bytes) + sequence (1 byte for small values) + address + port (2 bytes)
1754            // IPv4: 4 + 1 + 4 + 2 = 11 bytes
1755            // IPv6: 4 + 1 + 16 + 2 = 23 bytes
1756            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        // Test that multiple OBSERVED_ADDRESS frames can be encoded/decoded in a single packet
1781        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        // Encode first ObservedAddress frame
1795        observed1.encode(&mut buf);
1796        // Encode PING frame
1797        buf.write(FrameType::PING);
1798        // Encode second ObservedAddress frame
1799        observed2.encode(&mut buf);
1800        // Padding frame is just zeros, no special encoding needed
1801        buf.push(0); // PADDING frame type
1802
1803        let decoded_frames = frames(buf);
1804        assert_eq!(decoded_frames.len(), 4);
1805
1806        // Verify each frame matches
1807        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        // Test that parser can recover from malformed OBSERVED_ADDRESS frames
1837        let mut buf = Vec::new();
1838
1839        // Valid PING frame
1840        buf.put_u8(FrameType::PING.0 as u8);
1841
1842        // Malformed OBSERVED_ADDRESS frame (truncated)
1843        // Use IPv4 variant for test
1844        buf.write(FrameType::OBSERVED_ADDRESS_IPV4);
1845        buf.write_var(1); // sequence number
1846        buf.put_slice(&[192, 168]); // Only 2 bytes instead of 4 for IPv4
1847
1848        // Another valid PING frame (should not be parsed due to error above)
1849        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        // First frame should parse successfully
1856        let frame1 = iter.next();
1857        assert!(frame1.is_some());
1858        assert!(frame1.unwrap().is_ok());
1859
1860        // Second frame should fail
1861        let frame2 = iter.next();
1862        assert!(frame2.is_some());
1863        assert!(frame2.unwrap().is_err());
1864
1865        // Iterator should stop after error
1866        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        // Ensure frame type is correctly encoded as varint
1875        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        // Frame type 0x9f81a6 (10453414) needs 4-byte varint encoding
1884        // QUIC varint encoding for values >= 2^21 and < 2^30:
1885        // Format: 10xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
1886        // 0x9f81a6 = 10453414
1887        // First byte:  0x80 | ((value >> 24) & 0x3f) = 0x80
1888        // Second byte: (value >> 16) & 0xff = 0x9f
1889        // Third byte:  (value >> 8) & 0xff = 0x81
1890        // Fourth byte: value & 0xff = 0xa6
1891        assert_eq!(buf[0], 0x80); // First byte of 4-byte VarInt
1892        assert_eq!(buf[1], 0x9f); // Second byte
1893        assert_eq!(buf[2], 0x81); // Third byte
1894        assert_eq!(buf[3], 0xa6); // Fourth byte
1895    }
1896
1897    // Include comprehensive tests module
1898    mod comprehensive_tests {
1899        include!("frame/tests.rs");
1900    }
1901
1902    // Include sequence edge case tests
1903    mod sequence_edge_cases {
1904        include!("frame/sequence_edge_case_tests.rs");
1905    }
1906
1907    // Include IP version encoding tests
1908    mod ip_version_tests {
1909        include!("frame/ip_version_encoding_tests.rs");
1910    }
1911
1912    // Include observed address tests
1913    mod observed_address_test {
1914        include!("frame/observed_address_tests.rs");
1915    }
1916
1917    // Include observed address sequence validation tests
1918    mod observed_address_validation {
1919        include!("frame/observed_address_sequence_validation_tests.rs");
1920    }
1921
1922    // NAT frame interoperability tests
1923    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
2004// RFC-compliant NAT traversal frames
2005pub(crate) mod rfc_nat_traversal;
2006
2007// Compatibility layer for NAT traversal frame migration
2008pub(crate) mod nat_compat;
2009
2010// Unified NAT traversal frames with RFC compliance and backward compatibility
2011pub(crate) mod nat_traversal_unified;