s2n_quic_core/frame/
streams_blocked.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.14
8//# A STREAMS_BLOCKED
9//# frame of type 0x16 is used to indicate reaching the bidirectional
10//# stream limit, and a STREAMS_BLOCKED frame of type 0x17 is used to
11//# indicate reaching the unidirectional stream limit.
12
13macro_rules! streams_blocked_tag {
14    () => {
15        0x16u8..=0x17u8
16    };
17}
18const BIDIRECTIONAL_TAG: u8 = 0x16;
19const UNIDIRECTIONAL_TAG: u8 = 0x17;
20
21//= https://www.rfc-editor.org/rfc/rfc9000#section-19.14
22//# STREAMS_BLOCKED Frame {
23//#   Type (i) = 0x16..0x17,
24//#   Maximum Streams (i),
25//# }
26
27//= https://www.rfc-editor.org/rfc/rfc9000#section-19.14
28//# STREAMS_BLOCKED frames contain the following field:
29//#
30//# Maximum Streams:  A variable-length integer indicating the maximum
31//#    number of streams allowed at the time the frame was sent.
32
33#[derive(Copy, Clone, Debug, PartialEq, Eq)]
34pub struct StreamsBlocked {
35    pub stream_type: StreamType,
36
37    /// A variable-length integer indicating the stream limit at the
38    /// time the frame was sent.
39    pub stream_limit: VarInt,
40}
41
42impl StreamsBlocked {
43    pub fn tag(&self) -> u8 {
44        match self.stream_type {
45            StreamType::Bidirectional => BIDIRECTIONAL_TAG,
46            StreamType::Unidirectional => UNIDIRECTIONAL_TAG,
47        }
48    }
49}
50
51decoder_parameterized_value!(
52    impl<'a> StreamsBlocked {
53        fn decode(tag: Tag, buffer: Buffer) -> Result<Self> {
54            let stream_type = if BIDIRECTIONAL_TAG == tag {
55                StreamType::Bidirectional
56            } else {
57                StreamType::Unidirectional
58            };
59
60            let (stream_limit, buffer) = buffer.decode::<VarInt>()?;
61
62            //= https://www.rfc-editor.org/rfc/rfc9000#section-19.14
63            //# This
64            //# value cannot exceed 2^60, as it is not possible to encode stream
65            //# IDs larger than 2^62-1.  Receipt of a frame that encodes a larger
66            //# stream ID MUST be treated as a connection error of type
67            //# STREAM_LIMIT_ERROR or FRAME_ENCODING_ERROR.
68            decoder_invariant!(
69                *stream_limit <= 2u64.pow(60),
70                "maximum streams cannot exceed 2^60"
71            );
72
73            let frame = StreamsBlocked {
74                stream_type,
75                stream_limit,
76            };
77
78            Ok((frame, buffer))
79        }
80    }
81);
82
83impl EncoderValue for StreamsBlocked {
84    fn encode<E: Encoder>(&self, buffer: &mut E) {
85        buffer.encode(&self.tag());
86        buffer.encode(&self.stream_limit);
87    }
88}