diff --git a/deps/cares/cares.gyp b/deps/cares/cares.gyp index 03ae185fcce85a..fce52acb31f495 100644 --- a/deps/cares/cares.gyp +++ b/deps/cares/cares.gyp @@ -40,6 +40,7 @@ 'include/ares_rules.h', 'include/ares_version.h', 'include/nameser.h', + 'src/ares_android.c', 'src/ares_cancel.c', 'src/ares__close_sockets.c', 'src/ares_create_query.c', diff --git a/deps/cares/include/ares.h b/deps/cares/include/ares.h index cfd72b0c51be3e..65a82cb5b7eb47 100644 --- a/deps/cares/include/ares.h +++ b/deps/cares/include/ares.h @@ -68,6 +68,10 @@ # include #endif +#if defined(ANDROID) || defined(__ANDROID__) +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -307,6 +311,12 @@ CARES_EXTERN int ares_library_init_mem(int flags, void (*afree)(void *ptr), void *(*arealloc)(void *ptr, size_t size)); +#if defined(ANDROID) || defined(__ANDROID__) +CARES_EXTERN void ares_library_init_jvm(JavaVM *jvm); +CARES_EXTERN int ares_library_init_android(jobject connectivity_manager); +CARES_EXTERN int ares_library_android_initialized(void); +#endif + CARES_EXTERN int ares_library_initialized(void); CARES_EXTERN void ares_library_cleanup(void); diff --git a/deps/cares/include/ares_version.h b/deps/cares/include/ares_version.h index afa46c632fd991..61b2b98a8d3683 100644 --- a/deps/cares/include/ares_version.h +++ b/deps/cares/include/ares_version.h @@ -3,15 +3,15 @@ #define ARES__VERSION_H /* This is the global package copyright */ -#define ARES_COPYRIGHT "2004 - 2016 Daniel Stenberg, ." +#define ARES_COPYRIGHT "2004 - 2017 Daniel Stenberg, ." #define ARES_VERSION_MAJOR 1 -#define ARES_VERSION_MINOR 13 +#define ARES_VERSION_MINOR 14 #define ARES_VERSION_PATCH 0 #define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\ (ARES_VERSION_MINOR<<8)|\ (ARES_VERSION_PATCH)) -#define ARES_VERSION_STR "1.13.0" +#define ARES_VERSION_STR "1.14.0" #if (ARES_VERSION >= 0x010700) # define CARES_HAVE_ARES_LIBRARY_INIT 1 diff --git a/deps/cares/src/AUTHORS b/deps/cares/src/AUTHORS index af29ec86471fa0..7db6584c91f34f 100644 --- a/deps/cares/src/AUTHORS +++ b/deps/cares/src/AUTHORS @@ -37,6 +37,7 @@ Frederic Germain Geert Uytterhoeven George Neill Gisle Vanem +Google LLC Gregor Jasny Guenter Knauf Guilherme Balena Versiani @@ -45,6 +46,7 @@ Henrik Stoerner Jakub Hrozek James Bursa Jérémy Lal +John Schember Keith Shaw Lei Shi Marko Kreen diff --git a/deps/cares/src/README.md b/deps/cares/src/README.md index 6ad0168dc9a842..93c1f5f812de4c 100644 --- a/deps/cares/src/README.md +++ b/deps/cares/src/README.md @@ -5,6 +5,7 @@ c-ares [![Windows Build Status](https://ci.appveyor.com/api/projects/status/03i7151772eq3wn3/branch/master?svg=true)](https://ci.appveyor.com/project/c-ares/c-ares) [![Coverage Status](https://coveralls.io/repos/c-ares/c-ares/badge.svg?branch=master&service=github)](https://coveralls.io/github/c-ares/c-ares?branch=master) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/291/badge)](https://bestpractices.coreinfrastructure.org/projects/291) +[![Releases](https://coderelease.io/badge/c-ares/c-ares)](https://coderelease.io/github/repository/c-ares/c-ares) This is c-ares, an asynchronous resolver library. It is intended for applications which need to perform DNS queries without blocking, or need to diff --git a/deps/cares/src/RELEASE-NOTES b/deps/cares/src/RELEASE-NOTES index 122390473ab59b..3764e38466b150 100644 --- a/deps/cares/src/RELEASE-NOTES +++ b/deps/cares/src/RELEASE-NOTES @@ -1,53 +1,47 @@ -c-ares version 1.13.0 +c-ares version 1.14.0 Changes: - - o cmake build system support added - o Add virtual function set for socket IO: ares_set_socket_functions [5] - + o android: Introduce new ares_library_init_android() call for Oreo support. [5] + Bug fixes: - o CVE-2017-1000381: c-ares NAPTR parser out of bounds access [1] - o macos: do not set HAVE_CLOCK_GETTIME_MONOTONIC - o test: check ares_create_query with too-long name - o dist: add ares_library_initialized.* to the tarball - o fix build on OpenBSD - o dist: ship msvc_ver.inc too [2] - o test: Add gTest/gMock files to SOURCES - o test: add fuzz entrypoint for ares_create_query() - o configure: clock_gettime workaround [3] - o docs: convert INSTALL to MarkDown & tweak [4] - o ares_process: fix return type of socket_create function (win32 warning) - o docs: fixed references to ares_set_local_ip4 and ares_set_local_ip6 - o Windows DNS server sorting [6] - o Use ares_socklen_t instead of socket_t [7] - o ares_create_query: use ares_free not naked free - o msvc_ver.inc support most recent Visual Studio 2017 [8] - o acountry: Convert char from ISO-8859-1 to UTF-8 [9] - o ares_expand_name: limit number of indirections - o configure: do not check for ar if specified manually [10] - o Added support for Windows DNS Suffix Search List [11] - o ares.h: support compiling with QNX [12] + o Fix patch for CVE-2017-1000381 to not be overly aggressive. [1] + o win32: Preserve DNS server order returned by Windows when sorting and exclude + DNS servers in legacy subnets. [2] [4] + o win32: Support most recent Visual Studio 2017 + o gethostbyaddr should fail with ECANCELLED not ENOTFOUND when ares_cancel + is called. [3] + o win32: Exclude legacy ipv6 subnets [4] + o android: Applications compiled for Oreo can no longer use + __system_property_get and must use Java calls to retrieve DNS servers. + [5] [7] + o win32: Force use of ANSI functions [6] + o CMake minimum version is now 3.1 + o ares_gethostbyname.3: fix callback status values [8] + o docs: Document WSAStartup requirement [9] + o Fix a typo in init_by_resolv_conf [10] + o Android JNI code leaks local references in some cases [11] + o Force using the ANSI versions of WinAPI functions [12] Thanks go to these friendly people for their efforts and contributions: - Aaron Bieber, Andrew Sullivan, Brad House, Bruce Stephens, Calle Wilund, - Chris Araman, Christian Ammer, Daniel Stenberg, David Drysdale, David Hotham, - Dionna Glaze, Gregor Jasny, Michael Osei, Mulle kybernetiK, noiz at github, - Sergii Pylypenko, Stephen Sorley, Thomas Köckerbauer, + AC Thompson, Anna Henningsen, Antonio Tajuelo, Brad House, Brad Spencer, + Christian Ammer, Daniel Stenberg, David Drysdale, David Hotham, Felix Yan, + Gergely Nagy, Gregor Jasny, Jakub Hrozek, John Schember, + Konstantinos Sofokleous, Roman Teterin, Sergey Kolomenkin, Sheel Bedi, (18 contributors) References to bug reports and discussions on issues: - [1] = https://c-ares.haxx.se/adv_20170620.html - [2] = https://github.com/c-ares/c-ares/issues/69 - [3] = https://github.com/c-ares/c-ares/issues/71 - [4] = https://github.com/c-ares/c-ares/issues/83 - [5] = https://github.com/c-ares/c-ares/issues/72 - [6] = https://github.com/c-ares/c-ares/issues/81 - [7] = https://github.com/c-ares/c-ares/issues/92 - [8] = https://github.com/c-ares/c-ares/issues/101 - [9] = https://github.com/c-ares/c-ares/issues/97 - [10] = https://github.com/c-ares/c-ares/issues/62 - [11] = https://github.com/c-ares/c-ares/issues/93 - [12] = https://github.com/c-ares/c-ares/issues/113 + [1] = https://github.com/c-ares/c-ares/commit/18ea99 + [2] = https://github.com/c-ares/c-ares/issues/150 + [3] = https://github.com/c-ares/c-ares/pull/138 + [4] = https://github.com/c-ares/c-ares/pull/144 + [5] = https://github.com/c-ares/c-ares/pull/148 + [6] = https://github.com/c-ares/c-ares/pull/142 + [7] = https://github.com/c-ares/c-ares/pull/175 + [8] = https://c-ares.haxx.se/mail/c-ares-archive-2011-06/0012.shtml + [9] = https://github.com/c-ares/c-ares/pull/180 + [10] = https://github.com/c-ares/c-ares/pull/160 + [11] = https://github.com/c-ares/c-ares/pull/175 + [12] = https://github.com/c-ares/c-ares/pull/142 diff --git a/deps/cares/src/ares_android.c b/deps/cares/src/ares_android.c new file mode 100644 index 00000000000000..ab388110bdeff9 --- /dev/null +++ b/deps/cares/src/ares_android.c @@ -0,0 +1,347 @@ +/* Copyright (C) 2017 by John Schember + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ +#if defined(ANDROID) || defined(__ANDROID__) + +#include + +#include "ares_setup.h" +#include "ares.h" +#include "ares_android.h" +#include "ares_private.h" + +static JavaVM *android_jvm = NULL; +static jobject android_connectivity_manager = NULL; + +/* ConnectivityManager.getActiveNetwork */ +static jmethodID android_cm_active_net_mid = NULL; +/* ConnectivityManager.getLinkProperties */ +static jmethodID android_cm_link_props_mid = NULL; +/* LinkProperties.getDnsServers */ +static jmethodID android_lp_dns_servers_mid = NULL; +/* List.size */ +static jmethodID android_list_size_mid = NULL; +/* List.get */ +static jmethodID android_list_get_mid = NULL; +/* InetAddress.getHostAddress */ +static jmethodID android_ia_host_addr_mid = NULL; + +static jclass jni_get_class(JNIEnv *env, const char *path) +{ + jclass cls = NULL; + + if (env == NULL || path == NULL || *path == '\0') + return NULL; + + cls = (*env)->FindClass(env, path); + if ((*env)->ExceptionOccurred(env)) { + (*env)->ExceptionClear(env); + return NULL; + } + return cls; +} + +static jmethodID jni_get_method_id(JNIEnv *env, jclass cls, + const char *func_name, const char *signature) +{ + jmethodID mid = NULL; + + if (env == NULL || cls == NULL || func_name == NULL || *func_name == '\0' || + signature == NULL || *signature == '\0') + { + return NULL; + } + + mid = (*env)->GetMethodID(env, cls, func_name, signature); + if ((*env)->ExceptionOccurred(env)) + { + (*env)->ExceptionClear(env); + return NULL; + } + + return mid; +} + +void ares_library_init_jvm(JavaVM *jvm) +{ + android_jvm = jvm; +} + +int ares_library_init_android(jobject connectivity_manager) +{ + JNIEnv *env = NULL; + int need_detatch = 0; + int res; + int ret = ARES_ENOTINITIALIZED; + jclass obj_cls = NULL; + + if (android_jvm == NULL) + goto cleanup; + + res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); + if (res == JNI_EDETACHED) + { + env = NULL; + res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL); + need_detatch = 1; + } + if (res != JNI_OK || env == NULL) + goto cleanup; + + android_connectivity_manager = + (*env)->NewGlobalRef(env, connectivity_manager); + if (android_connectivity_manager == NULL) + goto cleanup; + + /* Initialization has succeeded. Now attempt to cache the methods that will be + * called by ares_get_android_server_list. */ + ret = ARES_SUCCESS; + + /* ConnectivityManager in API 1. */ + obj_cls = jni_get_class(env, "android/net/ConnectivityManager"); + if (obj_cls == NULL) + goto cleanup; + + /* ConnectivityManager.getActiveNetwork in API 23. */ + android_cm_active_net_mid = + jni_get_method_id(env, obj_cls, "getActiveNetwork", + "()Landroid/net/Network;"); + if (android_cm_active_net_mid == NULL) + goto cleanup; + + /* ConnectivityManager.getLinkProperties in API 21. */ + android_cm_link_props_mid = + jni_get_method_id(env, obj_cls, "getLinkProperties", + "(Landroid/net/Network;)Landroid/net/LinkProperties;"); + if (android_cm_link_props_mid == NULL) + goto cleanup; + + /* LinkProperties in API 21. */ + (*env)->DeleteLocalRef(env, obj_cls); + obj_cls = jni_get_class(env, "android/net/LinkProperties"); + if (obj_cls == NULL) + goto cleanup; + + /* getDnsServers in API 21. */ + android_lp_dns_servers_mid = jni_get_method_id(env, obj_cls, "getDnsServers", + "()Ljava/util/List;"); + if (android_lp_dns_servers_mid == NULL) + goto cleanup; + + (*env)->DeleteLocalRef(env, obj_cls); + obj_cls = jni_get_class(env, "java/util/List"); + if (obj_cls == NULL) + goto cleanup; + + android_list_size_mid = jni_get_method_id(env, obj_cls, "size", "()I"); + if (android_list_size_mid == NULL) + goto cleanup; + + android_list_get_mid = jni_get_method_id(env, obj_cls, "get", + "(I)Ljava/lang/Object;"); + if (android_list_get_mid == NULL) + goto cleanup; + + (*env)->DeleteLocalRef(env, obj_cls); + obj_cls = jni_get_class(env, "java/net/InetAddress"); + if (obj_cls == NULL) + goto cleanup; + + android_ia_host_addr_mid = jni_get_method_id(env, obj_cls, "getHostAddress", + "()Ljava/lang/String;"); + if (android_ia_host_addr_mid == NULL) + goto cleanup; + + (*env)->DeleteLocalRef(env, obj_cls); + goto done; + +cleanup: + if (obj_cls != NULL) + (*env)->DeleteLocalRef(env, obj_cls); + + android_cm_active_net_mid = NULL; + android_cm_link_props_mid = NULL; + android_lp_dns_servers_mid = NULL; + android_list_size_mid = NULL; + android_list_get_mid = NULL; + android_ia_host_addr_mid = NULL; + +done: + if (need_detatch) + (*android_jvm)->DetachCurrentThread(android_jvm); + + return ret; +} + +int ares_library_android_initialized(void) +{ + if (android_jvm == NULL || android_connectivity_manager == NULL) + return ARES_ENOTINITIALIZED; + return ARES_SUCCESS; +} + +void ares_library_cleanup_android(void) +{ + JNIEnv *env = NULL; + int need_detatch = 0; + int res; + + if (android_jvm == NULL || android_connectivity_manager == NULL) + return; + + res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); + if (res == JNI_EDETACHED) + { + env = NULL; + res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL); + need_detatch = 1; + } + if (res != JNI_OK || env == NULL) + return; + + android_cm_active_net_mid = NULL; + android_cm_link_props_mid = NULL; + android_lp_dns_servers_mid = NULL; + android_list_size_mid = NULL; + android_list_get_mid = NULL; + android_ia_host_addr_mid = NULL; + + (*env)->DeleteGlobalRef(env, android_connectivity_manager); + android_connectivity_manager = NULL; + + if (need_detatch) + (*android_jvm)->DetachCurrentThread(android_jvm); +} + +char **ares_get_android_server_list(size_t max_servers, + size_t *num_servers) +{ + JNIEnv *env = NULL; + jobject active_network = NULL; + jobject link_properties = NULL; + jobject server_list = NULL; + jobject server = NULL; + jstring str = NULL; + jint nserv; + const char *ch_server_address; + int res; + size_t i; + char **dns_list = NULL; + int need_detatch = 0; + + if (android_jvm == NULL || android_connectivity_manager == NULL || + max_servers == 0 || num_servers == NULL) + { + return NULL; + } + + if (android_cm_active_net_mid == NULL || android_cm_link_props_mid == NULL || + android_lp_dns_servers_mid == NULL || android_list_size_mid == NULL || + android_list_get_mid == NULL || android_ia_host_addr_mid == NULL) + { + return NULL; + } + + res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); + if (res == JNI_EDETACHED) + { + env = NULL; + res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL); + need_detatch = 1; + } + if (res != JNI_OK || env == NULL) + goto done; + + /* JNI below is equivalent to this Java code. + import android.content.Context; + import android.net.ConnectivityManager; + import android.net.LinkProperties; + import android.net.Network; + import java.net.InetAddress; + import java.util.List; + + ConnectivityManager cm = (ConnectivityManager)this.getApplicationContext() + .getSystemService(Context.CONNECTIVITY_SERVICE); + Network an = cm.getActiveNetwork(); + LinkProperties lp = cm.getLinkProperties(an); + List dns = lp.getDnsServers(); + for (InetAddress ia: dns) { + String ha = ia.getHostAddress(); + } + + Note: The JNI ConnectivityManager object and all method IDs were previously + initialized in ares_library_init_android. + */ + + active_network = (*env)->CallObjectMethod(env, android_connectivity_manager, + android_cm_active_net_mid); + if (active_network == NULL) + goto done; + + link_properties = + (*env)->CallObjectMethod(env, android_connectivity_manager, + android_cm_link_props_mid, active_network); + if (link_properties == NULL) + goto done; + + server_list = (*env)->CallObjectMethod(env, link_properties, + android_lp_dns_servers_mid); + if (server_list == NULL) + goto done; + + nserv = (*env)->CallIntMethod(env, server_list, android_list_size_mid); + if (nserv > (jint)max_servers) + nserv = (jint)max_servers; + if (nserv <= 0) + goto done; + *num_servers = (size_t)nserv; + + dns_list = ares_malloc(sizeof(*dns_list)*(*num_servers)); + for (i=0; i<*num_servers; i++) + { + server = (*env)->CallObjectMethod(env, server_list, android_list_get_mid, + (jint)i); + dns_list[i] = ares_malloc(64); + dns_list[i][0] = 0; + if (server == NULL) + { + continue; + } + str = (*env)->CallObjectMethod(env, server, android_ia_host_addr_mid); + ch_server_address = (*env)->GetStringUTFChars(env, str, 0); + strncpy(dns_list[i], ch_server_address, 64); + (*env)->ReleaseStringUTFChars(env, str, ch_server_address); + (*env)->DeleteLocalRef(env, str); + (*env)->DeleteLocalRef(env, server); + } + +done: + if ((*env)->ExceptionOccurred(env)) + (*env)->ExceptionClear(env); + + if (server_list != NULL) + (*env)->DeleteLocalRef(env, server_list); + if (link_properties != NULL) + (*env)->DeleteLocalRef(env, link_properties); + if (active_network != NULL) + (*env)->DeleteLocalRef(env, active_network); + + if (need_detatch) + (*android_jvm)->DetachCurrentThread(android_jvm); + return dns_list; +} +#else +/* warning: ISO C forbids an empty translation unit */ +typedef int dummy_make_iso_compilers_happy; +#endif diff --git a/deps/cares/src/ares_data.c b/deps/cares/src/ares_data.c index f89111381511a0..18dd650c7b91fb 100644 --- a/deps/cares/src/ares_data.c +++ b/deps/cares/src/ares_data.c @@ -40,10 +40,9 @@ void ares_free_data(void *dataptr) { - struct ares_data *ptr; - - if (!dataptr) - return; + while (dataptr != NULL) { + struct ares_data *ptr; + void *next_data = NULL; #ifdef __INTEL_COMPILER # pragma warning(push) @@ -51,80 +50,82 @@ void ares_free_data(void *dataptr) /* 1684: conversion from pointer to same-sized integral type */ #endif - ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data)); + ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data)); #ifdef __INTEL_COMPILER # pragma warning(pop) #endif - if (ptr->mark != ARES_DATATYPE_MARK) - return; - - switch (ptr->type) - { - case ARES_DATATYPE_MX_REPLY: - - if (ptr->data.mx_reply.next) - ares_free_data(ptr->data.mx_reply.next); - if (ptr->data.mx_reply.host) - ares_free(ptr->data.mx_reply.host); - break; - - case ARES_DATATYPE_SRV_REPLY: - - if (ptr->data.srv_reply.next) - ares_free_data(ptr->data.srv_reply.next); - if (ptr->data.srv_reply.host) - ares_free(ptr->data.srv_reply.host); - break; - - case ARES_DATATYPE_TXT_REPLY: - case ARES_DATATYPE_TXT_EXT: - - if (ptr->data.txt_reply.next) - ares_free_data(ptr->data.txt_reply.next); - if (ptr->data.txt_reply.txt) - ares_free(ptr->data.txt_reply.txt); - break; - - case ARES_DATATYPE_ADDR_NODE: - - if (ptr->data.addr_node.next) - ares_free_data(ptr->data.addr_node.next); - break; - - case ARES_DATATYPE_ADDR_PORT_NODE: - - if (ptr->data.addr_port_node.next) - ares_free_data(ptr->data.addr_port_node.next); - break; - - case ARES_DATATYPE_NAPTR_REPLY: - - if (ptr->data.naptr_reply.next) - ares_free_data(ptr->data.naptr_reply.next); - if (ptr->data.naptr_reply.flags) - ares_free(ptr->data.naptr_reply.flags); - if (ptr->data.naptr_reply.service) - ares_free(ptr->data.naptr_reply.service); - if (ptr->data.naptr_reply.regexp) - ares_free(ptr->data.naptr_reply.regexp); - if (ptr->data.naptr_reply.replacement) - ares_free(ptr->data.naptr_reply.replacement); - break; - - case ARES_DATATYPE_SOA_REPLY: - if (ptr->data.soa_reply.nsname) - ares_free(ptr->data.soa_reply.nsname); - if (ptr->data.soa_reply.hostmaster) - ares_free(ptr->data.soa_reply.hostmaster); - break; - - default: - return; - } - - ares_free(ptr); + if (ptr->mark != ARES_DATATYPE_MARK) + return; + + switch (ptr->type) + { + case ARES_DATATYPE_MX_REPLY: + + if (ptr->data.mx_reply.next) + next_data = ptr->data.mx_reply.next; + if (ptr->data.mx_reply.host) + ares_free(ptr->data.mx_reply.host); + break; + + case ARES_DATATYPE_SRV_REPLY: + + if (ptr->data.srv_reply.next) + next_data = ptr->data.srv_reply.next; + if (ptr->data.srv_reply.host) + ares_free(ptr->data.srv_reply.host); + break; + + case ARES_DATATYPE_TXT_REPLY: + case ARES_DATATYPE_TXT_EXT: + + if (ptr->data.txt_reply.next) + next_data = ptr->data.txt_reply.next; + if (ptr->data.txt_reply.txt) + ares_free(ptr->data.txt_reply.txt); + break; + + case ARES_DATATYPE_ADDR_NODE: + + if (ptr->data.addr_node.next) + next_data = ptr->data.addr_node.next; + break; + + case ARES_DATATYPE_ADDR_PORT_NODE: + + if (ptr->data.addr_port_node.next) + next_data = ptr->data.addr_port_node.next; + break; + + case ARES_DATATYPE_NAPTR_REPLY: + + if (ptr->data.naptr_reply.next) + next_data = ptr->data.naptr_reply.next; + if (ptr->data.naptr_reply.flags) + ares_free(ptr->data.naptr_reply.flags); + if (ptr->data.naptr_reply.service) + ares_free(ptr->data.naptr_reply.service); + if (ptr->data.naptr_reply.regexp) + ares_free(ptr->data.naptr_reply.regexp); + if (ptr->data.naptr_reply.replacement) + ares_free(ptr->data.naptr_reply.replacement); + break; + + case ARES_DATATYPE_SOA_REPLY: + if (ptr->data.soa_reply.nsname) + ares_free(ptr->data.soa_reply.nsname); + if (ptr->data.soa_reply.hostmaster) + ares_free(ptr->data.soa_reply.hostmaster); + break; + + default: + return; + } + + ares_free(ptr); + dataptr = next_data; + } } diff --git a/deps/cares/src/ares_gethostbyaddr.c b/deps/cares/src/ares_gethostbyaddr.c index a0a90f6bb1712b..a8ca0f5744d376 100644 --- a/deps/cares/src/ares_gethostbyaddr.c +++ b/deps/cares/src/ares_gethostbyaddr.c @@ -190,18 +190,18 @@ static int file_lookup(struct ares_addr *addr, struct hostent **host) char tmp[MAX_PATH]; HKEY hkeyHosts; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &hkeyHosts) == ERROR_SUCCESS) { DWORD dwLength = MAX_PATH; - RegQueryValueEx(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp, + RegQueryValueExA(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp, &dwLength); - ExpandEnvironmentStrings(tmp, PATH_HOSTS, MAX_PATH); + ExpandEnvironmentStringsA(tmp, PATH_HOSTS, MAX_PATH); RegCloseKey(hkeyHosts); } } else if (platform == WIN_9X) - GetWindowsDirectory(PATH_HOSTS, MAX_PATH); + GetWindowsDirectoryA(PATH_HOSTS, MAX_PATH); else return ARES_ENOTFOUND; diff --git a/deps/cares/src/ares_gethostbyname.c b/deps/cares/src/ares_gethostbyname.c index caab6ae49566d6..7c46d96ceaf214 100644 --- a/deps/cares/src/ares_gethostbyname.c +++ b/deps/cares/src/ares_gethostbyname.c @@ -351,18 +351,18 @@ static int file_lookup(const char *name, int family, struct hostent **host) char tmp[MAX_PATH]; HKEY hkeyHosts; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &hkeyHosts) == ERROR_SUCCESS) { DWORD dwLength = MAX_PATH; - RegQueryValueEx(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp, + RegQueryValueExA(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp, &dwLength); - ExpandEnvironmentStrings(tmp, PATH_HOSTS, MAX_PATH); + ExpandEnvironmentStringsA(tmp, PATH_HOSTS, MAX_PATH); RegCloseKey(hkeyHosts); } } else if (platform == WIN_9X) - GetWindowsDirectory(PATH_HOSTS, MAX_PATH); + GetWindowsDirectoryA(PATH_HOSTS, MAX_PATH); else return ARES_ENOTFOUND; diff --git a/deps/cares/src/ares_init.c b/deps/cares/src/ares_init.c index 3ba8cb3570c67d..42ff4106236ce3 100644 --- a/deps/cares/src/ares_init.c +++ b/deps/cares/src/ares_init.c @@ -44,6 +44,7 @@ #if defined(ANDROID) || defined(__ANDROID__) #include +#include "ares_android.h" /* From the Bionic sources */ #define DNS_PROP_NAME_PREFIX "net.dns" #define MAX_DNS_PROPERTIES 8 @@ -585,7 +586,7 @@ static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr) *outptr = NULL; /* Find out size of string stored in registry */ - res = RegQueryValueEx(hKey, leafKeyName, 0, NULL, NULL, &size); + res = RegQueryValueExA(hKey, leafKeyName, 0, NULL, NULL, &size); if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size) return 0; @@ -596,7 +597,7 @@ static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr) return 0; /* Get the value for real */ - res = RegQueryValueEx(hKey, leafKeyName, 0, NULL, + res = RegQueryValueExA(hKey, leafKeyName, 0, NULL, (unsigned char *)*outptr, &size); if ((res != ERROR_SUCCESS) || (size == 1)) { @@ -627,7 +628,7 @@ static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr) *outptr = NULL; /* Find out size of string stored in registry */ - res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType, NULL, &size); + res = RegQueryValueExA(hKey, leafKeyName, 0, &dataType, NULL, &size); if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size) return 0; @@ -638,7 +639,7 @@ static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr) return 0; /* Get the value for real */ - res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType, + res = RegQueryValueExA(hKey, leafKeyName, 0, &dataType, (unsigned char *)*outptr, &size); if ((res != ERROR_SUCCESS) || (size == 1)) { @@ -683,11 +684,11 @@ static int get_enum_REG_SZ(HKEY hKeyParent, const char *leafKeyName, for(;;) { enumKeyNameBuffSize = sizeof(enumKeyName); - res = RegEnumKeyEx(hKeyParent, enumKeyIdx++, enumKeyName, + res = RegEnumKeyExA(hKeyParent, enumKeyIdx++, enumKeyName, &enumKeyNameBuffSize, 0, NULL, NULL, NULL); if (res != ERROR_SUCCESS) break; - res = RegOpenKeyEx(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE, + res = RegOpenKeyExA(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE, &hKeyEnum); if (res != ERROR_SUCCESS) continue; @@ -718,7 +719,7 @@ static int get_DNS_Registry_9X(char **outptr) *outptr = NULL; - res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ, + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ, &hKey_VxD_MStcp); if (res != ERROR_SUCCESS) return 0; @@ -750,7 +751,7 @@ static int get_DNS_Registry_NT(char **outptr) *outptr = NULL; - res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &hKey_Tcpip_Parameters); if (res != ERROR_SUCCESS) return 0; @@ -772,7 +773,7 @@ static int get_DNS_Registry_NT(char **outptr) goto done; /* Try adapter specific parameters */ - res = RegOpenKeyEx(hKey_Tcpip_Parameters, "Interfaces", 0, + res = RegOpenKeyExA(hKey_Tcpip_Parameters, "Interfaces", 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey_Interfaces); if (res != ERROR_SUCCESS) @@ -949,9 +950,16 @@ static BOOL ares_IsWindowsVistaOrGreater(void) OSVERSIONINFO vinfo; memset(&vinfo, 0, sizeof(vinfo)); vinfo.dwOSVersionInfoSize = sizeof(vinfo); +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4996) /* warning C4996: 'GetVersionExW': was declared deprecated */ +#endif if (!GetVersionEx(&vinfo) || vinfo.dwMajorVersion < 6) return FALSE; return TRUE; +#ifdef _MSC_VER +#pragma warning(pop) +#endif } /* A structure to hold the string form of IPv4 and IPv6 addresses so we can @@ -962,6 +970,10 @@ typedef struct /* The metric we sort them by. */ ULONG metric; + /* Original index of the item, used as a secondary sort parameter to make + * qsort() stable if the metrics are equal */ + size_t orig_idx; + /* Room enough for the string form of any IPv4 or IPv6 address that * ares_inet_ntop() will create. Based on the existing c-ares practice. */ @@ -976,8 +988,69 @@ static int compareAddresses(const void *arg1, { const Address * const left = arg1; const Address * const right = arg2; + /* Lower metric the more preferred */ if(left->metric < right->metric) return -1; if(left->metric > right->metric) return 1; + /* If metrics are equal, lower original index more preferred */ + if(left->orig_idx < right->orig_idx) return -1; + if(left->orig_idx > right->orig_idx) return 1; + return 0; +} + +/* Validate that the ip address matches the subnet (network base and network + * mask) specified. Addresses are specified in standard Network Byte Order as + * 16 bytes, and the netmask is 0 to 128 (bits). + */ +static int ares_ipv6_subnet_matches(const unsigned char netbase[16], + unsigned char netmask, + const unsigned char ipaddr[16]) +{ + unsigned char mask[16] = { 0 }; + unsigned char i; + + /* Misuse */ + if (netmask > 128) + return 0; + + /* Quickly set whole bytes */ + memset(mask, 0xFF, netmask / 8); + + /* Set remaining bits */ + if(netmask % 8) { + mask[netmask / 8] = (unsigned char)(0xff << (8 - (netmask % 8))); + } + + for (i=0; i<16; i++) { + if ((netbase[i] & mask[i]) != (ipaddr[i] & mask[i])) + return 0; + } + + return 1; +} + +static int ares_ipv6_server_blacklisted(const unsigned char ipaddr[16]) +{ + const struct { + const char *netbase; + unsigned char netmask; + } blacklist[] = { + /* Deprecated by [RFC3879] in September 2004. Formerly a Site-Local scoped + * address prefix. Causes known issues on Windows as these are not valid DNS + * servers. */ + { "fec0::", 10 }, + { NULL, 0 } + }; + size_t i; + + for (i=0; blacklist[i].netbase != NULL; i++) { + unsigned char netbase[16]; + + if (ares_inet_pton(AF_INET6, blacklist[i].netbase, netbase) != 1) + continue; + + if (ares_ipv6_subnet_matches(netbase, blacklist[i].netmask, ipaddr)) + return 1; + } return 0; } @@ -1164,7 +1237,7 @@ static int get_DNS_AdaptersAddresses(char **outptr) /* Allocate room for another address, if necessary, else skip. */ if(addressesIndex == addressesSize) { const size_t newSize = addressesSize + 4; - Address * const newMem = + Address * const newMem = (Address*)ares_realloc(addresses, sizeof(Address) * newSize); if(newMem == NULL) { continue; @@ -1187,6 +1260,9 @@ static int get_DNS_AdaptersAddresses(char **outptr) addresses[addressesIndex].metric = -1; } + /* Record insertion index to make qsort stable */ + addresses[addressesIndex].orig_idx = addressesIndex; + if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr, addresses[addressesIndex].text, sizeof(addresses[0].text))) { @@ -1205,6 +1281,11 @@ static int get_DNS_AdaptersAddresses(char **outptr) sizeof(namesrvr.sa6->sin6_addr)) == 0) continue; + if (ares_ipv6_server_blacklisted( + (const unsigned char *)&namesrvr.sa6->sin6_addr) + ) + continue; + /* Allocate room for another address, if necessary, else skip. */ if(addressesIndex == addressesSize) { const size_t newSize = addressesSize + 4; @@ -1223,7 +1304,7 @@ static int get_DNS_AdaptersAddresses(char **outptr) /* Save the address as the next element in addresses. */ addresses[addressesIndex].metric = getBestRouteMetric(&ipaaEntry->Luid, - (SOCKADDR_INET*)(namesrvr.sa), + (SOCKADDR_INET*)(namesrvr.sa), ipaaEntry->Ipv6Metric); } else @@ -1231,6 +1312,9 @@ static int get_DNS_AdaptersAddresses(char **outptr) addresses[addressesIndex].metric = -1; } + /* Record insertion index to make qsort stable */ + addresses[addressesIndex].orig_idx = addressesIndex; + if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr, addresses[addressesIndex].text, sizeof(addresses[0].text))) { @@ -1245,7 +1329,8 @@ static int get_DNS_AdaptersAddresses(char **outptr) } } - /* Sort all of the textual addresses by their metric. */ + /* Sort all of the textual addresses by their metric (and original index if + * metrics are equal). */ qsort(addresses, addressesIndex, sizeof(*addresses), compareAddresses); /* Join them all into a single string, removing duplicates. */ @@ -1269,7 +1354,7 @@ static int get_DNS_AdaptersAddresses(char **outptr) done: ares_free(addresses); - + if (ipaa) ares_free(ipaa); @@ -1373,7 +1458,7 @@ static size_t next_suffix(const char** list, const size_t advance) * * Returns 1 and sets *outptr when returning a dynamically allocated string. * - * Implementation supports Windows Server 2003 and newer + * Implementation supports Windows Server 2003 and newer */ static int get_SuffixList_Windows(char **outptr) { @@ -1382,7 +1467,7 @@ static int get_SuffixList_Windows(char **outptr) DWORD keyNameBuffSize; DWORD keyIdx = 0; char *p = NULL; - char *pp; + const char *pp; size_t len = 0; *outptr = NULL; @@ -1391,7 +1476,7 @@ static int get_SuffixList_Windows(char **outptr) return 0; /* 1. Global DNS Suffix Search List */ - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { if (get_REG_SZ(hKey, SEARCHLIST_KEY, outptr)) @@ -1403,7 +1488,7 @@ static int get_SuffixList_Windows(char **outptr) /* 2. Connection Specific Search List composed of: * a. Primary DNS Suffix */ - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_DNSCLIENT, 0, + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_DNSCLIENT, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, outptr); @@ -1413,17 +1498,17 @@ static int get_SuffixList_Windows(char **outptr) return 0; /* b. Interface SearchList, Domain, DhcpDomain */ - if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY "\\" INTERFACES_KEY, 0, + if (!RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY "\\" INTERFACES_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS) return 0; for(;;) { keyNameBuffSize = sizeof(keyName); - if (RegEnumKeyEx(hKey, keyIdx++, keyName, &keyNameBuffSize, + if (RegEnumKeyExA(hKey, keyIdx++, keyName, &keyNameBuffSize, 0, NULL, NULL, NULL) != ERROR_SUCCESS) break; - if (RegOpenKeyEx(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum) + if (RegOpenKeyExA(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum) != ERROR_SUCCESS) continue; if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p) || @@ -1432,7 +1517,7 @@ static int get_SuffixList_Windows(char **outptr) { /* p can be comma separated (SearchList) */ pp = p; - while (len = next_suffix(&pp, len)) + while ((len = next_suffix(&pp, len)) != 0) { if (!contains_suffix(*outptr, pp, len)) commanjoin(outptr, pp, len); @@ -1542,18 +1627,55 @@ static int init_by_resolv_conf(ares_channel channel) unsigned int i; char propname[PROP_NAME_MAX]; char propvalue[PROP_VALUE_MAX]=""; + char **dns_servers; + size_t num_servers; + + /* Use the Android connectivity manager to get a list + * of DNS servers. As of Android 8 (Oreo) net.dns# + * system properties are no longer available. Google claims this + * improves privacy. Apps now need the ACCESS_NETWORK_STATE + * permission and must use the ConnectivityManager which + * is Java only. */ + dns_servers = ares_get_android_server_list(MAX_DNS_PROPERTIES, &num_servers); + if (dns_servers != NULL) + { + for (i = 0; i < num_servers; i++) + { + status = config_nameserver(&servers, &nservers, dns_servers[i]); + if (status != ARES_SUCCESS) + break; + status = ARES_EOF; + } + for (i = 0; i < num_servers; i++) + { + ares_free(dns_servers[i]); + } + ares_free(dns_servers); + } - for (i = 1; i <= MAX_DNS_PROPERTIES; i++) { - snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i); - if (__system_property_get(propname, propvalue) < 1) { +# ifdef HAVE___SYSTEM_PROPERTY_GET + /* Old way using the system property still in place as + * a fallback. Older android versions can still use this. + * it's possible for older apps not not have added the new + * permission and we want to try to avoid breaking those. + * + * We'll only run this if we don't have any dns servers + * because this will get the same ones (if it works). */ + if (status != ARES_EOF) { + for (i = 1; i <= MAX_DNS_PROPERTIES; i++) { + snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i); + if (__system_property_get(propname, propvalue) < 1) { + status = ARES_EOF; + break; + } + + status = config_nameserver(&servers, &nservers, propvalue); + if (status != ARES_SUCCESS) + break; status = ARES_EOF; - break; } - status = config_nameserver(&servers, &nservers, propvalue); - if (status != ARES_SUCCESS) - break; - status = ARES_EOF; } +# endif /* HAVE___SYSTEM_PROPERTY_GET */ #elif defined(CARES_USE_LIBRESOLV) struct __res_state res; memset(&res, 0, sizeof(res)); @@ -1873,8 +1995,10 @@ static int init_by_defaults(ares_channel channel) continue; } else if(res) { - rc = ARES_EBADNAME; - goto error; + /* Lets not treat a gethostname failure as critical, since we + * are ok if gethostname doesn't even exist */ + *hostname = '\0'; + break; } } while (res != 0); diff --git a/deps/cares/src/ares_library_init.c b/deps/cares/src/ares_library_init.c index 0a853d72cfa4e7..88e7a537480813 100644 --- a/deps/cares/src/ares_library_init.c +++ b/deps/cares/src/ares_library_init.c @@ -30,6 +30,10 @@ fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses = ZERO_NULL; fpGetBestRoute2_t ares_fpGetBestRoute2 = ZERO_NULL; #endif +#if defined(ANDROID) || defined(__ANDROID__) +#include "ares_android.h" +#endif + /* library-private global vars with source visibility restricted to this file */ static unsigned int ares_initialized; @@ -160,6 +164,10 @@ void ares_library_cleanup(void) if (ares_init_flags & ARES_LIB_INIT_WIN32) ares_win32_cleanup(); +#if defined(ANDROID) || defined(__ANDROID__) + ares_library_cleanup_android(); +#endif + ares_init_flags = ARES_LIB_INIT_NONE; ares_malloc = malloc; ares_realloc = realloc; diff --git a/deps/cares/src/ares_platform.c b/deps/cares/src/ares_platform.c index c20061583f42d6..6c749dccb24a12 100644 --- a/deps/cares/src/ares_platform.c +++ b/deps/cares/src/ares_platform.c @@ -36,6 +36,10 @@ win_platform ares__getplatform(void) memset(&OsvEx, 0, sizeof(OsvEx)); OsvEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4996) /* warning C4996: 'GetVersionExW': was declared deprecated */ +#endif if (!GetVersionEx((void *)&OsvEx)) { memset(&OsvEx, 0, sizeof(OsvEx)); @@ -43,6 +47,9 @@ win_platform ares__getplatform(void) if (!GetVersionEx((void *)&OsvEx)) return WIN_UNKNOWN; } +#ifdef _MSC_VER +#pragma warning(pop) +#endif switch(OsvEx.dwPlatformId) { diff --git a/deps/cares/src/config-win32.h b/deps/cares/src/config-win32.h index cc8e4430a49d23..8d704745269ae3 100644 --- a/deps/cares/src/config-win32.h +++ b/deps/cares/src/config-win32.h @@ -245,7 +245,7 @@ # define _CRT_NONSTDC_NO_DEPRECATE 1 #endif -/* Set the Target to Vista. However, any symbols required above Win2000 +/* Set the Target to Vista. However, any symbols required above Win2000 * should be loaded via LoadLibrary() */ #if defined(_MSC_VER) && (_MSC_VER >= 1500) # define VS2008_MIN_TARGET 0x0600 diff --git a/deps/cares/src/inet_ntop.c b/deps/cares/src/inet_ntop.c index 9420f6cb0d22a8..ce3ce588d3c0bd 100644 --- a/deps/cares/src/inet_ntop.c +++ b/deps/cares/src/inet_ntop.c @@ -54,7 +54,7 @@ static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size); * On Windows we store the error in the thread errno, not * in the winsock error code. This is to avoid loosing the * actual last winsock error. So use macro ERRNO to fetch the - * errno this funtion sets when returning NULL, not SOCKERRNO. + * errno this function sets when returning NULL, not SOCKERRNO. * author: * Paul Vixie, 1996. */