Skip to main content

net_wire/quic/frame/
token.rs

1//! RFC 9000 NEW_TOKEN frame parsing.
2
3use super::super::varint::QuicVarInt;
4use super::parse::{QuicFrameField, QuicFrameParseError};
5
6/// A checked borrowed RFC 9000 NEW_TOKEN frame view.
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8pub struct QuicNewTokenFrame<'a> {
9    bytes: &'a [u8],
10    frame_type: QuicVarInt<'a>,
11    token_length: QuicVarInt<'a>,
12    token: &'a [u8],
13}
14
15impl<'a> QuicNewTokenFrame<'a> {
16    /// Returns the exact encoded frame bytes.
17    pub const fn as_bytes(self) -> &'a [u8] {
18        self.bytes
19    }
20
21    /// Returns the exact encoded frame-type variable integer.
22    pub const fn frame_type(self) -> QuicVarInt<'a> {
23        self.frame_type
24    }
25
26    /// Returns the exact encoded token-length variable integer.
27    pub const fn token_length(self) -> QuicVarInt<'a> {
28        self.token_length
29    }
30
31    /// Returns the nonempty opaque token bytes.
32    pub const fn token(self) -> &'a [u8] {
33        self.token
34    }
35}
36
37pub(super) fn parse_new_token<'a>(
38    bytes: &'a [u8],
39    frame_type: QuicVarInt<'a>,
40    offset: usize,
41) -> Result<(QuicNewTokenFrame<'a>, &'a [u8]), QuicFrameParseError> {
42    let frame_type_len = frame_type.byte_len();
43    let token_length_offset = offset + frame_type_len;
44    let token_length = QuicVarInt::parse(&bytes[frame_type_len..]).map_err(|error| {
45        QuicFrameParseError::Field {
46            field: QuicFrameField::TokenLength,
47            offset: token_length_offset,
48            error,
49        }
50    })?;
51    let token_length_value = token_length.value();
52    let token_length_usize = usize::try_from(token_length_value).map_err(|_| {
53        QuicFrameParseError::LengthNotRepresentable {
54            field: QuicFrameField::TokenLength,
55            offset: token_length_offset,
56            value: token_length_value,
57        }
58    })?;
59    let token_start = frame_type_len + token_length.byte_len();
60    let token_offset = token_length_offset + token_length.byte_len();
61
62    if token_length_usize == 0 {
63        return Err(QuicFrameParseError::EmptyField {
64            field: QuicFrameField::Token,
65            offset: token_offset,
66        });
67    }
68
69    let token_end =
70        token_start
71            .checked_add(token_length_usize)
72            .ok_or(QuicFrameParseError::LengthOverflow {
73                field: QuicFrameField::Token,
74                offset: token_offset,
75                length: token_length_usize,
76            })?;
77    let available = bytes.len() - token_start;
78    if available < token_length_usize {
79        return Err(QuicFrameParseError::IncompleteBytes {
80            field: QuicFrameField::Token,
81            offset: token_offset,
82            required: token_length_usize,
83            available,
84        });
85    }
86
87    Ok((
88        QuicNewTokenFrame {
89            bytes: &bytes[..token_end],
90            frame_type,
91            token_length,
92            token: &bytes[token_start..token_end],
93        },
94        &bytes[token_end..],
95    ))
96}