1mod ack;
4mod connection_close;
5mod connection_id;
6mod control;
7mod crypto;
8mod parse;
9mod path;
10mod stream;
11mod token;
12
13pub use ack::{QuicAckFrame, QuicAckRange, QuicAckRanges, QuicEcnCounts};
14pub use connection_close::QuicConnectionCloseFrame;
15pub use connection_id::{QuicNewConnectionIdFrame, QuicRetireConnectionIdFrame};
16pub use control::{
17 QuicDataBlockedFrame, QuicMaxDataFrame, QuicMaxStreamDataFrame, QuicMaxStreamsFrame,
18 QuicResetStreamFrame, QuicStopSendingFrame, QuicStreamDataBlockedFrame, QuicStreamDirection,
19 QuicStreamsBlockedFrame,
20};
21pub use crypto::QuicCryptoFrame;
22pub use parse::{QuicFrameField, QuicFrameParseError};
23pub use path::{QuicPathChallengeFrame, QuicPathResponseFrame};
24pub use stream::QuicStreamFrame;
25pub use token::QuicNewTokenFrame;
26
27use core::iter::FusedIterator;
28
29use super::varint::QuicVarInt;
30
31#[derive(Clone, Copy, Debug, Eq, PartialEq)]
33pub struct QuicPaddingFrame<'a> {
34 bytes: &'a [u8],
35 frame_type: QuicVarInt<'a>,
36}
37
38impl<'a> QuicPaddingFrame<'a> {
39 pub const fn as_bytes(self) -> &'a [u8] {
41 self.bytes
42 }
43
44 pub const fn frame_type(self) -> QuicVarInt<'a> {
46 self.frame_type
47 }
48}
49
50#[derive(Clone, Copy, Debug, Eq, PartialEq)]
52pub struct QuicPingFrame<'a> {
53 bytes: &'a [u8],
54 frame_type: QuicVarInt<'a>,
55}
56
57impl<'a> QuicPingFrame<'a> {
58 pub const fn as_bytes(self) -> &'a [u8] {
60 self.bytes
61 }
62
63 pub const fn frame_type(self) -> QuicVarInt<'a> {
65 self.frame_type
66 }
67}
68
69#[derive(Clone, Copy, Debug, Eq, PartialEq)]
71pub struct QuicHandshakeDoneFrame<'a> {
72 bytes: &'a [u8],
73 frame_type: QuicVarInt<'a>,
74}
75
76impl<'a> QuicHandshakeDoneFrame<'a> {
77 pub const fn as_bytes(self) -> &'a [u8] {
79 self.bytes
80 }
81
82 pub const fn frame_type(self) -> QuicVarInt<'a> {
84 self.frame_type
85 }
86}
87
88#[derive(Clone, Copy, Debug, Eq, PartialEq)]
90pub enum QuicFrame<'a> {
91 Padding(QuicPaddingFrame<'a>),
93 Ping(QuicPingFrame<'a>),
95 Ack(QuicAckFrame<'a>),
97 NewToken(QuicNewTokenFrame<'a>),
99 Crypto(QuicCryptoFrame<'a>),
101 Stream(QuicStreamFrame<'a>),
103 ResetStream(QuicResetStreamFrame<'a>),
105 StopSending(QuicStopSendingFrame<'a>),
107 MaxData(QuicMaxDataFrame<'a>),
109 MaxStreamData(QuicMaxStreamDataFrame<'a>),
111 MaxStreams(QuicMaxStreamsFrame<'a>),
113 DataBlocked(QuicDataBlockedFrame<'a>),
115 StreamDataBlocked(QuicStreamDataBlockedFrame<'a>),
117 StreamsBlocked(QuicStreamsBlockedFrame<'a>),
119 NewConnectionId(QuicNewConnectionIdFrame<'a>),
121 RetireConnectionId(QuicRetireConnectionIdFrame<'a>),
123 PathChallenge(QuicPathChallengeFrame<'a>),
125 PathResponse(QuicPathResponseFrame<'a>),
127 ConnectionClose(QuicConnectionCloseFrame<'a>),
129 HandshakeDone(QuicHandshakeDoneFrame<'a>),
131}
132
133impl<'a> QuicFrame<'a> {
134 pub fn parse(bytes: &'a [u8]) -> Result<(Self, &'a [u8]), QuicFrameParseError> {
136 parse_at(bytes, 0)
137 }
138
139 pub const fn as_bytes(self) -> &'a [u8] {
141 match self {
142 Self::Padding(frame) => frame.as_bytes(),
143 Self::Ping(frame) => frame.as_bytes(),
144 Self::Ack(frame) => frame.as_bytes(),
145 Self::NewToken(frame) => frame.as_bytes(),
146 Self::Crypto(frame) => frame.as_bytes(),
147 Self::Stream(frame) => frame.as_bytes(),
148 Self::ResetStream(frame) => frame.as_bytes(),
149 Self::StopSending(frame) => frame.as_bytes(),
150 Self::MaxData(frame) => frame.as_bytes(),
151 Self::MaxStreamData(frame) => frame.as_bytes(),
152 Self::MaxStreams(frame) => frame.as_bytes(),
153 Self::DataBlocked(frame) => frame.as_bytes(),
154 Self::StreamDataBlocked(frame) => frame.as_bytes(),
155 Self::StreamsBlocked(frame) => frame.as_bytes(),
156 Self::NewConnectionId(frame) => frame.as_bytes(),
157 Self::RetireConnectionId(frame) => frame.as_bytes(),
158 Self::PathChallenge(frame) => frame.as_bytes(),
159 Self::PathResponse(frame) => frame.as_bytes(),
160 Self::ConnectionClose(frame) => frame.as_bytes(),
161 Self::HandshakeDone(frame) => frame.as_bytes(),
162 }
163 }
164
165 pub const fn frame_type(self) -> QuicVarInt<'a> {
167 match self {
168 Self::Padding(frame) => frame.frame_type(),
169 Self::Ping(frame) => frame.frame_type(),
170 Self::Ack(frame) => frame.frame_type(),
171 Self::NewToken(frame) => frame.frame_type(),
172 Self::Crypto(frame) => frame.frame_type(),
173 Self::Stream(frame) => frame.frame_type(),
174 Self::ResetStream(frame) => frame.frame_type(),
175 Self::StopSending(frame) => frame.frame_type(),
176 Self::MaxData(frame) => frame.frame_type(),
177 Self::MaxStreamData(frame) => frame.frame_type(),
178 Self::MaxStreams(frame) => frame.frame_type(),
179 Self::DataBlocked(frame) => frame.frame_type(),
180 Self::StreamDataBlocked(frame) => frame.frame_type(),
181 Self::StreamsBlocked(frame) => frame.frame_type(),
182 Self::NewConnectionId(frame) => frame.frame_type(),
183 Self::RetireConnectionId(frame) => frame.frame_type(),
184 Self::PathChallenge(frame) => frame.frame_type(),
185 Self::PathResponse(frame) => frame.frame_type(),
186 Self::ConnectionClose(frame) => frame.frame_type(),
187 Self::HandshakeDone(frame) => frame.frame_type(),
188 }
189 }
190}
191
192#[derive(Clone, Copy, Debug, Eq, PartialEq)]
194pub struct QuicFrames<'a> {
195 bytes: &'a [u8],
196}
197
198impl<'a> QuicFrames<'a> {
199 pub fn parse(bytes: &'a [u8]) -> Result<Self, QuicFrameParseError> {
201 if bytes.is_empty() {
202 return Err(QuicFrameParseError::EmptySequence);
203 }
204
205 for frame in QuicFrameIter::new(bytes) {
206 frame?;
207 }
208 Ok(Self { bytes })
209 }
210
211 pub const fn as_bytes(self) -> &'a [u8] {
213 self.bytes
214 }
215
216 pub const fn iter(self) -> QuicFrameIter<'a> {
218 QuicFrameIter::new(self.bytes)
219 }
220}
221
222#[derive(Clone, Debug)]
224pub struct QuicFrameIter<'a> {
225 remaining: &'a [u8],
226 offset: usize,
227 failed: bool,
228}
229
230impl<'a> QuicFrameIter<'a> {
231 pub const fn new(bytes: &'a [u8]) -> Self {
233 Self {
234 remaining: bytes,
235 offset: 0,
236 failed: false,
237 }
238 }
239}
240
241impl<'a> Iterator for QuicFrameIter<'a> {
242 type Item = Result<QuicFrame<'a>, QuicFrameParseError>;
243
244 fn next(&mut self) -> Option<Self::Item> {
245 if self.failed || self.remaining.is_empty() {
246 return None;
247 }
248
249 match parse_at(self.remaining, self.offset) {
250 Ok((frame, suffix)) => {
251 let consumed = frame.as_bytes().len();
252 self.remaining = suffix;
253 self.offset += consumed;
254 Some(Ok(frame))
255 }
256 Err(error) => {
257 self.failed = true;
258 self.remaining = &[];
259 Some(Err(error))
260 }
261 }
262 }
263}
264
265impl FusedIterator for QuicFrameIter<'_> {}
266
267fn parse_at<'a>(
268 bytes: &'a [u8],
269 offset: usize,
270) -> Result<(QuicFrame<'a>, &'a [u8]), QuicFrameParseError> {
271 let frame_type = QuicVarInt::parse(bytes)
272 .map_err(|error| QuicFrameParseError::FrameType { offset, error })?;
273 let frame_len = frame_type.byte_len();
274 let frame_bytes = &bytes[..frame_len];
275 let suffix = &bytes[frame_len..];
276
277 match frame_type.value() {
278 0 => Ok((
279 QuicFrame::Padding(QuicPaddingFrame {
280 bytes: frame_bytes,
281 frame_type,
282 }),
283 suffix,
284 )),
285 1 => Ok((
286 QuicFrame::Ping(QuicPingFrame {
287 bytes: frame_bytes,
288 frame_type,
289 }),
290 suffix,
291 )),
292 2 | 3 => ack::parse_ack(bytes, frame_type, offset)
293 .map(|(frame, suffix)| (QuicFrame::Ack(frame), suffix)),
294 7 => token::parse_new_token(bytes, frame_type, offset)
295 .map(|(frame, suffix)| (QuicFrame::NewToken(frame), suffix)),
296 6 => crypto::parse_crypto(bytes, frame_type, offset)
297 .map(|(frame, suffix)| (QuicFrame::Crypto(frame), suffix)),
298 0x08..=0x0f => stream::parse_stream(bytes, frame_type, offset)
299 .map(|(frame, suffix)| (QuicFrame::Stream(frame), suffix)),
300 4 => control::parse_reset_stream(bytes, frame_type, offset)
301 .map(|(frame, suffix)| (QuicFrame::ResetStream(frame), suffix)),
302 5 => control::parse_stop_sending(bytes, frame_type, offset)
303 .map(|(frame, suffix)| (QuicFrame::StopSending(frame), suffix)),
304 0x10 => control::parse_max_data(bytes, frame_type, offset)
305 .map(|(frame, suffix)| (QuicFrame::MaxData(frame), suffix)),
306 0x11 => control::parse_max_stream_data(bytes, frame_type, offset)
307 .map(|(frame, suffix)| (QuicFrame::MaxStreamData(frame), suffix)),
308 0x12 => control::parse_max_streams(
309 bytes,
310 frame_type,
311 offset,
312 QuicStreamDirection::Bidirectional,
313 )
314 .map(|(frame, suffix)| (QuicFrame::MaxStreams(frame), suffix)),
315 0x13 => control::parse_max_streams(
316 bytes,
317 frame_type,
318 offset,
319 QuicStreamDirection::Unidirectional,
320 )
321 .map(|(frame, suffix)| (QuicFrame::MaxStreams(frame), suffix)),
322 0x14 => control::parse_data_blocked(bytes, frame_type, offset)
323 .map(|(frame, suffix)| (QuicFrame::DataBlocked(frame), suffix)),
324 0x15 => control::parse_stream_data_blocked(bytes, frame_type, offset)
325 .map(|(frame, suffix)| (QuicFrame::StreamDataBlocked(frame), suffix)),
326 0x16 => control::parse_streams_blocked(
327 bytes,
328 frame_type,
329 offset,
330 QuicStreamDirection::Bidirectional,
331 )
332 .map(|(frame, suffix)| (QuicFrame::StreamsBlocked(frame), suffix)),
333 0x17 => control::parse_streams_blocked(
334 bytes,
335 frame_type,
336 offset,
337 QuicStreamDirection::Unidirectional,
338 )
339 .map(|(frame, suffix)| (QuicFrame::StreamsBlocked(frame), suffix)),
340 0x18 => connection_id::parse_new_connection_id(bytes, frame_type, offset)
341 .map(|(frame, suffix)| (QuicFrame::NewConnectionId(frame), suffix)),
342 0x19 => connection_id::parse_retire_connection_id(bytes, frame_type, offset)
343 .map(|(frame, suffix)| (QuicFrame::RetireConnectionId(frame), suffix)),
344 0x1a => path::parse_path_challenge(bytes, frame_type, offset)
345 .map(|(frame, suffix)| (QuicFrame::PathChallenge(frame), suffix)),
346 0x1b => path::parse_path_response(bytes, frame_type, offset)
347 .map(|(frame, suffix)| (QuicFrame::PathResponse(frame), suffix)),
348 0x1c | 0x1d => connection_close::parse_connection_close(bytes, frame_type, offset)
349 .map(|(frame, suffix)| (QuicFrame::ConnectionClose(frame), suffix)),
350 0x1e => Ok((
351 QuicFrame::HandshakeDone(QuicHandshakeDoneFrame {
352 bytes: frame_bytes,
353 frame_type,
354 }),
355 suffix,
356 )),
357 value => Err(QuicFrameParseError::UnsupportedFrameType {
358 value,
359 length: frame_type.encoded_len(),
360 offset,
361 }),
362 }
363}