use of org.jivesoftware.smack.util.dns.HostAddress in project Smack by igniterealtime.
the class DNSUtil method sortSRVRecords.
/**
* Sort a given list of SRVRecords as described in RFC 2782
* Note that we follow the RFC with one exception. In a group of the same priority, only the first entry
* is calculated by random. The others are ore simply ordered by their priority.
*
* @param records
* @return the list of resolved HostAddresses
*/
private static List<HostAddress> sortSRVRecords(List<SRVRecord> records) {
// (the root domain), abort."
if (records.size() == 1 && records.get(0).getFQDN().equals("."))
return Collections.emptyList();
// sorting the records improves the performance of the bisection later
Collections.sort(records);
// create the priority buckets
SortedMap<Integer, List<SRVRecord>> buckets = new TreeMap<Integer, List<SRVRecord>>();
for (SRVRecord r : records) {
Integer priority = r.getPriority();
List<SRVRecord> bucket = buckets.get(priority);
// create the list of SRVRecords if it doesn't exist
if (bucket == null) {
bucket = new LinkedList<SRVRecord>();
buckets.put(priority, bucket);
}
bucket.add(r);
}
List<HostAddress> res = new ArrayList<HostAddress>(records.size());
for (Integer priority : buckets.keySet()) {
List<SRVRecord> bucket = buckets.get(priority);
int bucketSize;
while ((bucketSize = bucket.size()) > 0) {
int[] totals = new int[bucketSize];
int running_total = 0;
int count = 0;
int zeroWeight = 1;
for (SRVRecord r : bucket) {
if (r.getWeight() > 0) {
zeroWeight = 0;
break;
}
}
for (SRVRecord r : bucket) {
running_total += (r.getWeight() + zeroWeight);
totals[count] = running_total;
count++;
}
int selectedPos;
if (running_total == 0) {
// If running total is 0, then all weights in this priority
// group are 0. So we simply select one of the weights randomly
// as the other 'normal' algorithm is unable to handle this case
selectedPos = (int) (Math.random() * bucketSize);
} else {
double rnd = Math.random() * running_total;
selectedPos = bisect(totals, rnd);
}
// add the SRVRecord that was randomly chosen on it's weight
// to the start of the result list
SRVRecord chosenSRVRecord = bucket.remove(selectedPos);
res.add(chosenSRVRecord);
}
}
return res;
}
use of org.jivesoftware.smack.util.dns.HostAddress in project Smack by igniterealtime.
the class SmackExceptionTest method testConnectionException.
@Test
public void testConnectionException() throws UnknownHostException {
List<HostAddress> failedAddresses = new LinkedList<HostAddress>();
String host = "foo.bar.example";
InetAddress inetAddress = InetAddress.getByAddress(host, new byte[] { 0, 0, 0, 0 });
List<InetAddress> inetAddresses = Collections.singletonList(inetAddress);
HostAddress hostAddress = new HostAddress(host, 1234, inetAddresses);
hostAddress.setException(new Exception("Failed for some reason"));
failedAddresses.add(hostAddress);
host = "barz.example";
inetAddress = InetAddress.getByAddress(host, new byte[] { 0, 0, 0, 0 });
inetAddresses = Collections.singletonList(inetAddress);
hostAddress = new HostAddress(host, 5678, inetAddresses);
hostAddress.setException(new Exception("Failed for some other reason"));
failedAddresses.add(hostAddress);
ConnectionException connectionException = ConnectionException.from(failedAddresses);
String message = connectionException.getMessage();
assertEquals("The following addresses failed: 'foo.bar.example:1234' failed because: java.lang.Exception: Failed for some reason, 'barz.example:5678' failed because: java.lang.Exception: Failed for some other reason", message);
}
use of org.jivesoftware.smack.util.dns.HostAddress in project Smack by igniterealtime.
the class MiniDnsResolver method lookupHostAddress0.
@Override
protected List<InetAddress> lookupHostAddress0(final String name, List<HostAddress> failedAddresses, DnssecMode dnssecMode) {
final ResolverApi resolver = getResolver(dnssecMode);
final ResolverResult<A> aResult;
final ResolverResult<AAAA> aaaaResult;
try {
aResult = resolver.resolve(name, A.class);
aaaaResult = resolver.resolve(name, AAAA.class);
} catch (IOException e) {
failedAddresses.add(new HostAddress(name, e));
return null;
}
if (!aResult.wasSuccessful() && !aaaaResult.wasSuccessful()) {
// Both results where not successful.
failedAddresses.add(new HostAddress(name, getExceptionFrom(aResult)));
failedAddresses.add(new HostAddress(name, getExceptionFrom(aaaaResult)));
return null;
}
if (shouldAbortIfNotAuthentic(name, dnssecMode, aResult, failedAddresses) || shouldAbortIfNotAuthentic(name, dnssecMode, aaaaResult, failedAddresses)) {
return null;
}
// TODO: Use ResolverResult.getAnswersOrEmptySet() once we updated MiniDNS.
Set<A> aResults;
if (aResult.wasSuccessful()) {
aResults = aResult.getAnswers();
} else {
aResults = Collections.emptySet();
}
// TODO: Use ResolverResult.getAnswersOrEmptySet() once we updated MiniDNS.
Set<AAAA> aaaaResults;
if (aaaaResult.wasSuccessful()) {
aaaaResults = aaaaResult.getAnswers();
} else {
aaaaResults = Collections.emptySet();
}
List<InetAddress> inetAddresses = new ArrayList<>(aResults.size() + aaaaResults.size());
for (A a : aResults) {
InetAddress inetAddress;
try {
inetAddress = InetAddress.getByAddress(a.getIp());
} catch (UnknownHostException e) {
continue;
}
inetAddresses.add(inetAddress);
}
for (AAAA aaaa : aaaaResults) {
InetAddress inetAddress;
try {
inetAddress = InetAddress.getByAddress(name, aaaa.getIp());
} catch (UnknownHostException e) {
continue;
}
inetAddresses.add(inetAddress);
}
return inetAddresses;
}
use of org.jivesoftware.smack.util.dns.HostAddress in project Smack by igniterealtime.
the class AbstractXMPPConnection method populateHostAddresses.
/**
* Populates {@link #hostAddresses} with the resolved addresses or with the configured host address. If no host
* address was configured and all lookups failed, for example with NX_DOMAIN, then {@link #hostAddresses} will be
* populated with the empty list.
*
* @return a list of host addresses where DNS (SRV) RR resolution failed.
*/
protected List<HostAddress> populateHostAddresses() {
List<HostAddress> failedAddresses = new LinkedList<>();
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, config.port, failedAddresses, config.getDnssecMode());
if (hostAddress != null) {
hostAddresses.add(hostAddress);
}
} else {
// N.B.: Important to use config.serviceName and not AbstractXMPPConnection.serviceName
hostAddresses = DNSUtil.resolveXMPPServiceDomain(config.getXMPPServiceDomain().toString(), failedAddresses, config.getDnssecMode());
}
// Either the populated host addresses are not empty *or* there must be at least one failed address.
assert (!hostAddresses.isEmpty() || !failedAddresses.isEmpty());
return failedAddresses;
}
use of org.jivesoftware.smack.util.dns.HostAddress in project Smack by igniterealtime.
the class DNSUtilTest method xmppClientDomainTest.
private void xmppClientDomainTest() {
List<HostAddress> hostAddresses = DNSUtil.resolveXMPPServiceDomain(igniterealtimeDomain);
HostAddress ha = hostAddresses.get(0);
assertEquals(ha.getFQDN(), igniterealtimeXMPPServer);
assertEquals(ha.getPort(), igniterealtimeClientPort);
}
Aggregations