diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java index 6f6237d12..c934037b4 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -602,12 +602,17 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { */ protected List populateHostAddresses() { List failedAddresses = new LinkedList<>(); - // N.B.: Important to use config.serviceName and not AbstractXMPPConnection.serviceName - if (config.host != null) { + if (config.hostAddress != null) { + hostAddresses = new ArrayList<>(1); + HostAddress hostAddress = new HostAddress(config.port, config.hostAddress); + hostAddresses.add(hostAddress); + } + else if (config.host != null) { hostAddresses = new ArrayList(1); - HostAddress hostAddress = DNSUtil.getDNSResolver().lookupHostAddress(config.host, failedAddresses, config.getDnssecMode()); + HostAddress hostAddress = DNSUtil.getDNSResolver().lookupHostAddress(config.host, config.port, failedAddresses, config.getDnssecMode()); hostAddresses.add(hostAddress); } else { + // N.B.: Important to use config.serviceName and not AbstractXMPPConnection.serviceName hostAddresses = DNSUtil.resolveXMPPServiceDomain(config.getXMPPServiceDomain().toString(), failedAddresses, config.getDnssecMode()); } // If we reach this, then hostAddresses *must not* be empty, i.e. there is at least one host added, either the diff --git a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java index b41ab46b0..79ef71e67 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java @@ -17,6 +17,7 @@ package org.jivesoftware.smack; +import java.net.InetAddress; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -62,6 +63,7 @@ public abstract class ConnectionConfiguration { */ protected final DomainBareJid xmppServiceDomain; + protected final InetAddress hostAddress; protected final String host; protected final int port; @@ -134,6 +136,7 @@ public abstract class ConnectionConfiguration { if (xmppServiceDomain == null) { throw new IllegalArgumentException("Must define the XMPP domain"); } + hostAddress = builder.hostAddress; host = builder.host; port = builder.port; @@ -509,6 +512,7 @@ public abstract class ConnectionConfiguration { private boolean debuggerEnabled = SmackConfiguration.DEBUG; private SocketFactory socketFactory; private DomainBareJid xmppServiceDomain; + private InetAddress hostAddress; private String host; private int port = 5222; private boolean allowEmptyOrNullUsername = false; @@ -599,12 +603,37 @@ public abstract class ConnectionConfiguration { return setResource(Resourcepart.from(resource.toString())); } + /** + * Set the Internet address of the host providing the XMPP service. If set, then this will overwrite anything + * set via {@link #setHost(String)}. + * + * @param address the Internet address of the host providing the XMPP service. + * @return a reference to this builder. + * @since 4.2 + */ + public B setHostAddress(InetAddress address) { + this.hostAddress = address; + return getThis(); + } + + /** + * Set the name of the host providing the XMPP service. Note that this method does only allow DNS names and not + * IP addresses. Use {@link #setHostAddress(InetAddress)} if you want to explicitly set the Internet address of + * the host providing the XMPP service. + * + * @param host the DNS name of the host providing the XMPP service. + * @return a reference to this builder. + */ public B setHost(String host) { this.host = host; return getThis(); } public B setPort(int port) { + if (port < 0 || port > 65535) { + throw new IllegalArgumentException( + "Port must be a 16-bit unsiged integer (i.e. between 0-65535. Port was: " + port); + } this.port = port; return getThis(); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java index 391e03034..17ed2a46b 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java @@ -196,8 +196,17 @@ public class DNSUtil { addresses.addAll(sortedRecords); } + int defaultPort = -1; + switch (domainType) { + case Client: + defaultPort = 5222; + break; + case Server: + defaultPort = 5269; + break; + } // Step two: Add the hostname to the end of the list - HostAddress hostAddress = dnsResolver.lookupHostAddress(domain, failedAddresses, dnssecMode); + HostAddress hostAddress = dnsResolver.lookupHostAddress(domain, defaultPort, failedAddresses, dnssecMode); if (hostAddress != null) { addresses.add(hostAddress); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/dns/DNSResolver.java b/smack-core/src/main/java/org/jivesoftware/smack/util/dns/DNSResolver.java index 052795bda..dde188959 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/dns/DNSResolver.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/dns/DNSResolver.java @@ -47,13 +47,13 @@ public abstract class DNSResolver { protected abstract List lookupSRVRecords0(String name, List failedAddresses, DnssecMode dnssecMode); - public final HostAddress lookupHostAddress(String name, List failedAddresses, DnssecMode dnssecMode) { + public final HostAddress lookupHostAddress(String name, int port, List failedAddresses, DnssecMode dnssecMode) { checkIfDnssecRequestedAndSupported(dnssecMode); List inetAddresses = lookupHostAddress0(name, failedAddresses, dnssecMode); if (inetAddresses == null) { return null; } - return new HostAddress(name, inetAddresses); + return new HostAddress(name, port, inetAddresses); } protected List lookupHostAddress0(String name, List failedAddresses, DnssecMode dnssecMode) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java b/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java index e9ae53717..e0eb98aed 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java @@ -33,17 +33,6 @@ public class HostAddress { private final Map exceptions = new LinkedHashMap<>(); private final List inetAddresses; - /** - * Creates a new HostAddress with the given FQDN. The port will be set to the default XMPP client port: 5222 - * - * @param fqdn Fully qualified domain name. - * @throws IllegalArgumentException If the fqdn is null. - */ - public HostAddress(String fqdn, List inetAddresses) { - // Set port to the default port for XMPP client communication - this(fqdn, 5222, inetAddresses); - } - /** * Creates a new HostAddress with the given FQDN. The port will be set to the default XMPP client port: 5222 * @@ -69,6 +58,10 @@ public class HostAddress { this.inetAddresses = inetAddresses; } + public HostAddress(int port, InetAddress hostAddress) { + this("", port, Collections.singletonList(hostAddress)); + } + /** * Constructs a new failed HostAddress. This constructor is usually used when the DNS resolution of the domain name * failed for some reason.