Skip to main content

ant_quic/
frame.rs

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