s2n_quic_core/packet/
long.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{
5    packet::{encoding::PacketPayloadLenCursor, number::TruncatedPacketNumber},
6    varint::VarInt,
7};
8use s2n_codec::{
9    decoder_invariant, CheckedRange, DecoderError, Encoder, EncoderBuffer, EncoderValue,
10};
11
12//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
13//# Long Header Packet {
14//#   Header Form (1) = 1,
15//#   Fixed Bit (1) = 1,
16//#   Long Packet Type (2),
17//#   Type-Specific Bits (4),
18//#   Version (32),
19//#   Destination Connection ID Length (8),
20//#   Destination Connection ID (0..160),
21//#   Source Connection ID Length (8),
22//#   Source Connection ID (0..160),
23//# }
24
25//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
26//# Header Form:  The most significant bit (0x80) of byte 0 (the first
27//#   byte) is set to 1 for long headers.
28
29//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
30//# Fixed Bit:  The next bit (0x40) of byte 0 is set to 1.
31
32//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
33//# Long Packet Type:  The next two bits (those with a mask of 0x30)
34//#    of byte 0 contain a packet type.  Packet types are listed in
35//#    Table 5.
36
37pub(crate) const PACKET_TYPE_MASK: u8 = 0x30;
38const PACKET_TYPE_OFFSET: u8 = 4;
39
40//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
41//# Type-Specific Bits:  The semantics of the lower four bits (those with
42//# a mask of 0x0f) of byte 0 are determined by the packet type.
43
44//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
45//# Version: The QUIC Version is a 32-bit field that follows the first
46//#    byte.  This field indicates the version of QUIC that is in use and
47//#    determines how the rest of the protocol fields are interpreted.
48
49pub(crate) type Version = u32;
50
51//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
52//# Destination Connection ID Length:  The byte following the version
53//#    contains the length in bytes of the Destination Connection ID
54//#    field that follows it.  This length is encoded as an 8-bit
55//#    unsigned integer.  In QUIC version 1, this value MUST NOT exceed
56//#    20.
57
58pub(crate) type DestinationConnectionIdLen = u8;
59pub(crate) const DESTINATION_CONNECTION_ID_MAX_LEN: usize = 20;
60
61//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
62//# Destination Connection ID:  The Destination Connection ID field
63//#   follows the Destination Connection ID Length field, which
64//#   indicates the length of this field.  Section 7.2 describes the use
65//#   of this field in more detail.
66
67pub(crate) fn validate_destination_connection_id_range(
68    range: &CheckedRange,
69) -> Result<(), DecoderError> {
70    validate_destination_connection_id_len(range.len())
71}
72
73pub(crate) fn validate_destination_connection_id_len(len: usize) -> Result<(), DecoderError> {
74    //= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
75    //# Endpoints that receive a version 1 long header with a value
76    //# larger than 20 MUST drop the packet.
77    decoder_invariant!(
78        len <= DESTINATION_CONNECTION_ID_MAX_LEN,
79        "destination connection exceeds max length"
80    );
81    Ok(())
82}
83
84//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
85//# Source Connection ID Length:  The byte following the Destination
86//#   Connection ID contains the length in bytes of the Source
87//#   Connection ID field that follows it.  This length is encoded as a
88//#   8-bit unsigned integer.  In QUIC version 1, this value MUST NOT
89//#   exceed 20 bytes.
90
91pub(crate) type SourceConnectionIdLen = u8;
92pub(crate) const SOURCE_CONNECTION_ID_MAX_LEN: usize = 20;
93
94//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
95//# Source Connection ID:  The Source Connection ID field follows the
96//#   Source Connection ID Length field, which indicates the length of
97//#   this field.  Section 7.2 describes the use of this field in more
98//#   detail.
99
100pub(crate) fn validate_source_connection_id_range(
101    range: &CheckedRange,
102) -> Result<(), DecoderError> {
103    //= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
104    //# Endpoints that receive a version 1 long header
105    //# with a value larger than 20 MUST drop the packet.
106    validate_source_connection_id_len(range.len())
107}
108
109pub(crate) fn validate_source_connection_id_len(len: usize) -> Result<(), DecoderError> {
110    decoder_invariant!(
111        len <= SOURCE_CONNECTION_ID_MAX_LEN,
112        "source connection exceeds max length"
113    );
114    Ok(())
115}
116
117//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
118//# In this version of QUIC, the following packet types with the long
119//# header are defined:
120//#
121//#                 +======+===========+================+
122//#                 | Type | Name      | Section        |
123//#                 +======+===========+================+
124//#                 | 0x00 | Initial   | Section 17.2.2 |
125//#                 +------+-----------+----------------+
126//#                 | 0x01 | 0-RTT     | Section 17.2.3 |
127//#                 +------+-----------+----------------+
128//#                 | 0x02 | Handshake | Section 17.2.4 |
129//#                 +------+-----------+----------------+
130//#                 | 0x03 | Retry     | Section 17.2.5 |
131//#                 +------+-----------+----------------+
132//#
133//#                   Table 5: Long Header Packet Types
134
135#[repr(u8)]
136#[derive(Clone, Copy, Debug)]
137pub enum PacketType {
138    Initial = 0x0,
139    ZeroRtt = 0x1,
140    Handshake = 0x2,
141    Retry = 0x3,
142}
143
144impl PacketType {
145    pub const fn into_bits(self) -> u8 {
146        ((self as u8) << PACKET_TYPE_OFFSET) & PACKET_TYPE_MASK
147    }
148
149    pub fn from_bits(bits: u8) -> Self {
150        (bits & (PACKET_TYPE_MASK >> PACKET_TYPE_OFFSET)).into()
151    }
152}
153
154impl From<u8> for PacketType {
155    fn from(bits: u8) -> Self {
156        match bits {
157            0x0 => PacketType::Initial,
158            0x1 => PacketType::ZeroRtt,
159            0x2 => PacketType::Handshake,
160            0x3 => PacketType::Retry,
161            _ => PacketType::Initial,
162        }
163    }
164}
165
166impl From<PacketType> for u8 {
167    fn from(v: PacketType) -> Self {
168        v.into_bits()
169    }
170}
171
172//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
173//# Reserved Bits:  Two bits (those with a mask of 0x0c) of byte 0 are
174//#    reserved across multiple packet types.  These bits are protected
175//#    using header protection; see Section 5.4 of [QUIC-TLS].
176pub const RESERVED_BITS_MASK: u8 = 0x0c;
177
178//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
179//# Packet Number Length:  In packet types that contain a Packet Number
180//# field, the least significant two bits (those with a mask of 0x03)
181//# of byte 0 contain the length of the Packet Number field, encoded
182//# as an unsigned two-bit integer that is one less than the length of
183//# the Packet Number field in bytes.
184
185//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
186//# Length:  This is the length of the remainder of the packet (that is,
187//# the Packet Number and Payload fields) in bytes, encoded as a
188//# variable-length integer (Section 16).
189
190//= https://www.rfc-editor.org/rfc/rfc9000#section-17.2
191//# Packet Number:  This field is 1 to 4 bytes long.  The packet number
192//# is protected using header protection; see Section 5.4 of
193//# [QUIC-TLS].  The length of the Packet Number field is encoded in
194//# the Packet Number Length bits of byte 0; see above.
195
196pub(crate) struct LongPayloadEncoder<Payload> {
197    pub packet_number: TruncatedPacketNumber,
198    pub payload: Payload,
199}
200
201impl<Payload: EncoderValue> EncoderValue for LongPayloadEncoder<&Payload> {
202    fn encode<E: Encoder>(&self, encoder: &mut E) {
203        self.packet_number.encode(encoder);
204        self.payload.encode(encoder);
205    }
206}
207
208impl<Payload: EncoderValue> EncoderValue for LongPayloadEncoder<&mut Payload> {
209    fn encode<E: Encoder>(&self, encoder: &mut E) {
210        self.packet_number.encode(encoder);
211        self.payload.encode(encoder);
212    }
213
214    fn encode_mut<E: Encoder>(&mut self, encoder: &mut E) {
215        self.packet_number.encode_mut(encoder);
216        self.payload.encode_mut(encoder);
217    }
218}
219
220// used internally for estimating long packet payload len values.
221#[doc(hidden)]
222#[derive(Clone, Copy, Debug, PartialEq)]
223pub struct LongPayloadLenCursor {
224    position: usize,
225    max_value: VarInt,
226}
227
228impl PacketPayloadLenCursor for LongPayloadLenCursor {
229    fn new() -> Self {
230        let max_value = VarInt::MAX;
231        Self {
232            position: 0,
233            max_value,
234        }
235    }
236
237    fn update(&self, buffer: &mut EncoderBuffer, actual_len: usize) {
238        debug_assert!(
239            self.position != 0,
240            "position cursor was not updated. encode_mut should be called instead of encode"
241        );
242
243        let actual_value =
244            VarInt::try_from(actual_len).expect("packets should not be larger than VarInt::MAX");
245        let max_value = self.max_value;
246
247        let prev_pos = buffer.len();
248        buffer.set_position(self.position);
249        max_value.encode_updated(actual_value, buffer);
250        buffer.set_position(prev_pos);
251    }
252}
253
254impl EncoderValue for LongPayloadLenCursor {
255    fn encode<E: Encoder>(&self, encoder: &mut E) {
256        self.max_value.encode(encoder)
257    }
258
259    fn encode_mut<E: Encoder>(&mut self, encoder: &mut E) {
260        self.position = encoder.len();
261        self.max_value = VarInt::try_from(encoder.remaining_capacity()).unwrap_or(VarInt::MAX);
262        self.max_value.encode(encoder)
263    }
264}