happy_eyeballs: enable parallel A/AAAA resolution

This commit is contained in:
Astro 2018-09-08 02:12:49 +02:00
parent d3fab29d38
commit 662c61b801
2 changed files with 19 additions and 7 deletions

View file

@ -62,7 +62,6 @@ impl Client {
.map_err(|_| Error::Idna) .map_err(|_| Error::Idna)
.and_then(|domain| .and_then(|domain|
done(Connecter::from_lookup(&domain, Some("_xmpp-client._tcp"), 5222)) done(Connecter::from_lookup(&domain, Some("_xmpp-client._tcp"), 5222))
.map_err(Error::Connection)
) )
.flatten() .flatten()
.and_then(move |tcp_stream| .and_then(move |tcp_stream|

View file

@ -1,4 +1,5 @@
use std::mem; use std::mem;
use std::io::Error as IoError;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::collections::VecDeque; use std::collections::VecDeque;
@ -8,6 +9,8 @@ use tokio::net::{ConnectFuture, TcpStream};
use trust_dns_resolver::{IntoName, Name, ResolverFuture, error::ResolveError}; use trust_dns_resolver::{IntoName, Name, ResolverFuture, error::ResolveError};
use trust_dns_resolver::lookup::SrvLookupFuture; use trust_dns_resolver::lookup::SrvLookupFuture;
use trust_dns_resolver::lookup_ip::LookupIpFuture; use trust_dns_resolver::lookup_ip::LookupIpFuture;
use trust_dns_resolver::system_conf;
use trust_dns_resolver::config::LookupIpStrategy;
use {Error, ConnecterError}; use {Error, ConnecterError};
enum State { enum State {
@ -27,8 +30,14 @@ pub struct Connecter {
error: Option<Error>, error: Option<Error>,
} }
fn resolver_future() -> Result<Box<Future<Item = ResolverFuture, Error = ResolveError> + Send>, IoError> {
let (conf, mut opts) = system_conf::read_system_conf()?;
opts.ip_strategy = LookupIpStrategy::Ipv4AndIpv6;
Ok(ResolverFuture::new(conf, opts))
}
impl Connecter { impl Connecter {
pub fn from_lookup(domain: &str, srv: Option<&str>, fallback_port: u16) -> Result<Connecter, ConnecterError> { pub fn from_lookup(domain: &str, srv: Option<&str>, fallback_port: u16) -> Result<Connecter, Error> {
if let Ok(ip) = domain.parse() { if let Ok(ip) = domain.parse() {
// use specified IP address, not domain name, skip the whole dns part // use specified IP address, not domain name, skip the whole dns part
let connect = let connect =
@ -36,18 +45,21 @@ impl Connecter {
return Ok(Connecter { return Ok(Connecter {
fallback_port, fallback_port,
srv_domain: None, srv_domain: None,
domain: "nohost".into_name()?, domain: "nohost".into_name()
.map_err(ConnecterError::Dns)?,
state: State::Connecting(None, vec![connect]), state: State::Connecting(None, vec![connect]),
targets: VecDeque::new(), targets: VecDeque::new(),
error: None, error: None,
}); });
} }
let resolver_future = ResolverFuture::from_system_conf()?; let state = State::AwaitResolver(resolver_future()?);
let state = State::AwaitResolver(resolver_future);
let srv_domain = match srv { let srv_domain = match srv {
Some(srv) => Some(srv) =>
Some(format!("{}.{}.", srv, domain).into_name()?), Some(format!("{}.{}.", srv, domain)
.into_name()
.map_err(ConnecterError::Dns)?
),
None => None =>
None, None,
}; };
@ -55,7 +67,8 @@ impl Connecter {
Ok(Connecter { Ok(Connecter {
fallback_port, fallback_port,
srv_domain, srv_domain,
domain: domain.into_name()?, domain: domain.into_name()
.map_err(ConnecterError::Dns)?,
state, state,
targets: VecDeque::new(), targets: VecDeque::new(),
error: None, error: None,