Skip to content

Commit

Permalink
feat(libp2p): add SwarmBuilder::with_dns_config
Browse files Browse the repository at this point in the history
Add the missing `SwarmBuilder::with_dns_config`.

The `SwarmBuilder` doesn't have any way of providing a custom DNS configuration. Also, `with_other_transport` could not be used because is using `or_transport` instead of just wrapping the inner transport.

Pull-Request: #4808.
  • Loading branch information
oblique authored Nov 10, 2023
1 parent 2b12663 commit 9ab0e6f
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 1 deletion.
2 changes: 2 additions & 0 deletions libp2p/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
97 changes: 97 additions & 0 deletions libp2p/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
45 changes: 44 additions & 1 deletion libp2p/src/builder/phase/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub struct DnsPhase<T> {

#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))]
impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::AsyncStd, DnsPhase<T>> {
// TODO: Remove `async`
pub async fn with_dns(
self,
) -> Result<
Expand All @@ -21,7 +22,7 @@ impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::AsyncSt
keypair: self.keypair,
phantom: PhantomData,
phase: WebsocketPhase {
transport: libp2p_dns::async_std::Transport::system(self.phase.transport).await?,
transport: libp2p_dns::async_std::Transport::system2(self.phase.transport)?,
},
})
}
Expand All @@ -48,6 +49,48 @@ impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::Tokio,
}
}

#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))]
impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::AsyncStd, DnsPhase<T>> {
pub fn with_dns_config(
self,
cfg: libp2p_dns::ResolverConfig,
opts: libp2p_dns::ResolverOpts,
) -> SwarmBuilder<
super::provider::AsyncStd,
WebsocketPhase<impl AuthenticatedMultiplexedTransport>,
> {
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<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::Tokio, DnsPhase<T>> {
pub fn with_dns_config(
self,
cfg: libp2p_dns::ResolverConfig,
opts: libp2p_dns::ResolverOpts,
) -> SwarmBuilder<super::provider::Tokio, WebsocketPhase<impl AuthenticatedMultiplexedTransport>>
{
SwarmBuilder {
keypair: self.keypair,
phantom: PhantomData,
phase: WebsocketPhase {
transport: libp2p_dns::tokio::Transport::custom(self.phase.transport, cfg, opts),
},
}
}
}

impl<Provider, T> SwarmBuilder<Provider, DnsPhase<T>> {
pub(crate) fn without_dns(self) -> SwarmBuilder<Provider, WebsocketPhase<T>> {
SwarmBuilder {
Expand Down
30 changes: 30 additions & 0 deletions libp2p/src/builder/phase/other_transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,36 @@ impl<T: AuthenticatedMultiplexedTransport>
self.without_any_other_transports().with_dns()
}
}
#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))]
impl<T: AuthenticatedMultiplexedTransport>
SwarmBuilder<super::provider::AsyncStd, OtherTransportPhase<T>>
{
pub fn with_dns_config(
self,
cfg: libp2p_dns::ResolverConfig,
opts: libp2p_dns::ResolverOpts,
) -> SwarmBuilder<
super::provider::AsyncStd,
WebsocketPhase<impl AuthenticatedMultiplexedTransport>,
> {
self.without_any_other_transports()
.with_dns_config(cfg, opts)
}
}
#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))]
impl<T: AuthenticatedMultiplexedTransport>
SwarmBuilder<super::provider::Tokio, OtherTransportPhase<T>>
{
pub fn with_dns_config(
self,
cfg: libp2p_dns::ResolverConfig,
opts: libp2p_dns::ResolverOpts,
) -> SwarmBuilder<super::provider::Tokio, WebsocketPhase<impl AuthenticatedMultiplexedTransport>>
{
self.without_any_other_transports()
.with_dns_config(cfg, opts)
}
}
#[cfg(feature = "relay")]
impl<T: AuthenticatedMultiplexedTransport, Provider>
SwarmBuilder<Provider, OtherTransportPhase<T>>
Expand Down
29 changes: 29 additions & 0 deletions libp2p/src/builder/phase/quic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,35 @@ impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::Tokio,
.with_dns()
}
}
#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))]
impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::AsyncStd, QuicPhase<T>> {
pub fn with_dns_config(
self,
cfg: libp2p_dns::ResolverConfig,
opts: libp2p_dns::ResolverOpts,
) -> SwarmBuilder<
super::provider::AsyncStd,
WebsocketPhase<impl AuthenticatedMultiplexedTransport>,
> {
self.without_quic()
.without_any_other_transports()
.with_dns_config(cfg, opts)
}
}
#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))]
impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::Tokio, QuicPhase<T>> {
pub fn with_dns_config(
self,
cfg: libp2p_dns::ResolverConfig,
opts: libp2p_dns::ResolverOpts,
) -> SwarmBuilder<super::provider::Tokio, WebsocketPhase<impl AuthenticatedMultiplexedTransport>>
{
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"))]
Expand Down
25 changes: 25 additions & 0 deletions transports/dns/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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<Transport<T>, 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<T> {
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"),
}
}
}
}

Expand Down

0 comments on commit 9ab0e6f

Please sign in to comment.