s2n_quic_core/frame/
new_token.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{frame::Tag, varint::VarInt};
5use s2n_codec::{decoder_invariant, decoder_parameterized_value, Encoder, EncoderValue};
6
7//= https://www.rfc-editor.org/rfc/rfc9000#section-19.7
8//# A server sends a NEW_TOKEN frame (type=0x07) to provide the client
9//# with a token to send in the header of an Initial packet for a future
10//# connection.
11
12macro_rules! new_token_tag {
13    () => {
14        0x07u8
15    };
16}
17
18//= https://www.rfc-editor.org/rfc/rfc9000#section-19.7
19//# NEW_TOKEN Frame {
20//#   Type (i) = 0x07,
21//#   Token Length (i),
22//#   Token (..),
23//# }
24
25//= https://www.rfc-editor.org/rfc/rfc9000#section-19.7
26//# NEW_TOKEN frames contain the following fields:
27//#
28//# Token Length:  A variable-length integer specifying the length of the
29//# token in bytes.
30//#
31//# Token:  An opaque blob that the client can use with a future Initial
32//# packet.  The token MUST NOT be empty.  A client MUST treat receipt
33//# of a NEW_TOKEN frame with an empty Token field as a connection
34//# error of type FRAME_ENCODING_ERROR.
35
36#[derive(Debug, PartialEq, Eq)]
37pub struct NewToken<'a> {
38    /// An opaque blob that the client may use with a future Initial packet.
39    pub token: &'a [u8],
40}
41
42impl NewToken<'_> {
43    pub const fn tag(&self) -> u8 {
44        new_token_tag!()
45    }
46}
47
48decoder_parameterized_value!(
49    impl<'a> NewToken<'a> {
50        fn decode(_tag: Tag, buffer: Buffer) -> Result<Self> {
51            let (token, buffer) = buffer.decode_slice_with_len_prefix::<VarInt>()?;
52            let token = token.into_less_safe_slice();
53
54            //= https://www.rfc-editor.org/rfc/rfc9000#section-19.7
55            //# A client MUST treat receipt of a NEW_TOKEN frame
56            //# with an empty Token field as a connection error
57            //# of type FRAME_ENCODING_ERROR.
58            decoder_invariant!(!token.is_empty(), "empty Token field");
59
60            let frame = NewToken { token };
61
62            Ok((frame, buffer))
63        }
64    }
65);
66
67impl EncoderValue for NewToken<'_> {
68    fn encode<E: Encoder>(&self, buffer: &mut E) {
69        buffer.encode(&self.tag());
70        buffer.encode_with_len_prefix::<VarInt, _>(&self.token);
71    }
72}