Skip to main content

net_wire/quic/frame/
ack.rs

1//! RFC 9000 ACK and ACK_ECN frame parsing.
2
3use core::iter::FusedIterator;
4
5use super::super::varint::QuicVarInt;
6use super::parse::{QuicFrameField, QuicFrameParseError};
7
8/// A checked borrowed RFC 9000 ACK or ACK_ECN frame view.
9#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10pub struct QuicAckFrame<'a> {
11    bytes: &'a [u8],
12    frame_type: QuicVarInt<'a>,
13    largest_acknowledged: QuicVarInt<'a>,
14    ack_delay: QuicVarInt<'a>,
15    ack_range_count: QuicVarInt<'a>,
16    first_ack_range: QuicVarInt<'a>,
17    first_smallest_acknowledged: u64,
18    ranges: &'a [u8],
19    ranges_offset: usize,
20    ecn_counts: Option<QuicEcnCounts<'a>>,
21}
22
23impl<'a> QuicAckFrame<'a> {
24    /// Returns the exact encoded frame bytes.
25    pub const fn as_bytes(self) -> &'a [u8] {
26        self.bytes
27    }
28
29    /// Returns the exact encoded frame-type variable integer.
30    pub const fn frame_type(self) -> QuicVarInt<'a> {
31        self.frame_type
32    }
33
34    /// Returns the exact encoded largest-acknowledged variable integer.
35    pub const fn largest_acknowledged(self) -> QuicVarInt<'a> {
36        self.largest_acknowledged
37    }
38
39    /// Returns the exact encoded ACK-delay variable integer.
40    pub const fn ack_delay(self) -> QuicVarInt<'a> {
41        self.ack_delay
42    }
43
44    /// Returns the exact encoded additional ACK-range count variable integer.
45    pub const fn ack_range_count(self) -> QuicVarInt<'a> {
46        self.ack_range_count
47    }
48
49    /// Returns the exact encoded first ACK-range variable integer.
50    pub const fn first_ack_range(self) -> QuicVarInt<'a> {
51        self.first_ack_range
52    }
53
54    /// Returns the decoded smallest packet number in the first ACK range.
55    pub const fn first_smallest_acknowledged(self) -> u64 {
56        self.first_smallest_acknowledged
57    }
58
59    /// Returns a fresh iterator over additional ACK ranges in wire order.
60    pub const fn ranges(self) -> QuicAckRanges<'a> {
61        QuicAckRanges {
62            remaining: self.ranges,
63            remaining_count: self.ack_range_count.value(),
64            previous_smallest: self.first_smallest_acknowledged,
65            offset: self.ranges_offset,
66            failed: false,
67        }
68    }
69
70    /// Returns exact ECN count fields for an ACK_ECN frame.
71    pub const fn ecn_counts(self) -> Option<QuicEcnCounts<'a>> {
72        self.ecn_counts
73    }
74}
75
76/// One checked additional ACK range in an ACK or ACK_ECN frame.
77#[derive(Clone, Copy, Debug, Eq, PartialEq)]
78pub struct QuicAckRange<'a> {
79    bytes: &'a [u8],
80    gap: QuicVarInt<'a>,
81    ack_range_length: QuicVarInt<'a>,
82    largest_acknowledged: u64,
83    smallest_acknowledged: u64,
84}
85
86impl<'a> QuicAckRange<'a> {
87    /// Returns the exact encoded Gap and ACK Range Length bytes.
88    pub const fn as_bytes(self) -> &'a [u8] {
89        self.bytes
90    }
91
92    /// Returns the exact encoded Gap variable integer.
93    pub const fn gap(self) -> QuicVarInt<'a> {
94        self.gap
95    }
96
97    /// Returns the exact encoded ACK Range Length variable integer.
98    pub const fn ack_range_length(self) -> QuicVarInt<'a> {
99        self.ack_range_length
100    }
101
102    /// Returns the decoded largest packet number in this ACK range.
103    pub const fn largest_acknowledged(self) -> u64 {
104        self.largest_acknowledged
105    }
106
107    /// Returns the decoded smallest packet number in this ACK range.
108    pub const fn smallest_acknowledged(self) -> u64 {
109        self.smallest_acknowledged
110    }
111}
112
113/// A fused iterator over checked additional ACK ranges.
114#[derive(Clone, Debug)]
115pub struct QuicAckRanges<'a> {
116    remaining: &'a [u8],
117    remaining_count: u64,
118    previous_smallest: u64,
119    offset: usize,
120    failed: bool,
121}
122
123impl<'a> Iterator for QuicAckRanges<'a> {
124    type Item = QuicAckRange<'a>;
125
126    fn next(&mut self) -> Option<Self::Item> {
127        if self.failed || self.remaining_count == 0 {
128            return None;
129        }
130        let parsed = match parse_range(self.remaining, self.previous_smallest, self.offset) {
131            Ok(range) => range,
132            Err(_) => {
133                self.failed = true;
134                self.remaining_count = 0;
135                return None;
136            }
137        };
138        self.remaining = &self.remaining[parsed.bytes.len()..];
139        self.remaining_count -= 1;
140        self.previous_smallest = parsed.smallest_acknowledged;
141        self.offset += parsed.bytes.len();
142        Some(parsed)
143    }
144}
145
146impl FusedIterator for QuicAckRanges<'_> {}
147
148/// Exact ECN count fields carried by an RFC 9000 ACK_ECN frame.
149#[derive(Clone, Copy, Debug, Eq, PartialEq)]
150pub struct QuicEcnCounts<'a> {
151    bytes: &'a [u8],
152    ect0_count: QuicVarInt<'a>,
153    ect1_count: QuicVarInt<'a>,
154    ecn_ce_count: QuicVarInt<'a>,
155}
156
157impl<'a> QuicEcnCounts<'a> {
158    /// Returns the exact encoded ECN count bytes.
159    pub const fn as_bytes(self) -> &'a [u8] {
160        self.bytes
161    }
162
163    /// Returns the exact encoded ECT(0) count variable integer.
164    pub const fn ect0_count(self) -> QuicVarInt<'a> {
165        self.ect0_count
166    }
167
168    /// Returns the exact encoded ECT(1) count variable integer.
169    pub const fn ect1_count(self) -> QuicVarInt<'a> {
170        self.ect1_count
171    }
172
173    /// Returns the exact encoded ECN-CE count variable integer.
174    pub const fn ecn_ce_count(self) -> QuicVarInt<'a> {
175        self.ecn_ce_count
176    }
177}
178
179pub(super) fn parse_ack<'a>(
180    bytes: &'a [u8],
181    frame_type: QuicVarInt<'a>,
182    offset: usize,
183) -> Result<(QuicAckFrame<'a>, &'a [u8]), QuicFrameParseError> {
184    let mut cursor = frame_type.byte_len();
185    let largest_acknowledged =
186        parse_field(bytes, cursor, offset, QuicFrameField::LargestAcknowledged)?;
187    cursor += largest_acknowledged.byte_len();
188    let ack_delay = parse_field(bytes, cursor, offset, QuicFrameField::AckDelay)?;
189    cursor += ack_delay.byte_len();
190    let ack_range_count = parse_field(bytes, cursor, offset, QuicFrameField::AckRangeCount)?;
191    cursor += ack_range_count.byte_len();
192    let first_ack_range = parse_field(bytes, cursor, offset, QuicFrameField::FirstAckRange)?;
193    let first_offset = offset + cursor;
194    cursor += first_ack_range.byte_len();
195
196    let first_smallest_acknowledged = subtract(
197        largest_acknowledged.value(),
198        first_ack_range.value(),
199        0,
200        QuicFrameField::FirstAckRange,
201        first_offset,
202    )?;
203    let ranges_start = cursor;
204    let ranges_offset = offset + ranges_start;
205    let mut previous_smallest = first_smallest_acknowledged;
206    let mut remaining_count = ack_range_count.value();
207    while remaining_count != 0 {
208        let range = parse_range(&bytes[cursor..], previous_smallest, offset + cursor)?;
209        cursor += range.bytes.len();
210        previous_smallest = range.smallest_acknowledged;
211        remaining_count -= 1;
212    }
213    let ranges = &bytes[ranges_start..cursor];
214
215    let ecn_counts = if frame_type.value() == 3 {
216        let counts_start = cursor;
217        let ect0_count = parse_field(bytes, cursor, offset, QuicFrameField::Ect0Count)?;
218        cursor += ect0_count.byte_len();
219        let ect1_count = parse_field(bytes, cursor, offset, QuicFrameField::Ect1Count)?;
220        cursor += ect1_count.byte_len();
221        let ecn_ce_count = parse_field(bytes, cursor, offset, QuicFrameField::EcnCeCount)?;
222        cursor += ecn_ce_count.byte_len();
223        Some(QuicEcnCounts {
224            bytes: &bytes[counts_start..cursor],
225            ect0_count,
226            ect1_count,
227            ecn_ce_count,
228        })
229    } else {
230        None
231    };
232
233    Ok((
234        QuicAckFrame {
235            bytes: &bytes[..cursor],
236            frame_type,
237            largest_acknowledged,
238            ack_delay,
239            ack_range_count,
240            first_ack_range,
241            first_smallest_acknowledged,
242            ranges,
243            ranges_offset,
244            ecn_counts,
245        },
246        &bytes[cursor..],
247    ))
248}
249
250fn parse_range<'a>(
251    bytes: &'a [u8],
252    previous_smallest: u64,
253    offset: usize,
254) -> Result<QuicAckRange<'a>, QuicFrameParseError> {
255    let gap = parse_field(bytes, 0, offset, QuicFrameField::AckGap)?;
256    let length_start = gap.byte_len();
257    let ack_range_length =
258        parse_field(bytes, length_start, offset, QuicFrameField::AckRangeLength)?;
259    let largest_acknowledged = subtract(
260        previous_smallest,
261        gap.value(),
262        2,
263        QuicFrameField::AckGap,
264        offset,
265    )?;
266    let smallest_acknowledged = subtract(
267        largest_acknowledged,
268        ack_range_length.value(),
269        0,
270        QuicFrameField::AckRangeLength,
271        offset + length_start,
272    )?;
273    let end = length_start + ack_range_length.byte_len();
274    Ok(QuicAckRange {
275        bytes: &bytes[..end],
276        gap,
277        ack_range_length,
278        largest_acknowledged,
279        smallest_acknowledged,
280    })
281}
282
283fn parse_field<'a>(
284    bytes: &'a [u8],
285    start: usize,
286    offset: usize,
287    field: QuicFrameField,
288) -> Result<QuicVarInt<'a>, QuicFrameParseError> {
289    QuicVarInt::parse(&bytes[start..]).map_err(|error| QuicFrameParseError::Field {
290        field,
291        offset: offset + start,
292        error,
293    })
294}
295
296fn subtract(
297    base: u64,
298    value: u64,
299    adjustment: u64,
300    field: QuicFrameField,
301    offset: usize,
302) -> Result<u64, QuicFrameParseError> {
303    base.checked_sub(value)
304        .and_then(|value| value.checked_sub(adjustment))
305        .ok_or(QuicFrameParseError::AckRangeUnderflow {
306            field,
307            offset,
308            base,
309            value,
310            adjustment,
311        })
312}