<div dir="ltr"><div>Hi Aleksei,</div><div><br></div><div>Thanks for running the test. I had checked the global search list, but realize I didn't check connection-specific suffixes which were causing the issue you see. While the documentation states that FirstDnsSuffix is populated on Vista+, amazingly it doesn't seem to be</div><div><br></div><div><a href="https://docs.microsoft.com/en-us/windows/win32/api/iptypes/ns-iptypes-ip_adapter_addresses_lh">https://docs.microsoft.com/en-us/windows/win32/api/iptypes/ns-iptypes-ip_adapter_addresses_lh</a> </div><div><br></div><div>Chromium has run into the same issue and just doesn't use the field</div><div><br></div><div><a href="https://cs.chromium.org/chromium/src/net/dns/dns_config_service_win.cc?q=firstdnssuffix&sq=package:chromium&dr=C&l=532">https://cs.chromium.org/chromium/src/net/dns/dns_config_service_win.cc?q=firstdnssuffix&sq=package:chromium&dr=C&l=532</a></div><div><br></div><div>So I have gone ahead and switched to using the normal DnsSuffix field. DnsSuffix and looking up the search list in the registry should generally give a full list.</div><div><br></div><div>During this testing, other issues I found are that the search list returns a comma-separated list. So to keep the string list parsing simple, I changed the delimiter from space to comma. Also, on my machine I would always have DNS servers like fec0:0:0:ffff:1 on some adapters. At first, I assumed it is ok to return these, since they are configured by the OS and should be valid, but I learnt that these are deprecated IPv6 site-local addresses and should not be used. </div><div><br></div><div><a href="https://en.wikipedia.org/wiki/Unique_local_address">https://en.wikipedia.org/wiki/Unique_local_address</a></div><div><br></div><div>I used the same check for site-local as Inet6Address, which just sees if the first bytes are fec0.</div><div><br></div><div>Thanks again - inline patch follows.</div><div><br></div><div>diff --git a/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java b/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java<br>index 2250b3158e..b9a06461ab 100644<br>--- a/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java<br>+++ b/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java<br>@@ -25,9 +25,9 @@<br> <br> package sun.net.dns;<br> <br>+import java.util.ArrayList;<br> import java.util.List;<br>-import java.util.LinkedList;<br>-import java.util.StringTokenizer;<br>+import java.util.concurrent.TimeUnit;<br> <br> /*<br> * An implementation of sun.net.ResolverConfiguration for Windows.<br>@@ -50,30 +50,65 @@ public class ResolverConfigurationImpl<br> <br>   // Cache timeout (120 seconds) - should be converted into property<br>   // or configured as preference in the future.<br>-   private static final int TIMEOUT = 120000;<br>+   private static final long TIMEOUT_NANOS = TimeUnit.SECONDS.toNanos(120);<br> <br>   // DNS suffix list and name servers populated by native method<br>   private static String os_searchlist;<br>   private static String os_nameservers;<br> <br>   // Cached lists<br>-   private static LinkedList<String> searchlist;<br>-   private static LinkedList<String> nameservers;<br>-<br>-   // Parse string that consists of token delimited by space or commas<br>-   // and return LinkedHashMap<br>-   private LinkedList<String> stringToList(String str) {<br>-     LinkedList<String> ll = new LinkedList<>();<br>-<br>-     // comma and space are valid delimiters<br>-     StringTokenizer st = new StringTokenizer(str, ", ");<br>-     while (st.hasMoreTokens()) {<br>-       String s = st.nextToken();<br>-       if (!ll.contains(s)) {<br>-         ll.add(s);<br>+   private static ArrayList<String> searchlist;<br>+   private static ArrayList<String> nameservers;<br>+<br>+   // Parse string that consists of token delimited by comma<br>+   // and return ArrayList. Refer to ResolverConfigurationImpl.c and<br>+   // strappend to see how the string is created.<br>+   private ArrayList<String> stringToList(String str) {<br>+     // String is delimited by comma.<br>+     String[] tokens = str.split(",");<br>+     ArrayList<String> l = new ArrayList<>(tokens.length);<br>+     for (String s : tokens) {<br>+       if (!l.contains(s)) {<br>+         l.add(s);<br>       }<br>     }<br>-     return ll;<br>+     l.trimToSize();<br>+     return l;<br>+   }<br>+<br>+   // Parse string that consists of token delimited by comma<br>+   // and return ArrayList. Refer to ResolverConfigurationImpl.c and<br>+   // strappend to see how the string is created.<br>+   // In addition to splitting the string, converts IPv6 addresses to<br>+   // BSD-style.<br>+   private ArrayList<String> addressesToList(String str) {<br>+     // String is delimited by comma<br>+     String[] tokens = str.split(",");<br>+     ArrayList<String> l = new ArrayList<>(tokens.length);<br>+<br>+     for (String s : tokens) {<br>+       if (!s.isEmpty()) {<br>+         if (s.indexOf(':') >= 0) {<br>+           // IPv6<br>+           if (s.charAt(0) != '[') {<br>+             // Not BSD style<br>+             s = '[' + s + ']';<br>+           }<br>+           if (s.startsWith("[fec0:")) {<br>+             // Deprecated site-local address. Windows adds<br>+             // such addresses to IPv6 adapters without DNS<br>+             // configured, but these should not actually be<br>+             // used for queries.<br>+             continue;<br>+           }<br>+         }<br>+         if (!l.contains(s)) {<br>+           l.add(s);<br>+         }<br>+       }<br>+     }<br>+     l.trimToSize();<br>+     return l;<br>   }<br> <br>   // Load DNS configuration from OS<br>@@ -81,28 +116,34 @@ public class ResolverConfigurationImpl<br>   private void loadConfig() {<br>     assert Thread.holdsLock(lock);<br> <br>-     // if address have changed then DNS probably changed as well;<br>-     // otherwise check if cached settings have expired.<br>-     //<br>+     // A change in the network address of the machine usually indicates<br>+     // a change in DNS configuration too so we always refresh the config<br>+     // after such a change.<br>     if (changed) {<br>       changed = false;<br>     } else {<br>+       // Otherwise we refresh if TIMEOUT_NANOS has passed since last<br>+       // load.<br>       if (lastRefresh >= 0) {<br>-         long currTime = System.currentTimeMillis();<br>-         if ((currTime - lastRefresh) < TIMEOUT) {<br>+         long currTime = System.nanoTime();<br>+         if ((currTime - lastRefresh) < TIMEOUT_NANOS) {<br>           return;<br>         }<br>       }<br>     }<br> <br>-     // load DNS configuration, update timestamp, create<br>-     // new HashMaps from the loaded configuration<br>-     //<br>+     // Native code that uses Windows API to find out the DNS server<br>+     // addresses and search suffixes. It builds a comma-delimited string<br>+     // of nameservers and domain suffixes and sets them to the static<br>+     // os_nameservers and os_searchlist. We then split these into Java<br>+     // Lists here.<br>     loadDNSconfig0();<br> <br>-     lastRefresh = System.currentTimeMillis();<br>+     // Record the time of update and refresh the lists of addresses /<br>+     // domain suffixes.<br>+     lastRefresh = System.nanoTime();<br>     searchlist = stringToList(os_searchlist);<br>-     nameservers = stringToList(os_nameservers);<br>+     nameservers = addressesToList(os_nameservers);<br>     os_searchlist = null;            // can be GC'ed<br>     os_nameservers = null;<br>   }<br>diff --git a/src/java.base/windows/native/libnet/NetworkInterface_winXP.c b/src/java.base/windows/native/libnet/NetworkInterface_winXP.c<br>index f2368bafcb..297a1561ef 100644<br>--- a/src/java.base/windows/native/libnet/NetworkInterface_winXP.c<br>+++ b/src/java.base/windows/native/libnet/NetworkInterface_winXP.c<br>@@ -73,8 +73,8 @@ const int MAX_TRIES = 3;<br> * for each adapter on the system. Returned in *adapters.<br> * Buffer is malloc'd and must be freed (unless error returned)<br> */<br>-static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES **adapters) {<br>-   DWORD ret, flags;<br>+int getAdapters (JNIEnv *env, int flags, IP_ADAPTER_ADDRESSES **adapters) {<br>+   DWORD ret;<br>   IP_ADAPTER_ADDRESSES *adapterInfo;<br>   ULONG len;<br>   int try;<br>@@ -87,9 +87,6 @@ static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES **adapters) {<br>   }<br> <br>   len = BUFF_SIZE;<br>-   flags = GAA_FLAG_SKIP_DNS_SERVER;<br>-   flags |= GAA_FLAG_SKIP_MULTICAST;<br>-   flags |= GAA_FLAG_INCLUDE_PREFIX;<br>   ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);<br> <br>   for (try = 0; ret == ERROR_BUFFER_OVERFLOW && try < MAX_TRIES; ++try) {<br>@@ -240,7 +237,7 @@ static int ipinflen = 2048;<br> */<br> int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)<br> {<br>-   DWORD ret;<br>+   DWORD ret, flags;<br>   MIB_IPADDRTABLE *tableP;<br>   IP_ADAPTER_ADDRESSES *ptr, *adapters=NULL;<br>   ULONG len=ipinflen, count=0;<br>@@ -296,7 +293,11 @@ int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)<br>     }<br>   }<br>   free(tableP);<br>-   ret = getAdapters (env, &adapters);<br>+<br>+   flags = GAA_FLAG_SKIP_DNS_SERVER;<br>+   flags |= GAA_FLAG_SKIP_MULTICAST;<br>+   flags |= GAA_FLAG_INCLUDE_PREFIX;<br>+   ret = getAdapters (env, flags, &adapters);<br>   if (ret != ERROR_SUCCESS) {<br>     goto err;<br>   }<br>diff --git a/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c b/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c<br>index 13b28044a5..427d7c85eb 100644<br>--- a/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c<br>+++ b/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c<br>@@ -1,5 +1,5 @@<br> /*<br>- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.<br>+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.<br> * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.<br> *<br> * This code is free software; you can redistribute it and/or modify it<br>@@ -30,6 +30,7 @@<br> #include <iprtrmib.h><br> #include <time.h><br> #include <assert.h><br>+#include <winsock2.h><br> #include <iphlpapi.h><br> <br> #include "jni_util.h"<br>@@ -48,8 +49,10 @@<br> static jfieldID searchlistID;<br> static jfieldID nameserversID;<br> <br>+extern int getAdapters(JNIEnv *env, int flags, IP_ADAPTER_ADDRESSES **adapters);<br>+<br> /*<br>- * Utility routine to append s2 to s1 with a space delimiter.<br>+ * Utility routine to append s2 to s1 with a comma delimiter.<br> *  strappend(s1="abc", "def")  => "abc def"<br> *  strappend(s1="", "def")   => "def<br> */<br>@@ -60,41 +63,30 @@ void strappend(char *s1, char *s2) {<br>     return;<br> <br>   len = strlen(s1)+1;<br>-   if (s1[0] != 0)             /* needs space character */<br>+   if (s1[0] != 0)             /* needs comma character */<br>     len++;<br>   if (len + strlen(s2) > MAX_STR_LEN)   /* insufficient space */<br>     return;<br> <br>   if (s1[0] != 0) {<br>-     strcat(s1, " ");<br>+     strcat(s1, ",");<br>   }<br>   strcat(s1, s2);<br> }<br> <br> /*<br>- * Windows 2000/XP<br>- *<br>- * Use registry approach based on settings described in Appendix C<br>- * of "Microsoft Windows 2000 TCP/IP Implementation Details".<br>- *<br>- * DNS suffix list is obtained from SearchList registry setting. If<br>- * this is not specified we compile suffix list based on the<br>- * per-connection domain suffix.<br>- *<br>- * DNS name servers and domain settings are on a per-connection<br>- * basic. We therefore enumerate the network adapters to get the<br>- * names of each adapter and then query the corresponding registry<br>- * settings to obtain NameServer/DhcpNameServer and Domain/DhcpDomain.<br>+ * Use DNS server addresses returned by GetAdaptersAddresses for currently<br>+ * active interfaces.<br> */<br>-static int loadConfig(char *sl, char *ns) {<br>-   IP_ADAPTER_INFO *adapterP;<br>-   ULONG size;<br>-   DWORD ret;<br>+static int loadConfig(JNIEnv *env, char *sl, char *ns) {<br>+   IP_ADAPTER_ADDRESSES *adapters, *adapter;<br>+   IP_ADAPTER_DNS_SERVER_ADDRESS *dnsServer;<br>+   WCHAR *suffix;<br>+   DWORD ret, flags;<br>   DWORD dwLen;<br>   ULONG ulType;<br>   char result[MAX_STR_LEN];<br>   HANDLE hKey;<br>-   int gotSearchList = 0;<br> <br>   /*<br>   * First see if there is a global suffix list specified.<br>@@ -112,122 +104,55 @@ static int loadConfig(char *sl, char *ns) {<br>       assert(ulType == REG_SZ);<br>       if (strlen(result) > 0) {<br>         strappend(sl, result);<br>-         gotSearchList = 1;<br>       }<br>     }<br>     RegCloseKey(hKey);<br>   }<br> <br>-   /*<br>-   * Ask the IP Helper library to enumerate the adapters<br>-   */<br>-   size = sizeof(IP_ADAPTER_INFO);<br>-   adapterP = (IP_ADAPTER_INFO *)malloc(size);<br>-   if (adapterP == NULL) {<br>-     return STS_ERROR;<br>-   }<br>-   ret = GetAdaptersInfo(adapterP, &size);<br>-   if (ret == ERROR_BUFFER_OVERFLOW) {<br>-     IP_ADAPTER_INFO *newAdapterP = (IP_ADAPTER_INFO *)realloc(adapterP, size);<br>-     if (newAdapterP == NULL) {<br>-       free(adapterP);<br>-       return STS_ERROR;<br>-     }<br>-     adapterP = newAdapterP;<br> <br>-     ret = GetAdaptersInfo(adapterP, &size);<br>+   // We only need DNS server addresses so skip everything else.<br>+   flags = GAA_FLAG_SKIP_UNICAST;<br>+   flags |= GAA_FLAG_SKIP_ANYCAST;<br>+   flags |= GAA_FLAG_SKIP_MULTICAST;<br>+   flags |= GAA_FLAG_SKIP_FRIENDLY_NAME;<br>+   ret = getAdapters(env, flags, &adapters);<br>+   if (ret != ERROR_SUCCESS) {<br>+     return STS_ERROR;<br>   }<br> <br>-   /*<br>-   * Iterate through the list of adapters as registry settings are<br>-   * keyed on the adapter name (GUID).<br>-   */<br>-   if (ret == ERROR_SUCCESS) {<br>-     IP_ADAPTER_INFO *curr = adapterP;<br>-     while (curr != NULL) {<br>-       char key[MAX_STR_LEN];<br>-<br>-       sprintf(key,<br>-         "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s",<br>-         curr->AdapterName);<br>-<br>-       ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,<br>-                key,<br>-                0,<br>-                KEY_READ,<br>-                (PHKEY)&hKey);<br>-       if (ret == ERROR_SUCCESS) {<br>-         DWORD enableDhcp = 0;<br>-<br>-         /*<br>-         * Is DHCP enabled on this interface<br>-         */<br>-         dwLen = sizeof(enableDhcp);<br>-         ret = RegQueryValueEx(hKey, "EnableDhcp", NULL, &ulType,<br>-                   (LPBYTE)&enableDhcp, &dwLen);<br>-<br>-         /*<br>-         * If we don't have the suffix list when get the Domain<br>-         * or DhcpDomain. If DHCP is enabled then Domain overides<br>-         * DhcpDomain<br>-         */<br>-         if (!gotSearchList) {<br>-           result[0] = '\0';<br>-           dwLen = sizeof(result);<br>-           ret = RegQueryValueEx(hKey, "Domain", NULL, &ulType,<br>-                     (LPBYTE)&result, &dwLen);<br>-           if (((ret != ERROR_SUCCESS) || (strlen(result) == 0)) &&<br>-             enableDhcp) {<br>-             dwLen = sizeof(result);<br>-             ret = RegQueryValueEx(hKey, "DhcpDomain", NULL, &ulType,<br>-                        (LPBYTE)&result, &dwLen);<br>-           }<br>-           if (ret == ERROR_SUCCESS) {<br>-             assert(ulType == REG_SZ);<br>-             strappend(sl, result);<br>-           }<br>-         }<br>-<br>-         /*<br>-         * Get DNS servers based on NameServer or DhcpNameServer<br>-         * registry setting. If NameServer is set then it overrides<br>-         * DhcpNameServer (even if DHCP is enabled).<br>-         */<br>-         result[0] = '\0';<br>+   adapter = adapters;<br>+   while (adapter != NULL) {<br>+     // Only load config from enabled adapters.<br>+     if (adapter->OperStatus == IfOperStatusUp) {<br>+       dnsServer = adapter->FirstDnsServerAddress;<br>+       while (dnsServer != NULL) {<br>         dwLen = sizeof(result);<br>-         ret = RegQueryValueEx(hKey, "NameServer", NULL, &ulType,<br>-                   (LPBYTE)&result, &dwLen);<br>-         if (((ret != ERROR_SUCCESS) || (strlen(result) == 0)) &&<br>-           enableDhcp) {<br>-           dwLen = sizeof(result);<br>-           ret = RegQueryValueEx(hKey, "DhcpNameServer", NULL, &ulType,<br>-                      (LPBYTE)&result, &dwLen);<br>-         }<br>-         if (ret == ERROR_SUCCESS) {<br>-           assert(ulType == REG_SZ);<br>+         ret = WSAAddressToStringA(dnsServer->Address.lpSockaddr,<br>+              dnsServer->Address.iSockaddrLength, NULL,<br>+              result, &dwLen);<br>+         if (ret == 0) {<br>           strappend(ns, result);<br>         }<br> <br>-         /*<br>-         * Finished with this registry key<br>-         */<br>-         RegCloseKey(hKey);<br>+         dnsServer = dnsServer->Next;<br>       }<br> <br>-       /*<br>-       * Onto the next adapeter<br>-       */<br>-       curr = curr->Next;<br>+       // Add connection-specific search domains in addition to global one.<br>+       suffix = adapter->DnsSuffix;<br>+       if (suffix != NULL) {<br>+         ret = WideCharToMultiByte(CP_UTF8, 0, suffix, -1,<br>+           result, sizeof(result), NULL, NULL);<br>+         if (ret != 0) {<br>+           strappend(sl, result);<br>+         }<br>+       }<br>     }<br>-   }<br> <br>-   /*<br>-   * Free the adpater structure<br>-   */<br>-   if (adapterP) {<br>-     free(adapterP);<br>+     adapter = adapter->Next;<br>   }<br> <br>+   free(adapters);<br>+<br>   return STS_SL_FOUND & STS_NS_FOUND;<br> }<br> <br>@@ -260,7 +185,7 @@ Java_sun_net_dns_ResolverConfigurationImpl_loadDNSconfig0(JNIEnv *env, jclass cl<br>   searchlist[0] = '\0';<br>   nameservers[0] = '\0';<br> <br>-   if (loadConfig(searchlist, nameservers) != STS_ERROR) {<br>+   if (loadConfig(env, searchlist, nameservers) != STS_ERROR) {<br> <br>     /*<br>     * Populate static fields in sun.net.DefaultResolverConfiguration<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Dec 10, 2019 at 1:29 AM Aleks Efimov <<a href="mailto:aleksej.efimov@oracle.com">aleksej.efimov@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF">
Hi Anuraag,<br>
<br>
The webrev with your latest changes can be found here:<br>
   <a href="http://cr.openjdk.java.net/~aefimov/anuraaga/7006496/01" target="_blank">http://cr.openjdk.java.net/~aefimov/anuraaga/7006496/01</a><br>
<br>
The copyright changes looks good.<br>
<br>
The split by space also looks good with assumption that we will
never get string with two spaces between IP addresses/DNS suffixes.<br>
<br>
I've also performed one test on Windows machine and it shows an
issue with the retrieval of DNS suffixes:<br>
Method to call:<br>
    sun.net.dns.ResolverConfiguration.open().searchlist()<br>
<br>
Old implementation returns:<br>
   [<a href="http://test.domain.com" target="_blank">test.domain.com</a>]<br>
<br>
With the latest patch the suffixes list (searchlist) is empty:<br>
   []<br>
<br>
I've collected the following information on the test host that might
help you to fix the issue:<br>
<blockquote>The host OS: Microsoft Windows Server 2016 Standard<br>
</blockquote>
<blockquote>Networking configuration (<---> is for masked
addresses/info):<br>
$ ipconfig /all<br>
<br>
Windows IP Configuration<br>
<br>
  Host Name . . . . . . . . . . . . : host-name-1<br>
  Primary Dns Suffix . . . . . . . :<br>
  Node Type . . . . . . . . . . . . : Hybrid<br>
  IP Routing Enabled. . . . . . . . : No<br>
  WINS Proxy Enabled. . . . . . . . : No<br>
  DNS Suffix Search List. . . . . . : <a href="http://test.domain.com" target="_blank">test.domain.com</a><br>
<br>
Ethernet adapter Ethernet:<br>
<br>
  Connection-specific DNS Suffix . : <a href="http://test.domain.com" target="_blank">test.domain.com</a><br>
  Description . . . . . . . . . . . : Broadcom NetXtreme-E
Virtual Function<br>
  Physical Address. . . . . . . . . : <------------><br>
  DHCP Enabled. . . . . . . . . . . : Yes<br>
  Autoconfiguration Enabled . . . . : Yes<br>
  Link-local IPv6 Address . . . . . : <------------><br>
  IPv4 Address. . . . . . . . . . . : <------------><br>
  Subnet Mask . . . . . . . . . . . : <------------><br>
  Lease Obtained. . . . . . . . . . : <------------><br>
  Lease Expires . . . . . . . . . . : <------------><br>
  Default Gateway . . . . . . . . . : <------------><br>
  DHCP Server . . . . . . . . . . . : <------------><br>
  DHCPv6 Client DUID. . . . . . . . : <------------><br>
  DNS Servers . . . . . . . . . . . : <------------><br>
                                      <------------><br>
  NetBIOS over Tcpip. . . . . . . . : Disabled<br>
<br>
Tunnel adapter <a href="http://isatap.test.domain.com" target="_blank">isatap.test.domain.com</a>:<br>
<br>
  Media State . . . . . . . . . . . : Media disconnected<br>
  Connection-specific DNS Suffix . : <a href="http://test.domain.com" target="_blank">test.domain.com</a><br>
  Description . . . . . . . . . . . : Microsoft ISATAP Adapter #3<br>
  Physical Address. . . . . . . . . : <------------><br>
  DHCP Enabled. . . . . . . . . . . : No<br>
  Autoconfiguration Enabled . . . . : Yes<br>
</blockquote>
<br>
- Aleksei<br>
<br>
<br>
<div>On 07/12/2019 09:44, Anuraag Agrawal
wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">Hi all,
<div><br>
</div>
<div>Thanks for the reviews. I've fixed the formatting errors,
and I hope I fixed the copyright issue. I couldn't find
documentation on the format of the copyright header, but
assume the second number is the year of modification to
update. I found ResolverConfigurationImpl.c to have an old one
and updated it to 2019.</div>
<div><br>
</div>
<div>I also found the note in the docs that StringTokenizer is
deprecated and shouldn't be used - I agree it's a good time to
replace it. As we have a simple split by space, I have gone
ahead and used the simpler String.split instead of regex, hope
that makes sense. While in many code I'd be a little concerned
with the array allocation, this is only run very infrequently
so I think it should be ok.</div>
<div><br>
</div>
<div>Inline diff follows</div>
<div><br>
</div>
<div>diff --git
a/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java
b/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java<br>
index 2250b3158e..47065e805e 100644<br>
---
a/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java<br>
+++
b/src/java.base/windows/classes/sun/net/dns/ResolverConfigurationImpl.java<br>
@@ -25,9 +25,9 @@<br>
 <br>
 package sun.net.dns;<br>
 <br>
+import java.util.ArrayList;<br>
 import java.util.List;<br>
-import java.util.LinkedList;<br>
-import java.util.StringTokenizer;<br>
+import java.util.concurrent.TimeUnit;<br>
 <br>
 /*<br>
 * An implementation of sun.net.ResolverConfiguration for
Windows.<br>
@@ -50,30 +50,55 @@ public class ResolverConfigurationImpl<br>
 <br>
   // Cache timeout (120 seconds) - should be converted into
property<br>
   // or configured as preference in the future.<br>
- Â Â private static final int TIMEOUT = 120000;<br>
+ Â Â private static final long TIMEOUT_NANOS =
TimeUnit.SECONDS.toNanos(120);<br>
 <br>
   // DNS suffix list and name servers populated by native
method<br>
   private static String os_searchlist;<br>
   private static String os_nameservers;<br>
 <br>
   // Cached lists<br>
- Â Â private static LinkedList<String> searchlist;<br>
- Â Â private static LinkedList<String> nameservers;<br>
-<br>
- Â Â // Parse string that consists of token delimited by space
or commas<br>
- Â Â // and return LinkedHashMap<br>
- Â Â private LinkedList<String> stringToList(String str)
{<br>
- Â Â Â Â LinkedList<String> ll = new
LinkedList<>();<br>
-<br>
- Â Â Â Â // comma and space are valid delimiters<br>
- Â Â Â Â StringTokenizer st = new StringTokenizer(str, ", ");<br>
- Â Â Â Â while (st.hasMoreTokens()) {<br>
- Â Â Â Â Â Â String s = st.nextToken();<br>
- Â Â Â Â Â Â if (!ll.contains(s)) {<br>
- Â Â Â Â Â Â Â Â ll.add(s);<br>
+ Â Â private static ArrayList<String> searchlist;<br>
+ Â Â private static ArrayList<String> nameservers;<br>
+<br>
+ Â Â // Parse string that consists of token delimited by space<br>
+ Â Â // and return ArrayList. Refer to
ResolverConfigurationImpl.c and<br>
+ Â Â // strappend to see how the string is created.<br>
+ Â Â private ArrayList<String> stringToList(String str)
{<br>
+ Â Â Â Â // String is delimited by space.<br>
+ Â Â Â Â String[] tokens = str.split(" ");<br>
+ Â Â Â Â ArrayList<String> l = new
ArrayList<>(tokens.length);<br>
+ Â Â Â Â for (String s : tokens) {<br>
+ Â Â Â Â Â Â if (!l.contains(s)) {<br>
+ Â Â Â Â Â Â Â Â l.add(s);<br>
       }<br>
     }<br>
- Â Â Â Â return ll;<br>
+ Â Â Â Â l.trimToSize();<br>
+ Â Â Â Â return l;<br>
+ Â Â }<br>
+<br>
+ Â Â // Parse string that consists of token delimited by space<br>
+   // and return ArrayList. Refer to
ResolverConfigurationImpl.c and<br>
+ Â Â // strappend to see how the string is created.<br>
+ Â Â // In addition to splitting the string, converts IPv6
addresses to<br>
+ Â Â // BSD-style.<br>
+ Â Â private ArrayList<String> addressesToList(String
str) {<br>
+ Â Â Â Â // String is delimited by space<br>
+ Â Â Â Â String[] tokens = str.split(" ");<br>
+ Â Â Â Â ArrayList<String> l = new
ArrayList<>(tokens.length);<br>
+<br>
+ Â Â Â Â for (String s : tokens) {<br>
+ Â Â Â Â Â Â if (!s.isEmpty()) {<br>
+ Â Â Â Â Â Â Â Â if (s.indexOf(':') >= 0 &&
s.charAt(0) != '[') {<br>
+ Â Â Â Â Â Â Â Â Â Â // Not BSD style<br>
+ Â Â Â Â Â Â Â Â Â Â s = '[' + s + ']';<br>
+ Â Â Â Â Â Â Â Â }<br>
+ Â Â Â Â Â Â Â Â if (!l.contains(s)) {<br>
+ Â Â Â Â Â Â Â Â Â Â l.add(s);<br>
+ Â Â Â Â Â Â Â Â }<br>
+ Â Â Â Â Â Â }<br>
+ Â Â Â Â }<br>
+ Â Â Â Â l.trimToSize();<br>
+ Â Â Â Â return l;<br>
   }<br>
 <br>
   // Load DNS configuration from OS<br>
@@ -81,28 +106,34 @@ public class ResolverConfigurationImpl<br>
   private void loadConfig() {<br>
     assert Thread.holdsLock(lock);<br>
 <br>
- Â Â Â Â // if address have changed then DNS probably changed
as well;<br>
- Â Â Â Â // otherwise check if cached settings have expired.<br>
- Â Â Â Â //<br>
+ Â Â Â Â // A change in the network address of the machine
usually indicates<br>
+ Â Â Â Â // a change in DNS configuration too so we always
refresh the config<br>
+ Â Â Â Â // after such a change.<br>
     if (changed) {<br>
       changed = false;<br>
     } else {<br>
+ Â Â Â Â Â Â // Otherwise we refresh if TIMEOUT_NANOS has
passed since last<br>
+ Â Â Â Â Â Â // load.<br>
       if (lastRefresh >= 0) {<br>
- Â Â Â Â Â Â Â Â long currTime = System.currentTimeMillis();<br>
- Â Â Â Â Â Â Â Â if ((currTime - lastRefresh) < TIMEOUT) {<br>
+ Â Â Â Â Â Â Â Â long currTime = System.nanoTime();<br>
+ Â Â Â Â Â Â Â Â if ((currTime - lastRefresh) <
TIMEOUT_NANOS) {<br>
           return;<br>
         }<br>
       }<br>
     }<br>
 <br>
- Â Â Â Â // load DNS configuration, update timestamp, create<br>
- Â Â Â Â // new HashMaps from the loaded configuration<br>
- Â Â Â Â //<br>
+ Â Â Â Â // Native code that uses Windows API to find out the
DNS server<br>
+ Â Â Â Â // addresses and search suffixes. It builds a
space-delimited string<br>
+ Â Â Â Â // of nameservers and domain suffixes and sets them
to the static<br>
+ Â Â Â Â // os_nameservers and os_searchlist. We then split
these into Java<br>
+ Â Â Â Â // Lists here.<br>
     loadDNSconfig0();<br>
 <br>
- Â Â Â Â lastRefresh = System.currentTimeMillis();<br>
+ Â Â Â Â // Record the time of update and refresh the lists of
addresses /<br>
+ Â Â Â Â // domain suffixes.<br>
+ Â Â Â Â lastRefresh = System.nanoTime();<br>
     searchlist = stringToList(os_searchlist);<br>
- Â Â Â Â nameservers = stringToList(os_nameservers);<br>
+ Â Â Â Â nameservers = addressesToList(os_nameservers);<br>
     os_searchlist = null;            // can be
GC'ed<br>
     os_nameservers = null;<br>
   }<br>
diff --git
a/src/java.base/windows/native/libnet/NetworkInterface_winXP.c
b/src/java.base/windows/native/libnet/NetworkInterface_winXP.c<br>
index f2368bafcb..297a1561ef 100644<br>
---
a/src/java.base/windows/native/libnet/NetworkInterface_winXP.c<br>
+++
b/src/java.base/windows/native/libnet/NetworkInterface_winXP.c<br>
@@ -73,8 +73,8 @@ const int MAX_TRIES = 3;<br>
 * for each adapter on the system. Returned in *adapters.<br>
 * Buffer is malloc'd and must be freed (unless error
returned)<br>
 */<br>
-static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES
**adapters) {<br>
- Â Â DWORD ret, flags;<br>
+int getAdapters (JNIEnv *env, int flags, IP_ADAPTER_ADDRESSES
**adapters) {<br>
+ Â Â DWORD ret;<br>
   IP_ADAPTER_ADDRESSES *adapterInfo;<br>
   ULONG len;<br>
   int try;<br>
@@ -87,9 +87,6 @@ static int getAdapters (JNIEnv *env,
IP_ADAPTER_ADDRESSES **adapters) {<br>
   }<br>
 <br>
   len = BUFF_SIZE;<br>
- Â Â flags = GAA_FLAG_SKIP_DNS_SERVER;<br>
- Â Â flags |= GAA_FLAG_SKIP_MULTICAST;<br>
- Â Â flags |= GAA_FLAG_INCLUDE_PREFIX;<br>
   ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL,
adapterInfo, &len);<br>
 <br>
   for (try = 0; ret == ERROR_BUFFER_OVERFLOW && try
< MAX_TRIES; ++try) {<br>
@@ -240,7 +237,7 @@ static int ipinflen = 2048;<br>
 */<br>
 int getAllInterfacesAndAddresses (JNIEnv *env, netif
**netifPP)<br>
 {<br>
- Â Â DWORD ret;<br>
+ Â Â DWORD ret, flags;<br>
   MIB_IPADDRTABLE *tableP;<br>
   IP_ADAPTER_ADDRESSES *ptr, *adapters=NULL;<br>
   ULONG len=ipinflen, count=0;<br>
@@ -296,7 +293,11 @@ int getAllInterfacesAndAddresses (JNIEnv
*env, netif **netifPP)<br>
     }<br>
   }<br>
   free(tableP);<br>
- Â Â ret = getAdapters (env, &adapters);<br>
+<br>
+ Â Â flags = GAA_FLAG_SKIP_DNS_SERVER;<br>
+ Â Â flags |= GAA_FLAG_SKIP_MULTICAST;<br>
+ Â Â flags |= GAA_FLAG_INCLUDE_PREFIX;<br>
+ Â Â ret = getAdapters (env, flags, &adapters);<br>
   if (ret != ERROR_SUCCESS) {<br>
     goto err;<br>
   }<br>
diff --git
a/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c
b/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c<br>
index 13b28044a5..85a7935314 100644<br>
---
a/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c<br>
+++
b/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c<br>
@@ -1,5 +1,5 @@<br>
 /*<br>
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates.
All rights reserved.<br>
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates.
All rights reserved.<br>
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
HEADER.<br>
 *<br>
 * This code is free software; you can redistribute it and/or
modify it<br>
@@ -30,6 +30,7 @@<br>
 #include <iprtrmib.h><br>
 #include <time.h><br>
 #include <assert.h><br>
+#include <winsock2.h><br>
 #include <iphlpapi.h><br>
 <br>
 #include "jni_util.h"<br>
@@ -48,6 +49,8 @@<br>
 static jfieldID searchlistID;<br>
 static jfieldID nameserversID;<br>
 <br>
+extern int getAdapters(JNIEnv *env, int flags,
IP_ADAPTER_ADDRESSES **adapters);<br>
+<br>
 /*<br>
 * Utility routine to append s2 to s1 with a space delimiter.<br>
 *  strappend(s1="abc", "def")  => "abc def"<br>
@@ -72,29 +75,19 @@ void strappend(char *s1, char *s2) {<br>
 }<br>
 <br>
 /*<br>
- * Windows 2000/XP<br>
- *<br>
- * Use registry approach based on settings described in
Appendix C<br>
- * of "Microsoft Windows 2000 TCP/IP Implementation Details".<br>
- *<br>
- * DNS suffix list is obtained from SearchList registry
setting. If<br>
- * this is not specified we compile suffix list based on the<br>
- * per-connection domain suffix.<br>
- *<br>
- * DNS name servers and domain settings are on a
per-connection<br>
- * basic. We therefore enumerate the network adapters to get
the<br>
- * names of each adapter and then query the corresponding
registry<br>
- * settings to obtain NameServer/DhcpNameServer and
Domain/DhcpDomain.<br>
+ * Use DNS server addresses returned by GetAdaptersAddresses
for currently<br>
+ * active interfaces.<br>
 */<br>
-static int loadConfig(char *sl, char *ns) {<br>
- Â Â IP_ADAPTER_INFO *adapterP;<br>
- Â Â ULONG size;<br>
- Â Â DWORD ret;<br>
+static int loadConfig(JNIEnv *env, char *sl, char *ns) {<br>
+ Â Â IP_ADAPTER_ADDRESSES *adapters, *adapter;<br>
+ Â Â IP_ADAPTER_DNS_SERVER_ADDRESS *dnsServer;<br>
+ Â Â SOCKADDR *address;<br>
+ Â Â IP_ADAPTER_DNS_SUFFIX *suffix;<br>
+ Â Â DWORD ret, flags;<br>
   DWORD dwLen;<br>
   ULONG ulType;<br>
   char result[MAX_STR_LEN];<br>
   HANDLE hKey;<br>
- Â Â int gotSearchList = 0;<br>
 <br>
   /*<br>
   * First see if there is a global suffix list specified.<br>
@@ -112,122 +105,58 @@ static int loadConfig(char *sl, char
*ns) {<br>
       assert(ulType == REG_SZ);<br>
       if (strlen(result) > 0) {<br>
         strappend(sl, result);<br>
- Â Â Â Â Â Â Â Â gotSearchList = 1;<br>
       }<br>
     }<br>
     RegCloseKey(hKey);<br>
   }<br>
 <br>
- Â Â /*<br>
- Â Â * Ask the IP Helper library to enumerate the adapters<br>
- Â Â */<br>
- Â Â size = sizeof(IP_ADAPTER_INFO);<br>
- Â Â adapterP = (IP_ADAPTER_INFO *)malloc(size);<br>
- Â Â if (adapterP == NULL) {<br>
- Â Â Â Â return STS_ERROR;<br>
- Â Â }<br>
- Â Â ret = GetAdaptersInfo(adapterP, &size);<br>
- Â Â if (ret == ERROR_BUFFER_OVERFLOW) {<br>
- Â Â Â Â IP_ADAPTER_INFO *newAdapterP = (IP_ADAPTER_INFO
*)realloc(adapterP, size);<br>
- Â Â Â Â if (newAdapterP == NULL) {<br>
- Â Â Â Â Â Â free(adapterP);<br>
- Â Â Â Â Â Â return STS_ERROR;<br>
- Â Â Â Â }<br>
- Â Â Â Â adapterP = newAdapterP;<br>
 <br>
- Â Â Â Â ret = GetAdaptersInfo(adapterP, &size);<br>
+ Â Â // We only need DNS server addresses so skip everything
else.<br>
+ Â Â flags = GAA_FLAG_SKIP_UNICAST;<br>
+ Â Â flags |= GAA_FLAG_SKIP_ANYCAST;<br>
+ Â Â flags |= GAA_FLAG_SKIP_MULTICAST;<br>
+ Â Â flags |= GAA_FLAG_SKIP_FRIENDLY_NAME;<br>
+ Â Â ret = getAdapters(env, flags, &adapters);<br>
+ Â Â if (ret != ERROR_SUCCESS) {<br>
+ Â Â Â Â return STS_ERROR;<br>
   }<br>
 <br>
- Â Â /*<br>
- Â Â * Iterate through the list of adapters as registry
settings are<br>
- Â Â * keyed on the adapter name (GUID).<br>
- Â Â */<br>
- Â Â if (ret == ERROR_SUCCESS) {<br>
- Â Â Â Â IP_ADAPTER_INFO *curr = adapterP;<br>
- Â Â Â Â while (curr != NULL) {<br>
- Â Â Â Â Â Â char key[MAX_STR_LEN];<br>
-<br>
- Â Â Â Â Â Â sprintf(key,<br>
- Â Â Â Â Â Â Â
 "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s",<br>
- Â Â Â Â Â Â Â Â curr->AdapterName);<br>
-<br>
- Â Â Â Â Â Â ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,<br>
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â key,<br>
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â 0,<br>
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â KEY_READ,<br>
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â (PHKEY)&hKey);<br>
- Â Â Â Â Â Â if (ret == ERROR_SUCCESS) {<br>
- Â Â Â Â Â Â Â Â DWORD enableDhcp = 0;<br>
-<br>
- Â Â Â Â Â Â Â Â /*<br>
- Â Â Â Â Â Â Â Â * Is DHCP enabled on this interface<br>
- Â Â Â Â Â Â Â Â */<br>
- Â Â Â Â Â Â Â Â dwLen = sizeof(enableDhcp);<br>
- Â Â Â Â Â Â Â Â ret = RegQueryValueEx(hKey, "EnableDhcp",
NULL, &ulType,<br>
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â (LPBYTE)&enableDhcp,
&dwLen);<br>
-<br>
- Â Â Â Â Â Â Â Â /*<br>
- Â Â Â Â Â Â Â Â * If we don't have the suffix list when get
the Domain<br>
- Â Â Â Â Â Â Â Â * or DhcpDomain. If DHCP is enabled then
Domain overides<br>
- Â Â Â Â Â Â Â Â * DhcpDomain<br>
- Â Â Â Â Â Â Â Â */<br>
- Â Â Â Â Â Â Â Â if (!gotSearchList) {<br>
- Â Â Â Â Â Â Â Â Â Â result[0] = '\0';<br>
- Â Â Â Â Â Â Â Â Â Â dwLen = sizeof(result);<br>
- Â Â Â Â Â Â Â Â Â Â ret = RegQueryValueEx(hKey, "Domain",
NULL, &ulType,<br>
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â (LPBYTE)&result,
&dwLen);<br>
- Â Â Â Â Â Â Â Â Â Â if (((ret != ERROR_SUCCESS) ||
(strlen(result) == 0)) &&<br>
- Â Â Â Â Â Â Â Â Â Â Â Â enableDhcp) {<br>
- Â Â Â Â Â Â Â Â Â Â Â Â dwLen = sizeof(result);<br>
- Â Â Â Â Â Â Â Â Â Â Â Â ret = RegQueryValueEx(hKey,
"DhcpDomain", NULL, &ulType,<br>
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
 (LPBYTE)&result, &dwLen);<br>
- Â Â Â Â Â Â Â Â Â Â }<br>
- Â Â Â Â Â Â Â Â Â Â if (ret == ERROR_SUCCESS) {<br>
- Â Â Â Â Â Â Â Â Â Â Â Â assert(ulType == REG_SZ);<br>
- Â Â Â Â Â Â Â Â Â Â Â Â strappend(sl, result);<br>
- Â Â Â Â Â Â Â Â Â Â }<br>
- Â Â Â Â Â Â Â Â }<br>
-<br>
- Â Â Â Â Â Â Â Â /*<br>
- Â Â Â Â Â Â Â Â * Get DNS servers based on NameServer or
DhcpNameServer<br>
- Â Â Â Â Â Â Â Â * registry setting. If NameServer is set
then it overrides<br>
- Â Â Â Â Â Â Â Â * DhcpNameServer (even if DHCP is enabled).<br>
- Â Â Â Â Â Â Â Â */<br>
- Â Â Â Â Â Â Â Â result[0] = '\0';<br>
+ Â Â adapter = adapters;<br>
+ Â Â while (adapter != NULL) {<br>
+ Â Â Â Â // Only load config from enabled adapters.<br>
+ Â Â Â Â if (adapter->OperStatus == IfOperStatusUp) {<br>
+ Â Â Â Â Â Â dnsServer = adapter->FirstDnsServerAddress;<br>
+ Â Â Â Â Â Â while (dnsServer != NULL) {<br>
+ Â Â Â Â Â Â Â Â address = dnsServer->Address.lpSockaddr;<br>
         dwLen = sizeof(result);<br>
- Â Â Â Â Â Â Â Â ret = RegQueryValueEx(hKey, "NameServer",
NULL, &ulType,<br>
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â (LPBYTE)&result,
&dwLen);<br>
- Â Â Â Â Â Â Â Â if (((ret != ERROR_SUCCESS) ||
(strlen(result) == 0)) &&<br>
- Â Â Â Â Â Â Â Â Â Â enableDhcp) {<br>
- Â Â Â Â Â Â Â Â Â Â dwLen = sizeof(result);<br>
- Â Â Â Â Â Â Â Â Â Â ret = RegQueryValueEx(hKey,
"DhcpNameServer", NULL, &ulType,<br>
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
 (LPBYTE)&result, &dwLen);<br>
- Â Â Â Â Â Â Â Â }<br>
- Â Â Â Â Â Â Â Â if (ret == ERROR_SUCCESS) {<br>
- Â Â Â Â Â Â Â Â Â Â assert(ulType == REG_SZ);<br>
+ Â Â Â Â Â Â Â Â ret =
WSAAddressToStringA(dnsServer->Address.lpSockaddr,<br>
+ Â Â Â Â Â Â Â Â Â Â Â Â
 dnsServer->Address.iSockaddrLength, NULL,<br>
+ Â Â Â Â Â Â Â Â Â Â Â Â Â result, &dwLen);<br>
+ Â Â Â Â Â Â Â Â if (ret == 0) {<br>
           strappend(ns, result);<br>
         }<br>
 <br>
- Â Â Â Â Â Â Â Â /*<br>
- Â Â Â Â Â Â Â Â * Finished with this registry key<br>
- Â Â Â Â Â Â Â Â */<br>
- Â Â Â Â Â Â Â Â RegCloseKey(hKey);<br>
+ Â Â Â Â Â Â Â Â dnsServer = dnsServer->Next;<br>
       }<br>
 <br>
- Â Â Â Â Â Â /*<br>
- Â Â Â Â Â Â * Onto the next adapeter<br>
- Â Â Â Â Â Â */<br>
- Â Â Â Â Â Â curr = curr->Next;<br>
+ Â Â Â Â Â Â // Add connection-specific search domains in
addition to global one.<br>
+ Â Â Â Â Â Â suffix = adapter->FirstDnsSuffix;<br>
+ Â Â Â Â Â Â while (suffix != NULL) {<br>
+ Â Â Â Â Â Â Â Â ret = WideCharToMultiByte(CP_UTF8, 0,
suffix->String, -1,<br>
+ Â Â Â Â Â Â Â Â Â Â result, sizeof(result), NULL, NULL);<br>
+ Â Â Â Â Â Â Â Â if (ret != 0) {<br>
+ Â Â Â Â Â Â Â Â Â Â strappend(sl, result);<br>
+ Â Â Â Â Â Â Â Â }<br>
+<br>
+ Â Â Â Â Â Â Â Â suffix = suffix->Next;<br>
+ Â Â Â Â Â Â }<br>
     }<br>
- Â Â }<br>
 <br>
- Â Â /*<br>
- Â Â * Free the adpater structure<br>
- Â Â */<br>
- Â Â if (adapterP) {<br>
- Â Â Â Â free(adapterP);<br>
+ Â Â Â Â adapter = adapter->Next;<br>
   }<br>
 <br>
+ Â Â free(adapters);<br>
+<br>
   return STS_SL_FOUND & STS_NS_FOUND;<br>
 }<br>
 <br>
@@ -260,7 +189,7 @@
Java_sun_net_dns_ResolverConfigurationImpl_loadDNSconfig0(JNIEnv
*env, jclass cl<br>
   searchlist[0] = '\0';<br>
   nameservers[0] = '\0';<br>
 <br>
- Â Â if (loadConfig(searchlist, nameservers) != STS_ERROR) {<br>
+ Â Â if (loadConfig(env, searchlist, nameservers) !=
STS_ERROR) {<br>
 <br>
     /*<br>
     * Populate static fields in
sun.net.DefaultResolverConfiguration<br>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Sat, Dec 7, 2019 at 12:41
AM Alan Bateman <<a href="mailto:Alan.Bateman@oracle.com" target="_blank">Alan.Bateman@oracle.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On
06/12/2019 15:34, Aleks Efimov wrote:<br>
> :<br>
><br>
> I've created webrev with your latest changes - it could
be convenient <br>
> for other reviewers:<br>
> <a href="http://cr.openjdk.java.net/~aefimov/anuraaga/7006496/00" rel="noreferrer" target="_blank">http://cr.openjdk.java.net/~aefimov/anuraaga/7006496/00</a><br>
><br>
> I will happily sponsor this change once it gets necessary
approvals<br>
This could be split into two issues but since the code using <br>
StringTokenizer is changing significantly then we should
replace it with <br>
regex while we there.<br>
<br>
-Alan<br>
</blockquote>
</div>
</blockquote>
<br>
</div>
</blockquote></div></div>