1use super::super::varint::{QuicVarInt, QuicVarIntParseError};
4use super::header::{QuicConnectionIdField, QuicLongHeader, QuicLongPacketType, QuicVersion};
5use super::parse::QuicPacketParseError;
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12pub struct QuicProtectedLongPacket<'a> {
13 bytes: &'a [u8],
14 header: QuicLongHeader<'a>,
15 packet_type: QuicLongPacketType,
16 token_length: Option<QuicVarInt<'a>>,
17 token: Option<&'a [u8]>,
18 length: QuicVarInt<'a>,
19 packet_number_offset: usize,
20 protected_remainder: &'a [u8],
21}
22
23impl<'a> QuicProtectedLongPacket<'a> {
24 pub(crate) const fn from_validated(
26 bytes: &'a [u8],
27 header: QuicLongHeader<'a>,
28 packet_type: QuicLongPacketType,
29 token_fields: Option<(QuicVarInt<'a>, &'a [u8])>,
30 length: QuicVarInt<'a>,
31 packet_number_offset: usize,
32 protected_remainder: &'a [u8],
33 ) -> Self {
34 let (token_length, token) = match token_fields {
35 Some((token_length, token)) => (Some(token_length), Some(token)),
36 None => (None, None),
37 };
38 Self {
39 bytes,
40 header,
41 packet_type,
42 token_length,
43 token,
44 length,
45 packet_number_offset,
46 protected_remainder,
47 }
48 }
49
50 pub fn parse(bytes: &'a [u8]) -> Result<(Self, &'a [u8]), QuicPacketParseError> {
52 let header = QuicLongHeader::parse(bytes)?;
53 let version = header.version();
54 if version != QuicVersion::V1 && version != QuicVersion::V2 {
55 return Err(QuicPacketParseError::UnsupportedVersion { version });
56 }
57 if !header.has_fixed_bit() {
58 return Err(QuicPacketParseError::FixedBitNotSet {
59 first_byte: header.first_byte(),
60 });
61 }
62 validate_connection_id(
63 QuicConnectionIdField::Destination,
64 header.destination_connection_id().len(),
65 )?;
66 validate_connection_id(
67 QuicConnectionIdField::Source,
68 header.source_connection_id().len(),
69 )?;
70
71 let packet_type = match header.long_packet_type() {
72 Some(packet_type) => packet_type,
73 None => return Err(QuicPacketParseError::UnsupportedVersion { version }),
74 };
75 if packet_type == QuicLongPacketType::Retry {
76 return Err(QuicPacketParseError::NotLengthDelimited { packet_type });
77 }
78
79 let header_end = header.as_bytes().len();
80 let (token_length, token, length_offset) = if packet_type == QuicLongPacketType::Initial {
81 let token_length = parse_varint_at(bytes, header_end)?;
82 let token_start = checked_end(header_end, token_length.byte_len())?;
83 let token_end = checked_end(token_start, to_usize(token_length.value())?)?;
84 require(bytes, token_end)?;
85 (
86 Some(token_length),
87 Some(&bytes[token_start..token_end]),
88 token_end,
89 )
90 } else {
91 (None, None, header_end)
92 };
93
94 let length = parse_varint_at(bytes, length_offset)?;
95 if length.value() < 2 {
96 return Err(QuicPacketParseError::ProtectedRemainderTooShort {
97 minimum: 2,
98 actual: length.value(),
99 });
100 }
101 let packet_number_offset = checked_end(length_offset, length.byte_len())?;
102 let packet_end = checked_end(packet_number_offset, to_usize(length.value())?)?;
103 require(bytes, packet_end)?;
104
105 Ok((
106 Self {
107 bytes: &bytes[..packet_end],
108 header,
109 packet_type,
110 token_length,
111 token,
112 length,
113 packet_number_offset,
114 protected_remainder: &bytes[packet_number_offset..packet_end],
115 },
116 &bytes[packet_end..],
117 ))
118 }
119
120 pub const fn header(self) -> QuicLongHeader<'a> {
122 self.header
123 }
124
125 pub const fn version(self) -> QuicVersion {
127 self.header.version()
128 }
129
130 pub const fn packet_type(self) -> QuicLongPacketType {
132 self.packet_type
133 }
134
135 pub const fn token_length(self) -> Option<QuicVarInt<'a>> {
137 self.token_length
138 }
139
140 pub const fn token(self) -> Option<&'a [u8]> {
142 self.token
143 }
144
145 pub const fn length(self) -> QuicVarInt<'a> {
147 self.length
148 }
149
150 pub const fn packet_number_offset(self) -> usize {
152 self.packet_number_offset
153 }
154
155 pub const fn protected_remainder(self) -> &'a [u8] {
157 self.protected_remainder
158 }
159
160 pub const fn as_bytes(self) -> &'a [u8] {
162 self.bytes
163 }
164}
165
166fn validate_connection_id(
167 field: QuicConnectionIdField,
168 length: usize,
169) -> Result<(), QuicPacketParseError> {
170 if length > 20 {
171 return Err(QuicPacketParseError::ConnectionIdTooLong { field, length });
172 }
173 Ok(())
174}
175
176fn parse_varint_at<'a>(
177 bytes: &'a [u8],
178 offset: usize,
179) -> Result<QuicVarInt<'a>, QuicPacketParseError> {
180 match QuicVarInt::parse(&bytes[offset..]) {
181 Ok(value) => Ok(value),
182 Err(QuicVarIntParseError::Incomplete {
183 required,
184 available: _,
185 }) => Err(QuicPacketParseError::Incomplete {
186 required: checked_end(offset, required)?,
187 available: bytes.len(),
188 }),
189 }
190}
191
192fn to_usize(value: u64) -> Result<usize, QuicPacketParseError> {
193 usize::try_from(value).map_err(|_| QuicPacketParseError::LengthNotRepresentable { value })
194}
195
196fn checked_end(offset: usize, length: usize) -> Result<usize, QuicPacketParseError> {
197 offset
198 .checked_add(length)
199 .ok_or(QuicPacketParseError::LengthOverflow { offset, length })
200}
201
202fn require(bytes: &[u8], required: usize) -> Result<(), QuicPacketParseError> {
203 if bytes.len() < required {
204 return Err(QuicPacketParseError::Incomplete {
205 required,
206 available: bytes.len(),
207 });
208 }
209 Ok(())
210}