tokio-xmpp: let happy_eyeballs connect to records in parallel

Astro created

Change summary

tokio-xmpp/src/starttls/happy_eyeballs.rs | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)

Detailed changes

tokio-xmpp/src/starttls/happy_eyeballs.rs 🔗

@@ -1,4 +1,5 @@
 use super::error::{ConnectorError, Error};
+use futures::{future::select_ok, FutureExt};
 use hickory_resolver::{
     config::LookupIpStrategy, name_server::TokioConnectionProvider, IntoName, TokioAsyncResolver,
 };
@@ -24,13 +25,15 @@ pub async fn connect_to_host(domain: &str, port: u16) -> Result<TcpStream, Error
         .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(_) => {}
-        }
-    }
-    Err(crate::Error::Disconnected.into())
+    // Happy Eyeballs: connect to all records in parallel, return the
+    // first to succeed
+    select_ok(
+        ips.into_iter()
+            .map(|ip| TcpStream::connect(SocketAddr::new(ip, port)).boxed()),
+    )
+    .await
+    .map(|(result, _)| result)
+    .map_err(|_| crate::Error::Disconnected.into())
 }
 
 pub async fn connect_with_srv(