Merge branch 'ipv6' into 'main'

tokio-xmpp: set resolve ip_strategy to Ipv4AndIpv6, let connect happy_eyeballs in parallel

See merge request xmpp-rs/xmpp-rs!308
This commit is contained in:
Astro 2024-04-16 19:12:00 +00:00
commit dd1e81fcc9
1 changed files with 24 additions and 6 deletions

View File

@ -1,5 +1,11 @@
use super::error::{ConnectorError, Error};
use hickory_resolver::{IntoName, TokioAsyncResolver};
use futures::{future, FutureExt};
use hickory_resolver::{
IntoName,
config::LookupIpStrategy,
TokioAsyncResolver,
name_server::TokioConnectionProvider,
};
use log::debug;
use std::net::SocketAddr;
use tokio::net::TcpStream;
@ -13,17 +19,29 @@ pub async fn connect_to_host(domain: &str, port: u16) -> Result<TcpStream, Error
.map_err(|e| Error::from(crate::Error::Io(e)))?);
}
let resolver = TokioAsyncResolver::tokio_from_system_conf().map_err(ConnectorError::Resolve)?;
let (config, mut options) = hickory_resolver::system_conf::read_system_conf()
.map_err(ConnectorError::Resolve)?;
options.ip_strategy = LookupIpStrategy::Ipv4AndIpv6;
let resolver = TokioAsyncResolver::new(
config, options,
TokioConnectionProvider::default()
);
let ips = resolver
.lookup_ip(ascii_domain)
.await
.map_err(ConnectorError::Resolve)?;
for ip in ips.iter() {
match TcpStream::connect(&SocketAddr::new(ip, port)).await {
Ok(stream) => return Ok(stream),
Err(_) => {}
// Happy Eyeballs: connect to all records in parallel
let mut connects = ips.into_iter()
.map(|ip| TcpStream::connect(SocketAddr::new(ip, port)).boxed())
.collect::<Vec<_>>();
while connects.len() > 0 {
let (result, _, remaining) = future::select_all(connects.into_iter()).await;
if let Ok(stream) = result {
// Use the first to connect successfully
return Ok(stream);
}
connects = remaining;
}
Err(crate::Error::Disconnected.into())
}