# HG changeset patch # User aefimov # Date 1573773227 0 # Node ID b92aac38b046529989aba79aed49d1fa1b4f02ac # Parent fcdb8e7ead8f113416ecb968b449ab596acbd18f aefimov-dns-client-branch: fix windows builds diff -r fcdb8e7ead8f -r b92aac38b046 src/java.base/share/classes/java/net/InetAddress.java --- a/src/java.base/share/classes/java/net/InetAddress.java Thu Nov 14 13:50:03 2019 +0000 +++ b/src/java.base/share/classes/java/net/InetAddress.java Thu Nov 14 23:13:47 2019 +0000 @@ -29,7 +29,6 @@ import java.util.ArrayList; import java.util.Objects; import java.util.Scanner; -import java.security.AccessController; import java.io.File; import java.io.FileNotFoundException; import java.io.ObjectStreamException; @@ -349,10 +348,11 @@ if (nameService != null) { return nameService; } - var nameService = ServiceLoader.load(NameService.class) - .findFirst() - .orElse(defaultNameService); - InetAddress.nameService = nameService; + String hostsFileProperty = GetPropertyAction.privilegedGetProperty("jdk.net.hosts.file"); + var cns = hostsFileProperty == null ? + ServiceLoader.load(NameService.class).findFirst().orElse(defaultNameService) + : defaultNameService; + InetAddress.nameService = cns; return nameService; } } else { diff -r fcdb8e7ead8f -r b92aac38b046 src/jdk.dns.client/windows/classes/jdk/dns/conf/DnsResolverConfiguration.java --- a/src/jdk.dns.client/windows/classes/jdk/dns/conf/DnsResolverConfiguration.java Thu Nov 14 13:50:03 2019 +0000 +++ b/src/jdk.dns.client/windows/classes/jdk/dns/conf/DnsResolverConfiguration.java Thu Nov 14 23:13:47 2019 +0000 @@ -25,9 +25,11 @@ package jdk.dns.conf; +import java.nio.file.Paths; import java.util.LinkedList; import java.util.List; import java.util.StringTokenizer; +import java.util.concurrent.locks.ReentrantLock; public class DnsResolverConfiguration { // Lock held whilst loading configuration or checking @@ -39,9 +41,9 @@ // Time of last refresh. private static long lastRefresh = -1; - // Cache timeout (120 seconds) - should be converted into property + // Cache timeout (120 seconds in nanoseconds) - should be converted into property // or configured as preference in the future. - private static final int TIMEOUT = 120000; + private static final long TIMEOUT = 120_000_000_000L; // DNS suffix list and name servers populated by native method private static String os_searchlist; @@ -50,6 +52,7 @@ // Cached lists private static LinkedList searchlist; private static LinkedList nameservers; + private volatile String domain = ""; // Parse string that consists of token delimited by space or commas // and return LinkedHashMap @@ -67,6 +70,15 @@ return ll; } + public static String getDefaultHostsFileLocation() { + return Paths.get(System.getenv("SystemRoot")) + .resolve("System32") + .resolve("drivers") + .resolve("etc") + .resolve("hosts") + .toString(); + } + // Load DNS configuration from OS private void loadConfig() { @@ -79,7 +91,7 @@ changed = false; } else { if (lastRefresh >= 0) { - long currTime = System.currentTimeMillis(); + long currTime = System.nanoTime(); if ((currTime - lastRefresh) < TIMEOUT) { return; } @@ -91,14 +103,19 @@ // loadDNSconfig0(); - lastRefresh = System.currentTimeMillis(); + lastRefresh = System.nanoTime(); searchlist = stringToList(os_searchlist); + if (searchlist.size() > 0) { + domain = searchlist.get(0); + } else { + domain = ""; + } nameservers = stringToList(os_nameservers); os_searchlist = null; // can be GC'ed os_nameservers = null; } - DnsResolverConfiguration() { + public DnsResolverConfiguration() { } @SuppressWarnings("unchecked") // clone() @@ -116,7 +133,7 @@ @SuppressWarnings("unchecked") // clone() public List nameservers() { - lock.lock() + lock.lock(); try { loadConfig(); @@ -127,6 +144,16 @@ } } + public String domain() { + lock.lock(); + try { + loadConfig(); + return domain; + } finally { + lock.unlock(); + } + } + // --- Address Change Listener static class AddressChangeListener extends Thread { diff -r fcdb8e7ead8f -r b92aac38b046 src/jdk.dns.client/windows/native/libresolve/DnsResolverConfiguration.c --- a/src/jdk.dns.client/windows/native/libresolve/DnsResolverConfiguration.c Thu Nov 14 13:50:03 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,304 +0,0 @@ -/* - * Copyright (c) 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "jni_util.h" - -#define MAX_STR_LEN 256 - -#define STS_NO_CONFIG 0x0 /* no configuration found */ -#define STS_SL_FOUND 0x1 /* search list found */ -#define STS_NS_FOUND 0x2 /* name servers found */ -#define STS_ERROR -1 /* error return lodConfig failed memory allccation failure*/ - -#define IS_SL_FOUND(sts) (sts & STS_SL_FOUND) -#define IS_NS_FOUND(sts) (sts & STS_NS_FOUND) - -/* JNI ids */ -static jfieldID searchlistID; -static jfieldID nameserversID; - -/* - * Utility routine to append s2 to s1 with a space delimiter. - * strappend(s1="abc", "def") => "abc def" - * strappend(s1="", "def") => "def - */ -void strappend(char *s1, char *s2) { - size_t len; - - if (s2[0] == '\0') /* nothing to append */ - return; - - len = strlen(s1)+1; - if (s1[0] != 0) /* needs space character */ - len++; - if (len + strlen(s2) > MAX_STR_LEN) /* insufficient space */ - return; - - if (s1[0] != 0) { - 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. - */ -static int loadConfig(char *sl, char *ns) { - IP_ADAPTER_INFO *adapterP; - ULONG size; - DWORD ret; - DWORD dwLen; - ULONG ulType; - char result[MAX_STR_LEN]; - HANDLE hKey; - int gotSearchList = 0; - - /* - * First see if there is a global suffix list specified. - */ - ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", - 0, - KEY_READ, - (PHKEY)&hKey); - if (ret == ERROR_SUCCESS) { - dwLen = sizeof(result); - ret = RegQueryValueEx(hKey, "SearchList", NULL, &ulType, - (LPBYTE)&result, &dwLen); - if (ret == ERROR_SUCCESS) { - 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); - } - - /* - * 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'; - 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); - strappend(ns, result); - } - - /* - * Finished with this registry key - */ - RegCloseKey(hKey); - } - - /* - * Onto the next adapeter - */ - curr = curr->Next; - } - } - - /* - * Free the adpater structure - */ - if (adapterP) { - free(adapterP); - } - - return STS_SL_FOUND & STS_NS_FOUND; -} - - -/* - * Initialize JNI field IDs. - */ -JNIEXPORT void JNICALL -Java_jdk_dns_conf_DnsResolverConfiguration_init0(JNIEnv *env, jclass cls) -{ - searchlistID = (*env)->GetStaticFieldID(env, cls, "os_searchlist", - "Ljava/lang/String;"); - CHECK_NULL(searchlistID); - nameserversID = (*env)->GetStaticFieldID(env, cls, "os_nameservers", - "Ljava/lang/String;"); -} - -/* - * Class: jdk_dns_conf_DnsResolverConfguration - * Method: loadConfig0 - * Signature: ()V - */ -JNIEXPORT void JNICALL -Java_jdk_dns_conf_DnsResolverConfiguration_loadDNSconfig0(JNIEnv *env, jclass cls) -{ - char searchlist[MAX_STR_LEN]; - char nameservers[MAX_STR_LEN]; - jstring obj; - - searchlist[0] = '\0'; - nameservers[0] = '\0'; - - if (loadConfig(searchlist, nameservers) != STS_ERROR) { - - /* - * Populate static fields in jdk.dns.conf.ResolverConfiguration - */ - obj = (*env)->NewStringUTF(env, searchlist); - CHECK_NULL(obj); - (*env)->SetStaticObjectField(env, cls, searchlistID, obj); - - obj = (*env)->NewStringUTF(env, nameservers); - CHECK_NULL(obj); - (*env)->SetStaticObjectField(env, cls, nameserversID, obj); - } else { - JNU_ThrowOutOfMemoryError(env, "native memory allocation failed"); - } -} - - -/* - * Class: jdk_dns_conf_DnsResolverConfguration - * Method: notifyAddrChange0 - * Signature: ()I - */ -JNIEXPORT jint JNICALL -Java_jdk_dns_conf_DnsResolverConfiguration_notifyAddrChange0(JNIEnv *env, jclass cls) -{ - OVERLAPPED ol; - HANDLE h; - DWORD rc, xfer; - - ol.hEvent = (HANDLE)0; - rc = NotifyAddrChange(&h, &ol); - if (rc == ERROR_IO_PENDING) { - rc = GetOverlappedResult(h, &ol, &xfer, TRUE); - if (rc != 0) { - return 0; /* address changed */ - } - } - - /* error */ - return -1; -} diff -r fcdb8e7ead8f -r b92aac38b046 src/jdk.dns.client/windows/native/libresolver/DnsResolverConfiguration.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.dns.client/windows/native/libresolver/DnsResolverConfiguration.c Thu Nov 14 23:13:47 2019 +0000 @@ -0,0 +1,304 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "jni_util.h" + +#define MAX_STR_LEN 256 + +#define STS_NO_CONFIG 0x0 /* no configuration found */ +#define STS_SL_FOUND 0x1 /* search list found */ +#define STS_NS_FOUND 0x2 /* name servers found */ +#define STS_ERROR -1 /* error return lodConfig failed memory allccation failure*/ + +#define IS_SL_FOUND(sts) (sts & STS_SL_FOUND) +#define IS_NS_FOUND(sts) (sts & STS_NS_FOUND) + +/* JNI ids */ +static jfieldID searchlistID; +static jfieldID nameserversID; + +/* + * Utility routine to append s2 to s1 with a space delimiter. + * strappend(s1="abc", "def") => "abc def" + * strappend(s1="", "def") => "def + */ +void strappend(char *s1, char *s2) { + size_t len; + + if (s2[0] == '\0') /* nothing to append */ + return; + + len = strlen(s1)+1; + if (s1[0] != 0) /* needs space character */ + len++; + if (len + strlen(s2) > MAX_STR_LEN) /* insufficient space */ + return; + + if (s1[0] != 0) { + 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. + */ +static int loadConfig(char *sl, char *ns) { + IP_ADAPTER_INFO *adapterP; + ULONG size; + DWORD ret; + DWORD dwLen; + ULONG ulType; + char result[MAX_STR_LEN]; + HANDLE hKey; + int gotSearchList = 0; + + /* + * First see if there is a global suffix list specified. + */ + ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", + 0, + KEY_READ, + (PHKEY)&hKey); + if (ret == ERROR_SUCCESS) { + dwLen = sizeof(result); + ret = RegQueryValueEx(hKey, "SearchList", NULL, &ulType, + (LPBYTE)&result, &dwLen); + if (ret == ERROR_SUCCESS) { + 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); + } + + /* + * 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'; + 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); + strappend(ns, result); + } + + /* + * Finished with this registry key + */ + RegCloseKey(hKey); + } + + /* + * Onto the next adapeter + */ + curr = curr->Next; + } + } + + /* + * Free the adpater structure + */ + if (adapterP) { + free(adapterP); + } + + return STS_SL_FOUND & STS_NS_FOUND; +} + + +/* + * Initialize JNI field IDs. + */ +JNIEXPORT void JNICALL +Java_jdk_dns_conf_DnsResolverConfiguration_init0(JNIEnv *env, jclass cls) +{ + searchlistID = (*env)->GetStaticFieldID(env, cls, "os_searchlist", + "Ljava/lang/String;"); + CHECK_NULL(searchlistID); + nameserversID = (*env)->GetStaticFieldID(env, cls, "os_nameservers", + "Ljava/lang/String;"); +} + +/* + * Class: jdk_dns_conf_DnsResolverConfguration + * Method: loadConfig0 + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_jdk_dns_conf_DnsResolverConfiguration_loadDNSconfig0(JNIEnv *env, jclass cls) +{ + char searchlist[MAX_STR_LEN]; + char nameservers[MAX_STR_LEN]; + jstring obj; + + searchlist[0] = '\0'; + nameservers[0] = '\0'; + + if (loadConfig(searchlist, nameservers) != STS_ERROR) { + + /* + * Populate static fields in jdk.dns.conf.ResolverConfiguration + */ + obj = (*env)->NewStringUTF(env, searchlist); + CHECK_NULL(obj); + (*env)->SetStaticObjectField(env, cls, searchlistID, obj); + + obj = (*env)->NewStringUTF(env, nameservers); + CHECK_NULL(obj); + (*env)->SetStaticObjectField(env, cls, nameserversID, obj); + } else { + JNU_ThrowOutOfMemoryError(env, "native memory allocation failed"); + } +} + + +/* + * Class: jdk_dns_conf_DnsResolverConfiguration + * Method: notifyAddrChange0 + * Signature: ()I + */ +JNIEXPORT jint JNICALL +Java_jdk_dns_conf_DnsResolverConfiguration_notifyAddrChange0(JNIEnv *env, jclass cls) +{ + OVERLAPPED ol; + HANDLE h; + DWORD rc, xfer; + + ol.hEvent = (HANDLE)0; + rc = NotifyAddrChange(&h, &ol); + if (rc == ERROR_IO_PENDING) { + rc = GetOverlappedResult(h, &ol, &xfer, TRUE); + if (rc != 0) { + return 0; /* address changed */ + } + } + + /* error */ + return -1; +}