// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 use crate::{frame::Tag, stream::StreamType, varint::VarInt}; use s2n_codec::{decoder_invariant, decoder_parameterized_value, Encoder, EncoderValue}; //= https://www.rfc-editor.org/rfc/rfc9000#section-19.11 //# A MAX_STREAMS frame (type=0x12 or 0x13) inform the peer of the //# cumulative number of streams of a given type it is permitted to open. //# A MAX_STREAMS frame with a type of 0x12 applies to bidirectional //# streams, and a MAX_STREAMS frame with a type of 0x13 applies to //# unidirectional streams. macro_rules! max_streams_tag { () => { 0x12u8..=0x13u8 }; } const BIDIRECTIONAL_TAG: u8 = 0x12; const UNIDIRECTIONAL_TAG: u8 = 0x13; //= https://www.rfc-editor.org/rfc/rfc9000#section-19.11 //# MAX_STREAMS Frame { //# Type (i) = 0x12..0x13, //# Maximum Streams (i), //# } //= https://www.rfc-editor.org/rfc/rfc9000#section-19.11 //# MAX_STREAMS frames contain the following field: //# //# Maximum Streams: A count of the cumulative number of streams of the //# corresponding type that can be opened over the lifetime of the //# connection. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct MaxStreams { pub stream_type: StreamType, /// A count of the cumulative number of streams of the corresponding /// type that can be opened over the lifetime of the connection. pub maximum_streams: VarInt, } impl MaxStreams { pub fn tag(&self) -> u8 { match self.stream_type { StreamType::Bidirectional => BIDIRECTIONAL_TAG, StreamType::Unidirectional => UNIDIRECTIONAL_TAG, } } } decoder_parameterized_value!( impl<'a> MaxStreams { fn decode(tag: Tag, buffer: Buffer) -> Result { let stream_type = if BIDIRECTIONAL_TAG == tag { StreamType::Bidirectional } else { StreamType::Unidirectional }; let (maximum_streams, buffer) = buffer.decode::()?; //= https://www.rfc-editor.org/rfc/rfc9000#section-4.6 //# If a max_streams transport parameter or a MAX_STREAMS frame is //# received with a value greater than 2^60, this would allow a maximum //# stream ID that cannot be expressed as a variable-length integer; see //# Section 16. If either is received, the connection MUST be closed //# immediately with a connection error of type TRANSPORT_PARAMETER_ERROR //# if the offending value was received in a transport parameter or of //# type FRAME_ENCODING_ERROR if it was received in a frame; see //# Section 10.2. //= https://www.rfc-editor.org/rfc/rfc9000#section-19.11 //# This value cannot exceed 2^60, as it is not possible //# to encode stream IDs larger than 2^62-1. Receipt of a frame that //# permits opening of a stream larger than this limit MUST be treated //# as a connection error of type FRAME_ENCODING_ERROR. decoder_invariant!( *maximum_streams <= 2u64.pow(60), "maximum streams cannot exceed 2^60" ); let frame = MaxStreams { stream_type, maximum_streams, }; Ok((frame, buffer)) } } ); impl EncoderValue for MaxStreams { fn encode(&self, buffer: &mut E) { buffer.encode(&self.tag()); buffer.encode(&self.maximum_streams); } }