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

Aleks Efimov aleksej.efimov at oracle.com
Tue Dec 24 10:12:17 UTC 2019


Hi Anuraag,

We need additional approval from openjdk reviewer. After that I will 
sponsor your change.

Merry Christmas and a Happy New Year,
Aleksei

On 18/12/2019 06:08, Anuraag Agrawal wrote:
> Hi Aleksei,
>
> Thanks for all the reviews, it's really helped a lot. Just wondering, 
> is there anything we need to go to finish getting approvals?
>
> Thanks,
> - Anuraag
>
> On Sat, Dec 14, 2019 at 12:35 AM Aleks Efimov 
> <aleksej.efimov at oracle.com <mailto:aleksej.efimov at oracle.com>> wrote:
>
>     Hi Anuraag,
>
>     Thank you for moving the site-local/link-local check to the native
>     code.
>     The latest version of your changes looks good to me. Webrev of it
>     can be viewed here:
>     http://cr.openjdk.java.net/~aefimov/anuraaga/7006496/03/
>
>     Our CI system is also happy with it.
>
>     With Best Regards,
>     Aleksei
>
>
>     On 12/12/2019 13:26, Anuraag Agrawal wrote:
>>     Hi Aleksei,
>>
>>     I've gone ahead and moved the site-local check to native code -
>>     it does reduce the chance of filling up our buffer, though the
>>     code is a bit more complicated. To get sockaddr_in6, I went ahead
>>     and switched the imports to net_util.h, which I noticed was used
>>     in other files. Let me know if it looks ok.
>>
>>     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 = 120000;
>>     +    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<String> searchlist;
>>     -    private static LinkedList<String> nameservers;
>>     -
>>     -    // Parse string that consists of token delimited by space or
>>     commas
>>     -    // and return LinkedHashMap
>>     -    private LinkedList<String> stringToList(String str) {
>>     -        LinkedList<String> 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<String> searchlist;
>>     +    private static ArrayList<String> 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<String> stringToList(String str) {
>>     +        // String is delimited by comma.
>>     +        String[] tokens = str.split(",");
>>     +        ArrayList<String> 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<String> addressesToList(String str) {
>>     +        // String is delimited by comma
>>     +        String[] tokens = str.split(",");
>>     +        ArrayList<String> 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();
>>     +        // Record the time of update and refresh the lists of
>>     addresses /
>>     +        // domain suffixes.
>>     +        lastRefresh = System.nanoTime();
>>              searchlist = stringToList(os_searchlist);
>>     -        nameservers = stringToList(os_nameservers);
>>     +        nameservers = addressesToList(os_nameservers);
>>              os_searchlist = null; // can be GC'ed
>>              os_nameservers = null;
>>          }
>>     diff --git
>>     a/src/java.base/windows/native/libnet/NetworkInterface_winXP.c
>>     b/src/java.base/windows/native/libnet/NetworkInterface_winXP.c
>>     index f2368bafcb..297a1561ef 100644
>>     --- a/src/java.base/windows/native/libnet/NetworkInterface_winXP.c
>>     +++ b/src/java.base/windows/native/libnet/NetworkInterface_winXP.c
>>     @@ -73,8 +73,8 @@ const int MAX_TRIES = 3;
>>       * for each adapter on the system. Returned in *adapters.
>>       * Buffer is malloc'd and must be freed (unless error returned)
>>       */
>>     -static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES
>>     **adapters) {
>>     -    DWORD ret, flags;
>>     +int getAdapters (JNIEnv *env, int flags, IP_ADAPTER_ADDRESSES
>>     **adapters) {
>>     +    DWORD ret;
>>          IP_ADAPTER_ADDRESSES *adapterInfo;
>>          ULONG len;
>>          int try;
>>     @@ -87,9 +87,6 @@ static int getAdapters (JNIEnv *env,
>>     IP_ADAPTER_ADDRESSES **adapters) {
>>          }
>>
>>          len = BUFF_SIZE;
>>     -    flags = GAA_FLAG_SKIP_DNS_SERVER;
>>     -    flags |= GAA_FLAG_SKIP_MULTICAST;
>>     -    flags |= GAA_FLAG_INCLUDE_PREFIX;
>>          ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL,
>>     adapterInfo, &len);
>>
>>          for (try = 0; ret == ERROR_BUFFER_OVERFLOW && try <
>>     MAX_TRIES; ++try) {
>>     @@ -240,7 +237,7 @@ static int ipinflen = 2048;
>>       */
>>      int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
>>      {
>>     -    DWORD ret;
>>     +    DWORD ret, flags;
>>          MIB_IPADDRTABLE *tableP;
>>          IP_ADAPTER_ADDRESSES *ptr, *adapters=NULL;
>>          ULONG len=ipinflen, count=0;
>>     @@ -296,7 +293,11 @@ int getAllInterfacesAndAddresses (JNIEnv
>>     *env, netif **netifPP)
>>              }
>>          }
>>          free(tableP);
>>     -    ret = getAdapters (env, &adapters);
>>     +
>>     +    flags = GAA_FLAG_SKIP_DNS_SERVER;
>>     +    flags |= GAA_FLAG_SKIP_MULTICAST;
>>     +    flags |= GAA_FLAG_INCLUDE_PREFIX;
>>     +    ret = getAdapters (env, flags, &adapters);
>>          if (ret != ERROR_SUCCESS) {
>>              goto err;
>>          }
>>     diff --git
>>     a/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c
>>     b/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c
>>     index 13b28044a5..580347540d 100644
>>     --- a/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c
>>     +++ b/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c
>>     @@ -1,5 +1,5 @@
>>      /*
>>     - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All
>>     rights reserved.
>>     + * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All
>>     rights reserved.
>>       * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>>       *
>>       * This code is free software; you can redistribute it and/or
>>     modify it
>>     @@ -24,14 +24,12 @@
>>       */
>>
>>      #include <stdlib.h>
>>     -#include <windows.h>
>>      #include <stdio.h>
>>      #include <stddef.h>
>>     -#include <iprtrmib.h>
>>      #include <time.h>
>>      #include <assert.h>
>>     -#include <iphlpapi.h>
>>
>>     +#include "net_util.h"
>>      #include "jni_util.h"
>>
>>      #define MAX_STR_LEN         256
>>     @@ -48,8 +46,10 @@
>>      static jfieldID searchlistID;
>>      static jfieldID nameserversID;
>>
>>     +extern int getAdapters(JNIEnv *env, int flags,
>>     IP_ADAPTER_ADDRESSES **adapters);
>>     +
>>      /*
>>     - * Utility routine to append s2 to s1 with a space delimiter.
>>     + * Utility routine to append s2 to s1 with a comma delimiter.
>>       *  strappend(s1="abc", "def")  => "abc def"
>>       *  strappend(s1="", "def")     => "def
>>       */
>>     @@ -60,41 +60,32 @@ void strappend(char *s1, char *s2) {
>>              return;
>>
>>          len = strlen(s1)+1;
>>     -    if (s1[0] != 0)                         /* needs space
>>     character */
>>     +    if (s1[0] != 0)                         /* needs comma
>>     character */
>>              len++;
>>          if (len + strlen(s2) > MAX_STR_LEN)     /* insufficient space */
>>              return;
>>
>>          if (s1[0] != 0) {
>>     -        strcat(s1, " ");
>>     +        strcat(s1, ",");
>>          }
>>          strcat(s1, s2);
>>      }
>>
>>      /*
>>     - * Windows 2000/XP
>>     - *
>>     - * Use registry approach based on settings described in Appendix C
>>     - * of "Microsoft Windows 2000 TCP/IP Implementation Details".
>>     - *
>>     - * DNS suffix list is obtained from SearchList registry setting. If
>>     - * this is not specified we compile suffix list based on the
>>     - * per-connection domain suffix.
>>     - *
>>     - * DNS name servers and domain settings are on a per-connection
>>     - * basic. We therefore enumerate the network adapters to get the
>>     - * names of each adapter and then query the corresponding registry
>>     - * settings to obtain NameServer/DhcpNameServer and
>>     Domain/DhcpDomain.
>>     + * Use DNS server addresses returned by GetAdaptersAddresses for
>>     currently
>>     + * active interfaces.
>>       */
>>     -static int loadConfig(char *sl, char *ns) {
>>     -    IP_ADAPTER_INFO *adapterP;
>>     -    ULONG size;
>>     -    DWORD ret;
>>     +static int loadConfig(JNIEnv *env, char *sl, char *ns) {
>>     +    IP_ADAPTER_ADDRESSES *adapters, *adapter;
>>     +    IP_ADAPTER_DNS_SERVER_ADDRESS *dnsServer;
>>     +    WCHAR *suffix;
>>     +    DWORD ret, flags;
>>          DWORD dwLen;
>>          ULONG ulType;
>>          char result[MAX_STR_LEN];
>>          HANDLE hKey;
>>     -    int gotSearchList = 0;
>>     +    SOCKADDR *sockAddr;
>>     +    struct sockaddr_in6 *sockAddrIpv6;
>>
>>          /*
>>           * First see if there is a global suffix list specified.
>>     @@ -112,122 +103,67 @@ static int loadConfig(char *sl, char *ns) {
>>                  assert(ulType == REG_SZ);
>>                  if (strlen(result) > 0) {
>>                      strappend(sl, result);
>>     -                gotSearchList = 1;
>>                  }
>>              }
>>              RegCloseKey(hKey);
>>          }
>>
>>     -    /*
>>     -     * Ask the IP Helper library to enumerate the adapters
>>     -     */
>>     -    size = sizeof(IP_ADAPTER_INFO);
>>     -    adapterP = (IP_ADAPTER_INFO *)malloc(size);
>>     -    if (adapterP == NULL) {
>>     -        return STS_ERROR;
>>     -    }
>>     -    ret = GetAdaptersInfo(adapterP, &size);
>>     -    if (ret == ERROR_BUFFER_OVERFLOW) {
>>     -        IP_ADAPTER_INFO *newAdapterP = (IP_ADAPTER_INFO
>>     *)realloc(adapterP, size);
>>     -        if (newAdapterP == NULL) {
>>     -            free(adapterP);
>>     -            return STS_ERROR;
>>     -        }
>>     -        adapterP = newAdapterP;
>>
>>     -        ret = GetAdaptersInfo(adapterP, &size);
>>     +    // We only need DNS server addresses so skip everything else.
>>     +    flags = GAA_FLAG_SKIP_UNICAST;
>>     +    flags |= GAA_FLAG_SKIP_ANYCAST;
>>     +    flags |= GAA_FLAG_SKIP_MULTICAST;
>>     +    flags |= GAA_FLAG_SKIP_FRIENDLY_NAME;
>>     +    ret = getAdapters(env, flags, &adapters);
>>     +    if (ret != ERROR_SUCCESS) {
>>     +        return STS_ERROR;
>>          }
>>
>>     -    /*
>>     -     * Iterate through the list of adapters as registry settings are
>>     -     * keyed on the adapter name (GUID).
>>     -     */
>>     -    if (ret == ERROR_SUCCESS) {
>>     -        IP_ADAPTER_INFO *curr = adapterP;
>>     -        while (curr != NULL) {
>>     -            char key[MAX_STR_LEN];
>>     -
>>     -            sprintf(key,
>>     -
>>      "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s",
>>     -                curr->AdapterName);
>>     -
>>     -            ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
>>     -                               key,
>>     -                               0,
>>     -                               KEY_READ,
>>     -                               (PHKEY)&hKey);
>>     -            if (ret == ERROR_SUCCESS) {
>>     -                DWORD enableDhcp = 0;
>>     -
>>     -                /*
>>     -                 * Is DHCP enabled on this interface
>>     -                 */
>>     -                dwLen = sizeof(enableDhcp);
>>     -                ret = RegQueryValueEx(hKey, "EnableDhcp", NULL,
>>     &ulType,
>>     - (LPBYTE)&enableDhcp, &dwLen);
>>     -
>>     -                /*
>>     -                 * If we don't have the suffix list when get the
>>     Domain
>>     -                 * or DhcpDomain. If DHCP is enabled then Domain
>>     overides
>>     -                 * DhcpDomain
>>     -                 */
>>     -                if (!gotSearchList) {
>>     -                    result[0] = '\0';
>>     -                    dwLen = sizeof(result);
>>     -                    ret = RegQueryValueEx(hKey, "Domain", NULL,
>>     &ulType,
>>     - (LPBYTE)&result, &dwLen);
>>     -                    if (((ret != ERROR_SUCCESS) ||
>>     (strlen(result) == 0)) &&
>>     -                        enableDhcp) {
>>     -                        dwLen = sizeof(result);
>>     -                        ret = RegQueryValueEx(hKey,
>>     "DhcpDomain", NULL, &ulType,
>>     -  (LPBYTE)&result, &dwLen);
>>     -                    }
>>     -                    if (ret == ERROR_SUCCESS) {
>>     -                        assert(ulType == REG_SZ);
>>     -                        strappend(sl, result);
>>     +    adapter = adapters;
>>     +    while (adapter != NULL) {
>>     +        // Only load config from enabled adapters.
>>     +        if (adapter->OperStatus == IfOperStatusUp) {
>>     +            dnsServer = adapter->FirstDnsServerAddress;
>>     +            while (dnsServer != NULL) {
>>     +                sockAddr = dnsServer->Address.lpSockaddr;
>>     +                if (sockAddr->sa_family == AF_INET6) {
>>     +                    sockAddrIpv6 = (struct sockaddr_in6 *)sockAddr;
>>     +                    if (sockAddrIpv6->sin6_scope_id != 0) {
>>     +                        // An address with a scope is either
>>     link-local or
>>     +                        // site-local, which aren't valid for
>>     DNS queries so
>>     +                        // we can skip them.
>>     +                        dnsServer = dnsServer->Next;
>>     +                        continue;
>>                          }
>>                      }
>>
>>     -                /*
>>     -                 * Get DNS servers based on NameServer or
>>     DhcpNameServer
>>     -                 * registry setting. If NameServer is set then
>>     it overrides
>>     -                 * DhcpNameServer (even if DHCP is enabled).
>>     -                 */
>>     -                result[0] = '\0';
>>                      dwLen = sizeof(result);
>>     -                ret = RegQueryValueEx(hKey, "NameServer", NULL,
>>     &ulType,
>>     - (LPBYTE)&result, &dwLen);
>>     -                if (((ret != ERROR_SUCCESS) || (strlen(result)
>>     == 0)) &&
>>     -                    enableDhcp) {
>>     -                    dwLen = sizeof(result);
>>     -                    ret = RegQueryValueEx(hKey,
>>     "DhcpNameServer", NULL, &ulType,
>>     -  (LPBYTE)&result, &dwLen);
>>     -                }
>>     -                if (ret == ERROR_SUCCESS) {
>>     -                    assert(ulType == REG_SZ);
>>     +                ret = WSAAddressToStringA(sockAddr,
>>     +  dnsServer->Address.iSockaddrLength, NULL,
>>     +                          result, &dwLen);
>>     +                if (ret == 0) {
>>                          strappend(ns, result);
>>                      }
>>
>>     -                /*
>>     -                 * Finished with this registry key
>>     -                 */
>>     -                RegCloseKey(hKey);
>>     +                dnsServer = dnsServer->Next;
>>                  }
>>
>>     -            /*
>>     -             * Onto the next adapeter
>>     -             */
>>     -            curr = curr->Next;
>>     +            // Add connection-specific search domains in
>>     addition to global one.
>>     +            suffix = adapter->DnsSuffix;
>>     +            if (suffix != NULL) {
>>     +                ret = WideCharToMultiByte(CP_UTF8, 0, suffix, -1,
>>     +                    result, sizeof(result), NULL, NULL);
>>     +                if (ret != 0) {
>>     +                    strappend(sl, result);
>>     +                }
>>     +            }
>>              }
>>     -    }
>>
>>     -    /*
>>     -     * Free the adpater structure
>>     -     */
>>     -    if (adapterP) {
>>     -        free(adapterP);
>>     +        adapter = adapter->Next;
>>          }
>>
>>     +    free(adapters);
>>     +
>>          return STS_SL_FOUND & STS_NS_FOUND;
>>      }
>>
>>     @@ -260,7 +196,7 @@
>>     Java_sun_net_dns_ResolverConfigurationImpl_loadDNSconfig0(JNIEnv
>>     *env, jclass cl
>>          searchlist[0] = '\0';
>>          nameservers[0] = '\0';
>>
>>     -    if (loadConfig(searchlist, nameservers) != STS_ERROR) {
>>     +    if (loadConfig(env, searchlist, nameservers) != STS_ERROR) {
>>
>>              /*
>>               * Populate static fields in
>>     sun.net.DefaultResolverConfiguration
>>
>>     On Thu, Dec 12, 2019 at 1:49 AM Anuraag Agrawal
>>     <anuraaga at gmail.com <mailto:anuraaga at gmail.com>> wrote:
>>
>>         Hi Aleksei,
>>
>>         Thanks for the feedback. I had thought about it but felt that
>>         it might be better to leave as much business logic to Java vs
>>         native as possible as a general principle. But if it makes
>>         more sense to do it native here happy to make the change :)
>>
>>         Thanks,
>>         - Anuraag
>>
>>         On Thu, Dec 12, 2019, 01:18 Aleks Efimov
>>         <aleksej.efimov at oracle.com
>>         <mailto:aleksej.efimov at oracle.com>> wrote:
>>
>>             Hi Anuraag,
>>
>>             The webrev with the latest patch can be viewed here:
>>             http://cr.openjdk.java.net/~aefimov/anuraaga/7006496/02
>>
>>             Thanks for replacing FirstDnsSuffix usages with
>>             DnsSuffix. I've double checked it with native application
>>             and can confirm that on my test host (Microsoft Windows
>>             Server 2016 Standard) the DnsSuffix contains correct
>>             information while the FirstDnsSuffix list is empty:
>>                     DNS Suffix (From DnsSuffix field):
>>             test.domain.com <http://test.domain.com>
>>                     Number of IP Adapter DNS suffix entries: 0
>>
>>                     DNS Suffix (From DnsSuffix field):
>>                     Number of IP Adapter DNS suffix entries: 0
>>
>>                     DNS Suffix (From DnsSuffix field):
>>                     Number of IP Adapter DNS suffix entries: 0
>>
>>                     DNS Suffix (From DnsSuffix field):
>>                     Number of IP Adapter DNS suffix entries: 0
>>
>>                     DNS Suffix (From DnsSuffix field):
>>             test.domain.com <http://test.domain.com>
>>                     Number of IP Adapter DNS suffix entries: 0
>>
>>             About site-local addresses: Maybe we can move the
>>             site-local address check to native code? i.e. analyze
>>             dnsServer->Address.lpSockaddr and filter out site-local
>>             addresses.
>>
>>             Testing:
>>             Run your latest patch though our CI system -  no issues
>>             detected.
>>
>>             -Aleksei
>>
>>             On 10/12/2019 06:59, Anuraag Agrawal wrote:
>>>             Hi Aleksei,
>>>
>>>             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
>>>
>>>             https://docs.microsoft.com/en-us/windows/win32/api/iptypes/ns-iptypes-ip_adapter_addresses_lh
>>>
>>>
>>>             Chromium has run into the same issue and just doesn't
>>>             use the field
>>>
>>>             https://cs.chromium.org/chromium/src/net/dns/dns_config_service_win.cc?q=firstdnssuffix&sq=package:chromium&dr=C&l=532
>>>
>>>             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.
>>>
>>>             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.
>>>
>>>             https://en.wikipedia.org/wiki/Unique_local_address
>>>
>>>             I used the same check for site-local as Inet6Address,
>>>             which just sees if the first bytes are fec0.
>>>
>>>             Thanks again - 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..b9a06461ab 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,65 @@ public class ResolverConfigurationImpl
>>>
>>>                  // Cache timeout (120 seconds) - should be
>>>             converted into property
>>>                  // or configured as preference in the future.
>>>             -    private static final int TIMEOUT = 120000;
>>>             +    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<String> searchlist;
>>>             -    private static LinkedList<String> nameservers;
>>>             -
>>>             -    // Parse string that consists of token delimited by
>>>             space or commas
>>>             -    // and return LinkedHashMap
>>>             -    private LinkedList<String> stringToList(String str) {
>>>             -        LinkedList<String> 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<String> searchlist;
>>>             +    private static ArrayList<String> 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<String> stringToList(String str) {
>>>             +        // String is delimited by comma.
>>>             +        String[] tokens = str.split(",");
>>>             +        ArrayList<String> 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<String> addressesToList(String str) {
>>>             +        // String is delimited by comma
>>>             +        String[] tokens = str.split(",");
>>>             +        ArrayList<String> l = new
>>>             ArrayList<>(tokens.length);
>>>             +
>>>             +        for (String s : tokens) {
>>>             +            if (!s.isEmpty()) {
>>>             +                if (s.indexOf(':') >= 0) {
>>>             +                    // IPv6
>>>             +                    if (s.charAt(0) != '[') {
>>>             +                        // Not BSD style
>>>             +                        s = '[' + s + ']';
>>>             +                    }
>>>             +                    if (s.startsWith("[fec0:")) {
>>>             +                        // Deprecated site-local
>>>             address. Windows adds
>>>             +                        // such addresses to IPv6
>>>             adapters without DNS
>>>             +                        // configured, but these should
>>>             not actually be
>>>             +                        // used for queries.
>>>             +                        continue;
>>>             +                    }
>>>             +                }
>>>             +                if (!l.contains(s)) {
>>>             +                    l.add(s);
>>>             +                }
>>>             +            }
>>>             +        }
>>>             +        l.trimToSize();
>>>             +        return l;
>>>                  }
>>>
>>>                  // Load DNS configuration from OS
>>>             @@ -81,28 +116,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();
>>>             +        // Record the time of update and refresh the
>>>             lists of addresses /
>>>             +        // domain suffixes.
>>>             +        lastRefresh = System.nanoTime();
>>>                      searchlist = stringToList(os_searchlist);
>>>             -        nameservers = stringToList(os_nameservers);
>>>             +        nameservers = addressesToList(os_nameservers);
>>>                      os_searchlist = null;               // can be GC'ed
>>>                      os_nameservers = null;
>>>                  }
>>>             diff --git
>>>             a/src/java.base/windows/native/libnet/NetworkInterface_winXP.c
>>>             b/src/java.base/windows/native/libnet/NetworkInterface_winXP.c
>>>             index f2368bafcb..297a1561ef 100644
>>>             ---
>>>             a/src/java.base/windows/native/libnet/NetworkInterface_winXP.c
>>>             +++
>>>             b/src/java.base/windows/native/libnet/NetworkInterface_winXP.c
>>>             @@ -73,8 +73,8 @@ const int MAX_TRIES = 3;
>>>               * for each adapter on the system. Returned in *adapters.
>>>               * Buffer is malloc'd and must be freed (unless error
>>>             returned)
>>>               */
>>>             -static int getAdapters (JNIEnv *env,
>>>             IP_ADAPTER_ADDRESSES **adapters) {
>>>             -    DWORD ret, flags;
>>>             +int getAdapters (JNIEnv *env, int flags,
>>>             IP_ADAPTER_ADDRESSES **adapters) {
>>>             +    DWORD ret;
>>>                  IP_ADAPTER_ADDRESSES *adapterInfo;
>>>                  ULONG len;
>>>                  int try;
>>>             @@ -87,9 +87,6 @@ static int getAdapters (JNIEnv *env,
>>>             IP_ADAPTER_ADDRESSES **adapters) {
>>>                  }
>>>
>>>                  len = BUFF_SIZE;
>>>             -    flags = GAA_FLAG_SKIP_DNS_SERVER;
>>>             -    flags |= GAA_FLAG_SKIP_MULTICAST;
>>>             -    flags |= GAA_FLAG_INCLUDE_PREFIX;
>>>                  ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL,
>>>             adapterInfo, &len);
>>>
>>>                  for (try = 0; ret == ERROR_BUFFER_OVERFLOW && try <
>>>             MAX_TRIES; ++try) {
>>>             @@ -240,7 +237,7 @@ static int ipinflen = 2048;
>>>               */
>>>              int getAllInterfacesAndAddresses (JNIEnv *env, netif
>>>             **netifPP)
>>>              {
>>>             -    DWORD ret;
>>>             +    DWORD ret, flags;
>>>                  MIB_IPADDRTABLE *tableP;
>>>                  IP_ADAPTER_ADDRESSES *ptr, *adapters=NULL;
>>>                  ULONG len=ipinflen, count=0;
>>>             @@ -296,7 +293,11 @@ int getAllInterfacesAndAddresses
>>>             (JNIEnv *env, netif **netifPP)
>>>                      }
>>>                  }
>>>                  free(tableP);
>>>             -    ret = getAdapters (env, &adapters);
>>>             +
>>>             +    flags = GAA_FLAG_SKIP_DNS_SERVER;
>>>             +    flags |= GAA_FLAG_SKIP_MULTICAST;
>>>             +    flags |= GAA_FLAG_INCLUDE_PREFIX;
>>>             +    ret = getAdapters (env, flags, &adapters);
>>>                  if (ret != ERROR_SUCCESS) {
>>>                      goto err;
>>>                  }
>>>             diff --git
>>>             a/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c
>>>             b/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c
>>>             index 13b28044a5..427d7c85eb 100644
>>>             ---
>>>             a/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c
>>>             +++
>>>             b/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c
>>>             @@ -1,5 +1,5 @@
>>>              /*
>>>             - * Copyright (c) 2002, 2013, Oracle and/or its
>>>             affiliates. All rights reserved.
>>>             + * Copyright (c) 2002, 2019, Oracle and/or its
>>>             affiliates. All rights reserved.
>>>               * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS
>>>             FILE HEADER.
>>>               *
>>>               * This code is free software; you can redistribute it
>>>             and/or modify it
>>>             @@ -30,6 +30,7 @@
>>>              #include <iprtrmib.h>
>>>              #include <time.h>
>>>              #include <assert.h>
>>>             +#include <winsock2.h>
>>>              #include <iphlpapi.h>
>>>
>>>              #include "jni_util.h"
>>>             @@ -48,8 +49,10 @@
>>>              static jfieldID searchlistID;
>>>              static jfieldID nameserversID;
>>>
>>>             +extern int getAdapters(JNIEnv *env, int flags,
>>>             IP_ADAPTER_ADDRESSES **adapters);
>>>             +
>>>              /*
>>>             - * Utility routine to append s2 to s1 with a space
>>>             delimiter.
>>>             + * Utility routine to append s2 to s1 with a comma
>>>             delimiter.
>>>               *  strappend(s1="abc", "def")  => "abc def"
>>>               *  strappend(s1="", "def")     => "def
>>>               */
>>>             @@ -60,41 +63,30 @@ void strappend(char *s1, char *s2) {
>>>                      return;
>>>
>>>                  len = strlen(s1)+1;
>>>             -    if (s1[0] != 0)       /* needs space character */
>>>             +    if (s1[0] != 0)       /* needs comma character */
>>>                      len++;
>>>                  if (len + strlen(s2) > MAX_STR_LEN)     /*
>>>             insufficient space */
>>>                      return;
>>>
>>>                  if (s1[0] != 0) {
>>>             -        strcat(s1, " ");
>>>             +        strcat(s1, ",");
>>>                  }
>>>                  strcat(s1, s2);
>>>              }
>>>
>>>              /*
>>>             - * Windows 2000/XP
>>>             - *
>>>             - * Use registry approach based on settings described in
>>>             Appendix C
>>>             - * of "Microsoft Windows 2000 TCP/IP Implementation
>>>             Details".
>>>             - *
>>>             - * DNS suffix list is obtained from SearchList registry
>>>             setting. If
>>>             - * this is not specified we compile suffix list based
>>>             on the
>>>             - * per-connection domain suffix.
>>>             - *
>>>             - * DNS name servers and domain settings are on a
>>>             per-connection
>>>             - * basic. We therefore enumerate the network adapters
>>>             to get the
>>>             - * names of each adapter and then query the
>>>             corresponding registry
>>>             - * settings to obtain NameServer/DhcpNameServer and
>>>             Domain/DhcpDomain.
>>>             + * Use DNS server addresses returned by
>>>             GetAdaptersAddresses for currently
>>>             + * active interfaces.
>>>               */
>>>             -static int loadConfig(char *sl, char *ns) {
>>>             -    IP_ADAPTER_INFO *adapterP;
>>>             -    ULONG size;
>>>             -    DWORD ret;
>>>             +static int loadConfig(JNIEnv *env, char *sl, char *ns) {
>>>             +    IP_ADAPTER_ADDRESSES *adapters, *adapter;
>>>             +    IP_ADAPTER_DNS_SERVER_ADDRESS *dnsServer;
>>>             +    WCHAR *suffix;
>>>             +    DWORD ret, flags;
>>>                  DWORD dwLen;
>>>                  ULONG ulType;
>>>                  char result[MAX_STR_LEN];
>>>                  HANDLE hKey;
>>>             -    int gotSearchList = 0;
>>>
>>>                  /*
>>>                   * First see if there is a global suffix list
>>>             specified.
>>>             @@ -112,122 +104,55 @@ static int loadConfig(char *sl,
>>>             char *ns) {
>>>                          assert(ulType == REG_SZ);
>>>                          if (strlen(result) > 0) {
>>>                              strappend(sl, result);
>>>             -                gotSearchList = 1;
>>>                          }
>>>                      }
>>>                      RegCloseKey(hKey);
>>>                  }
>>>
>>>             -    /*
>>>             -     * Ask the IP Helper library to enumerate the adapters
>>>             -     */
>>>             -    size = sizeof(IP_ADAPTER_INFO);
>>>             -    adapterP = (IP_ADAPTER_INFO *)malloc(size);
>>>             -    if (adapterP == NULL) {
>>>             -        return STS_ERROR;
>>>             -    }
>>>             -    ret = GetAdaptersInfo(adapterP, &size);
>>>             -    if (ret == ERROR_BUFFER_OVERFLOW) {
>>>             -        IP_ADAPTER_INFO *newAdapterP = (IP_ADAPTER_INFO
>>>             *)realloc(adapterP, size);
>>>             -        if (newAdapterP == NULL) {
>>>             -            free(adapterP);
>>>             -            return STS_ERROR;
>>>             -        }
>>>             -        adapterP = newAdapterP;
>>>
>>>             -        ret = GetAdaptersInfo(adapterP, &size);
>>>             +    // We only need DNS server addresses so skip
>>>             everything else.
>>>             +    flags = GAA_FLAG_SKIP_UNICAST;
>>>             +    flags |= GAA_FLAG_SKIP_ANYCAST;
>>>             +    flags |= GAA_FLAG_SKIP_MULTICAST;
>>>             +    flags |= GAA_FLAG_SKIP_FRIENDLY_NAME;
>>>             +    ret = getAdapters(env, flags, &adapters);
>>>             +    if (ret != ERROR_SUCCESS) {
>>>             +        return STS_ERROR;
>>>                  }
>>>
>>>             -    /*
>>>             -     * Iterate through the list of adapters as registry
>>>             settings are
>>>             -     * keyed on the adapter name (GUID).
>>>             -     */
>>>             -    if (ret == ERROR_SUCCESS) {
>>>             -        IP_ADAPTER_INFO *curr = adapterP;
>>>             -        while (curr != NULL) {
>>>             -            char key[MAX_STR_LEN];
>>>             -
>>>             -            sprintf(key,
>>>             -
>>>              "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s",
>>>             -  curr->AdapterName);
>>>             -
>>>             -            ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
>>>             -                               key,
>>>             -                               0,
>>>             - KEY_READ,
>>>             - (PHKEY)&hKey);
>>>             -            if (ret == ERROR_SUCCESS) {
>>>             -                DWORD enableDhcp = 0;
>>>             -
>>>             -                /*
>>>             -                 * Is DHCP enabled on this interface
>>>             -                 */
>>>             -                dwLen = sizeof(enableDhcp);
>>>             -                ret = RegQueryValueEx(hKey,
>>>             "EnableDhcp", NULL, &ulType,
>>>             - (LPBYTE)&enableDhcp, &dwLen);
>>>             -
>>>             -                /*
>>>             -                 * If we don't have the suffix list
>>>             when get the Domain
>>>             -                 * or DhcpDomain. If DHCP is enabled
>>>             then Domain overides
>>>             -                 * DhcpDomain
>>>             -                 */
>>>             -                if (!gotSearchList) {
>>>             -                    result[0] = '\0';
>>>             -                    dwLen = sizeof(result);
>>>             -                    ret = RegQueryValueEx(hKey,
>>>             "Domain", NULL, &ulType,
>>>             -     (LPBYTE)&result, &dwLen);
>>>             -                    if (((ret != ERROR_SUCCESS) ||
>>>             (strlen(result) == 0)) &&
>>>             -                        enableDhcp) {
>>>             -                        dwLen = sizeof(result);
>>>             -                        ret = RegQueryValueEx(hKey,
>>>             "DhcpDomain", NULL, &ulType,
>>>             -          (LPBYTE)&result, &dwLen);
>>>             -                    }
>>>             -                    if (ret == ERROR_SUCCESS) {
>>>             -                        assert(ulType == REG_SZ);
>>>             -                        strappend(sl, result);
>>>             -                    }
>>>             -                }
>>>             -
>>>             -                /*
>>>             -                 * Get DNS servers based on NameServer
>>>             or DhcpNameServer
>>>             -                 * registry setting. If NameServer is
>>>             set then it overrides
>>>             -                 * DhcpNameServer (even if DHCP is
>>>             enabled).
>>>             -                 */
>>>             -                result[0] = '\0';
>>>             +    adapter = adapters;
>>>             +    while (adapter != NULL) {
>>>             +        // Only load config from enabled adapters.
>>>             +        if (adapter->OperStatus == IfOperStatusUp) {
>>>             +            dnsServer = adapter->FirstDnsServerAddress;
>>>             +            while (dnsServer != NULL) {
>>>                              dwLen = sizeof(result);
>>>             -                ret = RegQueryValueEx(hKey,
>>>             "NameServer", NULL, &ulType,
>>>             - (LPBYTE)&result, &dwLen);
>>>             -                if (((ret != ERROR_SUCCESS) ||
>>>             (strlen(result) == 0)) &&
>>>             -                    enableDhcp) {
>>>             -                    dwLen = sizeof(result);
>>>             -                    ret = RegQueryValueEx(hKey,
>>>             "DhcpNameServer", NULL, &ulType,
>>>             -      (LPBYTE)&result, &dwLen);
>>>             -                }
>>>             -                if (ret == ERROR_SUCCESS) {
>>>             -                    assert(ulType == REG_SZ);
>>>             +                ret =
>>>             WSAAddressToStringA(dnsServer->Address.lpSockaddr,
>>>             +  dnsServer->Address.iSockaddrLength, NULL,
>>>             +                          result, &dwLen);
>>>             +                if (ret == 0) {
>>>                                  strappend(ns, result);
>>>                              }
>>>
>>>             -                /*
>>>             -                 * Finished with this registry key
>>>             -                 */
>>>             -                RegCloseKey(hKey);
>>>             +                dnsServer = dnsServer->Next;
>>>                          }
>>>
>>>             -            /*
>>>             -             * Onto the next adapeter
>>>             -             */
>>>             -            curr = curr->Next;
>>>             +            // Add connection-specific search domains
>>>             in addition to global one.
>>>             +            suffix = adapter->DnsSuffix;
>>>             +            if (suffix != NULL) {
>>>             +                ret = WideCharToMultiByte(CP_UTF8, 0,
>>>             suffix, -1,
>>>             +                    result, sizeof(result), NULL, NULL);
>>>             +                if (ret != 0) {
>>>             +                    strappend(sl, result);
>>>             +                }
>>>             +            }
>>>                      }
>>>             -    }
>>>
>>>             -    /*
>>>             -     * Free the adpater structure
>>>             -     */
>>>             -    if (adapterP) {
>>>             -        free(adapterP);
>>>             +        adapter = adapter->Next;
>>>                  }
>>>
>>>             +    free(adapters);
>>>             +
>>>                  return STS_SL_FOUND & STS_NS_FOUND;
>>>              }
>>>
>>>             @@ -260,7 +185,7 @@
>>>             Java_sun_net_dns_ResolverConfigurationImpl_loadDNSconfig0(JNIEnv
>>>             *env, jclass cl
>>>                  searchlist[0] = '\0';
>>>                  nameservers[0] = '\0';
>>>
>>>             -    if (loadConfig(searchlist, nameservers) != STS_ERROR) {
>>>             +    if (loadConfig(env, searchlist, nameservers) !=
>>>             STS_ERROR) {
>>>
>>>                      /*
>>>                       * Populate static fields in
>>>             sun.net.DefaultResolverConfiguration
>>>
>>>             On Tue, Dec 10, 2019 at 1:29 AM Aleks Efimov
>>>             <aleksej.efimov at oracle.com
>>>             <mailto:aleksej.efimov at oracle.com>> wrote:
>>>
>>>                 Hi Anuraag,
>>>
>>>                 The webrev with your latest changes can be found here:
>>>                 http://cr.openjdk.java.net/~aefimov/anuraaga/7006496/01
>>>
>>>                 The copyright changes looks good.
>>>
>>>                 The split by space also looks good with assumption
>>>                 that we will never get string with two spaces
>>>                 between IP addresses/DNS suffixes.
>>>
>>>                 I've also performed one test on Windows machine and
>>>                 it shows an issue with the retrieval of DNS suffixes:
>>>                 Method to call:
>>>                 sun.net.dns.ResolverConfiguration.open().searchlist()
>>>
>>>                 Old implementation returns:
>>>                     [test.domain.com <http://test.domain.com>]
>>>
>>>                 With the latest patch the suffixes list (searchlist)
>>>                 is empty:
>>>                     []
>>>
>>>                 I've collected the following information on the test
>>>                 host that might help you to fix the issue:
>>>
>>>                     The host OS: Microsoft Windows Server 2016 Standard
>>>
>>>                     Networking configuration (<---> is for masked
>>>                     addresses/info):
>>>                     $ ipconfig /all
>>>
>>>                     Windows IP Configuration
>>>
>>>                        Host Name . . . . . . . . . . . . : host-name-1
>>>                        Primary Dns Suffix  . . . . . . . :
>>>                        Node Type . . . . . . . . . . . . : Hybrid
>>>                        IP Routing Enabled. . . . . . . . : No
>>>                        WINS Proxy Enabled. . . . . . . . : No
>>>                        DNS Suffix Search List. . . . . . :
>>>                     test.domain.com <http://test.domain.com>
>>>
>>>                     Ethernet adapter Ethernet:
>>>
>>>                        Connection-specific DNS Suffix  . :
>>>                     test.domain.com <http://test.domain.com>
>>>                        Description . . . . . . . . . . . : Broadcom
>>>                     NetXtreme-E Virtual Function
>>>                        Physical Address. . . . . . . . . :
>>>                     <------------>
>>>                        DHCP Enabled. . . . . . . . . . . : Yes
>>>                        Autoconfiguration Enabled . . . . : Yes
>>>                        Link-local IPv6 Address . . . . . :
>>>                     <------------>
>>>                        IPv4 Address. . . . . . . . . . . :
>>>                     <------------>
>>>                        Subnet Mask . . . . . . . . . . . :
>>>                     <------------>
>>>                        Lease Obtained. . . . . . . . . . :
>>>                     <------------>
>>>                        Lease Expires . . . . . . . . . . :
>>>                     <------------>
>>>                        Default Gateway . . . . . . . . . :
>>>                     <------------>
>>>                        DHCP Server . . . . . . . . . . . :
>>>                     <------------>
>>>                        DHCPv6 Client DUID. . . . . . . . :
>>>                     <------------>
>>>                        DNS Servers . . . . . . . . . . . :
>>>                     <------------>
>>>                                                           
>>>                     <------------>
>>>                        NetBIOS over Tcpip. . . . . . . . : Disabled
>>>
>>>                     Tunnel adapter isatap.test.domain.com
>>>                     <http://isatap.test.domain.com>:
>>>
>>>                        Media State . . . . . . . . . . . : Media
>>>                     disconnected
>>>                        Connection-specific DNS Suffix  . :
>>>                     test.domain.com <http://test.domain.com>
>>>                        Description . . . . . . . . . . . : Microsoft
>>>                     ISATAP Adapter #3
>>>                        Physical Address. . . . . . . . . :
>>>                     <------------>
>>>                        DHCP Enabled. . . . . . . . . . . : No
>>>                        Autoconfiguration Enabled . . . . : Yes
>>>
>>>
>>>                 - Aleksei
>>>
>>>
>>>                 On 07/12/2019 09:44, Anuraag Agrawal wrote:
>>>>                 Hi all,
>>>>
>>>>                 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.
>>>>
>>>>                 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.
>>>>
>>>>                 Inline diff 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..47065e805e 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 = 120000;
>>>>                 +    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<String> searchlist;
>>>>                 -    private static LinkedList<String> nameservers;
>>>>                 -
>>>>                 -    // Parse string that consists of token
>>>>                 delimited by space or commas
>>>>                 -    // and return LinkedHashMap
>>>>                 -    private LinkedList<String> stringToList(String
>>>>                 str) {
>>>>                 -  LinkedList<String> 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<String> searchlist;
>>>>                 +    private static ArrayList<String> nameservers;
>>>>                 +
>>>>                 +    // Parse string that consists of token
>>>>                 delimited by space
>>>>                 +    // and return ArrayList. Refer to
>>>>                 ResolverConfigurationImpl.c and
>>>>                 +    // strappend to see how the string is created.
>>>>                 +    private ArrayList<String> stringToList(String
>>>>                 str) {
>>>>                 +        // String is delimited by space.
>>>>                 +        String[] tokens = str.split(" ");
>>>>                 +  ArrayList<String> 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 space
>>>>                 +    // 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<String>
>>>>                 addressesToList(String str) {
>>>>                 +        // String is delimited by space
>>>>                 +        String[] tokens = str.split(" ");
>>>>                 +  ArrayList<String> 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 space-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();
>>>>                 +        // Record the time of update and refresh
>>>>                 the lists of addresses /
>>>>                 +        // domain suffixes.
>>>>                 +        lastRefresh = System.nanoTime();
>>>>                          searchlist = stringToList(os_searchlist);
>>>>                 -        nameservers = stringToList(os_nameservers);
>>>>                 +        nameservers = addressesToList(os_nameservers);
>>>>                          os_searchlist = null; // can be GC'ed
>>>>                          os_nameservers = null;
>>>>                      }
>>>>                 diff --git
>>>>                 a/src/java.base/windows/native/libnet/NetworkInterface_winXP.c
>>>>                 b/src/java.base/windows/native/libnet/NetworkInterface_winXP.c
>>>>                 index f2368bafcb..297a1561ef 100644
>>>>                 ---
>>>>                 a/src/java.base/windows/native/libnet/NetworkInterface_winXP.c
>>>>                 +++
>>>>                 b/src/java.base/windows/native/libnet/NetworkInterface_winXP.c
>>>>                 @@ -73,8 +73,8 @@ const int MAX_TRIES = 3;
>>>>                   * for each adapter on the system. Returned in
>>>>                 *adapters.
>>>>                   * Buffer is malloc'd and must be freed (unless
>>>>                 error returned)
>>>>                   */
>>>>                 -static int getAdapters (JNIEnv *env,
>>>>                 IP_ADAPTER_ADDRESSES **adapters) {
>>>>                 -    DWORD ret, flags;
>>>>                 +int getAdapters (JNIEnv *env, int flags,
>>>>                 IP_ADAPTER_ADDRESSES **adapters) {
>>>>                 +    DWORD ret;
>>>>                      IP_ADAPTER_ADDRESSES *adapterInfo;
>>>>                      ULONG len;
>>>>                      int try;
>>>>                 @@ -87,9 +87,6 @@ static int getAdapters (JNIEnv
>>>>                 *env, IP_ADAPTER_ADDRESSES **adapters) {
>>>>                      }
>>>>
>>>>                      len = BUFF_SIZE;
>>>>                 -    flags = GAA_FLAG_SKIP_DNS_SERVER;
>>>>                 -    flags |= GAA_FLAG_SKIP_MULTICAST;
>>>>                 -    flags |= GAA_FLAG_INCLUDE_PREFIX;
>>>>                      ret = GetAdaptersAddresses(AF_UNSPEC, flags,
>>>>                 NULL, adapterInfo, &len);
>>>>
>>>>                      for (try = 0; ret == ERROR_BUFFER_OVERFLOW &&
>>>>                 try < MAX_TRIES; ++try) {
>>>>                 @@ -240,7 +237,7 @@ static int ipinflen = 2048;
>>>>                   */
>>>>                  int getAllInterfacesAndAddresses (JNIEnv *env,
>>>>                 netif **netifPP)
>>>>                  {
>>>>                 -    DWORD ret;
>>>>                 +    DWORD ret, flags;
>>>>                      MIB_IPADDRTABLE *tableP;
>>>>                      IP_ADAPTER_ADDRESSES *ptr, *adapters=NULL;
>>>>                      ULONG len=ipinflen, count=0;
>>>>                 @@ -296,7 +293,11 @@ int
>>>>                 getAllInterfacesAndAddresses (JNIEnv *env, netif
>>>>                 **netifPP)
>>>>                          }
>>>>                      }
>>>>                      free(tableP);
>>>>                 -    ret = getAdapters (env, &adapters);
>>>>                 +
>>>>                 +    flags = GAA_FLAG_SKIP_DNS_SERVER;
>>>>                 +    flags |= GAA_FLAG_SKIP_MULTICAST;
>>>>                 +    flags |= GAA_FLAG_INCLUDE_PREFIX;
>>>>                 +    ret = getAdapters (env, flags, &adapters);
>>>>                      if (ret != ERROR_SUCCESS) {
>>>>                          goto err;
>>>>                      }
>>>>                 diff --git
>>>>                 a/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c
>>>>                 b/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c
>>>>                 index 13b28044a5..85a7935314 100644
>>>>                 ---
>>>>                 a/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c
>>>>                 +++
>>>>                 b/src/java.base/windows/native/libnet/ResolverConfigurationImpl.c
>>>>                 @@ -1,5 +1,5 @@
>>>>                  /*
>>>>                 - * Copyright (c) 2002, 2013, Oracle and/or its
>>>>                 affiliates. All rights reserved.
>>>>                 + * Copyright (c) 2002, 2019, Oracle and/or its
>>>>                 affiliates. All rights reserved.
>>>>                   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR
>>>>                 THIS FILE HEADER.
>>>>                   *
>>>>                   * This code is free software; you can
>>>>                 redistribute it and/or modify it
>>>>                 @@ -30,6 +30,7 @@
>>>>                  #include <iprtrmib.h>
>>>>                  #include <time.h>
>>>>                  #include <assert.h>
>>>>                 +#include <winsock2.h>
>>>>                  #include <iphlpapi.h>
>>>>
>>>>                  #include "jni_util.h"
>>>>                 @@ -48,6 +49,8 @@
>>>>                  static jfieldID searchlistID;
>>>>                  static jfieldID nameserversID;
>>>>
>>>>                 +extern int getAdapters(JNIEnv *env, int flags,
>>>>                 IP_ADAPTER_ADDRESSES **adapters);
>>>>                 +
>>>>                  /*
>>>>                   * Utility routine to append s2 to s1 with a space
>>>>                 delimiter.
>>>>                   *  strappend(s1="abc", "def")  => "abc def"
>>>>                 @@ -72,29 +75,19 @@ void strappend(char *s1, char
>>>>                 *s2) {
>>>>                  }
>>>>
>>>>                  /*
>>>>                 - * Windows 2000/XP
>>>>                 - *
>>>>                 - * Use registry approach based on settings
>>>>                 described in Appendix C
>>>>                 - * of "Microsoft Windows 2000 TCP/IP
>>>>                 Implementation Details".
>>>>                 - *
>>>>                 - * DNS suffix list is obtained from SearchList
>>>>                 registry setting. If
>>>>                 - * this is not specified we compile suffix list
>>>>                 based on the
>>>>                 - * per-connection domain suffix.
>>>>                 - *
>>>>                 - * DNS name servers and domain settings are on a
>>>>                 per-connection
>>>>                 - * basic. We therefore enumerate the network
>>>>                 adapters to get the
>>>>                 - * names of each adapter and then query the
>>>>                 corresponding registry
>>>>                 - * settings to obtain NameServer/DhcpNameServer
>>>>                 and Domain/DhcpDomain.
>>>>                 + * Use DNS server addresses returned by
>>>>                 GetAdaptersAddresses for currently
>>>>                 + * active interfaces.
>>>>                   */
>>>>                 -static int loadConfig(char *sl, char *ns) {
>>>>                 -    IP_ADAPTER_INFO *adapterP;
>>>>                 -    ULONG size;
>>>>                 -    DWORD ret;
>>>>                 +static int loadConfig(JNIEnv *env, char *sl, char
>>>>                 *ns) {
>>>>                 +    IP_ADAPTER_ADDRESSES *adapters, *adapter;
>>>>                 +  IP_ADAPTER_DNS_SERVER_ADDRESS *dnsServer;
>>>>                 +    SOCKADDR *address;
>>>>                 +    IP_ADAPTER_DNS_SUFFIX *suffix;
>>>>                 +    DWORD ret, flags;
>>>>                      DWORD dwLen;
>>>>                      ULONG ulType;
>>>>                      char result[MAX_STR_LEN];
>>>>                      HANDLE hKey;
>>>>                 -    int gotSearchList = 0;
>>>>
>>>>                      /*
>>>>                       * First see if there is a global suffix list
>>>>                 specified.
>>>>                 @@ -112,122 +105,58 @@ static int loadConfig(char
>>>>                 *sl, char *ns) {
>>>>                              assert(ulType == REG_SZ);
>>>>                              if (strlen(result) > 0) {
>>>>                  strappend(sl, result);
>>>>                 -  gotSearchList = 1;
>>>>                              }
>>>>                          }
>>>>                          RegCloseKey(hKey);
>>>>                      }
>>>>
>>>>                 -    /*
>>>>                 -     * Ask the IP Helper library to enumerate the
>>>>                 adapters
>>>>                 -     */
>>>>                 -    size = sizeof(IP_ADAPTER_INFO);
>>>>                 -    adapterP = (IP_ADAPTER_INFO *)malloc(size);
>>>>                 -    if (adapterP == NULL) {
>>>>                 -        return STS_ERROR;
>>>>                 -    }
>>>>                 -    ret = GetAdaptersInfo(adapterP, &size);
>>>>                 -    if (ret == ERROR_BUFFER_OVERFLOW) {
>>>>                 -        IP_ADAPTER_INFO *newAdapterP =
>>>>                 (IP_ADAPTER_INFO *)realloc(adapterP, size);
>>>>                 -        if (newAdapterP == NULL) {
>>>>                 -            free(adapterP);
>>>>                 -            return STS_ERROR;
>>>>                 -        }
>>>>                 -        adapterP = newAdapterP;
>>>>
>>>>                 -        ret = GetAdaptersInfo(adapterP, &size);
>>>>                 +    // We only need DNS server addresses so skip
>>>>                 everything else.
>>>>                 +    flags = GAA_FLAG_SKIP_UNICAST;
>>>>                 +    flags |= GAA_FLAG_SKIP_ANYCAST;
>>>>                 +    flags |= GAA_FLAG_SKIP_MULTICAST;
>>>>                 +    flags |= GAA_FLAG_SKIP_FRIENDLY_NAME;
>>>>                 +    ret = getAdapters(env, flags, &adapters);
>>>>                 +    if (ret != ERROR_SUCCESS) {
>>>>                 +        return STS_ERROR;
>>>>                      }
>>>>
>>>>                 -    /*
>>>>                 -     * Iterate through the list of adapters as
>>>>                 registry settings are
>>>>                 -     * keyed on the adapter name (GUID).
>>>>                 -     */
>>>>                 -    if (ret == ERROR_SUCCESS) {
>>>>                 -        IP_ADAPTER_INFO *curr = adapterP;
>>>>                 -        while (curr != NULL) {
>>>>                 -            char key[MAX_STR_LEN];
>>>>                 -
>>>>                 -            sprintf(key,
>>>>                 -
>>>>                  "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s",
>>>>                 -  curr->AdapterName);
>>>>                 -
>>>>                 -            ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
>>>>                 -     key,
>>>>                 -     0,
>>>>                 -     KEY_READ,
>>>>                 -     (PHKEY)&hKey);
>>>>                 -            if (ret == ERROR_SUCCESS) {
>>>>                 -                DWORD enableDhcp = 0;
>>>>                 -
>>>>                 -                /*
>>>>                 -                 * Is DHCP enabled on this interface
>>>>                 -                 */
>>>>                 -                dwLen = sizeof(enableDhcp);
>>>>                 -                ret = RegQueryValueEx(hKey,
>>>>                 "EnableDhcp", NULL, &ulType,
>>>>                 - (LPBYTE)&enableDhcp, &dwLen);
>>>>                 -
>>>>                 -                /*
>>>>                 -                 * If we don't have the suffix
>>>>                 list when get the Domain
>>>>                 -                 * or DhcpDomain. If DHCP is
>>>>                 enabled then Domain overides
>>>>                 -                 * DhcpDomain
>>>>                 -                 */
>>>>                 -                if (!gotSearchList) {
>>>>                 -  result[0] = '\0';
>>>>                 -                    dwLen = sizeof(result);
>>>>                 -                    ret = RegQueryValueEx(hKey,
>>>>                 "Domain", NULL, &ulType,
>>>>                 - (LPBYTE)&result, &dwLen);
>>>>                 -                    if (((ret != ERROR_SUCCESS) ||
>>>>                 (strlen(result) == 0)) &&
>>>>                 -  enableDhcp) {
>>>>                 -  dwLen = sizeof(result);
>>>>                 -                        ret =
>>>>                 RegQueryValueEx(hKey, "DhcpDomain", NULL, &ulType,
>>>>                 -  (LPBYTE)&result, &dwLen);
>>>>                 -                    }
>>>>                 -                    if (ret == ERROR_SUCCESS) {
>>>>                 -  assert(ulType == REG_SZ);
>>>>                 -  strappend(sl, result);
>>>>                 -                    }
>>>>                 -                }
>>>>                 -
>>>>                 -                /*
>>>>                 -                 * Get DNS servers based on
>>>>                 NameServer or DhcpNameServer
>>>>                 -                 * registry setting. If NameServer
>>>>                 is set then it overrides
>>>>                 -                 * DhcpNameServer (even if DHCP is
>>>>                 enabled).
>>>>                 -                 */
>>>>                 -                result[0] = '\0';
>>>>                 +    adapter = adapters;
>>>>                 +    while (adapter != NULL) {
>>>>                 +        // Only load config from enabled adapters.
>>>>                 +        if (adapter->OperStatus == IfOperStatusUp) {
>>>>                 +            dnsServer =
>>>>                 adapter->FirstDnsServerAddress;
>>>>                 +            while (dnsServer != NULL) {
>>>>                 +                address =
>>>>                 dnsServer->Address.lpSockaddr;
>>>>                                  dwLen = sizeof(result);
>>>>                 -                ret = RegQueryValueEx(hKey,
>>>>                 "NameServer", NULL, &ulType,
>>>>                 - (LPBYTE)&result, &dwLen);
>>>>                 -                if (((ret != ERROR_SUCCESS) ||
>>>>                 (strlen(result) == 0)) &&
>>>>                 -  enableDhcp) {
>>>>                 -                    dwLen = sizeof(result);
>>>>                 -                    ret = RegQueryValueEx(hKey,
>>>>                 "DhcpNameServer", NULL, &ulType,
>>>>                 -  (LPBYTE)&result, &dwLen);
>>>>                 -                }
>>>>                 -                if (ret == ERROR_SUCCESS) {
>>>>                 -  assert(ulType == REG_SZ);
>>>>                 +                ret =
>>>>                 WSAAddressToStringA(dnsServer->Address.lpSockaddr,
>>>>                 +  dnsServer->Address.iSockaddrLength, NULL,
>>>>                 +  result, &dwLen);
>>>>                 +                if (ret == 0) {
>>>>                  strappend(ns, result);
>>>>                                  }
>>>>
>>>>                 -                /*
>>>>                 -                 * Finished with this registry key
>>>>                 -                 */
>>>>                 -  RegCloseKey(hKey);
>>>>                 +                dnsServer = dnsServer->Next;
>>>>                              }
>>>>
>>>>                 -            /*
>>>>                 -             * Onto the next adapeter
>>>>                 -             */
>>>>                 -            curr = curr->Next;
>>>>                 +            // Add connection-specific search
>>>>                 domains in addition to global one.
>>>>                 +            suffix = adapter->FirstDnsSuffix;
>>>>                 +            while (suffix != NULL) {
>>>>                 +                ret = WideCharToMultiByte(CP_UTF8,
>>>>                 0, suffix->String, -1,
>>>>                 +                    result, sizeof(result), NULL,
>>>>                 NULL);
>>>>                 +                if (ret != 0) {
>>>>                 +  strappend(sl, result);
>>>>                 +                }
>>>>                 +
>>>>                 +                suffix = suffix->Next;
>>>>                 +            }
>>>>                          }
>>>>                 -    }
>>>>
>>>>                 -    /*
>>>>                 -     * Free the adpater structure
>>>>                 -     */
>>>>                 -    if (adapterP) {
>>>>                 -        free(adapterP);
>>>>                 +        adapter = adapter->Next;
>>>>                      }
>>>>
>>>>                 +    free(adapters);
>>>>                 +
>>>>                      return STS_SL_FOUND & STS_NS_FOUND;
>>>>                  }
>>>>
>>>>                 @@ -260,7 +189,7 @@
>>>>                 Java_sun_net_dns_ResolverConfigurationImpl_loadDNSconfig0(JNIEnv
>>>>                 *env, jclass cl
>>>>                      searchlist[0] = '\0';
>>>>                      nameservers[0] = '\0';
>>>>
>>>>                 -    if (loadConfig(searchlist, nameservers) !=
>>>>                 STS_ERROR) {
>>>>                 +    if (loadConfig(env, searchlist, nameservers)
>>>>                 != STS_ERROR) {
>>>>
>>>>                          /*
>>>>                           * Populate static fields in
>>>>                 sun.net.DefaultResolverConfiguration
>>>>
>>>>                 On Sat, Dec 7, 2019 at 12:41 AM Alan Bateman
>>>>                 <Alan.Bateman at oracle.com
>>>>                 <mailto:Alan.Bateman at oracle.com>> wrote:
>>>>
>>>>                     On 06/12/2019 15:34, Aleks Efimov wrote:
>>>>                     > :
>>>>                     >
>>>>                     > I've created webrev with your latest changes
>>>>                     - it could be convenient
>>>>                     > for other reviewers:
>>>>                     >
>>>>                     http://cr.openjdk.java.net/~aefimov/anuraaga/7006496/00
>>>>                     >
>>>>                     > I will happily sponsor this change once it
>>>>                     gets necessary approvals
>>>>                     This could be split into two issues but since
>>>>                     the code using
>>>>                     StringTokenizer is changing significantly then
>>>>                     we should replace it with
>>>>                     regex while we there.
>>>>
>>>>                     -Alan
>>>>
>>>
>>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/net-dev/attachments/20191224/250b1f96/attachment-0001.htm>


More information about the net-dev mailing list