Search in sources :

Example 1 with SRV

use of org.minidns.record.SRV in project minidns by MiniDNS.

the class SrvUtil method sortSrvRecords.

/**
 * Sort the given collection of {@link SRV} resource records by their priority and weight.
 * <p>
 * Sorting by priority is easy. Sorting the buckets of SRV records with the same priority by weight requires to choose those records
 * randomly but taking the weight into account.
 * </p>
 *
 * @param srvRecords
 *            a collection of SRV records.
 * @return a sorted list of the given records.
 */
public static List<SRV> sortSrvRecords(Collection<SRV> srvRecords) {
    // (the root domain), abort."
    if (srvRecords.size() == 1 && srvRecords.iterator().next().target.equals(DNSName.ROOT)) {
        return Collections.emptyList();
    }
    // Create the priority buckets.
    SortedMap<Integer, List<SRV>> buckets = new TreeMap<>();
    for (SRV srvRecord : srvRecords) {
        Integer priority = srvRecord.priority;
        List<SRV> bucket = buckets.get(priority);
        if (bucket == null) {
            bucket = new LinkedList<>();
            buckets.put(priority, bucket);
        }
        bucket.add(srvRecord);
    }
    List<SRV> sortedSrvRecords = new ArrayList<>(srvRecords.size());
    for (List<SRV> bucket : buckets.values()) {
        // The list of buckets will be sorted by priority, thanks to SortedMap. We now have determine the order of
        // the SRV records with the same priority, i.e., within the same bucket, by their weight. This is done by
        // creating an array 'totals' which reflects the percentage of the SRV RRs weight by the total weight of all
        // SRV RRs in the bucket. For every entry in the bucket, we choose one using a random number and the sum of
        // all weights left in the bucket. We then select RRs position based on the according index of the selected
        // value in the 'total' array. This ensures that its weight is taken into account.
        int bucketSize;
        while ((bucketSize = bucket.size()) > 0) {
            int[] totals = new int[bucketSize];
            int zeroWeight = 1;
            for (SRV srv : bucket) {
                if (srv.weight > 0) {
                    zeroWeight = 0;
                    break;
                }
            }
            int bucketWeightSum = 0, count = 0;
            for (SRV srv : bucket) {
                bucketWeightSum += (srv.weight + zeroWeight);
                totals[count++] = bucketWeightSum;
            }
            int selectedPosition;
            if (bucketWeightSum == 0) {
                // If total priority is 0, then the sum of all weights in this priority bucket is 0. So we simply
                // select one of the weights randomly as the other algorithm performed in the else block is unable
                // to handle this case.
                selectedPosition = (int) (Math.random() * bucketSize);
            } else {
                double rnd = Math.random() * bucketWeightSum;
                selectedPosition = bisect(totals, rnd);
            }
            SRV choosenSrvRecord = bucket.remove(selectedPosition);
            sortedSrvRecords.add(choosenSrvRecord);
        }
    }
    return sortedSrvRecords;
}
Also used : SRV(org.minidns.record.SRV) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) ArrayList(java.util.ArrayList) TreeMap(java.util.TreeMap)

Example 2 with SRV

use of org.minidns.record.SRV in project minidns by MiniDNS.

the class SrvUtilTest method createSRVRecords.

private static List<SRV> createSRVRecords() {
    List<SRV> records = new ArrayList<>();
    // We create one record with priority 0 that should also be tried first
    // Then 4 records with priority 5 and different weights (50, 20, 20, 10)
    // Then 2 records with priority 10 and weight 0 which should be treated equal
    // These records are added in a 'random' way to the list
    // Priority 5, Weight 20
    records.add(new SRV(5, 20, 42, "5.20.one.foo.bar"));
    // Priority 10, Weight 0
    records.add(new SRV(10, 0, 42, "10.0.one.foo.bar"));
    // Priority 5, Weight 10
    records.add(new SRV(5, 10, 42, "5.10.foo.bar"));
    // Priority 10, Weight 0
    records.add(new SRV(10, 0, 42, "10.0.two.foo.bar"));
    // Priority 5, Weight 20
    records.add(new SRV(5, 20, 42, "5.20.two.foo.bar"));
    // Priority 0, Weight 20
    records.add(new SRV(0, 20, 42, "0.20.foo.bar"));
    // Priority 5, Weight 50
    records.add(new SRV(5, 50, 42, "5.50.foo.bar"));
    return records;
}
Also used : SRV(org.minidns.record.SRV) ArrayList(java.util.ArrayList)

Example 3 with SRV

use of org.minidns.record.SRV in project minidns by MiniDNS.

the class HlaTest method idnSrvTest.

@IntegrationTest
public static void idnSrvTest() throws IOException {
    ResolverResult<SRV> res = ResolverApi.INSTANCE.resolve("_xmpp-client._tcp.im.plä.net", SRV.class);
    Set<SRV> answers = res.getAnswers();
    assertEquals(1, answers.size());
    SRV srv = answers.iterator().next();
    ResolverResult<A> aRes = ResolverApi.INSTANCE.resolve(srv.target, A.class);
    assertTrue(aRes.wasSuccessful());
}
Also used : A(org.minidns.record.A) SRV(org.minidns.record.SRV)

Example 4 with SRV

use of org.minidns.record.SRV in project minidns by MiniDNS.

the class DNSMessageTest method testSRVLookup.

@Test
public void testSRVLookup() throws Exception {
    DNSMessage m = getMessageFromResource("gpn-srv");
    assertFalse(m.authoritativeAnswer);
    List<Record<? extends Data>> answers = m.answerSection;
    assertEquals(1, answers.size());
    Record<? extends Data> answer = answers.get(0);
    assertTrue(answer.getPayload() instanceof SRV);
    assertEquals(TYPE.SRV, answer.getPayload().getType());
    SRV r = (SRV) (answer.getPayload());
    assertCsEquals("raven.toroid.org", r.target);
    assertEquals(5222, r.port);
    assertEquals(0, r.priority);
}
Also used : SRV(org.minidns.record.SRV) Record(org.minidns.record.Record) Data(org.minidns.record.Data) DNSMessage(org.minidns.dnsmessage.DNSMessage) Test(org.junit.Test)

Example 5 with SRV

use of org.minidns.record.SRV in project minidns by MiniDNS.

the class SrvResolverResult method getSortedSrvResolvedAddresses.

public List<ResolvedSrvRecord> getSortedSrvResolvedAddresses() throws IOException {
    if (sortedSrvResolvedAddresses != null) {
        return sortedSrvResolvedAddresses;
    }
    throwIseIfErrorResponse();
    List<SRV> srvRecords = SrvUtil.sortSrvRecords(getAnswers());
    List<ResolvedSrvRecord> res = new ArrayList<>(srvRecords.size());
    for (SRV srvRecord : srvRecords) {
        ResolverResult<A> aRecordsResult = null;
        ResolverResult<AAAA> aaaaRecordsResult = null;
        Set<A> aRecords = Collections.emptySet();
        if (ipVersion.v4) {
            aRecordsResult = resolver.resolve(srvRecord.target, A.class);
            if (aRecordsResult.wasSuccessful() && !aRecordsResult.hasUnverifiedReasons()) {
                aRecords = aRecordsResult.getAnswers();
            }
        }
        Set<AAAA> aaaaRecords = Collections.emptySet();
        if (ipVersion.v6) {
            aaaaRecordsResult = resolver.resolve(srvRecord.target, AAAA.class);
            if (aaaaRecordsResult.wasSuccessful() && !aaaaRecordsResult.hasUnverifiedReasons()) {
                aaaaRecords = aaaaRecordsResult.getAnswers();
            }
        }
        if (aRecords.isEmpty() && aaaaRecords.isEmpty()) {
            /*
                ResolverResult<CNAME> cnameRecordResult = resolve(srvRecord.name, CNAME.class);
                if (cnameRecordResult.wasSuccessful()) {
                }
                */
            continue;
        }
        List<InternetAddressRR> srvAddresses = new ArrayList<>(aRecords.size() + aaaaRecords.size());
        switch(ipVersion) {
            case v4only:
                for (A a : aRecords) {
                    srvAddresses.add(a);
                }
                break;
            case v6only:
                for (AAAA aaaa : aaaaRecords) {
                    srvAddresses.add(aaaa);
                }
                break;
            case v4v6:
                for (A a : aRecords) {
                    srvAddresses.add(a);
                }
                for (AAAA aaaa : aaaaRecords) {
                    srvAddresses.add(aaaa);
                }
                break;
            case v6v4:
                for (AAAA aaaa : aaaaRecords) {
                    srvAddresses.add(aaaa);
                }
                for (A a : aRecords) {
                    srvAddresses.add(a);
                }
                break;
        }
        ResolvedSrvRecord resolvedSrvAddresses = new ResolvedSrvRecord(question.name, srvRecord, srvAddresses, aRecordsResult, aaaaRecordsResult);
        res.add(resolvedSrvAddresses);
    }
    sortedSrvResolvedAddresses = res;
    return res;
}
Also used : AAAA(org.minidns.record.AAAA) A(org.minidns.record.A) ArrayList(java.util.ArrayList) SRV(org.minidns.record.SRV) AAAA(org.minidns.record.AAAA) InternetAddressRR(org.minidns.record.InternetAddressRR)

Aggregations

SRV (org.minidns.record.SRV)8 ArrayList (java.util.ArrayList)6 RemoteConnectionEndpointLookupFailure (org.jivesoftware.smack.util.rce.RemoteConnectionEndpointLookupFailure)2 DnsName (org.minidns.dnsname.DnsName)2 A (org.minidns.record.A)2 InternetAddressRR (org.minidns.record.InternetAddressRR)2 InetAddress (java.net.InetAddress)1 LinkedList (java.util.LinkedList)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 UInt16 (org.jivesoftware.smack.datatypes.UInt16)1 Test (org.junit.Test)1 DNSMessage (org.minidns.dnsmessage.DNSMessage)1 AAAA (org.minidns.record.AAAA)1 Data (org.minidns.record.Data)1