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}