s2n_quic/client/builder.rs
1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{
5 client::{Client, ClientProviders, DefaultProviders},
6 provider::*,
7};
8
9/// A builder for configuring [`Client`] providers
10#[derive(Debug)]
11pub struct Builder<Providers>(pub(crate) Providers);
12
13impl Default for Builder<DefaultProviders> {
14 fn default() -> Self {
15 Self(Default::default())
16 }
17}
18
19impl<Providers: ClientProviders> Builder<Providers> {
20 impl_provider_method!(
21 /// Sets the connection ID provider for the [`Client`]
22 ///
23 /// # Examples
24 ///
25 /// Uses the default connection ID provider with the default configuration.
26 ///
27 /// ```rust,no_run
28 /// # use std::{error::Error, time::Duration};
29 /// use s2n_quic::{Client, provider::connection_id};
30 /// #
31 /// # #[tokio::main]
32 /// # async fn main() -> Result<(), Box<dyn Error>> {
33 /// let client = Client::builder()
34 /// .with_connection_id(connection_id::Default::default())?
35 /// .start()?;
36 /// #
37 /// # Ok(())
38 /// # }
39 /// ```
40 ///
41 /// Sets a custom connection ID provider for the client
42 ///
43 /// ```rust,no_run
44 /// # use std::{error::Error, time::Duration};
45 /// use s2n_quic::{Client, provider::connection_id};
46 /// use rand::prelude::*;
47 /// #
48 /// # #[tokio::main]
49 /// # async fn main() -> Result<(), Box<dyn Error>> {
50 /// struct MyConnectionIdFormat;
51 ///
52 /// impl connection_id::Generator for MyConnectionIdFormat {
53 /// fn generate(&mut self, _conn_info: &connection_id::ConnectionInfo) -> connection_id::LocalId {
54 /// let mut id = [0u8; 16];
55 /// rand::thread_rng().fill_bytes(&mut id);
56 /// connection_id::LocalId::try_from_bytes(&id[..]).unwrap()
57 /// }
58 /// }
59 ///
60 /// impl connection_id::Validator for MyConnectionIdFormat {
61 /// fn validate(&self, _conn_info: &connection_id::ConnectionInfo, packet: &[u8]) -> Option<usize> {
62 /// // this connection id format is always 16 bytes
63 /// Some(16)
64 /// }
65 /// }
66 ///
67 /// let client = Client::builder()
68 /// .with_connection_id(MyConnectionIdFormat)?
69 /// .start()?;
70 /// #
71 /// # Ok(())
72 /// # }
73 /// ```
74 with_connection_id,
75 connection_id,
76 ClientProviders
77 );
78
79 impl_provider_method!(
80 /// Sets the stateless reset token provider for the [`Client`]
81 ///
82 /// # Examples
83 ///
84 /// Sets a custom stateless reset token provider for the client
85 ///
86 /// ```rust,ignore
87 /// # use std::error::Error;
88 /// use s2n_quic::Client;
89 /// #
90 /// # #[tokio::main]
91 /// # async fn main() -> Result<(), Box<dyn Error>> {
92 /// let client = Client::builder()
93 /// .with_stateless_reset_token(MyStatelessResetTokenGenerator::new())?
94 /// .start()?;
95 /// #
96 /// # Ok(())
97 /// # }
98 /// ```
99 with_stateless_reset_token,
100 stateless_reset_token,
101 ClientProviders
102 );
103
104 impl_provider_method!(
105 /// Sets the limits provider for the [`Client`]
106 ///
107 /// # Examples
108 ///
109 /// Sets the max idle time, while inheriting the remaining default limits
110 ///
111 /// ```rust,no_run
112 /// # use std::{error::Error, time::Duration};
113 /// use s2n_quic::{Client, provider::limits};
114 /// #
115 /// # #[tokio::main]
116 /// # async fn main() -> Result<(), Box<dyn Error>> {
117 /// let client = Client::builder()
118 /// .with_limits(limits::Limits::new().with_max_idle_timeout(Duration::from_secs(40))?)?
119 /// .start()?;
120 /// #
121 /// # Ok(())
122 /// # }
123 /// ```
124 with_limits,
125 limits,
126 ClientProviders
127 );
128
129 impl_provider_method!(
130 /// Sets the path specific mtu config provider for the [`Client`]
131 ///
132 /// # Examples
133 ///
134 /// Set custom MTU values to use per path, while inheriting the remaining default
135 /// config
136 ///
137 /// ```rust,no_run
138 /// # use std::{error::Error, time::Duration};
139 /// use s2n_quic::{Client, provider::mtu};
140 ///
141 /// # #[tokio::main]
142 /// # async fn main() -> Result<(), Box<dyn Error>> {
143 ///
144 /// struct MyMtuProvider(mtu::Config);
145 ///
146 /// impl mtu::Endpoint for MyMtuProvider {
147 /// fn on_path(
148 /// &mut self,
149 /// info: &mtu::PathInfo,
150 /// endpoint_mtu_config: mtu::Config,
151 /// ) -> Option<mtu::Config> {
152 /// Some(self.0)
153 /// }
154 /// }
155 /// let mtu = MyMtuProvider(mtu::Config::builder().build().unwrap());
156 ///
157 /// let client = Client::builder()
158 /// .with_mtu(mtu)?
159 /// .start()?;
160 /// #
161 /// # Ok(())
162 /// # }
163 /// ```
164 with_mtu,
165 mtu,
166 ClientProviders
167 );
168
169 impl_provider_method!(
170 /// Sets the event provider for the [`Client`]
171 ///
172 /// # Examples
173 ///
174 /// Sets a custom event subscriber for the client
175 ///
176 /// ```rust,ignore
177 /// # use std::{error::Error, time::Duration};
178 /// use s2n_quic::Client;
179 /// #
180 /// # #[tokio::main]
181 /// # async fn main() -> Result<(), Box<dyn Error>> {
182 /// let client = Client::builder()
183 /// .with_event(MyEventLogger::new())?
184 /// .start()?;
185 /// #
186 /// # Ok(())
187 /// # }
188 /// ```
189 with_event,
190 event,
191 ClientProviders
192 );
193
194 impl_provider_method!(
195 /// Sets the IO provider for the [`Client`]
196 ///
197 /// # Examples
198 ///
199 /// Opens a socket on an address chosen by the operating system
200 ///
201 /// ```rust,no_run
202 /// # use std::error::Error;
203 /// use s2n_quic::Client;
204 /// #
205 /// # #[tokio::main]
206 /// # async fn main() -> Result<(), Box<dyn Error>> {
207 /// let client = Client::builder()
208 /// .with_io("0.0.0.0:0")?
209 /// .start()?;
210 /// #
211 /// # Ok(())
212 /// # }
213 /// ```
214 ///
215 /// Configures a socket with the provided `Builder`
216 ///
217 /// ```rust,no_run
218 /// # use std::error::Error;
219 /// use s2n_quic::{Client, provider::io::tokio::Builder as IoBuilder};
220 /// use std::net::ToSocketAddrs;
221 /// #
222 /// # #[tokio::main]
223 /// # async fn main() -> Result<(), Box<dyn Error>> {
224 /// let addr = "0.0.0.0:0".to_socket_addrs()?.next().unwrap();
225 ///
226 /// let io = IoBuilder::default()
227 /// .with_receive_address(addr)?
228 /// .build()?;
229 ///
230 /// let client = Client::builder()
231 /// .with_io(io)?
232 /// .start()?;
233 /// #
234 /// # Ok(())
235 /// # }
236 /// ```
237 with_io,
238 io,
239 ClientProviders
240 );
241
242 impl_provider_method!(
243 /// Sets the TLS provider for the [`Client`]
244 ///
245 /// # Examples
246 ///
247 /// The default TLS provider and configuration will be used with the
248 /// path to the private key.
249 ///
250 /// ```rust,no_run
251 /// # use std::{error::Error, path::Path};
252 /// # use s2n_quic::Client;
253 /// #
254 /// # #[tokio::main]
255 /// # async fn main() -> Result<(), Box<dyn Error>> {
256 /// let client = Client::builder()
257 /// .with_tls(Path::new("./certs/cert.pem"))?
258 /// .start()?;
259 /// #
260 /// # Ok(())
261 /// # }
262 /// ```
263 ///
264 /// Sets the TLS provider to a TLS client builder
265 ///
266 /// ```rust,ignore
267 /// # use std::{error::Error, path::Path};
268 /// # use s2n_quic::Client;
269 /// #
270 /// # #[tokio::main]
271 /// # async fn main() -> Result<(), Box<dyn Error>> {
272 /// let tls = s2n_tls::Client::builder()
273 /// .with_certificate(Path::new("./certs/cert.pem"))?
274 /// .with_security_policy(s2n::tls::security_policy::S2N_20190802)?;
275 ///
276 /// let client = Client::builder()
277 /// .with_tls(tls)?
278 /// .start()?;
279 /// #
280 /// # Ok(())
281 /// # }
282 /// ```
283 with_tls,
284 tls,
285 ClientProviders
286 );
287
288 #[cfg(any(test, feature = "unstable-provider-packet-interceptor"))]
289 impl_provider_method!(
290 /// Sets the packet interceptor provider for the [`Client`]
291 with_packet_interceptor,
292 packet_interceptor,
293 ClientProviders
294 );
295
296 #[cfg(any(test, feature = "unstable-provider-random"))]
297 impl_provider_method!(
298 /// Sets the random provider for the [`Client`]
299 with_random,
300 random,
301 ClientProviders
302 );
303
304 #[cfg(feature = "unstable-provider-datagram")]
305 impl_provider_method!(
306 /// Sets the datagram provider for the [`Client`]
307 with_datagram,
308 datagram,
309 ClientProviders
310 );
311
312 #[cfg(any(test, feature = "unstable-provider-dc"))]
313 impl_provider_method!(
314 /// Sets the dc provider for the [`Client`]
315 with_dc,
316 dc,
317 ClientProviders
318 );
319
320 impl_provider_method!(
321 /// Sets the congestion controller provider for the [`Client`]
322 with_congestion_controller,
323 congestion_controller,
324 ClientProviders
325 );
326
327 /// Starts the [`Client`] with the configured providers
328 ///
329 /// # Examples
330 ///
331 /// ```rust,no_run
332 /// # use std::{error::Error, path::Path};
333 /// # use s2n_quic::Client;
334 /// #
335 /// # #[tokio::main]
336 /// # async fn main() -> Result<(), Box<dyn Error>> {
337 /// let client = Client::builder()
338 /// .with_tls(Path::new("./certs/cert.pem"))?
339 /// .with_io("0.0.0.0:0")?
340 /// .start()?;
341 /// #
342 /// # Ok(())
343 /// # }
344 /// ```
345 pub fn start(self) -> Result<Client, StartError> {
346 self.0.build().start()
347 }
348}