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}