⚠️ VeridianOS Kernel Documentation - This is low-level kernel code. All functions are unsafe unless explicitly marked otherwise. no_std

veridian_kernel/net/
quic.rs

1//! QUIC Protocol Implementation (RFC 9000)
2//!
3//! Provides QUIC transport protocol support including:
4//! - Variable-length integer encoding (RFC 9000 Section 16)
5//! - Long and short header packet formats
6//! - Frame encoding/decoding (ACK, STREAM, CRYPTO, etc.)
7//! - Connection management with state machine
8//! - Bidirectional and unidirectional stream multiplexing
9//! - Loss detection and recovery (RFC 9002)
10//!
11//! All arithmetic is integer-only (no floating point) for `no_std`
12//! compatibility.
13
14#![allow(dead_code)]
15
16use alloc::{collections::BTreeMap, vec::Vec};
17
18// ---------------------------------------------------------------------------
19// Constants
20// ---------------------------------------------------------------------------
21
22/// QUIC version 1 (RFC 9000)
23pub const QUIC_V1: u32 = 0x00000001;
24
25/// Maximum connection ID length (bytes)
26const MAX_CID_LEN: usize = 20;
27
28/// Default idle timeout in milliseconds (30 seconds)
29const DEFAULT_IDLE_TIMEOUT_MS: u64 = 30_000;
30
31/// Default initial max data (bytes)
32const DEFAULT_INITIAL_MAX_DATA: u64 = 1_048_576; // 1 MB
33
34/// Default initial max stream data (bytes)
35const DEFAULT_INITIAL_MAX_STREAM_DATA: u64 = 262_144; // 256 KB
36
37/// Packet threshold for loss detection (RFC 9002 Section 6.1.1)
38const PACKET_THRESHOLD: u64 = 3;
39
40/// Time threshold numerator for loss detection (9/8 of RTT)
41const TIME_THRESHOLD_NUM: u64 = 9;
42const TIME_THRESHOLD_DEN: u64 = 8;
43
44/// Minimum PTO in microseconds (1ms)
45const PTO_MIN_US: u64 = 1_000;
46
47/// Initial RTT estimate in microseconds (333ms per RFC 9002)
48const INITIAL_RTT_US: u64 = 333_000;
49
50/// SRTT/RTTVAR fixed-point shift (same as TCP Jacobson)
51const SRTT_SHIFT: u32 = 3;
52const RTTVAR_SHIFT: u32 = 2;
53
54// ---------------------------------------------------------------------------
55// QUIC Error
56// ---------------------------------------------------------------------------
57
58/// QUIC transport error codes (RFC 9000 Section 20)
59#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60#[repr(u64)]
61pub enum QuicError {
62    NoError = 0x00,
63    InternalError = 0x01,
64    ConnectionRefused = 0x02,
65    FlowControlError = 0x03,
66    StreamLimitError = 0x04,
67    StreamStateError = 0x05,
68    FinalSizeError = 0x06,
69    FrameEncodingError = 0x07,
70    TransportParameterError = 0x08,
71    ConnectionIdLimitError = 0x09,
72    ProtocolViolation = 0x0A,
73    InvalidToken = 0x0B,
74    ApplicationError = 0x0C,
75    CryptoBufferExceeded = 0x0D,
76    KeyUpdateError = 0x0E,
77    AeadLimitReached = 0x0F,
78    NoViablePath = 0x10,
79    /// Crypto-related errors 0x0100-0x01FF
80    CryptoError = 0x0100,
81    /// Buffer too small for encoding/decoding
82    BufferTooSmall = 0xFFFF_0001,
83    /// Invalid packet format
84    InvalidPacket = 0xFFFF_0002,
85    /// Invalid frame format
86    InvalidFrame = 0xFFFF_0003,
87    /// Connection not found
88    ConnectionNotFound = 0xFFFF_0004,
89    /// Stream not found
90    StreamNotFound = 0xFFFF_0005,
91}
92
93impl QuicError {
94    pub(crate) fn as_u64(self) -> u64 {
95        self as u64
96    }
97
98    pub(crate) fn from_u64(val: u64) -> Self {
99        match val {
100            0x00 => Self::NoError,
101            0x01 => Self::InternalError,
102            0x02 => Self::ConnectionRefused,
103            0x03 => Self::FlowControlError,
104            0x04 => Self::StreamLimitError,
105            0x05 => Self::StreamStateError,
106            0x06 => Self::FinalSizeError,
107            0x07 => Self::FrameEncodingError,
108            0x08 => Self::TransportParameterError,
109            0x09 => Self::ConnectionIdLimitError,
110            0x0A => Self::ProtocolViolation,
111            0x0B => Self::InvalidToken,
112            0x0C => Self::ApplicationError,
113            0x0D => Self::CryptoBufferExceeded,
114            0x0E => Self::KeyUpdateError,
115            0x0F => Self::AeadLimitReached,
116            0x10 => Self::NoViablePath,
117            0x0100 => Self::CryptoError,
118            _ => Self::InternalError,
119        }
120    }
121}
122
123pub type QuicResult<T> = Result<T, QuicError>;
124
125// ---------------------------------------------------------------------------
126// Variable-Length Integer Encoding (RFC 9000 Section 16)
127// ---------------------------------------------------------------------------
128
129/// Encode a variable-length integer into `buf`, returning bytes written.
130///
131/// Values 0..63 use 1 byte, 64..16383 use 2 bytes,
132/// 16384..1073741823 use 4 bytes, larger use 8 bytes.
133pub(crate) fn encode_varint(value: u64, buf: &mut [u8]) -> QuicResult<usize> {
134    if value <= 63 {
135        if buf.is_empty() {
136            return Err(QuicError::BufferTooSmall);
137        }
138        buf[0] = value as u8;
139        Ok(1)
140    } else if value <= 16383 {
141        if buf.len() < 2 {
142            return Err(QuicError::BufferTooSmall);
143        }
144        let v = (value as u16) | 0x4000;
145        buf[0..2].copy_from_slice(&v.to_be_bytes());
146        Ok(2)
147    } else if value <= 1_073_741_823 {
148        if buf.len() < 4 {
149            return Err(QuicError::BufferTooSmall);
150        }
151        let v = (value as u32) | 0x8000_0000;
152        buf[0..4].copy_from_slice(&v.to_be_bytes());
153        Ok(4)
154    } else if value <= 4_611_686_018_427_387_903 {
155        if buf.len() < 8 {
156            return Err(QuicError::BufferTooSmall);
157        }
158        let v = value | 0xC000_0000_0000_0000;
159        buf[0..8].copy_from_slice(&v.to_be_bytes());
160        Ok(8)
161    } else {
162        Err(QuicError::FrameEncodingError)
163    }
164}
165
166/// Decode a variable-length integer from `buf`, returning (value,
167/// bytes_consumed).
168pub(crate) fn decode_varint(buf: &[u8]) -> QuicResult<(u64, usize)> {
169    if buf.is_empty() {
170        return Err(QuicError::BufferTooSmall);
171    }
172    let prefix = buf[0] >> 6;
173    match prefix {
174        0 => Ok((buf[0] as u64, 1)),
175        1 => {
176            if buf.len() < 2 {
177                return Err(QuicError::BufferTooSmall);
178            }
179            let mut bytes = [0u8; 2];
180            bytes.copy_from_slice(&buf[0..2]);
181            let v = u16::from_be_bytes(bytes) & 0x3FFF;
182            Ok((v as u64, 2))
183        }
184        2 => {
185            if buf.len() < 4 {
186                return Err(QuicError::BufferTooSmall);
187            }
188            let mut bytes = [0u8; 4];
189            bytes.copy_from_slice(&buf[0..4]);
190            let v = u32::from_be_bytes(bytes) & 0x3FFF_FFFF;
191            Ok((v as u64, 4))
192        }
193        3 => {
194            if buf.len() < 8 {
195                return Err(QuicError::BufferTooSmall);
196            }
197            let mut bytes = [0u8; 8];
198            bytes.copy_from_slice(&buf[0..8]);
199            let v = u64::from_be_bytes(bytes) & 0x3FFF_FFFF_FFFF_FFFF;
200            Ok((v, 8))
201        }
202        _ => unreachable!(),
203    }
204}
205
206/// Return the number of bytes needed to encode `value` as a varint.
207pub(crate) fn varint_len(value: u64) -> usize {
208    if value <= 63 {
209        1
210    } else if value <= 16383 {
211        2
212    } else if value <= 1_073_741_823 {
213        4
214    } else {
215        8
216    }
217}
218
219// ---------------------------------------------------------------------------
220// Connection ID
221// ---------------------------------------------------------------------------
222
223/// A QUIC Connection ID (0-20 bytes).
224#[derive(Debug, Clone, PartialEq, Eq)]
225pub struct ConnectionId {
226    pub len: u8,
227    pub bytes: [u8; MAX_CID_LEN],
228}
229
230impl ConnectionId {
231    pub const EMPTY: Self = Self {
232        len: 0,
233        bytes: [0u8; MAX_CID_LEN],
234    };
235
236    pub fn new(data: &[u8]) -> QuicResult<Self> {
237        if data.len() > MAX_CID_LEN {
238            return Err(QuicError::ConnectionIdLimitError);
239        }
240        let mut bytes = [0u8; MAX_CID_LEN];
241        bytes[..data.len()].copy_from_slice(data);
242        Ok(Self {
243            len: data.len() as u8,
244            bytes,
245        })
246    }
247
248    pub(crate) fn as_slice(&self) -> &[u8] {
249        &self.bytes[..self.len as usize]
250    }
251
252    /// Generate a connection ID from a simple seed (deterministic, for
253    /// testing).
254    pub fn generate(seed: u64, length: u8) -> QuicResult<Self> {
255        if length as usize > MAX_CID_LEN {
256            return Err(QuicError::ConnectionIdLimitError);
257        }
258        let mut bytes = [0u8; MAX_CID_LEN];
259        let seed_bytes = seed.to_le_bytes();
260        for i in 0..length as usize {
261            bytes[i] = seed_bytes[i % 8];
262        }
263        Ok(Self { len: length, bytes })
264    }
265}
266
267// ---------------------------------------------------------------------------
268// Packet Number Encoding
269// ---------------------------------------------------------------------------
270
271/// Encode a packet number using the fewest bytes needed to represent the
272/// difference from the largest acknowledged packet number.
273///
274/// Returns (encoded value, byte length 1-4).
275pub(crate) fn encode_packet_number(full_pn: u64, largest_acked: u64) -> (u32, usize) {
276    let num_unacked = if full_pn > largest_acked {
277        full_pn - largest_acked
278    } else {
279        1
280    };
281
282    // Use twice the range as the encoding window
283    let (encoded, len) = if num_unacked < 128 {
284        ((full_pn & 0xFF) as u32, 1)
285    } else if num_unacked < 32768 {
286        ((full_pn & 0xFFFF) as u32, 2)
287    } else if num_unacked < 8_388_608 {
288        ((full_pn & 0xFF_FFFF) as u32, 3)
289    } else {
290        ((full_pn & 0xFFFF_FFFF) as u32, 4)
291    };
292
293    (encoded, len)
294}
295
296/// Decode a truncated packet number back to the full packet number.
297///
298/// Uses the expected packet number (largest received + 1) and the truncated
299/// value to reconstruct the full packet number (RFC 9000 Appendix A).
300pub(crate) fn decode_packet_number(largest_pn: u64, truncated_pn: u32, pn_len: usize) -> u64 {
301    let expected_pn = largest_pn.wrapping_add(1);
302    let pn_nbits = (pn_len * 8) as u64;
303    let pn_win = 1u64 << pn_nbits;
304    let pn_hwin = pn_win / 2;
305    let pn_mask = pn_win - 1;
306
307    // Replace lower bits of expected_pn with truncated value
308    let candidate = (expected_pn & !pn_mask) | (truncated_pn as u64);
309
310    if candidate.wrapping_add(pn_hwin) <= expected_pn
311        && candidate < (1u64 << 62).wrapping_sub(pn_win)
312    {
313        candidate.wrapping_add(pn_win)
314    } else if candidate > expected_pn.wrapping_add(pn_hwin) && candidate >= pn_win {
315        candidate.wrapping_sub(pn_win)
316    } else {
317        candidate
318    }
319}
320
321// ---------------------------------------------------------------------------
322// Packet Types & Headers
323// ---------------------------------------------------------------------------
324
325/// QUIC long header packet types.
326#[derive(Debug, Clone, Copy, PartialEq, Eq)]
327pub enum LongPacketType {
328    Initial = 0x00,
329    ZeroRtt = 0x01,
330    Handshake = 0x02,
331    Retry = 0x03,
332}
333
334impl LongPacketType {
335    pub(crate) fn from_bits(bits: u8) -> QuicResult<Self> {
336        match bits {
337            0x00 => Ok(Self::Initial),
338            0x01 => Ok(Self::ZeroRtt),
339            0x02 => Ok(Self::Handshake),
340            0x03 => Ok(Self::Retry),
341            _ => Err(QuicError::InvalidPacket),
342        }
343    }
344}
345
346/// QUIC packet number space.
347#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
348pub enum PacketNumberSpace {
349    Initial = 0,
350    Handshake = 1,
351    ApplicationData = 2,
352}
353
354/// A parsed QUIC long header.
355#[derive(Debug, Clone, PartialEq, Eq)]
356pub struct LongHeader {
357    /// First byte (form bit, fixed bit, type, reserved, pn_len)
358    pub first_byte: u8,
359    pub version: u32,
360    pub dst_cid: ConnectionId,
361    pub src_cid: ConnectionId,
362    pub packet_type: LongPacketType,
363    /// Token (Initial packets only)
364    pub token: Vec<u8>,
365    /// Packet number (decoded)
366    pub packet_number: u64,
367    /// Payload length (from Length field, includes packet number bytes)
368    pub payload_length: u64,
369}
370
371impl LongHeader {
372    /// Encode a long header into `buf`, returning bytes written.
373    pub(crate) fn encode(&self, buf: &mut [u8]) -> QuicResult<usize> {
374        let mut off = 0;
375
376        // First byte: 1 (form) | 1 (fixed) | type (2 bits) | reserved (2) | pn_len (2)
377        let (_, pn_len) = encode_packet_number(self.packet_number, 0);
378        let first_byte =
379            0xC0 | ((self.packet_type as u8) << 4) | ((pn_len as u8).wrapping_sub(1) & 0x03);
380
381        if buf.len() < 7 {
382            return Err(QuicError::BufferTooSmall);
383        }
384        buf[off] = first_byte;
385        off += 1;
386
387        // Version (4 bytes)
388        buf[off..off + 4].copy_from_slice(&self.version.to_be_bytes());
389        off += 4;
390
391        // DCID length + DCID
392        buf[off] = self.dst_cid.len;
393        off += 1;
394        let dcid_len = self.dst_cid.len as usize;
395        if off + dcid_len > buf.len() {
396            return Err(QuicError::BufferTooSmall);
397        }
398        buf[off..off + dcid_len].copy_from_slice(self.dst_cid.as_slice());
399        off += dcid_len;
400
401        // SCID length + SCID
402        if off >= buf.len() {
403            return Err(QuicError::BufferTooSmall);
404        }
405        buf[off] = self.src_cid.len;
406        off += 1;
407        let scid_len = self.src_cid.len as usize;
408        if off + scid_len > buf.len() {
409            return Err(QuicError::BufferTooSmall);
410        }
411        buf[off..off + scid_len].copy_from_slice(self.src_cid.as_slice());
412        off += scid_len;
413
414        // Token (Initial only)
415        if self.packet_type == LongPacketType::Initial {
416            let tok_len = self.token.len() as u64;
417            let n = encode_varint(tok_len, &mut buf[off..])?;
418            off += n;
419            if off + self.token.len() > buf.len() {
420                return Err(QuicError::BufferTooSmall);
421            }
422            buf[off..off + self.token.len()].copy_from_slice(&self.token);
423            off += self.token.len();
424        }
425
426        // Length (varint): payload_length includes pn_len
427        let total_payload = self.payload_length + pn_len as u64;
428        let n = encode_varint(total_payload, &mut buf[off..])?;
429        off += n;
430
431        // Packet number
432        let (pn_val, _) = encode_packet_number(self.packet_number, 0);
433        if off + pn_len > buf.len() {
434            return Err(QuicError::BufferTooSmall);
435        }
436        match pn_len {
437            1 => buf[off] = pn_val as u8,
438            2 => buf[off..off + 2].copy_from_slice(&(pn_val as u16).to_be_bytes()),
439            3 => {
440                buf[off] = (pn_val >> 16) as u8;
441                buf[off + 1..off + 3].copy_from_slice(&(pn_val as u16).to_be_bytes());
442            }
443            4 => buf[off..off + 4].copy_from_slice(&pn_val.to_be_bytes()),
444            _ => return Err(QuicError::InvalidPacket),
445        }
446        off += pn_len;
447
448        Ok(off)
449    }
450
451    /// Decode a long header from `buf`, returning (header, bytes_consumed).
452    pub(crate) fn decode(buf: &[u8]) -> QuicResult<(Self, usize)> {
453        if buf.len() < 7 {
454            return Err(QuicError::BufferTooSmall);
455        }
456        let mut off = 0;
457
458        let first_byte = buf[off];
459        off += 1;
460
461        // Verify long header form bit
462        if first_byte & 0x80 == 0 {
463            return Err(QuicError::InvalidPacket);
464        }
465
466        let pkt_type_bits = (first_byte >> 4) & 0x03;
467        let packet_type = LongPacketType::from_bits(pkt_type_bits)?;
468        let pn_len = ((first_byte & 0x03) + 1) as usize;
469
470        // Version
471        let mut ver_bytes = [0u8; 4];
472        ver_bytes.copy_from_slice(&buf[off..off + 4]);
473        let version = u32::from_be_bytes(ver_bytes);
474        off += 4;
475
476        // DCID
477        let dcid_len = buf[off] as usize;
478        off += 1;
479        if dcid_len > MAX_CID_LEN || off + dcid_len > buf.len() {
480            return Err(QuicError::InvalidPacket);
481        }
482        let dst_cid = ConnectionId::new(&buf[off..off + dcid_len])?;
483        off += dcid_len;
484
485        // SCID
486        if off >= buf.len() {
487            return Err(QuicError::BufferTooSmall);
488        }
489        let scid_len = buf[off] as usize;
490        off += 1;
491        if scid_len > MAX_CID_LEN || off + scid_len > buf.len() {
492            return Err(QuicError::InvalidPacket);
493        }
494        let src_cid = ConnectionId::new(&buf[off..off + scid_len])?;
495        off += scid_len;
496
497        // Token (Initial only)
498        let mut token = Vec::new();
499        if packet_type == LongPacketType::Initial {
500            let (tok_len, n) = decode_varint(&buf[off..])?;
501            off += n;
502            if off + tok_len as usize > buf.len() {
503                return Err(QuicError::BufferTooSmall);
504            }
505            token = buf[off..off + tok_len as usize].to_vec();
506            off += tok_len as usize;
507        }
508
509        // Length
510        let (payload_length, n) = decode_varint(&buf[off..])?;
511        off += n;
512
513        // Packet number
514        if off + pn_len > buf.len() {
515            return Err(QuicError::BufferTooSmall);
516        }
517        let packet_number = match pn_len {
518            1 => buf[off] as u64,
519            2 => {
520                let mut b = [0u8; 2];
521                b.copy_from_slice(&buf[off..off + 2]);
522                u16::from_be_bytes(b) as u64
523            }
524            3 => ((buf[off] as u64) << 16) | ((buf[off + 1] as u64) << 8) | (buf[off + 2] as u64),
525            4 => {
526                let mut b = [0u8; 4];
527                b.copy_from_slice(&buf[off..off + 4]);
528                u32::from_be_bytes(b) as u64
529            }
530            _ => return Err(QuicError::InvalidPacket),
531        };
532        off += pn_len;
533
534        let hdr = LongHeader {
535            first_byte,
536            version,
537            dst_cid,
538            src_cid,
539            packet_type,
540            token,
541            packet_number,
542            payload_length,
543        };
544        Ok((hdr, off))
545    }
546}
547
548/// A parsed QUIC short header (1-RTT).
549#[derive(Debug, Clone, PartialEq, Eq)]
550pub struct ShortHeader {
551    /// First byte: 0 (form) | 1 (fixed) | spin | reserved (2) | key_phase |
552    /// pn_len (2)
553    pub first_byte: u8,
554    pub dst_cid: ConnectionId,
555    pub packet_number: u64,
556    pub spin_bit: bool,
557    pub key_phase: bool,
558}
559
560impl ShortHeader {
561    /// Create a new short header.
562    pub fn new(
563        dst_cid: ConnectionId,
564        packet_number: u64,
565        spin_bit: bool,
566        key_phase: bool,
567        largest_acked: u64,
568    ) -> Self {
569        let (_, pn_len) = encode_packet_number(packet_number, largest_acked);
570        let mut first_byte = 0x40; // form=0, fixed=1
571        if spin_bit {
572            first_byte |= 0x20;
573        }
574        if key_phase {
575            first_byte |= 0x04;
576        }
577        first_byte |= (pn_len as u8).wrapping_sub(1) & 0x03;
578
579        Self {
580            first_byte,
581            dst_cid,
582            packet_number,
583            spin_bit,
584            key_phase,
585        }
586    }
587
588    /// Encode a short header into `buf`, returning bytes written.
589    pub(crate) fn encode(&self, buf: &mut [u8], largest_acked: u64) -> QuicResult<usize> {
590        let mut off = 0;
591        let (pn_val, pn_len) = encode_packet_number(self.packet_number, largest_acked);
592
593        let needed = 1 + self.dst_cid.len as usize + pn_len;
594        if buf.len() < needed {
595            return Err(QuicError::BufferTooSmall);
596        }
597
598        buf[off] = self.first_byte;
599        off += 1;
600
601        // DCID (length is known from connection context, not encoded)
602        let dcid_len = self.dst_cid.len as usize;
603        buf[off..off + dcid_len].copy_from_slice(self.dst_cid.as_slice());
604        off += dcid_len;
605
606        // Packet number
607        match pn_len {
608            1 => buf[off] = pn_val as u8,
609            2 => buf[off..off + 2].copy_from_slice(&(pn_val as u16).to_be_bytes()),
610            3 => {
611                buf[off] = (pn_val >> 16) as u8;
612                buf[off + 1..off + 3].copy_from_slice(&(pn_val as u16).to_be_bytes());
613            }
614            4 => buf[off..off + 4].copy_from_slice(&pn_val.to_be_bytes()),
615            _ => return Err(QuicError::InvalidPacket),
616        }
617        off += pn_len;
618
619        Ok(off)
620    }
621}
622
623/// Apply header protection XOR mask to the first byte and packet number bytes.
624///
625/// `mask` is a 5-byte sample derived from the Header Protection (HP) key.
626/// Byte 0 masks the first byte; bytes 1-4 mask packet number bytes.
627pub(crate) fn apply_header_protection(buf: &mut [u8], pn_offset: usize, mask: &[u8; 5]) {
628    if buf.is_empty() {
629        return;
630    }
631    // Determine if long or short header
632    if buf[0] & 0x80 != 0 {
633        // Long header: mask lower 4 bits of first byte
634        buf[0] ^= mask[0] & 0x0F;
635    } else {
636        // Short header: mask lower 5 bits of first byte
637        buf[0] ^= mask[0] & 0x1F;
638    }
639    let pn_len = ((buf[0] & 0x03) + 1) as usize;
640    for i in 0..pn_len {
641        if pn_offset + i < buf.len() {
642            buf[pn_offset + i] ^= mask[1 + i];
643        }
644    }
645}
646
647// ---------------------------------------------------------------------------
648// QUIC Frames
649// ---------------------------------------------------------------------------
650
651/// QUIC frame types.
652#[derive(Debug, Clone, PartialEq, Eq)]
653pub enum QuicFrame {
654    /// PADDING frame (0x00)
655    Padding,
656
657    /// PING frame (0x01)
658    Ping,
659
660    /// ACK frame (0x02 or 0x03)
661    Ack {
662        largest_acked: u64,
663        ack_delay: u64,
664        first_ack_range: u64,
665        ack_ranges: Vec<AckRange>,
666        /// ECN counts present if frame type is 0x03
667        ecn_counts: Option<EcnCounts>,
668    },
669
670    /// CRYPTO frame (0x06)
671    Crypto { offset: u64, data: Vec<u8> },
672
673    /// NEW_CONNECTION_ID frame (0x18)
674    NewConnectionId {
675        sequence: u64,
676        retire_prior_to: u64,
677        connection_id: ConnectionId,
678        stateless_reset_token: [u8; 16],
679    },
680
681    /// STREAM frame (0x08-0x0F)
682    Stream {
683        stream_id: u64,
684        offset: u64,
685        data: Vec<u8>,
686        fin: bool,
687    },
688
689    /// MAX_DATA frame (0x10)
690    MaxData { maximum_data: u64 },
691
692    /// MAX_STREAM_DATA frame (0x11)
693    MaxStreamData {
694        stream_id: u64,
695        maximum_stream_data: u64,
696    },
697
698    /// DATA_BLOCKED frame (0x14)
699    DataBlocked { maximum_data: u64 },
700
701    /// STREAM_DATA_BLOCKED frame (0x15)
702    StreamDataBlocked {
703        stream_id: u64,
704        maximum_stream_data: u64,
705    },
706
707    /// CONNECTION_CLOSE frame (0x1C or 0x1D)
708    ConnectionClose {
709        error_code: u64,
710        frame_type: Option<u64>,
711        reason: Vec<u8>,
712        is_application: bool,
713    },
714
715    /// PATH_CHALLENGE frame (0x1A)
716    PathChallenge { data: [u8; 8] },
717
718    /// PATH_RESPONSE frame (0x1B)
719    PathResponse { data: [u8; 8] },
720}
721
722/// An ACK range (gap + ack_range_length).
723#[derive(Debug, Clone, Copy, PartialEq, Eq)]
724pub struct AckRange {
725    pub gap: u64,
726    pub ack_range_length: u64,
727}
728
729/// ECN counts for ACK frames.
730#[derive(Debug, Clone, Copy, PartialEq, Eq)]
731pub struct EcnCounts {
732    pub ect0: u64,
733    pub ect1: u64,
734    pub ecn_ce: u64,
735}
736
737impl QuicFrame {
738    /// Encode frame into `buf`, returning bytes written.
739    pub(crate) fn encode(&self, buf: &mut [u8]) -> QuicResult<usize> {
740        match self {
741            Self::Padding => {
742                if buf.is_empty() {
743                    return Err(QuicError::BufferTooSmall);
744                }
745                buf[0] = 0x00;
746                Ok(1)
747            }
748
749            Self::Ping => {
750                if buf.is_empty() {
751                    return Err(QuicError::BufferTooSmall);
752                }
753                buf[0] = 0x01;
754                Ok(1)
755            }
756
757            Self::Ack {
758                largest_acked,
759                ack_delay,
760                first_ack_range,
761                ack_ranges,
762                ecn_counts,
763            } => {
764                let mut off = 0;
765                // Frame type
766                let ft = if ecn_counts.is_some() { 0x03u8 } else { 0x02u8 };
767                off += encode_varint(ft as u64, &mut buf[off..])?;
768                off += encode_varint(*largest_acked, &mut buf[off..])?;
769                off += encode_varint(*ack_delay, &mut buf[off..])?;
770                off += encode_varint(ack_ranges.len() as u64, &mut buf[off..])?;
771                off += encode_varint(*first_ack_range, &mut buf[off..])?;
772                for range in ack_ranges {
773                    off += encode_varint(range.gap, &mut buf[off..])?;
774                    off += encode_varint(range.ack_range_length, &mut buf[off..])?;
775                }
776                if let Some(ecn) = ecn_counts {
777                    off += encode_varint(ecn.ect0, &mut buf[off..])?;
778                    off += encode_varint(ecn.ect1, &mut buf[off..])?;
779                    off += encode_varint(ecn.ecn_ce, &mut buf[off..])?;
780                }
781                Ok(off)
782            }
783
784            Self::Crypto { offset, data } => {
785                let mut off = 0;
786                off += encode_varint(0x06, &mut buf[off..])?;
787                off += encode_varint(*offset, &mut buf[off..])?;
788                off += encode_varint(data.len() as u64, &mut buf[off..])?;
789                if off + data.len() > buf.len() {
790                    return Err(QuicError::BufferTooSmall);
791                }
792                buf[off..off + data.len()].copy_from_slice(data);
793                off += data.len();
794                Ok(off)
795            }
796
797            Self::NewConnectionId {
798                sequence,
799                retire_prior_to,
800                connection_id,
801                stateless_reset_token,
802            } => {
803                let mut off = 0;
804                off += encode_varint(0x18, &mut buf[off..])?;
805                off += encode_varint(*sequence, &mut buf[off..])?;
806                off += encode_varint(*retire_prior_to, &mut buf[off..])?;
807                if off >= buf.len() {
808                    return Err(QuicError::BufferTooSmall);
809                }
810                buf[off] = connection_id.len;
811                off += 1;
812                let cid_len = connection_id.len as usize;
813                if off + cid_len + 16 > buf.len() {
814                    return Err(QuicError::BufferTooSmall);
815                }
816                buf[off..off + cid_len].copy_from_slice(connection_id.as_slice());
817                off += cid_len;
818                buf[off..off + 16].copy_from_slice(stateless_reset_token);
819                off += 16;
820                Ok(off)
821            }
822
823            Self::Stream {
824                stream_id,
825                offset,
826                data,
827                fin,
828            } => {
829                let mut off = 0;
830                // Frame type: 0x08 | OFF(0x04) | LEN(0x02) | FIN(0x01)
831                let mut ft: u8 = 0x08;
832                if *offset > 0 {
833                    ft |= 0x04; // OFF bit
834                }
835                ft |= 0x02; // LEN bit (always include length)
836                if *fin {
837                    ft |= 0x01;
838                }
839                off += encode_varint(ft as u64, &mut buf[off..])?;
840                off += encode_varint(*stream_id, &mut buf[off..])?;
841                if *offset > 0 {
842                    off += encode_varint(*offset, &mut buf[off..])?;
843                }
844                off += encode_varint(data.len() as u64, &mut buf[off..])?;
845                if off + data.len() > buf.len() {
846                    return Err(QuicError::BufferTooSmall);
847                }
848                buf[off..off + data.len()].copy_from_slice(data);
849                off += data.len();
850                Ok(off)
851            }
852
853            Self::MaxData { maximum_data } => {
854                let mut off = 0;
855                off += encode_varint(0x10, &mut buf[off..])?;
856                off += encode_varint(*maximum_data, &mut buf[off..])?;
857                Ok(off)
858            }
859
860            Self::MaxStreamData {
861                stream_id,
862                maximum_stream_data,
863            } => {
864                let mut off = 0;
865                off += encode_varint(0x11, &mut buf[off..])?;
866                off += encode_varint(*stream_id, &mut buf[off..])?;
867                off += encode_varint(*maximum_stream_data, &mut buf[off..])?;
868                Ok(off)
869            }
870
871            Self::DataBlocked { maximum_data } => {
872                let mut off = 0;
873                off += encode_varint(0x14, &mut buf[off..])?;
874                off += encode_varint(*maximum_data, &mut buf[off..])?;
875                Ok(off)
876            }
877
878            Self::StreamDataBlocked {
879                stream_id,
880                maximum_stream_data,
881            } => {
882                let mut off = 0;
883                off += encode_varint(0x15, &mut buf[off..])?;
884                off += encode_varint(*stream_id, &mut buf[off..])?;
885                off += encode_varint(*maximum_stream_data, &mut buf[off..])?;
886                Ok(off)
887            }
888
889            Self::ConnectionClose {
890                error_code,
891                frame_type,
892                reason,
893                is_application,
894            } => {
895                let mut off = 0;
896                let ft = if *is_application { 0x1Du64 } else { 0x1Cu64 };
897                off += encode_varint(ft, &mut buf[off..])?;
898                off += encode_varint(*error_code, &mut buf[off..])?;
899                if !is_application {
900                    off += encode_varint(frame_type.unwrap_or(0), &mut buf[off..])?;
901                }
902                off += encode_varint(reason.len() as u64, &mut buf[off..])?;
903                if off + reason.len() > buf.len() {
904                    return Err(QuicError::BufferTooSmall);
905                }
906                buf[off..off + reason.len()].copy_from_slice(reason);
907                off += reason.len();
908                Ok(off)
909            }
910
911            Self::PathChallenge { data } => {
912                let mut off = 0;
913                off += encode_varint(0x1A, &mut buf[off..])?;
914                if off + 8 > buf.len() {
915                    return Err(QuicError::BufferTooSmall);
916                }
917                buf[off..off + 8].copy_from_slice(data);
918                off += 8;
919                Ok(off)
920            }
921
922            Self::PathResponse { data } => {
923                let mut off = 0;
924                off += encode_varint(0x1B, &mut buf[off..])?;
925                if off + 8 > buf.len() {
926                    return Err(QuicError::BufferTooSmall);
927                }
928                buf[off..off + 8].copy_from_slice(data);
929                off += 8;
930                Ok(off)
931            }
932        }
933    }
934
935    /// Decode a single frame from `buf`, returning (frame, bytes_consumed).
936    pub(crate) fn decode(buf: &[u8]) -> QuicResult<(Self, usize)> {
937        if buf.is_empty() {
938            return Err(QuicError::BufferTooSmall);
939        }
940
941        let (frame_type, mut off) = decode_varint(buf)?;
942
943        match frame_type {
944            0x00 => Ok((Self::Padding, off)),
945
946            0x01 => Ok((Self::Ping, off)),
947
948            0x02 | 0x03 => {
949                let has_ecn = frame_type == 0x03;
950                let (largest_acked, n) = decode_varint(&buf[off..])?;
951                off += n;
952                let (ack_delay, n) = decode_varint(&buf[off..])?;
953                off += n;
954                let (ack_range_count, n) = decode_varint(&buf[off..])?;
955                off += n;
956                let (first_ack_range, n) = decode_varint(&buf[off..])?;
957                off += n;
958
959                let mut ack_ranges = Vec::new();
960                for _ in 0..ack_range_count {
961                    let (gap, n) = decode_varint(&buf[off..])?;
962                    off += n;
963                    let (ack_range_length, n) = decode_varint(&buf[off..])?;
964                    off += n;
965                    ack_ranges.push(AckRange {
966                        gap,
967                        ack_range_length,
968                    });
969                }
970
971                let ecn_counts = if has_ecn {
972                    let (ect0, n) = decode_varint(&buf[off..])?;
973                    off += n;
974                    let (ect1, n) = decode_varint(&buf[off..])?;
975                    off += n;
976                    let (ecn_ce, n) = decode_varint(&buf[off..])?;
977                    off += n;
978                    Some(EcnCounts { ect0, ect1, ecn_ce })
979                } else {
980                    None
981                };
982
983                Ok((
984                    Self::Ack {
985                        largest_acked,
986                        ack_delay,
987                        first_ack_range,
988                        ack_ranges,
989                        ecn_counts,
990                    },
991                    off,
992                ))
993            }
994
995            0x06 => {
996                let (offset, n) = decode_varint(&buf[off..])?;
997                off += n;
998                let (length, n) = decode_varint(&buf[off..])?;
999                off += n;
1000                let length = length as usize;
1001                if off + length > buf.len() {
1002                    return Err(QuicError::BufferTooSmall);
1003                }
1004                let data = buf[off..off + length].to_vec();
1005                off += length;
1006                Ok((Self::Crypto { offset, data }, off))
1007            }
1008
1009            // STREAM frames: 0x08..=0x0F
1010            ft @ 0x08..=0x0F => {
1011                let has_offset = ft & 0x04 != 0;
1012                let has_length = ft & 0x02 != 0;
1013                let fin = ft & 0x01 != 0;
1014
1015                let (stream_id, n) = decode_varint(&buf[off..])?;
1016                off += n;
1017
1018                let offset = if has_offset {
1019                    let (o, n) = decode_varint(&buf[off..])?;
1020                    off += n;
1021                    o
1022                } else {
1023                    0
1024                };
1025
1026                let data = if has_length {
1027                    let (length, n) = decode_varint(&buf[off..])?;
1028                    off += n;
1029                    let length = length as usize;
1030                    if off + length > buf.len() {
1031                        return Err(QuicError::BufferTooSmall);
1032                    }
1033                    let d = buf[off..off + length].to_vec();
1034                    off += length;
1035                    d
1036                } else {
1037                    // Remaining bytes in the packet
1038                    let d = buf[off..].to_vec();
1039                    off = buf.len();
1040                    d
1041                };
1042
1043                Ok((
1044                    Self::Stream {
1045                        stream_id,
1046                        offset,
1047                        data,
1048                        fin,
1049                    },
1050                    off,
1051                ))
1052            }
1053
1054            0x10 => {
1055                let (maximum_data, n) = decode_varint(&buf[off..])?;
1056                off += n;
1057                Ok((Self::MaxData { maximum_data }, off))
1058            }
1059
1060            0x11 => {
1061                let (stream_id, n) = decode_varint(&buf[off..])?;
1062                off += n;
1063                let (maximum_stream_data, n) = decode_varint(&buf[off..])?;
1064                off += n;
1065                Ok((
1066                    Self::MaxStreamData {
1067                        stream_id,
1068                        maximum_stream_data,
1069                    },
1070                    off,
1071                ))
1072            }
1073
1074            0x14 => {
1075                let (maximum_data, n) = decode_varint(&buf[off..])?;
1076                off += n;
1077                Ok((Self::DataBlocked { maximum_data }, off))
1078            }
1079
1080            0x15 => {
1081                let (stream_id, n) = decode_varint(&buf[off..])?;
1082                off += n;
1083                let (maximum_stream_data, n) = decode_varint(&buf[off..])?;
1084                off += n;
1085                Ok((
1086                    Self::StreamDataBlocked {
1087                        stream_id,
1088                        maximum_stream_data,
1089                    },
1090                    off,
1091                ))
1092            }
1093
1094            0x18 => {
1095                let (sequence, n) = decode_varint(&buf[off..])?;
1096                off += n;
1097                let (retire_prior_to, n) = decode_varint(&buf[off..])?;
1098                off += n;
1099                if off >= buf.len() {
1100                    return Err(QuicError::BufferTooSmall);
1101                }
1102                let cid_len = buf[off] as usize;
1103                off += 1;
1104                if cid_len > MAX_CID_LEN || off + cid_len + 16 > buf.len() {
1105                    return Err(QuicError::InvalidFrame);
1106                }
1107                let connection_id = ConnectionId::new(&buf[off..off + cid_len])?;
1108                off += cid_len;
1109                let mut stateless_reset_token = [0u8; 16];
1110                stateless_reset_token.copy_from_slice(&buf[off..off + 16]);
1111                off += 16;
1112                Ok((
1113                    Self::NewConnectionId {
1114                        sequence,
1115                        retire_prior_to,
1116                        connection_id,
1117                        stateless_reset_token,
1118                    },
1119                    off,
1120                ))
1121            }
1122
1123            0x1A => {
1124                if off + 8 > buf.len() {
1125                    return Err(QuicError::BufferTooSmall);
1126                }
1127                let mut data = [0u8; 8];
1128                data.copy_from_slice(&buf[off..off + 8]);
1129                off += 8;
1130                Ok((Self::PathChallenge { data }, off))
1131            }
1132
1133            0x1B => {
1134                if off + 8 > buf.len() {
1135                    return Err(QuicError::BufferTooSmall);
1136                }
1137                let mut data = [0u8; 8];
1138                data.copy_from_slice(&buf[off..off + 8]);
1139                off += 8;
1140                Ok((Self::PathResponse { data }, off))
1141            }
1142
1143            0x1C | 0x1D => {
1144                let is_application = frame_type == 0x1D;
1145                let (error_code, n) = decode_varint(&buf[off..])?;
1146                off += n;
1147                let frame_type_val = if !is_application {
1148                    let (ft, n) = decode_varint(&buf[off..])?;
1149                    off += n;
1150                    Some(ft)
1151                } else {
1152                    None
1153                };
1154                let (reason_len, n) = decode_varint(&buf[off..])?;
1155                off += n;
1156                let reason_len = reason_len as usize;
1157                if off + reason_len > buf.len() {
1158                    return Err(QuicError::BufferTooSmall);
1159                }
1160                let reason = buf[off..off + reason_len].to_vec();
1161                off += reason_len;
1162                Ok((
1163                    Self::ConnectionClose {
1164                        error_code,
1165                        frame_type: frame_type_val,
1166                        reason,
1167                        is_application,
1168                    },
1169                    off,
1170                ))
1171            }
1172
1173            _ => Err(QuicError::InvalidFrame),
1174        }
1175    }
1176
1177    /// Returns true if this frame is ack-eliciting.
1178    pub(crate) fn is_ack_eliciting(&self) -> bool {
1179        !matches!(self, Self::Ack { .. } | Self::Padding)
1180    }
1181}
1182
1183// ---------------------------------------------------------------------------
1184// Connection Management
1185// ---------------------------------------------------------------------------
1186
1187/// QUIC connection state machine.
1188#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1189pub enum ConnectionState {
1190    Idle,
1191    Handshake,
1192    Connected,
1193    Closing,
1194    Draining,
1195    Closed,
1196}
1197
1198/// Packet number space state.
1199#[derive(Debug, Clone)]
1200pub struct PnSpace {
1201    /// Next packet number to send
1202    pub next_pn: u64,
1203    /// Largest acknowledged packet number
1204    pub largest_acked: u64,
1205    /// Largest packet number received from peer
1206    pub largest_received: u64,
1207    /// Sent packets awaiting acknowledgement: pn -> (sent_time_us,
1208    /// ack_eliciting, size)
1209    pub sent_packets: BTreeMap<u64, SentPacketInfo>,
1210    /// Whether we owe the peer an ACK
1211    pub ack_pending: bool,
1212}
1213
1214/// Metadata about a sent packet.
1215#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1216pub struct SentPacketInfo {
1217    pub sent_time_us: u64,
1218    pub ack_eliciting: bool,
1219    pub size: usize,
1220}
1221
1222impl Default for PnSpace {
1223    fn default() -> Self {
1224        Self::new()
1225    }
1226}
1227
1228impl PnSpace {
1229    pub fn new() -> Self {
1230        Self {
1231            next_pn: 0,
1232            largest_acked: 0,
1233            largest_received: 0,
1234            sent_packets: BTreeMap::new(),
1235            ack_pending: false,
1236        }
1237    }
1238
1239    /// Allocate the next packet number.
1240    pub(crate) fn alloc_pn(&mut self) -> u64 {
1241        let pn = self.next_pn;
1242        self.next_pn += 1;
1243        pn
1244    }
1245
1246    /// Record a sent packet.
1247    pub(crate) fn on_packet_sent(
1248        &mut self,
1249        pn: u64,
1250        sent_time_us: u64,
1251        ack_eliciting: bool,
1252        size: usize,
1253    ) {
1254        self.sent_packets.insert(
1255            pn,
1256            SentPacketInfo {
1257                sent_time_us,
1258                ack_eliciting,
1259                size,
1260            },
1261        );
1262    }
1263
1264    /// Record a received packet number from peer.
1265    pub(crate) fn on_packet_received(&mut self, pn: u64, ack_eliciting: bool) {
1266        if pn > self.largest_received {
1267            self.largest_received = pn;
1268        }
1269        if ack_eliciting {
1270            self.ack_pending = true;
1271        }
1272    }
1273}
1274
1275/// QUIC connection.
1276#[derive(Debug)]
1277pub struct QuicConnection {
1278    pub state: ConnectionState,
1279    pub src_cid: ConnectionId,
1280    pub dst_cid: ConnectionId,
1281    /// Active connection IDs (for rotation)
1282    pub active_cids: Vec<ConnectionId>,
1283    /// Packet number spaces
1284    pub pn_spaces: [PnSpace; 3],
1285    /// Idle timeout in milliseconds
1286    pub idle_timeout_ms: u64,
1287    /// Last activity timestamp in microseconds
1288    pub last_activity_us: u64,
1289    /// RTT estimation
1290    pub rtt: RttEstimator,
1291    /// Connection-level flow control: maximum data we can send
1292    pub max_data_send: u64,
1293    /// Connection-level flow control: maximum data peer can send
1294    pub max_data_recv: u64,
1295    /// Total data sent
1296    pub data_sent: u64,
1297    /// Total data received
1298    pub data_received: u64,
1299    /// Stream manager
1300    pub streams: StreamManager,
1301    /// Path validation state
1302    pub path_challenge_data: Option<[u8; 8]>,
1303}
1304
1305impl QuicConnection {
1306    /// Create a new QUIC connection (client side).
1307    pub fn new_client(src_cid: ConnectionId, dst_cid: ConnectionId) -> Self {
1308        Self {
1309            state: ConnectionState::Idle,
1310            src_cid: src_cid.clone(),
1311            dst_cid,
1312            active_cids: alloc::vec![src_cid],
1313            pn_spaces: [PnSpace::new(), PnSpace::new(), PnSpace::new()],
1314            idle_timeout_ms: DEFAULT_IDLE_TIMEOUT_MS,
1315            last_activity_us: 0,
1316            rtt: RttEstimator::new(),
1317            max_data_send: DEFAULT_INITIAL_MAX_DATA,
1318            max_data_recv: DEFAULT_INITIAL_MAX_DATA,
1319            data_sent: 0,
1320            data_received: 0,
1321            streams: StreamManager::new(true),
1322            path_challenge_data: None,
1323        }
1324    }
1325
1326    /// Create a new QUIC connection (server side).
1327    pub fn new_server(src_cid: ConnectionId, dst_cid: ConnectionId) -> Self {
1328        Self {
1329            state: ConnectionState::Idle,
1330            src_cid: src_cid.clone(),
1331            dst_cid,
1332            active_cids: alloc::vec![src_cid],
1333            pn_spaces: [PnSpace::new(), PnSpace::new(), PnSpace::new()],
1334            idle_timeout_ms: DEFAULT_IDLE_TIMEOUT_MS,
1335            last_activity_us: 0,
1336            rtt: RttEstimator::new(),
1337            max_data_send: DEFAULT_INITIAL_MAX_DATA,
1338            max_data_recv: DEFAULT_INITIAL_MAX_DATA,
1339            data_sent: 0,
1340            data_received: 0,
1341            streams: StreamManager::new(false),
1342            path_challenge_data: None,
1343        }
1344    }
1345
1346    /// Transition to a new connection state.
1347    pub(crate) fn transition(&mut self, new_state: ConnectionState) -> QuicResult<()> {
1348        let valid = matches!(
1349            (self.state, new_state),
1350            (ConnectionState::Idle, ConnectionState::Handshake)
1351                | (ConnectionState::Handshake, ConnectionState::Connected)
1352                | (ConnectionState::Handshake, ConnectionState::Closing)
1353                | (ConnectionState::Connected, ConnectionState::Closing)
1354                | (ConnectionState::Connected, ConnectionState::Draining)
1355                | (ConnectionState::Closing, ConnectionState::Draining)
1356                | (ConnectionState::Closing, ConnectionState::Closed)
1357                | (ConnectionState::Draining, ConnectionState::Closed)
1358        );
1359        if !valid {
1360            return Err(QuicError::ProtocolViolation);
1361        }
1362        self.state = new_state;
1363        Ok(())
1364    }
1365
1366    /// Get the packet number space for a given space index.
1367    pub(crate) fn pn_space(&self, space: PacketNumberSpace) -> &PnSpace {
1368        &self.pn_spaces[space as usize]
1369    }
1370
1371    /// Get the packet number space mutably.
1372    pub(crate) fn pn_space_mut(&mut self, space: PacketNumberSpace) -> &mut PnSpace {
1373        &mut self.pn_spaces[space as usize]
1374    }
1375
1376    /// Check if the connection has timed out.
1377    pub(crate) fn is_idle_timeout(&self, now_us: u64) -> bool {
1378        if self.last_activity_us == 0 {
1379            return false;
1380        }
1381        let elapsed_ms = (now_us.saturating_sub(self.last_activity_us)) / 1000;
1382        elapsed_ms >= self.idle_timeout_ms
1383    }
1384
1385    /// Update last activity timestamp.
1386    pub(crate) fn touch(&mut self, now_us: u64) {
1387        self.last_activity_us = now_us;
1388    }
1389
1390    /// Rotate connection ID: add a new CID and optionally retire old ones.
1391    pub(crate) fn add_connection_id(&mut self, cid: ConnectionId) {
1392        self.active_cids.push(cid);
1393    }
1394
1395    /// Retire connection IDs with sequence numbers below `retire_prior_to`.
1396    pub(crate) fn retire_connection_ids(&mut self, retire_prior_to: usize) {
1397        if retire_prior_to < self.active_cids.len() {
1398            self.active_cids.drain(0..retire_prior_to);
1399        }
1400    }
1401
1402    /// Initiate path validation by sending PATH_CHALLENGE.
1403    pub(crate) fn initiate_path_challenge(&mut self, challenge_data: [u8; 8]) -> QuicFrame {
1404        self.path_challenge_data = Some(challenge_data);
1405        QuicFrame::PathChallenge {
1406            data: challenge_data,
1407        }
1408    }
1409
1410    /// Validate path response.
1411    pub(crate) fn validate_path_response(&mut self, response_data: &[u8; 8]) -> bool {
1412        if let Some(expected) = self.path_challenge_data {
1413            if *response_data == expected {
1414                self.path_challenge_data = None;
1415                return true;
1416            }
1417        }
1418        false
1419    }
1420
1421    /// Check connection-level send flow control.
1422    pub(crate) fn can_send(&self, bytes: u64) -> bool {
1423        self.data_sent + bytes <= self.max_data_send
1424    }
1425
1426    /// Update connection-level max data (received MAX_DATA from peer).
1427    pub(crate) fn update_max_data_send(&mut self, max_data: u64) {
1428        if max_data > self.max_data_send {
1429            self.max_data_send = max_data;
1430        }
1431    }
1432}
1433
1434// ---------------------------------------------------------------------------
1435// RTT Estimation
1436// ---------------------------------------------------------------------------
1437
1438/// RTT estimator using Jacobson's algorithm (RFC 6298), integer-only.
1439///
1440/// SRTT and RTTVAR are stored shifted for fixed-point precision.
1441#[derive(Debug, Clone)]
1442pub struct RttEstimator {
1443    /// Smoothed RTT in microseconds (shifted left by SRTT_SHIFT)
1444    srtt_shifted: u64,
1445    /// RTT variance in microseconds (shifted left by RTTVAR_SHIFT)
1446    rttvar_shifted: u64,
1447    /// Minimum RTT observed (microseconds)
1448    pub min_rtt: u64,
1449    /// Latest RTT sample (microseconds)
1450    pub latest_rtt: u64,
1451    /// Whether first sample has been received
1452    initialized: bool,
1453}
1454
1455impl Default for RttEstimator {
1456    fn default() -> Self {
1457        Self::new()
1458    }
1459}
1460
1461impl RttEstimator {
1462    pub fn new() -> Self {
1463        Self {
1464            srtt_shifted: INITIAL_RTT_US << SRTT_SHIFT,
1465            rttvar_shifted: (INITIAL_RTT_US / 2) << RTTVAR_SHIFT,
1466            min_rtt: u64::MAX,
1467            latest_rtt: INITIAL_RTT_US,
1468            initialized: false,
1469        }
1470    }
1471
1472    /// Update RTT estimate with a new sample.
1473    pub(crate) fn update(&mut self, rtt_sample_us: u64) {
1474        self.latest_rtt = rtt_sample_us;
1475        if rtt_sample_us < self.min_rtt {
1476            self.min_rtt = rtt_sample_us;
1477        }
1478
1479        if !self.initialized {
1480            self.srtt_shifted = rtt_sample_us << SRTT_SHIFT;
1481            self.rttvar_shifted = (rtt_sample_us / 2) << RTTVAR_SHIFT;
1482            self.initialized = true;
1483            return;
1484        }
1485
1486        // RTTVAR = (1 - beta) * RTTVAR + beta * |SRTT - R|
1487        // beta = 1/4 => shift by RTTVAR_SHIFT
1488        let srtt = self.smoothed_rtt();
1489        let abs_diff = rtt_sample_us.abs_diff(srtt);
1490        // rttvar_shifted = rttvar_shifted - (rttvar_shifted >> RTTVAR_SHIFT) + abs_diff
1491        self.rttvar_shifted =
1492            self.rttvar_shifted - (self.rttvar_shifted >> RTTVAR_SHIFT) + abs_diff;
1493
1494        // SRTT = (1 - alpha) * SRTT + alpha * R
1495        // alpha = 1/8 => shift by SRTT_SHIFT
1496        self.srtt_shifted = self.srtt_shifted - (self.srtt_shifted >> SRTT_SHIFT) + rtt_sample_us;
1497    }
1498
1499    /// Get smoothed RTT in microseconds.
1500    pub(crate) fn smoothed_rtt(&self) -> u64 {
1501        self.srtt_shifted >> SRTT_SHIFT
1502    }
1503
1504    /// Get RTT variance in microseconds.
1505    pub(crate) fn rttvar(&self) -> u64 {
1506        self.rttvar_shifted >> RTTVAR_SHIFT
1507    }
1508
1509    /// Calculate PTO (Probe Timeout) in microseconds.
1510    ///
1511    /// PTO = 2 * smoothed_RTT + max(4 * rttvar, 1ms)
1512    pub(crate) fn pto(&self) -> u64 {
1513        let srtt = self.smoothed_rtt();
1514        let rttvar = self.rttvar();
1515        let var_component = if rttvar * 4 > PTO_MIN_US {
1516            rttvar * 4
1517        } else {
1518            PTO_MIN_US
1519        };
1520        srtt * 2 + var_component
1521    }
1522
1523    /// Calculate the loss detection time threshold in microseconds.
1524    ///
1525    /// Time threshold = max(9/8 * max(smoothed_rtt, latest_rtt), 1ms)
1526    pub(crate) fn loss_time_threshold(&self) -> u64 {
1527        let base = if self.smoothed_rtt() > self.latest_rtt {
1528            self.smoothed_rtt()
1529        } else {
1530            self.latest_rtt
1531        };
1532        let threshold = (base * TIME_THRESHOLD_NUM) / TIME_THRESHOLD_DEN;
1533        if threshold < PTO_MIN_US {
1534            PTO_MIN_US
1535        } else {
1536            threshold
1537        }
1538    }
1539}
1540
1541// ---------------------------------------------------------------------------
1542// Stream Multiplexing
1543// ---------------------------------------------------------------------------
1544
1545/// Stream type classification from stream ID.
1546#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1547pub enum StreamType {
1548    /// Client-initiated bidirectional (ID & 0x03 == 0x00)
1549    ClientBidi,
1550    /// Server-initiated bidirectional (ID & 0x03 == 0x01)
1551    ServerBidi,
1552    /// Client-initiated unidirectional (ID & 0x03 == 0x02)
1553    ClientUni,
1554    /// Server-initiated unidirectional (ID & 0x03 == 0x03)
1555    ServerUni,
1556}
1557
1558impl StreamType {
1559    /// Classify a stream ID.
1560    pub(crate) fn from_id(stream_id: u64) -> Self {
1561        match stream_id & 0x03 {
1562            0x00 => Self::ClientBidi,
1563            0x01 => Self::ServerBidi,
1564            0x02 => Self::ClientUni,
1565            0x03 => Self::ServerUni,
1566            _ => unreachable!(),
1567        }
1568    }
1569
1570    /// Whether this stream type is bidirectional.
1571    pub(crate) fn is_bidirectional(self) -> bool {
1572        matches!(self, Self::ClientBidi | Self::ServerBidi)
1573    }
1574
1575    /// Whether this stream type is initiated by the client.
1576    pub(crate) fn is_client_initiated(self) -> bool {
1577        matches!(self, Self::ClientBidi | Self::ClientUni)
1578    }
1579}
1580
1581/// Stream state machine.
1582#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1583pub enum StreamState {
1584    Idle,
1585    Open,
1586    HalfClosedLocal,
1587    HalfClosedRemote,
1588    Closed,
1589}
1590
1591/// A single QUIC stream.
1592#[derive(Debug, Clone)]
1593pub struct QuicStream {
1594    pub id: u64,
1595    pub state: StreamState,
1596    pub stream_type: StreamType,
1597    /// Send buffer
1598    pub send_buf: Vec<u8>,
1599    /// Send offset (next byte to send)
1600    pub send_offset: u64,
1601    /// Receive buffer
1602    pub recv_buf: Vec<u8>,
1603    /// Receive offset (next expected byte)
1604    pub recv_offset: u64,
1605    /// Max data we can send on this stream
1606    pub max_send_data: u64,
1607    /// Max data peer can send on this stream
1608    pub max_recv_data: u64,
1609    /// Total bytes sent
1610    pub bytes_sent: u64,
1611    /// Total bytes received
1612    pub bytes_received: u64,
1613    /// Priority weight (higher = more important)
1614    pub priority: u8,
1615    /// Whether FIN has been sent
1616    pub fin_sent: bool,
1617    /// Whether FIN has been received
1618    pub fin_received: bool,
1619}
1620
1621impl QuicStream {
1622    pub fn new(id: u64, max_send_data: u64, max_recv_data: u64) -> Self {
1623        Self {
1624            id,
1625            state: StreamState::Idle,
1626            stream_type: StreamType::from_id(id),
1627            send_buf: Vec::new(),
1628            send_offset: 0,
1629            recv_buf: Vec::new(),
1630            recv_offset: 0,
1631            max_send_data,
1632            max_recv_data,
1633            bytes_sent: 0,
1634            bytes_received: 0,
1635            priority: 128, // default middle priority
1636            fin_sent: false,
1637            fin_received: false,
1638        }
1639    }
1640
1641    /// Transition stream state.
1642    pub(crate) fn transition(&mut self, new_state: StreamState) -> QuicResult<()> {
1643        let valid = matches!(
1644            (self.state, new_state),
1645            (StreamState::Idle, StreamState::Open)
1646                | (StreamState::Open, StreamState::HalfClosedLocal)
1647                | (StreamState::Open, StreamState::HalfClosedRemote)
1648                | (StreamState::Open, StreamState::Closed)
1649                | (StreamState::HalfClosedLocal, StreamState::Closed)
1650                | (StreamState::HalfClosedRemote, StreamState::Closed)
1651        );
1652        if !valid {
1653            return Err(QuicError::StreamStateError);
1654        }
1655        self.state = new_state;
1656        Ok(())
1657    }
1658
1659    /// Write data to the send buffer.
1660    pub(crate) fn write(&mut self, data: &[u8]) -> QuicResult<usize> {
1661        if self.state == StreamState::HalfClosedLocal || self.state == StreamState::Closed {
1662            return Err(QuicError::StreamStateError);
1663        }
1664        let available = self.max_send_data.saturating_sub(self.bytes_sent) as usize;
1665        let to_write = if data.len() < available {
1666            data.len()
1667        } else {
1668            available
1669        };
1670        if to_write == 0 {
1671            return Err(QuicError::FlowControlError);
1672        }
1673        self.send_buf.extend_from_slice(&data[..to_write]);
1674        Ok(to_write)
1675    }
1676
1677    /// Read data from the receive buffer.
1678    pub(crate) fn read(&mut self, buf: &mut [u8]) -> usize {
1679        let to_read = if buf.len() < self.recv_buf.len() {
1680            buf.len()
1681        } else {
1682            self.recv_buf.len()
1683        };
1684        buf[..to_read].copy_from_slice(&self.recv_buf[..to_read]);
1685        self.recv_buf.drain(..to_read);
1686        to_read
1687    }
1688
1689    /// Receive data from a STREAM frame.
1690    pub(crate) fn receive_data(&mut self, offset: u64, data: &[u8], fin: bool) -> QuicResult<()> {
1691        if self.state == StreamState::HalfClosedRemote || self.state == StreamState::Closed {
1692            return Err(QuicError::StreamStateError);
1693        }
1694
1695        let new_bytes = offset.saturating_add(data.len() as u64);
1696        if new_bytes > self.max_recv_data {
1697            return Err(QuicError::FlowControlError);
1698        }
1699
1700        // Simple in-order receive (for now, ignore out-of-order/gaps)
1701        if offset == self.recv_offset {
1702            self.recv_buf.extend_from_slice(data);
1703            self.recv_offset += data.len() as u64;
1704            self.bytes_received += data.len() as u64;
1705        }
1706
1707        if fin {
1708            self.fin_received = true;
1709            if self.state == StreamState::Open {
1710                self.state = StreamState::HalfClosedRemote;
1711            } else if self.state == StreamState::HalfClosedLocal {
1712                self.state = StreamState::Closed;
1713            }
1714        }
1715
1716        Ok(())
1717    }
1718
1719    /// Check if send flow control allows sending `bytes` more.
1720    pub(crate) fn can_send(&self, bytes: u64) -> bool {
1721        self.bytes_sent + bytes <= self.max_send_data
1722    }
1723
1724    /// Update max send data (received MAX_STREAM_DATA from peer).
1725    pub(crate) fn update_max_send_data(&mut self, max_data: u64) {
1726        if max_data > self.max_send_data {
1727            self.max_send_data = max_data;
1728        }
1729    }
1730}
1731
1732/// Manages all streams for a connection.
1733#[derive(Debug)]
1734pub struct StreamManager {
1735    pub streams: BTreeMap<u64, QuicStream>,
1736    /// Whether this is the client side
1737    pub is_client: bool,
1738    /// Next client-initiated bidirectional stream ID
1739    pub next_client_bidi: u64,
1740    /// Next server-initiated bidirectional stream ID
1741    pub next_server_bidi: u64,
1742    /// Next client-initiated unidirectional stream ID
1743    pub next_client_uni: u64,
1744    /// Next server-initiated unidirectional stream ID
1745    pub next_server_uni: u64,
1746    /// Default max stream data for new streams
1747    pub default_max_stream_data: u64,
1748}
1749
1750impl StreamManager {
1751    pub fn new(is_client: bool) -> Self {
1752        Self {
1753            streams: BTreeMap::new(),
1754            is_client,
1755            next_client_bidi: 0, // 0x00, 0x04, 0x08, ...
1756            next_server_bidi: 1, // 0x01, 0x05, 0x09, ...
1757            next_client_uni: 2,  // 0x02, 0x06, 0x0A, ...
1758            next_server_uni: 3,  // 0x03, 0x07, 0x0B, ...
1759            default_max_stream_data: DEFAULT_INITIAL_MAX_STREAM_DATA,
1760        }
1761    }
1762
1763    /// Open a new bidirectional stream, returning its ID.
1764    pub(crate) fn open_bidi_stream(&mut self) -> u64 {
1765        let id = if self.is_client {
1766            let id = self.next_client_bidi;
1767            self.next_client_bidi += 4;
1768            id
1769        } else {
1770            let id = self.next_server_bidi;
1771            self.next_server_bidi += 4;
1772            id
1773        };
1774        let mut stream = QuicStream::new(
1775            id,
1776            self.default_max_stream_data,
1777            self.default_max_stream_data,
1778        );
1779        stream.state = StreamState::Open;
1780        self.streams.insert(id, stream);
1781        id
1782    }
1783
1784    /// Open a new unidirectional stream, returning its ID.
1785    pub(crate) fn open_uni_stream(&mut self) -> u64 {
1786        let id = if self.is_client {
1787            let id = self.next_client_uni;
1788            self.next_client_uni += 4;
1789            id
1790        } else {
1791            let id = self.next_server_uni;
1792            self.next_server_uni += 4;
1793            id
1794        };
1795        let mut stream = QuicStream::new(
1796            id,
1797            self.default_max_stream_data,
1798            self.default_max_stream_data,
1799        );
1800        stream.state = StreamState::Open;
1801        self.streams.insert(id, stream);
1802        id
1803    }
1804
1805    /// Get a stream by ID, creating it if it was initiated by the peer.
1806    pub(crate) fn get_or_create(&mut self, stream_id: u64) -> &mut QuicStream {
1807        if !self.streams.contains_key(&stream_id) {
1808            let mut stream = QuicStream::new(
1809                stream_id,
1810                self.default_max_stream_data,
1811                self.default_max_stream_data,
1812            );
1813            stream.state = StreamState::Open;
1814            self.streams.insert(stream_id, stream);
1815        }
1816        // SAFETY: stream_id was just inserted above if missing.
1817        self.streams
1818            .get_mut(&stream_id)
1819            .expect("stream was just inserted")
1820    }
1821
1822    /// Get a stream by ID.
1823    pub(crate) fn get(&self, stream_id: u64) -> Option<&QuicStream> {
1824        self.streams.get(&stream_id)
1825    }
1826
1827    /// Get a mutable stream by ID.
1828    pub(crate) fn get_mut(&mut self, stream_id: u64) -> Option<&mut QuicStream> {
1829        self.streams.get_mut(&stream_id)
1830    }
1831
1832    /// Close a stream.
1833    pub(crate) fn close_stream(&mut self, stream_id: u64) -> QuicResult<()> {
1834        let stream = self
1835            .streams
1836            .get_mut(&stream_id)
1837            .ok_or(QuicError::StreamNotFound)?;
1838        match stream.state {
1839            StreamState::Open => stream.state = StreamState::Closed,
1840            StreamState::HalfClosedLocal | StreamState::HalfClosedRemote => {
1841                stream.state = StreamState::Closed
1842            }
1843            _ => return Err(QuicError::StreamStateError),
1844        }
1845        Ok(())
1846    }
1847
1848    /// Number of active (non-closed) streams.
1849    pub(crate) fn active_count(&self) -> usize {
1850        self.streams
1851            .values()
1852            .filter(|s| s.state != StreamState::Closed && s.state != StreamState::Idle)
1853            .count()
1854    }
1855}
1856
1857// ---------------------------------------------------------------------------
1858// Loss Detection & Recovery
1859// ---------------------------------------------------------------------------
1860
1861/// Loss detection state for a connection.
1862#[derive(Debug, Clone)]
1863pub struct LossDetector {
1864    /// Loss detection timer expiry (microseconds, 0 = not set)
1865    pub loss_detection_timer: u64,
1866    /// PTO count (doubles on each consecutive PTO)
1867    pub pto_count: u32,
1868    /// Time of last ack-eliciting packet sent (per space)
1869    pub time_of_last_ack_eliciting: [u64; 3],
1870}
1871
1872impl Default for LossDetector {
1873    fn default() -> Self {
1874        Self::new()
1875    }
1876}
1877
1878impl LossDetector {
1879    pub fn new() -> Self {
1880        Self {
1881            loss_detection_timer: 0,
1882            pto_count: 0,
1883            time_of_last_ack_eliciting: [0; 3],
1884        }
1885    }
1886
1887    /// Detect lost packets in the given packet number space.
1888    ///
1889    /// Returns a list of lost packet numbers.
1890    pub(crate) fn detect_lost_packets(
1891        pn_space: &PnSpace,
1892        rtt: &RttEstimator,
1893        now_us: u64,
1894    ) -> Vec<u64> {
1895        let mut lost = Vec::new();
1896        let largest_acked = pn_space.largest_acked;
1897        let loss_delay = rtt.loss_time_threshold();
1898
1899        for (&pn, info) in &pn_space.sent_packets {
1900            if pn > largest_acked {
1901                continue;
1902            }
1903
1904            // Packet threshold: lost if more than PACKET_THRESHOLD packets
1905            // have been acknowledged after it
1906            let pkt_threshold_lost = largest_acked.saturating_sub(pn) >= PACKET_THRESHOLD;
1907
1908            // Time threshold: lost if enough time has passed
1909            let time_threshold_lost = now_us.saturating_sub(info.sent_time_us) >= loss_delay;
1910
1911            if pkt_threshold_lost || time_threshold_lost {
1912                lost.push(pn);
1913            }
1914        }
1915
1916        lost
1917    }
1918
1919    /// Calculate PTO with exponential backoff.
1920    pub(crate) fn compute_pto(&self, rtt: &RttEstimator) -> u64 {
1921        let base_pto = rtt.pto();
1922        // Exponential backoff: PTO * 2^pto_count
1923        base_pto.checked_shl(self.pto_count).unwrap_or(u64::MAX)
1924    }
1925
1926    /// Record that an ack-eliciting packet was sent.
1927    pub(crate) fn on_ack_eliciting_sent(&mut self, space: PacketNumberSpace, now_us: u64) {
1928        self.time_of_last_ack_eliciting[space as usize] = now_us;
1929    }
1930
1931    /// Process an ACK and update loss detection state.
1932    ///
1933    /// Returns (newly_acked_packets, rtt_sample_us).
1934    pub(crate) fn on_ack_received(
1935        pn_space: &mut PnSpace,
1936        largest_acked: u64,
1937        ack_delay_us: u64,
1938        now_us: u64,
1939    ) -> (Vec<u64>, Option<u64>) {
1940        let mut newly_acked = Vec::new();
1941        let mut rtt_sample = None;
1942
1943        if largest_acked > pn_space.largest_acked {
1944            pn_space.largest_acked = largest_acked;
1945        }
1946
1947        // Find all acked packets up to largest_acked
1948        let acked_pns: Vec<u64> = pn_space
1949            .sent_packets
1950            .keys()
1951            .copied()
1952            .filter(|&pn| pn <= largest_acked)
1953            .collect();
1954
1955        for pn in acked_pns {
1956            if let Some(info) = pn_space.sent_packets.remove(&pn) {
1957                newly_acked.push(pn);
1958                // RTT sample from the largest newly acknowledged packet
1959                if pn == largest_acked {
1960                    let raw_rtt = now_us.saturating_sub(info.sent_time_us);
1961                    // Adjust for ACK delay (but don't let adjusted RTT go below min_rtt)
1962                    rtt_sample = Some(raw_rtt.saturating_sub(ack_delay_us));
1963                }
1964            }
1965        }
1966
1967        (newly_acked, rtt_sample)
1968    }
1969
1970    /// Reset PTO count (called when ack received).
1971    pub(crate) fn reset_pto(&mut self) {
1972        self.pto_count = 0;
1973    }
1974
1975    /// Increment PTO count (called on PTO timeout).
1976    pub(crate) fn on_pto_timeout(&mut self) {
1977        self.pto_count += 1;
1978    }
1979}
1980
1981// ---------------------------------------------------------------------------
1982// Tests
1983// ---------------------------------------------------------------------------
1984
1985#[cfg(test)]
1986mod tests {
1987    #[allow(unused_imports)]
1988    use alloc::vec;
1989
1990    use super::*;
1991
1992    // --- Variable-length integer tests ---
1993
1994    #[test]
1995    fn test_varint_encode_decode_1byte() {
1996        let mut buf = [0u8; 8];
1997        let n = encode_varint(37, &mut buf).unwrap();
1998        assert_eq!(n, 1);
1999        assert_eq!(buf[0], 37);
2000        let (val, consumed) = decode_varint(&buf).unwrap();
2001        assert_eq!(val, 37);
2002        assert_eq!(consumed, 1);
2003    }
2004
2005    #[test]
2006    fn test_varint_encode_decode_2byte() {
2007        let mut buf = [0u8; 8];
2008        let n = encode_varint(15293, &mut buf).unwrap();
2009        assert_eq!(n, 2);
2010        let (val, consumed) = decode_varint(&buf).unwrap();
2011        assert_eq!(val, 15293);
2012        assert_eq!(consumed, 2);
2013    }
2014
2015    #[test]
2016    fn test_varint_encode_decode_4byte() {
2017        let mut buf = [0u8; 8];
2018        let n = encode_varint(494878333, &mut buf).unwrap();
2019        assert_eq!(n, 4);
2020        let (val, consumed) = decode_varint(&buf).unwrap();
2021        assert_eq!(val, 494878333);
2022        assert_eq!(consumed, 4);
2023    }
2024
2025    #[test]
2026    fn test_varint_encode_decode_8byte() {
2027        let mut buf = [0u8; 8];
2028        let n = encode_varint(151_288_809_941_952_652, &mut buf).unwrap();
2029        assert_eq!(n, 8);
2030        let (val, consumed) = decode_varint(&buf).unwrap();
2031        assert_eq!(val, 151_288_809_941_952_652);
2032        assert_eq!(consumed, 8);
2033    }
2034
2035    #[test]
2036    fn test_varint_boundary_values() {
2037        let mut buf = [0u8; 8];
2038
2039        // Max 1-byte value
2040        let n = encode_varint(63, &mut buf).unwrap();
2041        assert_eq!(n, 1);
2042        let (val, _) = decode_varint(&buf).unwrap();
2043        assert_eq!(val, 63);
2044
2045        // Min 2-byte value
2046        let n = encode_varint(64, &mut buf).unwrap();
2047        assert_eq!(n, 2);
2048        let (val, _) = decode_varint(&buf).unwrap();
2049        assert_eq!(val, 64);
2050
2051        // Max 2-byte value
2052        let n = encode_varint(16383, &mut buf).unwrap();
2053        assert_eq!(n, 2);
2054        let (val, _) = decode_varint(&buf).unwrap();
2055        assert_eq!(val, 16383);
2056
2057        // Min 4-byte value
2058        let n = encode_varint(16384, &mut buf).unwrap();
2059        assert_eq!(n, 4);
2060        let (val, _) = decode_varint(&buf).unwrap();
2061        assert_eq!(val, 16384);
2062    }
2063
2064    #[test]
2065    fn test_varint_zero() {
2066        let mut buf = [0u8; 8];
2067        let n = encode_varint(0, &mut buf).unwrap();
2068        assert_eq!(n, 1);
2069        assert_eq!(buf[0], 0);
2070        let (val, consumed) = decode_varint(&buf).unwrap();
2071        assert_eq!(val, 0);
2072        assert_eq!(consumed, 1);
2073    }
2074
2075    #[test]
2076    fn test_varint_buffer_too_small() {
2077        let mut buf = [0u8; 1];
2078        assert_eq!(
2079            encode_varint(16384, &mut buf),
2080            Err(QuicError::BufferTooSmall)
2081        );
2082    }
2083
2084    // --- Long header tests ---
2085
2086    #[test]
2087    fn test_long_header_initial_roundtrip() {
2088        let src_cid = ConnectionId::new(&[0x01, 0x02, 0x03, 0x04]).unwrap();
2089        let dst_cid = ConnectionId::new(&[0x05, 0x06, 0x07, 0x08]).unwrap();
2090        let hdr = LongHeader {
2091            first_byte: 0xC0,
2092            version: QUIC_V1,
2093            dst_cid: dst_cid.clone(),
2094            src_cid: src_cid.clone(),
2095            packet_type: LongPacketType::Initial,
2096            token: vec![0xAA, 0xBB],
2097            packet_number: 42,
2098            payload_length: 100,
2099        };
2100
2101        let mut buf = [0u8; 256];
2102        let written = hdr.encode(&mut buf).unwrap();
2103        assert!(written > 0);
2104
2105        let (decoded, consumed) = LongHeader::decode(&buf[..written]).unwrap();
2106        assert_eq!(decoded.version, QUIC_V1);
2107        assert_eq!(decoded.packet_type, LongPacketType::Initial);
2108        assert_eq!(decoded.dst_cid, dst_cid);
2109        assert_eq!(decoded.src_cid, src_cid);
2110        assert_eq!(decoded.token, vec![0xAA, 0xBB]);
2111        assert_eq!(decoded.packet_number, 42);
2112        assert_eq!(consumed, written);
2113    }
2114
2115    #[test]
2116    fn test_long_header_handshake() {
2117        let src_cid = ConnectionId::new(&[0x10]).unwrap();
2118        let dst_cid = ConnectionId::new(&[0x20]).unwrap();
2119        let hdr = LongHeader {
2120            first_byte: 0xC0,
2121            version: QUIC_V1,
2122            dst_cid: dst_cid.clone(),
2123            src_cid: src_cid.clone(),
2124            packet_type: LongPacketType::Handshake,
2125            token: Vec::new(),
2126            packet_number: 0,
2127            payload_length: 50,
2128        };
2129
2130        let mut buf = [0u8; 128];
2131        let written = hdr.encode(&mut buf).unwrap();
2132        let (decoded, _) = LongHeader::decode(&buf[..written]).unwrap();
2133        assert_eq!(decoded.packet_type, LongPacketType::Handshake);
2134        assert_eq!(decoded.packet_number, 0);
2135    }
2136
2137    // --- Short header tests ---
2138
2139    #[test]
2140    fn test_short_header_construction() {
2141        let dst_cid = ConnectionId::new(&[0x01, 0x02, 0x03, 0x04]).unwrap();
2142        let hdr = ShortHeader::new(dst_cid.clone(), 100, true, false, 90);
2143
2144        assert!(hdr.spin_bit);
2145        assert!(!hdr.key_phase);
2146        assert_eq!(hdr.first_byte & 0x80, 0); // short header form bit = 0
2147        assert_eq!(hdr.first_byte & 0x40, 0x40); // fixed bit = 1
2148        assert!(hdr.first_byte & 0x20 != 0); // spin bit set
2149    }
2150
2151    #[test]
2152    fn test_short_header_encode() {
2153        let dst_cid = ConnectionId::new(&[0xAB, 0xCD]).unwrap();
2154        let hdr = ShortHeader::new(dst_cid, 5, false, true, 0);
2155        let mut buf = [0u8; 32];
2156        let written = hdr.encode(&mut buf, 0).unwrap();
2157        assert!(written >= 4); // 1 (first) + 2 (cid) + 1 (pn)
2158    }
2159
2160    // --- ACK frame tests ---
2161
2162    #[test]
2163    fn test_ack_frame_roundtrip() {
2164        let frame = QuicFrame::Ack {
2165            largest_acked: 100,
2166            ack_delay: 50,
2167            first_ack_range: 10,
2168            ack_ranges: vec![AckRange {
2169                gap: 5,
2170                ack_range_length: 3,
2171            }],
2172            ecn_counts: None,
2173        };
2174
2175        let mut buf = [0u8; 128];
2176        let written = frame.encode(&mut buf).unwrap();
2177        let (decoded, consumed) = QuicFrame::decode(&buf[..written]).unwrap();
2178        assert_eq!(consumed, written);
2179
2180        match decoded {
2181            QuicFrame::Ack {
2182                largest_acked,
2183                ack_delay,
2184                first_ack_range,
2185                ack_ranges,
2186                ecn_counts,
2187            } => {
2188                assert_eq!(largest_acked, 100);
2189                assert_eq!(ack_delay, 50);
2190                assert_eq!(first_ack_range, 10);
2191                assert_eq!(ack_ranges.len(), 1);
2192                assert_eq!(ack_ranges[0].gap, 5);
2193                assert_eq!(ack_ranges[0].ack_range_length, 3);
2194                assert!(ecn_counts.is_none());
2195            }
2196            _ => panic!("expected ACK frame"),
2197        }
2198    }
2199
2200    // --- STREAM frame tests ---
2201
2202    #[test]
2203    fn test_stream_frame_roundtrip() {
2204        let frame = QuicFrame::Stream {
2205            stream_id: 4,
2206            offset: 100,
2207            data: vec![0x01, 0x02, 0x03],
2208            fin: false,
2209        };
2210
2211        let mut buf = [0u8; 128];
2212        let written = frame.encode(&mut buf).unwrap();
2213        let (decoded, consumed) = QuicFrame::decode(&buf[..written]).unwrap();
2214        assert_eq!(consumed, written);
2215
2216        match decoded {
2217            QuicFrame::Stream {
2218                stream_id,
2219                offset,
2220                data,
2221                fin,
2222            } => {
2223                assert_eq!(stream_id, 4);
2224                assert_eq!(offset, 100);
2225                assert_eq!(data, vec![0x01, 0x02, 0x03]);
2226                assert!(!fin);
2227            }
2228            _ => panic!("expected STREAM frame"),
2229        }
2230    }
2231
2232    #[test]
2233    fn test_stream_frame_with_fin() {
2234        let frame = QuicFrame::Stream {
2235            stream_id: 8,
2236            offset: 0,
2237            data: vec![0xFF],
2238            fin: true,
2239        };
2240
2241        let mut buf = [0u8; 64];
2242        let written = frame.encode(&mut buf).unwrap();
2243        let (decoded, _) = QuicFrame::decode(&buf[..written]).unwrap();
2244
2245        match decoded {
2246            QuicFrame::Stream { fin, .. } => assert!(fin),
2247            _ => panic!("expected STREAM frame"),
2248        }
2249    }
2250
2251    // --- CRYPTO frame tests ---
2252
2253    #[test]
2254    fn test_crypto_frame_roundtrip() {
2255        let frame = QuicFrame::Crypto {
2256            offset: 0,
2257            data: vec![0x16, 0x03, 0x03, 0x00, 0x01], // TLS-like data
2258        };
2259
2260        let mut buf = [0u8; 64];
2261        let written = frame.encode(&mut buf).unwrap();
2262        let (decoded, consumed) = QuicFrame::decode(&buf[..written]).unwrap();
2263        assert_eq!(consumed, written);
2264
2265        match decoded {
2266            QuicFrame::Crypto { offset, data } => {
2267                assert_eq!(offset, 0);
2268                assert_eq!(data, vec![0x16, 0x03, 0x03, 0x00, 0x01]);
2269            }
2270            _ => panic!("expected CRYPTO frame"),
2271        }
2272    }
2273
2274    // --- CONNECTION_CLOSE frame tests ---
2275
2276    #[test]
2277    fn test_connection_close_transport() {
2278        let frame = QuicFrame::ConnectionClose {
2279            error_code: QuicError::FlowControlError.as_u64(),
2280            frame_type: Some(0x08),
2281            reason: vec![0x62, 0x61, 0x64], // "bad"
2282            is_application: false,
2283        };
2284
2285        let mut buf = [0u8; 64];
2286        let written = frame.encode(&mut buf).unwrap();
2287        let (decoded, consumed) = QuicFrame::decode(&buf[..written]).unwrap();
2288        assert_eq!(consumed, written);
2289
2290        match decoded {
2291            QuicFrame::ConnectionClose {
2292                error_code,
2293                frame_type,
2294                reason,
2295                is_application,
2296            } => {
2297                assert_eq!(error_code, 0x03);
2298                assert_eq!(frame_type, Some(0x08));
2299                assert_eq!(reason, vec![0x62, 0x61, 0x64]);
2300                assert!(!is_application);
2301            }
2302            _ => panic!("expected CONNECTION_CLOSE frame"),
2303        }
2304    }
2305
2306    #[test]
2307    fn test_connection_close_application() {
2308        let frame = QuicFrame::ConnectionClose {
2309            error_code: 42,
2310            frame_type: None,
2311            reason: Vec::new(),
2312            is_application: true,
2313        };
2314
2315        let mut buf = [0u8; 32];
2316        let written = frame.encode(&mut buf).unwrap();
2317        let (decoded, _) = QuicFrame::decode(&buf[..written]).unwrap();
2318
2319        match decoded {
2320            QuicFrame::ConnectionClose {
2321                is_application,
2322                error_code,
2323                ..
2324            } => {
2325                assert!(is_application);
2326                assert_eq!(error_code, 42);
2327            }
2328            _ => panic!("expected CONNECTION_CLOSE frame"),
2329        }
2330    }
2331
2332    // --- Stream ID classification tests ---
2333
2334    #[test]
2335    fn test_stream_id_classification() {
2336        // Client-initiated bidirectional: 0, 4, 8, ...
2337        assert_eq!(StreamType::from_id(0), StreamType::ClientBidi);
2338        assert_eq!(StreamType::from_id(4), StreamType::ClientBidi);
2339        assert!(StreamType::ClientBidi.is_bidirectional());
2340        assert!(StreamType::ClientBidi.is_client_initiated());
2341
2342        // Server-initiated bidirectional: 1, 5, 9, ...
2343        assert_eq!(StreamType::from_id(1), StreamType::ServerBidi);
2344        assert_eq!(StreamType::from_id(5), StreamType::ServerBidi);
2345        assert!(StreamType::ServerBidi.is_bidirectional());
2346        assert!(!StreamType::ServerBidi.is_client_initiated());
2347
2348        // Client-initiated unidirectional: 2, 6, 10, ...
2349        assert_eq!(StreamType::from_id(2), StreamType::ClientUni);
2350        assert!(!StreamType::ClientUni.is_bidirectional());
2351        assert!(StreamType::ClientUni.is_client_initiated());
2352
2353        // Server-initiated unidirectional: 3, 7, 11, ...
2354        assert_eq!(StreamType::from_id(3), StreamType::ServerUni);
2355        assert!(!StreamType::ServerUni.is_bidirectional());
2356        assert!(!StreamType::ServerUni.is_client_initiated());
2357    }
2358
2359    // --- Stream state transition tests ---
2360
2361    #[test]
2362    fn test_stream_state_transitions() {
2363        let mut stream = QuicStream::new(0, 65536, 65536);
2364        assert_eq!(stream.state, StreamState::Idle);
2365
2366        stream.transition(StreamState::Open).unwrap();
2367        assert_eq!(stream.state, StreamState::Open);
2368
2369        stream.transition(StreamState::HalfClosedLocal).unwrap();
2370        assert_eq!(stream.state, StreamState::HalfClosedLocal);
2371
2372        stream.transition(StreamState::Closed).unwrap();
2373        assert_eq!(stream.state, StreamState::Closed);
2374    }
2375
2376    #[test]
2377    fn test_stream_invalid_transition() {
2378        let mut stream = QuicStream::new(0, 65536, 65536);
2379        // Cannot go directly from Idle to Closed
2380        assert_eq!(
2381            stream.transition(StreamState::Closed),
2382            Err(QuicError::StreamStateError)
2383        );
2384    }
2385
2386    // --- Connection state transition tests ---
2387
2388    #[test]
2389    fn test_connection_state_transitions() {
2390        let src = ConnectionId::new(&[1]).unwrap();
2391        let dst = ConnectionId::new(&[2]).unwrap();
2392        let mut conn = QuicConnection::new_client(src, dst);
2393        assert_eq!(conn.state, ConnectionState::Idle);
2394
2395        conn.transition(ConnectionState::Handshake).unwrap();
2396        assert_eq!(conn.state, ConnectionState::Handshake);
2397
2398        conn.transition(ConnectionState::Connected).unwrap();
2399        assert_eq!(conn.state, ConnectionState::Connected);
2400
2401        conn.transition(ConnectionState::Closing).unwrap();
2402        assert_eq!(conn.state, ConnectionState::Closing);
2403
2404        conn.transition(ConnectionState::Closed).unwrap();
2405        assert_eq!(conn.state, ConnectionState::Closed);
2406    }
2407
2408    #[test]
2409    fn test_connection_invalid_transition() {
2410        let src = ConnectionId::new(&[1]).unwrap();
2411        let dst = ConnectionId::new(&[2]).unwrap();
2412        let mut conn = QuicConnection::new_client(src, dst);
2413        // Cannot go from Idle directly to Connected
2414        assert_eq!(
2415            conn.transition(ConnectionState::Connected),
2416            Err(QuicError::ProtocolViolation)
2417        );
2418    }
2419
2420    // --- Packet number encoding/decoding tests ---
2421
2422    #[test]
2423    fn test_packet_number_encode_1byte() {
2424        let (encoded, len) = encode_packet_number(10, 5);
2425        assert_eq!(len, 1);
2426        assert_eq!(encoded, 10);
2427    }
2428
2429    #[test]
2430    fn test_packet_number_encode_2byte() {
2431        let (encoded, len) = encode_packet_number(300, 0);
2432        assert_eq!(len, 2);
2433        assert_eq!(encoded, 300);
2434    }
2435
2436    #[test]
2437    fn test_packet_number_decode_roundtrip() {
2438        let full_pn = 12345u64;
2439        let largest_acked = 12340u64;
2440        let (truncated, pn_len) = encode_packet_number(full_pn, largest_acked);
2441        let decoded = decode_packet_number(largest_acked, truncated, pn_len);
2442        assert_eq!(decoded, full_pn);
2443    }
2444
2445    // --- Flow control tests ---
2446
2447    #[test]
2448    fn test_stream_flow_control_window() {
2449        let mut stream = QuicStream::new(0, 1024, 1024);
2450        stream.state = StreamState::Open;
2451
2452        assert!(stream.can_send(512));
2453        assert!(stream.can_send(1024));
2454        assert!(!stream.can_send(1025));
2455
2456        // Write some data
2457        let written = stream.write(&[0u8; 512]).unwrap();
2458        assert_eq!(written, 512);
2459        stream.bytes_sent += written as u64;
2460
2461        assert!(stream.can_send(512));
2462        assert!(!stream.can_send(513));
2463    }
2464
2465    #[test]
2466    fn test_connection_flow_control() {
2467        let src = ConnectionId::new(&[1]).unwrap();
2468        let dst = ConnectionId::new(&[2]).unwrap();
2469        let mut conn = QuicConnection::new_client(src, dst);
2470
2471        assert!(conn.can_send(1024));
2472        conn.data_sent = DEFAULT_INITIAL_MAX_DATA - 100;
2473        assert!(conn.can_send(100));
2474        assert!(!conn.can_send(101));
2475
2476        // Update max data
2477        conn.update_max_data_send(DEFAULT_INITIAL_MAX_DATA + 1000);
2478        assert!(conn.can_send(1100));
2479    }
2480
2481    // --- Loss detection tests ---
2482
2483    #[test]
2484    fn test_loss_detection_packet_threshold() {
2485        let mut pn_space = PnSpace::new();
2486        let rtt = RttEstimator::new();
2487
2488        // Send packets 0..5
2489        for pn in 0..5 {
2490            pn_space.on_packet_sent(pn, pn * 1000, true, 100);
2491        }
2492
2493        // ACK packet 4 (largest)
2494        pn_space.largest_acked = 4;
2495
2496        let now_us = 100_000;
2497        let lost = LossDetector::detect_lost_packets(&pn_space, &rtt, now_us);
2498
2499        // Packets 0 and 1 are lost (4 - 0 >= 3, 4 - 1 >= 3)
2500        assert!(lost.contains(&0));
2501        assert!(lost.contains(&1));
2502        // Packet 2 is borderline (4 - 2 = 2 < 3) unless time threshold triggers
2503    }
2504
2505    #[test]
2506    fn test_pto_calculation() {
2507        let rtt = RttEstimator::new();
2508        let pto = rtt.pto();
2509        // PTO = 2 * SRTT + max(4 * RTTVAR, 1ms)
2510        // SRTT = INITIAL_RTT_US = 333000
2511        // RTTVAR = INITIAL_RTT_US / 2 = 166500
2512        // PTO = 2 * 333000 + max(4 * 166500, 1000) = 666000 + 666000 = 1332000
2513        assert_eq!(pto, 1_332_000);
2514    }
2515
2516    #[test]
2517    fn test_pto_exponential_backoff() {
2518        let rtt = RttEstimator::new();
2519        let mut detector = LossDetector::new();
2520
2521        let base_pto = detector.compute_pto(&rtt);
2522        detector.on_pto_timeout();
2523        let pto_1 = detector.compute_pto(&rtt);
2524        assert_eq!(pto_1, base_pto * 2);
2525
2526        detector.on_pto_timeout();
2527        let pto_2 = detector.compute_pto(&rtt);
2528        assert_eq!(pto_2, base_pto * 4);
2529    }
2530
2531    // --- Connection ID tests ---
2532
2533    #[test]
2534    fn test_connection_id_generate() {
2535        let cid = ConnectionId::generate(0xDEAD_BEEF, 8).unwrap();
2536        assert_eq!(cid.len, 8);
2537        assert_eq!(cid.as_slice().len(), 8);
2538    }
2539
2540    #[test]
2541    fn test_connection_id_empty() {
2542        let cid = ConnectionId::EMPTY;
2543        assert_eq!(cid.len, 0);
2544        assert_eq!(cid.as_slice().len(), 0);
2545    }
2546
2547    #[test]
2548    fn test_connection_id_max_length() {
2549        let data = [0u8; 20];
2550        let cid = ConnectionId::new(&data).unwrap();
2551        assert_eq!(cid.len, 20);
2552
2553        let too_long = [0u8; 21];
2554        assert_eq!(
2555            ConnectionId::new(&too_long),
2556            Err(QuicError::ConnectionIdLimitError)
2557        );
2558    }
2559
2560    // --- Idle timeout test ---
2561
2562    #[test]
2563    fn test_idle_timeout() {
2564        let src = ConnectionId::new(&[1]).unwrap();
2565        let dst = ConnectionId::new(&[2]).unwrap();
2566        let mut conn = QuicConnection::new_client(src, dst);
2567        conn.idle_timeout_ms = 5000; // 5 seconds
2568
2569        conn.touch(1_000_000); // 1 second
2570        assert!(!conn.is_idle_timeout(3_000_000)); // 3 seconds total, 2s elapsed
2571
2572        // 7 seconds total = 6 seconds elapsed > 5 second timeout
2573        assert!(conn.is_idle_timeout(7_000_000));
2574    }
2575
2576    // --- Path validation tests ---
2577
2578    #[test]
2579    fn test_path_challenge_response() {
2580        let src = ConnectionId::new(&[1]).unwrap();
2581        let dst = ConnectionId::new(&[2]).unwrap();
2582        let mut conn = QuicConnection::new_client(src, dst);
2583
2584        let challenge = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
2585        let frame = conn.initiate_path_challenge(challenge);
2586
2587        match frame {
2588            QuicFrame::PathChallenge { data } => assert_eq!(data, challenge),
2589            _ => panic!("expected PATH_CHALLENGE"),
2590        }
2591
2592        // Wrong response
2593        let wrong = [0xFF; 8];
2594        assert!(!conn.validate_path_response(&wrong));
2595
2596        // Correct response
2597        assert!(conn.validate_path_response(&challenge));
2598        assert!(conn.path_challenge_data.is_none());
2599    }
2600
2601    // --- RTT estimation tests ---
2602
2603    #[test]
2604    fn test_rtt_first_sample() {
2605        let mut rtt = RttEstimator::new();
2606        rtt.update(100_000); // 100ms
2607
2608        assert_eq!(rtt.smoothed_rtt(), 100_000);
2609        assert_eq!(rtt.min_rtt, 100_000);
2610        assert_eq!(rtt.latest_rtt, 100_000);
2611    }
2612
2613    #[test]
2614    fn test_rtt_convergence() {
2615        let mut rtt = RttEstimator::new();
2616        // Feed constant RTT samples
2617        for _ in 0..20 {
2618            rtt.update(50_000); // 50ms
2619        }
2620        // SRTT should converge towards 50ms
2621        let srtt = rtt.smoothed_rtt();
2622        assert!(srtt > 45_000 && srtt < 55_000);
2623    }
2624
2625    // --- Stream manager tests ---
2626
2627    #[test]
2628    fn test_stream_manager_open_bidi() {
2629        let mut mgr = StreamManager::new(true); // client
2630        let id1 = mgr.open_bidi_stream();
2631        assert_eq!(id1, 0); // client bidi: 0, 4, 8, ...
2632        let id2 = mgr.open_bidi_stream();
2633        assert_eq!(id2, 4);
2634
2635        assert_eq!(mgr.active_count(), 2);
2636    }
2637
2638    #[test]
2639    fn test_stream_manager_open_uni() {
2640        let mut mgr = StreamManager::new(false); // server
2641        let id1 = mgr.open_uni_stream();
2642        assert_eq!(id1, 3); // server uni: 3, 7, 11, ...
2643        let id2 = mgr.open_uni_stream();
2644        assert_eq!(id2, 7);
2645    }
2646
2647    // --- Frame type tests ---
2648
2649    #[test]
2650    fn test_padding_frame() {
2651        let frame = QuicFrame::Padding;
2652        let mut buf = [0u8; 4];
2653        let written = frame.encode(&mut buf).unwrap();
2654        assert_eq!(written, 1);
2655        let (decoded, _) = QuicFrame::decode(&buf[..written]).unwrap();
2656        assert_eq!(decoded, QuicFrame::Padding);
2657    }
2658
2659    #[test]
2660    fn test_ping_frame() {
2661        let frame = QuicFrame::Ping;
2662        let mut buf = [0u8; 4];
2663        let written = frame.encode(&mut buf).unwrap();
2664        assert_eq!(written, 1);
2665        let (decoded, _) = QuicFrame::decode(&buf[..written]).unwrap();
2666        assert_eq!(decoded, QuicFrame::Ping);
2667    }
2668
2669    #[test]
2670    fn test_ack_eliciting() {
2671        assert!(!QuicFrame::Padding.is_ack_eliciting());
2672        assert!(QuicFrame::Ping.is_ack_eliciting());
2673        assert!(!QuicFrame::Ack {
2674            largest_acked: 0,
2675            ack_delay: 0,
2676            first_ack_range: 0,
2677            ack_ranges: Vec::new(),
2678            ecn_counts: None,
2679        }
2680        .is_ack_eliciting());
2681        assert!(QuicFrame::Stream {
2682            stream_id: 0,
2683            offset: 0,
2684            data: Vec::new(),
2685            fin: false,
2686        }
2687        .is_ack_eliciting());
2688    }
2689
2690    #[test]
2691    fn test_header_protection_apply() {
2692        let mut buf = [0xC0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42];
2693        let mask = [0x0F, 0xAA, 0xBB, 0xCC, 0xDD];
2694        let pn_offset = 6;
2695
2696        let orig_first = buf[0];
2697        let orig_pn = buf[6];
2698        apply_header_protection(&mut buf, pn_offset, &mask);
2699
2700        // Long header: mask lower 4 bits of first byte
2701        assert_eq!(buf[0], orig_first ^ (mask[0] & 0x0F));
2702        // PN byte masked with mask[1] (pn_len derived from first_byte after XOR)
2703        // After first byte XOR: 0xC0 ^ 0x0F = 0xCF, pn_len = (0xCF & 0x03) + 1 = 4
2704        // So all 4 PN bytes get masked, but we only have 1 byte at offset 6
2705        assert_eq!(buf[6], orig_pn ^ mask[1]);
2706    }
2707
2708    // --- Varint len tests ---
2709
2710    #[test]
2711    fn test_varint_len() {
2712        assert_eq!(varint_len(0), 1);
2713        assert_eq!(varint_len(63), 1);
2714        assert_eq!(varint_len(64), 2);
2715        assert_eq!(varint_len(16383), 2);
2716        assert_eq!(varint_len(16384), 4);
2717        assert_eq!(varint_len(1_073_741_823), 4);
2718        assert_eq!(varint_len(1_073_741_824), 8);
2719    }
2720}