1#![allow(dead_code)]
15
16use alloc::{collections::BTreeMap, vec::Vec};
17
18pub const QUIC_V1: u32 = 0x00000001;
24
25const MAX_CID_LEN: usize = 20;
27
28const DEFAULT_IDLE_TIMEOUT_MS: u64 = 30_000;
30
31const DEFAULT_INITIAL_MAX_DATA: u64 = 1_048_576; const DEFAULT_INITIAL_MAX_STREAM_DATA: u64 = 262_144; const PACKET_THRESHOLD: u64 = 3;
39
40const TIME_THRESHOLD_NUM: u64 = 9;
42const TIME_THRESHOLD_DEN: u64 = 8;
43
44const PTO_MIN_US: u64 = 1_000;
46
47const INITIAL_RTT_US: u64 = 333_000;
49
50const SRTT_SHIFT: u32 = 3;
52const RTTVAR_SHIFT: u32 = 2;
53
54#[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 CryptoError = 0x0100,
81 BufferTooSmall = 0xFFFF_0001,
83 InvalidPacket = 0xFFFF_0002,
85 InvalidFrame = 0xFFFF_0003,
87 ConnectionNotFound = 0xFFFF_0004,
89 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
125pub(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
166pub(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
206pub(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#[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 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
267pub(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 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
296pub(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 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#[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#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
348pub enum PacketNumberSpace {
349 Initial = 0,
350 Handshake = 1,
351 ApplicationData = 2,
352}
353
354#[derive(Debug, Clone, PartialEq, Eq)]
356pub struct LongHeader {
357 pub first_byte: u8,
359 pub version: u32,
360 pub dst_cid: ConnectionId,
361 pub src_cid: ConnectionId,
362 pub packet_type: LongPacketType,
363 pub token: Vec<u8>,
365 pub packet_number: u64,
367 pub payload_length: u64,
369}
370
371impl LongHeader {
372 pub(crate) fn encode(&self, buf: &mut [u8]) -> QuicResult<usize> {
374 let mut off = 0;
375
376 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 buf[off..off + 4].copy_from_slice(&self.version.to_be_bytes());
389 off += 4;
390
391 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 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 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 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 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 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 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 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 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 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 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 let (payload_length, n) = decode_varint(&buf[off..])?;
511 off += n;
512
513 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#[derive(Debug, Clone, PartialEq, Eq)]
550pub struct ShortHeader {
551 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 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; 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 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 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 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
623pub(crate) fn apply_header_protection(buf: &mut [u8], pn_offset: usize, mask: &[u8; 5]) {
628 if buf.is_empty() {
629 return;
630 }
631 if buf[0] & 0x80 != 0 {
633 buf[0] ^= mask[0] & 0x0F;
635 } else {
636 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#[derive(Debug, Clone, PartialEq, Eq)]
653pub enum QuicFrame {
654 Padding,
656
657 Ping,
659
660 Ack {
662 largest_acked: u64,
663 ack_delay: u64,
664 first_ack_range: u64,
665 ack_ranges: Vec<AckRange>,
666 ecn_counts: Option<EcnCounts>,
668 },
669
670 Crypto { offset: u64, data: Vec<u8> },
672
673 NewConnectionId {
675 sequence: u64,
676 retire_prior_to: u64,
677 connection_id: ConnectionId,
678 stateless_reset_token: [u8; 16],
679 },
680
681 Stream {
683 stream_id: u64,
684 offset: u64,
685 data: Vec<u8>,
686 fin: bool,
687 },
688
689 MaxData { maximum_data: u64 },
691
692 MaxStreamData {
694 stream_id: u64,
695 maximum_stream_data: u64,
696 },
697
698 DataBlocked { maximum_data: u64 },
700
701 StreamDataBlocked {
703 stream_id: u64,
704 maximum_stream_data: u64,
705 },
706
707 ConnectionClose {
709 error_code: u64,
710 frame_type: Option<u64>,
711 reason: Vec<u8>,
712 is_application: bool,
713 },
714
715 PathChallenge { data: [u8; 8] },
717
718 PathResponse { data: [u8; 8] },
720}
721
722#[derive(Debug, Clone, Copy, PartialEq, Eq)]
724pub struct AckRange {
725 pub gap: u64,
726 pub ack_range_length: u64,
727}
728
729#[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 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 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 let mut ft: u8 = 0x08;
832 if *offset > 0 {
833 ft |= 0x04; }
835 ft |= 0x02; 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 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 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 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 pub(crate) fn is_ack_eliciting(&self) -> bool {
1179 !matches!(self, Self::Ack { .. } | Self::Padding)
1180 }
1181}
1182
1183#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1189pub enum ConnectionState {
1190 Idle,
1191 Handshake,
1192 Connected,
1193 Closing,
1194 Draining,
1195 Closed,
1196}
1197
1198#[derive(Debug, Clone)]
1200pub struct PnSpace {
1201 pub next_pn: u64,
1203 pub largest_acked: u64,
1205 pub largest_received: u64,
1207 pub sent_packets: BTreeMap<u64, SentPacketInfo>,
1210 pub ack_pending: bool,
1212}
1213
1214#[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 pub(crate) fn alloc_pn(&mut self) -> u64 {
1241 let pn = self.next_pn;
1242 self.next_pn += 1;
1243 pn
1244 }
1245
1246 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 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#[derive(Debug)]
1277pub struct QuicConnection {
1278 pub state: ConnectionState,
1279 pub src_cid: ConnectionId,
1280 pub dst_cid: ConnectionId,
1281 pub active_cids: Vec<ConnectionId>,
1283 pub pn_spaces: [PnSpace; 3],
1285 pub idle_timeout_ms: u64,
1287 pub last_activity_us: u64,
1289 pub rtt: RttEstimator,
1291 pub max_data_send: u64,
1293 pub max_data_recv: u64,
1295 pub data_sent: u64,
1297 pub data_received: u64,
1299 pub streams: StreamManager,
1301 pub path_challenge_data: Option<[u8; 8]>,
1303}
1304
1305impl QuicConnection {
1306 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 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 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 pub(crate) fn pn_space(&self, space: PacketNumberSpace) -> &PnSpace {
1368 &self.pn_spaces[space as usize]
1369 }
1370
1371 pub(crate) fn pn_space_mut(&mut self, space: PacketNumberSpace) -> &mut PnSpace {
1373 &mut self.pn_spaces[space as usize]
1374 }
1375
1376 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 pub(crate) fn touch(&mut self, now_us: u64) {
1387 self.last_activity_us = now_us;
1388 }
1389
1390 pub(crate) fn add_connection_id(&mut self, cid: ConnectionId) {
1392 self.active_cids.push(cid);
1393 }
1394
1395 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 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 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 pub(crate) fn can_send(&self, bytes: u64) -> bool {
1423 self.data_sent + bytes <= self.max_data_send
1424 }
1425
1426 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#[derive(Debug, Clone)]
1442pub struct RttEstimator {
1443 srtt_shifted: u64,
1445 rttvar_shifted: u64,
1447 pub min_rtt: u64,
1449 pub latest_rtt: u64,
1451 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 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 let srtt = self.smoothed_rtt();
1489 let abs_diff = rtt_sample_us.abs_diff(srtt);
1490 self.rttvar_shifted =
1492 self.rttvar_shifted - (self.rttvar_shifted >> RTTVAR_SHIFT) + abs_diff;
1493
1494 self.srtt_shifted = self.srtt_shifted - (self.srtt_shifted >> SRTT_SHIFT) + rtt_sample_us;
1497 }
1498
1499 pub(crate) fn smoothed_rtt(&self) -> u64 {
1501 self.srtt_shifted >> SRTT_SHIFT
1502 }
1503
1504 pub(crate) fn rttvar(&self) -> u64 {
1506 self.rttvar_shifted >> RTTVAR_SHIFT
1507 }
1508
1509 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 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#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1547pub enum StreamType {
1548 ClientBidi,
1550 ServerBidi,
1552 ClientUni,
1554 ServerUni,
1556}
1557
1558impl StreamType {
1559 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 pub(crate) fn is_bidirectional(self) -> bool {
1572 matches!(self, Self::ClientBidi | Self::ServerBidi)
1573 }
1574
1575 pub(crate) fn is_client_initiated(self) -> bool {
1577 matches!(self, Self::ClientBidi | Self::ClientUni)
1578 }
1579}
1580
1581#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1583pub enum StreamState {
1584 Idle,
1585 Open,
1586 HalfClosedLocal,
1587 HalfClosedRemote,
1588 Closed,
1589}
1590
1591#[derive(Debug, Clone)]
1593pub struct QuicStream {
1594 pub id: u64,
1595 pub state: StreamState,
1596 pub stream_type: StreamType,
1597 pub send_buf: Vec<u8>,
1599 pub send_offset: u64,
1601 pub recv_buf: Vec<u8>,
1603 pub recv_offset: u64,
1605 pub max_send_data: u64,
1607 pub max_recv_data: u64,
1609 pub bytes_sent: u64,
1611 pub bytes_received: u64,
1613 pub priority: u8,
1615 pub fin_sent: bool,
1617 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, fin_sent: false,
1637 fin_received: false,
1638 }
1639 }
1640
1641 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 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 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 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 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 pub(crate) fn can_send(&self, bytes: u64) -> bool {
1721 self.bytes_sent + bytes <= self.max_send_data
1722 }
1723
1724 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#[derive(Debug)]
1734pub struct StreamManager {
1735 pub streams: BTreeMap<u64, QuicStream>,
1736 pub is_client: bool,
1738 pub next_client_bidi: u64,
1740 pub next_server_bidi: u64,
1742 pub next_client_uni: u64,
1744 pub next_server_uni: u64,
1746 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, next_server_bidi: 1, next_client_uni: 2, next_server_uni: 3, default_max_stream_data: DEFAULT_INITIAL_MAX_STREAM_DATA,
1760 }
1761 }
1762
1763 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 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 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 self.streams
1818 .get_mut(&stream_id)
1819 .expect("stream was just inserted")
1820 }
1821
1822 pub(crate) fn get(&self, stream_id: u64) -> Option<&QuicStream> {
1824 self.streams.get(&stream_id)
1825 }
1826
1827 pub(crate) fn get_mut(&mut self, stream_id: u64) -> Option<&mut QuicStream> {
1829 self.streams.get_mut(&stream_id)
1830 }
1831
1832 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 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#[derive(Debug, Clone)]
1863pub struct LossDetector {
1864 pub loss_detection_timer: u64,
1866 pub pto_count: u32,
1868 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 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 let pkt_threshold_lost = largest_acked.saturating_sub(pn) >= PACKET_THRESHOLD;
1907
1908 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 pub(crate) fn compute_pto(&self, rtt: &RttEstimator) -> u64 {
1921 let base_pto = rtt.pto();
1922 base_pto.checked_shl(self.pto_count).unwrap_or(u64::MAX)
1924 }
1925
1926 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 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 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 if pn == largest_acked {
1960 let raw_rtt = now_us.saturating_sub(info.sent_time_us);
1961 rtt_sample = Some(raw_rtt.saturating_sub(ack_delay_us));
1963 }
1964 }
1965 }
1966
1967 (newly_acked, rtt_sample)
1968 }
1969
1970 pub(crate) fn reset_pto(&mut self) {
1972 self.pto_count = 0;
1973 }
1974
1975 pub(crate) fn on_pto_timeout(&mut self) {
1977 self.pto_count += 1;
1978 }
1979}
1980
1981#[cfg(test)]
1986mod tests {
1987 #[allow(unused_imports)]
1988 use alloc::vec;
1989
1990 use super::*;
1991
1992 #[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 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 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 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 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 #[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 #[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); assert_eq!(hdr.first_byte & 0x40, 0x40); assert!(hdr.first_byte & 0x20 != 0); }
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); }
2159
2160 #[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 #[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 #[test]
2254 fn test_crypto_frame_roundtrip() {
2255 let frame = QuicFrame::Crypto {
2256 offset: 0,
2257 data: vec![0x16, 0x03, 0x03, 0x00, 0x01], };
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 #[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], 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 #[test]
2335 fn test_stream_id_classification() {
2336 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 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 assert_eq!(StreamType::from_id(2), StreamType::ClientUni);
2350 assert!(!StreamType::ClientUni.is_bidirectional());
2351 assert!(StreamType::ClientUni.is_client_initiated());
2352
2353 assert_eq!(StreamType::from_id(3), StreamType::ServerUni);
2355 assert!(!StreamType::ServerUni.is_bidirectional());
2356 assert!(!StreamType::ServerUni.is_client_initiated());
2357 }
2358
2359 #[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 assert_eq!(
2381 stream.transition(StreamState::Closed),
2382 Err(QuicError::StreamStateError)
2383 );
2384 }
2385
2386 #[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 assert_eq!(
2415 conn.transition(ConnectionState::Connected),
2416 Err(QuicError::ProtocolViolation)
2417 );
2418 }
2419
2420 #[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 #[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 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 conn.update_max_data_send(DEFAULT_INITIAL_MAX_DATA + 1000);
2478 assert!(conn.can_send(1100));
2479 }
2480
2481 #[test]
2484 fn test_loss_detection_packet_threshold() {
2485 let mut pn_space = PnSpace::new();
2486 let rtt = RttEstimator::new();
2487
2488 for pn in 0..5 {
2490 pn_space.on_packet_sent(pn, pn * 1000, true, 100);
2491 }
2492
2493 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 assert!(lost.contains(&0));
2501 assert!(lost.contains(&1));
2502 }
2504
2505 #[test]
2506 fn test_pto_calculation() {
2507 let rtt = RttEstimator::new();
2508 let pto = rtt.pto();
2509 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 #[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 #[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; conn.touch(1_000_000); assert!(!conn.is_idle_timeout(3_000_000)); assert!(conn.is_idle_timeout(7_000_000));
2574 }
2575
2576 #[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 let wrong = [0xFF; 8];
2594 assert!(!conn.validate_path_response(&wrong));
2595
2596 assert!(conn.validate_path_response(&challenge));
2598 assert!(conn.path_challenge_data.is_none());
2599 }
2600
2601 #[test]
2604 fn test_rtt_first_sample() {
2605 let mut rtt = RttEstimator::new();
2606 rtt.update(100_000); 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 for _ in 0..20 {
2618 rtt.update(50_000); }
2620 let srtt = rtt.smoothed_rtt();
2622 assert!(srtt > 45_000 && srtt < 55_000);
2623 }
2624
2625 #[test]
2628 fn test_stream_manager_open_bidi() {
2629 let mut mgr = StreamManager::new(true); let id1 = mgr.open_bidi_stream();
2631 assert_eq!(id1, 0); 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); let id1 = mgr.open_uni_stream();
2642 assert_eq!(id1, 3); let id2 = mgr.open_uni_stream();
2644 assert_eq!(id2, 7);
2645 }
2646
2647 #[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 assert_eq!(buf[0], orig_first ^ (mask[0] & 0x0F));
2702 assert_eq!(buf[6], orig_pn ^ mask[1]);
2706 }
2707
2708 #[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}