aefimov-dns-client-branch: Fix timeouts, add platform specific file locations aefimov-dns-client-branch
authoraefimov
Thu, 14 Nov 2019 23:16:40 +0000
branchaefimov-dns-client-branch
changeset 59101 258033faefc9
parent 59100 b92aac38b046
aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
src/jdk.dns.client/share/classes/jdk/dns/client/NetworkNamesResolver.java
src/jdk.dns.client/share/classes/jdk/dns/client/internal/DnsClient.java
src/jdk.dns.client/share/classes/jdk/dns/client/internal/HostsFileResolver.java
src/jdk.dns.client/share/classes/jdk/dns/client/internal/util/ReloadTracker.java
src/jdk.dns.client/unix/classes/jdk/dns/conf/DnsResolverConfiguration.java
--- a/src/jdk.dns.client/share/classes/jdk/dns/client/NetworkNamesResolver.java	Thu Nov 14 23:13:47 2019 +0000
+++ b/src/jdk.dns.client/share/classes/jdk/dns/client/NetworkNamesResolver.java	Thu Nov 14 23:16:40 2019 +0000
@@ -131,6 +131,9 @@
     public List<String> getAllHostsByAddr(InetAddress address) throws UnknownHostException {
         // First try hosts file
         // TODO: Add nsswitch.conf to select proper order
+        if (DEBUG) {
+            System.err.println("Resolver API: Reverse lookup call for address:"+address);
+        }
         try {
             return List.of(hostsFileResolver.getByAddress(address));
         } catch (UnknownHostException uhe) {
--- a/src/jdk.dns.client/share/classes/jdk/dns/client/internal/DnsClient.java	Thu Nov 14 23:13:47 2019 +0000
+++ b/src/jdk.dns.client/share/classes/jdk/dns/client/internal/DnsClient.java	Thu Nov 14 23:16:40 2019 +0000
@@ -37,15 +37,16 @@
 import java.net.DatagramPacket;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.PortUnreachableException;
 import java.net.Socket;
 import java.net.SocketTimeoutException;
 import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
 import java.nio.channels.DatagramChannel;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.security.SecureRandom;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -99,7 +100,6 @@
     private int timeout;                // initial timeout on UDP and TCP queries in ms
     private int retries;                // number of UDP retries
 
-
     private static final SecureRandom random;
 
     static {
@@ -131,6 +131,10 @@
         var serversList = new ArrayList<InetAddress>();
         var serverPortsList = new ArrayList<Integer>();
 
+        if (DEBUG) {
+            System.err.println("DNS Client: servers list:" + servers);
+        }
+
         for (String serverString : servers) {
 
             // Is optional port given?
@@ -305,6 +309,11 @@
                         }
                         return new ResourceRecords(msg, msg.length, hdr, false);
 
+                    } catch (PortUnreachableException e) {
+                        if (caughtException == null) {
+                            caughtException = e;
+                        }
+                        doNotRetry[i] = true;
                     } catch (IOException e) {
                         if (DEBUG) {
                             dprint("Caught IOException:" + e);
@@ -312,13 +321,6 @@
                         if (caughtException == null) {
                             caughtException = e;
                         }
-                        // Use reflection to allow pre-1.4 compilation.
-                        // This won't be needed much longer.
-                        if (e.getClass().getName().equals(
-                                "java.net.PortUnreachableException")) {
-                            doNotRetry[i] = true;
-                        }
-                        // doNotRetry set - needs to be added
                     } catch (DnsNameNotFoundException e) {
                         // This is authoritative, so return immediately
                         throw e;
@@ -394,12 +396,12 @@
                     long start = System.currentTimeMillis();
 
 
+                    dc.socket().receive(ipkt);
                     byte[] data = ipkt.getData();
-                    ByteBuffer bb = ByteBuffer.wrap(data);
-                    dc.read(bb);
+                    int length = ipkt.getLength();
                     long end = System.currentTimeMillis();
 
-                    if (isMatchResponse(data, xid)) {
+                    if (isMatchResponse(data, length, xid)) {
                         return data;
                     }
                     timeoutLeft = pktTimeout - ((int) (end - start));
@@ -537,10 +539,10 @@
      * Also checks that the domain name, type and class in the response
      * match those in the original query.
      */
-    private boolean isMatchResponse(byte[] pkt, int xid)
+    private boolean isMatchResponse(byte[] pkt, int length, int xid)
             throws DnsResolverException {
 
-        Header hdr = new Header(pkt, pkt.length);
+        Header hdr = new Header(pkt, length);
         if (hdr.query) {
             throw new DnsResolverException("DNS error: expecting response");
         }
@@ -557,7 +559,7 @@
             checkResponseCode(hdr);
             if (!hdr.query && hdr.numQuestions == 1) {
 
-                ResourceRecord rr = new ResourceRecord(pkt, pkt.length,
+                ResourceRecord rr = new ResourceRecord(pkt, length,
                         Header.HEADER_SIZE, true, false);
 
                 // Retrieve the original query
@@ -608,7 +610,7 @@
         queuesLock.lock();
         try {
             if (reqs.containsKey(hdr.xid)) { // enqueue only the first response
-                resps.put(hdr.xid, pkt);
+                resps.put(hdr.xid, Arrays.copyOf(pkt, length));
             }
         } finally {
             queuesLock.unlock();
--- a/src/jdk.dns.client/share/classes/jdk/dns/client/internal/HostsFileResolver.java	Thu Nov 14 23:13:47 2019 +0000
+++ b/src/jdk.dns.client/share/classes/jdk/dns/client/internal/HostsFileResolver.java	Thu Nov 14 23:16:40 2019 +0000
@@ -26,6 +26,7 @@
 package jdk.dns.client.internal;
 
 import jdk.dns.client.internal.util.ReloadTracker;
+import jdk.dns.conf.DnsResolverConfiguration;
 import sun.net.util.IPAddressUtil;
 
 import java.net.InetAddress;
@@ -53,12 +54,13 @@
 public class HostsFileResolver {
     private static final String HOSTS_FILE_LOCATION_PROPERTY_VALUE =
             AccessController.doPrivileged((PrivilegedAction<String>)
-                    () -> System.getProperty("jdk.net.hosts.file", "/etc/hosts")
+                    () -> System.getProperty("jdk.dns.client.hosts.file",
+                            DnsResolverConfiguration.getDefaultHostsFileLocation())
             );
     private static final ReadWriteLock LOCK = new ReentrantReadWriteLock();
 
     // 300 seconds, similar to DnsResolverConfiguration in millis since Epoch
-    private static final long REFRESH_TIMEOUT_MILLIS = 300_000;
+    private static final long REFRESH_TIMEOUT_NANOS = 300_000_000_000L;
     private static final ReloadTracker HOSTS_FILE_TRACKER;
     private static volatile Map<String, HostFileEntry> HOST_ADDRESSES = Collections.emptyMap();
 
@@ -262,7 +264,7 @@
         // TODO: Revisit
         try {
             var pea = (PrivilegedExceptionAction<ReloadTracker>) () ->
-                    ReloadTracker.newInstance(Paths.get(HOSTS_FILE_LOCATION_PROPERTY_VALUE), REFRESH_TIMEOUT_MILLIS);
+                    ReloadTracker.newInstance(Paths.get(HOSTS_FILE_LOCATION_PROPERTY_VALUE), REFRESH_TIMEOUT_NANOS);
             HOSTS_FILE_TRACKER = System.getSecurityManager() == null ? pea.run() :
                     AccessController.doPrivileged(pea);
         } catch (PrivilegedActionException pae) {
--- a/src/jdk.dns.client/share/classes/jdk/dns/client/internal/util/ReloadTracker.java	Thu Nov 14 23:13:47 2019 +0000
+++ b/src/jdk.dns.client/share/classes/jdk/dns/client/internal/util/ReloadTracker.java	Thu Nov 14 23:16:40 2019 +0000
@@ -25,20 +25,18 @@
 
 package jdk.dns.client.internal.util;
 
-import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.util.concurrent.atomic.AtomicLong;
 
 public class ReloadTracker {
 
-    public static ReloadTracker newInstance(Path fileToTrack, long refreshTimeoutMillis) {
+    public static ReloadTracker newInstance(Path fileToTrack, long refreshTimeoutNanos) {
         Path absolutePath = fileToTrack.toAbsolutePath();
-        return new ReloadTracker(absolutePath, refreshTimeoutMillis);
+        return new ReloadTracker(absolutePath, refreshTimeoutNanos);
     }
 
     public static class ReloadStatus {
@@ -66,9 +64,9 @@
     }
 
 
-    private ReloadTracker(Path filePath, long refreshTimeoutMillis) {
+    private ReloadTracker(Path filePath, long refreshTimeoutNanos) {
         this.filePath = filePath;
-        this.refreshTimeoutMillis = refreshTimeoutMillis;
+        this.refreshTimeoutNanos = refreshTimeoutNanos;
     }
 
 
@@ -92,13 +90,13 @@
         }
         return new ReloadStatus(fileExists,
                 (lastModificationTime != lastSeenChanged.get()) ||
-                        (System.currentTimeMillis() - lastReload > refreshTimeoutMillis),
+                        (System.nanoTime() - lastReload > refreshTimeoutNanos),
                 lastModificationTime);
     }
 
     public void updateTimestamps(ReloadStatus rs) {
         lastSeenChanged.set(rs.lastModificationTimestamp);
-        lastRefreshed.set(System.currentTimeMillis());
+        lastRefreshed.set(System.nanoTime());
     }
 
     // Last timestamp when tracked file has been reloaded by consumer of this utility class
@@ -106,7 +104,7 @@
     // Last processed FS last modified timestamp
     private final AtomicLong lastSeenChanged = new AtomicLong(-1);
     // Refresh timeout
-    private final long refreshTimeoutMillis;
+    private final long refreshTimeoutNanos;
     // Path of the tracked file
     private final Path filePath;
 }
--- a/src/jdk.dns.client/unix/classes/jdk/dns/conf/DnsResolverConfiguration.java	Thu Nov 14 23:13:47 2019 +0000
+++ b/src/jdk.dns.client/unix/classes/jdk/dns/conf/DnsResolverConfiguration.java	Thu Nov 14 23:16:40 2019 +0000
@@ -47,6 +47,11 @@
  */
 
 public class DnsResolverConfiguration {
+
+    public static String getDefaultHostsFileLocation() {
+        return "/etc/hosts";
+    }
+
     // Lock held whilst loading configuration or checking
     private static final ReadWriteLock LOCK = new ReentrantReadWriteLock();
 
@@ -56,16 +61,16 @@
     private static final ReloadTracker RESOLVE_CONF_TRACKER;
 
 
-    // Cache timeout (300 seconds) - should be converted into property
+    // Cache timeout (300 seconds) in nano seconds - should be converted into property
     // or configured as preference in the future.
-    private static final int TIMEOUT = 300_000;
+    private static final long TIMEOUT = 300_000_000_000L;
 
     // Parse /etc/resolv.conf to get the values for a particular
     // keyword.
     //
     private List<String> resolvconf(String keyword,
-                                          int maxperkeyword,
-                                          int maxkeywords) {
+                                    int maxperkeyword,
+                                    int maxkeywords) {
         LinkedList<String> ll = new LinkedList<>();
 
         try {
@@ -266,7 +271,10 @@
     static native String fallbackDomain0();
 
     static {
-        var pa = (PrivilegedAction<Void>) () -> {System.loadLibrary("resolver"); return null;};
+        var pa = (PrivilegedAction<Void>) () -> {
+            System.loadLibrary("resolver");
+            return null;
+        };
         if (System.getSecurityManager() == null) {
             pa.run();
         } else {