quiche/
packet.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::fmt::Display;
28use std::ops::Index;
29use std::ops::IndexMut;
30use std::ops::RangeInclusive;
31use std::time;
32
33use crate::Error;
34use crate::Result;
35use crate::DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS;
36
37use crate::crypto;
38use crate::rand;
39use crate::ranges;
40use crate::recovery;
41use crate::stream;
42
43const FORM_BIT: u8 = 0x80;
44const FIXED_BIT: u8 = 0x40;
45const KEY_PHASE_BIT: u8 = 0x04;
46
47const TYPE_MASK: u8 = 0x30;
48const PKT_NUM_MASK: u8 = 0x03;
49
50pub const MAX_CID_LEN: u8 = 20;
51
52pub const MAX_PKT_NUM_LEN: usize = 4;
53
54const SAMPLE_LEN: usize = 16;
55
56// Set the min skip skip interval to 2x the default number of initial packet
57// count.
58const MIN_SKIP_COUNTER_VALUE: u64 =
59    DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS as u64 * 2;
60
61const RETRY_AEAD_ALG: crypto::Algorithm = crypto::Algorithm::AES128_GCM;
62
63#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
64pub enum Epoch {
65    Initial     = 0,
66    Handshake   = 1,
67    Application = 2,
68}
69
70static EPOCHS: [Epoch; 3] =
71    [Epoch::Initial, Epoch::Handshake, Epoch::Application];
72
73impl Epoch {
74    /// Returns an ordered slice containing the `Epoch`s that fit in the
75    /// provided `range`.
76    pub fn epochs(range: RangeInclusive<Epoch>) -> &'static [Epoch] {
77        &EPOCHS[*range.start() as usize..=*range.end() as usize]
78    }
79
80    pub const fn count() -> usize {
81        3
82    }
83}
84
85impl Display for Epoch {
86    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87        write!(f, "{}", usize::from(*self))
88    }
89}
90
91impl From<Epoch> for usize {
92    fn from(e: Epoch) -> Self {
93        e as usize
94    }
95}
96
97impl<T> Index<Epoch> for [T]
98where
99    T: Sized,
100{
101    type Output = T;
102
103    fn index(&self, index: Epoch) -> &Self::Output {
104        self.index(usize::from(index))
105    }
106}
107
108impl<T> IndexMut<Epoch> for [T]
109where
110    T: Sized,
111{
112    fn index_mut(&mut self, index: Epoch) -> &mut Self::Output {
113        self.index_mut(usize::from(index))
114    }
115}
116
117/// QUIC packet type.
118#[derive(Clone, Copy, Debug, PartialEq, Eq)]
119pub enum Type {
120    /// Initial packet.
121    Initial,
122
123    /// Retry packet.
124    Retry,
125
126    /// Handshake packet.
127    Handshake,
128
129    /// 0-RTT packet.
130    ZeroRTT,
131
132    /// Version negotiation packet.
133    VersionNegotiation,
134
135    /// 1-RTT short header packet.
136    Short,
137}
138
139impl Type {
140    pub(crate) fn from_epoch(e: Epoch) -> Type {
141        match e {
142            Epoch::Initial => Type::Initial,
143
144            Epoch::Handshake => Type::Handshake,
145
146            Epoch::Application => Type::Short,
147        }
148    }
149
150    pub(crate) fn to_epoch(self) -> Result<Epoch> {
151        match self {
152            Type::Initial => Ok(Epoch::Initial),
153
154            Type::ZeroRTT => Ok(Epoch::Application),
155
156            Type::Handshake => Ok(Epoch::Handshake),
157
158            Type::Short => Ok(Epoch::Application),
159
160            _ => Err(Error::InvalidPacket),
161        }
162    }
163
164    #[cfg(feature = "qlog")]
165    pub(crate) fn to_qlog(self) -> qlog::events::quic::PacketType {
166        match self {
167            Type::Initial => qlog::events::quic::PacketType::Initial,
168
169            Type::Retry => qlog::events::quic::PacketType::Retry,
170
171            Type::Handshake => qlog::events::quic::PacketType::Handshake,
172
173            Type::ZeroRTT => qlog::events::quic::PacketType::ZeroRtt,
174
175            Type::VersionNegotiation =>
176                qlog::events::quic::PacketType::VersionNegotiation,
177
178            Type::Short => qlog::events::quic::PacketType::OneRtt,
179        }
180    }
181}
182
183/// A QUIC connection ID.
184pub struct ConnectionId<'a>(ConnectionIdInner<'a>);
185
186enum ConnectionIdInner<'a> {
187    Vec(Vec<u8>),
188    Ref(&'a [u8]),
189}
190
191impl<'a> ConnectionId<'a> {
192    /// Creates a new connection ID from the given vector.
193    #[inline]
194    pub const fn from_vec(cid: Vec<u8>) -> Self {
195        Self(ConnectionIdInner::Vec(cid))
196    }
197
198    /// Creates a new connection ID from the given slice.
199    #[inline]
200    pub const fn from_ref(cid: &'a [u8]) -> Self {
201        Self(ConnectionIdInner::Ref(cid))
202    }
203
204    /// Returns a new owning connection ID from the given existing one.
205    #[inline]
206    pub fn into_owned(self) -> ConnectionId<'static> {
207        ConnectionId::from_vec(self.into())
208    }
209}
210
211impl Default for ConnectionId<'_> {
212    #[inline]
213    fn default() -> Self {
214        Self::from_vec(Vec::new())
215    }
216}
217
218impl From<Vec<u8>> for ConnectionId<'_> {
219    #[inline]
220    fn from(v: Vec<u8>) -> Self {
221        Self::from_vec(v)
222    }
223}
224
225impl From<ConnectionId<'_>> for Vec<u8> {
226    #[inline]
227    fn from(id: ConnectionId<'_>) -> Self {
228        match id.0 {
229            ConnectionIdInner::Vec(cid) => cid,
230            ConnectionIdInner::Ref(cid) => cid.to_vec(),
231        }
232    }
233}
234
235impl PartialEq for ConnectionId<'_> {
236    #[inline]
237    fn eq(&self, other: &Self) -> bool {
238        self.as_ref() == other.as_ref()
239    }
240}
241
242impl Eq for ConnectionId<'_> {}
243
244impl AsRef<[u8]> for ConnectionId<'_> {
245    #[inline]
246    fn as_ref(&self) -> &[u8] {
247        match &self.0 {
248            ConnectionIdInner::Vec(v) => v.as_ref(),
249            ConnectionIdInner::Ref(v) => v,
250        }
251    }
252}
253
254impl std::hash::Hash for ConnectionId<'_> {
255    #[inline]
256    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
257        self.as_ref().hash(state);
258    }
259}
260
261impl std::ops::Deref for ConnectionId<'_> {
262    type Target = [u8];
263
264    #[inline]
265    fn deref(&self) -> &[u8] {
266        match &self.0 {
267            ConnectionIdInner::Vec(v) => v.as_ref(),
268            ConnectionIdInner::Ref(v) => v,
269        }
270    }
271}
272
273impl Clone for ConnectionId<'_> {
274    #[inline]
275    fn clone(&self) -> Self {
276        Self::from_vec(self.as_ref().to_vec())
277    }
278}
279
280impl std::fmt::Debug for ConnectionId<'_> {
281    #[inline]
282    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
283        for c in self.as_ref() {
284            write!(f, "{c:02x}")?;
285        }
286
287        Ok(())
288    }
289}
290
291/// A QUIC packet's header.
292#[derive(Clone, PartialEq, Eq)]
293pub struct Header<'a> {
294    /// The type of the packet.
295    pub ty: Type,
296
297    /// The version of the packet.
298    pub version: u32,
299
300    /// The destination connection ID of the packet.
301    pub dcid: ConnectionId<'a>,
302
303    /// The source connection ID of the packet.
304    pub scid: ConnectionId<'a>,
305
306    /// The packet number. It's only meaningful after the header protection is
307    /// removed.
308    pub(crate) pkt_num: u64,
309
310    /// The length of the packet number. It's only meaningful after the header
311    /// protection is removed.
312    pub(crate) pkt_num_len: usize,
313
314    /// The address verification token of the packet. Only present in `Initial`
315    /// and `Retry` packets.
316    pub token: Option<Vec<u8>>,
317
318    /// The list of versions in the packet. Only present in
319    /// `VersionNegotiation` packets.
320    pub versions: Option<Vec<u32>>,
321
322    /// The key phase bit of the packet. It's only meaningful after the header
323    /// protection is removed.
324    pub(crate) key_phase: bool,
325}
326
327impl<'a> Header<'a> {
328    /// Parses a QUIC packet header from the given buffer.
329    ///
330    /// The `dcid_len` parameter is the length of the destination connection ID,
331    /// required to parse short header packets.
332    ///
333    /// ## Examples:
334    ///
335    /// ```no_run
336    /// # const LOCAL_CONN_ID_LEN: usize = 16;
337    /// # let mut buf = [0; 512];
338    /// # let mut out = [0; 512];
339    /// # let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
340    /// let (len, src) = socket.recv_from(&mut buf).unwrap();
341    ///
342    /// let hdr = quiche::Header::from_slice(&mut buf[..len], LOCAL_CONN_ID_LEN)?;
343    /// # Ok::<(), quiche::Error>(())
344    /// ```
345    #[inline]
346    pub fn from_slice<'b>(
347        buf: &'b mut [u8], dcid_len: usize,
348    ) -> Result<Header<'a>> {
349        let mut b = octets::OctetsMut::with_slice(buf);
350        Header::from_bytes(&mut b, dcid_len)
351    }
352
353    pub(crate) fn from_bytes<'b>(
354        b: &'b mut octets::OctetsMut, dcid_len: usize,
355    ) -> Result<Header<'a>> {
356        let first = b.get_u8()?;
357
358        if !Header::is_long(first) {
359            // Decode short header.
360            let dcid = b.get_bytes(dcid_len)?;
361
362            return Ok(Header {
363                ty: Type::Short,
364                version: 0,
365                dcid: dcid.to_vec().into(),
366                scid: ConnectionId::default(),
367                pkt_num: 0,
368                pkt_num_len: 0,
369                token: None,
370                versions: None,
371                key_phase: false,
372            });
373        }
374
375        // Decode long header.
376        let version = b.get_u32()?;
377
378        let ty = if version == 0 {
379            Type::VersionNegotiation
380        } else {
381            match (first & TYPE_MASK) >> 4 {
382                0x00 => Type::Initial,
383                0x01 => Type::ZeroRTT,
384                0x02 => Type::Handshake,
385                0x03 => Type::Retry,
386                _ => return Err(Error::InvalidPacket),
387            }
388        };
389
390        let dcid_len = b.get_u8()?;
391        if crate::version_is_supported(version) && dcid_len > MAX_CID_LEN {
392            return Err(Error::InvalidPacket);
393        }
394        let dcid = b.get_bytes(dcid_len as usize)?.to_vec();
395
396        let scid_len = b.get_u8()?;
397        if crate::version_is_supported(version) && scid_len > MAX_CID_LEN {
398            return Err(Error::InvalidPacket);
399        }
400        let scid = b.get_bytes(scid_len as usize)?.to_vec();
401
402        // End of invariants.
403
404        let mut token: Option<Vec<u8>> = None;
405        let mut versions: Option<Vec<u32>> = None;
406
407        match ty {
408            Type::Initial => {
409                token = Some(b.get_bytes_with_varint_length()?.to_vec());
410            },
411
412            Type::Retry => {
413                const TAG_LEN: usize = RETRY_AEAD_ALG.tag_len();
414
415                // Exclude the integrity tag from the token.
416                if b.cap() < TAG_LEN {
417                    return Err(Error::InvalidPacket);
418                }
419
420                let token_len = b.cap() - TAG_LEN;
421                token = Some(b.get_bytes(token_len)?.to_vec());
422            },
423
424            Type::VersionNegotiation => {
425                let mut list: Vec<u32> = Vec::new();
426
427                while b.cap() > 0 {
428                    let version = b.get_u32()?;
429                    list.push(version);
430                }
431
432                versions = Some(list);
433            },
434
435            _ => (),
436        };
437
438        Ok(Header {
439            ty,
440            version,
441            dcid: dcid.into(),
442            scid: scid.into(),
443            pkt_num: 0,
444            pkt_num_len: 0,
445            token,
446            versions,
447            key_phase: false,
448        })
449    }
450
451    pub(crate) fn to_bytes(&self, out: &mut octets::OctetsMut) -> Result<()> {
452        let mut first = 0;
453
454        // Encode pkt num length.
455        first |= self.pkt_num_len.saturating_sub(1) as u8;
456
457        // Encode short header.
458        if self.ty == Type::Short {
459            // Unset form bit for short header.
460            first &= !FORM_BIT;
461
462            // Set fixed bit.
463            first |= FIXED_BIT;
464
465            // Set key phase bit.
466            if self.key_phase {
467                first |= KEY_PHASE_BIT;
468            } else {
469                first &= !KEY_PHASE_BIT;
470            }
471
472            out.put_u8(first)?;
473            out.put_bytes(&self.dcid)?;
474
475            return Ok(());
476        }
477
478        // Encode long header.
479        let ty: u8 = match self.ty {
480            Type::Initial => 0x00,
481            Type::ZeroRTT => 0x01,
482            Type::Handshake => 0x02,
483            Type::Retry => 0x03,
484            _ => return Err(Error::InvalidPacket),
485        };
486
487        first |= FORM_BIT | FIXED_BIT | (ty << 4);
488
489        out.put_u8(first)?;
490
491        out.put_u32(self.version)?;
492
493        out.put_u8(self.dcid.len() as u8)?;
494        out.put_bytes(&self.dcid)?;
495
496        out.put_u8(self.scid.len() as u8)?;
497        out.put_bytes(&self.scid)?;
498
499        // Only Initial and Retry packets have a token.
500        match self.ty {
501            Type::Initial => {
502                match self.token {
503                    Some(ref v) => {
504                        out.put_varint(v.len() as u64)?;
505                        out.put_bytes(v)?;
506                    },
507
508                    // No token, so length = 0.
509                    None => {
510                        out.put_varint(0)?;
511                    },
512                }
513            },
514
515            Type::Retry => {
516                // Retry packets don't have a token length.
517                out.put_bytes(self.token.as_ref().unwrap())?;
518            },
519
520            _ => (),
521        }
522
523        Ok(())
524    }
525
526    /// Returns true if the packet has a long header.
527    ///
528    /// The `b` parameter represents the first byte of the QUIC header.
529    fn is_long(b: u8) -> bool {
530        b & FORM_BIT != 0
531    }
532}
533
534impl std::fmt::Debug for Header<'_> {
535    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
536        write!(f, "{:?}", self.ty)?;
537
538        if self.ty != Type::Short {
539            write!(f, " version={:x}", self.version)?;
540        }
541
542        write!(f, " dcid={:?}", self.dcid)?;
543
544        if self.ty != Type::Short {
545            write!(f, " scid={:?}", self.scid)?;
546        }
547
548        if let Some(ref token) = self.token {
549            write!(f, " token=")?;
550            for b in token {
551                write!(f, "{b:02x}")?;
552            }
553        }
554
555        if let Some(ref versions) = self.versions {
556            write!(f, " versions={versions:x?}")?;
557        }
558
559        if self.ty == Type::Short {
560            write!(f, " key_phase={}", self.key_phase)?;
561        }
562
563        Ok(())
564    }
565}
566
567pub fn pkt_num_len(pn: u64, largest_acked: u64) -> usize {
568    let num_unacked: u64 = pn.saturating_sub(largest_acked) + 1;
569    // computes ceil of num_unacked.log2()
570    let min_bits = u64::BITS - num_unacked.leading_zeros();
571    // get the num len in bytes
572    min_bits.div_ceil(8) as usize
573}
574
575pub fn decrypt_hdr(
576    b: &mut octets::OctetsMut, hdr: &mut Header, aead: &crypto::Open,
577) -> Result<()> {
578    let mut first = {
579        let (first_buf, _) = b.split_at(1)?;
580        first_buf.as_ref()[0]
581    };
582
583    let mut pn_and_sample = b.peek_bytes_mut(MAX_PKT_NUM_LEN + SAMPLE_LEN)?;
584
585    let (mut ciphertext, sample) = pn_and_sample.split_at(MAX_PKT_NUM_LEN)?;
586
587    let ciphertext = ciphertext.as_mut();
588
589    let mask = aead.new_mask(sample.as_ref())?;
590
591    if Header::is_long(first) {
592        first ^= mask[0] & 0x0f;
593    } else {
594        first ^= mask[0] & 0x1f;
595    }
596
597    let pn_len = usize::from((first & PKT_NUM_MASK) + 1);
598
599    let ciphertext = &mut ciphertext[..pn_len];
600
601    for i in 0..pn_len {
602        ciphertext[i] ^= mask[i + 1];
603    }
604
605    // Extract packet number corresponding to the decoded length.
606    let pn = match pn_len {
607        1 => u64::from(b.get_u8()?),
608
609        2 => u64::from(b.get_u16()?),
610
611        3 => u64::from(b.get_u24()?),
612
613        4 => u64::from(b.get_u32()?),
614
615        _ => return Err(Error::InvalidPacket),
616    };
617
618    // Write decrypted first byte back into the input buffer.
619    let (mut first_buf, _) = b.split_at(1)?;
620    first_buf.as_mut()[0] = first;
621
622    hdr.pkt_num = pn;
623    hdr.pkt_num_len = pn_len;
624
625    if hdr.ty == Type::Short {
626        hdr.key_phase = (first & KEY_PHASE_BIT) != 0;
627    }
628
629    Ok(())
630}
631
632pub fn decode_pkt_num(largest_pn: u64, truncated_pn: u64, pn_len: usize) -> u64 {
633    let pn_nbits = pn_len * 8;
634    let expected_pn = largest_pn + 1;
635    let pn_win = 1 << pn_nbits;
636    let pn_hwin = pn_win / 2;
637    let pn_mask = pn_win - 1;
638    let candidate_pn = (expected_pn & !pn_mask) | truncated_pn;
639
640    if candidate_pn + pn_hwin <= expected_pn && candidate_pn < (1 << 62) - pn_win
641    {
642        return candidate_pn + pn_win;
643    }
644
645    if candidate_pn > expected_pn + pn_hwin && candidate_pn >= pn_win {
646        return candidate_pn - pn_win;
647    }
648
649    candidate_pn
650}
651
652pub fn decrypt_pkt<'a>(
653    b: &'a mut octets::OctetsMut, pn: u64, pn_len: usize, payload_len: usize,
654    aead: &crypto::Open,
655) -> Result<octets::Octets<'a>> {
656    let payload_offset = b.off();
657
658    let (header, mut payload) = b.split_at(payload_offset)?;
659
660    let payload_len = payload_len
661        .checked_sub(pn_len)
662        .ok_or(Error::InvalidPacket)?;
663
664    let mut ciphertext = payload.peek_bytes_mut(payload_len)?;
665
666    let payload_len =
667        aead.open_with_u64_counter(pn, header.as_ref(), ciphertext.as_mut())?;
668
669    Ok(b.get_bytes(payload_len)?)
670}
671
672pub fn encrypt_hdr(
673    b: &mut octets::OctetsMut, pn_len: usize, payload: &[u8], aead: &crypto::Seal,
674) -> Result<()> {
675    let sample = &payload
676        [MAX_PKT_NUM_LEN - pn_len..SAMPLE_LEN + (MAX_PKT_NUM_LEN - pn_len)];
677
678    let mask = aead.new_mask(sample)?;
679
680    let (mut first, mut rest) = b.split_at(1)?;
681
682    let first = first.as_mut();
683
684    if Header::is_long(first[0]) {
685        first[0] ^= mask[0] & 0x0f;
686    } else {
687        first[0] ^= mask[0] & 0x1f;
688    }
689
690    let pn_buf = rest.slice_last(pn_len)?;
691    for i in 0..pn_len {
692        pn_buf[i] ^= mask[i + 1];
693    }
694
695    Ok(())
696}
697
698pub fn encrypt_pkt(
699    b: &mut octets::OctetsMut, pn: u64, pn_len: usize, payload_len: usize,
700    payload_offset: usize, extra_in: Option<&[u8]>, aead: &crypto::Seal,
701) -> Result<usize> {
702    let (mut header, mut payload) = b.split_at(payload_offset)?;
703
704    let ciphertext_len = aead.seal_with_u64_counter(
705        pn,
706        header.as_ref(),
707        payload.as_mut(),
708        payload_len,
709        extra_in,
710    )?;
711
712    encrypt_hdr(&mut header, pn_len, payload.as_ref(), aead)?;
713
714    Ok(payload_offset + ciphertext_len)
715}
716
717pub fn encode_pkt_num(
718    pn: u64, pn_len: usize, b: &mut octets::OctetsMut,
719) -> Result<()> {
720    match pn_len {
721        1 => b.put_u8(pn as u8)?,
722
723        2 => b.put_u16(pn as u16)?,
724
725        3 => b.put_u24(pn as u32)?,
726
727        4 => b.put_u32(pn as u32)?,
728
729        _ => return Err(Error::InvalidPacket),
730    };
731
732    Ok(())
733}
734
735pub fn negotiate_version(
736    scid: &[u8], dcid: &[u8], out: &mut [u8],
737) -> Result<usize> {
738    let mut b = octets::OctetsMut::with_slice(out);
739
740    let first = rand::rand_u8() | FORM_BIT;
741
742    b.put_u8(first)?;
743    b.put_u32(0)?;
744
745    b.put_u8(scid.len() as u8)?;
746    b.put_bytes(scid)?;
747    b.put_u8(dcid.len() as u8)?;
748    b.put_bytes(dcid)?;
749    b.put_u32(crate::PROTOCOL_VERSION_V1)?;
750
751    Ok(b.off())
752}
753
754pub fn retry(
755    scid: &[u8], dcid: &[u8], new_scid: &[u8], token: &[u8], version: u32,
756    out: &mut [u8],
757) -> Result<usize> {
758    let mut b = octets::OctetsMut::with_slice(out);
759
760    if !crate::version_is_supported(version) {
761        return Err(Error::UnknownVersion);
762    }
763
764    let hdr = Header {
765        ty: Type::Retry,
766        version,
767        dcid: ConnectionId::from_ref(scid),
768        scid: ConnectionId::from_ref(new_scid),
769        pkt_num: 0,
770        pkt_num_len: 0,
771        token: Some(token.to_vec()),
772        versions: None,
773        key_phase: false,
774    };
775
776    hdr.to_bytes(&mut b)?;
777
778    let tag = compute_retry_integrity_tag(&b, dcid, version)?;
779
780    b.put_bytes(tag.as_ref())?;
781
782    Ok(b.off())
783}
784
785pub fn verify_retry_integrity(
786    b: &octets::OctetsMut, odcid: &[u8], version: u32,
787) -> Result<()> {
788    const TAG_LEN: usize = RETRY_AEAD_ALG.tag_len();
789
790    let tag = compute_retry_integrity_tag(b, odcid, version)?;
791
792    crypto::verify_slices_are_equal(&b.as_ref()[..TAG_LEN], tag.as_ref())
793}
794
795fn compute_retry_integrity_tag(
796    b: &octets::OctetsMut, odcid: &[u8], version: u32,
797) -> Result<Vec<u8>> {
798    const KEY_LEN: usize = RETRY_AEAD_ALG.key_len();
799    const TAG_LEN: usize = RETRY_AEAD_ALG.tag_len();
800
801    const RETRY_INTEGRITY_KEY_V1: [u8; KEY_LEN] = [
802        0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a, 0x1d, 0x76, 0x6b, 0x54,
803        0xe3, 0x68, 0xc8, 0x4e,
804    ];
805
806    const RETRY_INTEGRITY_NONCE_V1: [u8; crypto::MAX_NONCE_LEN] = [
807        0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb,
808    ];
809
810    let (key, nonce) = match version {
811        crate::PROTOCOL_VERSION_V1 =>
812            (&RETRY_INTEGRITY_KEY_V1, RETRY_INTEGRITY_NONCE_V1),
813
814        _ => (&RETRY_INTEGRITY_KEY_V1, RETRY_INTEGRITY_NONCE_V1),
815    };
816
817    let hdr_len = b.off();
818
819    let mut pseudo = vec![0; 1 + odcid.len() + hdr_len];
820
821    let mut pb = octets::OctetsMut::with_slice(&mut pseudo);
822
823    pb.put_u8(odcid.len() as u8)?;
824    pb.put_bytes(odcid)?;
825    pb.put_bytes(&b.buf()[..hdr_len])?;
826
827    let key = crypto::PacketKey::new(
828        RETRY_AEAD_ALG,
829        key.to_vec(),
830        nonce.to_vec(),
831        crypto::Seal::ENCRYPT,
832    )?;
833
834    let mut out_tag = vec![0_u8; TAG_LEN];
835
836    let out_len = key.seal_with_u64_counter(0, &pseudo, &mut out_tag, 0, None)?;
837
838    // Ensure that the output only contains the AEAD tag.
839    if out_len != out_tag.len() {
840        return Err(Error::CryptoFail);
841    }
842
843    Ok(out_tag)
844}
845
846pub struct KeyUpdate {
847    /// 1-RTT key used prior to a key update.
848    pub crypto_open: crypto::Open,
849
850    /// The packet number triggered the latest key-update.
851    ///
852    /// Incoming packets with lower pn should use this (prev) crypto key.
853    pub pn_on_update: u64,
854
855    /// Whether ACK frame for key-update has been sent.
856    pub update_acked: bool,
857
858    /// When the old key should be discarded.
859    pub timer: time::Instant,
860}
861
862pub struct PktNumSpace {
863    /// The largest packet number received.
864    pub largest_rx_pkt_num: u64,
865
866    /// Time the largest packet number received.
867    pub largest_rx_pkt_time: time::Instant,
868
869    /// The largest non-probing packet number.
870    pub largest_rx_non_probing_pkt_num: u64,
871
872    /// The largest packet number send in the packet number space so far.
873    pub largest_tx_pkt_num: Option<u64>,
874
875    /// Range of packet numbers that we need to send an ACK for.
876    pub recv_pkt_need_ack: ranges::RangeSet,
877
878    /// Tracks received packet numbers.
879    pub recv_pkt_num: PktNumWindow,
880
881    /// Track if a received packet is ack eliciting.
882    pub ack_elicited: bool,
883}
884
885impl PktNumSpace {
886    pub fn new() -> PktNumSpace {
887        PktNumSpace {
888            largest_rx_pkt_num: 0,
889            largest_rx_pkt_time: time::Instant::now(),
890            largest_rx_non_probing_pkt_num: 0,
891            largest_tx_pkt_num: None,
892            recv_pkt_need_ack: ranges::RangeSet::new(crate::MAX_ACK_RANGES),
893            recv_pkt_num: PktNumWindow::default(),
894            ack_elicited: false,
895        }
896    }
897
898    pub fn clear(&mut self) {
899        self.ack_elicited = false;
900    }
901
902    pub fn ready(&self) -> bool {
903        self.ack_elicited
904    }
905
906    pub fn on_packet_sent(&mut self, sent_pkt: &recovery::Sent) {
907        // Track the largest packet number sent
908        self.largest_tx_pkt_num =
909            self.largest_tx_pkt_num.max(Some(sent_pkt.pkt_num));
910    }
911}
912
913pub struct CryptoContext {
914    pub key_update: Option<KeyUpdate>,
915    pub crypto_open: Option<crypto::Open>,
916    pub crypto_seal: Option<crypto::Seal>,
917    pub crypto_0rtt_open: Option<crypto::Open>,
918    pub crypto_stream: stream::Stream,
919}
920
921impl CryptoContext {
922    pub fn new() -> CryptoContext {
923        let crypto_stream = stream::Stream::new(
924            0, // dummy
925            u64::MAX,
926            u64::MAX,
927            true,
928            true,
929            stream::MAX_STREAM_WINDOW,
930        );
931        CryptoContext {
932            key_update: None,
933            crypto_open: None,
934            crypto_seal: None,
935            crypto_0rtt_open: None,
936            crypto_stream,
937        }
938    }
939
940    pub fn clear(&mut self) {
941        self.crypto_open = None;
942        self.crypto_seal = None;
943        self.crypto_stream = <stream::Stream>::new(
944            0, // dummy
945            u64::MAX,
946            u64::MAX,
947            true,
948            true,
949            stream::MAX_STREAM_WINDOW,
950        );
951    }
952
953    pub fn data_available(&self) -> bool {
954        self.crypto_stream.is_flushable()
955    }
956
957    pub fn crypto_overhead(&self) -> Option<usize> {
958        Some(self.crypto_seal.as_ref()?.alg().tag_len())
959    }
960
961    pub fn has_keys(&self) -> bool {
962        self.crypto_open.is_some() && self.crypto_seal.is_some()
963    }
964}
965
966/// QUIC recommends skipping packet numbers to elicit a [faster ACK] or to
967/// mitigate an [optimistic ACK attack] (OACK attack). quiche currently skips
968/// packets only for the purposes of optimistic attack mitigation.
969///
970/// ## What is an Optimistic ACK attack
971/// A typical endpoint is responsible for making concurrent progress on multiple
972/// connections and needs to fairly allocate resources across those connection.
973/// In order to ensure fairness, an endpoint relies on "recovery signals" to
974/// determine the optimal sending rate per connection. For example, when a new
975/// flow joins a shared network, it might induce packet loss for other flows and
976/// cause those flows to yield bandwidth on the network. ACKs are the primary
977/// source of recovery signals for a QUIC connection.
978///
979/// The goal of an OACK attack is to mount a DDoS attack by exploiting recovery
980/// signals and causing a server to expand its sending rate. A server with an
981/// inflated sending rate would then be able to flood a shared network and
982/// cripple all other flows. The fundamental reason that makes OACK
983/// attach possible is the use of unvalidated ACK data, which is then used to
984/// modify internal state. Therefore at a high level, a mitigation should
985/// validate the incoming ACK data before use.
986///
987/// ## Optimistic ACK attack mitigation
988/// quiche follows the RFC's recommendation for mitigating an [optimistic ACK
989/// attack] by skipping packets and validating that the peer does NOT send ACKs
990/// for those skipped packets. If an ACK for a skipped packet is received, the
991/// connection is closed with a [PROTOCOL_VIOLATION] error.
992///
993/// A robust mitigation should skip packets randomly to ensure that an attacker
994/// can't predict which packet number was skipped. Skip/validation should happen
995/// "periodically" over the lifetime of the connection. Since skipping packets
996/// also elicits a faster ACK, we need to balance the skip frequency to
997/// sufficiently validate the peer without impacting other aspects of recovery.
998///
999/// A naive approach could be to skip a random packet number in the range
1000/// 200-500 (pick some static range). While this might work, its not apparent if
1001/// a static range is effective for all networks with varying bandwidths/RTTs.
1002///
1003/// Since an attacker can potentially influence the sending rate once per
1004/// "round", it would be ideal to validate the peer once per round. Therefore,
1005/// an ideal range seems to be one that dynamically adjusts based on packets
1006/// sent per round, ie. adjust skip range based on the current CWND.
1007///
1008/// [faster ACK]: https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.4
1009/// [optimistic ACK attack]: https://www.rfc-editor.org/rfc/rfc9000.html#section-21.4
1010/// [PROTOCOL_VIOLATION]: https://www.rfc-editor.org/rfc/rfc9000#section-13.1
1011pub struct PktNumManager {
1012    // TODO:
1013    // Defer including next_pkt_num in order to reduce the size of this patch
1014    // /// Next packet number.
1015    // next_pkt_num: u64,
1016    /// Track if we have skipped a packet number.
1017    skip_pn: Option<u64>,
1018
1019    /// Track when to skip the next packet number
1020    ///
1021    /// None indicates the counter is not armed while Some(0) indicates that the
1022    /// counter has expired.
1023    pub skip_pn_counter: Option<u64>,
1024}
1025
1026impl PktNumManager {
1027    pub fn new() -> Self {
1028        PktNumManager {
1029            skip_pn: None,
1030            skip_pn_counter: None,
1031        }
1032    }
1033
1034    pub fn on_packet_sent(
1035        &mut self, cwnd: usize, max_datagram_size: usize,
1036        handshake_completed: bool,
1037    ) {
1038        // Decrement skip_pn_counter for each packet sent
1039        if let Some(counter) = &mut self.skip_pn_counter {
1040            *counter = counter.saturating_sub(1);
1041        } else if self.should_arm_skip_counter(handshake_completed) {
1042            self.arm_skip_counter(cwnd, max_datagram_size);
1043        }
1044    }
1045
1046    fn should_arm_skip_counter(&self, handshake_completed: bool) -> bool {
1047        // Arm if the counter is not set
1048        let counter_not_set = self.skip_pn_counter.is_none();
1049        // Don't arm until we have verified the current skip_pn. Rearming the
1050        // counter could result in overwriting the skip_pn before
1051        // validating the current skip_pn.
1052        let no_current_skip_packet = self.skip_pn.is_none();
1053
1054        // Skip pn only after the handshake has completed
1055        counter_not_set && no_current_skip_packet && handshake_completed
1056    }
1057
1058    pub fn should_skip_pn(&self, handshake_completed: bool) -> bool {
1059        // Only skip a new packet once we have validated  the peer hasn't sent the
1060        // current skip packet.  For the purposes of OACK, a skip_pn is
1061        // considered validated once we receive an ACK for pn > skip_pn.
1062        let no_current_skip_packet = self.skip_pn.is_none();
1063        let counter_expired = match self.skip_pn_counter {
1064            // Skip if counter has expired
1065            Some(counter) => counter == 0,
1066            // Don't skip if the counter has not been set
1067            None => false,
1068        };
1069
1070        // Skip pn only after the handshake has completed
1071        counter_expired && no_current_skip_packet && handshake_completed
1072    }
1073
1074    pub fn skip_pn(&self) -> Option<u64> {
1075        self.skip_pn
1076    }
1077
1078    pub fn set_skip_pn(&mut self, skip_pn: Option<u64>) {
1079        if skip_pn.is_some() {
1080            // Never overwrite skip_pn until the previous one has been verified
1081            debug_assert!(self.skip_pn.is_none());
1082            // The skip_pn_counter should be expired
1083            debug_assert_eq!(self.skip_pn_counter.unwrap(), 0);
1084        }
1085
1086        self.skip_pn = skip_pn;
1087        // unset the counter
1088        self.skip_pn_counter = None;
1089    }
1090
1091    // Dynamically vary the skip counter based on the CWND.
1092    fn arm_skip_counter(&mut self, cwnd: usize, max_datagram_size: usize) {
1093        let packets_per_cwnd = (cwnd / max_datagram_size) as u64;
1094        let lower = packets_per_cwnd / 2;
1095        let upper = packets_per_cwnd * 2;
1096        // rand_u64_uniform requires a non-zero value so add 1
1097        let skip_range = upper - lower + 1;
1098        let rand_skip_value = rand::rand_u64_uniform(skip_range);
1099
1100        // Skip calculation:
1101        // skip_counter = min_skip
1102        //                + lower
1103        //                + rand(skip_range.lower, skip_range.upper)
1104        //
1105        //```
1106        // c: the current packet number
1107        // s: range of random packet number to skip from
1108        //
1109        // curr_pn
1110        //  |
1111        //  v               |-lower-|
1112        // [c x x x x x x x x x x x s s s s s s s s s s x x]
1113        //    |--min_skip---|       |---skip_range----|
1114        //
1115        //```
1116        let skip_pn_counter = MIN_SKIP_COUNTER_VALUE + lower + rand_skip_value;
1117
1118        self.skip_pn_counter = Some(skip_pn_counter);
1119    }
1120}
1121
1122#[derive(Clone, Copy, Default)]
1123pub struct PktNumWindow {
1124    lower: u64,
1125    window: u128,
1126}
1127
1128impl PktNumWindow {
1129    pub fn insert(&mut self, seq: u64) {
1130        // Packet is on the left end of the window.
1131        if seq < self.lower {
1132            return;
1133        }
1134
1135        // Packet is on the right end of the window.
1136        if seq > self.upper() {
1137            let diff = seq - self.upper();
1138            self.lower += diff;
1139
1140            self.window = self.window.checked_shl(diff as u32).unwrap_or(0);
1141        }
1142
1143        let mask = 1_u128 << (self.upper() - seq);
1144        self.window |= mask;
1145    }
1146
1147    pub fn contains(&mut self, seq: u64) -> bool {
1148        // Packet is on the right end of the window.
1149        if seq > self.upper() {
1150            return false;
1151        }
1152
1153        // Packet is on the left end of the window.
1154        if seq < self.lower {
1155            return true;
1156        }
1157
1158        let mask = 1_u128 << (self.upper() - seq);
1159        self.window & mask != 0
1160    }
1161
1162    fn upper(&self) -> u64 {
1163        self.lower
1164            .saturating_add(std::mem::size_of::<u128>() as u64 * 8) -
1165            1
1166    }
1167}
1168
1169#[cfg(test)]
1170mod tests {
1171    use super::*;
1172    use crate::test_utils;
1173    use crate::MAX_SEND_UDP_PAYLOAD_SIZE;
1174
1175    #[test]
1176    fn retry() {
1177        let hdr = Header {
1178            ty: Type::Retry,
1179            version: 0xafafafaf,
1180            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1181                .into(),
1182            scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1183            pkt_num: 0,
1184            pkt_num_len: 0,
1185            token: Some(vec![0xba; 24]),
1186            versions: None,
1187            key_phase: false,
1188        };
1189
1190        let mut d = [0; 63];
1191
1192        let mut b = octets::OctetsMut::with_slice(&mut d);
1193        assert!(hdr.to_bytes(&mut b).is_ok());
1194
1195        // Add fake retry integrity token.
1196        b.put_bytes(&[0xba; 16]).unwrap();
1197
1198        let mut b = octets::OctetsMut::with_slice(&mut d);
1199        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1200    }
1201
1202    #[test]
1203    fn initial() {
1204        let hdr = Header {
1205            ty: Type::Initial,
1206            version: 0xafafafaf,
1207            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1208                .into(),
1209            scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1210            pkt_num: 0,
1211            pkt_num_len: 0,
1212            token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1213            versions: None,
1214            key_phase: false,
1215        };
1216
1217        let mut d = [0; 50];
1218
1219        let mut b = octets::OctetsMut::with_slice(&mut d);
1220        assert!(hdr.to_bytes(&mut b).is_ok());
1221
1222        let mut b = octets::OctetsMut::with_slice(&mut d);
1223        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1224    }
1225
1226    #[test]
1227    fn initial_v1_dcid_too_long() {
1228        let hdr = Header {
1229            ty: Type::Initial,
1230            version: crate::PROTOCOL_VERSION,
1231            dcid: vec![
1232                0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
1233                0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
1234            ]
1235            .into(),
1236            scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1237            pkt_num: 0,
1238            pkt_num_len: 0,
1239            token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1240            versions: None,
1241            key_phase: false,
1242        };
1243
1244        let mut d = [0; 50];
1245
1246        let mut b = octets::OctetsMut::with_slice(&mut d);
1247        assert!(hdr.to_bytes(&mut b).is_ok());
1248
1249        let mut b = octets::OctetsMut::with_slice(&mut d);
1250        assert_eq!(Header::from_bytes(&mut b, 21), Err(Error::InvalidPacket));
1251    }
1252
1253    #[test]
1254    fn initial_v1_scid_too_long() {
1255        let hdr = Header {
1256            ty: Type::Initial,
1257            version: crate::PROTOCOL_VERSION,
1258            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1259                .into(),
1260            scid: vec![
1261                0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1262                0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1263            ]
1264            .into(),
1265            pkt_num: 0,
1266            pkt_num_len: 0,
1267            token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1268            versions: None,
1269            key_phase: false,
1270        };
1271
1272        let mut d = [0; 50];
1273
1274        let mut b = octets::OctetsMut::with_slice(&mut d);
1275        assert!(hdr.to_bytes(&mut b).is_ok());
1276
1277        let mut b = octets::OctetsMut::with_slice(&mut d);
1278        assert_eq!(Header::from_bytes(&mut b, 9), Err(Error::InvalidPacket));
1279    }
1280
1281    #[test]
1282    fn initial_non_v1_scid_long() {
1283        let hdr = Header {
1284            ty: Type::Initial,
1285            version: 0xafafafaf,
1286            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1287                .into(),
1288            scid: vec![
1289                0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1290                0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
1291            ]
1292            .into(),
1293            pkt_num: 0,
1294            pkt_num_len: 0,
1295            token: Some(vec![0x05, 0x06, 0x07, 0x08]),
1296            versions: None,
1297            key_phase: false,
1298        };
1299
1300        let mut d = [0; 50];
1301
1302        let mut b = octets::OctetsMut::with_slice(&mut d);
1303        assert!(hdr.to_bytes(&mut b).is_ok());
1304
1305        let mut b = octets::OctetsMut::with_slice(&mut d);
1306        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1307    }
1308
1309    #[test]
1310    fn handshake() {
1311        let hdr = Header {
1312            ty: Type::Handshake,
1313            version: 0xafafafaf,
1314            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1315                .into(),
1316            scid: vec![0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb].into(),
1317            pkt_num: 0,
1318            pkt_num_len: 0,
1319            token: None,
1320            versions: None,
1321            key_phase: false,
1322        };
1323
1324        let mut d = [0; 50];
1325
1326        let mut b = octets::OctetsMut::with_slice(&mut d);
1327        assert!(hdr.to_bytes(&mut b).is_ok());
1328
1329        let mut b = octets::OctetsMut::with_slice(&mut d);
1330        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1331    }
1332
1333    #[test]
1334    fn application() {
1335        let hdr = Header {
1336            ty: Type::Short,
1337            version: 0,
1338            dcid: vec![0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba]
1339                .into(),
1340            scid: ConnectionId::default(),
1341            pkt_num: 0,
1342            pkt_num_len: 0,
1343            token: None,
1344            versions: None,
1345            key_phase: false,
1346        };
1347
1348        let mut d = [0; 50];
1349
1350        let mut b = octets::OctetsMut::with_slice(&mut d);
1351        assert!(hdr.to_bytes(&mut b).is_ok());
1352
1353        let mut b = octets::OctetsMut::with_slice(&mut d);
1354        assert_eq!(Header::from_bytes(&mut b, 9).unwrap(), hdr);
1355    }
1356
1357    #[test]
1358    fn pkt_num_encode_decode() {
1359        let num_len = pkt_num_len(0, 0);
1360        assert_eq!(num_len, 1);
1361        let pn = decode_pkt_num(0xa82f30ea, 0x9b32, 2);
1362        assert_eq!(pn, 0xa82f9b32);
1363        let mut d = [0; 10];
1364        let mut b = octets::OctetsMut::with_slice(&mut d);
1365        let num_len = pkt_num_len(0xac5c02, 0xabe8b3);
1366        assert_eq!(num_len, 2);
1367        encode_pkt_num(0xac5c02, num_len, &mut b).unwrap();
1368        // reading
1369        let mut b = octets::OctetsMut::with_slice(&mut d);
1370        let hdr_num = u64::from(b.get_u16().unwrap());
1371        let pn = decode_pkt_num(0xac5c01, hdr_num, num_len);
1372        assert_eq!(pn, 0xac5c02);
1373        // sending 0xace8fe while having 0xabe8b3 acked
1374        let num_len = pkt_num_len(0xace9fe, 0xabe8b3);
1375        assert_eq!(num_len, 3);
1376        let mut b = octets::OctetsMut::with_slice(&mut d);
1377        encode_pkt_num(0xace9fe, num_len, &mut b).unwrap();
1378        // reading
1379        let mut b = octets::OctetsMut::with_slice(&mut d);
1380        let hdr_num = u64::from(b.get_u24().unwrap());
1381        let pn = decode_pkt_num(0xace9fa, hdr_num, num_len);
1382        assert_eq!(pn, 0xace9fe);
1383    }
1384
1385    #[test]
1386    fn pkt_num_window() {
1387        let mut win = PktNumWindow::default();
1388        assert_eq!(win.lower, 0);
1389        assert!(!win.contains(0));
1390        assert!(!win.contains(1));
1391
1392        win.insert(0);
1393        assert_eq!(win.lower, 0);
1394        assert!(win.contains(0));
1395        assert!(!win.contains(1));
1396
1397        win.insert(1);
1398        assert_eq!(win.lower, 0);
1399        assert!(win.contains(0));
1400        assert!(win.contains(1));
1401
1402        win.insert(3);
1403        assert_eq!(win.lower, 0);
1404        assert!(win.contains(0));
1405        assert!(win.contains(1));
1406        assert!(!win.contains(2));
1407        assert!(win.contains(3));
1408
1409        win.insert(10);
1410        assert_eq!(win.lower, 0);
1411        assert!(win.contains(0));
1412        assert!(win.contains(1));
1413        assert!(!win.contains(2));
1414        assert!(win.contains(3));
1415        assert!(!win.contains(4));
1416        assert!(!win.contains(5));
1417        assert!(!win.contains(6));
1418        assert!(!win.contains(7));
1419        assert!(!win.contains(8));
1420        assert!(!win.contains(9));
1421        assert!(win.contains(10));
1422
1423        win.insert(132);
1424        assert_eq!(win.lower, 5);
1425        assert!(win.contains(0));
1426        assert!(win.contains(1));
1427        assert!(win.contains(2));
1428        assert!(win.contains(3));
1429        assert!(win.contains(4));
1430        assert!(!win.contains(5));
1431        assert!(!win.contains(6));
1432        assert!(!win.contains(7));
1433        assert!(!win.contains(8));
1434        assert!(!win.contains(9));
1435        assert!(win.contains(10));
1436        assert!(!win.contains(128));
1437        assert!(!win.contains(130));
1438        assert!(!win.contains(131));
1439        assert!(win.contains(132));
1440
1441        win.insert(1024);
1442        assert_eq!(win.lower, 897);
1443        assert!(win.contains(0));
1444        assert!(win.contains(1));
1445        assert!(win.contains(2));
1446        assert!(win.contains(3));
1447        assert!(win.contains(4));
1448        assert!(win.contains(5));
1449        assert!(win.contains(6));
1450        assert!(win.contains(7));
1451        assert!(win.contains(8));
1452        assert!(win.contains(9));
1453        assert!(win.contains(10));
1454        assert!(win.contains(128));
1455        assert!(win.contains(130));
1456        assert!(win.contains(132));
1457        assert!(win.contains(896));
1458        assert!(!win.contains(897));
1459        assert!(!win.contains(1022));
1460        assert!(!win.contains(1023));
1461        assert!(win.contains(1024));
1462        assert!(!win.contains(1025));
1463        assert!(!win.contains(1026));
1464
1465        win.insert(u64::MAX - 1);
1466        assert!(win.contains(0));
1467        assert!(win.contains(1));
1468        assert!(win.contains(2));
1469        assert!(win.contains(3));
1470        assert!(win.contains(4));
1471        assert!(win.contains(5));
1472        assert!(win.contains(6));
1473        assert!(win.contains(7));
1474        assert!(win.contains(8));
1475        assert!(win.contains(9));
1476        assert!(win.contains(10));
1477        assert!(win.contains(128));
1478        assert!(win.contains(130));
1479        assert!(win.contains(132));
1480        assert!(win.contains(896));
1481        assert!(win.contains(897));
1482        assert!(win.contains(1022));
1483        assert!(win.contains(1023));
1484        assert!(win.contains(1024));
1485        assert!(win.contains(1025));
1486        assert!(win.contains(1026));
1487        assert!(!win.contains(u64::MAX - 2));
1488        assert!(win.contains(u64::MAX - 1));
1489    }
1490
1491    fn assert_decrypt_initial_pkt(
1492        pkt: &mut [u8], dcid: &[u8], is_server: bool, expected_frames: &[u8],
1493        expected_pn: u64, expected_pn_len: usize,
1494    ) {
1495        let mut b = octets::OctetsMut::with_slice(pkt);
1496
1497        let mut hdr = Header::from_bytes(&mut b, 0).unwrap();
1498        assert_eq!(hdr.ty, Type::Initial);
1499
1500        let payload_len = b.get_varint().unwrap() as usize;
1501
1502        let (aead, _) = crypto::derive_initial_key_material(
1503            dcid,
1504            hdr.version,
1505            is_server,
1506            false,
1507        )
1508        .unwrap();
1509
1510        decrypt_hdr(&mut b, &mut hdr, &aead).unwrap();
1511        assert_eq!(hdr.pkt_num_len, expected_pn_len);
1512
1513        let pn = decode_pkt_num(0, hdr.pkt_num, hdr.pkt_num_len);
1514        assert_eq!(pn, expected_pn);
1515
1516        let payload =
1517            decrypt_pkt(&mut b, pn, hdr.pkt_num_len, payload_len, &aead).unwrap();
1518
1519        let payload = payload.as_ref();
1520        assert_eq!(&payload[..expected_frames.len()], expected_frames);
1521    }
1522
1523    #[test]
1524    fn decrypt_client_initial_v1() {
1525        let mut pkt = [
1526            0xc0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1527            0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x7b, 0x9a, 0xec, 0x34,
1528            0xd1, 0xb1, 0xc9, 0x8d, 0xd7, 0x68, 0x9f, 0xb8, 0xec, 0x11, 0xd2,
1529            0x42, 0xb1, 0x23, 0xdc, 0x9b, 0xd8, 0xba, 0xb9, 0x36, 0xb4, 0x7d,
1530            0x92, 0xec, 0x35, 0x6c, 0x0b, 0xab, 0x7d, 0xf5, 0x97, 0x6d, 0x27,
1531            0xcd, 0x44, 0x9f, 0x63, 0x30, 0x00, 0x99, 0xf3, 0x99, 0x1c, 0x26,
1532            0x0e, 0xc4, 0xc6, 0x0d, 0x17, 0xb3, 0x1f, 0x84, 0x29, 0x15, 0x7b,
1533            0xb3, 0x5a, 0x12, 0x82, 0xa6, 0x43, 0xa8, 0xd2, 0x26, 0x2c, 0xad,
1534            0x67, 0x50, 0x0c, 0xad, 0xb8, 0xe7, 0x37, 0x8c, 0x8e, 0xb7, 0x53,
1535            0x9e, 0xc4, 0xd4, 0x90, 0x5f, 0xed, 0x1b, 0xee, 0x1f, 0xc8, 0xaa,
1536            0xfb, 0xa1, 0x7c, 0x75, 0x0e, 0x2c, 0x7a, 0xce, 0x01, 0xe6, 0x00,
1537            0x5f, 0x80, 0xfc, 0xb7, 0xdf, 0x62, 0x12, 0x30, 0xc8, 0x37, 0x11,
1538            0xb3, 0x93, 0x43, 0xfa, 0x02, 0x8c, 0xea, 0x7f, 0x7f, 0xb5, 0xff,
1539            0x89, 0xea, 0xc2, 0x30, 0x82, 0x49, 0xa0, 0x22, 0x52, 0x15, 0x5e,
1540            0x23, 0x47, 0xb6, 0x3d, 0x58, 0xc5, 0x45, 0x7a, 0xfd, 0x84, 0xd0,
1541            0x5d, 0xff, 0xfd, 0xb2, 0x03, 0x92, 0x84, 0x4a, 0xe8, 0x12, 0x15,
1542            0x46, 0x82, 0xe9, 0xcf, 0x01, 0x2f, 0x90, 0x21, 0xa6, 0xf0, 0xbe,
1543            0x17, 0xdd, 0xd0, 0xc2, 0x08, 0x4d, 0xce, 0x25, 0xff, 0x9b, 0x06,
1544            0xcd, 0xe5, 0x35, 0xd0, 0xf9, 0x20, 0xa2, 0xdb, 0x1b, 0xf3, 0x62,
1545            0xc2, 0x3e, 0x59, 0x6d, 0xee, 0x38, 0xf5, 0xa6, 0xcf, 0x39, 0x48,
1546            0x83, 0x8a, 0x3a, 0xec, 0x4e, 0x15, 0xda, 0xf8, 0x50, 0x0a, 0x6e,
1547            0xf6, 0x9e, 0xc4, 0xe3, 0xfe, 0xb6, 0xb1, 0xd9, 0x8e, 0x61, 0x0a,
1548            0xc8, 0xb7, 0xec, 0x3f, 0xaf, 0x6a, 0xd7, 0x60, 0xb7, 0xba, 0xd1,
1549            0xdb, 0x4b, 0xa3, 0x48, 0x5e, 0x8a, 0x94, 0xdc, 0x25, 0x0a, 0xe3,
1550            0xfd, 0xb4, 0x1e, 0xd1, 0x5f, 0xb6, 0xa8, 0xe5, 0xeb, 0xa0, 0xfc,
1551            0x3d, 0xd6, 0x0b, 0xc8, 0xe3, 0x0c, 0x5c, 0x42, 0x87, 0xe5, 0x38,
1552            0x05, 0xdb, 0x05, 0x9a, 0xe0, 0x64, 0x8d, 0xb2, 0xf6, 0x42, 0x64,
1553            0xed, 0x5e, 0x39, 0xbe, 0x2e, 0x20, 0xd8, 0x2d, 0xf5, 0x66, 0xda,
1554            0x8d, 0xd5, 0x99, 0x8c, 0xca, 0xbd, 0xae, 0x05, 0x30, 0x60, 0xae,
1555            0x6c, 0x7b, 0x43, 0x78, 0xe8, 0x46, 0xd2, 0x9f, 0x37, 0xed, 0x7b,
1556            0x4e, 0xa9, 0xec, 0x5d, 0x82, 0xe7, 0x96, 0x1b, 0x7f, 0x25, 0xa9,
1557            0x32, 0x38, 0x51, 0xf6, 0x81, 0xd5, 0x82, 0x36, 0x3a, 0xa5, 0xf8,
1558            0x99, 0x37, 0xf5, 0xa6, 0x72, 0x58, 0xbf, 0x63, 0xad, 0x6f, 0x1a,
1559            0x0b, 0x1d, 0x96, 0xdb, 0xd4, 0xfa, 0xdd, 0xfc, 0xef, 0xc5, 0x26,
1560            0x6b, 0xa6, 0x61, 0x17, 0x22, 0x39, 0x5c, 0x90, 0x65, 0x56, 0xbe,
1561            0x52, 0xaf, 0xe3, 0xf5, 0x65, 0x63, 0x6a, 0xd1, 0xb1, 0x7d, 0x50,
1562            0x8b, 0x73, 0xd8, 0x74, 0x3e, 0xeb, 0x52, 0x4b, 0xe2, 0x2b, 0x3d,
1563            0xcb, 0xc2, 0xc7, 0x46, 0x8d, 0x54, 0x11, 0x9c, 0x74, 0x68, 0x44,
1564            0x9a, 0x13, 0xd8, 0xe3, 0xb9, 0x58, 0x11, 0xa1, 0x98, 0xf3, 0x49,
1565            0x1d, 0xe3, 0xe7, 0xfe, 0x94, 0x2b, 0x33, 0x04, 0x07, 0xab, 0xf8,
1566            0x2a, 0x4e, 0xd7, 0xc1, 0xb3, 0x11, 0x66, 0x3a, 0xc6, 0x98, 0x90,
1567            0xf4, 0x15, 0x70, 0x15, 0x85, 0x3d, 0x91, 0xe9, 0x23, 0x03, 0x7c,
1568            0x22, 0x7a, 0x33, 0xcd, 0xd5, 0xec, 0x28, 0x1c, 0xa3, 0xf7, 0x9c,
1569            0x44, 0x54, 0x6b, 0x9d, 0x90, 0xca, 0x00, 0xf0, 0x64, 0xc9, 0x9e,
1570            0x3d, 0xd9, 0x79, 0x11, 0xd3, 0x9f, 0xe9, 0xc5, 0xd0, 0xb2, 0x3a,
1571            0x22, 0x9a, 0x23, 0x4c, 0xb3, 0x61, 0x86, 0xc4, 0x81, 0x9e, 0x8b,
1572            0x9c, 0x59, 0x27, 0x72, 0x66, 0x32, 0x29, 0x1d, 0x6a, 0x41, 0x82,
1573            0x11, 0xcc, 0x29, 0x62, 0xe2, 0x0f, 0xe4, 0x7f, 0xeb, 0x3e, 0xdf,
1574            0x33, 0x0f, 0x2c, 0x60, 0x3a, 0x9d, 0x48, 0xc0, 0xfc, 0xb5, 0x69,
1575            0x9d, 0xbf, 0xe5, 0x89, 0x64, 0x25, 0xc5, 0xba, 0xc4, 0xae, 0xe8,
1576            0x2e, 0x57, 0xa8, 0x5a, 0xaf, 0x4e, 0x25, 0x13, 0xe4, 0xf0, 0x57,
1577            0x96, 0xb0, 0x7b, 0xa2, 0xee, 0x47, 0xd8, 0x05, 0x06, 0xf8, 0xd2,
1578            0xc2, 0x5e, 0x50, 0xfd, 0x14, 0xde, 0x71, 0xe6, 0xc4, 0x18, 0x55,
1579            0x93, 0x02, 0xf9, 0x39, 0xb0, 0xe1, 0xab, 0xd5, 0x76, 0xf2, 0x79,
1580            0xc4, 0xb2, 0xe0, 0xfe, 0xb8, 0x5c, 0x1f, 0x28, 0xff, 0x18, 0xf5,
1581            0x88, 0x91, 0xff, 0xef, 0x13, 0x2e, 0xef, 0x2f, 0xa0, 0x93, 0x46,
1582            0xae, 0xe3, 0x3c, 0x28, 0xeb, 0x13, 0x0f, 0xf2, 0x8f, 0x5b, 0x76,
1583            0x69, 0x53, 0x33, 0x41, 0x13, 0x21, 0x19, 0x96, 0xd2, 0x00, 0x11,
1584            0xa1, 0x98, 0xe3, 0xfc, 0x43, 0x3f, 0x9f, 0x25, 0x41, 0x01, 0x0a,
1585            0xe1, 0x7c, 0x1b, 0xf2, 0x02, 0x58, 0x0f, 0x60, 0x47, 0x47, 0x2f,
1586            0xb3, 0x68, 0x57, 0xfe, 0x84, 0x3b, 0x19, 0xf5, 0x98, 0x40, 0x09,
1587            0xdd, 0xc3, 0x24, 0x04, 0x4e, 0x84, 0x7a, 0x4f, 0x4a, 0x0a, 0xb3,
1588            0x4f, 0x71, 0x95, 0x95, 0xde, 0x37, 0x25, 0x2d, 0x62, 0x35, 0x36,
1589            0x5e, 0x9b, 0x84, 0x39, 0x2b, 0x06, 0x10, 0x85, 0x34, 0x9d, 0x73,
1590            0x20, 0x3a, 0x4a, 0x13, 0xe9, 0x6f, 0x54, 0x32, 0xec, 0x0f, 0xd4,
1591            0xa1, 0xee, 0x65, 0xac, 0xcd, 0xd5, 0xe3, 0x90, 0x4d, 0xf5, 0x4c,
1592            0x1d, 0xa5, 0x10, 0xb0, 0xff, 0x20, 0xdc, 0xc0, 0xc7, 0x7f, 0xcb,
1593            0x2c, 0x0e, 0x0e, 0xb6, 0x05, 0xcb, 0x05, 0x04, 0xdb, 0x87, 0x63,
1594            0x2c, 0xf3, 0xd8, 0xb4, 0xda, 0xe6, 0xe7, 0x05, 0x76, 0x9d, 0x1d,
1595            0xe3, 0x54, 0x27, 0x01, 0x23, 0xcb, 0x11, 0x45, 0x0e, 0xfc, 0x60,
1596            0xac, 0x47, 0x68, 0x3d, 0x7b, 0x8d, 0x0f, 0x81, 0x13, 0x65, 0x56,
1597            0x5f, 0xd9, 0x8c, 0x4c, 0x8e, 0xb9, 0x36, 0xbc, 0xab, 0x8d, 0x06,
1598            0x9f, 0xc3, 0x3b, 0xd8, 0x01, 0xb0, 0x3a, 0xde, 0xa2, 0xe1, 0xfb,
1599            0xc5, 0xaa, 0x46, 0x3d, 0x08, 0xca, 0x19, 0x89, 0x6d, 0x2b, 0xf5,
1600            0x9a, 0x07, 0x1b, 0x85, 0x1e, 0x6c, 0x23, 0x90, 0x52, 0x17, 0x2f,
1601            0x29, 0x6b, 0xfb, 0x5e, 0x72, 0x40, 0x47, 0x90, 0xa2, 0x18, 0x10,
1602            0x14, 0xf3, 0xb9, 0x4a, 0x4e, 0x97, 0xd1, 0x17, 0xb4, 0x38, 0x13,
1603            0x03, 0x68, 0xcc, 0x39, 0xdb, 0xb2, 0xd1, 0x98, 0x06, 0x5a, 0xe3,
1604            0x98, 0x65, 0x47, 0x92, 0x6c, 0xd2, 0x16, 0x2f, 0x40, 0xa2, 0x9f,
1605            0x0c, 0x3c, 0x87, 0x45, 0xc0, 0xf5, 0x0f, 0xba, 0x38, 0x52, 0xe5,
1606            0x66, 0xd4, 0x45, 0x75, 0xc2, 0x9d, 0x39, 0xa0, 0x3f, 0x0c, 0xda,
1607            0x72, 0x19, 0x84, 0xb6, 0xf4, 0x40, 0x59, 0x1f, 0x35, 0x5e, 0x12,
1608            0xd4, 0x39, 0xff, 0x15, 0x0a, 0xab, 0x76, 0x13, 0x49, 0x9d, 0xbd,
1609            0x49, 0xad, 0xab, 0xc8, 0x67, 0x6e, 0xef, 0x02, 0x3b, 0x15, 0xb6,
1610            0x5b, 0xfc, 0x5c, 0xa0, 0x69, 0x48, 0x10, 0x9f, 0x23, 0xf3, 0x50,
1611            0xdb, 0x82, 0x12, 0x35, 0x35, 0xeb, 0x8a, 0x74, 0x33, 0xbd, 0xab,
1612            0xcb, 0x90, 0x92, 0x71, 0xa6, 0xec, 0xbc, 0xb5, 0x8b, 0x93, 0x6a,
1613            0x88, 0xcd, 0x4e, 0x8f, 0x2e, 0x6f, 0xf5, 0x80, 0x01, 0x75, 0xf1,
1614            0x13, 0x25, 0x3d, 0x8f, 0xa9, 0xca, 0x88, 0x85, 0xc2, 0xf5, 0x52,
1615            0xe6, 0x57, 0xdc, 0x60, 0x3f, 0x25, 0x2e, 0x1a, 0x8e, 0x30, 0x8f,
1616            0x76, 0xf0, 0xbe, 0x79, 0xe2, 0xfb, 0x8f, 0x5d, 0x5f, 0xbb, 0xe2,
1617            0xe3, 0x0e, 0xca, 0xdd, 0x22, 0x07, 0x23, 0xc8, 0xc0, 0xae, 0xa8,
1618            0x07, 0x8c, 0xdf, 0xcb, 0x38, 0x68, 0x26, 0x3f, 0xf8, 0xf0, 0x94,
1619            0x00, 0x54, 0xda, 0x48, 0x78, 0x18, 0x93, 0xa7, 0xe4, 0x9a, 0xd5,
1620            0xaf, 0xf4, 0xaf, 0x30, 0x0c, 0xd8, 0x04, 0xa6, 0xb6, 0x27, 0x9a,
1621            0xb3, 0xff, 0x3a, 0xfb, 0x64, 0x49, 0x1c, 0x85, 0x19, 0x4a, 0xab,
1622            0x76, 0x0d, 0x58, 0xa6, 0x06, 0x65, 0x4f, 0x9f, 0x44, 0x00, 0xe8,
1623            0xb3, 0x85, 0x91, 0x35, 0x6f, 0xbf, 0x64, 0x25, 0xac, 0xa2, 0x6d,
1624            0xc8, 0x52, 0x44, 0x25, 0x9f, 0xf2, 0xb1, 0x9c, 0x41, 0xb9, 0xf9,
1625            0x6f, 0x3c, 0xa9, 0xec, 0x1d, 0xde, 0x43, 0x4d, 0xa7, 0xd2, 0xd3,
1626            0x92, 0xb9, 0x05, 0xdd, 0xf3, 0xd1, 0xf9, 0xaf, 0x93, 0xd1, 0xaf,
1627            0x59, 0x50, 0xbd, 0x49, 0x3f, 0x5a, 0xa7, 0x31, 0xb4, 0x05, 0x6d,
1628            0xf3, 0x1b, 0xd2, 0x67, 0xb6, 0xb9, 0x0a, 0x07, 0x98, 0x31, 0xaa,
1629            0xf5, 0x79, 0xbe, 0x0a, 0x39, 0x01, 0x31, 0x37, 0xaa, 0xc6, 0xd4,
1630            0x04, 0xf5, 0x18, 0xcf, 0xd4, 0x68, 0x40, 0x64, 0x7e, 0x78, 0xbf,
1631            0xe7, 0x06, 0xca, 0x4c, 0xf5, 0xe9, 0xc5, 0x45, 0x3e, 0x9f, 0x7c,
1632            0xfd, 0x2b, 0x8b, 0x4c, 0x8d, 0x16, 0x9a, 0x44, 0xe5, 0x5c, 0x88,
1633            0xd4, 0xa9, 0xa7, 0xf9, 0x47, 0x42, 0x41, 0x10, 0x92, 0xab, 0xbd,
1634            0xf8, 0xb8, 0x89, 0xe5, 0xc1, 0x99, 0xd0, 0x96, 0xe3, 0xf2, 0x47,
1635            0x88,
1636        ];
1637
1638        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1639
1640        let frames = [
1641            0x06, 0x00, 0x40, 0xf1, 0x01, 0x00, 0x00, 0xed, 0x03, 0x03, 0xeb,
1642            0xf8, 0xfa, 0x56, 0xf1, 0x29, 0x39, 0xb9, 0x58, 0x4a, 0x38, 0x96,
1643            0x47, 0x2e, 0xc4, 0x0b, 0xb8, 0x63, 0xcf, 0xd3, 0xe8, 0x68, 0x04,
1644            0xfe, 0x3a, 0x47, 0xf0, 0x6a, 0x2b, 0x69, 0x48, 0x4c, 0x00, 0x00,
1645            0x04, 0x13, 0x01, 0x13, 0x02, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00,
1646            0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d,
1647            0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xff, 0x01, 0x00, 0x01,
1648            0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17,
1649            0x00, 0x18, 0x00, 0x10, 0x00, 0x07, 0x00, 0x05, 0x04, 0x61, 0x6c,
1650            0x70, 0x6e, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
1651            0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x93,
1652            0x70, 0xb2, 0xc9, 0xca, 0xa4, 0x7f, 0xba, 0xba, 0xf4, 0x55, 0x9f,
1653            0xed, 0xba, 0x75, 0x3d, 0xe1, 0x71, 0xfa, 0x71, 0xf5, 0x0f, 0x1c,
1654            0xe1, 0x5d, 0x43, 0xe9, 0x94, 0xec, 0x74, 0xd7, 0x48, 0x00, 0x2b,
1655            0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e,
1656            0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08,
1657            0x05, 0x08, 0x06, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c,
1658            0x00, 0x02, 0x40, 0x01, 0xff, 0xa5, 0x00, 0x32, 0x04, 0x08, 0xff,
1659            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x04, 0x80, 0x00,
1660            0xff, 0xff, 0x07, 0x04, 0x80, 0x00, 0xff, 0xff, 0x08, 0x01, 0x10,
1661            0x01, 0x04, 0x80, 0x00, 0x75, 0x30, 0x09, 0x01, 0x10, 0x0f, 0x08,
1662            0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0x06, 0x04, 0x80,
1663            0x00, 0xff, 0xff,
1664        ];
1665
1666        assert_decrypt_initial_pkt(&mut pkt, &dcid, true, &frames, 2, 4);
1667    }
1668
1669    #[test]
1670    fn decrypt_server_initial_v1() {
1671        let mut pkt = [
1672            0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
1673            0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0xc0, 0xd9, 0x5a, 0x48,
1674            0x2c, 0xd0, 0x99, 0x1c, 0xd2, 0x5b, 0x0a, 0xac, 0x40, 0x6a, 0x58,
1675            0x16, 0xb6, 0x39, 0x41, 0x00, 0xf3, 0x7a, 0x1c, 0x69, 0x79, 0x75,
1676            0x54, 0x78, 0x0b, 0xb3, 0x8c, 0xc5, 0xa9, 0x9f, 0x5e, 0xde, 0x4c,
1677            0xf7, 0x3c, 0x3e, 0xc2, 0x49, 0x3a, 0x18, 0x39, 0xb3, 0xdb, 0xcb,
1678            0xa3, 0xf6, 0xea, 0x46, 0xc5, 0xb7, 0x68, 0x4d, 0xf3, 0x54, 0x8e,
1679            0x7d, 0xde, 0xb9, 0xc3, 0xbf, 0x9c, 0x73, 0xcc, 0x3f, 0x3b, 0xde,
1680            0xd7, 0x4b, 0x56, 0x2b, 0xfb, 0x19, 0xfb, 0x84, 0x02, 0x2f, 0x8e,
1681            0xf4, 0xcd, 0xd9, 0x37, 0x95, 0xd7, 0x7d, 0x06, 0xed, 0xbb, 0x7a,
1682            0xaf, 0x2f, 0x58, 0x89, 0x18, 0x50, 0xab, 0xbd, 0xca, 0x3d, 0x20,
1683            0x39, 0x8c, 0x27, 0x64, 0x56, 0xcb, 0xc4, 0x21, 0x58, 0x40, 0x7d,
1684            0xd0, 0x74, 0xee,
1685        ];
1686
1687        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1688
1689        let frames = [
1690            0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x5a, 0x02, 0x00,
1691            0x00, 0x56, 0x03, 0x03, 0xee, 0xfc, 0xe7, 0xf7, 0xb3, 0x7b, 0xa1,
1692            0xd1, 0x63, 0x2e, 0x96, 0x67, 0x78, 0x25, 0xdd, 0xf7, 0x39, 0x88,
1693            0xcf, 0xc7, 0x98, 0x25, 0xdf, 0x56, 0x6d, 0xc5, 0x43, 0x0b, 0x9a,
1694            0x04, 0x5a, 0x12, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33,
1695            0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x9d, 0x3c, 0x94, 0x0d, 0x89,
1696            0x69, 0x0b, 0x84, 0xd0, 0x8a, 0x60, 0x99, 0x3c, 0x14, 0x4e, 0xca,
1697            0x68, 0x4d, 0x10, 0x81, 0x28, 0x7c, 0x83, 0x4d, 0x53, 0x11, 0xbc,
1698            0xf3, 0x2b, 0xb9, 0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04,
1699        ];
1700
1701        assert_decrypt_initial_pkt(&mut pkt, &dcid, false, &frames, 1, 2);
1702    }
1703
1704    #[test]
1705    fn decrypt_chacha20() {
1706        let secret = [
1707            0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42,
1708            0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0,
1709            0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b,
1710        ];
1711
1712        let mut pkt = [
1713            0x4c, 0xfe, 0x41, 0x89, 0x65, 0x5e, 0x5c, 0xd5, 0x5c, 0x41, 0xf6,
1714            0x90, 0x80, 0x57, 0x5d, 0x79, 0x99, 0xc2, 0x5a, 0x5b, 0xfb,
1715        ];
1716
1717        let mut b = octets::OctetsMut::with_slice(&mut pkt);
1718
1719        let alg = crypto::Algorithm::ChaCha20_Poly1305;
1720
1721        let aead = crypto::Open::from_secret(alg, &secret).unwrap();
1722
1723        let mut hdr = Header::from_bytes(&mut b, 0).unwrap();
1724        assert_eq!(hdr.ty, Type::Short);
1725
1726        let payload_len = b.cap();
1727
1728        decrypt_hdr(&mut b, &mut hdr, &aead).unwrap();
1729        assert_eq!(hdr.pkt_num_len, 3);
1730
1731        let pn = decode_pkt_num(654_360_564, hdr.pkt_num, hdr.pkt_num_len);
1732        assert_eq!(pn, 654_360_564);
1733
1734        let payload =
1735            decrypt_pkt(&mut b, pn, hdr.pkt_num_len, payload_len, &aead).unwrap();
1736
1737        let payload = payload.as_ref();
1738        assert_eq!(&payload, &[0x01]);
1739    }
1740
1741    fn assert_encrypt_initial_pkt(
1742        header: &mut [u8], dcid: &[u8], frames: &[u8], pn: u64, pn_len: usize,
1743        is_server: bool, expected_pkt: &[u8],
1744    ) {
1745        let mut b = octets::OctetsMut::with_slice(header);
1746
1747        let hdr = Header::from_bytes(&mut b, 0).unwrap();
1748        assert_eq!(hdr.ty, Type::Initial);
1749
1750        let mut out = vec![0; expected_pkt.len()];
1751        let mut b = octets::OctetsMut::with_slice(&mut out);
1752
1753        b.put_bytes(header).unwrap();
1754
1755        let (_, aead) = crypto::derive_initial_key_material(
1756            dcid,
1757            hdr.version,
1758            is_server,
1759            false,
1760        )
1761        .unwrap();
1762
1763        let payload_len = frames.len();
1764
1765        let payload_offset = b.off();
1766
1767        b.put_bytes(frames).unwrap();
1768
1769        let written = encrypt_pkt(
1770            &mut b,
1771            pn,
1772            pn_len,
1773            payload_len,
1774            payload_offset,
1775            None,
1776            &aead,
1777        )
1778        .unwrap();
1779
1780        assert_eq!(written, expected_pkt.len());
1781        assert_eq!(&out[..written], expected_pkt);
1782    }
1783
1784    #[test]
1785    fn encrypt_client_initial_v1() {
1786        let mut header = [
1787            0xc3, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1788            0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x00, 0x00, 0x00, 0x02,
1789        ];
1790
1791        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
1792
1793        let frames = [
1794            0x06, 0x00, 0x40, 0xf1, 0x01, 0x00, 0x00, 0xed, 0x03, 0x03, 0xeb,
1795            0xf8, 0xfa, 0x56, 0xf1, 0x29, 0x39, 0xb9, 0x58, 0x4a, 0x38, 0x96,
1796            0x47, 0x2e, 0xc4, 0x0b, 0xb8, 0x63, 0xcf, 0xd3, 0xe8, 0x68, 0x04,
1797            0xfe, 0x3a, 0x47, 0xf0, 0x6a, 0x2b, 0x69, 0x48, 0x4c, 0x00, 0x00,
1798            0x04, 0x13, 0x01, 0x13, 0x02, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00,
1799            0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d,
1800            0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xff, 0x01, 0x00, 0x01,
1801            0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17,
1802            0x00, 0x18, 0x00, 0x10, 0x00, 0x07, 0x00, 0x05, 0x04, 0x61, 0x6c,
1803            0x70, 0x6e, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
1804            0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x93,
1805            0x70, 0xb2, 0xc9, 0xca, 0xa4, 0x7f, 0xba, 0xba, 0xf4, 0x55, 0x9f,
1806            0xed, 0xba, 0x75, 0x3d, 0xe1, 0x71, 0xfa, 0x71, 0xf5, 0x0f, 0x1c,
1807            0xe1, 0x5d, 0x43, 0xe9, 0x94, 0xec, 0x74, 0xd7, 0x48, 0x00, 0x2b,
1808            0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e,
1809            0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08,
1810            0x05, 0x08, 0x06, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c,
1811            0x00, 0x02, 0x40, 0x01, 0xff, 0xa5, 0x00, 0x32, 0x04, 0x08, 0xff,
1812            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x04, 0x80, 0x00,
1813            0xff, 0xff, 0x07, 0x04, 0x80, 0x00, 0xff, 0xff, 0x08, 0x01, 0x10,
1814            0x01, 0x04, 0x80, 0x00, 0x75, 0x30, 0x09, 0x01, 0x10, 0x0f, 0x08,
1815            0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0x06, 0x04, 0x80,
1816            0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1817            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1818            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1819            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1820            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1821            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1822            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1823            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1824            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1825            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1826            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1827            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1828            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1829            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1830            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1831            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1832            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1833            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1834            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1835            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1836            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1837            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1838            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1839            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1841            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1842            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1843            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1844            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1845            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1846            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1847            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1848            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1849            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1850            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1851            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1852            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1853            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1854            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1855            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1856            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1857            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1858            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1859            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1860            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1861            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1862            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1863            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1864            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1865            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1866            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1867            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1868            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1869            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1870            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1871            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1872            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1873            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1874            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1875            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1876            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1877            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1878            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1879            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1880            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1881            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1882            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1883            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1884            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1885            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1886            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1887            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1888            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1889            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1890            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1891            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1892            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1893            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1894            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1895            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1896            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1897            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1898            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1899            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1900        ];
1901
1902        let pkt = [
1903            0xc0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e,
1904            0x51, 0x57, 0x08, 0x00, 0x00, 0x44, 0x9e, 0x7b, 0x9a, 0xec, 0x34,
1905            0xd1, 0xb1, 0xc9, 0x8d, 0xd7, 0x68, 0x9f, 0xb8, 0xec, 0x11, 0xd2,
1906            0x42, 0xb1, 0x23, 0xdc, 0x9b, 0xd8, 0xba, 0xb9, 0x36, 0xb4, 0x7d,
1907            0x92, 0xec, 0x35, 0x6c, 0x0b, 0xab, 0x7d, 0xf5, 0x97, 0x6d, 0x27,
1908            0xcd, 0x44, 0x9f, 0x63, 0x30, 0x00, 0x99, 0xf3, 0x99, 0x1c, 0x26,
1909            0x0e, 0xc4, 0xc6, 0x0d, 0x17, 0xb3, 0x1f, 0x84, 0x29, 0x15, 0x7b,
1910            0xb3, 0x5a, 0x12, 0x82, 0xa6, 0x43, 0xa8, 0xd2, 0x26, 0x2c, 0xad,
1911            0x67, 0x50, 0x0c, 0xad, 0xb8, 0xe7, 0x37, 0x8c, 0x8e, 0xb7, 0x53,
1912            0x9e, 0xc4, 0xd4, 0x90, 0x5f, 0xed, 0x1b, 0xee, 0x1f, 0xc8, 0xaa,
1913            0xfb, 0xa1, 0x7c, 0x75, 0x0e, 0x2c, 0x7a, 0xce, 0x01, 0xe6, 0x00,
1914            0x5f, 0x80, 0xfc, 0xb7, 0xdf, 0x62, 0x12, 0x30, 0xc8, 0x37, 0x11,
1915            0xb3, 0x93, 0x43, 0xfa, 0x02, 0x8c, 0xea, 0x7f, 0x7f, 0xb5, 0xff,
1916            0x89, 0xea, 0xc2, 0x30, 0x82, 0x49, 0xa0, 0x22, 0x52, 0x15, 0x5e,
1917            0x23, 0x47, 0xb6, 0x3d, 0x58, 0xc5, 0x45, 0x7a, 0xfd, 0x84, 0xd0,
1918            0x5d, 0xff, 0xfd, 0xb2, 0x03, 0x92, 0x84, 0x4a, 0xe8, 0x12, 0x15,
1919            0x46, 0x82, 0xe9, 0xcf, 0x01, 0x2f, 0x90, 0x21, 0xa6, 0xf0, 0xbe,
1920            0x17, 0xdd, 0xd0, 0xc2, 0x08, 0x4d, 0xce, 0x25, 0xff, 0x9b, 0x06,
1921            0xcd, 0xe5, 0x35, 0xd0, 0xf9, 0x20, 0xa2, 0xdb, 0x1b, 0xf3, 0x62,
1922            0xc2, 0x3e, 0x59, 0x6d, 0xee, 0x38, 0xf5, 0xa6, 0xcf, 0x39, 0x48,
1923            0x83, 0x8a, 0x3a, 0xec, 0x4e, 0x15, 0xda, 0xf8, 0x50, 0x0a, 0x6e,
1924            0xf6, 0x9e, 0xc4, 0xe3, 0xfe, 0xb6, 0xb1, 0xd9, 0x8e, 0x61, 0x0a,
1925            0xc8, 0xb7, 0xec, 0x3f, 0xaf, 0x6a, 0xd7, 0x60, 0xb7, 0xba, 0xd1,
1926            0xdb, 0x4b, 0xa3, 0x48, 0x5e, 0x8a, 0x94, 0xdc, 0x25, 0x0a, 0xe3,
1927            0xfd, 0xb4, 0x1e, 0xd1, 0x5f, 0xb6, 0xa8, 0xe5, 0xeb, 0xa0, 0xfc,
1928            0x3d, 0xd6, 0x0b, 0xc8, 0xe3, 0x0c, 0x5c, 0x42, 0x87, 0xe5, 0x38,
1929            0x05, 0xdb, 0x05, 0x9a, 0xe0, 0x64, 0x8d, 0xb2, 0xf6, 0x42, 0x64,
1930            0xed, 0x5e, 0x39, 0xbe, 0x2e, 0x20, 0xd8, 0x2d, 0xf5, 0x66, 0xda,
1931            0x8d, 0xd5, 0x99, 0x8c, 0xca, 0xbd, 0xae, 0x05, 0x30, 0x60, 0xae,
1932            0x6c, 0x7b, 0x43, 0x78, 0xe8, 0x46, 0xd2, 0x9f, 0x37, 0xed, 0x7b,
1933            0x4e, 0xa9, 0xec, 0x5d, 0x82, 0xe7, 0x96, 0x1b, 0x7f, 0x25, 0xa9,
1934            0x32, 0x38, 0x51, 0xf6, 0x81, 0xd5, 0x82, 0x36, 0x3a, 0xa5, 0xf8,
1935            0x99, 0x37, 0xf5, 0xa6, 0x72, 0x58, 0xbf, 0x63, 0xad, 0x6f, 0x1a,
1936            0x0b, 0x1d, 0x96, 0xdb, 0xd4, 0xfa, 0xdd, 0xfc, 0xef, 0xc5, 0x26,
1937            0x6b, 0xa6, 0x61, 0x17, 0x22, 0x39, 0x5c, 0x90, 0x65, 0x56, 0xbe,
1938            0x52, 0xaf, 0xe3, 0xf5, 0x65, 0x63, 0x6a, 0xd1, 0xb1, 0x7d, 0x50,
1939            0x8b, 0x73, 0xd8, 0x74, 0x3e, 0xeb, 0x52, 0x4b, 0xe2, 0x2b, 0x3d,
1940            0xcb, 0xc2, 0xc7, 0x46, 0x8d, 0x54, 0x11, 0x9c, 0x74, 0x68, 0x44,
1941            0x9a, 0x13, 0xd8, 0xe3, 0xb9, 0x58, 0x11, 0xa1, 0x98, 0xf3, 0x49,
1942            0x1d, 0xe3, 0xe7, 0xfe, 0x94, 0x2b, 0x33, 0x04, 0x07, 0xab, 0xf8,
1943            0x2a, 0x4e, 0xd7, 0xc1, 0xb3, 0x11, 0x66, 0x3a, 0xc6, 0x98, 0x90,
1944            0xf4, 0x15, 0x70, 0x15, 0x85, 0x3d, 0x91, 0xe9, 0x23, 0x03, 0x7c,
1945            0x22, 0x7a, 0x33, 0xcd, 0xd5, 0xec, 0x28, 0x1c, 0xa3, 0xf7, 0x9c,
1946            0x44, 0x54, 0x6b, 0x9d, 0x90, 0xca, 0x00, 0xf0, 0x64, 0xc9, 0x9e,
1947            0x3d, 0xd9, 0x79, 0x11, 0xd3, 0x9f, 0xe9, 0xc5, 0xd0, 0xb2, 0x3a,
1948            0x22, 0x9a, 0x23, 0x4c, 0xb3, 0x61, 0x86, 0xc4, 0x81, 0x9e, 0x8b,
1949            0x9c, 0x59, 0x27, 0x72, 0x66, 0x32, 0x29, 0x1d, 0x6a, 0x41, 0x82,
1950            0x11, 0xcc, 0x29, 0x62, 0xe2, 0x0f, 0xe4, 0x7f, 0xeb, 0x3e, 0xdf,
1951            0x33, 0x0f, 0x2c, 0x60, 0x3a, 0x9d, 0x48, 0xc0, 0xfc, 0xb5, 0x69,
1952            0x9d, 0xbf, 0xe5, 0x89, 0x64, 0x25, 0xc5, 0xba, 0xc4, 0xae, 0xe8,
1953            0x2e, 0x57, 0xa8, 0x5a, 0xaf, 0x4e, 0x25, 0x13, 0xe4, 0xf0, 0x57,
1954            0x96, 0xb0, 0x7b, 0xa2, 0xee, 0x47, 0xd8, 0x05, 0x06, 0xf8, 0xd2,
1955            0xc2, 0x5e, 0x50, 0xfd, 0x14, 0xde, 0x71, 0xe6, 0xc4, 0x18, 0x55,
1956            0x93, 0x02, 0xf9, 0x39, 0xb0, 0xe1, 0xab, 0xd5, 0x76, 0xf2, 0x79,
1957            0xc4, 0xb2, 0xe0, 0xfe, 0xb8, 0x5c, 0x1f, 0x28, 0xff, 0x18, 0xf5,
1958            0x88, 0x91, 0xff, 0xef, 0x13, 0x2e, 0xef, 0x2f, 0xa0, 0x93, 0x46,
1959            0xae, 0xe3, 0x3c, 0x28, 0xeb, 0x13, 0x0f, 0xf2, 0x8f, 0x5b, 0x76,
1960            0x69, 0x53, 0x33, 0x41, 0x13, 0x21, 0x19, 0x96, 0xd2, 0x00, 0x11,
1961            0xa1, 0x98, 0xe3, 0xfc, 0x43, 0x3f, 0x9f, 0x25, 0x41, 0x01, 0x0a,
1962            0xe1, 0x7c, 0x1b, 0xf2, 0x02, 0x58, 0x0f, 0x60, 0x47, 0x47, 0x2f,
1963            0xb3, 0x68, 0x57, 0xfe, 0x84, 0x3b, 0x19, 0xf5, 0x98, 0x40, 0x09,
1964            0xdd, 0xc3, 0x24, 0x04, 0x4e, 0x84, 0x7a, 0x4f, 0x4a, 0x0a, 0xb3,
1965            0x4f, 0x71, 0x95, 0x95, 0xde, 0x37, 0x25, 0x2d, 0x62, 0x35, 0x36,
1966            0x5e, 0x9b, 0x84, 0x39, 0x2b, 0x06, 0x10, 0x85, 0x34, 0x9d, 0x73,
1967            0x20, 0x3a, 0x4a, 0x13, 0xe9, 0x6f, 0x54, 0x32, 0xec, 0x0f, 0xd4,
1968            0xa1, 0xee, 0x65, 0xac, 0xcd, 0xd5, 0xe3, 0x90, 0x4d, 0xf5, 0x4c,
1969            0x1d, 0xa5, 0x10, 0xb0, 0xff, 0x20, 0xdc, 0xc0, 0xc7, 0x7f, 0xcb,
1970            0x2c, 0x0e, 0x0e, 0xb6, 0x05, 0xcb, 0x05, 0x04, 0xdb, 0x87, 0x63,
1971            0x2c, 0xf3, 0xd8, 0xb4, 0xda, 0xe6, 0xe7, 0x05, 0x76, 0x9d, 0x1d,
1972            0xe3, 0x54, 0x27, 0x01, 0x23, 0xcb, 0x11, 0x45, 0x0e, 0xfc, 0x60,
1973            0xac, 0x47, 0x68, 0x3d, 0x7b, 0x8d, 0x0f, 0x81, 0x13, 0x65, 0x56,
1974            0x5f, 0xd9, 0x8c, 0x4c, 0x8e, 0xb9, 0x36, 0xbc, 0xab, 0x8d, 0x06,
1975            0x9f, 0xc3, 0x3b, 0xd8, 0x01, 0xb0, 0x3a, 0xde, 0xa2, 0xe1, 0xfb,
1976            0xc5, 0xaa, 0x46, 0x3d, 0x08, 0xca, 0x19, 0x89, 0x6d, 0x2b, 0xf5,
1977            0x9a, 0x07, 0x1b, 0x85, 0x1e, 0x6c, 0x23, 0x90, 0x52, 0x17, 0x2f,
1978            0x29, 0x6b, 0xfb, 0x5e, 0x72, 0x40, 0x47, 0x90, 0xa2, 0x18, 0x10,
1979            0x14, 0xf3, 0xb9, 0x4a, 0x4e, 0x97, 0xd1, 0x17, 0xb4, 0x38, 0x13,
1980            0x03, 0x68, 0xcc, 0x39, 0xdb, 0xb2, 0xd1, 0x98, 0x06, 0x5a, 0xe3,
1981            0x98, 0x65, 0x47, 0x92, 0x6c, 0xd2, 0x16, 0x2f, 0x40, 0xa2, 0x9f,
1982            0x0c, 0x3c, 0x87, 0x45, 0xc0, 0xf5, 0x0f, 0xba, 0x38, 0x52, 0xe5,
1983            0x66, 0xd4, 0x45, 0x75, 0xc2, 0x9d, 0x39, 0xa0, 0x3f, 0x0c, 0xda,
1984            0x72, 0x19, 0x84, 0xb6, 0xf4, 0x40, 0x59, 0x1f, 0x35, 0x5e, 0x12,
1985            0xd4, 0x39, 0xff, 0x15, 0x0a, 0xab, 0x76, 0x13, 0x49, 0x9d, 0xbd,
1986            0x49, 0xad, 0xab, 0xc8, 0x67, 0x6e, 0xef, 0x02, 0x3b, 0x15, 0xb6,
1987            0x5b, 0xfc, 0x5c, 0xa0, 0x69, 0x48, 0x10, 0x9f, 0x23, 0xf3, 0x50,
1988            0xdb, 0x82, 0x12, 0x35, 0x35, 0xeb, 0x8a, 0x74, 0x33, 0xbd, 0xab,
1989            0xcb, 0x90, 0x92, 0x71, 0xa6, 0xec, 0xbc, 0xb5, 0x8b, 0x93, 0x6a,
1990            0x88, 0xcd, 0x4e, 0x8f, 0x2e, 0x6f, 0xf5, 0x80, 0x01, 0x75, 0xf1,
1991            0x13, 0x25, 0x3d, 0x8f, 0xa9, 0xca, 0x88, 0x85, 0xc2, 0xf5, 0x52,
1992            0xe6, 0x57, 0xdc, 0x60, 0x3f, 0x25, 0x2e, 0x1a, 0x8e, 0x30, 0x8f,
1993            0x76, 0xf0, 0xbe, 0x79, 0xe2, 0xfb, 0x8f, 0x5d, 0x5f, 0xbb, 0xe2,
1994            0xe3, 0x0e, 0xca, 0xdd, 0x22, 0x07, 0x23, 0xc8, 0xc0, 0xae, 0xa8,
1995            0x07, 0x8c, 0xdf, 0xcb, 0x38, 0x68, 0x26, 0x3f, 0xf8, 0xf0, 0x94,
1996            0x00, 0x54, 0xda, 0x48, 0x78, 0x18, 0x93, 0xa7, 0xe4, 0x9a, 0xd5,
1997            0xaf, 0xf4, 0xaf, 0x30, 0x0c, 0xd8, 0x04, 0xa6, 0xb6, 0x27, 0x9a,
1998            0xb3, 0xff, 0x3a, 0xfb, 0x64, 0x49, 0x1c, 0x85, 0x19, 0x4a, 0xab,
1999            0x76, 0x0d, 0x58, 0xa6, 0x06, 0x65, 0x4f, 0x9f, 0x44, 0x00, 0xe8,
2000            0xb3, 0x85, 0x91, 0x35, 0x6f, 0xbf, 0x64, 0x25, 0xac, 0xa2, 0x6d,
2001            0xc8, 0x52, 0x44, 0x25, 0x9f, 0xf2, 0xb1, 0x9c, 0x41, 0xb9, 0xf9,
2002            0x6f, 0x3c, 0xa9, 0xec, 0x1d, 0xde, 0x43, 0x4d, 0xa7, 0xd2, 0xd3,
2003            0x92, 0xb9, 0x05, 0xdd, 0xf3, 0xd1, 0xf9, 0xaf, 0x93, 0xd1, 0xaf,
2004            0x59, 0x50, 0xbd, 0x49, 0x3f, 0x5a, 0xa7, 0x31, 0xb4, 0x05, 0x6d,
2005            0xf3, 0x1b, 0xd2, 0x67, 0xb6, 0xb9, 0x0a, 0x07, 0x98, 0x31, 0xaa,
2006            0xf5, 0x79, 0xbe, 0x0a, 0x39, 0x01, 0x31, 0x37, 0xaa, 0xc6, 0xd4,
2007            0x04, 0xf5, 0x18, 0xcf, 0xd4, 0x68, 0x40, 0x64, 0x7e, 0x78, 0xbf,
2008            0xe7, 0x06, 0xca, 0x4c, 0xf5, 0xe9, 0xc5, 0x45, 0x3e, 0x9f, 0x7c,
2009            0xfd, 0x2b, 0x8b, 0x4c, 0x8d, 0x16, 0x9a, 0x44, 0xe5, 0x5c, 0x88,
2010            0xd4, 0xa9, 0xa7, 0xf9, 0x47, 0x42, 0x41, 0x10, 0x92, 0xab, 0xbd,
2011            0xf8, 0xb8, 0x89, 0xe5, 0xc1, 0x99, 0xd0, 0x96, 0xe3, 0xf2, 0x47,
2012            0x88,
2013        ];
2014
2015        assert_encrypt_initial_pkt(
2016            &mut header,
2017            &dcid,
2018            &frames,
2019            2,
2020            4,
2021            false,
2022            &pkt,
2023        );
2024    }
2025
2026    #[test]
2027    fn encrypt_server_initial_v1() {
2028        let mut header = [
2029            0xc1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
2030            0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0x00, 0x01,
2031        ];
2032
2033        let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
2034
2035        let frames = [
2036            0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x5a, 0x02, 0x00,
2037            0x00, 0x56, 0x03, 0x03, 0xee, 0xfc, 0xe7, 0xf7, 0xb3, 0x7b, 0xa1,
2038            0xd1, 0x63, 0x2e, 0x96, 0x67, 0x78, 0x25, 0xdd, 0xf7, 0x39, 0x88,
2039            0xcf, 0xc7, 0x98, 0x25, 0xdf, 0x56, 0x6d, 0xc5, 0x43, 0x0b, 0x9a,
2040            0x04, 0x5a, 0x12, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33,
2041            0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x9d, 0x3c, 0x94, 0x0d, 0x89,
2042            0x69, 0x0b, 0x84, 0xd0, 0x8a, 0x60, 0x99, 0x3c, 0x14, 0x4e, 0xca,
2043            0x68, 0x4d, 0x10, 0x81, 0x28, 0x7c, 0x83, 0x4d, 0x53, 0x11, 0xbc,
2044            0xf3, 0x2b, 0xb9, 0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04,
2045        ];
2046
2047        let pkt = [
2048            0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50,
2049            0x2a, 0x42, 0x62, 0xb5, 0x00, 0x40, 0x75, 0xc0, 0xd9, 0x5a, 0x48,
2050            0x2c, 0xd0, 0x99, 0x1c, 0xd2, 0x5b, 0x0a, 0xac, 0x40, 0x6a, 0x58,
2051            0x16, 0xb6, 0x39, 0x41, 0x00, 0xf3, 0x7a, 0x1c, 0x69, 0x79, 0x75,
2052            0x54, 0x78, 0x0b, 0xb3, 0x8c, 0xc5, 0xa9, 0x9f, 0x5e, 0xde, 0x4c,
2053            0xf7, 0x3c, 0x3e, 0xc2, 0x49, 0x3a, 0x18, 0x39, 0xb3, 0xdb, 0xcb,
2054            0xa3, 0xf6, 0xea, 0x46, 0xc5, 0xb7, 0x68, 0x4d, 0xf3, 0x54, 0x8e,
2055            0x7d, 0xde, 0xb9, 0xc3, 0xbf, 0x9c, 0x73, 0xcc, 0x3f, 0x3b, 0xde,
2056            0xd7, 0x4b, 0x56, 0x2b, 0xfb, 0x19, 0xfb, 0x84, 0x02, 0x2f, 0x8e,
2057            0xf4, 0xcd, 0xd9, 0x37, 0x95, 0xd7, 0x7d, 0x06, 0xed, 0xbb, 0x7a,
2058            0xaf, 0x2f, 0x58, 0x89, 0x18, 0x50, 0xab, 0xbd, 0xca, 0x3d, 0x20,
2059            0x39, 0x8c, 0x27, 0x64, 0x56, 0xcb, 0xc4, 0x21, 0x58, 0x40, 0x7d,
2060            0xd0, 0x74, 0xee,
2061        ];
2062
2063        assert_encrypt_initial_pkt(&mut header, &dcid, &frames, 1, 2, true, &pkt);
2064    }
2065
2066    #[test]
2067    fn encrypt_chacha20() {
2068        let secret = [
2069            0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42,
2070            0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0,
2071            0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b,
2072        ];
2073
2074        let mut header = [0x42, 0x00, 0xbf, 0xf4];
2075
2076        let expected_pkt = [
2077            0x4c, 0xfe, 0x41, 0x89, 0x65, 0x5e, 0x5c, 0xd5, 0x5c, 0x41, 0xf6,
2078            0x90, 0x80, 0x57, 0x5d, 0x79, 0x99, 0xc2, 0x5a, 0x5b, 0xfb,
2079        ];
2080
2081        let mut b = octets::OctetsMut::with_slice(&mut header);
2082
2083        let hdr = Header::from_bytes(&mut b, 0).unwrap();
2084        assert_eq!(hdr.ty, Type::Short);
2085
2086        let mut out = vec![0; expected_pkt.len()];
2087        let mut b = octets::OctetsMut::with_slice(&mut out);
2088
2089        b.put_bytes(&header).unwrap();
2090
2091        let alg = crypto::Algorithm::ChaCha20_Poly1305;
2092
2093        let aead = crypto::Seal::from_secret(alg, &secret).unwrap();
2094
2095        let pn = 654_360_564;
2096        let pn_len = 3;
2097
2098        let frames = [0x01];
2099
2100        let payload_len = frames.len();
2101
2102        let payload_offset = b.off();
2103
2104        b.put_bytes(&frames).unwrap();
2105
2106        let written = encrypt_pkt(
2107            &mut b,
2108            pn,
2109            pn_len,
2110            payload_len,
2111            payload_offset,
2112            None,
2113            &aead,
2114        )
2115        .unwrap();
2116
2117        assert_eq!(written, expected_pkt.len());
2118        assert_eq!(&out[..written], &expected_pkt[..]);
2119    }
2120
2121    #[test]
2122    fn decrypt_pkt_underflow() {
2123        let mut buf = [0; 65535];
2124        let mut b = octets::OctetsMut::with_slice(&mut buf);
2125
2126        let hdr = Header {
2127            ty: Type::Initial,
2128            version: crate::PROTOCOL_VERSION,
2129            dcid: ConnectionId::default(),
2130            scid: ConnectionId::default(),
2131            pkt_num: 0,
2132            pkt_num_len: 0,
2133            token: None,
2134            versions: None,
2135            key_phase: false,
2136        };
2137
2138        hdr.to_bytes(&mut b).unwrap();
2139
2140        b.put_bytes(&[0; 50]).unwrap();
2141
2142        let payload_len = b.get_varint().unwrap() as usize;
2143
2144        let (aead, _) =
2145            crypto::derive_initial_key_material(b"", hdr.version, true, false)
2146                .unwrap();
2147
2148        assert_eq!(
2149            decrypt_pkt(&mut b, 0, 1, payload_len, &aead),
2150            Err(Error::InvalidPacket)
2151        );
2152    }
2153
2154    #[test]
2155    fn decrypt_pkt_too_small() {
2156        let mut buf = [0; 65535];
2157        let mut b = octets::OctetsMut::with_slice(&mut buf);
2158
2159        let hdr = Header {
2160            ty: Type::Initial,
2161            version: crate::PROTOCOL_VERSION,
2162            dcid: ConnectionId::default(),
2163            scid: ConnectionId::default(),
2164            pkt_num: 0,
2165            pkt_num_len: 0,
2166            token: None,
2167            versions: None,
2168            key_phase: false,
2169        };
2170
2171        hdr.to_bytes(&mut b).unwrap();
2172
2173        b.put_bytes(&[0; 1]).unwrap();
2174
2175        // No space for decryption.
2176        let payload_len = 1;
2177
2178        let (aead, _) =
2179            crypto::derive_initial_key_material(b"", hdr.version, true, false)
2180                .unwrap();
2181
2182        assert_eq!(
2183            decrypt_pkt(&mut b, 0, 1, payload_len, &aead),
2184            Err(Error::CryptoFail)
2185        );
2186    }
2187
2188    #[test]
2189    fn track_largest_packet_sent() {
2190        let now = time::Instant::now();
2191        let mut pkt_space = PktNumSpace::new();
2192
2193        assert!(pkt_space.largest_tx_pkt_num.is_none());
2194
2195        let sent_ctx = test_utils::helper_packet_sent(1, now, 10);
2196        pkt_space.on_packet_sent(&sent_ctx);
2197        assert_eq!(pkt_space.largest_tx_pkt_num.unwrap(), 1);
2198
2199        let sent_ctx = test_utils::helper_packet_sent(2, now, 10);
2200        pkt_space.on_packet_sent(&sent_ctx);
2201        assert_eq!(pkt_space.largest_tx_pkt_num.unwrap(), 2);
2202    }
2203
2204    #[test]
2205    fn skip_pn() {
2206        let mut skip_manager = PktNumManager::new();
2207        let cwnd = 1000;
2208        let handshake_completed = true;
2209        let mut next_pn = 0;
2210
2211        assert!(skip_manager.skip_pn.is_none());
2212        assert!(skip_manager.skip_pn_counter.is_none());
2213        assert!(!skip_manager.should_skip_pn(handshake_completed));
2214
2215        // Arm `skip_pn_counter`
2216        skip_manager.on_packet_sent(
2217            cwnd,
2218            MAX_SEND_UDP_PAYLOAD_SIZE,
2219            handshake_completed,
2220        );
2221        assert_eq!(next_pn, 0);
2222        assert!(skip_manager.skip_pn.is_none());
2223        assert!(skip_manager.skip_pn_counter.unwrap() >= MIN_SKIP_COUNTER_VALUE);
2224        assert!(!skip_manager.should_skip_pn(handshake_completed));
2225
2226        // `should_skip_pn()` should be true once the counter expires
2227        while skip_manager.skip_pn_counter.unwrap() > 0 {
2228            // pretend to send the next packet
2229            next_pn += 1;
2230
2231            skip_manager.on_packet_sent(
2232                cwnd,
2233                MAX_SEND_UDP_PAYLOAD_SIZE,
2234                handshake_completed,
2235            );
2236        }
2237        assert!(next_pn >= MIN_SKIP_COUNTER_VALUE);
2238        assert!(skip_manager.skip_pn.is_none());
2239        assert_eq!(skip_manager.skip_pn_counter.unwrap(), 0);
2240        assert!(skip_manager.should_skip_pn(handshake_completed));
2241
2242        // skip the next pkt_num
2243        skip_manager.set_skip_pn(Some(next_pn));
2244        assert_eq!(skip_manager.skip_pn.unwrap(), next_pn);
2245        assert!(skip_manager.skip_pn_counter.is_none());
2246        assert!(!skip_manager.should_skip_pn(handshake_completed));
2247    }
2248
2249    #[test]
2250    fn arm_skip_counter_only_after_verifying_prev_skip_pn() {
2251        let mut skip_manager = PktNumManager::new();
2252        let cwnd = 1000;
2253        let handshake_completed = true;
2254
2255        // Set skip pn
2256        skip_manager.skip_pn_counter = Some(0);
2257        skip_manager.set_skip_pn(Some(42));
2258        assert!(skip_manager.skip_pn.is_some());
2259        assert!(skip_manager.skip_pn_counter.is_none());
2260
2261        // Don't arm the skip_pn_counter since its still armed (0 means
2262        // expired)
2263        skip_manager.on_packet_sent(
2264            cwnd,
2265            MAX_SEND_UDP_PAYLOAD_SIZE,
2266            handshake_completed,
2267        );
2268        assert!(skip_manager.skip_pn.is_some());
2269        assert!(skip_manager.skip_pn_counter.is_none());
2270
2271        // Arm the skip_pn_counter once the skip_pn has been verified
2272        skip_manager.skip_pn = None;
2273        skip_manager.on_packet_sent(
2274            cwnd,
2275            MAX_SEND_UDP_PAYLOAD_SIZE,
2276            handshake_completed,
2277        );
2278        assert!(skip_manager.skip_pn.is_none());
2279        assert!(skip_manager.skip_pn_counter.is_some());
2280    }
2281
2282    #[test]
2283    fn arm_skip_counter_only_after_handshake_complete() {
2284        let mut skip_manager = PktNumManager::new();
2285        let cwnd = 1000;
2286        skip_manager.skip_pn_counter = None;
2287
2288        // Don't arm the skip_pn_counter since handshake is not complete
2289        let mut handshake_completed = false;
2290        skip_manager.on_packet_sent(
2291            cwnd,
2292            MAX_SEND_UDP_PAYLOAD_SIZE,
2293            handshake_completed,
2294        );
2295        assert!(skip_manager.skip_pn_counter.is_none());
2296
2297        // Arm counter after handshake complete
2298        handshake_completed = true;
2299        skip_manager.on_packet_sent(
2300            cwnd,
2301            MAX_SEND_UDP_PAYLOAD_SIZE,
2302            handshake_completed,
2303        );
2304        assert!(skip_manager.skip_pn_counter.is_some());
2305    }
2306
2307    #[test]
2308    fn only_skip_after_handshake_complete() {
2309        let mut skip_manager = PktNumManager::new();
2310        skip_manager.skip_pn_counter = Some(0);
2311
2312        let mut handshake_completed = false;
2313        // Don't skip since handshake is not complete
2314        assert!(!skip_manager.should_skip_pn(handshake_completed));
2315
2316        handshake_completed = true;
2317        // Skip pn after handshake complete
2318        assert!(skip_manager.should_skip_pn(handshake_completed));
2319    }
2320}