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

Add transport support for dnsaddr #1450

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions transports/dns/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ categories = ["network-programming", "asynchronous"]
libp2p-core = { version = "0.15.0", path = "../../core" }
log = "0.4.1"
futures = "0.3.1"
trust-dns-client = "0.19.2"
trust-dns-proto = "0.19.2"
67 changes: 65 additions & 2 deletions transports/dns/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,19 @@
//! replaced with respectively an `/ip4/` or an `/ip6/` component.
//!

use futures::{prelude::*, channel::oneshot, future::BoxFuture};
use futures::{prelude::*, channel::oneshot, future::BoxFuture, FutureExt};
use libp2p_core::{
Transport,
multiaddr::{Protocol, Multiaddr},
transport::{TransportError, ListenerEvent}
};
use log::{error, debug, trace};
use std::{error, fmt, io, net::ToSocketAddrs};
use std::str::FromStr;
use trust_dns_client::rr::{DNSClass, RecordType};
use trust_dns_client::udp::UdpClientConnection;
use trust_dns_client::client::{SyncClient, Client};
use trust_dns_proto::rr::domain::Name;

/// Represents the configuration for a DNS transport capability of libp2p.
///
Expand Down Expand Up @@ -122,6 +127,7 @@ where
let contains_dns = addr.iter().any(|cmp| match cmp {
Protocol::Dns4(_) => true,
Protocol::Dns6(_) => true,
Protocol::Dnsaddr(_) => true,
_ => false,
});

Expand Down Expand Up @@ -170,7 +176,56 @@ where
})
.next()
.ok_or_else(|| DnsErr::ResolveFail(name))
}.left_future()
}.boxed().left_future()
Copy link
Member

Choose a reason for hiding this comment

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

You normally don't have to box the future. Just put an async block around the entire code instead of having two distinct async blocks.

Since this is a lot of code, it might be worth moving it to a separate freestanding function.

},
Protocol::Dnsaddr(ref name) => {
let conn = UdpClientConnection::new("8.8.8.8:53".parse().unwrap()).unwrap(); // TODO: error handling
let client = SyncClient::new(conn); // TODO: should use async client?

let name = Name::from_str(&format!("_dnsaddr.{}", name)).unwrap(); // TODO: error handling
let response = client.query(&name, DNSClass::IN, RecordType::TXT).unwrap(); // TODO: error handling
let resolved_addrs = response.answers().iter()
.filter_map(|record| {
if let trust_dns_client::proto::rr::RData::TXT(ref txt) = record.rdata() {
Some(txt.iter())
} else {
None
}
})
.flatten()
.filter_map(|bytes| {
let str = std::str::from_utf8(bytes).unwrap(); // TODO: error handling
let addr = Multiaddr::from_str(str.trim_start_matches("dnsaddr=")).unwrap(); // TODO: error handling

// TODO: suffix matching
// https://github.com/multiformats/multiaddr/blob/master/protocols/DNSADDR.md#suffix-matching

match addr.iter().next() {
Some(Protocol::Ip4(ipv4addr)) => {
Some(Protocol::from(ipv4addr))
}
Some(Protocol::Ip6(ipv6addr)) => {
Some(Protocol::from(ipv6addr))
}
Some(Protocol::Dnsaddr(ref name)) => {
// TODO: recursive resolution
error!("Resolved to the dnsaddr {:?} but recursive resolution is not supported for now.", name);
None
}
protocol => {
// TODO: error handling
error!("{:?}", protocol);
None
}
}
})
.collect::<Vec<_>>();

// if resolved_addrs.len() == 0 {} // TODO

async move {
Ok(resolved_addrs[0].clone())
}.boxed().left_future()
},
cmp => future::ready(Ok(cmp.acquire())).right_future()
})
Expand Down Expand Up @@ -299,10 +354,18 @@ mod tests {
.unwrap();

let _ = transport
.clone()
.dial("/ip4/1.2.3.4/tcp/20000".parse().unwrap())
.unwrap()
.await
.unwrap();

let _ = transport
.clone()
.dial("/dnsaddr/sjc-1.bootstrap.libp2p.io/tcp/4001".parse().unwrap())
.unwrap()
.await
.unwrap();
});
}
}