Try all Inet Addresses of the host when connecting

instead of the first resolved one.

Also some small refactorizations (e.g. getSocketFactory())
This commit is contained in:
Florian Schmaus 2015-01-04 16:38:45 +01:00
parent 717090d272
commit f6144c553c
1 changed files with 38 additions and 26 deletions

View File

@ -77,6 +77,7 @@ import org.jivesoftware.smack.util.dns.HostAddress;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
import javax.net.SocketFactory;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.KeyManagerFactory;
@ -95,6 +96,7 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.security.KeyManagementException; import java.security.KeyManagementException;
@ -107,6 +109,7 @@ import java.security.Security;
import java.security.UnrecoverableKeyException; import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
@ -508,37 +511,46 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
} }
Iterator<HostAddress> it = hostAddresses.iterator(); Iterator<HostAddress> it = hostAddresses.iterator();
List<HostAddress> failedAddresses = new LinkedList<HostAddress>(); List<HostAddress> failedAddresses = new LinkedList<HostAddress>();
while (it.hasNext()) { SocketFactory socketFactory = config.getSocketFactory();
Exception exception = null; if (socketFactory == null) {
socketFactory = SocketFactory.getDefault();
}
outerloop: while (it.hasNext()) {
HostAddress hostAddress = it.next(); HostAddress hostAddress = it.next();
String host = hostAddress.getFQDN(); String host = hostAddress.getFQDN();
int port = hostAddress.getPort(); int port = hostAddress.getPort();
if (config.getSocketFactory() == null) { socket = socketFactory.createSocket();
socket = new Socket();
}
else {
socket = config.getSocketFactory().createSocket();
}
LOGGER.finer("Trying to establish TCP connection to " + host + " at port " + port);
try { try {
socket.connect(new InetSocketAddress(host, port), config.getConnectTimeout()); Iterator<InetAddress> inetAddresses = Arrays.asList(InetAddress.getAllByName(host)).iterator();
} catch (Exception e) { innerloop: while (inetAddresses.hasNext()) {
exception = e; 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) { catch (Exception e) {
LOGGER.finer("Established TCP connection to " + host + " at port " + port); hostAddress.setException(e);
// We found a host to connect to, break here failedAddresses.add(hostAddress);
this.host = host; if (!it.hasNext()) {
this.port = port; // There are no more host addresses to try
break; // throw an exception and report all tried
} // HostAddresses in the exception
hostAddress.setException(exception); throw ConnectionException.from(failedAddresses);
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; socketClosed = false;