s2n_quic_core/frame/max_streams.rs
1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{frame::Tag, stream::StreamType, varint::VarInt};
5use s2n_codec::{decoder_invariant, decoder_parameterized_value, Encoder, EncoderValue};
6
7//= https://www.rfc-editor.org/rfc/rfc9000#section-19.11
8//# A MAX_STREAMS frame (type=0x12 or 0x13) inform the peer of the
9//# cumulative number of streams of a given type it is permitted to open.
10//# A MAX_STREAMS frame with a type of 0x12 applies to bidirectional
11//# streams, and a MAX_STREAMS frame with a type of 0x13 applies to
12//# unidirectional streams.
13
14macro_rules! max_streams_tag {
15 () => {
16 0x12u8..=0x13u8
17 };
18}
19const BIDIRECTIONAL_TAG: u8 = 0x12;
20const UNIDIRECTIONAL_TAG: u8 = 0x13;
21
22//= https://www.rfc-editor.org/rfc/rfc9000#section-19.11
23//# MAX_STREAMS Frame {
24//# Type (i) = 0x12..0x13,
25//# Maximum Streams (i),
26//# }
27
28//= https://www.rfc-editor.org/rfc/rfc9000#section-19.11
29//# MAX_STREAMS frames contain the following field:
30//#
31//# Maximum Streams: A count of the cumulative number of streams of the
32//# corresponding type that can be opened over the lifetime of the
33//# connection.
34
35#[derive(Copy, Clone, Debug, PartialEq, Eq)]
36pub struct MaxStreams {
37 pub stream_type: StreamType,
38
39 /// A count of the cumulative number of streams of the corresponding
40 /// type that can be opened over the lifetime of the connection.
41 pub maximum_streams: VarInt,
42}
43
44impl MaxStreams {
45 pub fn tag(&self) -> u8 {
46 match self.stream_type {
47 StreamType::Bidirectional => BIDIRECTIONAL_TAG,
48 StreamType::Unidirectional => UNIDIRECTIONAL_TAG,
49 }
50 }
51}
52
53decoder_parameterized_value!(
54 impl<'a> MaxStreams {
55 fn decode(tag: Tag, buffer: Buffer) -> Result<Self> {
56 let stream_type = if BIDIRECTIONAL_TAG == tag {
57 StreamType::Bidirectional
58 } else {
59 StreamType::Unidirectional
60 };
61
62 let (maximum_streams, buffer) = buffer.decode::<VarInt>()?;
63
64 //= https://www.rfc-editor.org/rfc/rfc9000#section-4.6
65 //# If a max_streams transport parameter or a MAX_STREAMS frame is
66 //# received with a value greater than 2^60, this would allow a maximum
67 //# stream ID that cannot be expressed as a variable-length integer; see
68 //# Section 16. If either is received, the connection MUST be closed
69 //# immediately with a connection error of type TRANSPORT_PARAMETER_ERROR
70 //# if the offending value was received in a transport parameter or of
71 //# type FRAME_ENCODING_ERROR if it was received in a frame; see
72 //# Section 10.2.
73
74 //= https://www.rfc-editor.org/rfc/rfc9000#section-19.11
75 //# This value cannot exceed 2^60, as it is not possible
76 //# to encode stream IDs larger than 2^62-1. Receipt of a frame that
77 //# permits opening of a stream larger than this limit MUST be treated
78 //# as a connection error of type FRAME_ENCODING_ERROR.
79 decoder_invariant!(
80 *maximum_streams <= 2u64.pow(60),
81 "maximum streams cannot exceed 2^60"
82 );
83
84 let frame = MaxStreams {
85 stream_type,
86 maximum_streams,
87 };
88
89 Ok((frame, buffer))
90 }
91 }
92);
93
94impl EncoderValue for MaxStreams {
95 fn encode<E: Encoder>(&self, buffer: &mut E) {
96 buffer.encode(&self.tag());
97 buffer.encode(&self.maximum_streams);
98 }
99}