aefimov-dns-client-branch: fix windows builds aefimov-dns-client-branch
authoraefimov
Thu, 14 Nov 2019 23:13:47 +0000
branchaefimov-dns-client-branch
changeset 59100 b92aac38b046
parent 59099 fcdb8e7ead8f
child 59101 258033faefc9
aefimov-dns-client-branch: fix windows builds
src/java.base/share/classes/java/net/InetAddress.java
src/jdk.dns.client/windows/classes/jdk/dns/conf/DnsResolverConfiguration.java
src/jdk.dns.client/windows/native/libresolve/DnsResolverConfiguration.c
src/jdk.dns.client/windows/native/libresolver/DnsResolverConfiguration.c
--- 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;
+}