Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libp2p-dns] Use trust-dns-resolver (with either async-std or tokio). Remove thread pool. #1927

Merged
merged 9 commits into from Mar 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Expand Up @@ -44,6 +44,13 @@

## Version 0.36.0 [unreleased]

- Consolidate top-level utility functions for constructing development
transports. There is now just `development_transport()` (available with default features)
and `tokio_development_transport()` (available when the corresponding tokio features are enabled).
Furthermore, these are now `async fn`s. The minor variations that also included `pnet`
support have been removed.
[PR 1927](https://github.com/libp2p/rust-libp2p/pull/1927)

- Update libp2p crates.

- Do not leak default features from libp2p crates.
Expand Down
7 changes: 4 additions & 3 deletions Cargo.toml
Expand Up @@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
[features]
default = [
"deflate",
"dns",
"dns-async-std",
"floodsub",
"identify",
"kad",
Expand All @@ -33,7 +33,8 @@ default = [
"yamux",
]
deflate = ["libp2p-deflate"]
dns = ["libp2p-dns"]
dns-async-std = ["libp2p-dns", "libp2p-dns/async-std"]
dns-tokio = ["libp2p-dns", "libp2p-dns/tokio"]
floodsub = ["libp2p-floodsub"]
identify = ["libp2p-identify"]
kad = ["libp2p-kad"]
Expand Down Expand Up @@ -88,7 +89,7 @@ wasm-timer = "0.2.4"

[target.'cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))'.dependencies]
libp2p-deflate = { version = "0.27.1", path = "transports/deflate", optional = true }
libp2p-dns = { version = "0.27.0", path = "transports/dns", optional = true }
libp2p-dns = { version = "0.28.0", path = "transports/dns", optional = true, default-features = false }
libp2p-mdns = { version = "0.29.0", path = "protocols/mdns", optional = true }
libp2p-tcp = { version = "0.27.1", path = "transports/tcp", default-features = false, optional = true }
libp2p-websocket = { version = "0.28.0", path = "transports/websocket", optional = true }
Expand Down
5 changes: 3 additions & 2 deletions examples/chat.rs
Expand Up @@ -63,7 +63,8 @@ use libp2p::{
};
use std::{error::Error, task::{Context, Poll}};

fn main() -> Result<(), Box<dyn Error>> {
#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();

// Create a random PeerId
Expand All @@ -72,7 +73,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("Local peer id: {:?}", local_peer_id);

// Set up a an encrypted DNS-enabled TCP Transport over the Mplex and Yamux protocols
let transport = libp2p::build_development_transport(local_key)?;
let transport = libp2p::development_transport(local_key).await?;

// Create a Floodsub topic
let floodsub_topic = floodsub::Topic::new("chat");
Expand Down
7 changes: 4 additions & 3 deletions examples/distributed-key-value-store.rs
Expand Up @@ -58,22 +58,23 @@ use libp2p::{
NetworkBehaviour,
PeerId,
Swarm,
build_development_transport,
development_transport,
identity,
mdns::{Mdns, MdnsConfig, MdnsEvent},
swarm::NetworkBehaviourEventProcess
};
use std::{error::Error, task::{Context, Poll}};

fn main() -> Result<(), Box<dyn Error>> {
#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();

// Create a random key for ourselves.
let local_key = identity::Keypair::generate_ed25519();
let local_peer_id = PeerId::from(local_key.public());

// Set up a an encrypted DNS-enabled TCP Transport over the Mplex protocol.
let transport = build_development_transport(local_key)?;
let transport = development_transport(local_key).await?;

// We create a custom network behaviour that combines Kademlia and mDNS.
#[derive(NetworkBehaviour)]
Expand Down
5 changes: 3 additions & 2 deletions examples/gossipsub-chat.rs
Expand Up @@ -62,7 +62,8 @@ use std::{
task::{Context, Poll},
};

fn main() -> Result<(), Box<dyn Error>> {
#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
Builder::from_env(Env::default().default_filter_or("info")).init();

// Create a random PeerId
Expand All @@ -71,7 +72,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("Local peer id: {:?}", local_peer_id);

// Set up an encrypted TCP Transport over the Mplex and Yamux protocols
let transport = libp2p::build_development_transport(local_key.clone())?;
let transport = libp2p::development_transport(local_key.clone()).await?;

// Create a Gossipsub topic
let topic = Topic::new("test-net");
Expand Down
7 changes: 4 additions & 3 deletions examples/ipfs-kad.rs
Expand Up @@ -28,7 +28,7 @@ use libp2p::{
Swarm,
PeerId,
identity,
build_development_transport
development_transport
};
use libp2p::kad::{
Kademlia,
Expand All @@ -40,15 +40,16 @@ use libp2p::kad::{
use libp2p::kad::record::store::MemoryStore;
use std::{env, error::Error, time::Duration};

fn main() -> Result<(), Box<dyn Error>> {
#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();

// Create a random key for ourselves.
let local_key = identity::Keypair::generate_ed25519();
let local_peer_id = PeerId::from(local_key.public());

// Set up a an encrypted DNS-enabled TCP Transport over the Mplex protocol
let transport = build_development_transport(local_key)?;
let transport = development_transport(local_key).await?;

// Create a swarm to manage peers and events.
let mut swarm = {
Expand Down
2 changes: 1 addition & 1 deletion examples/mdns-passive-discovery.rs
Expand Up @@ -31,7 +31,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
println!("Local peer id: {:?}", peer_id);

// Create a transport.
let transport = libp2p::build_development_transport(id_keys)?;
let transport = libp2p::development_transport(id_keys).await?;

// Create an MDNS network behaviour.
let behaviour = Mdns::new(MdnsConfig::default()).await?;
Expand Down
5 changes: 3 additions & 2 deletions examples/ping.rs
Expand Up @@ -43,7 +43,8 @@ use futures::{future, prelude::*};
use libp2p::{identity, PeerId, ping::{Ping, PingConfig}, Swarm};
use std::{error::Error, task::{Context, Poll}};

fn main() -> Result<(), Box<dyn Error>> {
#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();

// Create a random PeerId.
Expand All @@ -52,7 +53,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("Local peer id: {:?}", peer_id);

// Create a transport.
let transport = libp2p::build_development_transport(id_keys)?;
let transport = libp2p::development_transport(id_keys).await?;

// Create a ping network behaviour.
//
Expand Down
82 changes: 37 additions & 45 deletions src/lib.rs
Expand Up @@ -56,7 +56,7 @@
//! the dialing to take place and eventually resolve to a connection. Polling
//! futures is typically done through a [tokio] runtime.
//!
//! The easiest way to create a transport is to use [`build_development_transport`].
//! The easiest way to create a transport is to use [`development_transport`].
//! This function provides support for the most common protocols but it is also
//! subject to change over time and should thus not be used in production
//! configurations.
Expand All @@ -65,8 +65,8 @@
//!
//! ```rust
//! let keypair = libp2p::identity::Keypair::generate_ed25519();
//! let _transport = libp2p::build_development_transport(keypair);
//! // _transport.dial(...);
//! let _transport = libp2p::development_transport(keypair);
//! // _transport.await?.dial(...);
//! ```
//!
//! The keypair that is passed as an argument in the above example is used
Expand All @@ -85,7 +85,7 @@
//! Example ([`noise`] + [`yamux`] Protocol Upgrade):
//!
//! ```rust
//! # #[cfg(all(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), feature = "noise", feature = "yamux"))] {
//! # #[cfg(all(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), feature = "tcp-async-io", feature = "noise", feature = "yamux"))] {
//! use libp2p::{Transport, core::upgrade, tcp::TcpConfig, noise, identity::Keypair, yamux};
//! let tcp = TcpConfig::new();
//! let id_keys = Keypair::generate_ed25519();
Expand Down Expand Up @@ -130,7 +130,7 @@
//! identity of the remote peer of the established connection, which is
//! usually obtained through a transport encryption protocol such as
//! [`noise`] that authenticates the peer. See the implementation of
//! [`build_development_transport`] for an example.
//! [`development_transport`] for an example.
//! 3. Creating a struct that implements the [`NetworkBehaviour`] trait and combines all the
//! desired network behaviours, implementing the event handlers as per the
//! desired application's networking logic.
Expand All @@ -154,9 +154,6 @@
#![doc(html_logo_url = "https://libp2p.io/img/logo_small.png")]
#![doc(html_favicon_url = "https://libp2p.io/img/favicon.png")]

#[cfg(feature = "pnet")]
use libp2p_pnet::{PnetConfig, PreSharedKey};

pub use bytes;
pub use futures;
#[doc(inline)]
Expand All @@ -171,8 +168,8 @@ pub use libp2p_core as core;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))]
#[doc(inline)]
pub use libp2p_deflate as deflate;
#[cfg(feature = "dns")]
#[cfg_attr(docsrs, doc(cfg(feature = "dns")))]
#[cfg(any(feature = "dns-async-std", feature = "dns-tokio"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "dns-async-std", feature = "dns-tokio"))))]
#[cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))]
#[doc(inline)]
pub use libp2p_dns as dns;
Expand Down Expand Up @@ -268,35 +265,27 @@ pub use self::simple::SimpleProtocol;
pub use self::swarm::Swarm;
pub use self::transport_ext::TransportExt;

/// Builds a `Transport` that supports the most commonly-used protocols that libp2p supports.
/// Builds a `Transport` based on TCP/IP that supports the most commonly-used features of libp2p:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am very much in favor of this cleanup.

///
/// * DNS resolution.
/// * Noise protocol encryption.
/// * Websockets.
/// * Both Yamux and Mplex for substream multiplexing.
///
/// All async I/O of the transport is based on `async-std`.
///
/// > **Note**: This `Transport` is not suitable for production usage, as its implementation
/// > reserves the right to support additional protocols or remove deprecated protocols.
#[cfg(all(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), any(feature = "tcp-async-io", feature = "tcp-tokio"), feature = "websocket", feature = "noise", feature = "mplex", feature = "yamux"))]
#[cfg_attr(docsrs, doc(cfg(all(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), any(feature = "tcp-async-io", feature = "tcp-tokio"), feature = "websocket", feature = "noise", feature = "mplex", feature = "yamux"))))]
pub fn build_development_transport(keypair: identity::Keypair)
-> std::io::Result<core::transport::Boxed<(PeerId, core::muxing::StreamMuxerBox)>>
{
build_tcp_ws_noise_mplex_yamux(keypair)
}

/// Builds an implementation of `Transport` that is suitable for usage with the `Swarm`.
///
/// The implementation supports TCP/IP, WebSockets over TCP/IP, noise as the encryption layer,
/// and mplex or yamux as the multiplexing layer.
#[cfg(all(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), any(feature = "tcp-async-io", feature = "tcp-tokio"), feature = "websocket", feature = "noise", feature = "mplex", feature = "yamux"))]
#[cfg_attr(docsrs, doc(cfg(all(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), any(feature = "tcp-async-io", feature = "tcp-tokio"), feature = "websocket", feature = "noise", feature = "mplex", feature = "yamux"))))]
pub fn build_tcp_ws_noise_mplex_yamux(keypair: identity::Keypair)
#[cfg(all(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), feature = "tcp-async-io", feature = "dns-async-std", feature = "websocket", feature = "noise", feature = "mplex", feature = "yamux"))]
#[cfg_attr(docsrs, doc(cfg(all(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), feature = "tcp-async-io", feature = "dns-async-std", feature = "websocket", feature = "noise", feature = "mplex", feature = "yamux"))))]
pub async fn development_transport(keypair: identity::Keypair)
-> std::io::Result<core::transport::Boxed<(PeerId, core::muxing::StreamMuxerBox)>>
{
let transport = {
#[cfg(feature = "tcp-async-io")]
let tcp = tcp::TcpConfig::new().nodelay(true);
#[cfg(feature = "tcp-tokio")]
let tcp = tcp::TokioTcpConfig::new().nodelay(true);
let transport = dns::DnsConfig::new(tcp)?;
let trans_clone = transport.clone();
transport.or_transport(websocket::WsConfig::new(trans_clone))
let transport = dns::DnsConfig::system(tcp).await?;
let websockets = websocket::WsConfig::new(transport.clone());
transport.or_transport(websockets)
};

let noise_keys = noise::Keypair::<noise::X25519Spec>::new()
Expand All @@ -311,31 +300,34 @@ pub fn build_tcp_ws_noise_mplex_yamux(keypair: identity::Keypair)
.boxed())
}

/// Builds an implementation of `Transport` that is suitable for usage with the `Swarm`.
/// Builds a `Transport` based on TCP/IP that supports the most commonly-used features of libp2p:
///
/// * DNS resolution.
/// * Noise protocol encryption.
/// * Websockets.
/// * Both Yamux and Mplex for substream multiplexing.
///
/// All async I/O of the transport is based on `tokio`.
///
/// The implementation supports TCP/IP, WebSockets over TCP/IP, noise as the encryption layer,
/// and mplex or yamux as the multiplexing layer.
#[cfg(all(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), any(feature = "tcp-async-io", feature = "tcp-tokio"), feature = "websocket", feature = "noise", feature = "mplex", feature = "yamux", feature = "pnet"))]
#[cfg_attr(docsrs, doc(cfg(all(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), any(feature = "tcp-async-io", feature = "tcp-tokio"), feature = "websocket", feature = "noise", feature = "mplex", feature = "yamux", feature = "pnet"))))]
pub fn build_tcp_ws_pnet_noise_mplex_yamux(keypair: identity::Keypair, psk: PreSharedKey)
/// > **Note**: This `Transport` is not suitable for production usage, as its implementation
/// > reserves the right to support additional protocols or remove deprecated protocols.
#[cfg(all(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), feature = "tcp-tokio", feature = "dns-tokio", feature = "websocket", feature = "noise", feature = "mplex", feature = "yamux"))]
#[cfg_attr(docsrs, doc(cfg(all(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), feature = "tcp-tokio", feature = "dns-tokio", feature = "websocket", feature = "noise", feature = "mplex", feature = "yamux"))))]
pub fn tokio_development_transport(keypair: identity::Keypair)
-> std::io::Result<core::transport::Boxed<(PeerId, core::muxing::StreamMuxerBox)>>
{
let transport = {
#[cfg(feature = "tcp-async-io")]
let tcp = tcp::TcpConfig::new().nodelay(true);
#[cfg(feature = "tcp-tokio")]
let tcp = tcp::TokioTcpConfig::new().nodelay(true);
let transport = dns::DnsConfig::new(tcp)?;
let trans_clone = transport.clone();
transport.or_transport(websocket::WsConfig::new(trans_clone))
let transport = dns::TokioDnsConfig::system(tcp)?;
let websockets = websocket::WsConfig::new(transport.clone());
transport.or_transport(websockets)
};

let noise_keys = noise::Keypair::<noise::X25519Spec>::new()
.into_authentic(&keypair)
.expect("Signing libp2p-noise static DH keypair failed.");

Ok(transport
.and_then(move |socket, _| PnetConfig::new(psk).handshake(socket))
.upgrade(core::upgrade::Version::V1)
.authenticate(noise::NoiseConfig::xx(noise_keys).into_authenticated())
.multiplex(core::upgrade::SelectUpgrade::new(yamux::YamuxConfig::default(), mplex::MplexConfig::default()))
Expand Down
7 changes: 7 additions & 0 deletions transports/dns/CHANGELOG.md
@@ -1,3 +1,10 @@
# 0.28.0 [unreleased]

- Use `trust-dns-resolver`, removing the internal thread pool and
expanding the configurability of `libp2p-dns` by largely exposing the
configuration of `trust-dns-resolver`.
[PR 1927](https://github.com/libp2p/rust-libp2p/pull/1927)

# 0.27.0 [2021-01-12]

- Update dependencies.
Expand Down
20 changes: 19 additions & 1 deletion transports/dns/Cargo.toml
Expand Up @@ -2,7 +2,7 @@
name = "libp2p-dns"
edition = "2018"
description = "DNS transport implementation for libp2p"
version = "0.27.0"
version = "0.28.0"
authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p"
Expand All @@ -13,3 +13,21 @@ categories = ["network-programming", "asynchronous"]
libp2p-core = { version = "0.27.0", path = "../../core" }
log = "0.4.1"
futures = "0.3.1"
trust-dns-resolver = { version = "0.20", default-features = false, features = ["system-config"] }
async-std-resolver = { version = "0.20", optional = true }

[dev-dependencies]
env_logger = "0.6"
tokio-crate = { package = "tokio", version = "1.0", default-features = false, features = ["rt", "time"] }
async-std-crate = { package = "async-std", version = "1.6" }

[features]
default = ["async-std"]
async-std = ["async-std-resolver"]
tokio = ["trust-dns-resolver/tokio-runtime"]
# The `tokio-` prefix and feature dependency is just to be explicit,
# since these features of `trust-dns-resolver` are currently only
# available for `tokio`.
tokio-dns-over-rustls = ["tokio", "trust-dns-resolver/dns-over-rustls"]
tokio-dns-over-https-rustls = ["tokio", "trust-dns-resolver/dns-over-https-rustls"]