blob: 2addb8d8ff2d9721b0bbac13d73873928d6f9f0a [file] [log] [blame]
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001// Copyright (C) 2018-2019, Cloudflare, Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10//
11// * Redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
19// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
Mike Yuf57cb852022-09-20 12:25:20 +000027use std::convert::TryInto;
28
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +010029use crate::Error;
30use crate::Result;
31
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +010032use crate::packet;
33use crate::ranges;
34use crate::stream;
35
Mike Yuf57cb852022-09-20 12:25:20 +000036#[cfg(feature = "qlog")]
37use qlog::events::quic::AckedRanges;
38#[cfg(feature = "qlog")]
39use qlog::events::quic::ErrorSpace;
40#[cfg(feature = "qlog")]
41use qlog::events::quic::QuicFrame;
42#[cfg(feature = "qlog")]
43use qlog::events::quic::StreamType;
44
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +010045pub const MAX_CRYPTO_OVERHEAD: usize = 8;
46pub const MAX_DGRAM_OVERHEAD: usize = 2;
47pub const MAX_STREAM_OVERHEAD: usize = 12;
48pub const MAX_STREAM_SIZE: u64 = 1 << 62;
49
Mike Yufa78f722023-04-07 09:20:19 +000050#[derive(Clone, Debug, PartialEq, Eq)]
Mike Yuf57cb852022-09-20 12:25:20 +000051pub struct EcnCounts {
52 ect0_count: u64,
53 ect1_count: u64,
54 ecn_ce_count: u64,
55}
56
Mike Yufa78f722023-04-07 09:20:19 +000057#[derive(Clone, PartialEq, Eq)]
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +010058pub enum Frame {
59 Padding {
60 len: usize,
61 },
62
63 Ping,
64
65 ACK {
66 ack_delay: u64,
67 ranges: ranges::RangeSet,
Mike Yuf57cb852022-09-20 12:25:20 +000068 ecn_counts: Option<EcnCounts>,
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +010069 },
70
71 ResetStream {
72 stream_id: u64,
73 error_code: u64,
74 final_size: u64,
75 },
76
77 StopSending {
78 stream_id: u64,
79 error_code: u64,
80 },
81
82 Crypto {
83 data: stream::RangeBuf,
84 },
85
Joel Galenson96d408b2021-06-08 17:53:00 -070086 CryptoHeader {
87 offset: u64,
88 length: usize,
89 },
90
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +010091 NewToken {
92 token: Vec<u8>,
93 },
94
95 Stream {
96 stream_id: u64,
97 data: stream::RangeBuf,
98 },
99
Joel Galenson96d408b2021-06-08 17:53:00 -0700100 StreamHeader {
101 stream_id: u64,
102 offset: u64,
103 length: usize,
104 fin: bool,
105 },
106
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100107 MaxData {
108 max: u64,
109 },
110
111 MaxStreamData {
112 stream_id: u64,
113 max: u64,
114 },
115
116 MaxStreamsBidi {
117 max: u64,
118 },
119
120 MaxStreamsUni {
121 max: u64,
122 },
123
124 DataBlocked {
125 limit: u64,
126 },
127
128 StreamDataBlocked {
129 stream_id: u64,
130 limit: u64,
131 },
132
133 StreamsBlockedBidi {
134 limit: u64,
135 },
136
137 StreamsBlockedUni {
138 limit: u64,
139 },
140
141 NewConnectionId {
142 seq_num: u64,
143 retire_prior_to: u64,
144 conn_id: Vec<u8>,
Mike Yuf57cb852022-09-20 12:25:20 +0000145 reset_token: [u8; 16],
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100146 },
147
148 RetireConnectionId {
149 seq_num: u64,
150 },
151
152 PathChallenge {
Mike Yuf57cb852022-09-20 12:25:20 +0000153 data: [u8; 8],
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100154 },
155
156 PathResponse {
Mike Yuf57cb852022-09-20 12:25:20 +0000157 data: [u8; 8],
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100158 },
159
160 ConnectionClose {
161 error_code: u64,
162 frame_type: u64,
163 reason: Vec<u8>,
164 },
165
166 ApplicationClose {
167 error_code: u64,
168 reason: Vec<u8>,
169 },
170
171 HandshakeDone,
172
173 Datagram {
174 data: Vec<u8>,
175 },
Mike Yuf57cb852022-09-20 12:25:20 +0000176
177 DatagramHeader {
178 length: usize,
179 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100180}
181
182impl Frame {
183 pub fn from_bytes(
184 b: &mut octets::Octets, pkt: packet::Type,
185 ) -> Result<Frame> {
186 let frame_type = b.get_varint()?;
187
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100188 let frame = match frame_type {
189 0x00 => {
190 let mut len = 1;
191
192 while b.peek_u8() == Ok(0x00) {
193 b.get_u8()?;
194
195 len += 1;
196 }
197
198 Frame::Padding { len }
199 },
200
201 0x01 => Frame::Ping,
202
Mike Yuf57cb852022-09-20 12:25:20 +0000203 0x02..=0x03 => parse_ack_frame(frame_type, b)?,
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100204
205 0x04 => Frame::ResetStream {
206 stream_id: b.get_varint()?,
207 error_code: b.get_varint()?,
208 final_size: b.get_varint()?,
209 },
210
211 0x05 => Frame::StopSending {
212 stream_id: b.get_varint()?,
213 error_code: b.get_varint()?,
214 },
215
216 0x06 => {
217 let offset = b.get_varint()?;
218 let data = b.get_bytes_with_varint_length()?;
219 let data = stream::RangeBuf::from(data.as_ref(), offset, false);
220
221 Frame::Crypto { data }
222 },
223
224 0x07 => Frame::NewToken {
225 token: b.get_bytes_with_varint_length()?.to_vec(),
226 },
227
228 0x08..=0x0f => parse_stream_frame(frame_type, b)?,
229
230 0x10 => Frame::MaxData {
231 max: b.get_varint()?,
232 },
233
234 0x11 => Frame::MaxStreamData {
235 stream_id: b.get_varint()?,
236 max: b.get_varint()?,
237 },
238
239 0x12 => Frame::MaxStreamsBidi {
240 max: b.get_varint()?,
241 },
242
243 0x13 => Frame::MaxStreamsUni {
244 max: b.get_varint()?,
245 },
246
247 0x14 => Frame::DataBlocked {
248 limit: b.get_varint()?,
249 },
250
251 0x15 => Frame::StreamDataBlocked {
252 stream_id: b.get_varint()?,
253 limit: b.get_varint()?,
254 },
255
256 0x16 => Frame::StreamsBlockedBidi {
257 limit: b.get_varint()?,
258 },
259
260 0x17 => Frame::StreamsBlockedUni {
261 limit: b.get_varint()?,
262 },
263
264 0x18 => Frame::NewConnectionId {
265 seq_num: b.get_varint()?,
266 retire_prior_to: b.get_varint()?,
267 conn_id: b.get_bytes_with_u8_length()?.to_vec(),
Mike Yuf57cb852022-09-20 12:25:20 +0000268 reset_token: b
269 .get_bytes(16)?
270 .buf()
271 .try_into()
272 .map_err(|_| Error::BufferTooShort)?,
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100273 },
274
275 0x19 => Frame::RetireConnectionId {
276 seq_num: b.get_varint()?,
277 },
278
279 0x1a => Frame::PathChallenge {
Mike Yuf57cb852022-09-20 12:25:20 +0000280 data: b
281 .get_bytes(8)?
282 .buf()
283 .try_into()
284 .map_err(|_| Error::BufferTooShort)?,
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100285 },
286
287 0x1b => Frame::PathResponse {
Mike Yuf57cb852022-09-20 12:25:20 +0000288 data: b
289 .get_bytes(8)?
290 .buf()
291 .try_into()
292 .map_err(|_| Error::BufferTooShort)?,
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100293 },
294
295 0x1c => Frame::ConnectionClose {
296 error_code: b.get_varint()?,
297 frame_type: b.get_varint()?,
298 reason: b.get_bytes_with_varint_length()?.to_vec(),
299 },
300
301 0x1d => Frame::ApplicationClose {
302 error_code: b.get_varint()?,
303 reason: b.get_bytes_with_varint_length()?.to_vec(),
304 },
305
306 0x1e => Frame::HandshakeDone,
307
308 0x30 | 0x31 => parse_datagram_frame(frame_type, b)?,
309
310 _ => return Err(Error::InvalidFrame),
311 };
312
313 let allowed = match (pkt, &frame) {
314 // PADDING and PING are allowed on all packet types.
315 (_, Frame::Padding { .. }) | (_, Frame::Ping { .. }) => true,
316
317 // ACK, CRYPTO, HANDSHAKE_DONE, NEW_TOKEN, PATH_RESPONSE, and
318 // RETIRE_CONNECTION_ID can't be sent on 0-RTT packets.
319 (packet::Type::ZeroRTT, Frame::ACK { .. }) => false,
320 (packet::Type::ZeroRTT, Frame::Crypto { .. }) => false,
321 (packet::Type::ZeroRTT, Frame::HandshakeDone) => false,
322 (packet::Type::ZeroRTT, Frame::NewToken { .. }) => false,
323 (packet::Type::ZeroRTT, Frame::PathResponse { .. }) => false,
324 (packet::Type::ZeroRTT, Frame::RetireConnectionId { .. }) => false,
325 (packet::Type::ZeroRTT, Frame::ConnectionClose { .. }) => false,
326
327 // ACK, CRYPTO and CONNECTION_CLOSE can be sent on all other packet
328 // types.
329 (_, Frame::ACK { .. }) => true,
330 (_, Frame::Crypto { .. }) => true,
331 (_, Frame::ConnectionClose { .. }) => true,
332
333 // All frames are allowed on 0-RTT and 1-RTT packets.
334 (packet::Type::Short, _) => true,
335 (packet::Type::ZeroRTT, _) => true,
336
337 // All other cases are forbidden.
338 (..) => false,
339 };
340
341 if !allowed {
342 return Err(Error::InvalidPacket);
343 }
344
345 Ok(frame)
346 }
347
348 pub fn to_bytes(&self, b: &mut octets::OctetsMut) -> Result<usize> {
349 let before = b.cap();
350
351 match self {
352 Frame::Padding { len } => {
353 let mut left = *len;
354
355 while left > 0 {
356 b.put_varint(0x00)?;
357
358 left -= 1;
359 }
360 },
361
362 Frame::Ping => {
363 b.put_varint(0x01)?;
364 },
365
Mike Yuf57cb852022-09-20 12:25:20 +0000366 Frame::ACK {
367 ack_delay,
368 ranges,
369 ecn_counts,
370 } => {
371 if ecn_counts.is_none() {
372 b.put_varint(0x02)?;
373 } else {
374 b.put_varint(0x03)?;
375 }
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100376
377 let mut it = ranges.iter().rev();
378
379 let first = it.next().unwrap();
380 let ack_block = (first.end - 1) - first.start;
381
382 b.put_varint(first.end - 1)?;
383 b.put_varint(*ack_delay)?;
384 b.put_varint(it.len() as u64)?;
385 b.put_varint(ack_block)?;
386
387 let mut smallest_ack = first.start;
388
389 for block in it {
390 let gap = smallest_ack - block.end - 1;
391 let ack_block = (block.end - 1) - block.start;
392
393 b.put_varint(gap)?;
394 b.put_varint(ack_block)?;
395
396 smallest_ack = block.start;
397 }
Mike Yuf57cb852022-09-20 12:25:20 +0000398
399 if let Some(ecn) = ecn_counts {
400 b.put_varint(ecn.ect0_count)?;
401 b.put_varint(ecn.ect1_count)?;
402 b.put_varint(ecn.ecn_ce_count)?;
403 }
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100404 },
405
406 Frame::ResetStream {
407 stream_id,
408 error_code,
409 final_size,
410 } => {
411 b.put_varint(0x04)?;
412
413 b.put_varint(*stream_id)?;
414 b.put_varint(*error_code)?;
415 b.put_varint(*final_size)?;
416 },
417
418 Frame::StopSending {
419 stream_id,
420 error_code,
421 } => {
422 b.put_varint(0x05)?;
423
424 b.put_varint(*stream_id)?;
425 b.put_varint(*error_code)?;
426 },
427
428 Frame::Crypto { data } => {
Mike Yufa78f722023-04-07 09:20:19 +0000429 encode_crypto_header(data.off(), data.len() as u64, b)?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100430
Mike Yuf57cb852022-09-20 12:25:20 +0000431 b.put_bytes(data)?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100432 },
433
Joel Galenson96d408b2021-06-08 17:53:00 -0700434 Frame::CryptoHeader { .. } => (),
435
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100436 Frame::NewToken { token } => {
437 b.put_varint(0x07)?;
438
439 b.put_varint(token.len() as u64)?;
Mike Yuf57cb852022-09-20 12:25:20 +0000440 b.put_bytes(token)?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100441 },
442
443 Frame::Stream { stream_id, data } => {
Joel Galenson96d408b2021-06-08 17:53:00 -0700444 encode_stream_header(
445 *stream_id,
Mike Yufa78f722023-04-07 09:20:19 +0000446 data.off(),
Joel Galenson96d408b2021-06-08 17:53:00 -0700447 data.len() as u64,
448 data.fin(),
449 b,
450 )?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100451
Mike Yuf57cb852022-09-20 12:25:20 +0000452 b.put_bytes(data)?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100453 },
454
Joel Galenson96d408b2021-06-08 17:53:00 -0700455 Frame::StreamHeader { .. } => (),
456
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100457 Frame::MaxData { max } => {
458 b.put_varint(0x10)?;
459
460 b.put_varint(*max)?;
461 },
462
463 Frame::MaxStreamData { stream_id, max } => {
464 b.put_varint(0x11)?;
465
466 b.put_varint(*stream_id)?;
467 b.put_varint(*max)?;
468 },
469
470 Frame::MaxStreamsBidi { max } => {
471 b.put_varint(0x12)?;
472
473 b.put_varint(*max)?;
474 },
475
476 Frame::MaxStreamsUni { max } => {
477 b.put_varint(0x13)?;
478
479 b.put_varint(*max)?;
480 },
481
482 Frame::DataBlocked { limit } => {
483 b.put_varint(0x14)?;
484
485 b.put_varint(*limit)?;
486 },
487
488 Frame::StreamDataBlocked { stream_id, limit } => {
489 b.put_varint(0x15)?;
490
491 b.put_varint(*stream_id)?;
492 b.put_varint(*limit)?;
493 },
494
495 Frame::StreamsBlockedBidi { limit } => {
496 b.put_varint(0x16)?;
497
498 b.put_varint(*limit)?;
499 },
500
501 Frame::StreamsBlockedUni { limit } => {
502 b.put_varint(0x17)?;
503
504 b.put_varint(*limit)?;
505 },
506
507 Frame::NewConnectionId {
508 seq_num,
509 retire_prior_to,
510 conn_id,
511 reset_token,
512 } => {
513 b.put_varint(0x18)?;
514
515 b.put_varint(*seq_num)?;
516 b.put_varint(*retire_prior_to)?;
517 b.put_u8(conn_id.len() as u8)?;
518 b.put_bytes(conn_id.as_ref())?;
519 b.put_bytes(reset_token.as_ref())?;
520 },
521
522 Frame::RetireConnectionId { seq_num } => {
523 b.put_varint(0x19)?;
524
525 b.put_varint(*seq_num)?;
526 },
527
528 Frame::PathChallenge { data } => {
529 b.put_varint(0x1a)?;
530
531 b.put_bytes(data.as_ref())?;
532 },
533
534 Frame::PathResponse { data } => {
535 b.put_varint(0x1b)?;
536
537 b.put_bytes(data.as_ref())?;
538 },
539
540 Frame::ConnectionClose {
541 error_code,
542 frame_type,
543 reason,
544 } => {
545 b.put_varint(0x1c)?;
546
547 b.put_varint(*error_code)?;
548 b.put_varint(*frame_type)?;
549 b.put_varint(reason.len() as u64)?;
550 b.put_bytes(reason.as_ref())?;
551 },
552
553 Frame::ApplicationClose { error_code, reason } => {
554 b.put_varint(0x1d)?;
555
556 b.put_varint(*error_code)?;
557 b.put_varint(reason.len() as u64)?;
558 b.put_bytes(reason.as_ref())?;
559 },
560
561 Frame::HandshakeDone => {
562 b.put_varint(0x1e)?;
563 },
564
565 Frame::Datagram { data } => {
Mike Yuf57cb852022-09-20 12:25:20 +0000566 encode_dgram_header(data.len() as u64, b)?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100567
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100568 b.put_bytes(data.as_ref())?;
569 },
Mike Yuf57cb852022-09-20 12:25:20 +0000570
571 Frame::DatagramHeader { .. } => (),
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100572 }
573
574 Ok(before - b.cap())
575 }
576
577 pub fn wire_len(&self) -> usize {
578 match self {
579 Frame::Padding { len } => *len,
580
581 Frame::Ping => 1,
582
Mike Yuf57cb852022-09-20 12:25:20 +0000583 Frame::ACK {
584 ack_delay,
585 ranges,
586 ecn_counts,
587 } => {
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100588 let mut it = ranges.iter().rev();
589
590 let first = it.next().unwrap();
591 let ack_block = (first.end - 1) - first.start;
592
593 let mut len = 1 + // frame type
594 octets::varint_len(first.end - 1) + // largest_ack
595 octets::varint_len(*ack_delay) + // ack_delay
596 octets::varint_len(it.len() as u64) + // block_count
597 octets::varint_len(ack_block); // first_block
598
599 let mut smallest_ack = first.start;
600
601 for block in it {
602 let gap = smallest_ack - block.end - 1;
603 let ack_block = (block.end - 1) - block.start;
604
605 len += octets::varint_len(gap) + // gap
606 octets::varint_len(ack_block); // ack_block
607
608 smallest_ack = block.start;
609 }
610
Mike Yuf57cb852022-09-20 12:25:20 +0000611 if let Some(ecn) = ecn_counts {
612 len += octets::varint_len(ecn.ect0_count) +
613 octets::varint_len(ecn.ect1_count) +
614 octets::varint_len(ecn.ecn_ce_count);
615 }
616
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100617 len
618 },
619
620 Frame::ResetStream {
621 stream_id,
622 error_code,
623 final_size,
624 } => {
625 1 + // frame type
626 octets::varint_len(*stream_id) + // stream_id
627 octets::varint_len(*error_code) + // error_code
628 octets::varint_len(*final_size) // final_size
629 },
630
631 Frame::StopSending {
632 stream_id,
633 error_code,
634 } => {
635 1 + // frame type
636 octets::varint_len(*stream_id) + // stream_id
637 octets::varint_len(*error_code) // error_code
638 },
639
640 Frame::Crypto { data } => {
641 1 + // frame type
Mike Yufa78f722023-04-07 09:20:19 +0000642 octets::varint_len(data.off()) + // offset
Joel Galenson96d408b2021-06-08 17:53:00 -0700643 2 + // length, always encode as 2-byte varint
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100644 data.len() // data
645 },
646
Joel Galenson96d408b2021-06-08 17:53:00 -0700647 Frame::CryptoHeader { offset, length, .. } => {
648 1 + // frame type
649 octets::varint_len(*offset) + // offset
650 2 + // length, always encode as 2-byte varint
651 length // data
652 },
653
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100654 Frame::NewToken { token } => {
655 1 + // frame type
656 octets::varint_len(token.len() as u64) + // token length
657 token.len() // token
658 },
659
660 Frame::Stream { stream_id, data } => {
661 1 + // frame type
662 octets::varint_len(*stream_id) + // stream_id
Mike Yufa78f722023-04-07 09:20:19 +0000663 octets::varint_len(data.off()) + // offset
Joel Galenson96d408b2021-06-08 17:53:00 -0700664 2 + // length, always encode as 2-byte varint
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100665 data.len() // data
666 },
667
Joel Galenson96d408b2021-06-08 17:53:00 -0700668 Frame::StreamHeader {
669 stream_id,
670 offset,
671 length,
672 ..
673 } => {
674 1 + // frame type
675 octets::varint_len(*stream_id) + // stream_id
676 octets::varint_len(*offset) + // offset
677 2 + // length, always encode as 2-byte varint
678 length // data
679 },
680
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100681 Frame::MaxData { max } => {
682 1 + // frame type
683 octets::varint_len(*max) // max
684 },
685
686 Frame::MaxStreamData { stream_id, max } => {
687 1 + // frame type
688 octets::varint_len(*stream_id) + // stream_id
689 octets::varint_len(*max) // max
690 },
691
692 Frame::MaxStreamsBidi { max } => {
693 1 + // frame type
694 octets::varint_len(*max) // max
695 },
696
697 Frame::MaxStreamsUni { max } => {
698 1 + // frame type
699 octets::varint_len(*max) // max
700 },
701
702 Frame::DataBlocked { limit } => {
703 1 + // frame type
704 octets::varint_len(*limit) // limit
705 },
706
707 Frame::StreamDataBlocked { stream_id, limit } => {
708 1 + // frame type
709 octets::varint_len(*stream_id) + // stream_id
710 octets::varint_len(*limit) // limit
711 },
712
713 Frame::StreamsBlockedBidi { limit } => {
714 1 + // frame type
715 octets::varint_len(*limit) // limit
716 },
717
718 Frame::StreamsBlockedUni { limit } => {
719 1 + // frame type
720 octets::varint_len(*limit) // limit
721 },
722
723 Frame::NewConnectionId {
724 seq_num,
725 retire_prior_to,
726 conn_id,
727 reset_token,
728 } => {
729 1 + // frame type
730 octets::varint_len(*seq_num) + // seq_num
731 octets::varint_len(*retire_prior_to) + // retire_prior_to
732 1 + // conn_id length
733 conn_id.len() + // conn_id
734 reset_token.len() // reset_token
735 },
736
737 Frame::RetireConnectionId { seq_num } => {
738 1 + // frame type
739 octets::varint_len(*seq_num) // seq_num
740 },
741
742 Frame::PathChallenge { .. } => {
743 1 + // frame type
744 8 // data
745 },
746
747 Frame::PathResponse { .. } => {
748 1 + // frame type
749 8 // data
750 },
751
752 Frame::ConnectionClose {
753 frame_type,
754 error_code,
755 reason,
756 ..
757 } => {
758 1 + // frame type
759 octets::varint_len(*error_code) + // error_code
760 octets::varint_len(*frame_type) + // frame_type
761 octets::varint_len(reason.len() as u64) + // reason_len
762 reason.len() // reason
763 },
764
765 Frame::ApplicationClose { reason, error_code } => {
766 1 + // frame type
767 octets::varint_len(*error_code) + // error_code
768 octets::varint_len(reason.len() as u64) + // reason_len
769 reason.len() // reason
770 },
771
772 Frame::HandshakeDone => {
773 1 // frame type
774 },
775
776 Frame::Datagram { data } => {
777 1 + // frame type
Mike Yuf57cb852022-09-20 12:25:20 +0000778 2 + // length, always encode as 2-byte varint
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100779 data.len() // data
780 },
Mike Yuf57cb852022-09-20 12:25:20 +0000781
782 Frame::DatagramHeader { length } => {
783 1 + // frame type
784 2 + // length, always encode as 2-byte varint
785 *length // data
786 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100787 }
788 }
789
790 pub fn ack_eliciting(&self) -> bool {
791 // Any other frame is ack-eliciting (note the `!`).
Joel Galenson96d408b2021-06-08 17:53:00 -0700792 !matches!(
793 self,
794 Frame::Padding { .. } |
795 Frame::ACK { .. } |
796 Frame::ApplicationClose { .. } |
797 Frame::ConnectionClose { .. }
798 )
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100799 }
800
Mike Yufa78f722023-04-07 09:20:19 +0000801 pub fn probing(&self) -> bool {
802 matches!(
803 self,
804 Frame::Padding { .. } |
805 Frame::NewConnectionId { .. } |
806 Frame::PathChallenge { .. } |
807 Frame::PathResponse { .. }
808 )
809 }
810
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100811 #[cfg(feature = "qlog")]
Mike Yuf57cb852022-09-20 12:25:20 +0000812 pub fn to_qlog(&self) -> QuicFrame {
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100813 match self {
Mike Yuf57cb852022-09-20 12:25:20 +0000814 Frame::Padding { .. } => QuicFrame::Padding,
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100815
Mike Yuf57cb852022-09-20 12:25:20 +0000816 Frame::Ping { .. } => QuicFrame::Ping,
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100817
Mike Yuf57cb852022-09-20 12:25:20 +0000818 Frame::ACK {
819 ack_delay,
820 ranges,
821 ecn_counts,
822 } => {
823 let ack_ranges = AckedRanges::Double(
824 ranges.iter().map(|r| (r.start, r.end - 1)).collect(),
825 );
826
827 let (ect0, ect1, ce) = match ecn_counts {
828 Some(ecn) => (
829 Some(ecn.ect0_count),
830 Some(ecn.ect1_count),
831 Some(ecn.ecn_ce_count),
832 ),
833
834 None => (None, None, None),
835 };
836
837 QuicFrame::Ack {
838 ack_delay: Some(*ack_delay as f32 / 1000.0),
839 acked_ranges: Some(ack_ranges),
840 ect1,
841 ect0,
842 ce,
843 }
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100844 },
845
846 Frame::ResetStream {
847 stream_id,
848 error_code,
849 final_size,
Mike Yuf57cb852022-09-20 12:25:20 +0000850 } => QuicFrame::ResetStream {
851 stream_id: *stream_id,
852 error_code: *error_code,
853 final_size: *final_size,
854 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100855
856 Frame::StopSending {
857 stream_id,
858 error_code,
Mike Yuf57cb852022-09-20 12:25:20 +0000859 } => QuicFrame::StopSending {
860 stream_id: *stream_id,
861 error_code: *error_code,
862 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100863
Mike Yuf57cb852022-09-20 12:25:20 +0000864 Frame::Crypto { data } => QuicFrame::Crypto {
865 offset: data.off(),
866 length: data.len() as u64,
867 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100868
Mike Yuf57cb852022-09-20 12:25:20 +0000869 Frame::CryptoHeader { offset, length } => QuicFrame::Crypto {
870 offset: *offset,
871 length: *length as u64,
872 },
Joel Galenson96d408b2021-06-08 17:53:00 -0700873
Mike Yuf57cb852022-09-20 12:25:20 +0000874 Frame::NewToken { token } => QuicFrame::NewToken {
875 token: qlog::Token {
876 // TODO: pick the token type some how
Mike Yufa78f722023-04-07 09:20:19 +0000877 ty: Some(qlog::TokenType::Retry),
878 raw: Some(qlog::events::RawInfo {
879 data: qlog::HexSlice::maybe_string(Some(token)),
880 length: Some(token.len() as u64),
881 payload_length: None,
882 }),
Mike Yuf57cb852022-09-20 12:25:20 +0000883 details: None,
884 },
885 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100886
Mike Yuf57cb852022-09-20 12:25:20 +0000887 Frame::Stream { stream_id, data } => QuicFrame::Stream {
888 stream_id: *stream_id,
Mike Yufa78f722023-04-07 09:20:19 +0000889 offset: data.off(),
Mike Yuf57cb852022-09-20 12:25:20 +0000890 length: data.len() as u64,
Mike Yufa78f722023-04-07 09:20:19 +0000891 fin: data.fin().then_some(true),
Mike Yuf57cb852022-09-20 12:25:20 +0000892 raw: None,
893 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100894
Joel Galenson96d408b2021-06-08 17:53:00 -0700895 Frame::StreamHeader {
896 stream_id,
897 offset,
898 length,
899 fin,
Mike Yuf57cb852022-09-20 12:25:20 +0000900 } => QuicFrame::Stream {
901 stream_id: *stream_id,
902 offset: *offset,
903 length: *length as u64,
904 fin: fin.then(|| true),
905 raw: None,
906 },
Joel Galenson96d408b2021-06-08 17:53:00 -0700907
Mike Yuf57cb852022-09-20 12:25:20 +0000908 Frame::MaxData { max } => QuicFrame::MaxData { maximum: *max },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100909
Mike Yuf57cb852022-09-20 12:25:20 +0000910 Frame::MaxStreamData { stream_id, max } => QuicFrame::MaxStreamData {
911 stream_id: *stream_id,
912 maximum: *max,
913 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100914
Mike Yuf57cb852022-09-20 12:25:20 +0000915 Frame::MaxStreamsBidi { max } => QuicFrame::MaxStreams {
916 stream_type: StreamType::Bidirectional,
917 maximum: *max,
918 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100919
Mike Yuf57cb852022-09-20 12:25:20 +0000920 Frame::MaxStreamsUni { max } => QuicFrame::MaxStreams {
921 stream_type: StreamType::Unidirectional,
922 maximum: *max,
923 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100924
925 Frame::DataBlocked { limit } =>
Mike Yuf57cb852022-09-20 12:25:20 +0000926 QuicFrame::DataBlocked { limit: *limit },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100927
928 Frame::StreamDataBlocked { stream_id, limit } =>
Mike Yuf57cb852022-09-20 12:25:20 +0000929 QuicFrame::StreamDataBlocked {
930 stream_id: *stream_id,
931 limit: *limit,
932 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100933
Mike Yuf57cb852022-09-20 12:25:20 +0000934 Frame::StreamsBlockedBidi { limit } => QuicFrame::StreamsBlocked {
935 stream_type: StreamType::Bidirectional,
936 limit: *limit,
937 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100938
Mike Yuf57cb852022-09-20 12:25:20 +0000939 Frame::StreamsBlockedUni { limit } => QuicFrame::StreamsBlocked {
940 stream_type: StreamType::Unidirectional,
941 limit: *limit,
942 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100943
944 Frame::NewConnectionId {
945 seq_num,
946 retire_prior_to,
947 conn_id,
Mike Yuf57cb852022-09-20 12:25:20 +0000948 reset_token,
949 } => QuicFrame::NewConnectionId {
950 sequence_number: *seq_num as u32,
951 retire_prior_to: *retire_prior_to as u32,
952 connection_id_length: Some(conn_id.len() as u8),
953 connection_id: format!("{}", qlog::HexSlice::new(conn_id)),
Mike Yufa78f722023-04-07 09:20:19 +0000954 stateless_reset_token: qlog::HexSlice::maybe_string(Some(
955 reset_token,
956 )),
Mike Yuf57cb852022-09-20 12:25:20 +0000957 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100958
959 Frame::RetireConnectionId { seq_num } =>
Mike Yuf57cb852022-09-20 12:25:20 +0000960 QuicFrame::RetireConnectionId {
961 sequence_number: *seq_num as u32,
962 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100963
Mike Yuf57cb852022-09-20 12:25:20 +0000964 Frame::PathChallenge { .. } =>
965 QuicFrame::PathChallenge { data: None },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100966
Mike Yuf57cb852022-09-20 12:25:20 +0000967 Frame::PathResponse { .. } => QuicFrame::PathResponse { data: None },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100968
969 Frame::ConnectionClose {
970 error_code, reason, ..
Mike Yuf57cb852022-09-20 12:25:20 +0000971 } => QuicFrame::ConnectionClose {
972 error_space: Some(ErrorSpace::TransportError),
973 error_code: Some(*error_code),
Mike Yufa78f722023-04-07 09:20:19 +0000974 error_code_value: None, // raw error is no different for us
975 reason: Some(String::from_utf8_lossy(reason).into_owned()),
Mike Yuf57cb852022-09-20 12:25:20 +0000976 trigger_frame_type: None, // don't know trigger type
977 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100978
979 Frame::ApplicationClose { error_code, reason } =>
Mike Yuf57cb852022-09-20 12:25:20 +0000980 QuicFrame::ConnectionClose {
981 error_space: Some(ErrorSpace::ApplicationError),
982 error_code: Some(*error_code),
Mike Yufa78f722023-04-07 09:20:19 +0000983 error_code_value: None, // raw error is no different for us
984 reason: Some(String::from_utf8_lossy(reason).into_owned()),
Mike Yuf57cb852022-09-20 12:25:20 +0000985 trigger_frame_type: None, // don't know trigger type
986 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100987
Mike Yuf57cb852022-09-20 12:25:20 +0000988 Frame::HandshakeDone => QuicFrame::HandshakeDone,
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100989
Mike Yuf57cb852022-09-20 12:25:20 +0000990 Frame::Datagram { data } => QuicFrame::Datagram {
991 length: data.len() as u64,
992 raw: None,
993 },
994
995 Frame::DatagramHeader { length } => QuicFrame::Datagram {
996 length: *length as u64,
997 raw: None,
998 },
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +0100999 }
1000 }
1001}
1002
1003impl std::fmt::Debug for Frame {
1004 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1005 match self {
1006 Frame::Padding { len } => {
Mike Yufa78f722023-04-07 09:20:19 +00001007 write!(f, "PADDING len={len}")?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001008 },
1009
1010 Frame::Ping => {
1011 write!(f, "PING")?;
1012 },
1013
Mike Yuf57cb852022-09-20 12:25:20 +00001014 Frame::ACK {
1015 ack_delay,
1016 ranges,
1017 ecn_counts,
1018 } => {
1019 write!(
1020 f,
Mike Yufa78f722023-04-07 09:20:19 +00001021 "ACK delay={ack_delay} blocks={ranges:?} ecn_counts={ecn_counts:?}"
Mike Yuf57cb852022-09-20 12:25:20 +00001022 )?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001023 },
1024
1025 Frame::ResetStream {
1026 stream_id,
1027 error_code,
1028 final_size,
1029 } => {
1030 write!(
1031 f,
Mike Yufa78f722023-04-07 09:20:19 +00001032 "RESET_STREAM stream={stream_id} err={error_code:x} size={final_size}"
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001033 )?;
1034 },
1035
1036 Frame::StopSending {
1037 stream_id,
1038 error_code,
1039 } => {
Mike Yufa78f722023-04-07 09:20:19 +00001040 write!(f, "STOP_SENDING stream={stream_id} err={error_code:x}")?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001041 },
1042
1043 Frame::Crypto { data } => {
1044 write!(f, "CRYPTO off={} len={}", data.off(), data.len())?;
1045 },
1046
Joel Galenson96d408b2021-06-08 17:53:00 -07001047 Frame::CryptoHeader { offset, length } => {
Mike Yufa78f722023-04-07 09:20:19 +00001048 write!(f, "CRYPTO off={offset} len={length}")?;
Joel Galenson96d408b2021-06-08 17:53:00 -07001049 },
1050
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001051 Frame::NewToken { .. } => {
1052 write!(f, "NEW_TOKEN (TODO)")?;
1053 },
1054
1055 Frame::Stream { stream_id, data } => {
1056 write!(
1057 f,
1058 "STREAM id={} off={} len={} fin={}",
1059 stream_id,
1060 data.off(),
1061 data.len(),
1062 data.fin()
1063 )?;
1064 },
1065
Joel Galenson96d408b2021-06-08 17:53:00 -07001066 Frame::StreamHeader {
1067 stream_id,
1068 offset,
1069 length,
1070 fin,
1071 } => {
1072 write!(
1073 f,
Mike Yufa78f722023-04-07 09:20:19 +00001074 "STREAM id={stream_id} off={offset} len={length} fin={fin}"
Joel Galenson96d408b2021-06-08 17:53:00 -07001075 )?;
1076 },
1077
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001078 Frame::MaxData { max } => {
Mike Yufa78f722023-04-07 09:20:19 +00001079 write!(f, "MAX_DATA max={max}")?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001080 },
1081
1082 Frame::MaxStreamData { stream_id, max } => {
Mike Yufa78f722023-04-07 09:20:19 +00001083 write!(f, "MAX_STREAM_DATA stream={stream_id} max={max}")?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001084 },
1085
1086 Frame::MaxStreamsBidi { max } => {
Mike Yufa78f722023-04-07 09:20:19 +00001087 write!(f, "MAX_STREAMS type=bidi max={max}")?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001088 },
1089
1090 Frame::MaxStreamsUni { max } => {
Mike Yufa78f722023-04-07 09:20:19 +00001091 write!(f, "MAX_STREAMS type=uni max={max}")?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001092 },
1093
1094 Frame::DataBlocked { limit } => {
Mike Yufa78f722023-04-07 09:20:19 +00001095 write!(f, "DATA_BLOCKED limit={limit}")?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001096 },
1097
1098 Frame::StreamDataBlocked { stream_id, limit } => {
1099 write!(
1100 f,
Mike Yufa78f722023-04-07 09:20:19 +00001101 "STREAM_DATA_BLOCKED stream={stream_id} limit={limit}"
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001102 )?;
1103 },
1104
1105 Frame::StreamsBlockedBidi { limit } => {
Mike Yufa78f722023-04-07 09:20:19 +00001106 write!(f, "STREAMS_BLOCKED type=bidi limit={limit}")?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001107 },
1108
1109 Frame::StreamsBlockedUni { limit } => {
Mike Yufa78f722023-04-07 09:20:19 +00001110 write!(f, "STREAMS_BLOCKED type=uni limit={limit}")?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001111 },
1112
Mike Yufa78f722023-04-07 09:20:19 +00001113 Frame::NewConnectionId {
1114 seq_num,
1115 retire_prior_to,
1116 conn_id,
1117 reset_token,
1118 } => {
1119 write!(
1120 f,
1121 "NEW_CONNECTION_ID seq_num={seq_num} retire_prior_to={retire_prior_to} conn_id={conn_id:02x?} reset_token={reset_token:02x?}",
1122 )?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001123 },
1124
Mike Yufa78f722023-04-07 09:20:19 +00001125 Frame::RetireConnectionId { seq_num } => {
1126 write!(f, "RETIRE_CONNECTION_ID seq_num={seq_num}")?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001127 },
1128
1129 Frame::PathChallenge { data } => {
Mike Yufa78f722023-04-07 09:20:19 +00001130 write!(f, "PATH_CHALLENGE data={data:02x?}")?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001131 },
1132
1133 Frame::PathResponse { data } => {
Mike Yufa78f722023-04-07 09:20:19 +00001134 write!(f, "PATH_RESPONSE data={data:02x?}")?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001135 },
1136
1137 Frame::ConnectionClose {
1138 error_code,
1139 frame_type,
1140 reason,
1141 } => {
1142 write!(
1143 f,
Mike Yufa78f722023-04-07 09:20:19 +00001144 "CONNECTION_CLOSE err={error_code:x} frame={frame_type:x} reason={reason:x?}"
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001145 )?;
1146 },
1147
1148 Frame::ApplicationClose { error_code, reason } => {
1149 write!(
1150 f,
Mike Yufa78f722023-04-07 09:20:19 +00001151 "APPLICATION_CLOSE err={error_code:x} reason={reason:x?}"
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001152 )?;
1153 },
1154
1155 Frame::HandshakeDone => {
1156 write!(f, "HANDSHAKE_DONE")?;
1157 },
1158
1159 Frame::Datagram { data } => {
Mike Yuf57cb852022-09-20 12:25:20 +00001160 write!(f, "DATAGRAM len={}", data.len())?;
1161 },
1162
1163 Frame::DatagramHeader { length } => {
Mike Yufa78f722023-04-07 09:20:19 +00001164 write!(f, "DATAGRAM len={length}")?;
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001165 },
1166 }
1167
1168 Ok(())
1169 }
1170}
1171
Mike Yuf57cb852022-09-20 12:25:20 +00001172fn parse_ack_frame(ty: u64, b: &mut octets::Octets) -> Result<Frame> {
1173 let first = ty as u8;
1174
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001175 let largest_ack = b.get_varint()?;
1176 let ack_delay = b.get_varint()?;
1177 let block_count = b.get_varint()?;
1178 let ack_block = b.get_varint()?;
1179
1180 if largest_ack < ack_block {
1181 return Err(Error::InvalidFrame);
1182 }
1183
1184 let mut smallest_ack = largest_ack - ack_block;
1185
1186 let mut ranges = ranges::RangeSet::default();
1187
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001188 ranges.insert(smallest_ack..largest_ack + 1);
1189
1190 for _i in 0..block_count {
1191 let gap = b.get_varint()?;
1192
1193 if smallest_ack < 2 + gap {
1194 return Err(Error::InvalidFrame);
1195 }
1196
1197 let largest_ack = (smallest_ack - gap) - 2;
1198 let ack_block = b.get_varint()?;
1199
1200 if largest_ack < ack_block {
1201 return Err(Error::InvalidFrame);
1202 }
1203
1204 smallest_ack = largest_ack - ack_block;
1205
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001206 ranges.insert(smallest_ack..largest_ack + 1);
1207 }
1208
Mike Yuf57cb852022-09-20 12:25:20 +00001209 let ecn_counts = if first & 0x01 != 0 {
1210 let ecn = EcnCounts {
1211 ect0_count: b.get_varint()?,
1212 ect1_count: b.get_varint()?,
1213 ecn_ce_count: b.get_varint()?,
1214 };
1215
1216 Some(ecn)
1217 } else {
1218 None
1219 };
1220
1221 Ok(Frame::ACK {
1222 ack_delay,
1223 ranges,
1224 ecn_counts,
1225 })
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001226}
1227
Joel Galenson96d408b2021-06-08 17:53:00 -07001228pub fn encode_crypto_header(
1229 offset: u64, length: u64, b: &mut octets::OctetsMut,
1230) -> Result<()> {
1231 b.put_varint(0x06)?;
1232
1233 b.put_varint(offset)?;
1234
1235 // Always encode length field as 2-byte varint.
1236 b.put_varint_with_len(length, 2)?;
1237
1238 Ok(())
1239}
1240
1241pub fn encode_stream_header(
1242 stream_id: u64, offset: u64, length: u64, fin: bool,
1243 b: &mut octets::OctetsMut,
1244) -> Result<()> {
1245 let mut ty: u8 = 0x08;
1246
1247 // Always encode offset.
1248 ty |= 0x04;
1249
1250 // Always encode length.
1251 ty |= 0x02;
1252
1253 if fin {
1254 ty |= 0x01;
1255 }
1256
1257 b.put_varint(u64::from(ty))?;
1258
1259 b.put_varint(stream_id)?;
1260 b.put_varint(offset)?;
1261
1262 // Always encode length field as 2-byte varint.
1263 b.put_varint_with_len(length, 2)?;
1264
1265 Ok(())
1266}
1267
Mike Yuf57cb852022-09-20 12:25:20 +00001268pub fn encode_dgram_header(length: u64, b: &mut octets::OctetsMut) -> Result<()> {
1269 let mut ty: u8 = 0x30;
1270
1271 // Always encode length
1272 ty |= 0x01;
1273
1274 b.put_varint(u64::from(ty))?;
1275
1276 // Always encode length field as 2-byte varint.
1277 b.put_varint_with_len(length, 2)?;
1278
1279 Ok(())
1280}
1281
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001282fn parse_stream_frame(ty: u64, b: &mut octets::Octets) -> Result<Frame> {
1283 let first = ty as u8;
1284
1285 let stream_id = b.get_varint()?;
1286
1287 let offset = if first & 0x04 != 0 {
1288 b.get_varint()?
1289 } else {
1290 0
1291 };
1292
1293 let len = if first & 0x02 != 0 {
1294 b.get_varint()? as usize
1295 } else {
1296 b.cap()
1297 };
1298
1299 if offset + len as u64 >= MAX_STREAM_SIZE {
1300 return Err(Error::InvalidFrame);
1301 }
1302
1303 let fin = first & 0x01 != 0;
1304
1305 let data = b.get_bytes(len)?;
1306 let data = stream::RangeBuf::from(data.as_ref(), offset, fin);
1307
1308 Ok(Frame::Stream { stream_id, data })
1309}
1310
1311fn parse_datagram_frame(ty: u64, b: &mut octets::Octets) -> Result<Frame> {
1312 let first = ty as u8;
1313
1314 let len = if first & 0x01 != 0 {
1315 b.get_varint()? as usize
1316 } else {
1317 b.cap()
1318 };
1319
1320 let data = b.get_bytes(len)?;
1321
1322 Ok(Frame::Datagram {
1323 data: Vec::from(data.buf()),
1324 })
1325}
1326
1327#[cfg(test)]
1328mod tests {
1329 use super::*;
1330
1331 #[test]
1332 fn padding() {
1333 let mut d = [42; 128];
1334
1335 let frame = Frame::Padding { len: 128 };
1336
1337 let wire_len = {
1338 let mut b = octets::OctetsMut::with_slice(&mut d);
1339 frame.to_bytes(&mut b).unwrap()
1340 };
1341
1342 assert_eq!(wire_len, 128);
1343
1344 let mut b = octets::Octets::with_slice(&d);
1345 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1346
1347 let mut b = octets::Octets::with_slice(&d);
1348 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_ok());
1349
1350 let mut b = octets::Octets::with_slice(&d);
1351 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1352
1353 let mut b = octets::Octets::with_slice(&d);
1354 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_ok());
1355 }
1356
1357 #[test]
1358 fn ping() {
1359 let mut d = [42; 128];
1360
1361 let frame = Frame::Ping;
1362
1363 let wire_len = {
1364 let mut b = octets::OctetsMut::with_slice(&mut d);
1365 frame.to_bytes(&mut b).unwrap()
1366 };
1367
1368 assert_eq!(wire_len, 1);
Mike Yufa78f722023-04-07 09:20:19 +00001369 assert_eq!(&d[..wire_len], [0x01_u8]);
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001370
1371 let mut b = octets::Octets::with_slice(&d);
1372 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1373
1374 let mut b = octets::Octets::with_slice(&d);
1375 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1376
1377 let mut b = octets::Octets::with_slice(&d);
1378 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_ok());
1379
1380 let mut b = octets::Octets::with_slice(&d);
1381 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_ok());
1382 }
1383
1384 #[test]
1385 fn ack() {
1386 let mut d = [42; 128];
1387
1388 let mut ranges = ranges::RangeSet::default();
1389 ranges.insert(4..7);
1390 ranges.insert(9..12);
1391 ranges.insert(15..19);
1392 ranges.insert(3000..5000);
1393
1394 let frame = Frame::ACK {
1395 ack_delay: 874_656_534,
1396 ranges,
Mike Yuf57cb852022-09-20 12:25:20 +00001397 ecn_counts: None,
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001398 };
1399
1400 let wire_len = {
1401 let mut b = octets::OctetsMut::with_slice(&mut d);
1402 frame.to_bytes(&mut b).unwrap()
1403 };
1404
1405 assert_eq!(wire_len, 17);
1406
1407 let mut b = octets::Octets::with_slice(&d);
1408 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1409
1410 let mut b = octets::Octets::with_slice(&d);
1411 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_ok());
1412
1413 let mut b = octets::Octets::with_slice(&d);
1414 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
1415
1416 let mut b = octets::Octets::with_slice(&d);
1417 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_ok());
1418 }
1419
1420 #[test]
Mike Yuf57cb852022-09-20 12:25:20 +00001421 fn ack_ecn() {
1422 let mut d = [42; 128];
1423
1424 let mut ranges = ranges::RangeSet::default();
1425 ranges.insert(4..7);
1426 ranges.insert(9..12);
1427 ranges.insert(15..19);
1428 ranges.insert(3000..5000);
1429
1430 let ecn_counts = Some(EcnCounts {
1431 ect0_count: 100,
1432 ect1_count: 200,
1433 ecn_ce_count: 300,
1434 });
1435
1436 let frame = Frame::ACK {
1437 ack_delay: 874_656_534,
1438 ranges,
1439 ecn_counts,
1440 };
1441
1442 let wire_len = {
1443 let mut b = octets::OctetsMut::with_slice(&mut d);
1444 frame.to_bytes(&mut b).unwrap()
1445 };
1446
1447 assert_eq!(wire_len, 23);
1448
1449 let mut b = octets::Octets::with_slice(&d);
1450 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1451
1452 let mut b = octets::Octets::with_slice(&d);
1453 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_ok());
1454
1455 let mut b = octets::Octets::with_slice(&d);
1456 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
1457
1458 let mut b = octets::Octets::with_slice(&d);
1459 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_ok());
1460 }
1461
1462 #[test]
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001463 fn reset_stream() {
1464 let mut d = [42; 128];
1465
1466 let frame = Frame::ResetStream {
1467 stream_id: 123_213,
1468 error_code: 21_123_767,
1469 final_size: 21_123_767,
1470 };
1471
1472 let wire_len = {
1473 let mut b = octets::OctetsMut::with_slice(&mut d);
1474 frame.to_bytes(&mut b).unwrap()
1475 };
1476
1477 assert_eq!(wire_len, 13);
1478
1479 let mut b = octets::Octets::with_slice(&d);
1480 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1481
1482 let mut b = octets::Octets::with_slice(&d);
1483 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1484
1485 let mut b = octets::Octets::with_slice(&d);
1486 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1487
1488 let mut b = octets::Octets::with_slice(&d);
1489 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1490 }
1491
1492 #[test]
1493 fn stop_sending() {
1494 let mut d = [42; 128];
1495
1496 let frame = Frame::StopSending {
1497 stream_id: 123_213,
1498 error_code: 15_352,
1499 };
1500
1501 let wire_len = {
1502 let mut b = octets::OctetsMut::with_slice(&mut d);
1503 frame.to_bytes(&mut b).unwrap()
1504 };
1505
1506 assert_eq!(wire_len, 7);
1507
1508 let mut b = octets::Octets::with_slice(&d);
1509 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1510
1511 let mut b = octets::Octets::with_slice(&d);
1512 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1513
1514 let mut b = octets::Octets::with_slice(&d);
1515 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1516
1517 let mut b = octets::Octets::with_slice(&d);
1518 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1519 }
1520
1521 #[test]
1522 fn crypto() {
1523 let mut d = [42; 128];
1524
1525 let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
1526
1527 let frame = Frame::Crypto {
1528 data: stream::RangeBuf::from(&data, 1230976, false),
1529 };
1530
1531 let wire_len = {
1532 let mut b = octets::OctetsMut::with_slice(&mut d);
1533 frame.to_bytes(&mut b).unwrap()
1534 };
1535
Joel Galenson96d408b2021-06-08 17:53:00 -07001536 assert_eq!(wire_len, 19);
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001537
1538 let mut b = octets::Octets::with_slice(&d);
1539 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1540
1541 let mut b = octets::Octets::with_slice(&d);
1542 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_ok());
1543
1544 let mut b = octets::Octets::with_slice(&d);
1545 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
1546
1547 let mut b = octets::Octets::with_slice(&d);
1548 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_ok());
1549 }
1550
1551 #[test]
1552 fn new_token() {
1553 let mut d = [42; 128];
1554
1555 let frame = Frame::NewToken {
1556 token: Vec::from("this is a token"),
1557 };
1558
1559 let wire_len = {
1560 let mut b = octets::OctetsMut::with_slice(&mut d);
1561 frame.to_bytes(&mut b).unwrap()
1562 };
1563
1564 assert_eq!(wire_len, 17);
1565
1566 let mut b = octets::Octets::with_slice(&d);
1567 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1568
1569 let mut b = octets::Octets::with_slice(&d);
1570 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1571
1572 let mut b = octets::Octets::with_slice(&d);
1573 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
1574
1575 let mut b = octets::Octets::with_slice(&d);
1576 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1577 }
1578
1579 #[test]
1580 fn stream() {
1581 let mut d = [42; 128];
1582
1583 let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
1584
1585 let frame = Frame::Stream {
1586 stream_id: 32,
1587 data: stream::RangeBuf::from(&data, 1230976, true),
1588 };
1589
1590 let wire_len = {
1591 let mut b = octets::OctetsMut::with_slice(&mut d);
1592 frame.to_bytes(&mut b).unwrap()
1593 };
1594
Joel Galenson96d408b2021-06-08 17:53:00 -07001595 assert_eq!(wire_len, 20);
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001596
1597 let mut b = octets::Octets::with_slice(&d);
1598 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1599
1600 let mut b = octets::Octets::with_slice(&d);
1601 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1602
1603 let mut b = octets::Octets::with_slice(&d);
1604 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1605
1606 let mut b = octets::Octets::with_slice(&d);
1607 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1608 }
1609
1610 #[test]
1611 fn stream_too_big() {
1612 let mut d = [42; 128];
1613
1614 let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
1615
1616 let frame = Frame::Stream {
1617 stream_id: 32,
1618 data: stream::RangeBuf::from(&data, MAX_STREAM_SIZE - 11, true),
1619 };
1620
1621 let wire_len = {
1622 let mut b = octets::OctetsMut::with_slice(&mut d);
1623 frame.to_bytes(&mut b).unwrap()
1624 };
1625
Joel Galenson96d408b2021-06-08 17:53:00 -07001626 assert_eq!(wire_len, 24);
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001627
1628 let mut b = octets::Octets::with_slice(&d);
1629 assert_eq!(
1630 Frame::from_bytes(&mut b, packet::Type::Short),
1631 Err(Error::InvalidFrame)
1632 );
1633 }
1634
1635 #[test]
1636 fn max_data() {
1637 let mut d = [42; 128];
1638
1639 let frame = Frame::MaxData { max: 128_318_273 };
1640
1641 let wire_len = {
1642 let mut b = octets::OctetsMut::with_slice(&mut d);
1643 frame.to_bytes(&mut b).unwrap()
1644 };
1645
1646 assert_eq!(wire_len, 5);
1647
1648 let mut b = octets::Octets::with_slice(&d);
1649 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1650
1651 let mut b = octets::Octets::with_slice(&d);
1652 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1653
1654 let mut b = octets::Octets::with_slice(&d);
1655 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1656
1657 let mut b = octets::Octets::with_slice(&d);
1658 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1659 }
1660
1661 #[test]
1662 fn max_stream_data() {
1663 let mut d = [42; 128];
1664
1665 let frame = Frame::MaxStreamData {
1666 stream_id: 12_321,
1667 max: 128_318_273,
1668 };
1669
1670 let wire_len = {
1671 let mut b = octets::OctetsMut::with_slice(&mut d);
1672 frame.to_bytes(&mut b).unwrap()
1673 };
1674
1675 assert_eq!(wire_len, 7);
1676
1677 let mut b = octets::Octets::with_slice(&d);
1678 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1679
1680 let mut b = octets::Octets::with_slice(&d);
1681 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1682
1683 let mut b = octets::Octets::with_slice(&d);
1684 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1685
1686 let mut b = octets::Octets::with_slice(&d);
1687 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1688 }
1689
1690 #[test]
1691 fn max_streams_bidi() {
1692 let mut d = [42; 128];
1693
1694 let frame = Frame::MaxStreamsBidi { max: 128_318_273 };
1695
1696 let wire_len = {
1697 let mut b = octets::OctetsMut::with_slice(&mut d);
1698 frame.to_bytes(&mut b).unwrap()
1699 };
1700
1701 assert_eq!(wire_len, 5);
1702
1703 let mut b = octets::Octets::with_slice(&d);
1704 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1705
1706 let mut b = octets::Octets::with_slice(&d);
1707 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1708
1709 let mut b = octets::Octets::with_slice(&d);
1710 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1711
1712 let mut b = octets::Octets::with_slice(&d);
1713 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1714 }
1715
1716 #[test]
1717 fn max_streams_uni() {
1718 let mut d = [42; 128];
1719
1720 let frame = Frame::MaxStreamsUni { max: 128_318_273 };
1721
1722 let wire_len = {
1723 let mut b = octets::OctetsMut::with_slice(&mut d);
1724 frame.to_bytes(&mut b).unwrap()
1725 };
1726
1727 assert_eq!(wire_len, 5);
1728
1729 let mut b = octets::Octets::with_slice(&d);
1730 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1731
1732 let mut b = octets::Octets::with_slice(&d);
1733 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1734
1735 let mut b = octets::Octets::with_slice(&d);
1736 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1737
1738 let mut b = octets::Octets::with_slice(&d);
1739 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1740 }
1741
1742 #[test]
1743 fn data_blocked() {
1744 let mut d = [42; 128];
1745
1746 let frame = Frame::DataBlocked { limit: 128_318_273 };
1747
1748 let wire_len = {
1749 let mut b = octets::OctetsMut::with_slice(&mut d);
1750 frame.to_bytes(&mut b).unwrap()
1751 };
1752
1753 assert_eq!(wire_len, 5);
1754
1755 let mut b = octets::Octets::with_slice(&d);
1756 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1757
1758 let mut b = octets::Octets::with_slice(&d);
1759 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1760
1761 let mut b = octets::Octets::with_slice(&d);
1762 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1763
1764 let mut b = octets::Octets::with_slice(&d);
1765 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1766 }
1767
1768 #[test]
1769 fn stream_data_blocked() {
1770 let mut d = [42; 128];
1771
1772 let frame = Frame::StreamDataBlocked {
1773 stream_id: 12_321,
1774 limit: 128_318_273,
1775 };
1776
1777 let wire_len = {
1778 let mut b = octets::OctetsMut::with_slice(&mut d);
1779 frame.to_bytes(&mut b).unwrap()
1780 };
1781
1782 assert_eq!(wire_len, 7);
1783
1784 let mut b = octets::Octets::with_slice(&d);
1785 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1786
1787 let mut b = octets::Octets::with_slice(&d);
1788 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1789
1790 let mut b = octets::Octets::with_slice(&d);
1791 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1792
1793 let mut b = octets::Octets::with_slice(&d);
1794 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1795 }
1796
1797 #[test]
1798 fn streams_blocked_bidi() {
1799 let mut d = [42; 128];
1800
1801 let frame = Frame::StreamsBlockedBidi { limit: 128_318_273 };
1802
1803 let wire_len = {
1804 let mut b = octets::OctetsMut::with_slice(&mut d);
1805 frame.to_bytes(&mut b).unwrap()
1806 };
1807
1808 assert_eq!(wire_len, 5);
1809
1810 let mut b = octets::Octets::with_slice(&d);
1811 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1812
1813 let mut b = octets::Octets::with_slice(&d);
1814 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1815
1816 let mut b = octets::Octets::with_slice(&d);
1817 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1818
1819 let mut b = octets::Octets::with_slice(&d);
1820 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1821 }
1822
1823 #[test]
1824 fn streams_blocked_uni() {
1825 let mut d = [42; 128];
1826
1827 let frame = Frame::StreamsBlockedUni { limit: 128_318_273 };
1828
1829 let wire_len = {
1830 let mut b = octets::OctetsMut::with_slice(&mut d);
1831 frame.to_bytes(&mut b).unwrap()
1832 };
1833
1834 assert_eq!(wire_len, 5);
1835
1836 let mut b = octets::Octets::with_slice(&d);
1837 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1838
1839 let mut b = octets::Octets::with_slice(&d);
1840 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1841
1842 let mut b = octets::Octets::with_slice(&d);
1843 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1844
1845 let mut b = octets::Octets::with_slice(&d);
1846 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1847 }
1848
1849 #[test]
1850 fn new_connection_id() {
1851 let mut d = [42; 128];
1852
1853 let frame = Frame::NewConnectionId {
1854 seq_num: 123_213,
1855 retire_prior_to: 122_211,
1856 conn_id: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
Mike Yuf57cb852022-09-20 12:25:20 +00001857 reset_token: [0x42; 16],
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001858 };
1859
1860 let wire_len = {
1861 let mut b = octets::OctetsMut::with_slice(&mut d);
1862 frame.to_bytes(&mut b).unwrap()
1863 };
1864
1865 assert_eq!(wire_len, 41);
1866
1867 let mut b = octets::Octets::with_slice(&d);
1868 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1869
1870 let mut b = octets::Octets::with_slice(&d);
1871 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1872
1873 let mut b = octets::Octets::with_slice(&d);
1874 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1875
1876 let mut b = octets::Octets::with_slice(&d);
1877 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1878 }
1879
1880 #[test]
1881 fn retire_connection_id() {
1882 let mut d = [42; 128];
1883
1884 let frame = Frame::RetireConnectionId { seq_num: 123_213 };
1885
1886 let wire_len = {
1887 let mut b = octets::OctetsMut::with_slice(&mut d);
1888 frame.to_bytes(&mut b).unwrap()
1889 };
1890
1891 assert_eq!(wire_len, 5);
1892
1893 let mut b = octets::Octets::with_slice(&d);
1894 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1895
1896 let mut b = octets::Octets::with_slice(&d);
1897 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1898
1899 let mut b = octets::Octets::with_slice(&d);
1900 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
1901
1902 let mut b = octets::Octets::with_slice(&d);
1903 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1904 }
1905
1906 #[test]
1907 fn path_challenge() {
1908 let mut d = [42; 128];
1909
1910 let frame = Frame::PathChallenge {
Mike Yuf57cb852022-09-20 12:25:20 +00001911 data: [1, 2, 3, 4, 5, 6, 7, 8],
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001912 };
1913
1914 let wire_len = {
1915 let mut b = octets::OctetsMut::with_slice(&mut d);
1916 frame.to_bytes(&mut b).unwrap()
1917 };
1918
1919 assert_eq!(wire_len, 9);
1920
1921 let mut b = octets::Octets::with_slice(&d);
1922 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1923
1924 let mut b = octets::Octets::with_slice(&d);
1925 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1926
1927 let mut b = octets::Octets::with_slice(&d);
1928 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1929
1930 let mut b = octets::Octets::with_slice(&d);
1931 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1932 }
1933
1934 #[test]
1935 fn path_response() {
1936 let mut d = [42; 128];
1937
1938 let frame = Frame::PathResponse {
Mike Yuf57cb852022-09-20 12:25:20 +00001939 data: [1, 2, 3, 4, 5, 6, 7, 8],
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01001940 };
1941
1942 let wire_len = {
1943 let mut b = octets::OctetsMut::with_slice(&mut d);
1944 frame.to_bytes(&mut b).unwrap()
1945 };
1946
1947 assert_eq!(wire_len, 9);
1948
1949 let mut b = octets::Octets::with_slice(&d);
1950 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1951
1952 let mut b = octets::Octets::with_slice(&d);
1953 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1954
1955 let mut b = octets::Octets::with_slice(&d);
1956 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
1957
1958 let mut b = octets::Octets::with_slice(&d);
1959 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1960 }
1961
1962 #[test]
1963 fn connection_close() {
1964 let mut d = [42; 128];
1965
1966 let frame = Frame::ConnectionClose {
1967 error_code: 0xbeef,
1968 frame_type: 523_423,
1969 reason: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
1970 };
1971
1972 let wire_len = {
1973 let mut b = octets::OctetsMut::with_slice(&mut d);
1974 frame.to_bytes(&mut b).unwrap()
1975 };
1976
1977 assert_eq!(wire_len, 22);
1978
1979 let mut b = octets::Octets::with_slice(&d);
1980 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1981
1982 let mut b = octets::Octets::with_slice(&d);
1983 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_ok());
1984
1985 let mut b = octets::Octets::with_slice(&d);
1986 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
1987
1988 let mut b = octets::Octets::with_slice(&d);
1989 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_ok());
1990 }
1991
1992 #[test]
1993 fn application_close() {
1994 let mut d = [42; 128];
1995
1996 let frame = Frame::ApplicationClose {
1997 error_code: 0xbeef,
1998 reason: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
1999 };
2000
2001 let wire_len = {
2002 let mut b = octets::OctetsMut::with_slice(&mut d);
2003 frame.to_bytes(&mut b).unwrap()
2004 };
2005
2006 assert_eq!(wire_len, 18);
2007
2008 let mut b = octets::Octets::with_slice(&d);
2009 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
2010
2011 let mut b = octets::Octets::with_slice(&d);
2012 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
2013
2014 let mut b = octets::Octets::with_slice(&d);
2015 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
2016
2017 let mut b = octets::Octets::with_slice(&d);
2018 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
2019 }
2020
2021 #[test]
2022 fn handshake_done() {
2023 let mut d = [42; 128];
2024
2025 let frame = Frame::HandshakeDone;
2026
2027 let wire_len = {
2028 let mut b = octets::OctetsMut::with_slice(&mut d);
2029 frame.to_bytes(&mut b).unwrap()
2030 };
2031
2032 assert_eq!(wire_len, 1);
2033
2034 let mut b = octets::Octets::with_slice(&d);
2035 assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
2036
2037 let mut b = octets::Octets::with_slice(&d);
2038 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
2039
2040 let mut b = octets::Octets::with_slice(&d);
2041 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
2042
2043 let mut b = octets::Octets::with_slice(&d);
2044 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
2045 }
2046
2047 #[test]
2048 fn datagram() {
2049 let mut d = [42; 128];
2050
2051 let data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
2052
Mike Yuf57cb852022-09-20 12:25:20 +00002053 let frame = Frame::Datagram { data: data.clone() };
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01002054
2055 let wire_len = {
2056 let mut b = octets::OctetsMut::with_slice(&mut d);
2057 frame.to_bytes(&mut b).unwrap()
2058 };
2059
Mike Yuf57cb852022-09-20 12:25:20 +00002060 assert_eq!(wire_len, 15);
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01002061
2062 let mut b = octets::Octets::with_slice(&mut d);
2063 assert_eq!(
2064 Frame::from_bytes(&mut b, packet::Type::Short),
2065 Ok(frame.clone())
2066 );
2067
2068 let mut b = octets::Octets::with_slice(&mut d);
2069 assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
2070
2071 let mut b = octets::Octets::with_slice(&mut d);
2072 assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
2073
2074 let mut b = octets::Octets::with_slice(&mut d);
2075 assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
2076
2077 let frame_data = match &frame {
2078 Frame::Datagram { data } => data.clone(),
2079
2080 _ => unreachable!(),
2081 };
2082
2083 assert_eq!(frame_data, data);
Jeff Vander Stoep2bbaf7e2020-12-04 14:00:07 +01002084 }
2085}