Add ConnectionConfiguration.setHostAddress(InetAddress)

In previous Smack versions, it was possible to set the host's IP
address via setHost(String), this is no longer possible (since the
support for DNSSEC was introduced). The new
setHostAddress(InetAddress) allows it again to explicitly specifiy the
XMPP service's host IP.
This commit is contained in:
Florian Schmaus 2016-12-28 23:18:28 +01:00
parent 7655ac17f2
commit 3129165a1c
5 changed files with 53 additions and 17 deletions

View File

@ -602,12 +602,17 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
*/
protected List<HostAddress> populateHostAddresses() {
List<HostAddress> 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<HostAddress>(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

View File

@ -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();
}

View File

@ -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);
}

View File

@ -47,13 +47,13 @@ public abstract class DNSResolver {
protected abstract List<SRVRecord> lookupSRVRecords0(String name, List<HostAddress> failedAddresses, DnssecMode dnssecMode);
public final HostAddress lookupHostAddress(String name, List<HostAddress> failedAddresses, DnssecMode dnssecMode) {
public final HostAddress lookupHostAddress(String name, int port, List<HostAddress> failedAddresses, DnssecMode dnssecMode) {
checkIfDnssecRequestedAndSupported(dnssecMode);
List<InetAddress> inetAddresses = lookupHostAddress0(name, failedAddresses, dnssecMode);
if (inetAddresses == null) {
return null;
}
return new HostAddress(name, inetAddresses);
return new HostAddress(name, port, inetAddresses);
}
protected List<InetAddress> lookupHostAddress0(String name, List<HostAddress> failedAddresses, DnssecMode dnssecMode) {

View File

@ -33,17 +33,6 @@ public class HostAddress {
private final Map<InetAddress, Exception> exceptions = new LinkedHashMap<>();
private final List<InetAddress> 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<InetAddress> 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.