diff --git a/Cargo.lock b/Cargo.lock index 007d97c07f5..592ea05fc7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2535,7 +2535,7 @@ dependencies = [ [[package]] name = "libp2p-dns" -version = "0.40.0" +version = "0.40.1" dependencies = [ "async-std", "async-std-resolver", diff --git a/Cargo.toml b/Cargo.toml index 9b703d9c4ee..9685bd42d5f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,7 +78,7 @@ libp2p-connection-limits = { version = "0.2.1", path = "misc/connection-limits" libp2p-core = { version = "0.40.1", path = "core" } libp2p-dcutr = { version = "0.10.0", path = "protocols/dcutr" } libp2p-deflate = { version = "0.40.0", path = "transports/deflate" } -libp2p-dns = { version = "0.40.0", path = "transports/dns" } +libp2p-dns = { version = "0.40.1", path = "transports/dns" } libp2p-floodsub = { version = "0.43.0", path = "protocols/floodsub" } libp2p-gossipsub = { version = "0.45.1", path = "protocols/gossipsub" } libp2p-identify = { version = "0.43.0", path = "protocols/identify" } diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index e9e731b011b..ec308521874 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -33,9 +33,7 @@ use libp2p::{ transport::Transport, upgrade, }, - dcutr, - dns::DnsConfig, - identify, identity, noise, ping, quic, relay, + dcutr, dns, identify, identity, noise, ping, quic, relay, swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent}, tcp, yamux, PeerId, }; @@ -102,7 +100,7 @@ fn main() -> Result<(), Box> { &local_key, ))); - block_on(DnsConfig::system(relay_tcp_quic_transport)) + block_on(dns::async_std::Transport::system(relay_tcp_quic_transport)) .unwrap() .map(|either_output, _| match either_output { Either::Left((peer_id, muxer)) => (peer_id, StreamMuxerBox::new(muxer)), diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index 624ff897c17..0d4ea730dc0 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -189,12 +189,12 @@ pub async fn development_transport( keypair: identity::Keypair, ) -> std::io::Result> { let transport = { - let dns_tcp = dns::DnsConfig::system(tcp::async_io::Transport::new( + let dns_tcp = dns::async_std::Transport::system(tcp::async_io::Transport::new( tcp::Config::new().nodelay(true), )) .await?; let ws_dns_tcp = websocket::WsConfig::new( - dns::DnsConfig::system(tcp::async_io::Transport::new( + dns::async_std::Transport::system(tcp::async_io::Transport::new( tcp::Config::new().nodelay(true), )) .await?, @@ -234,10 +234,10 @@ pub fn tokio_development_transport( keypair: identity::Keypair, ) -> std::io::Result> { let transport = { - let dns_tcp = dns::TokioDnsConfig::system(tcp::tokio::Transport::new( + let dns_tcp = dns::tokio::Transport::system(tcp::tokio::Transport::new( tcp::Config::new().nodelay(true), ))?; - let ws_dns_tcp = websocket::WsConfig::new(dns::TokioDnsConfig::system( + let ws_dns_tcp = websocket::WsConfig::new(dns::tokio::Transport::system( tcp::tokio::Transport::new(tcp::Config::new().nodelay(true)), )?); dns_tcp.or_transport(ws_dns_tcp) diff --git a/misc/server/src/main.rs b/misc/server/src/main.rs index 26737085d91..e885301d590 100644 --- a/misc/server/src/main.rs +++ b/misc/server/src/main.rs @@ -88,7 +88,7 @@ async fn main() -> Result<(), Box> { let quic_transport = quic::tokio::Transport::new(quic::Config::new(&local_keypair)); - dns::TokioDnsConfig::system(libp2p::core::transport::OrTransport::new( + dns::tokio::Transport::system(libp2p::core::transport::OrTransport::new( quic_transport, tcp_transport, ))? diff --git a/protocols/perf/src/bin/perf.rs b/protocols/perf/src/bin/perf.rs index b6b090608f5..31644324571 100644 --- a/protocols/perf/src/bin/perf.rs +++ b/protocols/perf/src/bin/perf.rs @@ -405,7 +405,7 @@ async fn swarm() -> Result> { libp2p_quic::tokio::Transport::new(config) }; - let dns = libp2p_dns::TokioDnsConfig::system(OrTransport::new(quic, tcp))?; + let dns = libp2p_dns::tokio::Transport::system(OrTransport::new(quic, tcp))?; dns.map(|either_output, _| match either_output { Either::Left((peer_id, muxer)) => (peer_id, StreamMuxerBox::new(muxer)), diff --git a/transports/dns/CHANGELOG.md b/transports/dns/CHANGELOG.md index a51e4165c18..29b5ac4403a 100644 --- a/transports/dns/CHANGELOG.md +++ b/transports/dns/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.40.1 - unreleased + +- Remove `Dns` prefix from types like `TokioDnsConfig` and `DnsConfig` in favor of modules that describe the different variants. + Users are encouraged to import the `libp2p::dns` module and refer to types as `dns::tokio::Transport` and `dns::async_std::Transport`. + See [PR 4505]. + +[PR 4505]: https://github.com/libp2p/rust-libp2p/pull/4505 + ## 0.40.0 - Raise MSRV to 1.65. diff --git a/transports/dns/Cargo.toml b/transports/dns/Cargo.toml index 77c8e57e3ff..7c7bd439f41 100644 --- a/transports/dns/Cargo.toml +++ b/transports/dns/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p-dns" edition = "2021" rust-version = { workspace = true } description = "DNS transport implementation for libp2p" -version = "0.40.0" +version = "0.40.1" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" @@ -35,7 +35,7 @@ tokio = ["trust-dns-resolver/tokio-runtime"] tokio-dns-over-rustls = ["tokio", "trust-dns-resolver/dns-over-rustls"] tokio-dns-over-https-rustls = ["tokio", "trust-dns-resolver/dns-over-https-rustls"] -# Passing arguments to the docsrs builder in order to properly document cfg's. +# Passing arguments to the docsrs builder in order to properly document cfg's. # More information: https://docs.rs/about/builds#cross-compiling [package.metadata.docs.rs] all-features = true diff --git a/transports/dns/src/lib.rs b/transports/dns/src/lib.rs index 61d1f4fed91..b27b14a77c0 100644 --- a/transports/dns/src/lib.rs +++ b/transports/dns/src/lib.rs @@ -21,17 +21,17 @@ //! # [DNS name resolution](https://github.com/libp2p/specs/blob/master/addressing/README.md#ip-and-name-resolution) //! [`Transport`] for libp2p. //! -//! This crate provides the type [`GenDnsConfig`] with its instantiations -//! [`DnsConfig`] and `TokioDnsConfig` for use with `async-std` and `tokio`, +//! This crate provides the type [`async_std::Transport`] and [`tokio::Transport`] +//! for use with `async-std` and `tokio`, //! respectively. //! -//! A [`GenDnsConfig`] is an address-rewriting [`Transport`] wrapper around +//! A [`Transport`] is an address-rewriting [`libp2p_core::Transport`] wrapper around //! an inner `Transport`. The composed transport behaves like the inner -//! transport, except that [`Transport::dial`] resolves `/dns/...`, `/dns4/...`, +//! transport, except that [`libp2p_core::Transport::dial`] resolves `/dns/...`, `/dns4/...`, //! `/dns6/...` and `/dnsaddr/...` components of the given `Multiaddr` through //! a DNS, replacing them with the resolved protocols (typically TCP/IP). //! -//! The `async-std` feature and hence the `DnsConfig` are +//! The `async-std` feature and hence the [`async_std::Transport`] are //! enabled by default. Tokio users can furthermore opt-in //! to the `tokio-dns-over-rustls` and `tokio-dns-over-https-rustls` //! features. For more information about these features, please @@ -49,7 +49,7 @@ //! problematic on platforms like Android, where there's a lot of //! complexity hidden behind the system APIs. //! If the implementation requires different characteristics, one should -//! consider providing their own implementation of [`GenDnsConfig`] or use +//! consider providing their own implementation of [`Transport`] or use //! platform specific APIs to extract the host's DNS configuration (if possible) //! and provide a custom [`ResolverConfig`]. //! @@ -58,14 +58,87 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #[cfg(feature = "async-std")] -use async_std_resolver::AsyncStdResolver; +pub mod async_std { + use async_std_resolver::AsyncStdResolver; + use parking_lot::Mutex; + use std::{io, sync::Arc}; + use trust_dns_resolver::{ + config::{ResolverConfig, ResolverOpts}, + system_conf, + }; + + /// A `Transport` wrapper for performing DNS lookups when dialing `Multiaddr`esses + /// using `async-std` for all async I/O. + pub type Transport = crate::Transport; + + impl Transport { + /// Creates a new [`Transport`] from the OS's DNS configuration and defaults. + pub async fn system(inner: T) -> Result, io::Error> { + let (cfg, opts) = system_conf::read_system_conf()?; + Self::custom(inner, cfg, opts).await + } + + /// Creates a [`Transport`] with a custom resolver configuration and options. + pub async fn custom( + inner: T, + cfg: ResolverConfig, + opts: ResolverOpts, + ) -> Result, io::Error> { + Ok(Transport { + inner: Arc::new(Mutex::new(inner)), + resolver: async_std_resolver::resolver(cfg, opts).await, + }) + } + } +} + +#[cfg(feature = "async-std")] +#[deprecated(note = "Use `async_std::Transport` instead.")] +pub type DnsConfig = async_std::Transport; + +#[cfg(feature = "tokio")] +pub mod tokio { + use parking_lot::Mutex; + use std::sync::Arc; + use trust_dns_resolver::{system_conf, TokioAsyncResolver}; + + /// A `Transport` wrapper for performing DNS lookups when dialing `Multiaddr`esses + /// using `tokio` for all async I/O. + pub type Transport = crate::Transport; + + impl Transport { + /// Creates a new [`Transport`] from the OS's DNS configuration and defaults. + pub fn system(inner: T) -> Result, std::io::Error> { + let (cfg, opts) = system_conf::read_system_conf()?; + Self::custom(inner, cfg, opts) + } + + /// Creates a [`Transport`] with a custom resolver configuration + /// and options. + pub fn custom( + inner: T, + cfg: trust_dns_resolver::config::ResolverConfig, + opts: trust_dns_resolver::config::ResolverOpts, + ) -> Result, std::io::Error> { + // TODO: Make infallible in next breaking release. Or deprecation? + Ok(Transport { + inner: Arc::new(Mutex::new(inner)), + resolver: TokioAsyncResolver::tokio(cfg, opts), + }) + } + } +} + +#[cfg(feature = "tokio")] +#[deprecated(note = "Use `tokio::Transport` instead.")] +pub type TokioDnsConfig = tokio::Transport; + use async_trait::async_trait; use futures::{future::BoxFuture, prelude::*}; use libp2p_core::{ connection::Endpoint, multiaddr::{Multiaddr, Protocol}, transport::{ListenerId, TransportError, TransportEvent}, - Transport, }; use parking_lot::Mutex; use smallvec::SmallVec; @@ -80,10 +153,6 @@ use std::{ sync::Arc, task::{Context, Poll}, }; -#[cfg(any(feature = "async-std", feature = "tokio"))] -use trust_dns_resolver::system_conf; -#[cfg(feature = "tokio")] -use trust_dns_resolver::TokioAsyncResolver; pub use trust_dns_resolver::config::{ResolverConfig, ResolverOpts}; pub use trust_dns_resolver::error::{ResolveError, ResolveErrorKind}; @@ -110,85 +179,28 @@ const MAX_DNS_LOOKUPS: usize = 32; /// result of a single `/dnsaddr` lookup. const MAX_TXT_RECORDS: usize = 16; -/// A `Transport` wrapper for performing DNS lookups when dialing `Multiaddr`esses -/// using `async-std` for all async I/O. -#[cfg(feature = "async-std")] -pub type DnsConfig = GenDnsConfig; - -/// A `Transport` wrapper for performing DNS lookups when dialing `Multiaddr`esses -/// using `tokio` for all async I/O. -#[cfg(feature = "tokio")] -pub type TokioDnsConfig = GenDnsConfig; - -/// A `Transport` wrapper for performing DNS lookups when dialing `Multiaddr`esses. +/// A [`Transport`] for performing DNS lookups when dialing `Multiaddr`esses. +/// You shouldn't need to use this type directly. Use [`tokio::Transport`] or [`async_std::Transport`] instead. #[derive(Debug)] -pub struct GenDnsConfig { +pub struct Transport { /// The underlying transport. inner: Arc>, /// The DNS resolver used when dialing addresses with DNS components. resolver: R, } -#[cfg(feature = "async-std")] -impl DnsConfig -where - T: Send, -{ - /// Creates a new [`DnsConfig`] from the OS's DNS configuration and defaults. - pub async fn system(inner: T) -> Result, io::Error> { - let (cfg, opts) = system_conf::read_system_conf()?; - Self::custom(inner, cfg, opts).await - } - - /// Creates a [`DnsConfig`] with a custom resolver configuration and options. - pub async fn custom( - inner: T, - cfg: ResolverConfig, - opts: ResolverOpts, - ) -> Result, io::Error> { - // TODO: Make infallible in next breaking release. Or deprecation? - Ok(DnsConfig { - inner: Arc::new(Mutex::new(inner)), - resolver: async_std_resolver::resolver(cfg, opts).await, - }) - } -} +#[deprecated(note = "Use `async_std::Transport` or `tokio::Transport` instead.")] +pub type GenDnsConfig = Transport; -#[cfg(feature = "tokio")] -impl TokioDnsConfig +impl libp2p_core::Transport for Transport where - T: Send, -{ - /// Creates a new [`TokioDnsConfig`] from the OS's DNS configuration and defaults. - pub fn system(inner: T) -> Result, io::Error> { - let (cfg, opts) = system_conf::read_system_conf()?; - Self::custom(inner, cfg, opts) - } - - /// Creates a [`TokioDnsConfig`] with a custom resolver configuration - /// and options. - pub fn custom( - inner: T, - cfg: ResolverConfig, - opts: ResolverOpts, - ) -> Result, io::Error> { - // TODO: Make infallible in next breaking release. Or deprecation? - Ok(TokioDnsConfig { - inner: Arc::new(Mutex::new(inner)), - resolver: TokioAsyncResolver::tokio(cfg, opts), - }) - } -} - -impl Transport for GenDnsConfig -where - T: Transport + Send + Unpin + 'static, + T: libp2p_core::Transport + Send + Unpin + 'static, T::Error: Send, T::Dial: Send, R: Clone + Send + Sync + Resolver + 'static, { type Output = T::Output; - type Error = DnsErr; + type Error = Error; type ListenerUpgrade = future::MapErr Self::Error>; type Dial = future::Either< future::MapErr Self::Error>, @@ -203,7 +215,7 @@ where self.inner .lock() .listen_on(id, addr) - .map_err(|e| e.map(DnsErr::Transport)) + .map_err(|e| e.map(Error::Transport)) } fn remove_listener(&mut self, id: ListenerId) -> bool { @@ -230,17 +242,17 @@ where cx: &mut Context<'_>, ) -> Poll> { let mut inner = self.inner.lock(); - Transport::poll(Pin::new(inner.deref_mut()), cx).map(|event| { + libp2p_core::Transport::poll(Pin::new(inner.deref_mut()), cx).map(|event| { event - .map_upgrade(|upgr| upgr.map_err::<_, fn(_) -> _>(DnsErr::Transport)) - .map_err(DnsErr::Transport) + .map_upgrade(|upgr| upgr.map_err::<_, fn(_) -> _>(Error::Transport)) + .map_err(Error::Transport) }) } } -impl GenDnsConfig +impl Transport where - T: Transport + Send + Unpin + 'static, + T: libp2p_core::Transport + Send + Unpin + 'static, T::Error: Send, T::Dial: Send, R: Clone + Send + Sync + Resolver + 'static, @@ -249,7 +261,10 @@ where &mut self, addr: Multiaddr, role_override: Endpoint, - ) -> Result<::Dial, TransportError<::Error>> { + ) -> Result< + ::Dial, + TransportError<::Error>, + > { let resolver = self.resolver.clone(); let inner = self.inner.clone(); @@ -279,7 +294,7 @@ where }) { if dns_lookups == MAX_DNS_LOOKUPS { log::debug!("Too many DNS lookups. Dropping unresolved {}.", addr); - last_err = Some(DnsErr::TooManyLookups); + last_err = Some(Error::TooManyLookups); // There may still be fully resolved addresses in `unresolved`, // so keep going until `unresolved` is empty. continue; @@ -344,12 +359,12 @@ where // actually accepted, i.e. for which it produced // a dialing future. dial_attempts += 1; - out.await.map_err(DnsErr::Transport) + out.await.map_err(Error::Transport) } Err(TransportError::MultiaddrNotSupported(a)) => { - Err(DnsErr::MultiaddrNotSupported(a)) + Err(Error::MultiaddrNotSupported(a)) } - Err(TransportError::Other(err)) => Err(DnsErr::Transport(err)), + Err(TransportError::Other(err)) => Err(Error::Transport(err)), }; match result { @@ -377,7 +392,7 @@ where // for the given address to begin with (i.e. DNS lookups succeeded but // produced no records relevant for the given `addr`). Err(last_err.unwrap_or_else(|| { - DnsErr::ResolveError(ResolveErrorKind::Message("No matching records found.").into()) + Error::ResolveError(ResolveErrorKind::Message("No matching records found.").into()) })) } .boxed() @@ -385,10 +400,10 @@ where } } -/// The possible errors of a [`GenDnsConfig`] wrapped transport. +/// The possible errors of a [`Transport`] wrapped transport. #[derive(Debug)] #[allow(clippy::large_enum_variant)] -pub enum DnsErr { +pub enum Error { /// The underlying transport encountered an error. Transport(TErr), /// DNS resolution failed. @@ -404,30 +419,33 @@ pub enum DnsErr { TooManyLookups, } -impl fmt::Display for DnsErr +#[deprecated(note = "Use `Error` instead.")] +pub type DnsErr = Error; + +impl fmt::Display for Error where TErr: fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - DnsErr::Transport(err) => write!(f, "{err}"), - DnsErr::ResolveError(err) => write!(f, "{err}"), - DnsErr::MultiaddrNotSupported(a) => write!(f, "Unsupported resolved address: {a}"), - DnsErr::TooManyLookups => write!(f, "Too many DNS lookups"), + Error::Transport(err) => write!(f, "{err}"), + Error::ResolveError(err) => write!(f, "{err}"), + Error::MultiaddrNotSupported(a) => write!(f, "Unsupported resolved address: {a}"), + Error::TooManyLookups => write!(f, "Too many DNS lookups"), } } } -impl error::Error for DnsErr +impl error::Error for Error where TErr: error::Error + 'static, { fn source(&self) -> Option<&(dyn error::Error + 'static)> { match self { - DnsErr::Transport(err) => Some(err), - DnsErr::ResolveError(err) => Some(err), - DnsErr::MultiaddrNotSupported(_) => None, - DnsErr::TooManyLookups => None, + Error::Transport(err) => Some(err), + Error::ResolveError(err) => Some(err), + Error::MultiaddrNotSupported(_) => None, + Error::TooManyLookups => None, } } } @@ -453,7 +471,7 @@ enum Resolved<'a> { fn resolve<'a, E: 'a + Send, R: Resolver>( proto: &Protocol<'a>, resolver: &'a R, -) -> BoxFuture<'a, Result, DnsErr>> { +) -> BoxFuture<'a, Result, Error>> { match proto { Protocol::Dns(ref name) => resolver .lookup_ip(name.clone().into_owned()) @@ -475,7 +493,7 @@ fn resolve<'a, E: 'a + Send, R: Resolver>( Ok(Resolved::One(Protocol::from(one))) } } - Err(e) => Err(DnsErr::ResolveError(e)), + Err(e) => Err(Error::ResolveError(e)), }) .boxed(), Protocol::Dns4(ref name) => resolver @@ -499,7 +517,7 @@ fn resolve<'a, E: 'a + Send, R: Resolver>( Ok(Resolved::One(Protocol::from(Ipv4Addr::from(one)))) } } - Err(e) => Err(DnsErr::ResolveError(e)), + Err(e) => Err(Error::ResolveError(e)), }) .boxed(), Protocol::Dns6(ref name) => resolver @@ -523,7 +541,7 @@ fn resolve<'a, E: 'a + Send, R: Resolver>( Ok(Resolved::One(Protocol::from(Ipv6Addr::from(one)))) } } - Err(e) => Err(DnsErr::ResolveError(e)), + Err(e) => Err(Error::ResolveError(e)), }) .boxed(), Protocol::Dnsaddr(ref name) => { @@ -548,7 +566,7 @@ fn resolve<'a, E: 'a + Send, R: Resolver>( } Ok(Resolved::Addrs(addrs)) } - Err(e) => Err(DnsErr::ResolveError(e)), + Err(e) => Err(Error::ResolveError(e)), }) .boxed() } @@ -664,7 +682,7 @@ mod tests { } } - async fn run(mut transport: GenDnsConfig) + async fn run(mut transport: super::Transport) where T: Transport + Clone + Send + Unpin + 'static, T::Error: Send, @@ -719,7 +737,7 @@ mod tests { .unwrap() .await { - Err(DnsErr::ResolveError(_)) => {} + Err(Error::ResolveError(_)) => {} Err(e) => panic!("Unexpected error: {e:?}"), Ok(_) => panic!("Unexpected success."), } @@ -730,7 +748,7 @@ mod tests { .unwrap() .await { - Err(DnsErr::ResolveError(e)) => match e.kind() { + Err(Error::ResolveError(e)) => match e.kind() { ResolveErrorKind::NoRecordsFound { .. } => {} _ => panic!("Unexpected DNS error: {e:?}"), }, @@ -746,7 +764,8 @@ mod tests { let config = ResolverConfig::quad9(); let opts = ResolverOpts::default(); async_std_crate::task::block_on( - DnsConfig::custom(CustomTransport, config, opts).then(|dns| run(dns.unwrap())), + async_std::Transport::custom(CustomTransport, config, opts) + .then(|dns| run(dns.unwrap())), ); } @@ -761,8 +780,9 @@ mod tests { .enable_time() .build() .unwrap(); + rt.block_on(run( - TokioDnsConfig::custom(CustomTransport, config, opts).unwrap() + tokio::Transport::custom(CustomTransport, config, opts).unwrap() )); } } diff --git a/transports/tcp/Cargo.toml b/transports/tcp/Cargo.toml index 1714debada5..ffee29c54c6 100644 --- a/transports/tcp/Cargo.toml +++ b/transports/tcp/Cargo.toml @@ -35,5 +35,6 @@ env_logger = "0.10.0" # More information: https://docs.rs/about/builds#cross-compiling [package.metadata.docs.rs] all-features = true + rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] diff --git a/transports/websocket/src/lib.rs b/transports/websocket/src/lib.rs index 01c02b15320..d7dd7628888 100644 --- a/transports/websocket/src/lib.rs +++ b/transports/websocket/src/lib.rs @@ -74,7 +74,7 @@ use std::{ /// # #[async_std::main] /// # async fn main() { /// -/// let mut transport = websocket::WsConfig::new(dns::DnsConfig::system( +/// let mut transport = websocket::WsConfig::new(dns::async_std::Transport::system( /// tcp::async_io::Transport::new(tcp::Config::default()), /// ).await.unwrap()); ///