happy_eyeballs: propagate actual connection error
This commit is contained in:
parent
81191041c4
commit
ce2ce363b0
3 changed files with 31 additions and 19 deletions
|
|
@ -64,10 +64,8 @@ impl Client {
|
||||||
done(Connecter::from_lookup(&domain, Some("_xmpp-client._tcp"), 5222))
|
done(Connecter::from_lookup(&domain, Some("_xmpp-client._tcp"), 5222))
|
||||||
.map_err(Error::Connection)
|
.map_err(Error::Connection)
|
||||||
)
|
)
|
||||||
.and_then(|connecter|
|
.flatten()
|
||||||
connecter
|
.and_then(move |tcp_stream|
|
||||||
.map_err(Error::Connection)
|
|
||||||
).and_then(move |tcp_stream|
|
|
||||||
xmpp_stream::XMPPStream::start(tcp_stream, jid1, NS_JABBER_CLIENT.to_owned())
|
xmpp_stream::XMPPStream::start(tcp_stream, jid1, NS_JABBER_CLIENT.to_owned())
|
||||||
).and_then(|xmpp_stream| {
|
).and_then(|xmpp_stream| {
|
||||||
if Self::can_starttls(&xmpp_stream) {
|
if Self::can_starttls(&xmpp_stream) {
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,6 @@ impl Component {
|
||||||
let password = password;
|
let password = password;
|
||||||
done(Connecter::from_lookup(server, None, port))
|
done(Connecter::from_lookup(server, None, port))
|
||||||
.flatten()
|
.flatten()
|
||||||
.map_err(Error::Connection)
|
|
||||||
.and_then(move |tcp_stream| {
|
.and_then(move |tcp_stream| {
|
||||||
xmpp_stream::XMPPStream::start(tcp_stream, jid1, NS_JABBER_COMPONENT_ACCEPT.to_owned())
|
xmpp_stream::XMPPStream::start(tcp_stream, jid1, NS_JABBER_COMPONENT_ACCEPT.to_owned())
|
||||||
}).and_then(move |xmpp_stream| {
|
}).and_then(move |xmpp_stream| {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ 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 ConnecterError;
|
use {Error, ConnecterError};
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
AwaitResolver(Box<Future<Item = ResolverFuture, Error = ResolveError> + Send>),
|
AwaitResolver(Box<Future<Item = ResolverFuture, Error = ResolveError> + Send>),
|
||||||
|
|
@ -24,6 +24,7 @@ pub struct Connecter {
|
||||||
domain: Name,
|
domain: Name,
|
||||||
state: State,
|
state: State,
|
||||||
targets: VecDeque<(Name, u16)>,
|
targets: VecDeque<(Name, u16)>,
|
||||||
|
error: Option<Error>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Connecter {
|
impl Connecter {
|
||||||
|
|
@ -38,6 +39,7 @@ impl Connecter {
|
||||||
domain: "nohost".into_name()?,
|
domain: "nohost".into_name()?,
|
||||||
state: State::Connecting(None, vec![connect]),
|
state: State::Connecting(None, vec![connect]),
|
||||||
targets: VecDeque::new(),
|
targets: VecDeque::new(),
|
||||||
|
error: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,19 +58,20 @@ impl Connecter {
|
||||||
domain: domain.into_name()?,
|
domain: domain.into_name()?,
|
||||||
state,
|
state,
|
||||||
targets: VecDeque::new(),
|
targets: VecDeque::new(),
|
||||||
|
error: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Future for Connecter {
|
impl Future for Connecter {
|
||||||
type Item = TcpStream;
|
type Item = TcpStream;
|
||||||
type Error = ConnecterError;
|
type Error = Error;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
let state = mem::replace(&mut self.state, State::Invalid);
|
let state = mem::replace(&mut self.state, State::Invalid);
|
||||||
match state {
|
match state {
|
||||||
State::AwaitResolver(mut resolver_future) => {
|
State::AwaitResolver(mut resolver_future) => {
|
||||||
match resolver_future.poll()? {
|
match resolver_future.poll().map_err(ConnecterError::Resolve)? {
|
||||||
Async::NotReady => {
|
Async::NotReady => {
|
||||||
self.state = State::AwaitResolver(resolver_future);
|
self.state = State::AwaitResolver(resolver_future);
|
||||||
Ok(Async::NotReady)
|
Ok(Async::NotReady)
|
||||||
|
|
@ -122,14 +125,12 @@ impl Future for Connecter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
State::Connecting(resolver, mut connects) => {
|
State::Connecting(resolver, mut connects) => {
|
||||||
if resolver.is_some() &&
|
if resolver.is_some() && connects.len() == 0 && self.targets.len() > 0 {
|
||||||
connects.len() == 0 &&
|
let resolver = resolver.unwrap();
|
||||||
self.targets.len() > 0 {
|
let (host, port) = self.targets.pop_front().unwrap();
|
||||||
let resolver = resolver.unwrap();
|
let ip_lookup = resolver.lookup_ip(host);
|
||||||
let (host, port) = self.targets.pop_front().unwrap();
|
self.state = State::ResolveTarget(resolver, ip_lookup, port);
|
||||||
let ip_lookup = resolver.lookup_ip(host);
|
self.poll()
|
||||||
self.state = State::ResolveTarget(resolver, ip_lookup, port);
|
|
||||||
self.poll()
|
|
||||||
} else if connects.len() > 0 {
|
} else if connects.len() > 0 {
|
||||||
let mut success = None;
|
let mut success = None;
|
||||||
connects.retain(|connect| {
|
connects.retain(|connect| {
|
||||||
|
|
@ -139,7 +140,12 @@ impl Future for Connecter {
|
||||||
success = Some(connection);
|
success = Some(connection);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
Err(_) => false,
|
Err(e) => {
|
||||||
|
if self.error.is_none() {
|
||||||
|
self.error = Some(e.into());
|
||||||
|
}
|
||||||
|
false
|
||||||
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
match success {
|
match success {
|
||||||
|
|
@ -151,7 +157,13 @@ impl Future for Connecter {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} 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) => {
|
State::ResolveTarget(resolver, mut ip_lookup, port) => {
|
||||||
|
|
@ -168,7 +180,10 @@ impl Future for Connecter {
|
||||||
self.state = State::Connecting(Some(resolver), connects);
|
self.state = State::Connecting(Some(resolver), connects);
|
||||||
self.poll()
|
self.poll()
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(e) => {
|
||||||
|
if self.error.is_none() {
|
||||||
|
self.error = Some(ConnecterError::Resolve(e).into());
|
||||||
|
}
|
||||||
// ignore, next…
|
// ignore, next…
|
||||||
self.state = State::Connecting(Some(resolver), vec![]);
|
self.state = State::Connecting(Some(resolver), vec![]);
|
||||||
self.poll()
|
self.poll()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue