From f6144c553c29c76fd4434d1ab6da0c6aee4128b5 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 4 Jan 2015 16:38:45 +0100 Subject: [PATCH] Try all Inet Addresses of the host when connecting instead of the first resolved one. Also some small refactorizations (e.g. getSocketFactory()) --- .../smack/tcp/XMPPTCPConnection.java | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index c4c25be31..3747ec685 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -77,6 +77,7 @@ import org.jivesoftware.smack.util.dns.HostAddress; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; +import javax.net.SocketFactory; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; @@ -95,6 +96,7 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.lang.reflect.Constructor; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.security.KeyManagementException; @@ -107,6 +109,7 @@ import java.security.Security; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashSet; @@ -508,37 +511,46 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { } Iterator it = hostAddresses.iterator(); List failedAddresses = new LinkedList(); - while (it.hasNext()) { - Exception exception = null; + SocketFactory socketFactory = config.getSocketFactory(); + if (socketFactory == null) { + socketFactory = SocketFactory.getDefault(); + } + outerloop: while (it.hasNext()) { HostAddress hostAddress = it.next(); String host = hostAddress.getFQDN(); int port = hostAddress.getPort(); - if (config.getSocketFactory() == null) { - socket = new Socket(); - } - else { - socket = config.getSocketFactory().createSocket(); - } - LOGGER.finer("Trying to establish TCP connection to " + host + " at port " + port); + socket = socketFactory.createSocket(); try { - socket.connect(new InetSocketAddress(host, port), config.getConnectTimeout()); - } catch (Exception e) { - exception = e; + Iterator inetAddresses = Arrays.asList(InetAddress.getAllByName(host)).iterator(); + innerloop: while (inetAddresses.hasNext()) { + final InetAddress inetAddress = inetAddresses.next(); + final String inetAddressAndPort = inetAddress + "at port " + port; + LOGGER.finer("Trying to establish TCP connection to " + inetAddressAndPort); + try { + socket.connect(new InetSocketAddress(inetAddress, port), config.getConnectTimeout()); + } catch (Exception e) { + if (inetAddresses.hasNext()) { + continue innerloop; + } else { + throw e; + } + } + LOGGER.finer("Established TCP connection to " + inetAddressAndPort); + // We found a host to connect to, break here + this.host = host; + this.port = port; + break outerloop; + } } - if (exception == null) { - LOGGER.finer("Established TCP connection to " + host + " at port " + port); - // We found a host to connect to, break here - this.host = host; - this.port = port; - break; - } - hostAddress.setException(exception); - failedAddresses.add(hostAddress); - if (!it.hasNext()) { - // There are no more host addresses to try - // throw an exception and report all tried - // HostAddresses in the exception - throw ConnectionException.from(failedAddresses); + catch (Exception e) { + hostAddress.setException(e); + failedAddresses.add(hostAddress); + if (!it.hasNext()) { + // There are no more host addresses to try + // throw an exception and report all tried + // HostAddresses in the exception + throw ConnectionException.from(failedAddresses); + } } } socketClosed = false;