happy_eyeballs: propagate actual connection error

This commit is contained in:
Astro 2018-09-08 01:35:26 +02:00
parent 81191041c4
commit ce2ce363b0
3 changed files with 31 additions and 19 deletions

View file

@ -64,10 +64,8 @@ impl Client {
done(Connecter::from_lookup(&domain, Some("_xmpp-client._tcp"), 5222))
.map_err(Error::Connection)
)
.and_then(|connecter|
connecter
.map_err(Error::Connection)
).and_then(move |tcp_stream|
.flatten()
.and_then(move |tcp_stream|
xmpp_stream::XMPPStream::start(tcp_stream, jid1, NS_JABBER_CLIENT.to_owned())
).and_then(|xmpp_stream| {
if Self::can_starttls(&xmpp_stream) {

View file

@ -55,7 +55,6 @@ impl Component {
let password = password;
done(Connecter::from_lookup(server, None, port))
.flatten()
.map_err(Error::Connection)
.and_then(move |tcp_stream| {
xmpp_stream::XMPPStream::start(tcp_stream, jid1, NS_JABBER_COMPONENT_ACCEPT.to_owned())
}).and_then(move |xmpp_stream| {

View file

@ -8,7 +8,7 @@ use tokio::net::{ConnectFuture, TcpStream};
use trust_dns_resolver::{IntoName, Name, ResolverFuture, error::ResolveError};
use trust_dns_resolver::lookup::SrvLookupFuture;
use trust_dns_resolver::lookup_ip::LookupIpFuture;
use ConnecterError;
use {Error, ConnecterError};
enum State {
AwaitResolver(Box<Future<Item = ResolverFuture, Error = ResolveError> + Send>),
@ -24,6 +24,7 @@ pub struct Connecter {
domain: Name,
state: State,
targets: VecDeque<(Name, u16)>,
error: Option<Error>,
}
impl Connecter {
@ -38,6 +39,7 @@ impl Connecter {
domain: "nohost".into_name()?,
state: State::Connecting(None, vec![connect]),
targets: VecDeque::new(),
error: None,
});
}
@ -56,19 +58,20 @@ impl Connecter {
domain: domain.into_name()?,
state,
targets: VecDeque::new(),
error: None,
})
}
}
impl Future for Connecter {
type Item = TcpStream;
type Error = ConnecterError;
type Error = Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let state = mem::replace(&mut self.state, State::Invalid);
match state {
State::AwaitResolver(mut resolver_future) => {
match resolver_future.poll()? {
match resolver_future.poll().map_err(ConnecterError::Resolve)? {
Async::NotReady => {
self.state = State::AwaitResolver(resolver_future);
Ok(Async::NotReady)
@ -122,9 +125,7 @@ impl Future for Connecter {
}
}
State::Connecting(resolver, mut connects) => {
if resolver.is_some() &&
connects.len() == 0 &&
self.targets.len() > 0 {
if resolver.is_some() && connects.len() == 0 && self.targets.len() > 0 {
let resolver = resolver.unwrap();
let (host, port) = self.targets.pop_front().unwrap();
let ip_lookup = resolver.lookup_ip(host);
@ -139,7 +140,12 @@ impl Future for Connecter {
success = Some(connection);
false
}
Err(_) => false,
Err(e) => {
if self.error.is_none() {
self.error = Some(e.into());
}
false
},
}
});
match success {
@ -151,7 +157,13 @@ impl Future for Connecter {
},
}
} else {
Err(ConnecterError::AllFailed)
// All targets tried
match self.error.take() {
None =>
Err(ConnecterError::AllFailed.into()),
Some(e) =>
Err(e),
}
}
}
State::ResolveTarget(resolver, mut ip_lookup, port) => {
@ -168,7 +180,10 @@ impl Future for Connecter {
self.state = State::Connecting(Some(resolver), connects);
self.poll()
}
Err(_) => {
Err(e) => {
if self.error.is_none() {
self.error = Some(ConnecterError::Resolve(e).into());
}
// ignore, next…
self.state = State::Connecting(Some(resolver), vec![]);
self.poll()