Move DNS resolving into connect()

It was misplaced in ConnectionConfiguration anyways, as the sole
instantiation of a ConnectionConfiguration should not cause any network
I/O.
This commit is contained in:
Florian Schmaus 2014-03-18 17:29:38 +01:00
parent dbab9b8995
commit d349940537
7 changed files with 56 additions and 64 deletions

View File

@ -102,8 +102,6 @@ public class ConnectionConfiguration implements Cloneable {
* @param serviceName the name of the service provided by an XMPP server. * @param serviceName the name of the service provided by an XMPP server.
*/ */
public ConnectionConfiguration(String serviceName) { public ConnectionConfiguration(String serviceName) {
// Perform DNS lookup to get host and port to use
hostAddresses = DNSUtil.resolveXMPPDomain(serviceName);
init(serviceName, ProxyInfo.forDefaultProxy()); init(serviceName, ProxyInfo.forDefaultProxy());
} }
@ -117,8 +115,6 @@ public class ConnectionConfiguration implements Cloneable {
* @param proxy the proxy through which XMPP is to be connected * @param proxy the proxy through which XMPP is to be connected
*/ */
public ConnectionConfiguration(String serviceName,ProxyInfo proxy) { public ConnectionConfiguration(String serviceName,ProxyInfo proxy) {
// Perform DNS lookup to get host and port to use
hostAddresses = DNSUtil.resolveXMPPDomain(serviceName);
init(serviceName, proxy); init(serviceName, proxy);
} }
@ -203,7 +199,7 @@ public class ConnectionConfiguration implements Cloneable {
* *
* @param serviceName the XMPP domain of the target server. * @param serviceName the XMPP domain of the target server.
*/ */
public void setServiceName(String serviceName) { void setServiceName(String serviceName) {
this.serviceName = serviceName; this.serviceName = serviceName;
} }
@ -569,14 +565,17 @@ public class ConnectionConfiguration implements Cloneable {
this.resource = resource; this.resource = resource;
} }
void maybeResolveDns() throws Exception {
// Abort if we did already resolve the hosts successfully
if (hostAddresses != null)
return;
hostAddresses = DNSUtil.resolveXMPPDomain(serviceName);
}
private void initHostAddresses(String host, int port) { private void initHostAddresses(String host, int port) {
hostAddresses = new ArrayList<HostAddress>(1); hostAddresses = new ArrayList<HostAddress>(1);
HostAddress hostAddress; HostAddress hostAddress;
try { hostAddress = new HostAddress(host, port);
hostAddress = new HostAddress(host, port);
} catch (Exception e) {
throw new IllegalStateException(e);
}
hostAddresses.add(hostAddress); hostAddresses.add(hostAddress);
} }
} }

View File

@ -77,8 +77,9 @@ public class DNSUtil {
* @param domain the domain. * @param domain the domain.
* @return List of HostAddress, which encompasses the hostname and port that the * @return List of HostAddress, which encompasses the hostname and port that the
* XMPP server can be reached at for the specified domain. * XMPP server can be reached at for the specified domain.
* @throws Exception
*/ */
public static List<HostAddress> resolveXMPPDomain(final String domain) { public static List<HostAddress> resolveXMPPDomain(final String domain) throws Exception {
if (dnsResolver == null) { if (dnsResolver == null) {
List<HostAddress> addresses = new ArrayList<HostAddress>(1); List<HostAddress> addresses = new ArrayList<HostAddress>(1);
addresses.add(new HostAddress(domain, 5222)); addresses.add(new HostAddress(domain, 5222));
@ -103,8 +104,9 @@ public class DNSUtil {
* @param domain the domain. * @param domain the domain.
* @return List of HostAddress, which encompasses the hostname and port that the * @return List of HostAddress, which encompasses the hostname and port that the
* XMPP server can be reached at for the specified domain. * XMPP server can be reached at for the specified domain.
* @throws Exception
*/ */
public static List<HostAddress> resolveXMPPServerDomain(final String domain) { public static List<HostAddress> resolveXMPPServerDomain(final String domain) throws Exception {
if (dnsResolver == null) { if (dnsResolver == null) {
List<HostAddress> addresses = new ArrayList<HostAddress>(1); List<HostAddress> addresses = new ArrayList<HostAddress>(1);
addresses.add(new HostAddress(domain, 5269)); addresses.add(new HostAddress(domain, 5269));
@ -113,7 +115,7 @@ public class DNSUtil {
return resolveDomain(domain, 's'); return resolveDomain(domain, 's');
} }
private static List<HostAddress> resolveDomain(String domain, char keyPrefix) { private static List<HostAddress> resolveDomain(String domain, char keyPrefix) throws Exception {
// Prefix the key with 's' to distinguish him from the client domain lookups // Prefix the key with 's' to distinguish him from the client domain lookups
String key = keyPrefix + domain; String key = keyPrefix + domain;
// Return item from cache if it exists. // Return item from cache if it exists.

View File

@ -29,6 +29,6 @@ public interface DNSResolver {
* @param name The symbolic name of the service. * @param name The symbolic name of the service.
* @return The list of SRV records mapped to the service name. * @return The list of SRV records mapped to the service name.
*/ */
List<SRVRecord> lookupSRVRecords(String name); List<SRVRecord> lookupSRVRecords(String name) throws Exception;
} }

View File

@ -51,7 +51,7 @@ public class HostAddress {
this(fqdn); this(fqdn);
if (port < 0 || port > 65535) if (port < 0 || port > 65535)
throw new IllegalArgumentException( throw new IllegalArgumentException(
"DNS SRV records weight must be a 16-bit unsiged integer (i.e. between 0-65535. Port was: " + port); "Port must be a 16-bit unsiged integer (i.e. between 0-65535. Port was: " + port);
this.port = port; this.port = port;
} }

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2013 Florian Schmaus * Copyright 2013-2014 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ import java.util.List;
import org.xbill.DNS.Lookup; import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record; import org.xbill.DNS.Record;
import org.xbill.DNS.TextParseException;
import org.xbill.DNS.Type; import org.xbill.DNS.Type;
/** /**
@ -39,35 +40,27 @@ public class DNSJavaResolver implements DNSResolver {
} }
@Override @Override
public List<SRVRecord> lookupSRVRecords(String name) { public List<SRVRecord> lookupSRVRecords(String name) throws TextParseException {
List<SRVRecord> res = new ArrayList<SRVRecord>(); List<SRVRecord> res = new ArrayList<SRVRecord>();
try { Lookup lookup = new Lookup(name, Type.SRV);
Lookup lookup = new Lookup(name, Type.SRV); Record recs[] = lookup.run();
Record recs[] = lookup.run(); if (recs == null)
if (recs == null) return res;
return res;
for (Record record : recs) { for (Record record : recs) {
org.xbill.DNS.SRVRecord srvRecord = (org.xbill.DNS.SRVRecord) record; org.xbill.DNS.SRVRecord srvRecord = (org.xbill.DNS.SRVRecord) record;
if (srvRecord != null && srvRecord.getTarget() != null) { if (srvRecord != null && srvRecord.getTarget() != null) {
String host = srvRecord.getTarget().toString(); String host = srvRecord.getTarget().toString();
int port = srvRecord.getPort(); int port = srvRecord.getPort();
int priority = srvRecord.getPriority(); int priority = srvRecord.getPriority();
int weight = srvRecord.getWeight(); int weight = srvRecord.getWeight();
SRVRecord r; SRVRecord r = new SRVRecord(host, port, priority, weight);
try { res.add(r);
r = new SRVRecord(host, port, priority, weight);
} catch (Exception e) {
continue;
}
res.add(r);
}
} }
} catch (Exception e) {
} }
return res; return res;
} }
} }

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2013 Florian Schmaus * Copyright 2013-2014 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ import java.util.Hashtable;
import java.util.List; import java.util.List;
import javax.naming.NamingEnumeration; import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute; import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes; import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext; import javax.naming.directory.DirContext;
@ -68,32 +69,23 @@ public class JavaxResolver implements DNSResolver {
} }
@Override @Override
public List<SRVRecord> lookupSRVRecords(String name) { public List<SRVRecord> lookupSRVRecords(String name) throws NamingException {
List<SRVRecord> res = new ArrayList<SRVRecord>(); List<SRVRecord> res = new ArrayList<SRVRecord>();
try {
Attributes dnsLookup = dirContext.getAttributes(name, new String[]{"SRV"});
Attribute srvAttribute = dnsLookup.get("SRV");
@SuppressWarnings("unchecked")
NamingEnumeration<String> srvRecords = (NamingEnumeration<String>) srvAttribute.getAll();
while (srvRecords.hasMore()) {
String srvRecordString = srvRecords.next();
String[] srvRecordEntries = srvRecordString.split(" ");
int priority = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 4]);
int port = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 2]);
int weight = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 3]);
String host = srvRecordEntries[srvRecordEntries.length - 1];
SRVRecord srvRecord; Attributes dnsLookup = dirContext.getAttributes(name, new String[] { "SRV" });
try { Attribute srvAttribute = dnsLookup.get("SRV");
srvRecord = new SRVRecord(host, port, priority, weight); @SuppressWarnings("unchecked")
} catch (Exception e) { NamingEnumeration<String> srvRecords = (NamingEnumeration<String>) srvAttribute.getAll();
continue; while (srvRecords.hasMore()) {
} String srvRecordString = srvRecords.next();
res.add(srvRecord); String[] srvRecordEntries = srvRecordString.split(" ");
} int priority = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 4]);
} catch (Exception e) { int port = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 2]);
int weight = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 3]);
String host = srvRecordEntries[srvRecordEntries.length - 1];
SRVRecord srvRecord = new SRVRecord(host, port, priority, weight);
res.add(srvRecord);
} }
return res; return res;
} }

View File

@ -420,6 +420,12 @@ public class TCPConnection extends XMPPConnection {
private void connectUsingConfiguration(ConnectionConfiguration config) throws SmackException, IOException { private void connectUsingConfiguration(ConnectionConfiguration config) throws SmackException, IOException {
Exception exception = null; Exception exception = null;
try {
config.maybeResolveDns();
}
catch (Exception e) {
throw new SmackException(e);
}
Iterator<HostAddress> it = config.getHostAddresses().iterator(); Iterator<HostAddress> it = config.getHostAddresses().iterator();
List<HostAddress> failedAddresses = new LinkedList<HostAddress>(); List<HostAddress> failedAddresses = new LinkedList<HostAddress>();
while (it.hasNext()) { while (it.hasNext()) {