s2n_quic_core/stream/
limits.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{
5    transport::parameters::{InitialMaxStreamsBidi, InitialMaxStreamsUni, ValidationError},
6    varint::VarInt,
7};
8
9/// The default send buffer size for Streams
10///
11/// This value is based on a common default maximum send buffer size for TCP (net.ipv4.tcp_wmem)
12const DEFAULT_STREAM_MAX_SEND_BUFFER_SIZE: u32 = 4096 * 1024;
13
14pub trait LocalLimits {
15    fn as_varint(&self) -> VarInt;
16}
17
18/// Per-stream limits
19#[derive(Debug, Copy, Clone, PartialEq, Eq)]
20pub struct Limits {
21    /// The maximum send buffer size for a Stream
22    pub max_send_buffer_size: MaxSendBufferSize,
23    /// The maximum number of unidirectional streams that may
24    /// be opened concurrently by the local endpoint. This value
25    /// is not communicated to the peer, it is only used for limiting
26    /// concurrent streams opened locally by the application.
27    pub max_open_local_unidirectional_streams: LocalUnidirectional,
28    /// The maximum number of bidirectional streams that may
29    /// be opened concurrently by the local endpoint. This value
30    /// is not communicated to the peer, it is only used for limiting
31    /// concurrent streams opened locally by the application.
32    pub max_open_local_bidirectional_streams: LocalBidirectional,
33}
34
35impl Default for Limits {
36    fn default() -> Self {
37        Self::RECOMMENDED
38    }
39}
40
41impl Limits {
42    pub const RECOMMENDED: Self = Self {
43        max_send_buffer_size: MaxSendBufferSize::RECOMMENDED,
44        max_open_local_unidirectional_streams: LocalUnidirectional::RECOMMENDED,
45        max_open_local_bidirectional_streams: LocalBidirectional::RECOMMENDED,
46    };
47}
48
49macro_rules! local_limits {
50    ($name:ident($encodable_type:ty)) => {
51        #[derive(Debug, Copy, Clone, PartialEq, Eq)]
52        pub struct $name($encodable_type);
53    };
54}
55
56// VarInt specific functionality
57macro_rules! varint_local_limits {
58    ($name:ident($encodable_type:ty)) => {
59        local_limits!($name($encodable_type));
60
61        impl LocalLimits for $name {
62            #[inline]
63            fn as_varint(&self) -> VarInt {
64                self.0
65            }
66        }
67
68        impl TryFrom<u64> for $name {
69            type Error = ValidationError;
70
71            #[inline]
72            fn try_from(value: u64) -> Result<Self, Self::Error> {
73                let value = VarInt::new(value)?;
74                Ok(Self(value))
75            }
76        }
77    };
78}
79
80local_limits!(MaxSendBufferSize(u32));
81
82impl MaxSendBufferSize {
83    pub const RECOMMENDED: Self = Self(DEFAULT_STREAM_MAX_SEND_BUFFER_SIZE);
84
85    #[inline]
86    pub fn as_u32(self) -> u32 {
87        self.0
88    }
89}
90
91impl TryFrom<u32> for MaxSendBufferSize {
92    type Error = ValidationError;
93
94    #[inline]
95    fn try_from(value: u32) -> Result<Self, Self::Error> {
96        Ok(Self(value))
97    }
98}
99
100varint_local_limits!(LocalUnidirectional(VarInt));
101
102impl LocalUnidirectional {
103    pub const RECOMMENDED: Self = Self(InitialMaxStreamsUni::RECOMMENDED.as_varint());
104}
105
106varint_local_limits!(LocalBidirectional(VarInt));
107
108impl LocalBidirectional {
109    pub const RECOMMENDED: Self = Self(InitialMaxStreamsBidi::RECOMMENDED.as_varint());
110}
111
112impl From<InitialMaxStreamsBidi> for LocalBidirectional {
113    fn from(value: InitialMaxStreamsBidi) -> Self {
114        Self(value.as_varint())
115    }
116}