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}