1use core::fmt;
8
9use super::header::QuicShortHeader;
10use super::long::QuicProtectedLongPacket;
11
12const LONG_PRESERVED_MASK: u8 = 0xf0;
13const SHORT_PRESERVED_MASK: u8 = 0xe0;
14
15#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17pub enum QuicUnprotectedHeaderError {
18 PreservedBitsMismatch {
20 protected_first_byte: u8,
22 unprotected_first_byte: u8,
24 preserved_mask: u8,
26 },
27 PacketNumberLengthMismatch {
29 expected: usize,
31 supplied: usize,
33 },
34 ProtectedRemainderTooShort {
36 required: usize,
38 available: usize,
40 },
41}
42
43impl fmt::Display for QuicUnprotectedHeaderError {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 match self {
46 Self::PreservedBitsMismatch {
47 protected_first_byte,
48 unprotected_first_byte,
49 preserved_mask,
50 } => write!(
51 f,
52 "QUIC protected first byte {protected_first_byte:#04x} and unprotected first byte {unprotected_first_byte:#04x} differ under preserved-bit mask {preserved_mask:#04x}"
53 ),
54 Self::PacketNumberLengthMismatch { expected, supplied } => write!(
55 f,
56 "QUIC unprotected packet-number width mismatch: need {expected} bytes, have {supplied}"
57 ),
58 Self::ProtectedRemainderTooShort {
59 required,
60 available,
61 } => write!(
62 f,
63 "QUIC protected packet remainder is too short for its unprotected packet number: need {required} bytes, have {available}"
64 ),
65 }
66 }
67}
68
69#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
71pub enum QuicPacketNumberLen {
72 One,
74 Two,
76 Three,
78 Four,
80}
81
82impl QuicPacketNumberLen {
83 pub const fn byte_len(self) -> usize {
85 match self {
86 Self::One => 1,
87 Self::Two => 2,
88 Self::Three => 3,
89 Self::Four => 4,
90 }
91 }
92
93 const fn from_first_byte(first_byte: u8) -> Self {
94 match first_byte & 0x03 {
95 0 => Self::One,
96 1 => Self::Two,
97 2 => Self::Three,
98 _ => Self::Four,
99 }
100 }
101}
102
103#[derive(Clone, Copy, Debug, Eq, PartialEq)]
107pub struct QuicTruncatedPacketNumber<'a> {
108 bytes: &'a [u8],
109 encoded_len: QuicPacketNumberLen,
110}
111
112impl<'a> QuicTruncatedPacketNumber<'a> {
113 const fn new(bytes: &'a [u8], encoded_len: QuicPacketNumberLen) -> Self {
114 Self { bytes, encoded_len }
115 }
116
117 pub const fn as_bytes(self) -> &'a [u8] {
119 self.bytes
120 }
121
122 pub const fn encoded_len(self) -> QuicPacketNumberLen {
124 self.encoded_len
125 }
126
127 pub fn value(self) -> u32 {
129 self.bytes
130 .iter()
131 .fold(0, |value, &byte| (value << 8) | u32::from(byte))
132 }
133}
134
135#[derive(Clone, Copy, Debug, Eq, PartialEq)]
141pub struct QuicUnprotectedLongHeader<'packet, 'unprotected> {
142 protected_packet: QuicProtectedLongPacket<'packet>,
143 unprotected_first_byte: u8,
144 packet_number: QuicTruncatedPacketNumber<'unprotected>,
145}
146
147impl<'packet, 'unprotected> QuicUnprotectedLongHeader<'packet, 'unprotected> {
148 pub fn new(
153 protected_packet: QuicProtectedLongPacket<'packet>,
154 unprotected_first_byte: u8,
155 unprotected_packet_number: &'unprotected [u8],
156 ) -> Result<Self, QuicUnprotectedHeaderError> {
157 validate(
158 protected_packet.header().first_byte(),
159 unprotected_first_byte,
160 LONG_PRESERVED_MASK,
161 unprotected_packet_number,
162 protected_packet.protected_remainder().len(),
163 )?;
164 Ok(Self {
165 protected_packet,
166 unprotected_first_byte,
167 packet_number: QuicTruncatedPacketNumber::new(
168 unprotected_packet_number,
169 QuicPacketNumberLen::from_first_byte(unprotected_first_byte),
170 ),
171 })
172 }
173
174 pub const fn protected_packet(self) -> QuicProtectedLongPacket<'packet> {
176 self.protected_packet
177 }
178
179 pub const fn unprotected_first_byte(self) -> u8 {
181 self.unprotected_first_byte
182 }
183
184 pub const fn packet_number(self) -> QuicTruncatedPacketNumber<'unprotected> {
186 self.packet_number
187 }
188
189 pub const fn raw_reserved_bits(self) -> u8 {
191 (self.unprotected_first_byte >> 2) & 0x03
192 }
193}
194
195#[derive(Clone, Copy, Debug, Eq, PartialEq)]
201pub struct QuicUnprotectedShortHeader<'packet, 'unprotected> {
202 protected_packet: QuicShortHeader<'packet>,
203 unprotected_first_byte: u8,
204 packet_number: QuicTruncatedPacketNumber<'unprotected>,
205}
206
207impl<'packet, 'unprotected> QuicUnprotectedShortHeader<'packet, 'unprotected> {
208 pub fn new(
213 protected_packet: QuicShortHeader<'packet>,
214 unprotected_first_byte: u8,
215 unprotected_packet_number: &'unprotected [u8],
216 ) -> Result<Self, QuicUnprotectedHeaderError> {
217 validate(
218 protected_packet.first_byte(),
219 unprotected_first_byte,
220 SHORT_PRESERVED_MASK,
221 unprotected_packet_number,
222 protected_packet.protected_remainder().len(),
223 )?;
224 Ok(Self {
225 protected_packet,
226 unprotected_first_byte,
227 packet_number: QuicTruncatedPacketNumber::new(
228 unprotected_packet_number,
229 QuicPacketNumberLen::from_first_byte(unprotected_first_byte),
230 ),
231 })
232 }
233
234 pub const fn protected_packet(self) -> QuicShortHeader<'packet> {
236 self.protected_packet
237 }
238
239 pub const fn unprotected_first_byte(self) -> u8 {
241 self.unprotected_first_byte
242 }
243
244 pub const fn packet_number(self) -> QuicTruncatedPacketNumber<'unprotected> {
246 self.packet_number
247 }
248
249 pub const fn raw_reserved_bits(self) -> u8 {
251 (self.unprotected_first_byte >> 3) & 0x03
252 }
253
254 pub const fn spin_bit(self) -> bool {
256 self.unprotected_first_byte & 0x20 != 0
257 }
258
259 pub const fn key_phase(self) -> bool {
261 self.unprotected_first_byte & 0x04 != 0
262 }
263}
264
265fn validate(
266 protected_first_byte: u8,
267 unprotected_first_byte: u8,
268 preserved_mask: u8,
269 unprotected_packet_number: &[u8],
270 protected_remainder_len: usize,
271) -> Result<(), QuicUnprotectedHeaderError> {
272 if protected_first_byte & preserved_mask != unprotected_first_byte & preserved_mask {
273 return Err(QuicUnprotectedHeaderError::PreservedBitsMismatch {
274 protected_first_byte,
275 unprotected_first_byte,
276 preserved_mask,
277 });
278 }
279
280 let expected = QuicPacketNumberLen::from_first_byte(unprotected_first_byte).byte_len();
281 let supplied = unprotected_packet_number.len();
282 if supplied != expected {
283 return Err(QuicUnprotectedHeaderError::PacketNumberLengthMismatch { expected, supplied });
284 }
285
286 if protected_remainder_len < expected {
287 return Err(QuicUnprotectedHeaderError::ProtectedRemainderTooShort {
288 required: expected,
289 available: protected_remainder_len,
290 });
291 }
292 Ok(())
293}