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