2013-03-18 09:53:11 +01:00
|
|
|
/**
|
2014-02-17 18:57:38 +01:00
|
|
|
*
|
2018-04-24 21:41:31 +02:00
|
|
|
* Copyright © 2013-2018 Florian Schmaus
|
2013-03-18 09:53:11 +01:00
|
|
|
*
|
2014-02-17 18:57:38 +01:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
2013-03-18 09:53:11 +01:00
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
package org.jivesoftware.smack.util.dns;
|
|
|
|
|
2016-01-07 19:22:03 +01:00
|
|
|
import java.net.InetAddress;
|
2019-02-04 08:59:39 +01:00
|
|
|
import java.net.InetSocketAddress;
|
2016-01-07 19:22:03 +01:00
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.LinkedHashMap;
|
2016-10-31 10:45:38 +01:00
|
|
|
import java.util.List;
|
2016-01-07 19:22:03 +01:00
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Map.Entry;
|
|
|
|
|
2014-06-17 11:00:05 +02:00
|
|
|
import org.jivesoftware.smack.SmackException.ConnectionException;
|
2018-04-24 21:41:31 +02:00
|
|
|
|
2018-05-05 10:24:45 +02:00
|
|
|
import org.minidns.dnsname.DnsName;
|
2014-06-17 11:00:05 +02:00
|
|
|
|
2013-03-18 09:53:11 +01:00
|
|
|
public class HostAddress {
|
2018-05-05 10:24:45 +02:00
|
|
|
private final DnsName fqdn;
|
2014-06-17 10:52:49 +02:00
|
|
|
private final int port;
|
2016-01-07 19:22:03 +01:00
|
|
|
private final Map<InetAddress, Exception> exceptions = new LinkedHashMap<>();
|
2016-10-31 10:45:38 +01:00
|
|
|
private final List<InetAddress> inetAddresses;
|
2013-03-18 09:53:11 +01:00
|
|
|
|
2013-04-01 15:40:02 +02:00
|
|
|
/**
|
2017-01-04 15:35:47 +01:00
|
|
|
* Creates a new HostAddress with the given FQDN.
|
2018-05-09 23:06:12 +02:00
|
|
|
*
|
2017-01-04 15:35:47 +01:00
|
|
|
* @param fqdn the optional fully qualified domain name (FQDN).
|
2013-04-01 15:40:02 +02:00
|
|
|
* @param port The port to connect on.
|
2017-12-23 20:21:19 +01:00
|
|
|
* @param inetAddresses list of addresses.
|
2017-01-04 15:35:47 +01:00
|
|
|
* @throws IllegalArgumentException If the port is out of valid range (0 - 65535).
|
2013-04-01 15:40:02 +02:00
|
|
|
*/
|
2018-05-05 10:24:45 +02:00
|
|
|
public HostAddress(DnsName fqdn, int port, List<InetAddress> inetAddresses) {
|
2013-03-18 09:53:11 +01:00
|
|
|
if (port < 0 || port > 65535)
|
|
|
|
throw new IllegalArgumentException(
|
2017-12-13 23:10:11 +01:00
|
|
|
"Port must be a 16-bit unsigned integer (i.e. between 0-65535. Port was: " + port);
|
2018-04-24 21:41:31 +02:00
|
|
|
this.fqdn = fqdn;
|
2013-03-18 09:53:11 +01:00
|
|
|
this.port = port;
|
2016-10-31 10:45:38 +01:00
|
|
|
if (inetAddresses.isEmpty()) {
|
|
|
|
throw new IllegalArgumentException("Must provide at least one InetAddress");
|
|
|
|
}
|
|
|
|
this.inetAddresses = inetAddresses;
|
|
|
|
}
|
|
|
|
|
2016-12-28 23:18:28 +01:00
|
|
|
public HostAddress(int port, InetAddress hostAddress) {
|
2017-01-04 15:35:47 +01:00
|
|
|
this(null, port, Collections.singletonList(hostAddress));
|
2016-12-28 23:18:28 +01:00
|
|
|
}
|
|
|
|
|
2016-10-31 10:45:38 +01:00
|
|
|
/**
|
|
|
|
* Constructs a new failed HostAddress. This constructor is usually used when the DNS resolution of the domain name
|
|
|
|
* failed for some reason.
|
|
|
|
*
|
|
|
|
* @param fqdn the domain name of the host.
|
|
|
|
* @param e the exception causing the failure.
|
|
|
|
*/
|
2018-05-05 10:24:45 +02:00
|
|
|
public HostAddress(DnsName fqdn, Exception e) {
|
2016-10-31 10:45:38 +01:00
|
|
|
this.fqdn = fqdn;
|
|
|
|
this.port = 5222;
|
|
|
|
inetAddresses = Collections.emptyList();
|
|
|
|
setException(e);
|
2013-03-18 09:53:11 +01:00
|
|
|
}
|
|
|
|
|
2019-02-04 08:59:39 +01:00
|
|
|
public HostAddress(InetSocketAddress inetSocketAddress, Exception exception) {
|
|
|
|
String hostString = inetSocketAddress.getHostString();
|
|
|
|
this.fqdn = DnsName.from(hostString);
|
|
|
|
this.port = inetSocketAddress.getPort();
|
|
|
|
inetAddresses = Collections.emptyList();
|
|
|
|
setException(exception);
|
|
|
|
}
|
|
|
|
|
2017-07-02 18:09:15 +02:00
|
|
|
public String getHost() {
|
|
|
|
if (fqdn != null) {
|
2018-04-24 21:41:31 +02:00
|
|
|
return fqdn.toString();
|
2017-07-02 18:09:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// In this case, the HostAddress(int, InetAddress) constructor must been used. We have no FQDN. And
|
|
|
|
// inetAddresses.size() must be exactly one.
|
|
|
|
assert inetAddresses.size() == 1;
|
|
|
|
return inetAddresses.get(0).getHostAddress();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the fully qualified domain name. This may return <code>null</code> in case there host address is only numeric, i.e. an IP address.
|
|
|
|
*
|
|
|
|
* @return the fully qualified domain name or <code>null</code>
|
|
|
|
*/
|
2018-05-05 10:24:45 +02:00
|
|
|
public DnsName getFQDN() {
|
2013-03-18 09:53:11 +01:00
|
|
|
return fqdn;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getPort() {
|
|
|
|
return port;
|
|
|
|
}
|
|
|
|
|
2016-01-07 19:22:03 +01:00
|
|
|
public void setException(Exception exception) {
|
|
|
|
setException(null, exception);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setException(InetAddress inetAddress, Exception exception) {
|
|
|
|
Exception old = exceptions.put(inetAddress, exception);
|
2017-05-23 16:45:04 +02:00
|
|
|
assert (old == null);
|
2013-03-18 09:53:11 +01:00
|
|
|
}
|
|
|
|
|
2014-06-17 11:00:05 +02:00
|
|
|
/**
|
|
|
|
* Retrieve the Exception that caused a connection failure to this HostAddress. Every
|
|
|
|
* HostAddress found in {@link ConnectionException} will have an Exception set,
|
|
|
|
* which can be retrieved with this method.
|
2018-05-09 23:06:12 +02:00
|
|
|
*
|
2014-06-17 11:00:05 +02:00
|
|
|
* @return the Exception causing this HostAddress to fail
|
|
|
|
*/
|
2016-01-07 19:22:03 +01:00
|
|
|
public Map<InetAddress, Exception> getExceptions() {
|
|
|
|
return Collections.unmodifiableMap(exceptions);
|
2014-06-17 10:52:49 +02:00
|
|
|
}
|
|
|
|
|
2016-10-31 10:45:38 +01:00
|
|
|
public List<InetAddress> getInetAddresses() {
|
|
|
|
return Collections.unmodifiableList(inetAddresses);
|
|
|
|
}
|
|
|
|
|
2013-04-01 15:40:02 +02:00
|
|
|
@Override
|
2013-03-18 09:53:11 +01:00
|
|
|
public String toString() {
|
2017-07-02 18:09:15 +02:00
|
|
|
return getHost() + ":" + port;
|
2013-03-18 09:53:11 +01:00
|
|
|
}
|
|
|
|
|
2013-04-01 15:40:02 +02:00
|
|
|
@Override
|
2013-03-18 09:53:11 +01:00
|
|
|
public boolean equals(Object o) {
|
|
|
|
if (this == o) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (!(o instanceof HostAddress)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
final HostAddress address = (HostAddress) o;
|
|
|
|
|
2017-07-02 18:09:15 +02:00
|
|
|
if (!getHost().equals(address.getHost())) {
|
2013-03-18 09:53:11 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return port == address.port;
|
|
|
|
}
|
|
|
|
|
2013-04-01 15:40:02 +02:00
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
int result = 1;
|
2017-07-02 18:09:15 +02:00
|
|
|
result = 37 * result + getHost().hashCode();
|
2013-04-01 15:40:02 +02:00
|
|
|
return result * 37 + port;
|
|
|
|
}
|
|
|
|
|
2013-03-18 09:53:11 +01:00
|
|
|
public String getErrorMessage() {
|
2016-01-07 19:22:03 +01:00
|
|
|
if (exceptions.isEmpty()) {
|
2015-01-18 18:57:08 +01:00
|
|
|
return "No error logged";
|
2013-03-18 09:53:11 +01:00
|
|
|
}
|
2016-01-07 19:22:03 +01:00
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append('\'').append(toString()).append("' failed because: ");
|
|
|
|
Iterator<Entry<InetAddress, Exception>> iterator = exceptions.entrySet().iterator();
|
|
|
|
while (iterator.hasNext()) {
|
|
|
|
Entry<InetAddress, Exception> entry = iterator.next();
|
|
|
|
InetAddress inetAddress = entry.getKey();
|
|
|
|
if (inetAddress != null) {
|
|
|
|
sb.append(entry.getKey()).append(" exception: ");
|
|
|
|
}
|
|
|
|
sb.append(entry.getValue());
|
|
|
|
if (iterator.hasNext()) {
|
|
|
|
sb.append(", ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return sb.toString();
|
2013-03-18 09:53:11 +01:00
|
|
|
}
|
|
|
|
}
|