From d3499405370b96a82bf81f187eb9965d5acff5c1 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 18 Mar 2014 17:29:38 +0100 Subject: [PATCH] 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. --- .../smack/ConnectionConfiguration.java | 19 ++++----- .../org/jivesoftware/smack/util/DNSUtil.java | 8 ++-- .../smack/util/dns/DNSResolver.java | 2 +- .../smack/util/dns/HostAddress.java | 2 +- .../smack/util/dns/DNSJavaResolver.java | 41 ++++++++---------- .../smack/util/dns/JavaxResolver.java | 42 ++++++++----------- .../org/jivesoftware/smack/TCPConnection.java | 6 +++ 7 files changed, 56 insertions(+), 64 deletions(-) diff --git a/core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java b/core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java index 858c751fa..ef345172c 100644 --- a/core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java +++ b/core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java @@ -102,8 +102,6 @@ public class ConnectionConfiguration implements Cloneable { * @param serviceName the name of the service provided by an XMPP server. */ public ConnectionConfiguration(String serviceName) { - // Perform DNS lookup to get host and port to use - hostAddresses = DNSUtil.resolveXMPPDomain(serviceName); init(serviceName, ProxyInfo.forDefaultProxy()); } @@ -117,8 +115,6 @@ public class ConnectionConfiguration implements Cloneable { * @param proxy the proxy through which XMPP is to be connected */ public ConnectionConfiguration(String serviceName,ProxyInfo proxy) { - // Perform DNS lookup to get host and port to use - hostAddresses = DNSUtil.resolveXMPPDomain(serviceName); init(serviceName, proxy); } @@ -203,7 +199,7 @@ public class ConnectionConfiguration implements Cloneable { * * @param serviceName the XMPP domain of the target server. */ - public void setServiceName(String serviceName) { + void setServiceName(String serviceName) { this.serviceName = serviceName; } @@ -569,14 +565,17 @@ public class ConnectionConfiguration implements Cloneable { 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) { hostAddresses = new ArrayList(1); HostAddress hostAddress; - try { - hostAddress = new HostAddress(host, port); - } catch (Exception e) { - throw new IllegalStateException(e); - } + hostAddress = new HostAddress(host, port); hostAddresses.add(hostAddress); } } diff --git a/core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java b/core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java index ea50e1f07..a3d32315a 100644 --- a/core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java +++ b/core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java @@ -77,8 +77,9 @@ public class DNSUtil { * @param domain the domain. * @return List of HostAddress, which encompasses the hostname and port that the * XMPP server can be reached at for the specified domain. + * @throws Exception */ - public static List resolveXMPPDomain(final String domain) { + public static List resolveXMPPDomain(final String domain) throws Exception { if (dnsResolver == null) { List addresses = new ArrayList(1); addresses.add(new HostAddress(domain, 5222)); @@ -103,8 +104,9 @@ public class DNSUtil { * @param domain the domain. * @return List of HostAddress, which encompasses the hostname and port that the * XMPP server can be reached at for the specified domain. + * @throws Exception */ - public static List resolveXMPPServerDomain(final String domain) { + public static List resolveXMPPServerDomain(final String domain) throws Exception { if (dnsResolver == null) { List addresses = new ArrayList(1); addresses.add(new HostAddress(domain, 5269)); @@ -113,7 +115,7 @@ public class DNSUtil { return resolveDomain(domain, 's'); } - private static List resolveDomain(String domain, char keyPrefix) { + private static List resolveDomain(String domain, char keyPrefix) throws Exception { // Prefix the key with 's' to distinguish him from the client domain lookups String key = keyPrefix + domain; // Return item from cache if it exists. diff --git a/core/src/main/java/org/jivesoftware/smack/util/dns/DNSResolver.java b/core/src/main/java/org/jivesoftware/smack/util/dns/DNSResolver.java index a6488a3bd..89f1b404a 100644 --- a/core/src/main/java/org/jivesoftware/smack/util/dns/DNSResolver.java +++ b/core/src/main/java/org/jivesoftware/smack/util/dns/DNSResolver.java @@ -29,6 +29,6 @@ public interface DNSResolver { * @param name The symbolic name of the service. * @return The list of SRV records mapped to the service name. */ - List lookupSRVRecords(String name); + List lookupSRVRecords(String name) throws Exception; } diff --git a/core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java b/core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java index b1c14e3fd..f051805c4 100644 --- a/core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java +++ b/core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java @@ -51,7 +51,7 @@ public class HostAddress { this(fqdn); if (port < 0 || port > 65535) 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; } diff --git a/resolver-dnsjava/src/main/java/org/jivesoftware/smack/util/dns/DNSJavaResolver.java b/resolver-dnsjava/src/main/java/org/jivesoftware/smack/util/dns/DNSJavaResolver.java index ef2b26944..d3d8a6859 100644 --- a/resolver-dnsjava/src/main/java/org/jivesoftware/smack/util/dns/DNSJavaResolver.java +++ b/resolver-dnsjava/src/main/java/org/jivesoftware/smack/util/dns/DNSJavaResolver.java @@ -1,6 +1,6 @@ /** * - * Copyright 2013 Florian Schmaus + * Copyright 2013-2014 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (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.Record; +import org.xbill.DNS.TextParseException; import org.xbill.DNS.Type; /** @@ -39,35 +40,27 @@ public class DNSJavaResolver implements DNSResolver { } @Override - public List lookupSRVRecords(String name) { + public List lookupSRVRecords(String name) throws TextParseException { List res = new ArrayList(); - try { - Lookup lookup = new Lookup(name, Type.SRV); - Record recs[] = lookup.run(); - if (recs == null) - return res; + Lookup lookup = new Lookup(name, Type.SRV); + Record recs[] = lookup.run(); + if (recs == null) + return res; - for (Record record : recs) { - org.xbill.DNS.SRVRecord srvRecord = (org.xbill.DNS.SRVRecord) record; - if (srvRecord != null && srvRecord.getTarget() != null) { - String host = srvRecord.getTarget().toString(); - int port = srvRecord.getPort(); - int priority = srvRecord.getPriority(); - int weight = srvRecord.getWeight(); + for (Record record : recs) { + org.xbill.DNS.SRVRecord srvRecord = (org.xbill.DNS.SRVRecord) record; + if (srvRecord != null && srvRecord.getTarget() != null) { + String host = srvRecord.getTarget().toString(); + int port = srvRecord.getPort(); + int priority = srvRecord.getPriority(); + int weight = srvRecord.getWeight(); - SRVRecord r; - try { - r = new SRVRecord(host, port, priority, weight); - } catch (Exception e) { - continue; - } - res.add(r); - } + SRVRecord r = new SRVRecord(host, port, priority, weight); + res.add(r); } - - } catch (Exception e) { } + return res; } } diff --git a/resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/JavaxResolver.java b/resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/JavaxResolver.java index 1318ed352..71a475f9c 100644 --- a/resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/JavaxResolver.java +++ b/resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/JavaxResolver.java @@ -1,6 +1,6 @@ /** * - * Copyright 2013 Florian Schmaus + * Copyright 2013-2014 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (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 javax.naming.NamingEnumeration; +import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.DirContext; @@ -68,32 +69,23 @@ public class JavaxResolver implements DNSResolver { } @Override - public List lookupSRVRecords(String name) { + public List lookupSRVRecords(String name) throws NamingException { List res = new ArrayList(); - - try { - Attributes dnsLookup = dirContext.getAttributes(name, new String[]{"SRV"}); - Attribute srvAttribute = dnsLookup.get("SRV"); - @SuppressWarnings("unchecked") - NamingEnumeration srvRecords = (NamingEnumeration) 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; - try { - srvRecord = new SRVRecord(host, port, priority, weight); - } catch (Exception e) { - continue; - } - res.add(srvRecord); - } - } catch (Exception e) { - + Attributes dnsLookup = dirContext.getAttributes(name, new String[] { "SRV" }); + Attribute srvAttribute = dnsLookup.get("SRV"); + @SuppressWarnings("unchecked") + NamingEnumeration srvRecords = (NamingEnumeration) 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 = new SRVRecord(host, port, priority, weight); + res.add(srvRecord); } return res; } diff --git a/tcp/src/main/java/org/jivesoftware/smack/TCPConnection.java b/tcp/src/main/java/org/jivesoftware/smack/TCPConnection.java index d2f4e74ee..bb261a34e 100644 --- a/tcp/src/main/java/org/jivesoftware/smack/TCPConnection.java +++ b/tcp/src/main/java/org/jivesoftware/smack/TCPConnection.java @@ -420,6 +420,12 @@ public class TCPConnection extends XMPPConnection { private void connectUsingConfiguration(ConnectionConfiguration config) throws SmackException, IOException { Exception exception = null; + try { + config.maybeResolveDns(); + } + catch (Exception e) { + throw new SmackException(e); + } Iterator it = config.getHostAddresses().iterator(); List failedAddresses = new LinkedList(); while (it.hasNext()) {