Skip to main content

quiche/
frame.rs

1// 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
27use std::convert::TryInto;
28
29use crate::Error;
30use crate::Result;
31
32use crate::packet;
33use crate::range_buf::RangeBuf;
34use crate::ranges;
35
36#[cfg(feature = "qlog")]
37use qlog::events::quic::AckRange;
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
45pub 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
50#[derive(Clone, Debug, PartialEq, Eq)]
51pub struct EcnCounts {
52    ect0_count: u64,
53    ect1_count: u64,
54    ecn_ce_count: u64,
55}
56
57#[derive(Clone, PartialEq, Eq)]
58pub enum Frame {
59    Padding {
60        len: usize,
61    },
62
63    Ping {
64        // Attach metadata to the Ping frame. This doesn't appear on the wire,
65        // but does tell us if this frame was part of a PMTUD probe and how
66        // large the probe was. This will only show up on sent frames and be
67        // None otherwise. This is the total size of the QUIC packet in the
68        // probe.
69        mtu_probe: Option<usize>,
70    },
71
72    ACK {
73        ack_delay: u64,
74        ranges: ranges::RangeSet,
75        ecn_counts: Option<EcnCounts>,
76    },
77
78    ResetStream {
79        stream_id: u64,
80        error_code: u64,
81        final_size: u64,
82    },
83
84    StopSending {
85        stream_id: u64,
86        error_code: u64,
87    },
88
89    Crypto {
90        data: RangeBuf,
91    },
92
93    CryptoHeader {
94        offset: u64,
95        length: usize,
96    },
97
98    NewToken {
99        token: Vec<u8>,
100    },
101
102    Stream {
103        stream_id: u64,
104        data: RangeBuf,
105    },
106
107    StreamHeader {
108        stream_id: u64,
109        offset: u64,
110        length: usize,
111        fin: bool,
112    },
113
114    MaxData {
115        max: u64,
116    },
117
118    MaxStreamData {
119        stream_id: u64,
120        max: u64,
121    },
122
123    MaxStreamsBidi {
124        max: u64,
125    },
126
127    MaxStreamsUni {
128        max: u64,
129    },
130
131    DataBlocked {
132        limit: u64,
133    },
134
135    StreamDataBlocked {
136        stream_id: u64,
137        limit: u64,
138    },
139
140    StreamsBlockedBidi {
141        limit: u64,
142    },
143
144    StreamsBlockedUni {
145        limit: u64,
146    },
147
148    NewConnectionId {
149        seq_num: u64,
150        retire_prior_to: u64,
151        conn_id: Vec<u8>,
152        reset_token: [u8; 16],
153    },
154
155    RetireConnectionId {
156        seq_num: u64,
157    },
158
159    PathChallenge {
160        data: [u8; 8],
161    },
162
163    PathResponse {
164        data: [u8; 8],
165    },
166
167    ConnectionClose {
168        error_code: u64,
169        frame_type: u64,
170        reason: Vec<u8>,
171    },
172
173    ApplicationClose {
174        error_code: u64,
175        reason: Vec<u8>,
176    },
177
178    HandshakeDone,
179
180    Datagram {
181        data: Vec<u8>,
182    },
183
184    DatagramHeader {
185        length: usize,
186    },
187}
188
189impl Frame {
190    pub fn from_bytes(
191        b: &mut octets::Octets, pkt: packet::Type,
192    ) -> Result<Frame> {
193        let frame_type = b.get_varint()?;
194
195        let frame = match frame_type {
196            0x00 => {
197                let mut len = 1;
198
199                while b.peek_u8() == Ok(0x00) {
200                    b.get_u8()?;
201
202                    len += 1;
203                }
204
205                Frame::Padding { len }
206            },
207
208            0x01 => Frame::Ping { mtu_probe: None },
209
210            0x02..=0x03 => parse_ack_frame(frame_type, b)?,
211
212            0x04 => Frame::ResetStream {
213                stream_id: b.get_varint()?,
214                error_code: b.get_varint()?,
215                final_size: b.get_varint()?,
216            },
217
218            0x05 => Frame::StopSending {
219                stream_id: b.get_varint()?,
220                error_code: b.get_varint()?,
221            },
222
223            0x06 => {
224                let offset = b.get_varint()?;
225                let data = b.get_bytes_with_varint_length()?;
226                let data = <RangeBuf>::from(data.as_ref(), offset, false);
227
228                Frame::Crypto { data }
229            },
230
231            0x07 => {
232                let len = b.get_varint()?;
233                if len == 0 {
234                    return Err(Error::InvalidFrame);
235                }
236
237                Frame::NewToken {
238                    token: b.get_bytes(len as usize)?.to_vec(),
239                }
240            },
241
242            0x08..=0x0f => parse_stream_frame(frame_type, b)?,
243
244            0x10 => Frame::MaxData {
245                max: b.get_varint()?,
246            },
247
248            0x11 => Frame::MaxStreamData {
249                stream_id: b.get_varint()?,
250                max: b.get_varint()?,
251            },
252
253            0x12 => Frame::MaxStreamsBidi {
254                max: b.get_varint()?,
255            },
256
257            0x13 => Frame::MaxStreamsUni {
258                max: b.get_varint()?,
259            },
260
261            0x14 => Frame::DataBlocked {
262                limit: b.get_varint()?,
263            },
264
265            0x15 => Frame::StreamDataBlocked {
266                stream_id: b.get_varint()?,
267                limit: b.get_varint()?,
268            },
269
270            0x16 => Frame::StreamsBlockedBidi {
271                limit: b.get_varint()?,
272            },
273
274            0x17 => Frame::StreamsBlockedUni {
275                limit: b.get_varint()?,
276            },
277
278            0x18 => {
279                let seq_num = b.get_varint()?;
280                let retire_prior_to = b.get_varint()?;
281                let conn_id_len = b.get_u8()?;
282
283                if !(1..=packet::MAX_CID_LEN).contains(&conn_id_len) {
284                    return Err(Error::InvalidFrame);
285                }
286
287                Frame::NewConnectionId {
288                    seq_num,
289                    retire_prior_to,
290                    conn_id: b.get_bytes(conn_id_len as usize)?.to_vec(),
291                    reset_token: b
292                        .get_bytes(16)?
293                        .buf()
294                        .try_into()
295                        .map_err(|_| Error::BufferTooShort)?,
296                }
297            },
298
299            0x19 => Frame::RetireConnectionId {
300                seq_num: b.get_varint()?,
301            },
302
303            0x1a => Frame::PathChallenge {
304                data: b
305                    .get_bytes(8)?
306                    .buf()
307                    .try_into()
308                    .map_err(|_| Error::BufferTooShort)?,
309            },
310
311            0x1b => Frame::PathResponse {
312                data: b
313                    .get_bytes(8)?
314                    .buf()
315                    .try_into()
316                    .map_err(|_| Error::BufferTooShort)?,
317            },
318
319            0x1c => Frame::ConnectionClose {
320                error_code: b.get_varint()?,
321                frame_type: b.get_varint()?,
322                reason: b.get_bytes_with_varint_length()?.to_vec(),
323            },
324
325            0x1d => Frame::ApplicationClose {
326                error_code: b.get_varint()?,
327                reason: b.get_bytes_with_varint_length()?.to_vec(),
328            },
329
330            0x1e => Frame::HandshakeDone,
331
332            0x30 | 0x31 => parse_datagram_frame(frame_type, b)?,
333
334            _ => return Err(Error::InvalidFrame),
335        };
336
337        let allowed = match (pkt, &frame) {
338            // PADDING and PING are allowed on all packet types.
339            (_, Frame::Padding { .. }) | (_, Frame::Ping { .. }) => true,
340
341            // ACK, CRYPTO, HANDSHAKE_DONE, NEW_TOKEN, PATH_RESPONSE, and
342            // RETIRE_CONNECTION_ID can't be sent on 0-RTT packets.
343            (packet::Type::ZeroRTT, Frame::ACK { .. }) => false,
344            (packet::Type::ZeroRTT, Frame::Crypto { .. }) => false,
345            (packet::Type::ZeroRTT, Frame::HandshakeDone) => false,
346            (packet::Type::ZeroRTT, Frame::NewToken { .. }) => false,
347            (packet::Type::ZeroRTT, Frame::PathResponse { .. }) => false,
348            (packet::Type::ZeroRTT, Frame::RetireConnectionId { .. }) => false,
349            (packet::Type::ZeroRTT, Frame::ConnectionClose { .. }) => false,
350
351            // ACK, CRYPTO and CONNECTION_CLOSE can be sent on all other packet
352            // types.
353            (_, Frame::ACK { .. }) => true,
354            (_, Frame::Crypto { .. }) => true,
355            (_, Frame::ConnectionClose { .. }) => true,
356
357            // All frames are allowed on 0-RTT and 1-RTT packets.
358            (packet::Type::Short, _) => true,
359            (packet::Type::ZeroRTT, _) => true,
360
361            // All other cases are forbidden.
362            (..) => false,
363        };
364
365        if !allowed {
366            return Err(Error::InvalidPacket);
367        }
368
369        Ok(frame)
370    }
371
372    pub fn to_bytes(&self, b: &mut octets::OctetsMut) -> Result<usize> {
373        let before = b.cap();
374
375        match self {
376            Frame::Padding { len } => {
377                let mut left = *len;
378
379                while left > 0 {
380                    b.put_varint(0x00)?;
381
382                    left -= 1;
383                }
384            },
385
386            Frame::Ping { .. } => {
387                b.put_varint(0x01)?;
388            },
389
390            Frame::ACK {
391                ack_delay,
392                ranges,
393                ecn_counts,
394            } => {
395                if ecn_counts.is_none() {
396                    b.put_varint(0x02)?;
397                } else {
398                    b.put_varint(0x03)?;
399                }
400
401                let mut it = ranges.iter().rev();
402
403                let first = it.next().unwrap();
404                let ack_block = (first.end - 1) - first.start;
405
406                b.put_varint(first.end - 1)?;
407                b.put_varint(*ack_delay)?;
408                b.put_varint(it.len() as u64)?;
409                b.put_varint(ack_block)?;
410
411                let mut smallest_ack = first.start;
412
413                for block in it {
414                    let gap = smallest_ack - block.end - 1;
415                    let ack_block = (block.end - 1) - block.start;
416
417                    b.put_varint(gap)?;
418                    b.put_varint(ack_block)?;
419
420                    smallest_ack = block.start;
421                }
422
423                if let Some(ecn) = ecn_counts {
424                    b.put_varint(ecn.ect0_count)?;
425                    b.put_varint(ecn.ect1_count)?;
426                    b.put_varint(ecn.ecn_ce_count)?;
427                }
428            },
429
430            Frame::ResetStream {
431                stream_id,
432                error_code,
433                final_size,
434            } => {
435                b.put_varint(0x04)?;
436
437                b.put_varint(*stream_id)?;
438                b.put_varint(*error_code)?;
439                b.put_varint(*final_size)?;
440            },
441
442            Frame::StopSending {
443                stream_id,
444                error_code,
445            } => {
446                b.put_varint(0x05)?;
447
448                b.put_varint(*stream_id)?;
449                b.put_varint(*error_code)?;
450            },
451
452            Frame::Crypto { data } => {
453                encode_crypto_header(data.off(), data.len() as u64, b)?;
454
455                b.put_bytes(data)?;
456            },
457
458            Frame::CryptoHeader { .. } => (),
459
460            Frame::NewToken { token } => {
461                b.put_varint(0x07)?;
462
463                b.put_varint(token.len() as u64)?;
464                b.put_bytes(token)?;
465            },
466
467            Frame::Stream { stream_id, data } => {
468                encode_stream_header(
469                    *stream_id,
470                    data.off(),
471                    data.len() as u64,
472                    data.fin(),
473                    b,
474                )?;
475
476                b.put_bytes(data)?;
477            },
478
479            Frame::StreamHeader { .. } => (),
480
481            Frame::MaxData { max } => {
482                b.put_varint(0x10)?;
483
484                b.put_varint(*max)?;
485            },
486
487            Frame::MaxStreamData { stream_id, max } => {
488                b.put_varint(0x11)?;
489
490                b.put_varint(*stream_id)?;
491                b.put_varint(*max)?;
492            },
493
494            Frame::MaxStreamsBidi { max } => {
495                b.put_varint(0x12)?;
496
497                b.put_varint(*max)?;
498            },
499
500            Frame::MaxStreamsUni { max } => {
501                b.put_varint(0x13)?;
502
503                b.put_varint(*max)?;
504            },
505
506            Frame::DataBlocked { limit } => {
507                b.put_varint(0x14)?;
508
509                b.put_varint(*limit)?;
510            },
511
512            Frame::StreamDataBlocked { stream_id, limit } => {
513                b.put_varint(0x15)?;
514
515                b.put_varint(*stream_id)?;
516                b.put_varint(*limit)?;
517            },
518
519            Frame::StreamsBlockedBidi { limit } => {
520                b.put_varint(0x16)?;
521
522                b.put_varint(*limit)?;
523            },
524
525            Frame::StreamsBlockedUni { limit } => {
526                b.put_varint(0x17)?;
527
528                b.put_varint(*limit)?;
529            },
530
531            Frame::NewConnectionId {
532                seq_num,
533                retire_prior_to,
534                conn_id,
535                reset_token,
536            } => {
537                b.put_varint(0x18)?;
538
539                b.put_varint(*seq_num)?;
540                b.put_varint(*retire_prior_to)?;
541                b.put_u8(conn_id.len() as u8)?;
542                b.put_bytes(conn_id.as_ref())?;
543                b.put_bytes(reset_token.as_ref())?;
544            },
545
546            Frame::RetireConnectionId { seq_num } => {
547                b.put_varint(0x19)?;
548
549                b.put_varint(*seq_num)?;
550            },
551
552            Frame::PathChallenge { data } => {
553                b.put_varint(0x1a)?;
554
555                b.put_bytes(data.as_ref())?;
556            },
557
558            Frame::PathResponse { data } => {
559                b.put_varint(0x1b)?;
560
561                b.put_bytes(data.as_ref())?;
562            },
563
564            Frame::ConnectionClose {
565                error_code,
566                frame_type,
567                reason,
568            } => {
569                b.put_varint(0x1c)?;
570
571                b.put_varint(*error_code)?;
572                b.put_varint(*frame_type)?;
573                b.put_varint(reason.len() as u64)?;
574                b.put_bytes(reason.as_ref())?;
575            },
576
577            Frame::ApplicationClose { error_code, reason } => {
578                b.put_varint(0x1d)?;
579
580                b.put_varint(*error_code)?;
581                b.put_varint(reason.len() as u64)?;
582                b.put_bytes(reason.as_ref())?;
583            },
584
585            Frame::HandshakeDone => {
586                b.put_varint(0x1e)?;
587            },
588
589            Frame::Datagram { data } => {
590                encode_dgram_header(data.len() as u64, b)?;
591
592                b.put_bytes(data.as_ref())?;
593            },
594
595            Frame::DatagramHeader { .. } => (),
596        }
597
598        Ok(before - b.cap())
599    }
600
601    pub fn wire_len(&self) -> usize {
602        match self {
603            Frame::Padding { len } => *len,
604
605            Frame::Ping { .. } => 1,
606
607            Frame::ACK {
608                ack_delay,
609                ranges,
610                ecn_counts,
611            } => {
612                let mut it = ranges.iter().rev();
613
614                let first = it.next().unwrap();
615                let ack_block = (first.end - 1) - first.start;
616
617                let mut len = 1 + // frame type
618                    octets::varint_len(first.end - 1) + // largest_ack
619                    octets::varint_len(*ack_delay) + // ack_delay
620                    octets::varint_len(it.len() as u64) + // block_count
621                    octets::varint_len(ack_block); // first_block
622
623                let mut smallest_ack = first.start;
624
625                for block in it {
626                    let gap = smallest_ack - block.end - 1;
627                    let ack_block = (block.end - 1) - block.start;
628
629                    len += octets::varint_len(gap) + // gap
630                           octets::varint_len(ack_block); // ack_block
631
632                    smallest_ack = block.start;
633                }
634
635                if let Some(ecn) = ecn_counts {
636                    len += octets::varint_len(ecn.ect0_count) +
637                        octets::varint_len(ecn.ect1_count) +
638                        octets::varint_len(ecn.ecn_ce_count);
639                }
640
641                len
642            },
643
644            Frame::ResetStream {
645                stream_id,
646                error_code,
647                final_size,
648            } => {
649                1 + // frame type
650                octets::varint_len(*stream_id) + // stream_id
651                octets::varint_len(*error_code) + // error_code
652                octets::varint_len(*final_size) // final_size
653            },
654
655            Frame::StopSending {
656                stream_id,
657                error_code,
658            } => {
659                1 + // frame type
660                octets::varint_len(*stream_id) + // stream_id
661                octets::varint_len(*error_code) // error_code
662            },
663
664            Frame::Crypto { data } => {
665                1 + // frame type
666                octets::varint_len(data.off()) + // offset
667                2 + // length, always encode as 2-byte varint
668                data.len() // data
669            },
670
671            Frame::CryptoHeader { offset, length, .. } => {
672                1 + // frame type
673                octets::varint_len(*offset) + // offset
674                2 + // length, always encode as 2-byte varint
675                length // data
676            },
677
678            Frame::NewToken { token } => {
679                1 + // frame type
680                octets::varint_len(token.len() as u64) + // token length
681                token.len() // token
682            },
683
684            Frame::Stream { stream_id, data } => {
685                1 + // frame type
686                octets::varint_len(*stream_id) + // stream_id
687                octets::varint_len(data.off()) + // offset
688                2 + // length, always encode as 2-byte varint
689                data.len() // data
690            },
691
692            Frame::StreamHeader {
693                stream_id,
694                offset,
695                length,
696                ..
697            } => {
698                1 + // frame type
699                octets::varint_len(*stream_id) + // stream_id
700                octets::varint_len(*offset) + // offset
701                2 + // length, always encode as 2-byte varint
702                length // data
703            },
704
705            Frame::MaxData { max } => {
706                1 + // frame type
707                octets::varint_len(*max) // max
708            },
709
710            Frame::MaxStreamData { stream_id, max } => {
711                1 + // frame type
712                octets::varint_len(*stream_id) + // stream_id
713                octets::varint_len(*max) // max
714            },
715
716            Frame::MaxStreamsBidi { max } => {
717                1 + // frame type
718                octets::varint_len(*max) // max
719            },
720
721            Frame::MaxStreamsUni { max } => {
722                1 + // frame type
723                octets::varint_len(*max) // max
724            },
725
726            Frame::DataBlocked { limit } => {
727                1 + // frame type
728                octets::varint_len(*limit) // limit
729            },
730
731            Frame::StreamDataBlocked { stream_id, limit } => {
732                1 + // frame type
733                octets::varint_len(*stream_id) + // stream_id
734                octets::varint_len(*limit) // limit
735            },
736
737            Frame::StreamsBlockedBidi { limit } => {
738                1 + // frame type
739                octets::varint_len(*limit) // limit
740            },
741
742            Frame::StreamsBlockedUni { limit } => {
743                1 + // frame type
744                octets::varint_len(*limit) // limit
745            },
746
747            Frame::NewConnectionId {
748                seq_num,
749                retire_prior_to,
750                conn_id,
751                reset_token,
752            } => {
753                1 + // frame type
754                octets::varint_len(*seq_num) + // seq_num
755                octets::varint_len(*retire_prior_to) + // retire_prior_to
756                1 + // conn_id length
757                conn_id.len() + // conn_id
758                reset_token.len() // reset_token
759            },
760
761            Frame::RetireConnectionId { seq_num } => {
762                1 + // frame type
763                octets::varint_len(*seq_num) // seq_num
764            },
765
766            Frame::PathChallenge { .. } => {
767                1 + // frame type
768                8 // data
769            },
770
771            Frame::PathResponse { .. } => {
772                1 + // frame type
773                8 // data
774            },
775
776            Frame::ConnectionClose {
777                frame_type,
778                error_code,
779                reason,
780                ..
781            } => {
782                1 + // frame type
783                octets::varint_len(*error_code) + // error_code
784                octets::varint_len(*frame_type) + // frame_type
785                octets::varint_len(reason.len() as u64) + // reason_len
786                reason.len() // reason
787            },
788
789            Frame::ApplicationClose { reason, error_code } => {
790                1 + // frame type
791                octets::varint_len(*error_code) + // error_code
792                octets::varint_len(reason.len() as u64) + // reason_len
793                reason.len() // reason
794            },
795
796            Frame::HandshakeDone => {
797                1 // frame type
798            },
799
800            Frame::Datagram { data } => {
801                1 + // frame type
802                2 + // length, always encode as 2-byte varint
803                data.len() // data
804            },
805
806            Frame::DatagramHeader { length } => {
807                1 + // frame type
808                2 + // length, always encode as 2-byte varint
809                *length // data
810            },
811        }
812    }
813
814    pub fn ack_eliciting(&self) -> bool {
815        // Any other frame is ack-eliciting (note the `!`).
816        !matches!(
817            self,
818            Frame::Padding { .. } |
819                Frame::ACK { .. } |
820                Frame::ApplicationClose { .. } |
821                Frame::ConnectionClose { .. }
822        )
823    }
824
825    pub fn probing(&self) -> bool {
826        matches!(
827            self,
828            Frame::Padding { .. } |
829                Frame::NewConnectionId { .. } |
830                Frame::PathChallenge { .. } |
831                Frame::PathResponse { .. }
832        )
833    }
834
835    #[cfg(feature = "qlog")]
836    pub fn to_qlog(&self) -> QuicFrame {
837        use qlog::events::ConnectionClosedFrameError;
838        use qlog::events::RawInfo;
839
840        match self {
841            Frame::Padding { len } => QuicFrame::Padding {
842                raw: Some(Box::new(RawInfo {
843                    length: None,
844                    payload_length: Some(*len as u64),
845                    data: None,
846                })),
847            },
848
849            Frame::Ping { .. } => QuicFrame::Ping { raw: None },
850
851            Frame::ACK {
852                ack_delay,
853                ranges,
854                ecn_counts,
855            } => {
856                let ack_ranges = ranges
857                    .iter()
858                    .map(|r| AckRange::new(r.start, r.end - 1))
859                    .collect();
860
861                let (ect0, ect1, ce) = match ecn_counts {
862                    Some(ecn) => (
863                        Some(ecn.ect0_count),
864                        Some(ecn.ect1_count),
865                        Some(ecn.ecn_ce_count),
866                    ),
867
868                    None => (None, None, None),
869                };
870
871                QuicFrame::Ack {
872                    ack_delay: Some(*ack_delay as f32 / 1000.0),
873                    acked_ranges: Some(ack_ranges),
874                    ect1,
875                    ect0,
876                    ce,
877                    raw: None,
878                }
879            },
880
881            Frame::ResetStream {
882                stream_id,
883                error_code,
884                final_size,
885            } => QuicFrame::ResetStream {
886                stream_id: *stream_id,
887                error: qlog::events::ApplicationError::Unknown,
888                error_code: Some(*error_code),
889                final_size: *final_size,
890                raw: None,
891            },
892
893            Frame::StopSending {
894                stream_id,
895                error_code,
896            } => QuicFrame::StopSending {
897                stream_id: *stream_id,
898                error: qlog::events::ApplicationError::Unknown,
899                error_code: Some(*error_code),
900                raw: None,
901            },
902
903            Frame::Crypto { data } => QuicFrame::Crypto {
904                offset: data.off(),
905                raw: Some(Box::new(RawInfo {
906                    length: None,
907                    payload_length: Some(data.len() as u64),
908                    data: None,
909                })),
910            },
911
912            Frame::CryptoHeader { offset, length } => QuicFrame::Crypto {
913                offset: *offset,
914                raw: Some(Box::new(RawInfo {
915                    length: None,
916                    payload_length: Some(*length as u64),
917                    data: None,
918                })),
919            },
920
921            Frame::NewToken { token } => QuicFrame::NewToken {
922                token: qlog::Token {
923                    // TODO: pick the token type some how
924                    ty: Some(qlog::TokenType::Retry),
925                    raw: Some(RawInfo {
926                        data: qlog::HexSlice::maybe_string(Some(token))
927                            .map(Box::new),
928                        length: Some(token.len() as u64),
929                        payload_length: None,
930                    }),
931                    details: None,
932                },
933                raw: None,
934            },
935
936            Frame::Stream { stream_id, data } => QuicFrame::Stream {
937                stream_id: *stream_id,
938                offset: Some(data.off()),
939                fin: data.fin().then_some(true),
940                raw: Some(Box::new(RawInfo {
941                    length: None,
942                    payload_length: Some(data.len() as u64),
943                    data: None,
944                })),
945            },
946
947            Frame::StreamHeader {
948                stream_id,
949                offset,
950                length,
951                fin,
952            } => QuicFrame::Stream {
953                stream_id: *stream_id,
954                offset: Some(*offset),
955                fin: fin.then(|| true),
956                raw: Some(Box::new(RawInfo {
957                    length: None,
958                    payload_length: Some(*length as u64),
959                    data: None,
960                })),
961            },
962
963            Frame::MaxData { max } => QuicFrame::MaxData {
964                maximum: *max,
965                raw: None,
966            },
967
968            Frame::MaxStreamData { stream_id, max } => QuicFrame::MaxStreamData {
969                stream_id: *stream_id,
970                maximum: *max,
971                raw: None,
972            },
973
974            Frame::MaxStreamsBidi { max } => QuicFrame::MaxStreams {
975                stream_type: StreamType::Bidirectional,
976                maximum: *max,
977                raw: None,
978            },
979
980            Frame::MaxStreamsUni { max } => QuicFrame::MaxStreams {
981                stream_type: StreamType::Unidirectional,
982                maximum: *max,
983                raw: None,
984            },
985
986            Frame::DataBlocked { limit } => QuicFrame::DataBlocked {
987                limit: *limit,
988                raw: None,
989            },
990
991            Frame::StreamDataBlocked { stream_id, limit } =>
992                QuicFrame::StreamDataBlocked {
993                    stream_id: *stream_id,
994                    limit: *limit,
995                    raw: None,
996                },
997
998            Frame::StreamsBlockedBidi { limit } => QuicFrame::StreamsBlocked {
999                stream_type: StreamType::Bidirectional,
1000                limit: *limit,
1001                raw: None,
1002            },
1003
1004            Frame::StreamsBlockedUni { limit } => QuicFrame::StreamsBlocked {
1005                stream_type: StreamType::Unidirectional,
1006                limit: *limit,
1007                raw: None,
1008            },
1009
1010            Frame::NewConnectionId {
1011                seq_num,
1012                retire_prior_to,
1013                conn_id,
1014                reset_token,
1015            } => QuicFrame::NewConnectionId {
1016                sequence_number: *seq_num,
1017                retire_prior_to: *retire_prior_to,
1018                connection_id_length: Some(conn_id.len() as u8),
1019                connection_id: format!("{}", qlog::HexSlice::new(conn_id)),
1020                stateless_reset_token: qlog::HexSlice::maybe_string(Some(
1021                    reset_token,
1022                )),
1023                raw: None,
1024            },
1025
1026            Frame::RetireConnectionId { seq_num } =>
1027                QuicFrame::RetireConnectionId {
1028                    sequence_number: *seq_num,
1029                    raw: None,
1030                },
1031
1032            Frame::PathChallenge { .. } => QuicFrame::PathChallenge {
1033                data: None,
1034                raw: None,
1035            },
1036
1037            Frame::PathResponse { .. } => QuicFrame::PathResponse {
1038                data: None,
1039                raw: None,
1040            },
1041
1042            Frame::ConnectionClose {
1043                error_code, reason, ..
1044            } => QuicFrame::ConnectionClose {
1045                // TODO: use actual variant not unknown
1046                error: Some(ConnectionClosedFrameError::TransportError(
1047                    qlog::events::quic::TransportError::Unknown,
1048                )),
1049                error_space: Some(ErrorSpace::Transport),
1050                error_code: Some(*error_code),
1051                reason: Some(String::from_utf8_lossy(reason).into_owned()),
1052                reason_bytes: None,
1053                trigger_frame_type: None, // don't know trigger type
1054            },
1055
1056            Frame::ApplicationClose { error_code, reason } => {
1057                QuicFrame::ConnectionClose {
1058                    error: Some(ConnectionClosedFrameError::ApplicationError(
1059                        qlog::events::ApplicationError::Unknown,
1060                    )),
1061                    error_space: Some(ErrorSpace::Application),
1062                    error_code: Some(*error_code),
1063                    reason: Some(String::from_utf8_lossy(reason).into_owned()),
1064                    reason_bytes: None,
1065                    trigger_frame_type: None, // don't know trigger type
1066                }
1067            },
1068
1069            Frame::HandshakeDone => QuicFrame::HandshakeDone { raw: None },
1070
1071            Frame::Datagram { data } => QuicFrame::Datagram {
1072                raw: Some(Box::new(RawInfo {
1073                    length: None,
1074                    payload_length: Some(data.len() as u64),
1075                    data: None,
1076                })),
1077            },
1078
1079            Frame::DatagramHeader { length } => QuicFrame::Datagram {
1080                raw: Some(Box::new(RawInfo {
1081                    length: None,
1082                    payload_length: Some(*length as u64),
1083                    data: None,
1084                })),
1085            },
1086        }
1087    }
1088}
1089
1090impl std::fmt::Debug for Frame {
1091    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1092        match self {
1093            Frame::Padding { len } => {
1094                write!(f, "PADDING len={len}")?;
1095            },
1096
1097            Frame::Ping { mtu_probe } => {
1098                write!(f, "PING mtu_probe={mtu_probe:?}")?;
1099            },
1100
1101            Frame::ACK {
1102                ack_delay,
1103                ranges,
1104                ecn_counts,
1105            } => {
1106                write!(
1107                    f,
1108                    "ACK delay={ack_delay} blocks={ranges:?} ecn_counts={ecn_counts:?}"
1109                )?;
1110            },
1111
1112            Frame::ResetStream {
1113                stream_id,
1114                error_code,
1115                final_size,
1116            } => {
1117                write!(
1118                    f,
1119                    "RESET_STREAM stream={stream_id} err={error_code:x} size={final_size}"
1120                )?;
1121            },
1122
1123            Frame::StopSending {
1124                stream_id,
1125                error_code,
1126            } => {
1127                write!(f, "STOP_SENDING stream={stream_id} err={error_code:x}")?;
1128            },
1129
1130            Frame::Crypto { data } => {
1131                write!(f, "CRYPTO off={} len={}", data.off(), data.len())?;
1132            },
1133
1134            Frame::CryptoHeader { offset, length } => {
1135                write!(f, "CRYPTO off={offset} len={length}")?;
1136            },
1137
1138            Frame::NewToken { token } => {
1139                write!(f, "NEW_TOKEN len={}", token.len())?;
1140            },
1141
1142            Frame::Stream { stream_id, data } => {
1143                write!(
1144                    f,
1145                    "STREAM id={} off={} len={} fin={}",
1146                    stream_id,
1147                    data.off(),
1148                    data.len(),
1149                    data.fin()
1150                )?;
1151            },
1152
1153            Frame::StreamHeader {
1154                stream_id,
1155                offset,
1156                length,
1157                fin,
1158            } => {
1159                write!(
1160                    f,
1161                    "STREAM id={stream_id} off={offset} len={length} fin={fin}"
1162                )?;
1163            },
1164
1165            Frame::MaxData { max } => {
1166                write!(f, "MAX_DATA max={max}")?;
1167            },
1168
1169            Frame::MaxStreamData { stream_id, max } => {
1170                write!(f, "MAX_STREAM_DATA stream={stream_id} max={max}")?;
1171            },
1172
1173            Frame::MaxStreamsBidi { max } => {
1174                write!(f, "MAX_STREAMS type=bidi max={max}")?;
1175            },
1176
1177            Frame::MaxStreamsUni { max } => {
1178                write!(f, "MAX_STREAMS type=uni max={max}")?;
1179            },
1180
1181            Frame::DataBlocked { limit } => {
1182                write!(f, "DATA_BLOCKED limit={limit}")?;
1183            },
1184
1185            Frame::StreamDataBlocked { stream_id, limit } => {
1186                write!(
1187                    f,
1188                    "STREAM_DATA_BLOCKED stream={stream_id} limit={limit}"
1189                )?;
1190            },
1191
1192            Frame::StreamsBlockedBidi { limit } => {
1193                write!(f, "STREAMS_BLOCKED type=bidi limit={limit}")?;
1194            },
1195
1196            Frame::StreamsBlockedUni { limit } => {
1197                write!(f, "STREAMS_BLOCKED type=uni limit={limit}")?;
1198            },
1199
1200            Frame::NewConnectionId {
1201                seq_num,
1202                retire_prior_to,
1203                conn_id,
1204                reset_token,
1205            } => {
1206                write!(
1207                    f,
1208                    "NEW_CONNECTION_ID seq_num={seq_num} retire_prior_to={retire_prior_to} conn_id={conn_id:02x?} reset_token={reset_token:02x?}",
1209                )?;
1210            },
1211
1212            Frame::RetireConnectionId { seq_num } => {
1213                write!(f, "RETIRE_CONNECTION_ID seq_num={seq_num}")?;
1214            },
1215
1216            Frame::PathChallenge { data } => {
1217                write!(f, "PATH_CHALLENGE data={data:02x?}")?;
1218            },
1219
1220            Frame::PathResponse { data } => {
1221                write!(f, "PATH_RESPONSE data={data:02x?}")?;
1222            },
1223
1224            Frame::ConnectionClose {
1225                error_code,
1226                frame_type,
1227                reason,
1228            } => {
1229                write!(
1230                    f,
1231                    "CONNECTION_CLOSE err={error_code:x} frame={frame_type:x} reason={reason:x?}"
1232                )?;
1233            },
1234
1235            Frame::ApplicationClose { error_code, reason } => {
1236                write!(
1237                    f,
1238                    "APPLICATION_CLOSE err={error_code:x} reason={reason:x?}"
1239                )?;
1240            },
1241
1242            Frame::HandshakeDone => {
1243                write!(f, "HANDSHAKE_DONE")?;
1244            },
1245
1246            Frame::Datagram { data } => {
1247                write!(f, "DATAGRAM len={}", data.len())?;
1248            },
1249
1250            Frame::DatagramHeader { length } => {
1251                write!(f, "DATAGRAM len={length}")?;
1252            },
1253        }
1254
1255        Ok(())
1256    }
1257}
1258
1259fn parse_ack_frame(ty: u64, b: &mut octets::Octets) -> Result<Frame> {
1260    let first = ty as u8;
1261
1262    let largest_ack = b.get_varint()?;
1263    let ack_delay = b.get_varint()?;
1264    let block_count = b.get_varint()?;
1265    let ack_block = b.get_varint()?;
1266
1267    if largest_ack < ack_block {
1268        return Err(Error::InvalidFrame);
1269    }
1270
1271    let mut smallest_ack = largest_ack - ack_block;
1272
1273    let mut ranges = ranges::RangeSet::default();
1274
1275    ranges.insert(smallest_ack..largest_ack + 1);
1276
1277    for _i in 0..block_count {
1278        let gap = b.get_varint()?;
1279
1280        if smallest_ack < 2 + gap {
1281            return Err(Error::InvalidFrame);
1282        }
1283
1284        let largest_ack = (smallest_ack - gap) - 2;
1285        let ack_block = b.get_varint()?;
1286
1287        if largest_ack < ack_block {
1288            return Err(Error::InvalidFrame);
1289        }
1290
1291        smallest_ack = largest_ack - ack_block;
1292
1293        ranges.insert(smallest_ack..largest_ack + 1);
1294    }
1295
1296    let ecn_counts = if first & 0x01 != 0 {
1297        let ecn = EcnCounts {
1298            ect0_count: b.get_varint()?,
1299            ect1_count: b.get_varint()?,
1300            ecn_ce_count: b.get_varint()?,
1301        };
1302
1303        Some(ecn)
1304    } else {
1305        None
1306    };
1307
1308    Ok(Frame::ACK {
1309        ack_delay,
1310        ranges,
1311        ecn_counts,
1312    })
1313}
1314
1315pub fn encode_crypto_header(
1316    offset: u64, length: u64, b: &mut octets::OctetsMut,
1317) -> Result<()> {
1318    b.put_varint(0x06)?;
1319
1320    b.put_varint(offset)?;
1321
1322    // Always encode length field as 2-byte varint.
1323    b.put_varint_with_len(length, 2)?;
1324
1325    Ok(())
1326}
1327
1328pub fn encode_stream_header(
1329    stream_id: u64, offset: u64, length: u64, fin: bool,
1330    b: &mut octets::OctetsMut,
1331) -> Result<()> {
1332    let mut ty: u8 = 0x08;
1333
1334    // Always encode offset.
1335    ty |= 0x04;
1336
1337    // Always encode length.
1338    ty |= 0x02;
1339
1340    if fin {
1341        ty |= 0x01;
1342    }
1343
1344    b.put_varint(u64::from(ty))?;
1345
1346    b.put_varint(stream_id)?;
1347    b.put_varint(offset)?;
1348
1349    // Always encode length field as 2-byte varint.
1350    b.put_varint_with_len(length, 2)?;
1351
1352    Ok(())
1353}
1354
1355pub fn encode_dgram_header(length: u64, b: &mut octets::OctetsMut) -> Result<()> {
1356    let mut ty: u8 = 0x30;
1357
1358    // Always encode length
1359    ty |= 0x01;
1360
1361    b.put_varint(u64::from(ty))?;
1362
1363    // Always encode length field as 2-byte varint.
1364    b.put_varint_with_len(length, 2)?;
1365
1366    Ok(())
1367}
1368
1369fn parse_stream_frame(ty: u64, b: &mut octets::Octets) -> Result<Frame> {
1370    let first = ty as u8;
1371
1372    let stream_id = b.get_varint()?;
1373
1374    let offset = if first & 0x04 != 0 {
1375        b.get_varint()?
1376    } else {
1377        0
1378    };
1379
1380    let len = if first & 0x02 != 0 {
1381        b.get_varint()? as usize
1382    } else {
1383        b.cap()
1384    };
1385
1386    if offset + len as u64 >= MAX_STREAM_SIZE {
1387        return Err(Error::InvalidFrame);
1388    }
1389
1390    let fin = first & 0x01 != 0;
1391
1392    let data = b.get_bytes(len)?;
1393    let data = <RangeBuf>::from(data.as_ref(), offset, fin);
1394
1395    Ok(Frame::Stream { stream_id, data })
1396}
1397
1398fn parse_datagram_frame(ty: u64, b: &mut octets::Octets) -> Result<Frame> {
1399    let first = ty as u8;
1400
1401    let len = if first & 0x01 != 0 {
1402        b.get_varint()? as usize
1403    } else {
1404        b.cap()
1405    };
1406
1407    let data = b.get_bytes(len)?;
1408
1409    Ok(Frame::Datagram {
1410        data: Vec::from(data.buf()),
1411    })
1412}
1413
1414#[cfg(test)]
1415mod tests {
1416    use super::*;
1417
1418    #[test]
1419    fn padding() {
1420        let mut d = [42; 128];
1421
1422        let frame = Frame::Padding { len: 128 };
1423
1424        let wire_len = {
1425            let mut b = octets::OctetsMut::with_slice(&mut d);
1426            frame.to_bytes(&mut b).unwrap()
1427        };
1428
1429        assert_eq!(wire_len, 128);
1430
1431        let mut b = octets::Octets::with_slice(&d);
1432        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1433
1434        let mut b = octets::Octets::with_slice(&d);
1435        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_ok());
1436
1437        let mut b = octets::Octets::with_slice(&d);
1438        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1439
1440        let mut b = octets::Octets::with_slice(&d);
1441        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_ok());
1442    }
1443
1444    #[test]
1445    fn ping() {
1446        let mut d = [42; 128];
1447
1448        let frame = Frame::Ping { mtu_probe: None };
1449
1450        let wire_len = {
1451            let mut b = octets::OctetsMut::with_slice(&mut d);
1452            frame.to_bytes(&mut b).unwrap()
1453        };
1454
1455        assert_eq!(wire_len, 1);
1456        assert_eq!(&d[..wire_len], [0x01_u8]);
1457
1458        let mut b = octets::Octets::with_slice(&d);
1459        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1460
1461        let mut b = octets::Octets::with_slice(&d);
1462        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1463
1464        let mut b = octets::Octets::with_slice(&d);
1465        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_ok());
1466
1467        let mut b = octets::Octets::with_slice(&d);
1468        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_ok());
1469    }
1470
1471    #[test]
1472    fn ack() {
1473        let mut d = [42; 128];
1474
1475        let mut ranges = ranges::RangeSet::default();
1476        ranges.insert(4..7);
1477        ranges.insert(9..12);
1478        ranges.insert(15..19);
1479        ranges.insert(3000..5000);
1480
1481        let frame = Frame::ACK {
1482            ack_delay: 874_656_534,
1483            ranges,
1484            ecn_counts: None,
1485        };
1486
1487        let wire_len = {
1488            let mut b = octets::OctetsMut::with_slice(&mut d);
1489            frame.to_bytes(&mut b).unwrap()
1490        };
1491
1492        assert_eq!(wire_len, 17);
1493
1494        let mut b = octets::Octets::with_slice(&d);
1495        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1496
1497        let mut b = octets::Octets::with_slice(&d);
1498        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_ok());
1499
1500        let mut b = octets::Octets::with_slice(&d);
1501        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
1502
1503        let mut b = octets::Octets::with_slice(&d);
1504        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_ok());
1505    }
1506
1507    #[test]
1508    fn ack_ecn() {
1509        let mut d = [42; 128];
1510
1511        let mut ranges = ranges::RangeSet::default();
1512        ranges.insert(4..7);
1513        ranges.insert(9..12);
1514        ranges.insert(15..19);
1515        ranges.insert(3000..5000);
1516
1517        let ecn_counts = Some(EcnCounts {
1518            ect0_count: 100,
1519            ect1_count: 200,
1520            ecn_ce_count: 300,
1521        });
1522
1523        let frame = Frame::ACK {
1524            ack_delay: 874_656_534,
1525            ranges,
1526            ecn_counts,
1527        };
1528
1529        let wire_len = {
1530            let mut b = octets::OctetsMut::with_slice(&mut d);
1531            frame.to_bytes(&mut b).unwrap()
1532        };
1533
1534        assert_eq!(wire_len, 23);
1535
1536        let mut b = octets::Octets::with_slice(&d);
1537        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1538
1539        let mut b = octets::Octets::with_slice(&d);
1540        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_ok());
1541
1542        let mut b = octets::Octets::with_slice(&d);
1543        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
1544
1545        let mut b = octets::Octets::with_slice(&d);
1546        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_ok());
1547    }
1548
1549    #[test]
1550    fn reset_stream() {
1551        let mut d = [42; 128];
1552
1553        let frame = Frame::ResetStream {
1554            stream_id: 123_213,
1555            error_code: 21_123_767,
1556            final_size: 21_123_767,
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, 13);
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::ZeroRTT).is_ok());
1571
1572        let mut b = octets::Octets::with_slice(&d);
1573        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).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 stop_sending() {
1581        let mut d = [42; 128];
1582
1583        let frame = Frame::StopSending {
1584            stream_id: 123_213,
1585            error_code: 15_352,
1586        };
1587
1588        let wire_len = {
1589            let mut b = octets::OctetsMut::with_slice(&mut d);
1590            frame.to_bytes(&mut b).unwrap()
1591        };
1592
1593        assert_eq!(wire_len, 7);
1594
1595        let mut b = octets::Octets::with_slice(&d);
1596        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1597
1598        let mut b = octets::Octets::with_slice(&d);
1599        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1600
1601        let mut b = octets::Octets::with_slice(&d);
1602        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1603
1604        let mut b = octets::Octets::with_slice(&d);
1605        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1606    }
1607
1608    #[test]
1609    fn crypto() {
1610        let mut d = [42; 128];
1611
1612        let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
1613
1614        let frame = Frame::Crypto {
1615            data: <RangeBuf>::from(&data, 1230976, false),
1616        };
1617
1618        let wire_len = {
1619            let mut b = octets::OctetsMut::with_slice(&mut d);
1620            frame.to_bytes(&mut b).unwrap()
1621        };
1622
1623        assert_eq!(wire_len, 19);
1624
1625        let mut b = octets::Octets::with_slice(&d);
1626        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1627
1628        let mut b = octets::Octets::with_slice(&d);
1629        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_ok());
1630
1631        let mut b = octets::Octets::with_slice(&d);
1632        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
1633
1634        let mut b = octets::Octets::with_slice(&d);
1635        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_ok());
1636    }
1637
1638    #[test]
1639    fn new_token() {
1640        let mut d = [42; 128];
1641
1642        let frame = Frame::NewToken {
1643            token: Vec::from("this is a token"),
1644        };
1645
1646        let wire_len = {
1647            let mut b = octets::OctetsMut::with_slice(&mut d);
1648            frame.to_bytes(&mut b).unwrap()
1649        };
1650
1651        assert_eq!(wire_len, 17);
1652
1653        let mut b = octets::Octets::with_slice(&d);
1654        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1655
1656        let mut b = octets::Octets::with_slice(&d);
1657        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1658
1659        let mut b = octets::Octets::with_slice(&d);
1660        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
1661
1662        let mut b = octets::Octets::with_slice(&d);
1663        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1664    }
1665
1666    #[test]
1667    fn stream() {
1668        let mut d = [42; 128];
1669
1670        let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
1671
1672        let frame = Frame::Stream {
1673            stream_id: 32,
1674            data: <RangeBuf>::from(&data, 1230976, true),
1675        };
1676
1677        let wire_len = {
1678            let mut b = octets::OctetsMut::with_slice(&mut d);
1679            frame.to_bytes(&mut b).unwrap()
1680        };
1681
1682        assert_eq!(wire_len, 20);
1683
1684        let mut b = octets::Octets::with_slice(&d);
1685        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1686
1687        let mut b = octets::Octets::with_slice(&d);
1688        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1689
1690        let mut b = octets::Octets::with_slice(&d);
1691        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1692
1693        let mut b = octets::Octets::with_slice(&d);
1694        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1695    }
1696
1697    #[test]
1698    fn stream_too_big() {
1699        let mut d = [42; 128];
1700
1701        let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
1702
1703        let frame = Frame::Stream {
1704            stream_id: 32,
1705            data: <RangeBuf>::from(&data, MAX_STREAM_SIZE - 11, true),
1706        };
1707
1708        let wire_len = {
1709            let mut b = octets::OctetsMut::with_slice(&mut d);
1710            frame.to_bytes(&mut b).unwrap()
1711        };
1712
1713        assert_eq!(wire_len, 24);
1714
1715        let mut b = octets::Octets::with_slice(&d);
1716        assert_eq!(
1717            Frame::from_bytes(&mut b, packet::Type::Short),
1718            Err(Error::InvalidFrame)
1719        );
1720    }
1721
1722    #[test]
1723    fn max_data() {
1724        let mut d = [42; 128];
1725
1726        let frame = Frame::MaxData { max: 128_318_273 };
1727
1728        let wire_len = {
1729            let mut b = octets::OctetsMut::with_slice(&mut d);
1730            frame.to_bytes(&mut b).unwrap()
1731        };
1732
1733        assert_eq!(wire_len, 5);
1734
1735        let mut b = octets::Octets::with_slice(&d);
1736        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1737
1738        let mut b = octets::Octets::with_slice(&d);
1739        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1740
1741        let mut b = octets::Octets::with_slice(&d);
1742        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1743
1744        let mut b = octets::Octets::with_slice(&d);
1745        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1746    }
1747
1748    #[test]
1749    fn max_stream_data() {
1750        let mut d = [42; 128];
1751
1752        let frame = Frame::MaxStreamData {
1753            stream_id: 12_321,
1754            max: 128_318_273,
1755        };
1756
1757        let wire_len = {
1758            let mut b = octets::OctetsMut::with_slice(&mut d);
1759            frame.to_bytes(&mut b).unwrap()
1760        };
1761
1762        assert_eq!(wire_len, 7);
1763
1764        let mut b = octets::Octets::with_slice(&d);
1765        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1766
1767        let mut b = octets::Octets::with_slice(&d);
1768        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1769
1770        let mut b = octets::Octets::with_slice(&d);
1771        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1772
1773        let mut b = octets::Octets::with_slice(&d);
1774        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1775    }
1776
1777    #[test]
1778    fn max_streams_bidi() {
1779        let mut d = [42; 128];
1780
1781        let frame = Frame::MaxStreamsBidi { max: 128_318_273 };
1782
1783        let wire_len = {
1784            let mut b = octets::OctetsMut::with_slice(&mut d);
1785            frame.to_bytes(&mut b).unwrap()
1786        };
1787
1788        assert_eq!(wire_len, 5);
1789
1790        let mut b = octets::Octets::with_slice(&d);
1791        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1792
1793        let mut b = octets::Octets::with_slice(&d);
1794        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1795
1796        let mut b = octets::Octets::with_slice(&d);
1797        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1798
1799        let mut b = octets::Octets::with_slice(&d);
1800        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1801    }
1802
1803    #[test]
1804    fn max_streams_uni() {
1805        let mut d = [42; 128];
1806
1807        let frame = Frame::MaxStreamsUni { max: 128_318_273 };
1808
1809        let wire_len = {
1810            let mut b = octets::OctetsMut::with_slice(&mut d);
1811            frame.to_bytes(&mut b).unwrap()
1812        };
1813
1814        assert_eq!(wire_len, 5);
1815
1816        let mut b = octets::Octets::with_slice(&d);
1817        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1818
1819        let mut b = octets::Octets::with_slice(&d);
1820        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1821
1822        let mut b = octets::Octets::with_slice(&d);
1823        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1824
1825        let mut b = octets::Octets::with_slice(&d);
1826        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1827    }
1828
1829    #[test]
1830    fn data_blocked() {
1831        let mut d = [42; 128];
1832
1833        let frame = Frame::DataBlocked { limit: 128_318_273 };
1834
1835        let wire_len = {
1836            let mut b = octets::OctetsMut::with_slice(&mut d);
1837            frame.to_bytes(&mut b).unwrap()
1838        };
1839
1840        assert_eq!(wire_len, 5);
1841
1842        let mut b = octets::Octets::with_slice(&d);
1843        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1844
1845        let mut b = octets::Octets::with_slice(&d);
1846        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1847
1848        let mut b = octets::Octets::with_slice(&d);
1849        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1850
1851        let mut b = octets::Octets::with_slice(&d);
1852        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1853    }
1854
1855    #[test]
1856    fn stream_data_blocked() {
1857        let mut d = [42; 128];
1858
1859        let frame = Frame::StreamDataBlocked {
1860            stream_id: 12_321,
1861            limit: 128_318_273,
1862        };
1863
1864        let wire_len = {
1865            let mut b = octets::OctetsMut::with_slice(&mut d);
1866            frame.to_bytes(&mut b).unwrap()
1867        };
1868
1869        assert_eq!(wire_len, 7);
1870
1871        let mut b = octets::Octets::with_slice(&d);
1872        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1873
1874        let mut b = octets::Octets::with_slice(&d);
1875        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1876
1877        let mut b = octets::Octets::with_slice(&d);
1878        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1879
1880        let mut b = octets::Octets::with_slice(&d);
1881        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1882    }
1883
1884    #[test]
1885    fn streams_blocked_bidi() {
1886        let mut d = [42; 128];
1887
1888        let frame = Frame::StreamsBlockedBidi { limit: 128_318_273 };
1889
1890        let wire_len = {
1891            let mut b = octets::OctetsMut::with_slice(&mut d);
1892            frame.to_bytes(&mut b).unwrap()
1893        };
1894
1895        assert_eq!(wire_len, 5);
1896
1897        let mut b = octets::Octets::with_slice(&d);
1898        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1899
1900        let mut b = octets::Octets::with_slice(&d);
1901        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1902
1903        let mut b = octets::Octets::with_slice(&d);
1904        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1905
1906        let mut b = octets::Octets::with_slice(&d);
1907        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1908    }
1909
1910    #[test]
1911    fn streams_blocked_uni() {
1912        let mut d = [42; 128];
1913
1914        let frame = Frame::StreamsBlockedUni { limit: 128_318_273 };
1915
1916        let wire_len = {
1917            let mut b = octets::OctetsMut::with_slice(&mut d);
1918            frame.to_bytes(&mut b).unwrap()
1919        };
1920
1921        assert_eq!(wire_len, 5);
1922
1923        let mut b = octets::Octets::with_slice(&d);
1924        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1925
1926        let mut b = octets::Octets::with_slice(&d);
1927        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1928
1929        let mut b = octets::Octets::with_slice(&d);
1930        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1931
1932        let mut b = octets::Octets::with_slice(&d);
1933        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1934    }
1935
1936    #[test]
1937    fn new_connection_id() {
1938        let mut d = [42; 128];
1939
1940        let frame = Frame::NewConnectionId {
1941            seq_num: 123_213,
1942            retire_prior_to: 122_211,
1943            conn_id: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
1944            reset_token: [0x42; 16],
1945        };
1946
1947        let wire_len = {
1948            let mut b = octets::OctetsMut::with_slice(&mut d);
1949            frame.to_bytes(&mut b).unwrap()
1950        };
1951
1952        assert_eq!(wire_len, 41);
1953
1954        let mut b = octets::Octets::with_slice(&d);
1955        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1956
1957        let mut b = octets::Octets::with_slice(&d);
1958        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
1959
1960        let mut b = octets::Octets::with_slice(&d);
1961        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1962
1963        let mut b = octets::Octets::with_slice(&d);
1964        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1965    }
1966
1967    #[test]
1968    fn retire_connection_id() {
1969        let mut d = [42; 128];
1970
1971        let frame = Frame::RetireConnectionId { seq_num: 123_213 };
1972
1973        let wire_len = {
1974            let mut b = octets::OctetsMut::with_slice(&mut d);
1975            frame.to_bytes(&mut b).unwrap()
1976        };
1977
1978        assert_eq!(wire_len, 5);
1979
1980        let mut b = octets::Octets::with_slice(&d);
1981        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
1982
1983        let mut b = octets::Octets::with_slice(&d);
1984        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
1985
1986        let mut b = octets::Octets::with_slice(&d);
1987        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
1988
1989        let mut b = octets::Octets::with_slice(&d);
1990        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
1991    }
1992
1993    #[test]
1994    fn path_challenge() {
1995        let mut d = [42; 128];
1996
1997        let frame = Frame::PathChallenge {
1998            data: [1, 2, 3, 4, 5, 6, 7, 8],
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, 9);
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 path_response() {
2023        let mut d = [42; 128];
2024
2025        let frame = Frame::PathResponse {
2026            data: [1, 2, 3, 4, 5, 6, 7, 8],
2027        };
2028
2029        let wire_len = {
2030            let mut b = octets::OctetsMut::with_slice(&mut d);
2031            frame.to_bytes(&mut b).unwrap()
2032        };
2033
2034        assert_eq!(wire_len, 9);
2035
2036        let mut b = octets::Octets::with_slice(&d);
2037        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
2038
2039        let mut b = octets::Octets::with_slice(&d);
2040        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
2041
2042        let mut b = octets::Octets::with_slice(&d);
2043        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
2044
2045        let mut b = octets::Octets::with_slice(&d);
2046        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
2047    }
2048
2049    #[test]
2050    fn connection_close() {
2051        let mut d = [42; 128];
2052
2053        let frame = Frame::ConnectionClose {
2054            error_code: 0xbeef,
2055            frame_type: 523_423,
2056            reason: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
2057        };
2058
2059        let wire_len = {
2060            let mut b = octets::OctetsMut::with_slice(&mut d);
2061            frame.to_bytes(&mut b).unwrap()
2062        };
2063
2064        assert_eq!(wire_len, 22);
2065
2066        let mut b = octets::Octets::with_slice(&d);
2067        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
2068
2069        let mut b = octets::Octets::with_slice(&d);
2070        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_ok());
2071
2072        let mut b = octets::Octets::with_slice(&d);
2073        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
2074
2075        let mut b = octets::Octets::with_slice(&d);
2076        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_ok());
2077    }
2078
2079    #[test]
2080    fn application_close() {
2081        let mut d = [42; 128];
2082
2083        let frame = Frame::ApplicationClose {
2084            error_code: 0xbeef,
2085            reason: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
2086        };
2087
2088        let wire_len = {
2089            let mut b = octets::OctetsMut::with_slice(&mut d);
2090            frame.to_bytes(&mut b).unwrap()
2091        };
2092
2093        assert_eq!(wire_len, 18);
2094
2095        let mut b = octets::Octets::with_slice(&d);
2096        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
2097
2098        let mut b = octets::Octets::with_slice(&d);
2099        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
2100
2101        let mut b = octets::Octets::with_slice(&d);
2102        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
2103
2104        let mut b = octets::Octets::with_slice(&d);
2105        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
2106    }
2107
2108    #[test]
2109    fn handshake_done() {
2110        let mut d = [42; 128];
2111
2112        let frame = Frame::HandshakeDone;
2113
2114        let wire_len = {
2115            let mut b = octets::OctetsMut::with_slice(&mut d);
2116            frame.to_bytes(&mut b).unwrap()
2117        };
2118
2119        assert_eq!(wire_len, 1);
2120
2121        let mut b = octets::Octets::with_slice(&d);
2122        assert_eq!(Frame::from_bytes(&mut b, packet::Type::Short), Ok(frame));
2123
2124        let mut b = octets::Octets::with_slice(&d);
2125        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
2126
2127        let mut b = octets::Octets::with_slice(&d);
2128        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_err());
2129
2130        let mut b = octets::Octets::with_slice(&d);
2131        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
2132    }
2133
2134    #[test]
2135    fn datagram() {
2136        let mut d = [42; 128];
2137
2138        let data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
2139
2140        let frame = Frame::Datagram { data: data.clone() };
2141
2142        let wire_len = {
2143            let mut b = octets::OctetsMut::with_slice(&mut d);
2144            frame.to_bytes(&mut b).unwrap()
2145        };
2146
2147        assert_eq!(wire_len, 15);
2148
2149        let mut b = octets::Octets::with_slice(&d);
2150        assert_eq!(
2151            Frame::from_bytes(&mut b, packet::Type::Short),
2152            Ok(frame.clone())
2153        );
2154
2155        let mut b = octets::Octets::with_slice(&d);
2156        assert!(Frame::from_bytes(&mut b, packet::Type::Initial).is_err());
2157
2158        let mut b = octets::Octets::with_slice(&d);
2159        assert!(Frame::from_bytes(&mut b, packet::Type::ZeroRTT).is_ok());
2160
2161        let mut b = octets::Octets::with_slice(&d);
2162        assert!(Frame::from_bytes(&mut b, packet::Type::Handshake).is_err());
2163
2164        let frame_data = match &frame {
2165            Frame::Datagram { data } => data.clone(),
2166
2167            _ => unreachable!(),
2168        };
2169
2170        assert_eq!(frame_data, data);
2171    }
2172}