1use quik_util::*;
2
3use crate::common::{ConnectionId, StreamId, VarInt};
4
5pub enum Frame<'a> {
6 Padding,
7 Ping,
8 Ack(Ack),
9 ResetStream(ResetStream),
10 StopSending(StopSending),
11 Crypto(Crypto<'a>),
12 NewToken(NewToken<'a>),
13 Stream(Stream<'a>),
14 MaxData(MaxData),
15 MaxStreamData(MaxStreamData),
16 MaxStreams(MaxStreams),
17 DataBlocked(DataBlocked),
18 StreamDataBlocked(StreamDataBlocked),
19 StreamsBlocked(StreamsBlocked),
20 NewConnectionId(NewConnectionId),
21 RetireConnectionId(RetireConnectionId),
22 PathChallenge(PathChallenge),
23 PathResponse(PathResponse),
24 ConnectionClose(ConnectionClose<'a>),
25 HandshakeDone,
26}
27
28pub struct Padding;
29
30pub struct Ping;
31
32pub struct AckRange {
33 pub gap: VarInt,
34 pub range_length: VarInt,
35}
36
37pub struct EcnCounts {
38 pub ect0: VarInt,
39 pub ect1: VarInt,
40 pub ce: VarInt,
41}
42
43pub struct Ack {
44 pub largest_acked: VarInt,
45 pub ack_delay: VarInt,
46 pub ack_range_count: VarInt,
47 pub first_ack_range: VarInt,
48 pub ack_ranges: Vec<AckRange>,
49 pub ecn_counts: Option<EcnCounts>,
50}
51
52pub struct ResetStream {
53 pub stream_id: StreamId,
54 pub err_code: VarInt,
55 pub final_size: VarInt,
56}
57
58pub struct StopSending {
59 pub stream_id: StreamId,
60 pub err_code: VarInt,
61}
62
63pub struct Crypto<'a> {
64 pub data: &'a [u8],
65}
66
67pub struct NewToken<'a> {
68 pub token: &'a [u8],
69}
70
71pub struct Stream<'a> {
72 pub stream_id: StreamId,
73 pub fin: bool,
74 pub data: &'a [u8],
75}
76
77pub struct MaxData {
78 pub max_data: VarInt,
79}
80
81pub struct MaxStreamData {
82 pub stream_id: StreamId,
83 pub max_stream_data: VarInt,
84}
85
86pub struct MaxStreams {
87 pub max_streams: VarInt,
88}
89
90pub struct DataBlocked {
91 pub max_data: VarInt,
92}
93
94pub struct StreamDataBlocked {
95 pub stream_id: StreamId,
96 pub max_stream_data: VarInt,
97}
98
99pub struct StreamsBlocked {
100 pub max_streams: VarInt,
101}
102
103pub struct NewConnectionId {
104 pub seq_num: VarInt,
105 pub retire_prior_to: VarInt,
106 pub cid: ConnectionId,
107 pub stateless_reset_token: u128,
108}
109
110pub struct RetireConnectionId {
111 pub seq_num: VarInt,
112}
113
114pub struct PathChallenge {
115 pub data: u64,
116}
117
118pub struct PathResponse {
119 pub data: u64,
120}
121
122pub struct ConnectionClose<'a> {
123 pub err_code: VarInt,
124 pub frame_type: Option<VarInt>,
126 pub reason_phrase: &'a [u8],
127}
128
129pub struct HandshakeDone;
130
131impl<'a> Frame<'a> {
132 pub fn parse_multiple(mut data: &'a [u8]) -> impl Iterator<Item = Result<Frame<'a>>> {
133 std::iter::from_fn(move || {
134 if !data.is_empty() {
135 Some(Frame::parse(data).map(|(frame, rem_data)| {
136 data = rem_data;
137 frame
138 }))
139 } else {
140 None
141 }
142 })
143 }
144
145 pub fn parse(mut data: &'a [u8]) -> Result<(Frame<'a>, &'a [u8])> {
146 let typ: usize = VarInt::parse(&mut data)?.into();
147 let frame = match typ {
148 0x00 => {
149 Frame::Padding
152 }
153 0x01 => {
154 Frame::Ping
157 }
158 0x02..=0x03 => {
159 let largest_acked = VarInt::parse(&mut data)?;
162 let ack_delay = VarInt::parse(&mut data)?;
163 let ack_range_count = VarInt::parse(&mut data)?;
164 let first_ack_range = VarInt::parse(&mut data)?;
165
166 let ack_ranges = (0..ack_range_count.clone().into())
167 .map(|_| {
168 let gap = VarInt::parse(&mut data)?;
169 let range_length = VarInt::parse(&mut data)?;
170 Ok(AckRange { gap, range_length })
171 })
172 .collect::<Result<Vec<_>>>()?;
173
174 let ecn_counts = if typ == 0x03 {
175 let ect0 = VarInt::parse(&mut data)?;
176 let ect1 = VarInt::parse(&mut data)?;
177 let ce = VarInt::parse(&mut data)?;
178 Some(EcnCounts { ect0, ect1, ce })
179 } else {
180 None
181 };
182
183 Frame::Ack(Ack {
184 largest_acked,
185 ack_delay,
186 ack_range_count,
187 first_ack_range,
188 ack_ranges,
189 ecn_counts,
190 })
191 }
192 0x04 => {
193 let stream_id = VarInt::parse(&mut data)?;
196 let err_code = VarInt::parse(&mut data)?;
197 let final_size = VarInt::parse(&mut data)?;
198
199 Frame::ResetStream(ResetStream {
200 stream_id,
201 err_code,
202 final_size,
203 })
204 }
205 0x05 => {
206 let stream_id = VarInt::parse(&mut data)?;
209 let err_code = VarInt::parse(&mut data)?;
210
211 Frame::StopSending(StopSending {
212 stream_id,
213 err_code,
214 })
215 }
216 0x06 => {
217 let offset = VarInt::parse(&mut data)?;
220 let length = VarInt::parse(&mut data)?;
221 let crypto_data = data.extract(Some(offset.into()), Some(length.into()))?;
222
223 Frame::Crypto(Crypto { data: crypto_data })
224 }
225 0x07 => {
226 let token_length = VarInt::parse(&mut data)?;
229 let token = data.slice(token_length.into())?;
230
231 Frame::NewToken(NewToken { token })
232 }
233 0x08..=0x0f => {
234 let off_bit = typ & 0b100;
237 let len_bit = typ & 0b010;
238 let fin_bit = typ & 0b001;
239
240 let stream_id = VarInt::parse(&mut data)?;
241 let offset = if off_bit != 0 {
242 Some(VarInt::parse(&mut data)?.into())
243 } else {
244 None
245 };
246 let length = if len_bit != 0 {
247 Some(VarInt::parse(&mut data)?.into())
248 } else {
249 None
250 };
251 let stream_data = data.extract(offset.into(), length.into())?;
252
253 Frame::Stream(Stream {
254 stream_id,
255 data: stream_data,
256 fin: fin_bit != 0,
257 })
258 }
259 0x10 => {
260 let max_data = VarInt::parse(&mut data)?;
263
264 Frame::MaxData(MaxData { max_data })
265 }
266 0x11 => {
267 let stream_id = VarInt::parse(&mut data)?;
270 let max_stream_data = VarInt::parse(&mut data)?;
271
272 Frame::MaxStreamData(MaxStreamData {
273 stream_id,
274 max_stream_data,
275 })
276 }
277 0x12..=0x13 => {
278 let max_streams = VarInt::parse(&mut data)?;
281 Frame::MaxStreams(MaxStreams { max_streams })
284 }
285 0x14 => {
286 let max_data = VarInt::parse(&mut data)?;
289
290 Frame::DataBlocked(DataBlocked { max_data })
291 }
292 0x15 => {
293 let stream_id = VarInt::parse(&mut data)?;
296 let max_stream_data = VarInt::parse(&mut data)?;
297
298 Frame::StreamDataBlocked(StreamDataBlocked {
299 stream_id,
300 max_stream_data,
301 })
302 }
303 0x16..=0x17 => {
304 let max_streams = VarInt::parse(&mut data)?;
307 Frame::StreamsBlocked(StreamsBlocked { max_streams })
310 }
311 0x18 => {
312 let seq_num = VarInt::parse(&mut data)?;
315 let retire_prior_to = VarInt::parse(&mut data)?;
316 let cid = ConnectionId::parse(&mut data)?;
317 let stateless_reset_token = data.read_u128::<NetworkEndian>()?;
318
319 Frame::NewConnectionId(NewConnectionId {
320 seq_num,
321 retire_prior_to,
322 cid,
323 stateless_reset_token,
324 })
325 }
326 0x19 => {
327 let seq_num = VarInt::parse(&mut data)?;
330
331 Frame::RetireConnectionId(RetireConnectionId { seq_num })
332 }
333 0x1a => {
334 let data = data.read_u64::<NetworkEndian>()?;
337
338 Frame::PathChallenge(PathChallenge { data })
339 }
340 0x1b => {
341 let data = data.read_u64::<NetworkEndian>()?;
344
345 Frame::PathResponse(PathResponse { data })
346 }
347 0x1c..=0x1d => {
348 let err_code = VarInt::parse(&mut data)?;
351 let frame_type = if typ == 0x1c {
352 Some(VarInt::parse(&mut data)?)
353 } else {
354 None
355 };
356 let reason_phrase_length = VarInt::parse(&mut data)?;
357 let reason_phrase = data.slice(reason_phrase_length.into())?;
358
359 Frame::ConnectionClose(ConnectionClose {
360 err_code,
361 frame_type,
362 reason_phrase,
363 })
364 }
365 0x1e => {
366 Frame::HandshakeDone
369 }
370 _ => Err("Unknown frame type")?,
371 };
372
373 Ok((frame, data))
374 }
375}