1use std::{
2 cmp,
3 collections::{BTreeMap, BTreeSet, VecDeque},
4 mem,
5 ops::{Bound, Index, IndexMut},
6};
7
8use rand::{CryptoRng, RngExt};
9use rustc_hash::{FxHashMap, FxHashSet};
10use sorted_index_buffer::SortedIndexBuffer;
11use tracing::trace;
12
13use super::{PathId, paths::PathResponses, paths::PathRetransmits};
14use crate::{
15 Dir, Duration, FourTuple, Instant, StreamId, TransportError, TransportErrorCode, VarInt,
16 connection::StreamsState,
17 frame::{self, AddAddress, RemoveAddress},
18 packet::SpaceId,
19 range_set::ArrayRangeSet,
20 shared::IssuedCid,
21};
22
23pub(super) struct PacketSpace {
24 pub(super) pending: Retransmits,
26
27 pub(super) number_spaces: BTreeMap<PathId, PacketNumberSpace>,
33}
34
35impl PacketSpace {
36 pub(super) fn new(now: Instant, space: SpaceId, rng: &mut (impl CryptoRng + ?Sized)) -> Self {
37 let number_space_0 = PacketNumberSpace::new(now, space, rng);
38 Self {
39 pending: Retransmits::default(),
40 number_spaces: BTreeMap::from([(PathId::ZERO, number_space_0)]),
41 }
42 }
43
44 #[cfg(test)]
45 pub(super) fn new_deterministic(now: Instant, space: SpaceId) -> Self {
46 let number_space_0 = PacketNumberSpace::new_deterministic(now, space);
47 Self {
48 pending: Retransmits::default(),
49 number_spaces: BTreeMap::from([(PathId::ZERO, number_space_0)]),
50 }
51 }
52
53 pub(super) fn path_space(&self, path_id: PathId) -> Option<&PacketNumberSpace> {
57 self.number_spaces.get(&path_id)
58 }
59
60 pub(super) fn path_space_mut(&mut self, path_id: PathId) -> Option<&mut PacketNumberSpace> {
64 self.number_spaces.get_mut(&path_id)
65 }
66
67 pub(super) fn for_path(&mut self, path: PathId) -> &mut PacketNumberSpace {
76 self.number_spaces
77 .get_mut(&path)
78 .unwrap_or_else(|| panic!("PacketNumberSpace missing for {path}"))
79 }
80
81 pub(super) fn iter_paths_mut(&mut self) -> impl Iterator<Item = &mut PacketNumberSpace> {
82 self.number_spaces.values_mut()
83 }
84
85 pub(super) fn queue_tail_loss_probe(
98 &mut self,
99 path_id: PathId,
100 request_immediate_ack: bool,
101 streams: &StreamsState,
102 ) {
103 if request_immediate_ack {
104 self.for_path(path_id).pending_immediate_ack = true;
107 }
108
109 if !self.pending.is_empty(streams) {
111 return;
113 }
114
115 for packet in self
117 .number_spaces
118 .values_mut()
119 .flat_map(|s| s.sent_packets.values_mut())
120 {
121 if !packet.retransmits.is_empty(streams) {
122 self.pending |= mem::take(&mut packet.retransmits);
125 return;
126 }
127 }
128
129 if !self.for_path(path_id).pending_immediate_ack {
133 self.for_path(path_id).pending_ping = true;
134 }
135 }
136
137 pub(super) fn can_send(&self, path_id: PathId, streams: &StreamsState) -> SendableFrames {
145 let acks = self
146 .number_spaces
147 .values()
148 .any(|pns| pns.pending_acks.can_send());
149 let space_specific = self.number_spaces.get(&path_id).is_some_and(|s| {
150 s.pending_ping || s.pending_immediate_ack || !s.pending_path_responses.is_empty()
151 });
152 let other = !self.pending.is_empty(streams);
153 SendableFrames {
154 acks,
155 close: false,
156 space_specific,
157 other,
158 }
159 }
160}
161
162impl Index<SpaceId> for [PacketSpace; 3] {
163 type Output = PacketSpace;
164 fn index(&self, space: SpaceId) -> &PacketSpace {
165 &self.as_ref()[space as usize]
166 }
167}
168
169impl IndexMut<SpaceId> for [PacketSpace; 3] {
170 fn index_mut(&mut self, space: SpaceId) -> &mut PacketSpace {
171 &mut self.as_mut()[space as usize]
172 }
173}
174
175#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
180pub(crate) enum SpaceKind {
181 Initial = 0,
183 Handshake = 1,
185 Data = 2,
187}
188
189impl SpaceKind {
190 pub(crate) fn encryption_level(self) -> super::EncryptionLevel {
192 match self {
193 Self::Initial => super::EncryptionLevel::Initial,
194 Self::Handshake => super::EncryptionLevel::Handshake,
195 Self::Data => super::EncryptionLevel::OneRtt,
196 }
197 }
198}
199
200impl Index<SpaceKind> for [PacketSpace; 3] {
201 type Output = PacketSpace;
202 fn index(&self, space: SpaceKind) -> &PacketSpace {
203 &self.as_ref()[space as usize]
204 }
205}
206
207impl IndexMut<SpaceKind> for [PacketSpace; 3] {
208 fn index_mut(&mut self, space: SpaceKind) -> &mut PacketSpace {
209 &mut self.as_mut()[space as usize]
210 }
211}
212
213pub(super) struct PacketNumberSpace {
230 pub(super) open_status: OpenStatus,
241
242 pub(super) largest_received_packet_number: Option<u64>,
244 pub(super) next_packet_number: u64,
247 pub(super) largest_acked_packet_pn: Option<u64>,
249 pub(super) largest_acked_packet_send_time: Instant,
250 pub(super) largest_ack_eliciting_sent: u64,
252 pub(super) unacked_non_ack_eliciting_tail: u64,
254 pub(super) sent_packets: SortedIndexBuffer<SentPacket>,
257 pub(super) lost_packets: SortedIndexBuffer<LostPacket>,
260 pub(super) ecn_counters: frame::EcnCounts,
262 pub(super) ecn_feedback: frame::EcnCounts,
269 pub(super) pending_ping: bool,
271 pub(super) pending_acks: PendingAcks,
273 pub(super) pending_immediate_ack: bool,
275 pub(super) pending_path_responses: PathResponses,
281 pub(super) dedup: Dedup,
283
284 pub(super) time_of_last_ack_eliciting_packet: Option<Instant>,
289 pub(super) loss_time: Option<Instant>,
295 pub(super) loss_probes: u32,
297
298 pn_filter: Option<PacketNumberFilter>,
300}
301
302impl PacketNumberSpace {
303 pub(super) fn new(now: Instant, space: SpaceId, rng: &mut (impl CryptoRng + ?Sized)) -> Self {
304 let pn_filter = match space {
305 SpaceId::Initial | SpaceId::Handshake => None,
306 SpaceId::Data => Some(PacketNumberFilter::new(rng)),
307 };
308 Self {
309 open_status: OpenStatus::default(),
310 largest_received_packet_number: None,
311 next_packet_number: 0,
312 largest_acked_packet_pn: None,
313 largest_acked_packet_send_time: now,
314 largest_ack_eliciting_sent: 0,
315 unacked_non_ack_eliciting_tail: 0,
316 sent_packets: SortedIndexBuffer::new(),
317 lost_packets: SortedIndexBuffer::new(),
318 ecn_counters: frame::EcnCounts::ZERO,
319 ecn_feedback: frame::EcnCounts::ZERO,
320 pending_ping: false,
321 pending_acks: PendingAcks::new(),
322 pending_immediate_ack: false,
323 pending_path_responses: PathResponses::default(),
324 dedup: Default::default(),
325 time_of_last_ack_eliciting_packet: None,
326 loss_time: None,
327 loss_probes: 0,
328 pn_filter,
329 }
330 }
331
332 #[cfg(test)]
333 fn new_deterministic(now: Instant, space: SpaceId) -> Self {
334 let pn_filter = match space {
335 SpaceId::Initial | SpaceId::Handshake => None,
336 SpaceId::Data => Some(PacketNumberFilter::disabled()),
337 };
338 Self {
339 open_status: OpenStatus::default(),
340 largest_received_packet_number: None,
341 next_packet_number: 0,
342 largest_acked_packet_pn: None,
343 largest_acked_packet_send_time: now,
344 largest_ack_eliciting_sent: 0,
345 unacked_non_ack_eliciting_tail: 0,
346 sent_packets: SortedIndexBuffer::new(),
347 lost_packets: SortedIndexBuffer::new(),
348 ecn_counters: frame::EcnCounts::ZERO,
349 ecn_feedback: frame::EcnCounts::ZERO,
350 pending_ping: false,
351 pending_acks: PendingAcks::new(),
352 pending_immediate_ack: false,
353 pending_path_responses: PathResponses::default(),
354 dedup: Default::default(),
355 time_of_last_ack_eliciting_packet: None,
356 loss_time: None,
357 loss_probes: 0,
358 pn_filter,
359 }
360 }
361
362 pub(super) fn get_tx_number(&mut self, rng: &mut (impl CryptoRng + ?Sized)) -> u64 {
367 assert!(self.next_packet_number < 2u64.pow(62));
369 let mut pn = self.next_packet_number;
370 self.next_packet_number += 1;
371
372 if let Some(ref mut filter) = self.pn_filter
374 && filter.skip_pn(pn, rng)
375 {
376 pn = self.next_packet_number;
377 self.next_packet_number += 1;
378 }
379 pn
380 }
381
382 pub(super) fn peek_tx_number(&mut self) -> u64 {
383 let pn = self.next_packet_number;
384 if let Some(ref filter) = self.pn_filter
385 && pn == filter.next_skipped_packet_number
386 {
387 return pn + 1;
388 }
389 pn
390 }
391
392 pub(super) fn check_ack(&self, range: std::ops::Range<u64>) -> Result<(), TransportError> {
394 if let Some(ref filter) = self.pn_filter
395 && filter
396 .prev_skipped_packet_number
397 .is_some_and(|pn| range.contains(&pn))
398 {
399 return Err(TransportError::PROTOCOL_VIOLATION("unsent packet acked"));
400 }
401 Ok(())
402 }
403
404 pub(super) fn detect_ecn(
406 &mut self,
407 newly_acked: u64,
408 ecn: frame::EcnCounts,
409 ) -> Result<bool, &'static str> {
410 let ect0_increase = ecn
411 .ect0
412 .checked_sub(self.ecn_feedback.ect0)
413 .ok_or("peer ECT(0) count regression")?;
414 let ect1_increase = ecn
415 .ect1
416 .checked_sub(self.ecn_feedback.ect1)
417 .ok_or("peer ECT(1) count regression")?;
418 let ce_increase = ecn
419 .ce
420 .checked_sub(self.ecn_feedback.ce)
421 .ok_or("peer CE count regression")?;
422 let total_increase = ect0_increase + ect1_increase + ce_increase;
423 if total_increase < newly_acked {
424 return Err("ECN bleaching");
425 }
426 if (ect0_increase + ce_increase) < newly_acked || ect1_increase != 0 {
427 return Err("ECN corruption");
428 }
429 self.ecn_feedback = ecn;
434 Ok(ce_increase != 0)
435 }
436
437 pub(super) fn take(&mut self, number: u64) -> Option<SentPacket> {
439 let packet = self.sent_packets.remove(number)?;
440 if !packet.ack_eliciting && number > self.largest_ack_eliciting_sent {
441 self.unacked_non_ack_eliciting_tail =
442 self.unacked_non_ack_eliciting_tail.checked_sub(1).unwrap();
443 }
444 Some(packet)
445 }
446
447 pub(super) fn sent(&mut self, number: u64, packet: SentPacket) -> Option<SentPacket> {
449 const MAX_UNACKED_NON_ACK_ELICTING_TAIL: u64 = 1_000;
456
457 let mut forgotten = None;
458 if packet.ack_eliciting {
459 self.unacked_non_ack_eliciting_tail = 0;
460 self.largest_ack_eliciting_sent = number;
461 } else if self.unacked_non_ack_eliciting_tail > MAX_UNACKED_NON_ACK_ELICTING_TAIL {
462 let oldest_after_ack_eliciting = self
463 .sent_packets
464 .keys_range((
465 Bound::Excluded(self.largest_ack_eliciting_sent),
466 Bound::Unbounded,
467 ))
468 .next()
469 .unwrap();
470 let packet = self
475 .sent_packets
476 .remove(oldest_after_ack_eliciting)
477 .unwrap();
478 debug_assert!(!packet.ack_eliciting);
479 forgotten = Some(packet);
480 } else {
481 self.unacked_non_ack_eliciting_tail += 1;
482 }
483
484 self.sent_packets.insert(number, packet);
485 forgotten
486 }
487
488 pub(super) fn has_in_flight(&self) -> bool {
490 self.sent_packets.values().any(|x| x.size != 0)
494 }
495}
496
497#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
498pub(super) enum OpenStatus {
499 #[default]
501 Pending,
502 Informed,
504}
505
506#[derive(Debug, Clone)]
508pub(super) struct SentPacket {
509 pub(super) path_generation: u64,
511 pub(super) time_sent: Instant,
513 pub(super) size: u16,
517 pub(super) ack_eliciting: bool,
519 pub(super) largest_acked: FxHashMap<PathId, u64>,
521 pub(super) retransmits: ThinRetransmits,
525 pub(super) path_retransmits: PathRetransmits,
527 pub(super) stream_frames: frame::StreamMetaVec,
531}
532
533#[derive(Debug)]
535pub(super) struct LostPacket {
536 pub(super) time_sent: Instant,
538}
539
540#[allow(unreachable_pub)] #[derive(Debug, Default, Clone)]
545pub struct Retransmits {
546 pub(super) max_data: bool,
547 pub(super) max_stream_id: [bool; 2],
548 pub(super) streams_blocked: [bool; 2],
549 pub(super) reset_stream: Vec<(StreamId, VarInt)>,
550 pub(super) stop_sending: Vec<frame::StopSending>,
551 pub(super) max_stream_data: FxHashSet<StreamId>,
552 pub(super) crypto: VecDeque<frame::Crypto>,
553 pub(super) new_cids: PendingNewCids,
554 pub(super) retire_cids: Vec<(PathId, u64)>,
555 pub(super) ack_frequency: bool,
556 pub(super) handshake_done: bool,
557 pub(super) max_path_id: bool,
559 pub(super) paths_blocked: Option<PathId>,
567 pub(super) new_tokens: Vec<FourTuple>,
584 pub(super) path_abandon: BTreeMap<PathId, TransportErrorCode>,
586 pub(super) path_status: BTreeSet<PathId>,
588 pub(super) path_cids_blocked: BTreeMap<PathId, VarInt>,
594
595 pub(super) add_address: BTreeSet<AddAddress>,
598 pub(super) remove_address: BTreeSet<RemoveAddress>,
600 pub(super) reach_out: PendingReachOutFrames,
602}
603
604impl Retransmits {
605 pub(super) fn is_empty(&self, streams: &StreamsState) -> bool {
606 let Self {
607 max_data,
608 max_stream_id,
609 streams_blocked,
610 reset_stream,
611 stop_sending,
612 max_stream_data,
613 crypto,
614 new_cids,
615 retire_cids,
616 ack_frequency,
617 handshake_done,
618 max_path_id,
619 paths_blocked,
620 new_tokens,
621 path_abandon,
622 path_status,
623 path_cids_blocked,
624 add_address,
625 remove_address,
626 reach_out,
627 } = &self;
628 !max_data
629 && !max_stream_id.iter().any(|x| *x)
630 && !streams_blocked.iter().any(|x| *x)
631 && reset_stream.is_empty()
632 && stop_sending.is_empty()
633 && max_stream_data
634 .iter()
635 .all(|&id| !streams.can_send_flow_control(id))
636 && crypto.is_empty()
637 && new_cids.is_empty()
638 && retire_cids.is_empty()
639 && !ack_frequency
640 && !handshake_done
641 && !max_path_id
642 && paths_blocked.is_none()
643 && new_tokens.is_empty()
644 && path_abandon.is_empty()
645 && path_status.is_empty()
646 && path_cids_blocked.is_empty()
647 && add_address.is_empty()
648 && remove_address.is_empty()
649 && reach_out.is_empty()
650 }
651}
652
653impl ::std::ops::BitOrAssign for Retransmits {
654 fn bitor_assign(&mut self, rhs: Self) {
655 let Self {
656 max_data,
657 max_stream_id,
658 streams_blocked,
659 reset_stream,
660 stop_sending,
661 max_stream_data,
662 crypto,
663 new_cids,
664 retire_cids,
665 ack_frequency,
666 handshake_done,
667 max_path_id,
668 paths_blocked,
669 new_tokens,
670 mut path_abandon,
671 mut path_status,
672 mut path_cids_blocked,
673 add_address,
674 remove_address,
675 mut reach_out,
676 } = rhs;
677
678 self.max_data |= max_data;
681 for dir in Dir::iter() {
682 self.max_stream_id[dir as usize] |= max_stream_id[dir as usize];
683 self.streams_blocked[dir as usize] |= streams_blocked[dir as usize];
684 }
685 self.reset_stream.extend_from_slice(&reset_stream);
686 self.stop_sending.extend_from_slice(&stop_sending);
687 self.max_stream_data.extend(&max_stream_data);
688 for crypto in crypto.into_iter().rev() {
689 self.crypto.push_front(crypto);
690 }
691 self.new_cids.extend(&new_cids);
692 self.retire_cids.extend(retire_cids);
693 self.ack_frequency |= ack_frequency;
694 self.handshake_done |= handshake_done;
695 self.max_path_id |= max_path_id;
696 self.paths_blocked = cmp::max(self.paths_blocked, paths_blocked);
697 self.new_tokens.extend_from_slice(&new_tokens);
698 self.path_abandon.append(&mut path_abandon);
699 self.path_status.append(&mut path_status);
700 self.path_cids_blocked.append(&mut path_cids_blocked);
701 self.add_address.extend(add_address.iter().copied());
702 self.remove_address.extend(remove_address.iter().copied());
703 self.reach_out.append(&mut reach_out);
704 }
705}
706
707impl ::std::ops::BitOrAssign<ThinRetransmits> for Retransmits {
708 fn bitor_assign(&mut self, rhs: ThinRetransmits) {
709 let ThinRetransmits { retransmits } = rhs;
710 if let Some(retransmits) = retransmits {
711 self.bitor_assign(*retransmits)
712 }
713 }
714}
715
716impl ::std::iter::FromIterator<Self> for Retransmits {
717 fn from_iter<T>(iter: T) -> Self
718 where
719 T: IntoIterator<Item = Self>,
720 {
721 let mut result = Self::default();
722 for packet in iter {
723 result |= packet;
724 }
725 result
726 }
727}
728
729#[derive(Clone, Debug, Default)]
736pub(super) struct PendingNewCids {
737 cids: Vec<IssuedCid>,
739 sorted: bool,
741}
742
743impl PendingNewCids {
744 pub(super) fn push(&mut self, cid: IssuedCid) {
746 self.cids.push(cid);
747 self.sorted = false;
748 }
749
750 pub(super) fn pop(&mut self) -> Option<IssuedCid> {
752 if !mem::replace(&mut self.sorted, true) {
753 self.cids
754 .sort_by_key(|cid| cmp::Reverse((cid.path_id, cid.sequence)));
755 }
756 self.cids.pop()
757 }
758
759 pub(super) fn is_empty(&self) -> bool {
760 self.cids.is_empty()
761 }
762
763 pub(super) fn extend(&mut self, other: &Self) {
764 self.cids.extend(&other.cids);
765 self.sorted = false;
766 }
767
768 pub(super) fn retain<F>(&mut self, f: F)
769 where
770 F: FnMut(&IssuedCid) -> bool,
771 {
772 self.cids.retain(f);
773 }
774}
775
776#[derive(Debug, Default, Clone)]
783pub(crate) struct PendingReachOutFrames {
784 round: VarInt,
786 frames: Vec<frame::ReachOut>,
788}
789
790impl PendingReachOutFrames {
791 pub(crate) fn len(&self) -> usize {
792 self.frames.len()
793 }
794
795 pub(crate) fn is_empty(&self) -> bool {
796 self.frames.is_empty()
797 }
798
799 pub(crate) fn push(&mut self, frame: frame::ReachOut) {
800 if frame.round < self.round {
801 return;
802 } else if frame.round > self.round {
803 self.round = frame.round;
804 self.frames.clear();
805 }
806 self.frames.push(frame);
807 }
808
809 pub(crate) fn append(&mut self, other: &mut Self) {
810 if other.round < self.round {
811 other.frames.clear();
812 return;
813 } else if other.round > self.round {
814 self.round = other.round;
815 self.frames.clear();
816 }
817 self.frames.append(&mut other.frames);
818 }
819
820 pub(crate) fn pop_if(
821 &mut self,
822 predicate: impl FnOnce(&mut frame::ReachOut) -> bool,
823 ) -> Option<frame::ReachOut> {
824 self.frames.pop_if(predicate)
825 }
826}
827
828impl FromIterator<frame::ReachOut> for PendingReachOutFrames {
829 fn from_iter<T: IntoIterator<Item = frame::ReachOut>>(iter: T) -> Self {
830 let iter = iter.into_iter();
831 let size_hint = iter.size_hint();
832 let mut this = Self {
833 round: Default::default(),
834 frames: Vec::with_capacity(size_hint.1.unwrap_or(size_hint.0)),
835 };
836 for frame in iter {
837 this.push(frame);
838 }
839 this
840 }
841}
842
843#[derive(Debug, Default, Clone)]
845pub(super) struct ThinRetransmits {
846 retransmits: Option<Box<Retransmits>>,
847}
848
849impl ThinRetransmits {
850 pub(super) fn is_empty(&self, streams: &StreamsState) -> bool {
852 match &self.retransmits {
853 Some(retransmits) => retransmits.is_empty(streams),
854 None => true,
855 }
856 }
857
858 pub(super) fn get(&self) -> Option<&Retransmits> {
860 self.retransmits.as_deref()
861 }
862
863 pub(super) fn get_mut(&mut self) -> Option<&mut Retransmits> {
865 self.retransmits.as_deref_mut()
866 }
867
868 pub(super) fn get_or_create(&mut self) -> &mut Retransmits {
872 if self.retransmits.is_none() {
873 self.retransmits = Some(Box::default());
874 }
875 self.retransmits.as_deref_mut().unwrap()
876 }
877}
878
879#[derive(Debug, Default)]
891pub(super) struct Dedup {
892 window: Window,
893 next: u64,
895}
896
897impl Dedup {
898 #[cfg(test)]
900 pub(super) fn new() -> Self {
901 Self { window: 0, next: 0 }
902 }
903
904 fn highest(&self) -> u64 {
906 self.next - 1
907 }
908
909 pub(super) fn insert(&mut self, packet: u64) -> bool {
913 if let Some(diff) = packet.checked_sub(self.next) {
914 self.window = ((self.window << 1) | 1)
916 .checked_shl(cmp::min(diff, u64::from(u32::MAX)) as u32)
917 .unwrap_or(0);
918 self.next = packet + 1;
919 false
920 } else if self.highest() - packet < WINDOW_SIZE {
921 if let Some(bit) = (self.highest() - packet).checked_sub(1) {
923 let mask = 1 << bit;
925 let duplicate = self.window & mask != 0;
926 self.window |= mask;
927 duplicate
928 } else {
929 true
931 }
932 } else {
933 true
935 }
936 }
937
938 fn smallest_missing_in_interval(&self, lower_bound: u64, upper_bound: u64) -> Option<u64> {
942 debug_assert!(lower_bound <= upper_bound);
943 debug_assert!(upper_bound <= self.highest());
944 const BITFIELD_SIZE: u64 = Window::BITS as u64;
945
946 let lower_bound = lower_bound + 1;
950 let upper_bound = upper_bound.saturating_sub(1);
951
952 let start_offset = (self.highest() - upper_bound).max(1) - 1;
955 if start_offset >= BITFIELD_SIZE {
956 return None;
959 }
960
961 let end_offset_exclusive = self.highest().saturating_sub(lower_bound);
962
963 let range_len = end_offset_exclusive
966 .saturating_sub(start_offset)
967 .min(BITFIELD_SIZE);
968 if range_len == 0 {
969 return None;
970 }
971
972 let mask = if range_len == BITFIELD_SIZE {
975 u128::MAX
976 } else {
977 ((1u128 << range_len) - 1) << start_offset
978 };
979 let gaps = !self.window & mask;
980
981 let smallest_missing_offset = 128 - gaps.leading_zeros() as u64;
982 let smallest_missing_packet = self.highest() - smallest_missing_offset;
983
984 if smallest_missing_packet <= upper_bound {
985 Some(smallest_missing_packet)
986 } else {
987 None
988 }
989 }
990
991 fn missing_in_interval(&self, lower_bound: u64, upper_bound: u64) -> bool {
995 self.smallest_missing_in_interval(lower_bound, upper_bound)
996 .is_some()
997 }
998}
999
1000type Window = u128;
1005
1006const WINDOW_SIZE: u64 = 1 + size_of::<Window>() as u64 * 8;
1008#[derive(Clone, Copy, PartialEq, Eq, Debug)]
1012pub(super) struct SendableFrames {
1013 pub(super) acks: bool,
1015 pub(super) close: bool,
1017 pub(super) space_specific: bool,
1025 pub(super) other: bool,
1027}
1028
1029impl SendableFrames {
1030 pub(super) fn empty() -> Self {
1032 Self {
1033 acks: false,
1034 close: false,
1035 space_specific: false,
1036 other: false,
1037 }
1038 }
1039
1040 pub(super) fn is_ack_eliciting(&self) -> bool {
1042 let Self {
1043 acks: _,
1044 close,
1045 space_specific,
1046 other,
1047 } = *self;
1048 if close {
1049 return false;
1051 }
1052 space_specific || other
1053 }
1054
1055 pub(super) fn is_empty(&self) -> bool {
1057 let Self {
1058 acks,
1059 close,
1060 space_specific,
1061 other,
1062 } = *self;
1063 !acks && !close && !space_specific && !other
1064 }
1065}
1066
1067impl ::std::ops::BitOrAssign for SendableFrames {
1068 fn bitor_assign(&mut self, rhs: Self) {
1069 let Self {
1070 acks,
1071 close,
1072 space_specific,
1073 other,
1074 } = rhs;
1075
1076 self.acks |= acks;
1077 self.close |= close;
1078 self.space_specific |= space_specific;
1079 self.other |= other;
1080 }
1081}
1082
1083#[derive(Debug)]
1084pub(super) struct PendingAcks {
1085 immediate_ack_required: bool,
1090 ack_eliciting_since_last_ack_sent: u64,
1094 non_ack_eliciting_since_last_ack_sent: u64,
1095 ack_eliciting_threshold: u64,
1096 reordering_threshold: u64,
1104 earliest_ack_eliciting_since_last_ack_sent: Option<Instant>,
1107 ranges: ArrayRangeSet,
1113 largest_packet: Option<(u64, Instant)>,
1117 largest_ack_eliciting_packet: Option<u64>,
1119 largest_acked: Option<u64>,
1121}
1122
1123impl PendingAcks {
1124 fn new() -> Self {
1125 Self {
1126 immediate_ack_required: false,
1127 ack_eliciting_since_last_ack_sent: 0,
1128 non_ack_eliciting_since_last_ack_sent: 0,
1129 ack_eliciting_threshold: 1,
1130 reordering_threshold: 1,
1131 earliest_ack_eliciting_since_last_ack_sent: None,
1132 ranges: Default::default(),
1133 largest_packet: Default::default(),
1134 largest_ack_eliciting_packet: Default::default(),
1135 largest_acked: Default::default(),
1136 }
1137 }
1138
1139 pub(super) fn set_ack_frequency_params(&mut self, frame: &frame::AckFrequency) {
1140 self.ack_eliciting_threshold = frame.ack_eliciting_threshold.into_inner();
1141 self.reordering_threshold = frame.reordering_threshold.into_inner();
1142 }
1143
1144 pub(super) fn set_immediate_ack_required(&mut self) {
1145 self.immediate_ack_required = true;
1146 }
1147
1148 pub(super) fn on_max_ack_delay_timeout(&mut self) {
1149 self.immediate_ack_required = self.ack_eliciting_since_last_ack_sent > 0;
1150 }
1151
1152 pub(super) fn max_ack_delay_timeout(&self, max_ack_delay: Duration) -> Option<Instant> {
1153 self.earliest_ack_eliciting_since_last_ack_sent
1154 .map(|earliest_unacked| earliest_unacked + max_ack_delay)
1155 }
1156
1157 pub(super) fn can_send(&self) -> bool {
1166 self.immediate_ack_required && !self.ranges.is_empty()
1167 }
1168
1169 pub(super) fn ack_delay(&self, now: Instant) -> Duration {
1171 self.largest_packet
1172 .map_or_else(Duration::default, |(_, received)| now - received)
1173 }
1174
1175 pub(super) fn packet_received(
1179 &mut self,
1180 now: Instant,
1181 packet_number: u64,
1182 ack_eliciting: bool,
1183 dedup: &Dedup,
1184 ) -> bool {
1185 if !ack_eliciting {
1186 self.non_ack_eliciting_since_last_ack_sent += 1;
1187 return false;
1188 }
1189
1190 let prev_largest_ack_eliciting = self.largest_ack_eliciting_packet.unwrap_or(0);
1191
1192 self.largest_ack_eliciting_packet = self
1194 .largest_ack_eliciting_packet
1195 .map(|pn| pn.max(packet_number))
1196 .or(Some(packet_number));
1197
1198 self.ack_eliciting_since_last_ack_sent += 1;
1200 self.immediate_ack_required |=
1201 self.ack_eliciting_since_last_ack_sent > self.ack_eliciting_threshold;
1202
1203 self.immediate_ack_required |=
1205 self.is_out_of_order(packet_number, prev_largest_ack_eliciting, dedup);
1206
1207 if self.earliest_ack_eliciting_since_last_ack_sent.is_none() && !self.can_send() {
1209 self.earliest_ack_eliciting_since_last_ack_sent = Some(now);
1210 return true;
1211 }
1212
1213 false
1214 }
1215
1216 fn is_out_of_order(
1217 &self,
1218 packet_number: u64,
1219 prev_largest_ack_eliciting: u64,
1220 dedup: &Dedup,
1221 ) -> bool {
1222 match self.reordering_threshold {
1223 0 => false,
1224 1 => {
1225 packet_number < prev_largest_ack_eliciting
1227 || dedup.missing_in_interval(prev_largest_ack_eliciting, packet_number)
1228 }
1229 _ => {
1230 let Some((largest_acked, largest_unacked)) =
1233 self.largest_acked.zip(self.largest_ack_eliciting_packet)
1234 else {
1235 return false;
1236 };
1237 if self.reordering_threshold > largest_acked {
1238 return false;
1239 }
1240 let largest_reported = largest_acked - self.reordering_threshold + 1;
1243 let Some(smallest_missing_unreported) =
1244 dedup.smallest_missing_in_interval(largest_reported, largest_unacked)
1245 else {
1246 return false;
1247 };
1248 largest_unacked - smallest_missing_unreported >= self.reordering_threshold
1249 }
1250 }
1251 }
1252
1253 pub(super) fn acks_sent(&mut self) {
1257 self.immediate_ack_required = false;
1267 self.ack_eliciting_since_last_ack_sent = 0;
1268 self.non_ack_eliciting_since_last_ack_sent = 0;
1269 self.earliest_ack_eliciting_since_last_ack_sent = None;
1270 self.largest_acked = self.largest_ack_eliciting_packet;
1271 }
1272
1273 pub(super) fn insert_one(&mut self, packet: u64, now: Instant) {
1275 self.ranges.insert_one(packet);
1276
1277 if self.largest_packet.is_none_or(|(pn, _)| packet > pn) {
1278 self.largest_packet = Some((packet, now));
1279 }
1280
1281 if self.ranges.range_count() > MAX_ACK_BLOCKS {
1282 self.ranges.pop_min();
1283 }
1284 }
1285
1286 pub(super) fn subtract_below(&mut self, max: u64) {
1288 self.ranges.remove(0..(max + 1));
1289 }
1290
1291 pub(super) fn ranges(&self) -> &ArrayRangeSet {
1293 &self.ranges
1294 }
1295
1296 pub(super) fn maybe_ack_non_eliciting(&mut self) {
1302 const LAZY_ACK_THRESHOLD: u64 = 10;
1307 if self.non_ack_eliciting_since_last_ack_sent > LAZY_ACK_THRESHOLD {
1308 self.immediate_ack_required = true;
1309 }
1310 }
1311}
1312
1313pub(super) struct PacketNumberFilter {
1330 next_skipped_packet_number: u64,
1332 prev_skipped_packet_number: Option<u64>,
1334 exponent: u32,
1336}
1337
1338impl PacketNumberFilter {
1339 pub(super) fn new(rng: &mut (impl CryptoRng + ?Sized)) -> Self {
1340 let exponent = 6;
1342 Self {
1343 next_skipped_packet_number: rng.random_range(0..2u64.saturating_pow(exponent)),
1344 prev_skipped_packet_number: None,
1345 exponent,
1346 }
1347 }
1348
1349 #[cfg(test)]
1350 pub(super) fn disabled() -> Self {
1351 Self {
1352 next_skipped_packet_number: u64::MAX,
1353 prev_skipped_packet_number: None,
1354 exponent: u32::MAX,
1355 }
1356 }
1357
1358 pub(super) fn skip_pn(&mut self, n: u64, rng: &mut (impl CryptoRng + ?Sized)) -> bool {
1360 if n != self.next_skipped_packet_number {
1361 return false;
1362 }
1363
1364 trace!("skipping pn {n}");
1365 self.prev_skipped_packet_number = Some(self.next_skipped_packet_number);
1367 let next_exponent = self.exponent.saturating_add(1);
1368 self.next_skipped_packet_number = rng
1369 .random_range(2u64.saturating_pow(self.exponent)..2u64.saturating_pow(next_exponent));
1370 self.exponent = next_exponent;
1371 true
1372 }
1373}
1374
1375const MAX_ACK_BLOCKS: usize = 64;
1377
1378#[cfg(test)]
1379mod test {
1380 use rand::Rng;
1381 use rand::seq::SliceRandom;
1382
1383 use crate::token::ResetToken;
1384 use crate::{ConnectionIdGenerator, RandomConnectionIdGenerator};
1385
1386 use super::*;
1387
1388 #[test]
1389 fn sanity() {
1390 let mut dedup = Dedup::new();
1391 assert!(!dedup.insert(0));
1392 assert_eq!(dedup.next, 1);
1393 assert_eq!(dedup.window, 0b1);
1394 assert!(dedup.insert(0));
1395 assert_eq!(dedup.next, 1);
1396 assert_eq!(dedup.window, 0b1);
1397 assert!(!dedup.insert(1));
1398 assert_eq!(dedup.next, 2);
1399 assert_eq!(dedup.window, 0b11);
1400 assert!(!dedup.insert(2));
1401 assert_eq!(dedup.next, 3);
1402 assert_eq!(dedup.window, 0b111);
1403 assert!(!dedup.insert(4));
1404 assert_eq!(dedup.next, 5);
1405 assert_eq!(dedup.window, 0b11110);
1406 assert!(!dedup.insert(7));
1407 assert_eq!(dedup.next, 8);
1408 assert_eq!(dedup.window, 0b1111_0100);
1409 assert!(dedup.insert(4));
1410 assert!(!dedup.insert(3));
1411 assert_eq!(dedup.next, 8);
1412 assert_eq!(dedup.window, 0b1111_1100);
1413 assert!(!dedup.insert(6));
1414 assert_eq!(dedup.next, 8);
1415 assert_eq!(dedup.window, 0b1111_1101);
1416 assert!(!dedup.insert(5));
1417 assert_eq!(dedup.next, 8);
1418 assert_eq!(dedup.window, 0b1111_1111);
1419 }
1420
1421 #[test]
1422 fn happypath() {
1423 let mut dedup = Dedup::new();
1424 for i in 0..(2 * WINDOW_SIZE) {
1425 assert!(!dedup.insert(i));
1426 for j in 0..=i {
1427 assert!(dedup.insert(j));
1428 }
1429 }
1430 }
1431
1432 #[test]
1433 fn jump() {
1434 let mut dedup = Dedup::new();
1435 dedup.insert(2 * WINDOW_SIZE);
1436 assert!(dedup.insert(WINDOW_SIZE));
1437 assert_eq!(dedup.next, 2 * WINDOW_SIZE + 1);
1438 assert_eq!(dedup.window, 0);
1439 assert!(!dedup.insert(WINDOW_SIZE + 1));
1440 assert_eq!(dedup.next, 2 * WINDOW_SIZE + 1);
1441 assert_eq!(dedup.window, 1 << (WINDOW_SIZE - 2));
1442 }
1443
1444 #[test]
1445 fn dedup_has_missing() {
1446 let mut dedup = Dedup::new();
1447
1448 dedup.insert(0);
1449 assert!(!dedup.missing_in_interval(0, 0));
1450
1451 dedup.insert(1);
1452 assert!(!dedup.missing_in_interval(0, 1));
1453
1454 dedup.insert(3);
1455 assert!(dedup.missing_in_interval(1, 3));
1456
1457 dedup.insert(4);
1458 assert!(!dedup.missing_in_interval(3, 4));
1459 assert!(dedup.missing_in_interval(0, 4));
1460
1461 dedup.insert(2);
1462 assert!(!dedup.missing_in_interval(0, 4));
1463 }
1464
1465 #[test]
1466 fn dedup_outside_of_window_has_missing() {
1467 let mut dedup = Dedup::new();
1468
1469 for i in 0..140 {
1470 dedup.insert(i);
1471 }
1472
1473 assert!(!dedup.missing_in_interval(0, 4));
1475 dedup.insert(160);
1476 assert!(!dedup.missing_in_interval(0, 4));
1477 assert!(!dedup.missing_in_interval(0, 140));
1478 assert!(dedup.missing_in_interval(0, 160));
1479 }
1480
1481 #[test]
1482 fn dedup_smallest_missing() {
1483 let mut dedup = Dedup::new();
1484
1485 dedup.insert(0);
1486 assert_eq!(dedup.smallest_missing_in_interval(0, 0), None);
1487
1488 dedup.insert(1);
1489 assert_eq!(dedup.smallest_missing_in_interval(0, 1), None);
1490
1491 dedup.insert(5);
1492 dedup.insert(7);
1493 assert_eq!(dedup.smallest_missing_in_interval(0, 7), Some(2));
1494 assert_eq!(dedup.smallest_missing_in_interval(5, 7), Some(6));
1495
1496 dedup.insert(2);
1497 assert_eq!(dedup.smallest_missing_in_interval(1, 7), Some(3));
1498
1499 dedup.insert(170);
1500 dedup.insert(172);
1501 dedup.insert(300);
1502 assert_eq!(dedup.smallest_missing_in_interval(170, 172), None);
1503
1504 dedup.insert(500);
1505 assert_eq!(dedup.smallest_missing_in_interval(0, 500), Some(372));
1506 assert_eq!(dedup.smallest_missing_in_interval(0, 373), Some(372));
1507 assert_eq!(dedup.smallest_missing_in_interval(0, 372), None);
1508 }
1509
1510 #[test]
1511 fn pending_acks_first_packet_is_not_considered_reordered() {
1512 let mut acks = PendingAcks::new();
1513 let mut dedup = Dedup::new();
1514 dedup.insert(0);
1515 acks.packet_received(Instant::now(), 0, true, &dedup);
1516 assert!(!acks.immediate_ack_required);
1517 }
1518
1519 #[test]
1520 fn pending_acks_after_immediate_ack_set() {
1521 let mut acks = PendingAcks::new();
1522 let mut dedup = Dedup::new();
1523
1524 dedup.insert(0);
1526 let now = Instant::now();
1527 acks.insert_one(0, now);
1528 acks.packet_received(now, 0, true, &dedup);
1529
1530 assert!(!acks.ranges.is_empty());
1532 assert!(!acks.can_send());
1533
1534 acks.set_immediate_ack_required();
1536 assert!(acks.can_send());
1537 }
1538
1539 #[test]
1540 fn pending_acks_ack_delay() {
1541 let mut acks = PendingAcks::new();
1542 let mut dedup = Dedup::new();
1543
1544 let t1 = Instant::now();
1545 let t2 = t1 + Duration::from_millis(2);
1546 let t3 = t2 + Duration::from_millis(5);
1547 assert_eq!(acks.ack_delay(t1), Duration::from_millis(0));
1548 assert_eq!(acks.ack_delay(t2), Duration::from_millis(0));
1549 assert_eq!(acks.ack_delay(t3), Duration::from_millis(0));
1550
1551 dedup.insert(0);
1553 acks.insert_one(0, t1);
1554 acks.packet_received(t1, 0, true, &dedup);
1555 assert_eq!(acks.ack_delay(t1), Duration::from_millis(0));
1556 assert_eq!(acks.ack_delay(t2), Duration::from_millis(2));
1557 assert_eq!(acks.ack_delay(t3), Duration::from_millis(7));
1558
1559 dedup.insert(3);
1561 acks.insert_one(3, t2);
1562 acks.packet_received(t2, 3, true, &dedup);
1563 assert_eq!(acks.ack_delay(t2), Duration::from_millis(0));
1564 assert_eq!(acks.ack_delay(t3), Duration::from_millis(5));
1565
1566 dedup.insert(2);
1568 acks.insert_one(2, t3);
1569 acks.packet_received(t3, 2, true, &dedup);
1570 assert_eq!(acks.ack_delay(t3), Duration::from_millis(5));
1571 }
1572
1573 #[test]
1574 fn sent_packet_size() {
1575 assert!(size_of::<SentPacket>() <= 128);
1578 }
1579
1580 #[test]
1581 fn pending_new_cids() {
1582 #[cfg(all(feature = "aws-lc-rs", not(feature = "ring")))]
1583 use aws_lc_rs::hmac;
1584 #[cfg(feature = "ring")]
1585 use ring::hmac;
1586
1587 let mut cid_generator = RandomConnectionIdGenerator::new(8);
1588 let mut reset_key = [0; 64];
1589 rand::rng().fill_bytes(&mut reset_key);
1590 let hmac = hmac::Key::new(hmac::HMAC_SHA256, &reset_key);
1591
1592 let cid_a = cid_generator.generate_cid();
1593 let a = IssuedCid {
1594 path_id: PathId::ZERO,
1595 sequence: 1,
1596 id: cid_a,
1597 reset_token: ResetToken::new(&hmac, cid_a),
1598 };
1599 let cid_b = cid_generator.generate_cid();
1600 let b = IssuedCid {
1601 path_id: PathId::ZERO,
1602 sequence: 2,
1603 id: cid_b,
1604 reset_token: ResetToken::new(&hmac, cid_b),
1605 };
1606 let cid_c = cid_generator.generate_cid();
1607 let c = IssuedCid {
1608 path_id: PathId(1),
1609 sequence: 1,
1610 id: cid_c,
1611 reset_token: ResetToken::new(&hmac, cid_c),
1612 };
1613
1614 let mut pending_cids = PendingNewCids::default();
1615
1616 for _ in 0..9 {
1617 let mut input = vec![a, b, c];
1619 input.shuffle(&mut rand::rng());
1620 for cid in input {
1621 pending_cids.push(cid);
1622 }
1623
1624 assert_eq!(pending_cids.pop().map(|i| i.id), Some(a.id));
1626 assert_eq!(pending_cids.pop().map(|i| i.id), Some(b.id));
1627 assert_eq!(pending_cids.pop().map(|i| i.id), Some(c.id));
1628 assert!(pending_cids.pop().is_none());
1629 }
1630 }
1631}