<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>