--- 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 {
--- 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<String> searchlist;
private static LinkedList<String> 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<String> 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 {
--- 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 <stdlib.h>
-#include <windows.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <iprtrmib.h>
-#include <time.h>
-#include <assert.h>
-#include <iphlpapi.h>
-
-#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;
-}
--- /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 <stdlib.h>
+#include <windows.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <iprtrmib.h>
+#include <time.h>
+#include <assert.h>
+#include <iphlpapi.h>
+
+#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;
+}