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::*;
27pub use traits::*;
28
29pub type Version = u32;
30
31pub const SUPPORTED_VERSIONS: [Version; 1] = [0x0];
33
34pub fn select_version(client_supported_versions: DcSupportedVersions) -> Option<Version> {
38 let client_supported_versions = client_supported_versions.into_iter().as_slice();
39 SUPPORTED_VERSIONS
40 .iter()
41 .find(|&supported_version| client_supported_versions.contains(supported_version))
42 .copied()
43}
44
45#[derive(Clone, Debug)]
48#[non_exhaustive]
49pub struct ConnectionInfo<'a> {
50 pub remote_address: SocketAddress<'a>,
52 pub dc_version: u32,
54 pub application_params: ApplicationParams,
56 pub endpoint_type: EndpointType,
58}
59
60impl<'a> ConnectionInfo<'a> {
61 #[inline]
62 #[doc(hidden)]
63 pub fn new(
64 remote_address: &'a inet::SocketAddress,
65 dc_version: Version,
66 application_params: ApplicationParams,
67 endpoint_type: EndpointType,
68 ) -> Self {
69 Self {
70 remote_address: remote_address.into_event(),
71 dc_version,
72 application_params,
73 endpoint_type,
74 }
75 }
76}
77
78#[derive(Clone, Debug)]
81#[non_exhaustive]
82pub struct DatagramInfo<'a> {
83 pub remote_address: SocketAddress<'a>,
85}
86
87impl<'a> DatagramInfo<'a> {
88 #[inline]
89 #[doc(hidden)]
90 pub fn new(remote_address: &'a inet::SocketAddress) -> Self {
91 Self {
92 remote_address: remote_address.into_event(),
93 }
94 }
95}
96
97#[derive(Debug)]
99#[non_exhaustive]
100pub struct ApplicationParams {
101 pub max_datagram_size: AtomicU16,
102 pub remote_max_data: VarInt,
103 pub local_send_max_data: VarInt,
104 pub local_recv_max_data: VarInt,
105 pub max_idle_timeout: Option<NonZeroU32>,
107}
108
109impl Clone for ApplicationParams {
110 fn clone(&self) -> Self {
111 Self {
112 max_datagram_size: AtomicU16::new(self.max_datagram_size.load(Ordering::Relaxed)),
113 remote_max_data: self.remote_max_data,
114 local_send_max_data: self.local_send_max_data,
115 local_recv_max_data: self.local_recv_max_data,
116 max_idle_timeout: self.max_idle_timeout,
117 }
118 }
119}
120
121impl ApplicationParams {
122 pub fn new(
123 max_datagram_size: u16,
124 peer_flow_control_limits: &InitialFlowControlLimits,
125 limits: &Limits,
126 ) -> Self {
127 Self {
128 max_datagram_size: AtomicU16::new(max_datagram_size),
129 remote_max_data: peer_flow_control_limits.max_data,
130 local_send_max_data: limits.initial_stream_limits().max_data_bidi_local,
131 local_recv_max_data: limits.initial_stream_limits().max_data_bidi_remote,
132 max_idle_timeout: limits
133 .max_idle_timeout()
134 .and_then(|v| v.as_millis().try_into().ok())
136 .and_then(NonZeroU32::new),
137 }
138 }
139
140 pub fn max_idle_timeout(&self) -> Option<Duration> {
141 Some(Duration::from_millis(self.max_idle_timeout?.get() as u64))
142 }
143
144 pub fn max_datagram_size(&self) -> u16 {
145 self.max_datagram_size.load(Ordering::Relaxed)
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use crate::{
152 connection::Limits, dc::ApplicationParams, transport::parameters::InitialFlowControlLimits,
153 varint::VarInt,
154 };
155 use std::{sync::atomic::Ordering, time::Duration};
156
157 #[test]
158 fn clone() {
159 let initial_flow_control_limits = InitialFlowControlLimits {
160 max_data: VarInt::from_u32(2222),
161 ..Default::default()
162 };
163
164 let limits = Limits {
165 bidirectional_local_data_window: 1234.try_into().unwrap(),
166 bidirectional_remote_data_window: 6789.try_into().unwrap(),
167 max_idle_timeout: Duration::from_millis(999).try_into().unwrap(),
168 ..Default::default()
169 };
170
171 let params = ApplicationParams::new(9000, &initial_flow_control_limits, &limits);
172
173 assert_eq!(9000, params.max_datagram_size.load(Ordering::Relaxed));
174 assert_eq!(limits.max_idle_timeout(), params.max_idle_timeout());
175 assert_eq!(1234, params.local_send_max_data.as_u64());
176 assert_eq!(6789, params.local_recv_max_data.as_u64());
177 assert_eq!(2222, params.remote_max_data.as_u64());
178
179 let cloned_params = params.clone();
180
181 assert_eq!(
182 params.max_datagram_size.load(Ordering::Relaxed),
183 cloned_params.max_datagram_size.load(Ordering::Relaxed)
184 );
185 assert_eq!(params.max_idle_timeout, cloned_params.max_idle_timeout);
186 assert_eq!(
187 params.local_send_max_data,
188 cloned_params.local_send_max_data
189 );
190 assert_eq!(
191 params.local_recv_max_data,
192 cloned_params.local_recv_max_data
193 );
194 assert_eq!(params.remote_max_data, cloned_params.remote_max_data);
195 }
196}