libp2p/builder/phase/
quic.rs

1use super::*;
2use crate::SwarmBuilder;
3#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))]
4use libp2p_core::muxing::StreamMuxer;
5use libp2p_core::upgrade::{InboundConnectionUpgrade, OutboundConnectionUpgrade};
6#[cfg(any(
7    feature = "relay",
8    all(not(target_arch = "wasm32"), feature = "websocket")
9))]
10use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, UpgradeInfo};
11use std::{marker::PhantomData, sync::Arc};
12
13pub struct QuicPhase<T> {
14    pub(crate) transport: T,
15}
16
17macro_rules! impl_quic_builder {
18    ($providerKebabCase:literal, $providerPascalCase:ty, $quic:ident) => {
19        #[cfg(all(not(target_arch = "wasm32"), feature = "quic", feature = $providerKebabCase))]
20        impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<$providerPascalCase, QuicPhase<T>> {
21            pub fn with_quic(
22                self,
23            ) -> SwarmBuilder<
24                $providerPascalCase,
25                OtherTransportPhase<impl AuthenticatedMultiplexedTransport>,
26            > {
27                self.with_quic_config(std::convert::identity)
28            }
29
30            pub fn with_quic_config(
31                self,
32                constructor: impl FnOnce(libp2p_quic::Config) -> libp2p_quic::Config,
33            ) -> SwarmBuilder<
34                $providerPascalCase,
35                OtherTransportPhase<impl AuthenticatedMultiplexedTransport>,
36            > {
37                SwarmBuilder {
38                    phase: OtherTransportPhase {
39                        transport: self
40                            .phase
41                            .transport
42                            .or_transport(
43                                libp2p_quic::$quic::Transport::new(constructor(
44                                    libp2p_quic::Config::new(&self.keypair),
45                                ))
46                                .map(|(peer_id, muxer), _| {
47                                    (peer_id, libp2p_core::muxing::StreamMuxerBox::new(muxer))
48                                }),
49                            )
50                            .map(|either, _| either.into_inner()),
51                    },
52                    keypair: self.keypair,
53                    phantom: PhantomData,
54                }
55            }
56        }
57    };
58}
59
60impl_quic_builder!("async-std", AsyncStd, async_std);
61impl_quic_builder!("tokio", super::provider::Tokio, tokio);
62
63impl<Provider, T> SwarmBuilder<Provider, QuicPhase<T>> {
64    pub(crate) fn without_quic(self) -> SwarmBuilder<Provider, OtherTransportPhase<T>> {
65        SwarmBuilder {
66            keypair: self.keypair,
67            phantom: PhantomData,
68            phase: OtherTransportPhase {
69                transport: self.phase.transport,
70            },
71        }
72    }
73}
74
75// Shortcuts
76impl<Provider, T: AuthenticatedMultiplexedTransport> SwarmBuilder<Provider, QuicPhase<T>> {
77    /// See [`SwarmBuilder::with_relay_client`].
78    #[cfg(feature = "relay")]
79    pub fn with_relay_client<SecUpgrade, SecStream, SecError, MuxUpgrade, MuxStream, MuxError>(
80        self,
81        security_upgrade: SecUpgrade,
82        multiplexer_upgrade: MuxUpgrade,
83    ) -> Result<
84        SwarmBuilder<
85            Provider,
86            BandwidthLoggingPhase<impl AuthenticatedMultiplexedTransport, libp2p_relay::client::Behaviour>,
87        >,
88        SecUpgrade::Error,
89        > where
90
91        SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static,
92        SecError: std::error::Error + Send + Sync + 'static,
93        SecUpgrade: IntoSecurityUpgrade<libp2p_relay::client::Connection>,
94        SecUpgrade::Upgrade: InboundConnectionUpgrade<Negotiated<libp2p_relay::client::Connection>, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + OutboundConnectionUpgrade<Negotiated<libp2p_relay::client::Connection>, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + Clone + Send + 'static,
95    <SecUpgrade::Upgrade as InboundConnectionUpgrade<Negotiated<libp2p_relay::client::Connection>>>::Future: Send,
96    <SecUpgrade::Upgrade as OutboundConnectionUpgrade<Negotiated<libp2p_relay::client::Connection>>>::Future: Send,
97    <<<SecUpgrade as IntoSecurityUpgrade<libp2p_relay::client::Connection>>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send,
98    <<SecUpgrade as IntoSecurityUpgrade<libp2p_relay::client::Connection>>::Upgrade as UpgradeInfo>::Info: Send,
99
100        MuxStream: libp2p_core::muxing::StreamMuxer + Send + 'static,
101        MuxStream::Substream: Send + 'static,
102        MuxStream::Error: Send + Sync + 'static,
103        MuxUpgrade: IntoMultiplexerUpgrade<SecStream>,
104        MuxUpgrade::Upgrade: InboundConnectionUpgrade<Negotiated<SecStream>, Output = MuxStream, Error = MuxError> + OutboundConnectionUpgrade<Negotiated<SecStream>, Output = MuxStream, Error = MuxError> + Clone + Send + 'static,
105    <MuxUpgrade::Upgrade as InboundConnectionUpgrade<Negotiated<SecStream>>>::Future: Send,
106    <MuxUpgrade::Upgrade as OutboundConnectionUpgrade<Negotiated<SecStream>>>::Future: Send,
107        MuxError: std::error::Error + Send + Sync + 'static,
108    <<<MuxUpgrade as IntoMultiplexerUpgrade<SecStream>>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send,
109    <<MuxUpgrade as IntoMultiplexerUpgrade<SecStream>>::Upgrade as UpgradeInfo>::Info: Send,
110    {
111        self.without_quic()
112            .without_any_other_transports()
113            .without_dns()
114            .without_websocket()
115            .with_relay_client(security_upgrade, multiplexer_upgrade)
116    }
117
118    pub fn with_other_transport<
119        Muxer: libp2p_core::muxing::StreamMuxer + Send + 'static,
120        OtherTransport: Transport<Output = (libp2p_identity::PeerId, Muxer)> + Send + Unpin + 'static,
121        R: TryIntoTransport<OtherTransport>,
122    >(
123        self,
124        constructor: impl FnOnce(&libp2p_identity::Keypair) -> R,
125    ) -> Result<
126        SwarmBuilder<Provider, OtherTransportPhase<impl AuthenticatedMultiplexedTransport>>,
127        R::Error,
128    >
129    where
130        <OtherTransport as Transport>::Error: Send + Sync + 'static,
131        <OtherTransport as Transport>::Dial: Send,
132        <OtherTransport as Transport>::ListenerUpgrade: Send,
133        <Muxer as libp2p_core::muxing::StreamMuxer>::Substream: Send,
134        <Muxer as libp2p_core::muxing::StreamMuxer>::Error: Send + Sync,
135    {
136        self.without_quic().with_other_transport(constructor)
137    }
138
139    pub fn with_behaviour<B, R: TryIntoBehaviour<B>>(
140        self,
141        constructor: impl FnOnce(&libp2p_identity::Keypair) -> R,
142    ) -> Result<SwarmBuilder<Provider, SwarmPhase<T, B>>, R::Error> {
143        self.without_quic()
144            .without_any_other_transports()
145            .without_dns()
146            .without_websocket()
147            .without_relay()
148            .with_behaviour(constructor)
149    }
150}
151#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))]
152impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::AsyncStd, QuicPhase<T>> {
153    pub async fn with_dns(
154        self,
155    ) -> Result<
156        SwarmBuilder<
157            super::provider::AsyncStd,
158            WebsocketPhase<impl AuthenticatedMultiplexedTransport>,
159        >,
160        std::io::Error,
161    > {
162        self.without_quic()
163            .without_any_other_transports()
164            .with_dns()
165            .await
166    }
167}
168#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))]
169impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::Tokio, QuicPhase<T>> {
170    pub fn with_dns(
171        self,
172    ) -> Result<
173        SwarmBuilder<
174            super::provider::Tokio,
175            WebsocketPhase<impl AuthenticatedMultiplexedTransport>,
176        >,
177        std::io::Error,
178    > {
179        self.without_quic()
180            .without_any_other_transports()
181            .with_dns()
182    }
183}
184#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))]
185impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::AsyncStd, QuicPhase<T>> {
186    pub fn with_dns_config(
187        self,
188        cfg: libp2p_dns::ResolverConfig,
189        opts: libp2p_dns::ResolverOpts,
190    ) -> SwarmBuilder<
191        super::provider::AsyncStd,
192        WebsocketPhase<impl AuthenticatedMultiplexedTransport>,
193    > {
194        self.without_quic()
195            .without_any_other_transports()
196            .with_dns_config(cfg, opts)
197    }
198}
199#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))]
200impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::Tokio, QuicPhase<T>> {
201    pub fn with_dns_config(
202        self,
203        cfg: libp2p_dns::ResolverConfig,
204        opts: libp2p_dns::ResolverOpts,
205    ) -> SwarmBuilder<super::provider::Tokio, WebsocketPhase<impl AuthenticatedMultiplexedTransport>>
206    {
207        self.without_quic()
208            .without_any_other_transports()
209            .with_dns_config(cfg, opts)
210    }
211}
212
213macro_rules! impl_quic_phase_with_websocket {
214    ($providerKebabCase:literal, $providerPascalCase:ty, $websocketStream:ty) => {
215        #[cfg(all(feature = $providerKebabCase, not(target_arch = "wasm32"), feature = "websocket"))]
216        impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<$providerPascalCase, QuicPhase<T>> {
217            /// See [`SwarmBuilder::with_websocket`].
218            pub async fn with_websocket <
219                SecUpgrade,
220                SecStream,
221                SecError,
222                MuxUpgrade,
223                MuxStream,
224                MuxError,
225            > (
226                self,
227                security_upgrade: SecUpgrade,
228                multiplexer_upgrade: MuxUpgrade,
229            ) -> Result<
230                    SwarmBuilder<
231                        $providerPascalCase,
232                        RelayPhase<impl AuthenticatedMultiplexedTransport>,
233                    >,
234                    super::websocket::WebsocketError<SecUpgrade::Error>,
235                >
236            where
237                SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static,
238                SecError: std::error::Error + Send + Sync + 'static,
239                SecUpgrade: IntoSecurityUpgrade<$websocketStream>,
240                SecUpgrade::Upgrade: InboundConnectionUpgrade<Negotiated<$websocketStream>, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + OutboundConnectionUpgrade<Negotiated<$websocketStream>, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + Clone + Send + 'static,
241            <SecUpgrade::Upgrade as InboundConnectionUpgrade<Negotiated<$websocketStream>>>::Future: Send,
242            <SecUpgrade::Upgrade as OutboundConnectionUpgrade<Negotiated<$websocketStream>>>::Future: Send,
243            <<<SecUpgrade as IntoSecurityUpgrade<$websocketStream>>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send,
244            <<SecUpgrade as IntoSecurityUpgrade<$websocketStream>>::Upgrade as UpgradeInfo>::Info: Send,
245
246                MuxStream: StreamMuxer + Send + 'static,
247                MuxStream::Substream: Send + 'static,
248                MuxStream::Error: Send + Sync + 'static,
249                MuxUpgrade: IntoMultiplexerUpgrade<SecStream>,
250                MuxUpgrade::Upgrade: InboundConnectionUpgrade<Negotiated<SecStream>, Output = MuxStream, Error = MuxError> + OutboundConnectionUpgrade<Negotiated<SecStream>, Output = MuxStream, Error = MuxError> + Clone + Send + 'static,
251                <MuxUpgrade::Upgrade as InboundConnectionUpgrade<Negotiated<SecStream>>>::Future: Send,
252                <MuxUpgrade::Upgrade as OutboundConnectionUpgrade<Negotiated<SecStream>>>::Future: Send,
253                    MuxError: std::error::Error + Send + Sync + 'static,
254                <<<MuxUpgrade as IntoMultiplexerUpgrade<SecStream>>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send,
255                <<MuxUpgrade as IntoMultiplexerUpgrade<SecStream>>::Upgrade as UpgradeInfo>::Info: Send,
256            {
257                self.without_quic()
258                    .without_any_other_transports()
259                    .without_dns()
260                    .with_websocket(security_upgrade, multiplexer_upgrade)
261                    .await
262            }
263        }
264    }
265}
266impl_quic_phase_with_websocket!(
267    "async-std",
268    super::provider::AsyncStd,
269    rw_stream_sink::RwStreamSink<
270        libp2p_websocket::BytesConnection<libp2p_tcp::async_io::TcpStream>,
271    >
272);
273impl_quic_phase_with_websocket!(
274    "tokio",
275    super::provider::Tokio,
276    rw_stream_sink::RwStreamSink<libp2p_websocket::BytesConnection<libp2p_tcp::tokio::TcpStream>>
277);
278impl<Provider, T: AuthenticatedMultiplexedTransport> SwarmBuilder<Provider, QuicPhase<T>> {
279    #[allow(deprecated)]
280    #[deprecated(note = "Use `with_bandwidth_metrics` instead.")]
281    pub fn with_bandwidth_logging(
282        self,
283    ) -> (
284        SwarmBuilder<
285            Provider,
286            BandwidthMetricsPhase<impl AuthenticatedMultiplexedTransport, NoRelayBehaviour>,
287        >,
288        Arc<crate::bandwidth::BandwidthSinks>,
289    ) {
290        #[allow(deprecated)]
291        self.without_quic()
292            .without_any_other_transports()
293            .without_dns()
294            .without_websocket()
295            .without_relay()
296            .with_bandwidth_logging()
297    }
298}
299#[cfg(feature = "metrics")]
300impl<Provider, T: AuthenticatedMultiplexedTransport> SwarmBuilder<Provider, QuicPhase<T>> {
301    pub fn with_bandwidth_metrics(
302        self,
303        registry: &mut libp2p_metrics::Registry,
304    ) -> SwarmBuilder<
305        Provider,
306        BehaviourPhase<impl AuthenticatedMultiplexedTransport, NoRelayBehaviour>,
307    > {
308        self.without_quic()
309            .without_any_other_transports()
310            .without_dns()
311            .without_websocket()
312            .without_relay()
313            .without_bandwidth_logging()
314            .with_bandwidth_metrics(registry)
315    }
316}