s2n_quic_core/ack/
ranges.rs1use crate::{
5 ack::Settings,
6 frame::ack,
7 interval_set::{IntervalSet, RangeInclusiveIter},
8 packet::number::{PacketNumber, PacketNumberRange},
9 varint::VarInt,
10};
11use core::{
12 convert::TryInto,
13 num::NonZeroUsize,
14 ops::{Bound, Deref, DerefMut, RangeInclusive},
15};
16
17#[derive(Clone, Debug)]
18pub struct Ranges(IntervalSet<PacketNumber>);
19
20impl Default for Ranges {
21 #[inline]
22 fn default() -> Self {
23 Self::new(Settings::default().ack_ranges_limit as usize)
24 }
25}
26
27impl Ranges {
28 #[inline]
29 pub fn new(limit: usize) -> Self {
30 let limit = NonZeroUsize::new(limit).expect("limit should be nonzero");
31 Self(IntervalSet::with_limit(limit))
32 }
33
34 #[inline]
36 pub fn insert_packet_number_range(&mut self, pn_range: PacketNumberRange) -> Result<(), Error> {
37 let interval = (
38 Bound::Included(pn_range.start()),
39 Bound::Included(pn_range.end()),
40 );
41 if self.0.insert(interval).is_ok() {
42 return Ok(());
43 }
44
45 match self.0.pop_min() {
47 Some(min) => {
48 if min < pn_range.start() {
49 let insert_res = self.0.insert(interval);
50 debug_assert!(
51 insert_res.is_ok(),
52 "min range was removed, so it should be possible to insert another range",
53 );
54 insert_res.map_err(|_| Error::RangeInsertionFailed {
55 min: pn_range.start(),
56 max: pn_range.end(),
57 })?;
58
59 Err(Error::LowestRangeDropped {
60 min: min.start_inclusive(),
61 max: min.end_inclusive(),
62 })
63 } else {
64 let _ = self.0.insert_front(min);
66 Err(Error::RangeInsertionFailed {
67 min: pn_range.start(),
68 max: pn_range.end(),
69 })
70 }
71 }
72 None => {
73 debug_assert!(
74 false,
75 "IntervalSet should have capacity and return lowest entry"
76 );
77 Err(Error::RangeInsertionFailed {
78 min: pn_range.start(),
79 max: pn_range.end(),
80 })
81 }
82 }
83 }
84
85 #[inline]
87 pub fn insert_packet_number(&mut self, packet_number: PacketNumber) -> Result<(), Error> {
88 self.insert_packet_number_range(PacketNumberRange::new(packet_number, packet_number))
89 }
90
91 #[inline]
93 pub fn spread(&self) -> usize {
94 match (self.min_value(), self.max_value()) {
95 (Some(min), Some(max)) => {
96 let min = PacketNumber::as_varint(min);
97 let max = PacketNumber::as_varint(max);
98 (max - min).try_into().unwrap_or(usize::MAX)
99 }
100 _ => 0,
101 }
102 }
103}
104
105type Iter<'a> = core::iter::Map<
106 core::iter::Rev<RangeInclusiveIter<'a, PacketNumber>>,
107 fn(RangeInclusive<PacketNumber>) -> RangeInclusive<VarInt>,
108>;
109
110impl<'a> ack::AckRanges for &'a Ranges {
111 type Iter = Iter<'a>;
112
113 #[inline]
114 fn ack_ranges(&self) -> Self::Iter {
115 self.0.inclusive_ranges().rev().map(|range| {
116 let (start, end) = range.into_inner();
117 PacketNumber::as_varint(start)..=PacketNumber::as_varint(end)
118 })
119 }
120}
121
122impl Deref for Ranges {
123 type Target = IntervalSet<PacketNumber>;
124
125 #[inline]
126 fn deref(&self) -> &Self::Target {
127 &self.0
128 }
129}
130
131impl DerefMut for Ranges {
132 #[inline]
133 fn deref_mut(&mut self) -> &mut Self::Target {
134 &mut self.0
135 }
136}
137
138#[derive(Debug, Copy, Clone, PartialEq, Eq)]
139pub enum Error {
140 RangeInsertionFailed {
141 min: PacketNumber,
142 max: PacketNumber,
143 },
144 LowestRangeDropped {
145 min: PacketNumber,
146 max: PacketNumber,
147 },
148}
149
150#[cfg(test)]
151mod tests {
152 use super::*;
153 use crate::{
154 packet::number::{testing::iter as packet_numbers_iter, PacketNumberSpace},
155 varint,
156 };
157 use bolero::check;
158
159 #[test]
160 fn insert_value_test() {
161 let mut ack_ranges = Ranges::new(3);
162 let mut packet_numbers = packet_numbers_iter(PacketNumberSpace::ApplicationData).step_by(2); let pn_a = packet_numbers.next().unwrap();
166 assert!(ack_ranges.insert_packet_number(pn_a).is_ok());
167
168 let pn_b = packet_numbers.next().unwrap();
169 assert!(ack_ranges.insert_packet_number(pn_b).is_ok());
170
171 let pn_c = packet_numbers.next().unwrap();
172 assert!(ack_ranges.insert_packet_number(pn_c).is_ok());
173
174 assert_eq!(ack_ranges.interval_len(), 3);
176 assert!(ack_ranges.contains(&pn_a));
177 assert!(ack_ranges.contains(&pn_b));
178 assert!(ack_ranges.contains(&pn_c));
179
180 let pn_d = packet_numbers.next().unwrap();
182 assert_eq!(
183 ack_ranges.insert_packet_number(pn_d).err().unwrap(),
184 Error::LowestRangeDropped {
185 min: pn_a,
186 max: pn_a
187 }
188 );
189
190 assert_eq!(ack_ranges.interval_len(), 3);
192 assert!(!ack_ranges.contains(&pn_a));
193 assert!(ack_ranges.contains(&pn_b));
194 assert!(ack_ranges.contains(&pn_c));
195 assert!(ack_ranges.contains(&pn_d));
196
197 assert_eq!(
199 ack_ranges.insert_packet_number(pn_a).err().unwrap(),
200 Error::RangeInsertionFailed {
201 min: pn_a,
202 max: pn_a
203 }
204 );
205 assert_eq!(ack_ranges.interval_len(), 3);
206 assert!(!ack_ranges.contains(&pn_a));
207 assert!(ack_ranges.contains(&pn_b));
208 assert!(ack_ranges.contains(&pn_c));
209 assert!(ack_ranges.contains(&pn_d));
210 }
211
212 #[test]
213 fn overlapping_range_test() {
214 let mut packet_numbers = packet_numbers_iter(PacketNumberSpace::ApplicationData).step_by(2); let mut ack_ranges = Ranges::new(3);
216
217 let pn_a = packet_numbers.next().unwrap();
226 let pn_b = packet_numbers.next().unwrap();
227 let pn_c = packet_numbers.next().unwrap();
228 let pn_d = packet_numbers.next().unwrap();
229 let pn_e = packet_numbers.next().unwrap();
230 let pn_f = packet_numbers.next().unwrap();
231 let pn_g = packet_numbers.next().unwrap();
232 let pn_h = packet_numbers.next().unwrap();
233 let pn_i = packet_numbers.next().unwrap();
234 let range_0 = PacketNumberRange::new(pn_a, pn_a);
235 let range_1 = PacketNumberRange::new(pn_b, pn_c);
236 let range_2 = PacketNumberRange::new(pn_d, pn_f);
237 let range_3 = PacketNumberRange::new(pn_g, pn_h);
238 let range_4 = PacketNumberRange::new(pn_h, pn_i);
239 let range_0_1 = PacketNumberRange::new(pn_a, pn_c);
240 let range_1_2 = PacketNumberRange::new(pn_c, pn_e);
241
242 assert!(ack_ranges.insert_packet_number_range(range_1).is_ok());
243 assert!(ack_ranges.insert_packet_number_range(range_2).is_ok());
244 assert!(ack_ranges.insert_packet_number_range(range_3).is_ok());
245 assert_eq!(ack_ranges.interval_len(), 3);
246
247 for pn in range_1 {
248 assert!(ack_ranges.contains(&pn));
249 }
250 for pn in range_2 {
251 assert!(ack_ranges.contains(&pn));
252 }
253 for pn in range_3 {
254 assert!(ack_ranges.contains(&pn));
255 }
256
257 assert!(ack_ranges.insert_packet_number_range(range_1_2).is_ok());
259 assert_eq!(ack_ranges.interval_len(), 2);
260
261 assert!(ack_ranges.insert_packet_number_range(range_0).is_ok());
263 assert_eq!(ack_ranges.interval_len(), 3);
264
265 assert!(ack_ranges.insert_packet_number_range(range_0_1).is_ok());
267 assert_eq!(ack_ranges.interval_len(), 2);
268
269 assert!(ack_ranges.insert_packet_number_range(range_4).is_ok());
271 assert_eq!(ack_ranges.interval_len(), 2);
272 }
273
274 #[test]
275 fn large_range_test() {
276 let pn_a = PacketNumberSpace::ApplicationData.new_packet_number(VarInt::from_u32(1));
277 let pn_b = PacketNumberSpace::ApplicationData
278 .new_packet_number(VarInt::new(varint::MAX_VARINT_VALUE).unwrap());
279 let mut ack_ranges = Ranges::new(3);
280
281 let range_1 = PacketNumberRange::new(pn_a, pn_b);
282
283 assert!(ack_ranges.insert_packet_number_range(range_1).is_ok());
284 assert_eq!(ack_ranges.interval_len(), 1);
285 }
286
287 #[test]
288 #[cfg_attr(miri, ignore)]
289 #[cfg(target_pointer_width = "64")]
290 fn size_of_snapshots() {
291 use core::mem::size_of;
292 use insta::assert_debug_snapshot;
293
294 assert_debug_snapshot!("Ranges", size_of::<Ranges>());
295 }
296
297 #[test]
298 fn insert_packet_number_range_fuzz() {
299 check!()
300 .with_type::<(u32, u32)>()
301 .map(|(a, b)| (a.min(b), a.max(b))) .for_each(|(a, b)| {
303 let mut ack_ranges = Ranges::new(1);
304
305 let pn_a = PacketNumberSpace::Initial.new_packet_number(VarInt::from_u32(*a));
306 let pn_b = PacketNumberSpace::Initial.new_packet_number(VarInt::from_u32(*b));
307 let range_1 = PacketNumberRange::new(pn_a, pn_b);
308
309 assert!(ack_ranges.insert_packet_number_range(range_1).is_ok());
310 });
311 }
312}