diff --git a/libp2p/CHANGELOG.md b/libp2p/CHANGELOG.md index 545e089ae30..772b4f24a2a 100644 --- a/libp2p/CHANGELOG.md +++ b/libp2p/CHANGELOG.md @@ -2,6 +2,8 @@ - Allow `SwarmBuilder::with_quic_config` to be called without `with_tcp` first. See [PR 4821](https://github.com/libp2p/rust-libp2p/pull/4821). +- Introduce `SwarmBuilder::with_dns_config`. + See [PR 4808](https://github.com/libp2p/rust-libp2p/pull/4808). ## 0.53.0 diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index f492b323efa..b219ded2c44 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -363,6 +363,103 @@ mod tests { .build(); } + #[tokio::test] + #[cfg(all( + feature = "tokio", + feature = "tcp", + feature = "noise", + feature = "yamux", + feature = "dns" + ))] + async fn tcp_dns_config() { + SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp( + Default::default(), + (libp2p_tls::Config::new, libp2p_noise::Config::new), + libp2p_yamux::Config::default, + ) + .unwrap() + .with_dns_config( + libp2p_dns::ResolverConfig::default(), + libp2p_dns::ResolverOpts::default(), + ) + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .unwrap() + .build(); + } + + #[tokio::test] + #[cfg(all(feature = "tokio", feature = "quic", feature = "dns"))] + async fn quic_dns_config() { + SwarmBuilder::with_new_identity() + .with_tokio() + .with_quic() + .with_dns_config( + libp2p_dns::ResolverConfig::default(), + libp2p_dns::ResolverOpts::default(), + ) + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .unwrap() + .build(); + } + + #[tokio::test] + #[cfg(all( + feature = "tokio", + feature = "tcp", + feature = "noise", + feature = "yamux", + feature = "quic", + feature = "dns" + ))] + async fn tcp_quic_dns_config() { + SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp( + Default::default(), + (libp2p_tls::Config::new, libp2p_noise::Config::new), + libp2p_yamux::Config::default, + ) + .unwrap() + .with_quic() + .with_dns_config( + libp2p_dns::ResolverConfig::default(), + libp2p_dns::ResolverOpts::default(), + ) + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .unwrap() + .build(); + } + + #[tokio::test] + #[cfg(all( + feature = "async-std", + feature = "tcp", + feature = "noise", + feature = "yamux", + feature = "quic", + feature = "dns" + ))] + async fn async_std_tcp_quic_dns_config() { + SwarmBuilder::with_new_identity() + .with_async_std() + .with_tcp( + Default::default(), + (libp2p_tls::Config::new, libp2p_noise::Config::new), + libp2p_yamux::Config::default, + ) + .unwrap() + .with_quic() + .with_dns_config( + libp2p_dns::ResolverConfig::default(), + libp2p_dns::ResolverOpts::default(), + ) + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .unwrap() + .build(); + } + /// Showcases how to provide custom transports unknown to the libp2p crate, e.g. WebRTC. #[test] #[cfg(feature = "tokio")] diff --git a/libp2p/src/builder/phase/dns.rs b/libp2p/src/builder/phase/dns.rs index ebcb3af54a2..135f6c57b19 100644 --- a/libp2p/src/builder/phase/dns.rs +++ b/libp2p/src/builder/phase/dns.rs @@ -8,6 +8,7 @@ pub struct DnsPhase { #[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))] impl SwarmBuilder> { + // TODO: Remove `async` pub async fn with_dns( self, ) -> Result< @@ -21,7 +22,7 @@ impl SwarmBuilder SwarmBuilder SwarmBuilder> { + pub fn with_dns_config( + self, + cfg: libp2p_dns::ResolverConfig, + opts: libp2p_dns::ResolverOpts, + ) -> SwarmBuilder< + super::provider::AsyncStd, + WebsocketPhase, + > { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: WebsocketPhase { + transport: libp2p_dns::async_std::Transport::custom2( + self.phase.transport, + cfg, + opts, + ), + }, + } + } +} + +#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))] +impl SwarmBuilder> { + pub fn with_dns_config( + self, + cfg: libp2p_dns::ResolverConfig, + opts: libp2p_dns::ResolverOpts, + ) -> SwarmBuilder> + { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: WebsocketPhase { + transport: libp2p_dns::tokio::Transport::custom(self.phase.transport, cfg, opts), + }, + } + } +} + impl SwarmBuilder> { pub(crate) fn without_dns(self) -> SwarmBuilder> { SwarmBuilder { diff --git a/libp2p/src/builder/phase/other_transport.rs b/libp2p/src/builder/phase/other_transport.rs index 946b696323c..033326e0a9f 100644 --- a/libp2p/src/builder/phase/other_transport.rs +++ b/libp2p/src/builder/phase/other_transport.rs @@ -100,6 +100,36 @@ impl self.without_any_other_transports().with_dns() } } +#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))] +impl + SwarmBuilder> +{ + pub fn with_dns_config( + self, + cfg: libp2p_dns::ResolverConfig, + opts: libp2p_dns::ResolverOpts, + ) -> SwarmBuilder< + super::provider::AsyncStd, + WebsocketPhase, + > { + self.without_any_other_transports() + .with_dns_config(cfg, opts) + } +} +#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))] +impl + SwarmBuilder> +{ + pub fn with_dns_config( + self, + cfg: libp2p_dns::ResolverConfig, + opts: libp2p_dns::ResolverOpts, + ) -> SwarmBuilder> + { + self.without_any_other_transports() + .with_dns_config(cfg, opts) + } +} #[cfg(feature = "relay")] impl SwarmBuilder> diff --git a/libp2p/src/builder/phase/quic.rs b/libp2p/src/builder/phase/quic.rs index ae8d9400c25..6bfea017ace 100644 --- a/libp2p/src/builder/phase/quic.rs +++ b/libp2p/src/builder/phase/quic.rs @@ -181,6 +181,35 @@ impl SwarmBuilder SwarmBuilder> { + pub fn with_dns_config( + self, + cfg: libp2p_dns::ResolverConfig, + opts: libp2p_dns::ResolverOpts, + ) -> SwarmBuilder< + super::provider::AsyncStd, + WebsocketPhase, + > { + self.without_quic() + .without_any_other_transports() + .with_dns_config(cfg, opts) + } +} +#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))] +impl SwarmBuilder> { + pub fn with_dns_config( + self, + cfg: libp2p_dns::ResolverConfig, + opts: libp2p_dns::ResolverOpts, + ) -> SwarmBuilder> + { + self.without_quic() + .without_any_other_transports() + .with_dns_config(cfg, opts) + } +} + macro_rules! impl_quic_phase_with_websocket { ($providerKebabCase:literal, $providerPascalCase:ty, $websocketStream:ty) => { #[cfg(all(feature = $providerKebabCase, not(target_arch = "wasm32"), feature = "websocket"))] diff --git a/transports/dns/src/lib.rs b/transports/dns/src/lib.rs index 483d50be15b..0c41990fab1 100644 --- a/transports/dns/src/lib.rs +++ b/transports/dns/src/lib.rs @@ -60,6 +60,7 @@ #[cfg(feature = "async-std")] pub mod async_std { use async_std_resolver::AsyncStdResolver; + use futures::FutureExt; use hickory_resolver::{ config::{ResolverConfig, ResolverOpts}, system_conf, @@ -85,6 +86,30 @@ pub mod async_std { resolver: async_std_resolver::resolver(cfg, opts).await, } } + + // TODO: Replace `system` implementation with this + #[doc(hidden)] + pub fn system2(inner: T) -> Result, io::Error> { + Ok(Transport { + inner: Arc::new(Mutex::new(inner)), + resolver: async_std_resolver::resolver_from_system_conf() + .now_or_never() + .expect( + "async_std_resolver::resolver_from_system_conf did not resolve immediately", + )?, + }) + } + + // TODO: Replace `custom` implementation with this + #[doc(hidden)] + pub fn custom2(inner: T, cfg: ResolverConfig, opts: ResolverOpts) -> Transport { + Transport { + inner: Arc::new(Mutex::new(inner)), + resolver: async_std_resolver::resolver(cfg, opts) + .now_or_never() + .expect("async_std_resolver::resolver did not resolve immediately"), + } + } } }