Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/native/sun/net/dns/ResolverConfigurationImpl.c
32288 views
/*1* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include <stdlib.h>26#include <windows.h>27#include <stdio.h>28#include <stddef.h>29#include <iprtrmib.h>30#include <time.h>31#include <assert.h>32#include <iphlpapi.h>3334#include "jni_util.h"3536#define MAX_STR_LEN 2563738#define STS_NO_CONFIG 0x0 /* no configuration found */39#define STS_SL_FOUND 0x1 /* search list found */40#define STS_NS_FOUND 0x2 /* name servers found */41#define STS_ERROR -1 /* error return lodConfig failed memory allccation failure*/4243#define IS_SL_FOUND(sts) (sts & STS_SL_FOUND)44#define IS_NS_FOUND(sts) (sts & STS_NS_FOUND)4546/* JNI ids */47static jfieldID searchlistID;48static jfieldID nameserversID;4950/*51* Utility routine to append s2 to s1 with a space delimiter.52* strappend(s1="abc", "def") => "abc def"53* strappend(s1="", "def") => "def54*/55void strappend(char *s1, char *s2) {56size_t len;5758if (s2[0] == '\0') /* nothing to append */59return;6061len = strlen(s1)+1;62if (s1[0] != 0) /* needs space character */63len++;64if (len + strlen(s2) > MAX_STR_LEN) /* insufficient space */65return;6667if (s1[0] != 0) {68strcat(s1, " ");69}70strcat(s1, s2);71}7273/*74* Windows 2000/XP75*76* Use registry approach based on settings described in Appendix C77* of "Microsoft Windows 2000 TCP/IP Implementation Details".78*79* DNS suffix list is obtained from SearchList registry setting. If80* this is not specified we compile suffix list based on the81* per-connection domain suffix.82*83* DNS name servers and domain settings are on a per-connection84* basic. We therefore enumerate the network adapters to get the85* names of each adapter and then query the corresponding registry86* settings to obtain NameServer/DhcpNameServer and Domain/DhcpDomain.87*/88static int loadConfig(char *sl, char *ns) {89IP_ADAPTER_INFO *adapterP;90ULONG size;91DWORD ret;92DWORD dwLen;93ULONG ulType;94char result[MAX_STR_LEN];95HANDLE hKey;96int gotSearchList = 0;9798/*99* First see if there is a global suffix list specified.100*/101ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,102"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",1030,104KEY_READ,105(PHKEY)&hKey);106if (ret == ERROR_SUCCESS) {107dwLen = sizeof(result);108ret = RegQueryValueEx(hKey, "SearchList", NULL, &ulType,109(LPBYTE)&result, &dwLen);110if (ret == ERROR_SUCCESS) {111assert(ulType == REG_SZ);112if (strlen(result) > 0) {113strappend(sl, result);114gotSearchList = 1;115}116}117RegCloseKey(hKey);118}119120/*121* Ask the IP Helper library to enumerate the adapters122*/123size = sizeof(IP_ADAPTER_INFO);124adapterP = (IP_ADAPTER_INFO *)malloc(size);125if (adapterP == NULL) {126return STS_ERROR;127}128ret = GetAdaptersInfo(adapterP, &size);129if (ret == ERROR_BUFFER_OVERFLOW) {130IP_ADAPTER_INFO *newAdapterP = (IP_ADAPTER_INFO *)realloc(adapterP, size);131if (newAdapterP == NULL) {132free(adapterP);133return STS_ERROR;134}135adapterP = newAdapterP;136137ret = GetAdaptersInfo(adapterP, &size);138}139140/*141* Iterate through the list of adapters as registry settings are142* keyed on the adapter name (GUID).143*/144if (ret == ERROR_SUCCESS) {145IP_ADAPTER_INFO *curr = adapterP;146while (curr != NULL) {147char key[MAX_STR_LEN];148149sprintf(key,150"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s",151curr->AdapterName);152153ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,154key,1550,156KEY_READ,157(PHKEY)&hKey);158if (ret == ERROR_SUCCESS) {159DWORD enableDhcp = 0;160161/*162* Is DHCP enabled on this interface163*/164dwLen = sizeof(enableDhcp);165ret = RegQueryValueEx(hKey, "EnableDhcp", NULL, &ulType,166(LPBYTE)&enableDhcp, &dwLen);167168/*169* If we don't have the suffix list when get the Domain170* or DhcpDomain. If DHCP is enabled then Domain overides171* DhcpDomain172*/173if (!gotSearchList) {174result[0] = '\0';175dwLen = sizeof(result);176ret = RegQueryValueEx(hKey, "Domain", NULL, &ulType,177(LPBYTE)&result, &dwLen);178if (((ret != ERROR_SUCCESS) || (strlen(result) == 0)) &&179enableDhcp) {180dwLen = sizeof(result);181ret = RegQueryValueEx(hKey, "DhcpDomain", NULL, &ulType,182(LPBYTE)&result, &dwLen);183}184if (ret == ERROR_SUCCESS) {185assert(ulType == REG_SZ);186strappend(sl, result);187}188}189190/*191* Get DNS servers based on NameServer or DhcpNameServer192* registry setting. If NameServer is set then it overrides193* DhcpNameServer (even if DHCP is enabled).194*/195result[0] = '\0';196dwLen = sizeof(result);197ret = RegQueryValueEx(hKey, "NameServer", NULL, &ulType,198(LPBYTE)&result, &dwLen);199if (((ret != ERROR_SUCCESS) || (strlen(result) == 0)) &&200enableDhcp) {201dwLen = sizeof(result);202ret = RegQueryValueEx(hKey, "DhcpNameServer", NULL, &ulType,203(LPBYTE)&result, &dwLen);204}205if (ret == ERROR_SUCCESS) {206assert(ulType == REG_SZ);207strappend(ns, result);208}209210/*211* Finished with this registry key212*/213RegCloseKey(hKey);214}215216/*217* Onto the next adapeter218*/219curr = curr->Next;220}221}222223/*224* Free the adpater structure225*/226if (adapterP) {227free(adapterP);228}229230return STS_SL_FOUND & STS_NS_FOUND;231}232233234/*235* Initialize JNI field IDs.236*/237JNIEXPORT void JNICALL238Java_sun_net_dns_ResolverConfigurationImpl_init0(JNIEnv *env, jclass cls)239{240searchlistID = (*env)->GetStaticFieldID(env, cls, "os_searchlist",241"Ljava/lang/String;");242CHECK_NULL(searchlistID);243nameserversID = (*env)->GetStaticFieldID(env, cls, "os_nameservers",244"Ljava/lang/String;");245}246247/*248* Class: sun_net_dns_ResolverConfgurationImpl249* Method: loadConfig0250* Signature: ()V251*/252JNIEXPORT void JNICALL253Java_sun_net_dns_ResolverConfigurationImpl_loadDNSconfig0(JNIEnv *env, jclass cls)254{255char searchlist[MAX_STR_LEN];256char nameservers[MAX_STR_LEN];257jstring obj;258259searchlist[0] = '\0';260nameservers[0] = '\0';261262if (loadConfig(searchlist, nameservers) != STS_ERROR) {263264/*265* Populate static fields in sun.net.DefaultResolverConfiguration266*/267obj = (*env)->NewStringUTF(env, searchlist);268CHECK_NULL(obj);269(*env)->SetStaticObjectField(env, cls, searchlistID, obj);270271obj = (*env)->NewStringUTF(env, nameservers);272CHECK_NULL(obj);273(*env)->SetStaticObjectField(env, cls, nameserversID, obj);274} else {275JNU_ThrowOutOfMemoryError(env, "native memory allocation failed");276}277}278279280/*281* Class: sun_net_dns_ResolverConfgurationImpl282* Method: notifyAddrChange0283* Signature: ()I284*/285JNIEXPORT jint JNICALL286Java_sun_net_dns_ResolverConfigurationImpl_notifyAddrChange0(JNIEnv *env, jclass cls)287{288OVERLAPPED ol;289HANDLE h;290DWORD rc, xfer;291292ol.hEvent = (HANDLE)0;293rc = NotifyAddrChange(&h, &ol);294if (rc == ERROR_IO_PENDING) {295rc = GetOverlappedResult(h, &ol, &xfer, TRUE);296if (rc != 0) {297return 0; /* address changed */298}299}300301/* error */302return -1;303}304305306