aefimov-dns-client-branch: Add system property to control ANY requests aefimov-dns-client-branch
authoraefimov
Fri, 08 Nov 2019 14:54:17 +0000
branchaefimov-dns-client-branch
changeset 58984 15e026239a6c
parent 58983 956b1255a5ec
child 59099 fcdb8e7ead8f
aefimov-dns-client-branch: Add system property to control ANY requests
src/jdk.dns.client/share/classes/jdk/dns/client/NetworkNamesResolver.java
src/jdk.dns.client/share/classes/jdk/dns/client/internal/AddressResolutionQueue.java
src/jdk.dns.client/share/classes/jdk/dns/client/internal/ResourceRecords.java
--- a/src/jdk.dns.client/share/classes/jdk/dns/client/NetworkNamesResolver.java	Fri Nov 08 14:49:00 2019 +0000
+++ b/src/jdk.dns.client/share/classes/jdk/dns/client/NetworkNamesResolver.java	Fri Nov 08 14:54:17 2019 +0000
@@ -76,7 +76,7 @@
 
         // If no luck - try to ask name servers
         try (DnsResolver dnsResolver = new DnsResolver()) {
-            var results = lookup(dnsResolver, hostname, protocolFamily, true);
+            var results = lookup(dnsResolver, hostname, protocolFamily, false);
             return results.get(0);
         }
     }
@@ -101,7 +101,7 @@
         }
 
         try (var dnsResolver = new DnsResolver()) {
-            var results = lookup(dnsResolver, hostname, null, false);
+            var results = lookup(dnsResolver, hostname, null, true);
             if (results.isEmpty()) {
                 throw new UnknownHostException(hostname + " unknown host name");
             }
@@ -178,11 +178,11 @@
         return addressBuff.toString();
     }
 
-    private List<InetAddress> lookup(DnsResolver dnsResolver, String host, ProtocolFamily protocolFamily, boolean oneIsEnough) throws UnknownHostException {
+    private List<InetAddress> lookup(DnsResolver dnsResolver, String host, ProtocolFamily protocolFamily, boolean needAllAddresses) throws UnknownHostException {
         if (DEBUG) {
             System.out.printf("Resolver API: internal lookup call - %s%n", host);
         }
-        return AddressResolutionQueue.resolve(dnsResolver, host, protocolFamily, oneIsEnough);
+        return AddressResolutionQueue.resolve(dnsResolver, host, protocolFamily, needAllAddresses);
     }
 
     private static HostsFileResolver hostsFileResolver = new HostsFileResolver();
--- a/src/jdk.dns.client/share/classes/jdk/dns/client/internal/AddressResolutionQueue.java	Fri Nov 08 14:49:00 2019 +0000
+++ b/src/jdk.dns.client/share/classes/jdk/dns/client/internal/AddressResolutionQueue.java	Fri Nov 08 14:54:17 2019 +0000
@@ -89,7 +89,7 @@
             }
             InetAddress address = InetAddress.getByAddress(hostName, addrBytes);
             results.add(address);
-            if (needAllAddresses) {
+            if (!needAllAddresses) {
                 break;
             }
         }
@@ -116,7 +116,7 @@
         // Used in non-ANY mode and stores the host name that yielded some result (A or AAAA)
         String gotResultsFor = "";
         // Init queue with ANY requests first
-        isAnyMode = true;
+        isAnyMode = USE_ANY_SP_VALUE;
         fillQueue();
         List<ResolvedAddress> addresses = new ArrayList<>();
         while (true) {
@@ -144,7 +144,7 @@
             // name and only for the left addresses and no need to process CNAME requests
             if (gotResultsFor.isEmpty() || (resRequest.hostName.equals(gotResultsFor)
                     && resRequest.resourceId != ResourceRecord.TYPE_CNAME)) {
-                var result = executeRequest(resRequest);
+                var result = executeRequest(resRequest, !gotResultsFor.isEmpty());
                 addresses.addAll(result);
             }
 
@@ -175,16 +175,14 @@
         }
     }
 
-    private List<ResolvedAddress> executeRequest(ResolutionRequest request) {
+    private List<ResolvedAddress> executeRequest(ResolutionRequest request, boolean alreadyHaveResults) {
 
         try {
-            if (DEBUG) {
-                System.err.printf("Executing processing request:%s%n", request);
-            }
             var rrs = dnsResolver.query(request.hostName, request.resourceId);
             if (DEBUG) {
                 System.err.println("================DNS Resolution queue==================");
-                System.err.println("Got answers:" + rrs.answer);
+                System.err.printf("Got answers for '%s':%n", request);
+                System.err.println(rrs.answer);
                 System.err.println("======================================================");
             }
             // If no addresses or aliases - return
@@ -209,24 +207,26 @@
                         .map(ResolvedAddress::of)
                         .collect(Collectors.toList());
             }
-            // If has alias - clear the queue and add new requests withSystem.out.println("================DNS Resolution queue==================");
-            // the requested addresses
-            Optional<String> aliasO = rrs.answer.stream()
-                    .filter(rr -> rr.rrtype == ResourceRecord.TYPE_CNAME)
-                    .map(ResourceRecord::getRdata)
-                    .map(Object::toString)
-                    .findFirst();
-            if (aliasO.isPresent()) {
-                queue.clear();
-                String cname = aliasO.get();
-                if (DEBUG) {
-                    System.err.println("Found alias: " + cname);
+            // If has alias - clear the queue and add new requests with
+            // the alias name. Do it only for cases when no addresses is found
+            if (!alreadyHaveResults) {
+                Optional<String> aliasO = rrs.answer.stream()
+                        .filter(rr -> rr.rrtype == ResourceRecord.TYPE_CNAME)
+                        .map(ResourceRecord::getRdata)
+                        .map(Object::toString)
+                        .findFirst();
+                if (aliasO.isPresent()) {
+                    queue.clear();
+                    String cname = aliasO.get();
+                    if (DEBUG) {
+                        System.err.println("Found alias: " + cname);
+                    }
+                    cnameCount++;
+                    if (cnameCount > MAX_CNAME_RESOLUTION_DEPTH) {
+                        throw new RuntimeException("CNAME loop detected");
+                    }
+                    addQueriesForHostname(cname);
                 }
-                cnameCount++;
-                if (cnameCount > MAX_CNAME_RESOLUTION_DEPTH) {
-                    throw new RuntimeException("CNAME loop detected");
-                }
-                addQueriesForHostname(cname);
             }
             // Filter the results depending on typeOfAddress
             return Collections.emptyList();
@@ -305,6 +305,9 @@
     // Private resolution queue has two modes - ANY and single requests.
     // The mode in use is tracked with this boolean flag
     private boolean isAnyMode;
+    // Use any mode property value
+    private static final boolean USE_ANY_SP_VALUE = java.security.AccessController.doPrivileged(
+            (PrivilegedAction<Boolean>) () -> Boolean.getBoolean("jdk.dns.client.use.any"));
     // Maximum number of sequential CNAME requests
     private static final int MAX_CNAME_RESOLUTION_DEPTH = 4;
     // Enable debug output
--- a/src/jdk.dns.client/share/classes/jdk/dns/client/internal/ResourceRecords.java	Fri Nov 08 14:49:00 2019 +0000
+++ b/src/jdk.dns.client/share/classes/jdk/dns/client/internal/ResourceRecords.java	Fri Nov 08 14:54:17 2019 +0000
@@ -48,7 +48,6 @@
     Vector<ResourceRecord> question = new Vector<>();
     public Vector<ResourceRecord> answer = new Vector<>();
     Vector<ResourceRecord> authority = new Vector<>();
-    // TODO: Try to reuse additional section to avoid additional CNAME lookups
     public Vector<ResourceRecord> additional = new Vector<>();
 
     private boolean hasIpv4InAnswer;