Search in sources :

Example 1 with SRVRecord

use of org.jivesoftware.smack.util.dns.SRVRecord 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;
}
Also used : ArrayList(java.util.ArrayList) TreeMap(java.util.TreeMap) HostAddress(org.jivesoftware.smack.util.dns.HostAddress) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) SRVRecord(org.jivesoftware.smack.util.dns.SRVRecord)

Example 2 with SRVRecord

use of org.jivesoftware.smack.util.dns.SRVRecord in project Smack by igniterealtime.

the class DNSJavaResolver method lookupSRVRecords0.

@Override
protected List<SRVRecord> lookupSRVRecords0(String name, List<HostAddress> failedAddresses, DnssecMode dnssecMode) {
    List<SRVRecord> res = new ArrayList<SRVRecord>();
    Lookup lookup;
    try {
        lookup = new Lookup(name, Type.SRV);
    } catch (TextParseException e) {
        throw new IllegalStateException(e);
    }
    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();
            List<InetAddress> hostAddresses = lookupHostAddress0(host, failedAddresses, dnssecMode);
            if (hostAddresses == null) {
                continue;
            }
            SRVRecord r = new SRVRecord(host, port, priority, weight, hostAddresses);
            res.add(r);
        }
    }
    return res;
}
Also used : ArrayList(java.util.ArrayList) Lookup(org.xbill.DNS.Lookup) SRVRecord(org.jivesoftware.smack.util.dns.SRVRecord) Record(org.xbill.DNS.Record) SRVRecord(org.jivesoftware.smack.util.dns.SRVRecord) InetAddress(java.net.InetAddress) TextParseException(org.xbill.DNS.TextParseException)

Example 3 with SRVRecord

use of org.jivesoftware.smack.util.dns.SRVRecord in project Smack by igniterealtime.

the class DNSUtil method resolveDomain.

/**
     * 
     * @param domain the domain.
     * @param domainType the XMPP domain type, server or client.
     * @param failedAddresses a list that will be populated with host addresses that failed to resolve.
     * @return a list of resolver host addresses for this domain.
     */
private static List<HostAddress> resolveDomain(String domain, DomainType domainType, List<HostAddress> failedAddresses, DnssecMode dnssecMode) {
    if (dnsResolver == null) {
        throw new IllegalStateException("No DNS Resolver active in Smack");
    }
    List<HostAddress> addresses = new ArrayList<HostAddress>();
    // Step one: Do SRV lookups
    String srvDomain;
    switch(domainType) {
        case Server:
            srvDomain = "_xmpp-server._tcp." + domain;
            break;
        case Client:
            srvDomain = "_xmpp-client._tcp." + domain;
            break;
        default:
            throw new AssertionError();
    }
    List<SRVRecord> srvRecords = dnsResolver.lookupSRVRecords(srvDomain, failedAddresses, dnssecMode);
    if (srvRecords != null && !srvRecords.isEmpty()) {
        if (LOGGER.isLoggable(Level.FINE)) {
            String logMessage = "Resolved SRV RR for " + srvDomain + ":";
            for (SRVRecord r : srvRecords) logMessage += " " + r;
            LOGGER.fine(logMessage);
        }
        List<HostAddress> sortedRecords = sortSRVRecords(srvRecords);
        addresses.addAll(sortedRecords);
    } else {
        LOGGER.info("Could not resolve DNS SRV resource records for " + srvDomain + ". Consider adding those.");
    }
    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, defaultPort, failedAddresses, dnssecMode);
    if (hostAddress != null) {
        addresses.add(hostAddress);
    }
    return addresses;
}
Also used : ArrayList(java.util.ArrayList) SRVRecord(org.jivesoftware.smack.util.dns.SRVRecord) HostAddress(org.jivesoftware.smack.util.dns.HostAddress)

Example 4 with SRVRecord

use of org.jivesoftware.smack.util.dns.SRVRecord in project Smack by igniterealtime.

the class JavaxResolver method lookupSRVRecords0.

@Override
protected List<SRVRecord> lookupSRVRecords0(String name, List<HostAddress> failedAddresses, DnssecMode dnssecMode) {
    List<SRVRecord> res = null;
    Attribute srvAttribute;
    try {
        Attributes dnsLookup = dirContext.getAttributes(name, new String[] { "SRV" });
        srvAttribute = dnsLookup.get("SRV");
        if (srvAttribute == null)
            return null;
    } catch (NameNotFoundException e) {
        LOGGER.log(Level.FINEST, "No DNS SRV RR found for " + name, e);
        return null;
    } catch (NamingException e) {
        LOGGER.log(Level.WARNING, "Exception while resolving DNS SRV RR for " + name, e);
        return null;
    }
    try {
        @SuppressWarnings("unchecked") NamingEnumeration<String> srvRecords = (NamingEnumeration<String>) srvAttribute.getAll();
        res = new ArrayList<>();
        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];
            List<InetAddress> hostAddresses = lookupHostAddress0(host, failedAddresses, dnssecMode);
            if (hostAddresses == null) {
                continue;
            }
            SRVRecord srvRecord = new SRVRecord(host, port, priority, weight, hostAddresses);
            res.add(srvRecord);
        }
    } catch (NamingException e) {
        LOGGER.log(Level.SEVERE, "Exception while resolving DNS SRV RR for" + name, e);
    }
    return res;
}
Also used : Attribute(javax.naming.directory.Attribute) NameNotFoundException(javax.naming.NameNotFoundException) Attributes(javax.naming.directory.Attributes) NamingEnumeration(javax.naming.NamingEnumeration) NamingException(javax.naming.NamingException) SRVRecord(org.jivesoftware.smack.util.dns.SRVRecord) InetAddress(java.net.InetAddress)

Example 5 with SRVRecord

use of org.jivesoftware.smack.util.dns.SRVRecord in project Smack by igniterealtime.

the class MiniDnsResolver method lookupSRVRecords0.

@Override
protected List<SRVRecord> lookupSRVRecords0(final String name, List<HostAddress> failedAddresses, DnssecMode dnssecMode) {
    final ResolverApi resolver = getResolver(dnssecMode);
    ResolverResult<SRV> result;
    try {
        result = resolver.resolve(name, SRV.class);
    } catch (IOException e) {
        failedAddresses.add(new HostAddress(name, e));
        return null;
    }
    // TODO: Use ResolverResult.getResolutionUnsuccessfulException() found in newer MiniDNS versions.
    if (!result.wasSuccessful()) {
        ResolutionUnsuccessfulException resolutionUnsuccessfulException = getExceptionFrom(result);
        failedAddresses.add(new HostAddress(name, resolutionUnsuccessfulException));
        return null;
    }
    if (shouldAbortIfNotAuthentic(name, dnssecMode, result, failedAddresses)) {
        return null;
    }
    List<SRVRecord> res = new LinkedList<SRVRecord>();
    for (SRV srv : result.getAnswers()) {
        String hostname = srv.name.ace;
        List<InetAddress> hostAddresses = lookupHostAddress0(hostname, failedAddresses, dnssecMode);
        if (hostAddresses == null) {
            continue;
        }
        SRVRecord srvRecord = new SRVRecord(hostname, srv.port, srv.priority, srv.weight, hostAddresses);
        res.add(srvRecord);
    }
    return res;
}
Also used : SRV(de.measite.minidns.record.SRV) ResolutionUnsuccessfulException(de.measite.minidns.hla.ResolutionUnsuccessfulException) ResolverApi(de.measite.minidns.hla.ResolverApi) DnssecResolverApi(de.measite.minidns.hla.DnssecResolverApi) IOException(java.io.IOException) SRVRecord(org.jivesoftware.smack.util.dns.SRVRecord) HostAddress(org.jivesoftware.smack.util.dns.HostAddress) InetAddress(java.net.InetAddress) LinkedList(java.util.LinkedList)

Aggregations

SRVRecord (org.jivesoftware.smack.util.dns.SRVRecord)6 ArrayList (java.util.ArrayList)4 InetAddress (java.net.InetAddress)3 HostAddress (org.jivesoftware.smack.util.dns.HostAddress)3 LinkedList (java.util.LinkedList)2 DnssecResolverApi (de.measite.minidns.hla.DnssecResolverApi)1 ResolutionUnsuccessfulException (de.measite.minidns.hla.ResolutionUnsuccessfulException)1 ResolverApi (de.measite.minidns.hla.ResolverApi)1 SRV (de.measite.minidns.record.SRV)1 IOException (java.io.IOException)1 List (java.util.List)1 TreeMap (java.util.TreeMap)1 NameNotFoundException (javax.naming.NameNotFoundException)1 NamingEnumeration (javax.naming.NamingEnumeration)1 NamingException (javax.naming.NamingException)1 Attribute (javax.naming.directory.Attribute)1 Attributes (javax.naming.directory.Attributes)1 Lookup (org.xbill.DNS.Lookup)1 Record (org.xbill.DNS.Record)1 TextParseException (org.xbill.DNS.TextParseException)1