1use crate::{
5 connection::Limits,
6 event::{
7 api::{EndpointType, SocketAddress},
8 IntoEvent as _,
9 },
10 inet,
11 transport::parameters::{DcSupportedVersions, InitialFlowControlLimits},
12 varint::VarInt,
13};
14use core::{
15 num::NonZeroU32,
16 sync::atomic::{AtomicU16, Ordering},
17 time::Duration,
18};
19
20mod disabled;
21mod traits;
22
23#[cfg(any(test, feature = "testing"))]
24pub mod testing;
25
26pub use disabled::*;
27use s2n_codec::{decoder_value, DecoderError, Encoder, EncoderValue};
28pub use traits::*;
29
30pub type Version = u32;
31
32pub const SUPPORTED_VERSIONS: [Version; 1] = [0x0];
34
35pub fn select_version(client_supported_versions: DcSupportedVersions) -> Option<Version> {
39 let client_supported_versions = client_supported_versions.into_iter().as_slice();
40 SUPPORTED_VERSIONS
41 .iter()
42 .find(|&supported_version| client_supported_versions.contains(supported_version))
43 .copied()
44}
45
46#[derive(Clone, Debug)]
49#[non_exhaustive]
50pub struct ConnectionInfo<'a> {
51 pub remote_address: SocketAddress<'a>,
53 pub dc_version: u32,
55 pub application_params: ApplicationParams,
57 pub endpoint_type: EndpointType,
59}
60
61impl<'a> ConnectionInfo<'a> {
62 #[inline]
63 #[doc(hidden)]
64 pub fn new(
65 remote_address: &'a inet::SocketAddress,
66 dc_version: Version,
67 application_params: ApplicationParams,
68 endpoint_type: EndpointType,
69 ) -> Self {
70 Self {
71 remote_address: remote_address.into_event(),
72 dc_version,
73 application_params,
74 endpoint_type,
75 }
76 }
77}
78
79#[derive(Clone, Debug)]
82#[non_exhaustive]
83pub struct DatagramInfo<'a> {
84 pub remote_address: SocketAddress<'a>,
86}
87
88impl<'a> DatagramInfo<'a> {
89 #[inline]
90 #[doc(hidden)]
91 pub fn new(remote_address: &'a inet::SocketAddress) -> Self {
92 Self {
93 remote_address: remote_address.into_event(),
94 }
95 }
96}
97
98#[derive(Debug)]
100#[non_exhaustive]
101pub struct ApplicationParams {
102 pub max_datagram_size: AtomicU16,
103 pub remote_max_data: VarInt,
104 pub local_send_max_data: VarInt,
105 pub local_recv_max_data: VarInt,
106 pub max_idle_timeout: Option<NonZeroU32>,
108}
109
110impl Clone for ApplicationParams {
111 fn clone(&self) -> Self {
112 Self {
113 max_datagram_size: AtomicU16::new(self.max_datagram_size.load(Ordering::Relaxed)),
114 remote_max_data: self.remote_max_data,
115 local_send_max_data: self.local_send_max_data,
116 local_recv_max_data: self.local_recv_max_data,
117 max_idle_timeout: self.max_idle_timeout,
118 }
119 }
120}
121
122impl ApplicationParams {
123 pub fn new(
124 max_datagram_size: u16,
125 peer_flow_control_limits: &InitialFlowControlLimits,
126 limits: &Limits,
127 ) -> Self {
128 Self {
129 max_datagram_size: AtomicU16::new(max_datagram_size),
130 remote_max_data: peer_flow_control_limits.max_data,
131 local_send_max_data: limits.initial_stream_limits().max_data_bidi_local,
132 local_recv_max_data: limits.initial_stream_limits().max_data_bidi_remote,
133 max_idle_timeout: limits
134 .max_idle_timeout()
135 .and_then(|v| v.as_millis().try_into().ok())
137 .and_then(NonZeroU32::new),
138 }
139 }
140
141 pub fn max_idle_timeout(&self) -> Option<Duration> {
142 Some(Duration::from_millis(self.max_idle_timeout?.get() as u64))
143 }
144
145 pub fn max_datagram_size(&self) -> u16 {
146 self.max_datagram_size.load(Ordering::Relaxed)
147 }
148}
149
150decoder_value!(
151 impl<'a> ApplicationParams {
152 fn decode(buffer: Buffer) -> Result<Self> {
153 let (max_datagram_size, buffer) = buffer.decode::<u16>()?;
154 let (remote_max_data, buffer) = buffer.decode::<VarInt>()?;
155 let (local_send_max_data, buffer) = buffer.decode::<VarInt>()?;
156 let (local_recv_max_data, buffer) = buffer.decode::<VarInt>()?;
157
158 let (timeout_value, buffer) = buffer.decode::<VarInt>()?;
159 let timeout_value: u32 = timeout_value.try_into().map_err(|_| {
160 DecoderError::InvariantViolation("Timeout value exceeds u32 maximum")
161 })?;
162 let max_idle_timeout = NonZeroU32::new(timeout_value);
163
164 Ok((
165 Self {
166 max_datagram_size: AtomicU16::new(max_datagram_size),
167 remote_max_data,
168 local_send_max_data,
169 local_recv_max_data,
170 max_idle_timeout,
171 },
172 buffer,
173 ))
174 }
175 }
176);
177
178impl EncoderValue for ApplicationParams {
179 fn encode<E: Encoder>(&self, buffer: &mut E) {
180 buffer.encode(&self.max_datagram_size.load(Ordering::Relaxed));
181 buffer.encode(&self.remote_max_data);
182 buffer.encode(&self.local_send_max_data);
183 buffer.encode(&self.local_recv_max_data);
184
185 match self.max_idle_timeout {
186 Some(timeout) => {
187 buffer.encode(&VarInt::from(u32::from(timeout)));
188 }
189 None => {
190 buffer.encode(&VarInt::from(0u32));
191 }
192 }
193 }
194}
195
196#[cfg(test)]
197mod tests {
198 use crate::{
199 connection::Limits, dc::ApplicationParams, transport::parameters::InitialFlowControlLimits,
200 varint::VarInt,
201 };
202 use std::{sync::atomic::Ordering, time::Duration};
203
204 #[test]
205 fn clone() {
206 let initial_flow_control_limits = InitialFlowControlLimits {
207 max_data: VarInt::from_u32(2222),
208 ..Default::default()
209 };
210
211 let limits = Limits {
212 bidirectional_local_data_window: 1234.try_into().unwrap(),
213 bidirectional_remote_data_window: 6789.try_into().unwrap(),
214 max_idle_timeout: Duration::from_millis(999).try_into().unwrap(),
215 ..Default::default()
216 };
217
218 let params = ApplicationParams::new(9000, &initial_flow_control_limits, &limits);
219
220 assert_eq!(9000, params.max_datagram_size.load(Ordering::Relaxed));
221 assert_eq!(limits.max_idle_timeout(), params.max_idle_timeout());
222 assert_eq!(1234, params.local_send_max_data.as_u64());
223 assert_eq!(6789, params.local_recv_max_data.as_u64());
224 assert_eq!(2222, params.remote_max_data.as_u64());
225
226 let cloned_params = params.clone();
227
228 assert_eq!(
229 params.max_datagram_size.load(Ordering::Relaxed),
230 cloned_params.max_datagram_size.load(Ordering::Relaxed)
231 );
232 assert_eq!(params.max_idle_timeout, cloned_params.max_idle_timeout);
233 assert_eq!(
234 params.local_send_max_data,
235 cloned_params.local_send_max_data
236 );
237 assert_eq!(
238 params.local_recv_max_data,
239 cloned_params.local_recv_max_data
240 );
241 assert_eq!(params.remote_max_data, cloned_params.remote_max_data);
242 }
243}