Re: [PATCH] 7006496: Use modern Windows API to retrieve OS DNS servers

2020-01-08 Thread Chris Hegarty

> On 8 Jan 2020, at 05:12, Anuraag Agrawal  wrote:
> 
> Hi Chris,
> 
> Happy new year - sorry for the long delay. I have made an updated patch 
> fixing the comment (missing comma), bumping MAX_STR_LEN, and tweaking the 
> exception behavior.
> 
> Basically, as you pointed out loadDNSConfig itself does not throw any 
> exception. The getAdapters function will throw a) OutOfMemoryError if native 
> memory allocation failed or b) Error if the Windows SDK function randomly 
> failed. I have gone ahead and added code to check the exception thrown when 
> getAdapters failed and propagate it if it is OOME or clear it otherwise. This 
> should be the same behavior as the old version of loadDNSConfig.


...

> -if (adapterP) {
> -free(adapterP);
> +free(adapters);
> +} else {
> +th = (*env)->ExceptionOccurred(env);
> +if (th != NULL) {
> +// We only throw errors if not able to allocate memory, otherwise
> +// ignore ones related to Windows API usage itself.
> +(*env)->ExceptionClear(env);
> +if ((*env)->IsInstanceOf(env, th, outOfMemoryErrCl)) {
> +(*env)->Throw(env, th);
> +return STS_ERROR;
> +}
> +}

I think that it would be preferable to NOT clear the pending exception, and 
just allow it to propagate up.

-Chris.



Re: [PATCH] 7006496: Use modern Windows API to retrieve OS DNS servers

2020-01-08 Thread Anuraag Agrawal
Hi Chris,

Ah ok - I was worried it might be a backwards incompatible change, but I
guess these are internal classes anyways. I have updated the patch,
removing the exception handling logic so the errors propagate up.

Inline patch follows

diff --git
a/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java
b/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java
index 2250b3158e..c3ebe09776 100644
---
a/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java
+++
b/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java
@@ -25,9 +25,9 @@

 package sun.net.dns;

+import java.util.ArrayList;
 import java.util.List;
-import java.util.LinkedList;
-import java.util.StringTokenizer;
+import java.util.concurrent.TimeUnit;

 /*
  * An implementation of sun.net.ResolverConfiguration for Windows.
@@ -50,30 +50,55 @@ public class ResolverConfigurationImpl

 // Cache timeout (120 seconds) - should be converted into property
 // or configured as preference in the future.
-private static final int TIMEOUT = 12;
+private static final long TIMEOUT_NANOS =
TimeUnit.SECONDS.toNanos(120);

 // DNS suffix list and name servers populated by native method
 private static String os_searchlist;
 private static String os_nameservers;

 // Cached lists
-private static LinkedList searchlist;
-private static LinkedList nameservers;
-
-// Parse string that consists of token delimited by space or commas
-// and return LinkedHashMap
-private LinkedList stringToList(String str) {
-LinkedList ll = new LinkedList<>();
-
-// comma and space are valid delimiters
-StringTokenizer st = new StringTokenizer(str, ", ");
-while (st.hasMoreTokens()) {
-String s = st.nextToken();
-if (!ll.contains(s)) {
-ll.add(s);
+private static ArrayList searchlist;
+private static ArrayList nameservers;
+
+// Parse string that consists of token delimited by comma
+// and return ArrayList. Refer to ResolverConfigurationImpl.c and
+// strappend to see how the string is created.
+private ArrayList stringToList(String str) {
+// String is delimited by comma.
+String[] tokens = str.split(",");
+ArrayList l = new ArrayList<>(tokens.length);
+for (String s : tokens) {
+if (!l.contains(s)) {
+l.add(s);
 }
 }
-return ll;
+l.trimToSize();
+return l;
+}
+
+// Parse string that consists of token delimited by comma
+// and return ArrayList.  Refer to ResolverConfigurationImpl.c and
+// strappend to see how the string is created.
+// In addition to splitting the string, converts IPv6 addresses to
+// BSD-style.
+private ArrayList addressesToList(String str) {
+// String is delimited by comma
+String[] tokens = str.split(",");
+ArrayList l = new ArrayList<>(tokens.length);
+
+for (String s : tokens) {
+if (!s.isEmpty()) {
+if (s.indexOf(':') >= 0 && s.charAt(0) != '[') {
+// Not BSD style
+s = '[' + s + ']';
+}
+if (!l.contains(s)) {
+l.add(s);
+}
+}
+}
+l.trimToSize();
+return l;
 }

 // Load DNS configuration from OS
@@ -81,28 +106,34 @@ public class ResolverConfigurationImpl
 private void loadConfig() {
 assert Thread.holdsLock(lock);

-// if address have changed then DNS probably changed as well;
-// otherwise check if cached settings have expired.
-//
+// A change in the network address of the machine usually indicates
+// a change in DNS configuration too so we always refresh the
config
+// after such a change.
 if (changed) {
 changed = false;
 } else {
+// Otherwise we refresh if TIMEOUT_NANOS has passed since last
+// load.
 if (lastRefresh >= 0) {
-long currTime = System.currentTimeMillis();
-if ((currTime - lastRefresh) < TIMEOUT) {
+long currTime = System.nanoTime();
+if ((currTime - lastRefresh) < TIMEOUT_NANOS) {
 return;
 }
 }
 }

-// load DNS configuration, update timestamp, create
-// new HashMaps from the loaded configuration
-//
+// Native code that uses Windows API to find out the DNS server
+// addresses and search suffixes. It builds a comma-delimited
string
+// of nameservers and domain suffixes and sets them to the static
+// os_nameservers and os_searchlist. We then split these into Java
+// Lists here.
 loadDNSconfig0();

-lastRefresh = System.currentTimeMillis();
+// Re

Re: [PATCH] 7006496: Use modern Windows API to retrieve OS DNS servers

2020-01-08 Thread Aleks Efimov

Hi Anuraag,

I've uploaded your latest patch to the following location:
http://cr.openjdk.java.net/~aefimov/anuraaga/7006496/04

The local Windows build and the acquired configuration are good.

I will run you patch through our CI system and will update this thread 
once I get the results.


Kind Regards,
Aleksei

On 08/01/2020 15:50, Anuraag Agrawal wrote:

Hi Chris,

Ah ok - I was worried it might be a backwards incompatible change, but 
I guess these are internal classes anyways. I have updated the patch, 
removing the exception handling logic so the errors propagate up.


Inline patch follows

diff --git 
a/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java 
b/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java

index 2250b3158e..c3ebe09776 100644
--- 
a/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java
+++ 
b/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java

@@ -25,9 +25,9 @@

 package sun.net.dns;

+import java.util.ArrayList;
 import java.util.List;
-import java.util.LinkedList;
-import java.util.StringTokenizer;
+import java.util.concurrent.TimeUnit;

 /*
  * An implementation of sun.net.ResolverConfiguration for Windows.
@@ -50,30 +50,55 @@ public class ResolverConfigurationImpl

     // Cache timeout (120 seconds) - should be converted into property
     // or configured as preference in the future.
-    private static final int TIMEOUT = 12;
+    private static final long TIMEOUT_NANOS = 
TimeUnit.SECONDS.toNanos(120);


     // DNS suffix list and name servers populated by native method
     private static String os_searchlist;
     private static String os_nameservers;

     // Cached lists
-    private static LinkedList searchlist;
-    private static LinkedList nameservers;
-
-    // Parse string that consists of token delimited by space or commas
-    // and return LinkedHashMap
-    private LinkedList stringToList(String str) {
-        LinkedList ll = new LinkedList<>();
-
-        // comma and space are valid delimiters
-        StringTokenizer st = new StringTokenizer(str, ", ");
-        while (st.hasMoreTokens()) {
-            String s = st.nextToken();
-            if (!ll.contains(s)) {
-                ll.add(s);
+    private static ArrayList searchlist;
+    private static ArrayList nameservers;
+
+    // Parse string that consists of token delimited by comma
+    // and return ArrayList. Refer to ResolverConfigurationImpl.c and
+    // strappend to see how the string is created.
+    private ArrayList stringToList(String str) {
+        // String is delimited by comma.
+        String[] tokens = str.split(",");
+        ArrayList l = new ArrayList<>(tokens.length);
+        for (String s : tokens) {
+            if (!l.contains(s)) {
+                l.add(s);
             }
         }
-        return ll;
+        l.trimToSize();
+        return l;
+    }
+
+    // Parse string that consists of token delimited by comma
+    // and return ArrayList.  Refer to ResolverConfigurationImpl.c and
+    // strappend to see how the string is created.
+    // In addition to splitting the string, converts IPv6 addresses to
+    // BSD-style.
+    private ArrayList addressesToList(String str) {
+        // String is delimited by comma
+        String[] tokens = str.split(",");
+        ArrayList l = new ArrayList<>(tokens.length);
+
+        for (String s : tokens) {
+            if (!s.isEmpty()) {
+                if (s.indexOf(':') >= 0 && s.charAt(0) != '[') {
+                    // Not BSD style
+                    s = '[' + s + ']';
+                }
+                if (!l.contains(s)) {
+                    l.add(s);
+                }
+            }
+        }
+        l.trimToSize();
+        return l;
     }

     // Load DNS configuration from OS
@@ -81,28 +106,34 @@ public class ResolverConfigurationImpl
     private void loadConfig() {
         assert Thread.holdsLock(lock);

-        // if address have changed then DNS probably changed as well;
-        // otherwise check if cached settings have expired.
-        //
+        // A change in the network address of the machine usually 
indicates
+        // a change in DNS configuration too so we always refresh the 
config

+        // after such a change.
         if (changed) {
             changed = false;
         } else {
+            // Otherwise we refresh if TIMEOUT_NANOS has passed since 
last

+            // load.
             if (lastRefresh >= 0) {
-                long currTime = System.currentTimeMillis();
-                if ((currTime - lastRefresh) < TIMEOUT) {
+                long currTime = System.nanoTime();
+                if ((currTime - lastRefresh) < TIMEOUT_NANOS) {
                     return;
                 }
             }
         }

-        // load DNS configuration, update timestamp, create
-        // new HashMaps from the loaded configuration
-        //
+        // Native code that uses Windows

Re: [PATCH] 7006496: Use modern Windows API to retrieve OS DNS servers

2020-01-08 Thread Aleks Efimov
Got the testing results: the CI is happy with the last patch - no JNDI 
test failures observed


Kind Regards,
Aleksei

On 08/01/2020 18:23, Aleks Efimov wrote:

Hi Anuraag,

I've uploaded your latest patch to the following location:
http://cr.openjdk.java.net/~aefimov/anuraaga/7006496/04

The local Windows build and the acquired configuration are good.

I will run you patch through our CI system and will update this thread 
once I get the results.


Kind Regards,
Aleksei

On 08/01/2020 15:50, Anuraag Agrawal wrote:

Hi Chris,

Ah ok - I was worried it might be a backwards incompatible change, 
but I guess these are internal classes anyways. I have updated the 
patch, removing the exception handling logic so the errors propagate up.


Inline patch follows

diff --git 
a/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java 
b/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java

index 2250b3158e..c3ebe09776 100644
--- 
a/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java
+++ 
b/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java

@@ -25,9 +25,9 @@

 package sun.net.dns;

+import java.util.ArrayList;
 import java.util.List;
-import java.util.LinkedList;
-import java.util.StringTokenizer;
+import java.util.concurrent.TimeUnit;

 /*
  * An implementation of sun.net.ResolverConfiguration for Windows.
@@ -50,30 +50,55 @@ public class ResolverConfigurationImpl

     // Cache timeout (120 seconds) - should be converted into property
     // or configured as preference in the future.
-    private static final int TIMEOUT = 12;
+    private static final long TIMEOUT_NANOS = 
TimeUnit.SECONDS.toNanos(120);


     // DNS suffix list and name servers populated by native method
     private static String os_searchlist;
     private static String os_nameservers;

     // Cached lists
-    private static LinkedList searchlist;
-    private static LinkedList nameservers;
-
-    // Parse string that consists of token delimited by space or commas
-    // and return LinkedHashMap
-    private LinkedList stringToList(String str) {
-        LinkedList ll = new LinkedList<>();
-
-        // comma and space are valid delimiters
-        StringTokenizer st = new StringTokenizer(str, ", ");
-        while (st.hasMoreTokens()) {
-            String s = st.nextToken();
-            if (!ll.contains(s)) {
-                ll.add(s);
+    private static ArrayList searchlist;
+    private static ArrayList nameservers;
+
+    // Parse string that consists of token delimited by comma
+    // and return ArrayList. Refer to ResolverConfigurationImpl.c and
+    // strappend to see how the string is created.
+    private ArrayList stringToList(String str) {
+        // String is delimited by comma.
+        String[] tokens = str.split(",");
+        ArrayList l = new ArrayList<>(tokens.length);
+        for (String s : tokens) {
+            if (!l.contains(s)) {
+                l.add(s);
             }
         }
-        return ll;
+        l.trimToSize();
+        return l;
+    }
+
+    // Parse string that consists of token delimited by comma
+    // and return ArrayList.  Refer to ResolverConfigurationImpl.c and
+    // strappend to see how the string is created.
+    // In addition to splitting the string, converts IPv6 addresses to
+    // BSD-style.
+    private ArrayList addressesToList(String str) {
+        // String is delimited by comma
+        String[] tokens = str.split(",");
+        ArrayList l = new ArrayList<>(tokens.length);
+
+        for (String s : tokens) {
+            if (!s.isEmpty()) {
+                if (s.indexOf(':') >= 0 && s.charAt(0) != '[') {
+                    // Not BSD style
+                    s = '[' + s + ']';
+                }
+                if (!l.contains(s)) {
+                    l.add(s);
+                }
+            }
+        }
+        l.trimToSize();
+        return l;
     }

     // Load DNS configuration from OS
@@ -81,28 +106,34 @@ public class ResolverConfigurationImpl
     private void loadConfig() {
         assert Thread.holdsLock(lock);

-        // if address have changed then DNS probably changed as well;
-        // otherwise check if cached settings have expired.
-        //
+        // A change in the network address of the machine usually 
indicates
+        // a change in DNS configuration too so we always refresh 
the config

+        // after such a change.
         if (changed) {
             changed = false;
         } else {
+            // Otherwise we refresh if TIMEOUT_NANOS has passed 
since last

+            // load.
             if (lastRefresh >= 0) {
-                long currTime = System.currentTimeMillis();
-                if ((currTime - lastRefresh) < TIMEOUT) {
+                long currTime = System.nanoTime();
+                if ((currTime - lastRefresh) < TIMEOUT_NANOS) {
                     return;
                 }
             }
         }

-