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}