quic/s2n-quic-core/src/frame/max_streams.rs (24 lines of code) (raw):
// 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<Self> {
let stream_type = if BIDIRECTIONAL_TAG == tag {
StreamType::Bidirectional
} else {
StreamType::Unidirectional
};
let (maximum_streams, buffer) = buffer.decode::<VarInt>()?;
//= 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<E: Encoder>(&self, buffer: &mut E) {
buffer.encode(&self.tag());
buffer.encode(&self.maximum_streams);
}
}