1use std::{
2 cmp,
3 collections::{BTreeMap, VecDeque},
4 mem,
5 ops::{Bound, Index, IndexMut},
6};
7
8use rand::Rng;
9use rustc_hash::FxHashSet;
10use tracing::trace;
11
12use super::assembler::Assembler;
13use crate::{
14 Dir, Duration, Instant, SocketAddr, StreamId, TransportError, VarInt, connection::StreamsState,
15 crypto::Keys, frame, packet::SpaceId, range_set::ArrayRangeSet, shared::IssuedCid,
16};
17
18pub(super) struct PacketSpace {
19 pub(super) crypto: Option<Keys>,
20 pub(super) dedup: Dedup,
21 pub(super) rx_packet: u64,
23
24 pub(super) pending: Retransmits,
26 pub(super) pending_acks: PendingAcks,
28
29 pub(super) next_packet_number: u64,
32 pub(super) largest_acked_packet: Option<u64>,
34 pub(super) largest_acked_packet_sent: Instant,
35 pub(super) largest_ack_eliciting_sent: u64,
37 pub(super) unacked_non_ack_eliciting_tail: u64,
39 pub(super) sent_packets: BTreeMap<u64, SentPacket>,
42 pub(super) ecn_counters: frame::EcnCounts,
44 pub(super) ecn_feedback: frame::EcnCounts,
51
52 pub(super) crypto_stream: Assembler,
54 pub(super) crypto_offset: u64,
56
57 pub(super) time_of_last_ack_eliciting_packet: Option<Instant>,
59 pub(super) loss_time: Option<Instant>,
63 pub(super) loss_probes: u32,
65 pub(super) ping_pending: bool,
66 pub(super) immediate_ack_pending: bool,
67 pub(super) in_flight: u64,
69 pub(super) sent_with_keys: u64,
71}
72
73impl PacketSpace {
74 pub(super) fn new(now: Instant) -> Self {
75 Self {
76 crypto: None,
77 dedup: Dedup::new(),
78 rx_packet: 0,
79
80 pending: Retransmits::default(),
81 pending_acks: PendingAcks::new(),
82
83 next_packet_number: 0,
84 largest_acked_packet: None,
85 largest_acked_packet_sent: now,
86 largest_ack_eliciting_sent: 0,
87 unacked_non_ack_eliciting_tail: 0,
88 sent_packets: BTreeMap::new(),
89 ecn_counters: frame::EcnCounts::ZERO,
90 ecn_feedback: frame::EcnCounts::ZERO,
91
92 crypto_stream: Assembler::new(),
93 crypto_offset: 0,
94
95 time_of_last_ack_eliciting_packet: None,
96 loss_time: None,
97 loss_probes: 0,
98 ping_pending: false,
99 immediate_ack_pending: false,
100 in_flight: 0,
101 sent_with_keys: 0,
102 }
103 }
104
105 pub(super) fn maybe_queue_probe(
118 &mut self,
119 request_immediate_ack: bool,
120 streams: &StreamsState,
121 ) {
122 if self.loss_probes == 0 {
123 return;
124 }
125
126 if request_immediate_ack {
127 self.immediate_ack_pending = true;
130 }
131
132 if !self.pending.is_empty(streams) {
133 return;
135 }
136
137 for packet in self.sent_packets.values_mut() {
139 if !packet.retransmits.is_empty(streams) {
140 self.pending |= mem::take(&mut packet.retransmits);
143 return;
144 }
145 }
146
147 if !self.immediate_ack_pending {
151 self.ping_pending = true;
152 }
153 }
154
155 pub(super) fn get_tx_number(&mut self) -> u64 {
160 assert!(self.next_packet_number < 2u64.pow(62));
162 let x = self.next_packet_number;
163 self.next_packet_number += 1;
164 self.sent_with_keys += 1;
165 x
166 }
167
168 pub(super) fn can_send(&self, streams: &StreamsState) -> SendableFrames {
169 let acks = self.pending_acks.can_send();
170 let other =
171 !self.pending.is_empty(streams) || self.ping_pending || self.immediate_ack_pending;
172
173 SendableFrames { acks, other }
174 }
175
176 pub(super) fn detect_ecn(
178 &mut self,
179 newly_acked: u64,
180 ecn: frame::EcnCounts,
181 ) -> Result<bool, &'static str> {
182 let ect0_increase = ecn
183 .ect0
184 .checked_sub(self.ecn_feedback.ect0)
185 .ok_or("peer ECT(0) count regression")?;
186 let ect1_increase = ecn
187 .ect1
188 .checked_sub(self.ecn_feedback.ect1)
189 .ok_or("peer ECT(1) count regression")?;
190 let ce_increase = ecn
191 .ce
192 .checked_sub(self.ecn_feedback.ce)
193 .ok_or("peer CE count regression")?;
194 let total_increase = ect0_increase + ect1_increase + ce_increase;
195 if total_increase < newly_acked {
196 return Err("ECN bleaching");
197 }
198 if (ect0_increase + ce_increase) < newly_acked || ect1_increase != 0 {
199 return Err("ECN corruption");
200 }
201 self.ecn_feedback = ecn;
206 Ok(ce_increase != 0)
207 }
208
209 pub(super) fn take(&mut self, number: u64) -> Option<SentPacket> {
211 let packet = self.sent_packets.remove(&number)?;
212 self.in_flight -= u64::from(packet.size);
213 if !packet.ack_eliciting && number > self.largest_ack_eliciting_sent {
214 self.unacked_non_ack_eliciting_tail =
215 self.unacked_non_ack_eliciting_tail.checked_sub(1).unwrap();
216 }
217 Some(packet)
218 }
219
220 pub(super) fn sent(&mut self, number: u64, packet: SentPacket) -> u64 {
222 const MAX_UNACKED_NON_ACK_ELICTING_TAIL: u64 = 1_000;
229
230 let mut forgotten_bytes = 0;
231 if packet.ack_eliciting {
232 self.unacked_non_ack_eliciting_tail = 0;
233 self.largest_ack_eliciting_sent = number;
234 } else if self.unacked_non_ack_eliciting_tail > MAX_UNACKED_NON_ACK_ELICTING_TAIL {
235 let oldest_after_ack_eliciting = *self
236 .sent_packets
237 .range((
238 Bound::Excluded(self.largest_ack_eliciting_sent),
239 Bound::Unbounded,
240 ))
241 .next()
242 .unwrap()
243 .0;
244 let packet = self
249 .sent_packets
250 .remove(&oldest_after_ack_eliciting)
251 .unwrap();
252 forgotten_bytes = u64::from(packet.size);
253 self.in_flight -= forgotten_bytes;
254 } else {
255 self.unacked_non_ack_eliciting_tail += 1;
256 }
257
258 self.in_flight += u64::from(packet.size);
259 self.sent_packets.insert(number, packet);
260 forgotten_bytes
261 }
262}
263
264impl Index<SpaceId> for [PacketSpace; 3] {
265 type Output = PacketSpace;
266 fn index(&self, space: SpaceId) -> &PacketSpace {
267 &self.as_ref()[space as usize]
268 }
269}
270
271impl IndexMut<SpaceId> for [PacketSpace; 3] {
272 fn index_mut(&mut self, space: SpaceId) -> &mut PacketSpace {
273 &mut self.as_mut()[space as usize]
274 }
275}
276
277#[derive(Debug, Clone)]
279pub(super) struct SentPacket {
280 pub(super) time_sent: Instant,
282 pub(super) size: u16,
286 pub(super) ack_eliciting: bool,
288 pub(super) largest_acked: Option<u64>,
290 pub(super) retransmits: ThinRetransmits,
294 pub(super) stream_frames: frame::StreamMetaVec,
298}
299
300#[derive(Debug, Default, Clone)]
302pub struct Retransmits {
303 pub(super) max_data: bool,
304 pub(super) max_stream_id: [bool; 2],
305 pub(super) reset_stream: Vec<(StreamId, VarInt)>,
306 pub(super) stop_sending: Vec<frame::StopSending>,
307 pub(super) max_stream_data: FxHashSet<StreamId>,
308 pub(super) crypto: VecDeque<frame::Crypto>,
309 pub(super) new_cids: Vec<IssuedCid>,
310 pub(super) retire_cids: Vec<u64>,
311 pub(super) ack_frequency: bool,
312 pub(super) handshake_done: bool,
313 pub(super) new_tokens: Vec<SocketAddr>,
330 pub(super) add_addresses: Vec<frame::AddAddress>,
332 pub(super) punch_me_now: Vec<frame::PunchMeNow>,
334 pub(super) remove_addresses: Vec<frame::RemoveAddress>,
336 pub(super) observed_addresses: Vec<frame::ObservedAddress>,
338}
339
340impl Retransmits {
341 pub(super) fn is_empty(&self, streams: &StreamsState) -> bool {
342 !self.max_data
343 && !self.max_stream_id.into_iter().any(|x| x)
344 && self.reset_stream.is_empty()
345 && self.stop_sending.is_empty()
346 && self
347 .max_stream_data
348 .iter()
349 .all(|&id| !streams.can_send_flow_control(id))
350 && self.crypto.is_empty()
351 && self.new_cids.is_empty()
352 && self.retire_cids.is_empty()
353 && !self.ack_frequency
354 && !self.handshake_done
355 && self.new_tokens.is_empty()
356 && self.add_addresses.is_empty()
357 && self.punch_me_now.is_empty()
358 && self.remove_addresses.is_empty()
359 && self.observed_addresses.is_empty()
360 }
361}
362
363impl ::std::ops::BitOrAssign for Retransmits {
364 fn bitor_assign(&mut self, rhs: Self) {
365 self.max_data |= rhs.max_data;
368 for dir in Dir::iter() {
369 self.max_stream_id[dir as usize] |= rhs.max_stream_id[dir as usize];
370 }
371 self.reset_stream.extend_from_slice(&rhs.reset_stream);
372 self.stop_sending.extend_from_slice(&rhs.stop_sending);
373 self.max_stream_data.extend(&rhs.max_stream_data);
374 for crypto in rhs.crypto.into_iter().rev() {
375 self.crypto.push_front(crypto);
376 }
377 self.new_cids.extend(&rhs.new_cids);
378 self.retire_cids.extend(rhs.retire_cids);
379 self.ack_frequency |= rhs.ack_frequency;
380 self.handshake_done |= rhs.handshake_done;
381 self.new_tokens.extend_from_slice(&rhs.new_tokens);
382 self.add_addresses.extend_from_slice(&rhs.add_addresses);
383 self.punch_me_now.extend_from_slice(&rhs.punch_me_now);
384 self.remove_addresses
385 .extend_from_slice(&rhs.remove_addresses);
386 self.observed_addresses
387 .extend_from_slice(&rhs.observed_addresses);
388 }
389}
390
391impl ::std::ops::BitOrAssign<ThinRetransmits> for Retransmits {
392 fn bitor_assign(&mut self, rhs: ThinRetransmits) {
393 if let Some(retransmits) = rhs.retransmits {
394 self.bitor_assign(*retransmits)
395 }
396 }
397}
398
399impl ::std::iter::FromIterator<Self> for Retransmits {
400 fn from_iter<T>(iter: T) -> Self
401 where
402 T: IntoIterator<Item = Self>,
403 {
404 let mut result = Self::default();
405 for packet in iter {
406 result |= packet;
407 }
408 result
409 }
410}
411
412#[derive(Debug, Default, Clone)]
414pub(super) struct ThinRetransmits {
415 retransmits: Option<Box<Retransmits>>,
416}
417
418impl ThinRetransmits {
419 pub(super) fn is_empty(&self, streams: &StreamsState) -> bool {
421 match &self.retransmits {
422 Some(retransmits) => retransmits.is_empty(streams),
423 None => true,
424 }
425 }
426
427 pub(super) fn get(&self) -> Option<&Retransmits> {
429 self.retransmits.as_deref()
430 }
431
432 pub(super) fn get_or_create(&mut self) -> &mut Retransmits {
436 if self.retransmits.is_none() {
437 self.retransmits = Some(Box::default());
438 }
439 self.retransmits.as_deref_mut().unwrap()
440 }
441}
442
443pub(super) struct Dedup {
455 window: Window,
456 next: u64,
458}
459
460type Window = u128;
465
466const WINDOW_SIZE: u64 = 1 + mem::size_of::<Window>() as u64 * 8;
468
469impl Dedup {
470 pub(super) fn new() -> Self {
472 Self { window: 0, next: 0 }
473 }
474
475 fn highest(&self) -> u64 {
477 self.next - 1
478 }
479
480 pub(super) fn insert(&mut self, packet: u64) -> bool {
484 if let Some(diff) = packet.checked_sub(self.next) {
485 self.window = ((self.window << 1) | 1)
487 .checked_shl(cmp::min(diff, u64::from(u32::MAX)) as u32)
488 .unwrap_or(0);
489 self.next = packet + 1;
490 false
491 } else if self.highest() - packet < WINDOW_SIZE {
492 if let Some(bit) = (self.highest() - packet).checked_sub(1) {
494 let mask = 1 << bit;
496 let duplicate = self.window & mask != 0;
497 self.window |= mask;
498 duplicate
499 } else {
500 true
502 }
503 } else {
504 true
506 }
507 }
508
509 fn smallest_missing_in_interval(&self, lower_bound: u64, upper_bound: u64) -> Option<u64> {
513 debug_assert!(lower_bound <= upper_bound);
514 debug_assert!(upper_bound <= self.highest());
515 const BITFIELD_SIZE: u64 = (mem::size_of::<Window>() * 8) as u64;
516
517 let lower_bound = lower_bound + 1;
521 let upper_bound = upper_bound.saturating_sub(1);
522
523 let start_offset = (self.highest() - upper_bound).max(1) - 1;
526 if start_offset >= BITFIELD_SIZE {
527 return None;
530 }
531
532 let end_offset_exclusive = self.highest().saturating_sub(lower_bound);
533
534 let range_len = end_offset_exclusive
537 .saturating_sub(start_offset)
538 .min(BITFIELD_SIZE);
539 if range_len == 0 {
540 return None;
541 }
542
543 let mask = if range_len == BITFIELD_SIZE {
546 u128::MAX
547 } else {
548 ((1u128 << range_len) - 1) << start_offset
549 };
550 let gaps = !self.window & mask;
551
552 let smallest_missing_offset = 128 - gaps.leading_zeros() as u64;
553 let smallest_missing_packet = self.highest() - smallest_missing_offset;
554
555 if smallest_missing_packet <= upper_bound {
556 Some(smallest_missing_packet)
557 } else {
558 None
559 }
560 }
561
562 fn missing_in_interval(&self, lower_bound: u64, upper_bound: u64) -> bool {
566 self.smallest_missing_in_interval(lower_bound, upper_bound)
567 .is_some()
568 }
569}
570
571#[derive(Clone, Copy, PartialEq, Eq, Debug)]
573pub(super) struct SendableFrames {
574 pub(super) acks: bool,
575 pub(super) other: bool,
576}
577
578impl SendableFrames {
579 pub(super) fn empty() -> Self {
581 Self {
582 acks: false,
583 other: false,
584 }
585 }
586
587 pub(super) fn is_empty(&self) -> bool {
589 !self.acks && !self.other
590 }
591}
592
593#[derive(Debug)]
594pub(super) struct PendingAcks {
595 immediate_ack_required: bool,
600 ack_eliciting_since_last_ack_sent: u64,
604 non_ack_eliciting_since_last_ack_sent: u64,
605 ack_eliciting_threshold: u64,
606 reordering_threshold: u64,
614 earliest_ack_eliciting_since_last_ack_sent: Option<Instant>,
617 ranges: ArrayRangeSet,
620 largest_packet: Option<(u64, Instant)>,
623 largest_ack_eliciting_packet: Option<u64>,
625 largest_acked: Option<u64>,
627}
628
629impl PendingAcks {
630 fn new() -> Self {
631 Self {
632 immediate_ack_required: false,
633 ack_eliciting_since_last_ack_sent: 0,
634 non_ack_eliciting_since_last_ack_sent: 0,
635 ack_eliciting_threshold: 1,
636 reordering_threshold: 1,
637 earliest_ack_eliciting_since_last_ack_sent: None,
638 ranges: ArrayRangeSet::default(),
639 largest_packet: None,
640 largest_ack_eliciting_packet: None,
641 largest_acked: None,
642 }
643 }
644
645 pub(super) fn set_ack_frequency_params(&mut self, frame: &frame::AckFrequency) {
646 self.ack_eliciting_threshold = frame.ack_eliciting_threshold.into_inner();
647 self.reordering_threshold = frame.reordering_threshold.into_inner();
648 }
649
650 pub(super) fn set_immediate_ack_required(&mut self) {
651 self.immediate_ack_required = true;
652 }
653
654 pub(super) fn on_max_ack_delay_timeout(&mut self) {
655 self.immediate_ack_required = self.ack_eliciting_since_last_ack_sent > 0;
656 }
657
658 pub(super) fn max_ack_delay_timeout(&self, max_ack_delay: Duration) -> Option<Instant> {
659 self.earliest_ack_eliciting_since_last_ack_sent
660 .map(|earliest_unacked| earliest_unacked + max_ack_delay)
661 }
662
663 pub(super) fn can_send(&self) -> bool {
665 self.immediate_ack_required && !self.ranges.is_empty()
666 }
667
668 pub(super) fn ack_delay(&self, now: Instant) -> Duration {
670 self.largest_packet
671 .map_or(Duration::default(), |(_, received)| now - received)
672 }
673
674 pub(super) fn packet_received(
678 &mut self,
679 now: Instant,
680 packet_number: u64,
681 ack_eliciting: bool,
682 dedup: &Dedup,
683 ) -> bool {
684 if !ack_eliciting {
685 self.non_ack_eliciting_since_last_ack_sent += 1;
686 return false;
687 }
688
689 let prev_largest_ack_eliciting = self.largest_ack_eliciting_packet.unwrap_or(0);
690
691 self.largest_ack_eliciting_packet = self
693 .largest_ack_eliciting_packet
694 .map(|pn| pn.max(packet_number))
695 .or(Some(packet_number));
696
697 self.ack_eliciting_since_last_ack_sent += 1;
699 self.immediate_ack_required |=
700 self.ack_eliciting_since_last_ack_sent > self.ack_eliciting_threshold;
701
702 self.immediate_ack_required |=
704 self.is_out_of_order(packet_number, prev_largest_ack_eliciting, dedup);
705
706 if self.earliest_ack_eliciting_since_last_ack_sent.is_none() && !self.can_send() {
708 self.earliest_ack_eliciting_since_last_ack_sent = Some(now);
709 return true;
710 }
711
712 false
713 }
714
715 fn is_out_of_order(
716 &self,
717 packet_number: u64,
718 prev_largest_ack_eliciting: u64,
719 dedup: &Dedup,
720 ) -> bool {
721 match self.reordering_threshold {
722 0 => false,
723 1 => {
724 packet_number < prev_largest_ack_eliciting
726 || dedup.missing_in_interval(prev_largest_ack_eliciting, packet_number)
727 }
728 _ => {
729 let Some((largest_acked, largest_unacked)) =
732 self.largest_acked.zip(self.largest_ack_eliciting_packet)
733 else {
734 return false;
735 };
736 if self.reordering_threshold > largest_acked {
737 return false;
738 }
739 let largest_reported = largest_acked - self.reordering_threshold + 1;
742 let Some(smallest_missing_unreported) =
743 dedup.smallest_missing_in_interval(largest_reported, largest_unacked)
744 else {
745 return false;
746 };
747 largest_unacked - smallest_missing_unreported >= self.reordering_threshold
748 }
749 }
750 }
751
752 pub(super) fn acks_sent(&mut self) {
756 self.immediate_ack_required = false;
766 self.ack_eliciting_since_last_ack_sent = 0;
767 self.non_ack_eliciting_since_last_ack_sent = 0;
768 self.earliest_ack_eliciting_since_last_ack_sent = None;
769 self.largest_acked = self.largest_ack_eliciting_packet;
770 }
771
772 pub(super) fn insert_one(&mut self, packet: u64, now: Instant) {
774 self.ranges.insert_one(packet);
775
776 if self.largest_packet.is_none_or(|(pn, _)| packet > pn) {
777 self.largest_packet = Some((packet, now));
778 }
779
780 if self.ranges.len() > MAX_ACK_BLOCKS {
781 self.ranges.pop_min();
782 }
783 }
784
785 pub(super) fn subtract_below(&mut self, max: u64) {
787 self.ranges.remove(0..(max + 1));
788 }
789
790 pub(super) fn ranges(&self) -> &ArrayRangeSet {
792 &self.ranges
793 }
794
795 pub(super) fn maybe_ack_non_eliciting(&mut self) {
801 const LAZY_ACK_THRESHOLD: u64 = 10;
806 if self.non_ack_eliciting_since_last_ack_sent > LAZY_ACK_THRESHOLD {
807 self.immediate_ack_required = true;
808 }
809 }
810}
811
812pub(super) struct PacketNumberFilter {
829 next_skipped_packet_number: u64,
831 prev_skipped_packet_number: Option<u64>,
833 exponent: u32,
835}
836
837impl PacketNumberFilter {
838 pub(super) fn new(rng: &mut (impl Rng + ?Sized)) -> Self {
839 let exponent = 6;
841 Self {
842 next_skipped_packet_number: rng.gen_range(0..2u64.saturating_pow(exponent)),
843 prev_skipped_packet_number: None,
844 exponent,
845 }
846 }
847
848 #[cfg(test)]
849 pub(super) fn disabled() -> Self {
850 Self {
851 next_skipped_packet_number: u64::MAX,
852 prev_skipped_packet_number: None,
853 exponent: u32::MAX,
854 }
855 }
856
857 pub(super) fn peek(&self, space: &PacketSpace) -> u64 {
858 let n = space.next_packet_number;
859 if n != self.next_skipped_packet_number {
860 return n;
861 }
862 n + 1
863 }
864
865 pub(super) fn allocate(
866 &mut self,
867 rng: &mut (impl Rng + ?Sized),
868 space: &mut PacketSpace,
869 ) -> u64 {
870 let n = space.get_tx_number();
871 if n != self.next_skipped_packet_number {
872 return n;
873 }
874
875 trace!("skipping pn {n}");
876 self.prev_skipped_packet_number = Some(self.next_skipped_packet_number);
878 let next_exponent = self.exponent.saturating_add(1);
879 self.next_skipped_packet_number =
880 rng.gen_range(2u64.saturating_pow(self.exponent)..2u64.saturating_pow(next_exponent));
881 self.exponent = next_exponent;
882
883 space.get_tx_number()
884 }
885
886 pub(super) fn check_ack(
887 &self,
888 space_id: SpaceId,
889 range: std::ops::RangeInclusive<u64>,
890 ) -> Result<(), TransportError> {
891 if space_id == SpaceId::Data
892 && self
893 .prev_skipped_packet_number
894 .is_some_and(|x| range.contains(&x))
895 {
896 return Err(TransportError::PROTOCOL_VIOLATION("unsent packet acked"));
897 }
898 Ok(())
899 }
900}
901
902const MAX_ACK_BLOCKS: usize = 64;
904
905#[cfg(test)]
906mod test {
907 use super::*;
908
909 #[test]
910 fn sanity() {
911 let mut dedup = Dedup::new();
912 assert!(!dedup.insert(0));
913 assert_eq!(dedup.next, 1);
914 assert_eq!(dedup.window, 0b1);
915 assert!(dedup.insert(0));
916 assert_eq!(dedup.next, 1);
917 assert_eq!(dedup.window, 0b1);
918 assert!(!dedup.insert(1));
919 assert_eq!(dedup.next, 2);
920 assert_eq!(dedup.window, 0b11);
921 assert!(!dedup.insert(2));
922 assert_eq!(dedup.next, 3);
923 assert_eq!(dedup.window, 0b111);
924 assert!(!dedup.insert(4));
925 assert_eq!(dedup.next, 5);
926 assert_eq!(dedup.window, 0b11110);
927 assert!(!dedup.insert(7));
928 assert_eq!(dedup.next, 8);
929 assert_eq!(dedup.window, 0b1111_0100);
930 assert!(dedup.insert(4));
931 assert!(!dedup.insert(3));
932 assert_eq!(dedup.next, 8);
933 assert_eq!(dedup.window, 0b1111_1100);
934 assert!(!dedup.insert(6));
935 assert_eq!(dedup.next, 8);
936 assert_eq!(dedup.window, 0b1111_1101);
937 assert!(!dedup.insert(5));
938 assert_eq!(dedup.next, 8);
939 assert_eq!(dedup.window, 0b1111_1111);
940 }
941
942 #[test]
943 fn happypath() {
944 let mut dedup = Dedup::new();
945 for i in 0..(2 * WINDOW_SIZE) {
946 assert!(!dedup.insert(i));
947 for j in 0..=i {
948 assert!(dedup.insert(j));
949 }
950 }
951 }
952
953 #[test]
954 fn jump() {
955 let mut dedup = Dedup::new();
956 dedup.insert(2 * WINDOW_SIZE);
957 assert!(dedup.insert(WINDOW_SIZE));
958 assert_eq!(dedup.next, 2 * WINDOW_SIZE + 1);
959 assert_eq!(dedup.window, 0);
960 assert!(!dedup.insert(WINDOW_SIZE + 1));
961 assert_eq!(dedup.next, 2 * WINDOW_SIZE + 1);
962 assert_eq!(dedup.window, 1 << (WINDOW_SIZE - 2));
963 }
964
965 #[test]
966 fn dedup_has_missing() {
967 let mut dedup = Dedup::new();
968
969 dedup.insert(0);
970 assert!(!dedup.missing_in_interval(0, 0));
971
972 dedup.insert(1);
973 assert!(!dedup.missing_in_interval(0, 1));
974
975 dedup.insert(3);
976 assert!(dedup.missing_in_interval(1, 3));
977
978 dedup.insert(4);
979 assert!(!dedup.missing_in_interval(3, 4));
980 assert!(dedup.missing_in_interval(0, 4));
981
982 dedup.insert(2);
983 assert!(!dedup.missing_in_interval(0, 4));
984 }
985
986 #[test]
987 fn dedup_outside_of_window_has_missing() {
988 let mut dedup = Dedup::new();
989
990 for i in 0..140 {
991 dedup.insert(i);
992 }
993
994 assert!(!dedup.missing_in_interval(0, 4));
996 dedup.insert(160);
997 assert!(!dedup.missing_in_interval(0, 4));
998 assert!(!dedup.missing_in_interval(0, 140));
999 assert!(dedup.missing_in_interval(0, 160));
1000 }
1001
1002 #[test]
1003 fn dedup_smallest_missing() {
1004 let mut dedup = Dedup::new();
1005
1006 dedup.insert(0);
1007 assert_eq!(dedup.smallest_missing_in_interval(0, 0), None);
1008
1009 dedup.insert(1);
1010 assert_eq!(dedup.smallest_missing_in_interval(0, 1), None);
1011
1012 dedup.insert(5);
1013 dedup.insert(7);
1014 assert_eq!(dedup.smallest_missing_in_interval(0, 7), Some(2));
1015 assert_eq!(dedup.smallest_missing_in_interval(5, 7), Some(6));
1016
1017 dedup.insert(2);
1018 assert_eq!(dedup.smallest_missing_in_interval(1, 7), Some(3));
1019
1020 dedup.insert(170);
1021 dedup.insert(172);
1022 dedup.insert(300);
1023 assert_eq!(dedup.smallest_missing_in_interval(170, 172), None);
1024
1025 dedup.insert(500);
1026 assert_eq!(dedup.smallest_missing_in_interval(0, 500), Some(372));
1027 assert_eq!(dedup.smallest_missing_in_interval(0, 373), Some(372));
1028 assert_eq!(dedup.smallest_missing_in_interval(0, 372), None);
1029 }
1030
1031 #[test]
1032 fn pending_acks_first_packet_is_not_considered_reordered() {
1033 let mut acks = PendingAcks::new();
1034 let mut dedup = Dedup::new();
1035 dedup.insert(0);
1036 acks.packet_received(Instant::now(), 0, true, &dedup);
1037 assert!(!acks.immediate_ack_required);
1038 }
1039
1040 #[test]
1041 fn pending_acks_after_immediate_ack_set() {
1042 let mut acks = PendingAcks::new();
1043 let mut dedup = Dedup::new();
1044
1045 dedup.insert(0);
1047 let now = Instant::now();
1048 acks.insert_one(0, now);
1049 acks.packet_received(now, 0, true, &dedup);
1050
1051 assert!(!acks.ranges.is_empty());
1053 assert!(!acks.can_send());
1054
1055 acks.set_immediate_ack_required();
1057 assert!(acks.can_send());
1058 }
1059
1060 #[test]
1061 fn pending_acks_ack_delay() {
1062 let mut acks = PendingAcks::new();
1063 let mut dedup = Dedup::new();
1064
1065 let t1 = Instant::now();
1066 let t2 = t1 + Duration::from_millis(2);
1067 let t3 = t2 + Duration::from_millis(5);
1068 assert_eq!(acks.ack_delay(t1), Duration::from_millis(0));
1069 assert_eq!(acks.ack_delay(t2), Duration::from_millis(0));
1070 assert_eq!(acks.ack_delay(t3), Duration::from_millis(0));
1071
1072 dedup.insert(0);
1074 acks.insert_one(0, t1);
1075 acks.packet_received(t1, 0, true, &dedup);
1076 assert_eq!(acks.ack_delay(t1), Duration::from_millis(0));
1077 assert_eq!(acks.ack_delay(t2), Duration::from_millis(2));
1078 assert_eq!(acks.ack_delay(t3), Duration::from_millis(7));
1079
1080 dedup.insert(3);
1082 acks.insert_one(3, t2);
1083 acks.packet_received(t2, 3, true, &dedup);
1084 assert_eq!(acks.ack_delay(t2), Duration::from_millis(0));
1085 assert_eq!(acks.ack_delay(t3), Duration::from_millis(5));
1086
1087 dedup.insert(2);
1089 acks.insert_one(2, t3);
1090 acks.packet_received(t3, 2, true, &dedup);
1091 assert_eq!(acks.ack_delay(t3), Duration::from_millis(5));
1092 }
1093
1094 #[test]
1095 fn sent_packet_size() {
1096 assert!(std::mem::size_of::<SentPacket>() <= 128);
1099 }
1100}