summaryrefslogtreecommitdiff
path: root/deps/cares
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2018-10-24 16:49:04 +0200
committerAnna Henningsen <anna@addaleax.net>2018-11-06 11:29:22 +0000
commit3a25b174aa5451311002247c31a7aa9a461b63b6 (patch)
tree4c53395c19c6cfc8202854c8e19b12be0633cfe8 /deps/cares
parent50f951c90f7a68bc4285a1cfb8e0180c9a336060 (diff)
downloadandroid-node-v8-3a25b174aa5451311002247c31a7aa9a461b63b6.tar.gz
android-node-v8-3a25b174aa5451311002247c31a7aa9a461b63b6.tar.bz2
android-node-v8-3a25b174aa5451311002247c31a7aa9a461b63b6.zip
deps: upgrade to c-ares v1.15.0
Our out-of-tree patch from 2b6bb9f588 ("deps: c-ares float, win ipv6 bad fec0 prefix") should no longer be necessary, c-ares now blacklists such addresses itself. PR-URL: https://github.com/nodejs/node/pull/23854 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Diffstat (limited to 'deps/cares')
-rw-r--r--deps/cares/LICENSE.md2
-rw-r--r--deps/cares/cares.gyp1
-rw-r--r--deps/cares/include/ares.h2
-rw-r--r--deps/cares/include/ares_build.h12
-rw-r--r--deps/cares/include/ares_rules.h2
-rw-r--r--deps/cares/src/RELEASE-NOTES72
-rw-r--r--deps/cares/src/ares_android.c99
-rw-r--r--deps/cares/src/ares_android.h1
-rw-r--r--deps/cares/src/ares_create_query.c6
-rw-r--r--deps/cares/src/ares_destroy.c7
-rw-r--r--deps/cares/src/ares_gethostbyname.c11
-rw-r--r--deps/cares/src/ares_getnameinfo.c11
-rw-r--r--deps/cares/src/ares_init.c400
-rw-r--r--deps/cares/src/ares_library_init.c16
-rw-r--r--deps/cares/src/ares_options.c8
-rw-r--r--deps/cares/src/ares_parse_ptr_reply.c6
-rw-r--r--deps/cares/src/ares_private.h30
-rw-r--r--deps/cares/src/ares_process.c29
-rw-r--r--deps/cares/src/ares_search.c7
-rw-r--r--deps/cares/src/ares_send.c6
-rw-r--r--deps/cares/src/ares_strsplit.c174
-rw-r--r--deps/cares/src/ares_strsplit.h42
-rw-r--r--deps/cares/src/inet_ntop.c3
23 files changed, 662 insertions, 285 deletions
diff --git a/deps/cares/LICENSE.md b/deps/cares/LICENSE.md
index 86b520b91d..ad6bb52b72 100644
--- a/deps/cares/LICENSE.md
+++ b/deps/cares/LICENSE.md
@@ -1,6 +1,6 @@
# c-ares license
-Copyright (c) 2007 - 2016, Daniel Stenberg with many contributors, see AUTHORS
+Copyright (c) 2007 - 2018, Daniel Stenberg with many contributors, see AUTHORS
file.
Copyright 1998 by the Massachusetts Institute of Technology.
diff --git a/deps/cares/cares.gyp b/deps/cares/cares.gyp
index c5719f4d90..be7931f774 100644
--- a/deps/cares/cares.gyp
+++ b/deps/cares/cares.gyp
@@ -92,6 +92,7 @@
'src/ares_strdup.c',
'src/ares_strdup.h',
'src/ares_strerror.c',
+ 'src/ares_strsplit.c',
'src/ares_timeout.c',
'src/ares__timeval.c',
'src/ares_version.c',
diff --git a/deps/cares/include/ares.h b/deps/cares/include/ares.h
index 65a82cb5b7..06f60b3330 100644
--- a/deps/cares/include/ares.h
+++ b/deps/cares/include/ares.h
@@ -164,6 +164,7 @@ extern "C" {
#define ARES_OPT_ROTATE (1 << 14)
#define ARES_OPT_EDNSPSZ (1 << 15)
#define ARES_OPT_NOROTATE (1 << 16)
+#define ARES_OPT_RESOLVCONF (1 << 17)
/* Nameinfo flag values */
#define ARES_NI_NOFQDN (1 << 0)
@@ -270,6 +271,7 @@ struct ares_options {
struct apattern *sortlist;
int nsort;
int ednspsz;
+ char *resolvconf_path;
};
struct hostent;
diff --git a/deps/cares/include/ares_build.h b/deps/cares/include/ares_build.h
index f5535b3849..5e3ba9f0d8 100644
--- a/deps/cares/include/ares_build.h
+++ b/deps/cares/include/ares_build.h
@@ -194,16 +194,14 @@
/* Data type definition of ares_ssize_t. */
#ifdef _WIN32
# ifdef _WIN64
- typedef __int64 ares_ssize_t;
+# define CARES_TYPEOF_ARES_SSIZE_T __int64
# else
- typedef long ares_ssize_t;
+# define CARES_TYPEOF_ARES_SSIZE_T long
# endif
#else
-# ifdef CARES_TYPEOF_ARES_SSIZE_T
- typedef CARES_TYPEOF_ARES_SSIZE_T ares_ssize_t;
-# else
- typedef ssize_t ares_ssize_t;
-# endif
+# define CARES_TYPEOF_ARES_SSIZE_T ssize_t
#endif
+typedef CARES_TYPEOF_ARES_SSIZE_T ares_ssize_t;
+
#endif /* __CARES_BUILD_H */
diff --git a/deps/cares/include/ares_rules.h b/deps/cares/include/ares_rules.h
index e617fdc6da..cac23cf2e3 100644
--- a/deps/cares/include/ares_rules.h
+++ b/deps/cares/include/ares_rules.h
@@ -83,7 +83,7 @@
/*
* Verify that the size previously defined and expected for
- * ares_socklen_t is actually the the same as the one reported
+ * ares_socklen_t is actually the same as the one reported
* by sizeof() at compile time.
*/
diff --git a/deps/cares/src/RELEASE-NOTES b/deps/cares/src/RELEASE-NOTES
index 91230a325b..62276fdf4e 100644
--- a/deps/cares/src/RELEASE-NOTES
+++ b/deps/cares/src/RELEASE-NOTES
@@ -1,47 +1,43 @@
-c-ares version 1.14.0
+c-ares version 1.15.0
Changes:
- o android: Introduce new ares_library_init_android() call for Oreo support. [5]
+ o Add ares_init_options() configurability for path to resolv.conf file [1]
+ o Ability to exclude building of tools (adig, ahost, acountry) in CMake [3]
+ o Android: Support for domain search suffix [4]
+ o Report ARES_ENOTFOUND for .onion domain names as per RFC7686. [13]
Bug fixes:
-
- 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]
+ o AIX build fix for trying to include both nameser_compat.h and
+ onameser_compat.h [2]
+ o Windows: Improve DNS suffixes extracting from WinNT registry [5]
+ o Fix modern GCC warnings [6]
+ o Apply the IPv6 server blacklist to all nameserver sources, not just Windows
+ [7]
+ o Fix warnings emitted by MSVC when using -W4 [8]
+ o Prevent changing name servers while queries are outstanding [9]
+ o Harden and rationalize c-ares timeout computation [10]
+ o Distribute ares_android.h [11]
+ o ares_set_servers_csv() on failure should not leave channel in a bad state
+ [12]
+ o Add missing docs to distribution
Thanks go to these friendly people for their efforts and contributions:
-
- 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)
+ @afalin, Andi Schnebinger, Ben Noordhuis, Brad House, Brad Spencer,
+ David Hotham, @flyingdutchman23, John Schember, Ruslan Baratov,
+ Sarat Addepalli, Tobias Nießen (11 contributors)
References to bug reports and discussions on issues:
+ [1] = https://github.com/c-ares/c-ares/issues/220
+ [2] = https://github.com/c-ares/c-ares/issues/224
+ [3] = https://github.com/c-ares/c-ares/issues/200
+ [4] = https://github.com/c-ares/c-ares/issues/207
+ [5] = https://github.com/c-ares/c-ares/pull/202
+ [6] = https://github.com/c-ares/c-ares/pull/201
+ [7] = https://github.com/c-ares/c-ares/pull/193
+ [8] = https://github.com/c-ares/c-ares/pull/192
+ [9] = https://github.com/c-ares/c-ares/pull/191
+ [10] = https://github.com/c-ares/c-ares/pull/187
+ [11] = https://c-ares.haxx.se/mail/c-ares-archive-2018-04/0000.shtml
+ [12] = https://c-ares.haxx.se/mail/c-ares-archive-2018-03/0000.shtml
+ [13] = https://github.com/c-ares/c-ares/issues/196
- [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
index ab388110bd..bf77131b58 100644
--- a/deps/cares/src/ares_android.c
+++ b/deps/cares/src/ares_android.c
@@ -30,6 +30,8 @@ static jmethodID android_cm_active_net_mid = NULL;
static jmethodID android_cm_link_props_mid = NULL;
/* LinkProperties.getDnsServers */
static jmethodID android_lp_dns_servers_mid = NULL;
+/* LinkProperties.getDomains */
+static jmethodID android_lp_domains_mid = NULL;
/* List.size */
static jmethodID android_list_size_mid = NULL;
/* List.get */
@@ -139,6 +141,12 @@ int ares_library_init_android(jobject connectivity_manager)
if (android_lp_dns_servers_mid == NULL)
goto cleanup;
+ /* getDomains in API 21. */
+ android_lp_domains_mid = jni_get_method_id(env, obj_cls, "getDomains",
+ "()Ljava/lang/String;");
+ if (android_lp_domains_mid == NULL)
+ goto cleanup;
+
(*env)->DeleteLocalRef(env, obj_cls);
obj_cls = jni_get_class(env, "java/util/List");
if (obj_cls == NULL)
@@ -173,6 +181,7 @@ cleanup:
android_cm_active_net_mid = NULL;
android_cm_link_props_mid = NULL;
android_lp_dns_servers_mid = NULL;
+ android_lp_domains_mid = NULL;
android_list_size_mid = NULL;
android_list_get_mid = NULL;
android_ia_host_addr_mid = NULL;
@@ -213,6 +222,7 @@ void ares_library_cleanup_android(void)
android_cm_active_net_mid = NULL;
android_cm_link_props_mid = NULL;
android_lp_dns_servers_mid = NULL;
+ android_lp_domains_mid = NULL;
android_list_size_mid = NULL;
android_list_get_mid = NULL;
android_ia_host_addr_mid = NULL;
@@ -341,6 +351,95 @@ done:
(*android_jvm)->DetachCurrentThread(android_jvm);
return dns_list;
}
+
+char *ares_get_android_search_domains_list(void)
+{
+ JNIEnv *env = NULL;
+ jobject active_network = NULL;
+ jobject link_properties = NULL;
+ jstring domains = NULL;
+ const char *domain;
+ int res;
+ size_t i;
+ size_t cnt = 0;
+ char *domain_list = NULL;
+ int need_detatch = 0;
+
+ if (android_jvm == NULL || android_connectivity_manager == NULL)
+ {
+ return NULL;
+ }
+
+ if (android_cm_active_net_mid == NULL || android_cm_link_props_mid == NULL ||
+ android_lp_domains_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;
+
+ ConnectivityManager cm = (ConnectivityManager)this.getApplicationContext()
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ Network an = cm.getActiveNetwork();
+ LinkProperties lp = cm.getLinkProperties(an);
+ String domains = lp.getDomains();
+ for (String domain: domains.split(",")) {
+ String d = domain;
+ }
+
+ 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;
+
+ /* Get the domains. It is a common separated list of domains to search. */
+ domains = (*env)->CallObjectMethod(env, link_properties,
+ android_lp_domains_mid);
+ if (domains == NULL)
+ goto done;
+
+ /* Split on , */
+ domain = (*env)->GetStringUTFChars(env, domains, 0);
+ domain_list = ares_strdup(domain);
+ (*env)->ReleaseStringUTFChars(env, domains, domain);
+ (*env)->DeleteLocalRef(env, domains);
+
+done:
+ if ((*env)->ExceptionOccurred(env))
+ (*env)->ExceptionClear(env);
+
+ 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 domain_list;
+}
#else
/* warning: ISO C forbids an empty translation unit */
typedef int dummy_make_iso_compilers_happy;
diff --git a/deps/cares/src/ares_android.h b/deps/cares/src/ares_android.h
index ff520f96e8..93fb75f585 100644
--- a/deps/cares/src/ares_android.h
+++ b/deps/cares/src/ares_android.h
@@ -19,6 +19,7 @@
#if defined(ANDROID) || defined(__ANDROID__)
char **ares_get_android_server_list(size_t max_servers, size_t *num_servers);
+char *ares_get_android_search_domains_list(void);
void ares_library_cleanup_android(void);
#endif
diff --git a/deps/cares/src/ares_create_query.c b/deps/cares/src/ares_create_query.c
index 07d7570114..1606b1a100 100644
--- a/deps/cares/src/ares_create_query.c
+++ b/deps/cares/src/ares_create_query.c
@@ -94,6 +94,10 @@ int ares_create_query(const char *name, int dnsclass, int type,
size_t buflen;
unsigned char *buf;
+ /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
+ if (ares__is_onion_domain(name))
+ return ARES_ENOTFOUND;
+
/* Set our results early, in case we bail out early with an error. */
*buflenp = 0;
*bufp = NULL;
@@ -188,7 +192,7 @@ int ares_create_query(const char *name, int dnsclass, int type,
* specified in RFC 1035 ("To simplify implementations, the total length of
* a domain name (i.e., label octets and label length octets) is restricted
* to 255 octets or less."). */
- if (buflen > (MAXCDNAME + HFIXEDSZ + QFIXEDSZ +
+ if (buflen > (size_t)(MAXCDNAME + HFIXEDSZ + QFIXEDSZ +
(max_udp_size ? EDNSFIXEDSZ : 0))) {
ares_free (buf);
return ARES_EBADNAME;
diff --git a/deps/cares/src/ares_destroy.c b/deps/cares/src/ares_destroy.c
index 8aa42236ae..fed2009ab3 100644
--- a/deps/cares/src/ares_destroy.c
+++ b/deps/cares/src/ares_destroy.c
@@ -36,6 +36,8 @@ void ares_destroy_options(struct ares_options *options)
ares_free(options->sortlist);
if(options->lookups)
ares_free(options->lookups);
+ if(options->resolvconf_path)
+ ares_free(options->resolvconf_path);
}
void ares_destroy(ares_channel channel)
@@ -44,7 +46,7 @@ void ares_destroy(ares_channel channel)
struct query *query;
struct list_node* list_head;
struct list_node* list_node;
-
+
if (!channel)
return;
@@ -85,6 +87,9 @@ void ares_destroy(ares_channel channel)
if (channel->lookups)
ares_free(channel->lookups);
+ if (channel->resolvconf_path)
+ ares_free(channel->resolvconf_path);
+
ares_free(channel);
}
diff --git a/deps/cares/src/ares_gethostbyname.c b/deps/cares/src/ares_gethostbyname.c
index 7c46d96cea..8187746bb1 100644
--- a/deps/cares/src/ares_gethostbyname.c
+++ b/deps/cares/src/ares_gethostbyname.c
@@ -95,6 +95,13 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
return;
}
+ /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
+ if (ares__is_onion_domain(name))
+ {
+ callback(arg, ARES_ENOTFOUND, 0, NULL);
+ return;
+ }
+
if (fake_hostent(name, family, callback, arg))
return;
@@ -339,6 +346,10 @@ static int file_lookup(const char *name, int family, struct hostent **host)
int status;
int error;
+ /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
+ if (ares__is_onion_domain(name))
+ return ARES_ENOTFOUND;
+
#ifdef WIN32
char PATH_HOSTS[MAX_PATH];
win_platform platform;
diff --git a/deps/cares/src/ares_getnameinfo.c b/deps/cares/src/ares_getnameinfo.c
index c77b1f8153..aa08941706 100644
--- a/deps/cares/src/ares_getnameinfo.c
+++ b/deps/cares/src/ares_getnameinfo.c
@@ -440,3 +440,14 @@ STATIC_TESTABLE char *ares_striendstr(const char *s1, const char *s2)
}
return (char *)c1_begin;
}
+
+int ares__is_onion_domain(const char *name)
+{
+ if (ares_striendstr(name, ".onion"))
+ return 1;
+
+ if (ares_striendstr(name, ".onion."))
+ return 1;
+
+ return 0;
+}
diff --git a/deps/cares/src/ares_init.c b/deps/cares/src/ares_init.c
index 90cfcabdd3..c2c00d6523 100644
--- a/deps/cares/src/ares_init.c
+++ b/deps/cares/src/ares_init.c
@@ -169,6 +169,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
channel->sock_config_cb_data = NULL;
channel->sock_funcs = NULL;
channel->sock_func_cb_data = NULL;
+ channel->resolvconf_path = NULL;
channel->last_server = 0;
channel->last_timeout_processed = (time_t)now.tv_sec;
@@ -236,16 +237,14 @@ done:
/* Something failed; clean up memory we may have allocated. */
if (channel->servers)
ares_free(channel->servers);
- if (channel->domains)
- {
- for (i = 0; i < channel->ndomains; i++)
- ares_free(channel->domains[i]);
- ares_free(channel->domains);
- }
+ if (channel->ndomains != -1)
+ ares_strsplit_free(channel->domains, channel->ndomains);
if (channel->sortlist)
ares_free(channel->sortlist);
if(channel->lookups)
ares_free(channel->lookups);
+ if(channel->resolvconf_path)
+ ares_free(channel->resolvconf_path);
ares_free(channel);
return status;
}
@@ -299,7 +298,7 @@ int ares_dup(ares_channel *dest, ares_channel src)
(*dest)->sock_func_cb_data = src->sock_func_cb_data;
strncpy((*dest)->local_dev_name, src->local_dev_name,
- sizeof(src->local_dev_name));
+ sizeof((*dest)->local_dev_name));
(*dest)->local_ip4 = src->local_ip4;
memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
@@ -354,6 +353,9 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS);
(*optmask) |= (channel->rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE);
+ if (channel->resolvconf_path)
+ (*optmask) |= ARES_OPT_RESOLVCONF;
+
/* Copy easy stuff */
options->flags = channel->flags;
@@ -426,6 +428,13 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
}
options->nsort = channel->nsort;
+ /* copy path for resolv.conf file */
+ if (channel->resolvconf_path) {
+ options->resolvconf_path = ares_strdup(channel->resolvconf_path);
+ if (!options->resolvconf_path)
+ return ARES_ENOMEM;
+ }
+
return ARES_SUCCESS;
}
@@ -534,6 +543,14 @@ static int init_by_options(ares_channel channel,
channel->nsort = options->nsort;
}
+ /* Set path for resolv.conf file, if given. */
+ if ((optmask & ARES_OPT_RESOLVCONF) && !channel->resolvconf_path)
+ {
+ channel->resolvconf_path = ares_strdup(options->resolvconf_path);
+ if (!channel->resolvconf_path && options->resolvconf_path)
+ return ARES_ENOMEM;
+ }
+
channel->optmask = optmask;
return ARES_SUCCESS;
@@ -997,63 +1014,6 @@ static int compareAddresses(const void *arg1,
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;
-}
-
/* There can be multiple routes to "the Internet". And there can be different
* DNS servers associated with each of the interfaces that offer those routes.
* We have to assume that any DNS server can serve any request. But, some DNS
@@ -1257,7 +1217,7 @@ static int get_DNS_AdaptersAddresses(char **outptr)
}
else
{
- addresses[addressesIndex].metric = -1;
+ addresses[addressesIndex].metric = (ULONG)-1;
}
/* Record insertion index to make qsort stable */
@@ -1272,20 +1232,10 @@ static int get_DNS_AdaptersAddresses(char **outptr)
}
else if (namesrvr.sa->sa_family == AF_INET6)
{
- /* Windows apparently always reports some IPv6 DNS servers that
- * prefixed with fec0:0:0:ffff. These ususally do not point to
- * working DNS servers, so we ignore them. */
- if (strncmp(addresses[addressesIndex].text, "fec0:0:0:ffff:", 14) == 0)
- continue;
if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
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;
@@ -1309,7 +1259,7 @@ static int get_DNS_AdaptersAddresses(char **outptr)
}
else
{
- addresses[addressesIndex].metric = -1;
+ addresses[addressesIndex].metric = (ULONG)-1;
}
/* Record insertion index to make qsort stable */
@@ -1394,59 +1344,6 @@ static int get_DNS_Windows(char **outptr)
return get_DNS_Registry(outptr);
}
-static void replace_comma_by_space(char* str)
-{
- /* replace ',' by ' ' to coincide with resolv.conf search parameter */
- char *p;
- for (p = str; *p != '\0'; p++)
- {
- if (*p == ',')
- *p = ' ';
- }
-}
-
-/* Search if 'suffix' is containted in the 'searchlist'. Returns true if yes,
- * otherwise false. 'searchlist' is a comma separated list of domain suffixes,
- * 'suffix' is one domain suffix, 'len' is the length of 'suffix'.
- * The search ignores case. E.g.:
- * contains_suffix("abc.def,ghi.jkl", "ghi.JKL") returns true */
-static bool contains_suffix(const char* const searchlist,
- const char* const suffix, const size_t len)
-{
- const char* beg = searchlist;
- const char* end;
- if (!*suffix)
- return true;
- for (;;)
- {
- while (*beg && (ISSPACE(*beg) || (*beg == ',')))
- ++beg;
- if (!*beg)
- return false;
- end = beg;
- while (*end && !ISSPACE(*end) && (*end != ','))
- ++end;
- if (len == (end - beg) && !strnicmp(beg, suffix, len))
- return true;
- beg = end;
- }
-}
-
-/* advances list to the next suffix within a comma separated search list.
- * len is the length of the next suffix. */
-static size_t next_suffix(const char** list, const size_t advance)
-{
- const char* beg = *list + advance;
- const char* end;
- while (*beg && (ISSPACE(*beg) || (*beg == ',')))
- ++beg;
- end = beg;
- while (*end && !ISSPACE(*end) && (*end != ','))
- ++end;
- *list = beg;
- return end - beg;
-}
-
/*
* get_SuffixList_Windows()
*
@@ -1467,8 +1364,6 @@ static int get_SuffixList_Windows(char **outptr)
DWORD keyNameBuffSize;
DWORD keyIdx = 0;
char *p = NULL;
- const char *pp;
- size_t len = 0;
*outptr = NULL;
@@ -1479,11 +1374,26 @@ static int get_SuffixList_Windows(char **outptr)
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
KEY_READ, &hKey) == ERROR_SUCCESS)
{
- if (get_REG_SZ(hKey, SEARCHLIST_KEY, outptr))
- replace_comma_by_space(*outptr);
+ get_REG_SZ(hKey, SEARCHLIST_KEY, outptr);
+ if (get_REG_SZ(hKey, DOMAIN_KEY, &p))
+ {
+ commajoin(outptr, p);
+ ares_free(p);
+ p = NULL;
+ }
+ RegCloseKey(hKey);
+ }
+
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NT_DNSCLIENT, 0,
+ KEY_READ, &hKey) == ERROR_SUCCESS)
+ {
+ if (get_REG_SZ(hKey, SEARCHLIST_KEY, &p))
+ {
+ commajoin(outptr, p);
+ ares_free(p);
+ p = NULL;
+ }
RegCloseKey(hKey);
- if (*outptr)
- return 1;
}
/* 2. Connection Specific Search List composed of:
@@ -1491,45 +1401,53 @@ static int get_SuffixList_Windows(char **outptr)
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_DNSCLIENT, 0,
KEY_READ, &hKey) == ERROR_SUCCESS)
{
- get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, outptr);
+ if (get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, &p))
+ {
+ commajoin(outptr, p);
+ ares_free(p);
+ p = NULL;
+ }
RegCloseKey(hKey);
}
- if (!*outptr)
- return 0;
/* b. Interface SearchList, Domain, DhcpDomain */
- if (!RegOpenKeyExA(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 (RegEnumKeyExA(hKey, keyIdx++, keyName, &keyNameBuffSize,
- 0, NULL, NULL, NULL)
- != ERROR_SUCCESS)
- break;
- if (RegOpenKeyExA(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum)
- != ERROR_SUCCESS)
- continue;
- if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p) ||
- get_REG_SZ(hKeyEnum, DOMAIN_KEY, &p) ||
- get_REG_SZ(hKeyEnum, DHCPDOMAIN_KEY, &p))
+ for(;;)
{
+ keyNameBuffSize = sizeof(keyName);
+ if (RegEnumKeyExA(hKey, keyIdx++, keyName, &keyNameBuffSize,
+ 0, NULL, NULL, NULL)
+ != ERROR_SUCCESS)
+ break;
+ if (RegOpenKeyExA(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum)
+ != ERROR_SUCCESS)
+ continue;
/* p can be comma separated (SearchList) */
- pp = p;
- while ((len = next_suffix(&pp, len)) != 0)
+ if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p))
{
- if (!contains_suffix(*outptr, pp, len))
- commanjoin(outptr, pp, len);
+ commajoin(outptr, p);
+ ares_free(p);
+ p = NULL;
}
- ares_free(p);
- p = NULL;
+ if (get_REG_SZ(hKeyEnum, DOMAIN_KEY, &p))
+ {
+ commajoin(outptr, p);
+ ares_free(p);
+ p = NULL;
+ }
+ if (get_REG_SZ(hKeyEnum, DHCPDOMAIN_KEY, &p))
+ {
+ commajoin(outptr, p);
+ ares_free(p);
+ p = NULL;
+ }
+ RegCloseKey(hKeyEnum);
}
- RegCloseKey(hKeyEnum);
+ RegCloseKey(hKey);
}
- RegCloseKey(hKey);
- if (*outptr)
- replace_comma_by_space(*outptr);
+
return *outptr != NULL;
}
@@ -1628,6 +1546,7 @@ static int init_by_resolv_conf(ares_channel channel)
char propname[PROP_NAME_MAX];
char propvalue[PROP_VALUE_MAX]="";
char **dns_servers;
+ char *domains;
size_t num_servers;
/* Use the Android connectivity manager to get a list
@@ -1652,6 +1571,12 @@ static int init_by_resolv_conf(ares_channel channel)
}
ares_free(dns_servers);
}
+ if (channel->ndomains == -1)
+ {
+ domains = ares_get_android_search_domains_list();
+ set_search(channel, domains);
+ ares_free(domains);
+ }
# ifdef HAVE___SYSTEM_PROPERTY_GET
/* Old way using the system property still in place as
@@ -1740,6 +1665,7 @@ static int init_by_resolv_conf(ares_channel channel)
size_t linesize;
int error;
int update_domains;
+ const char *resolvconf_path;
/* Don't read resolv.conf and friends if we don't have to */
if (ARES_CONFIG_CHECK(channel))
@@ -1748,7 +1674,14 @@ static int init_by_resolv_conf(ares_channel channel)
/* Only update search domains if they're not already specified */
update_domains = (channel->ndomains == -1);
- fp = fopen(PATH_RESOLV_CONF, "r");
+ /* Support path for resolvconf filename set by ares_init_options */
+ if(channel->resolvconf_path) {
+ resolvconf_path = channel->resolvconf_path;
+ } else {
+ resolvconf_path = PATH_RESOLV_CONF;
+ }
+
+ fp = fopen(resolvconf_path, "r");
if (fp) {
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
{
@@ -1759,10 +1692,10 @@ static int init_by_resolv_conf(ares_channel channel)
else if ((p = try_config(line, "search", ';')) && update_domains)
status = set_search(channel, p);
else if ((p = try_config(line, "nameserver", ';')) &&
- channel->nservers == -1)
+ channel->nservers == -1)
status = config_nameserver(&servers, &nservers, p);
else if ((p = try_config(line, "sortlist", ';')) &&
- channel->nsort == -1)
+ channel->nsort == -1)
status = config_sortlist(&sortlist, &nsort, p);
else if ((p = try_config(line, "options", ';')))
status = set_options(channel, p);
@@ -1782,7 +1715,7 @@ static int init_by_resolv_conf(ares_channel channel)
break;
default:
DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
- error, strerror(error)));
+ error, strerror(error)));
DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
status = ARES_EFILE;
}
@@ -2050,6 +1983,11 @@ static int init_by_defaults(ares_channel channel)
ares_free(channel->lookups);
channel->lookups = NULL;
}
+
+ if(channel->resolvconf_path) {
+ ares_free(channel->resolvconf_path);
+ channel->resolvconf_path = NULL;
+ }
}
if(hostname)
@@ -2114,6 +2052,76 @@ static int config_lookup(ares_channel channel, const char *str,
#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ & !CARES_USE_LIBRESOLV */
#ifndef WATT32
+/* 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;
+}
+
+/* Return true iff the IPv6 ipaddr is blacklisted. */
+static int ares_ipv6_server_blacklisted(const unsigned char ipaddr[16])
+{
+ /* A list of blacklisted IPv6 subnets. */
+ const struct {
+ const unsigned char netbase[16];
+ unsigned char netmask;
+ } blacklist[] = {
+ /* fec0::/10 was deprecated by [RFC3879] in September 2004. Formerly a
+ * Site-Local scoped address prefix. These are never valid DNS servers,
+ * but are known to be returned at least sometimes on Windows and Android.
+ */
+ {
+ {
+ 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ 10
+ }
+ };
+ size_t i;
+
+ /* See if ipaddr matches any of the entries in the blacklist. */
+ for (i = 0; i < sizeof(blacklist) / sizeof(blacklist[0]); ++i) {
+ if (ares_ipv6_subnet_matches(
+ blacklist[i].netbase, blacklist[i].netmask, ipaddr))
+ return 1;
+ }
+ return 0;
+}
+
+/* Add the IPv4 or IPv6 nameservers in str (separated by commas) to the
+ * servers list, updating servers and nservers as required.
+ *
+ * This will silently ignore blacklisted IPv6 nameservers as detected by
+ * ares_ipv6_server_blacklisted().
+ *
+ * Returns an error code on failure, else ARES_SUCCESS.
+ */
static int config_nameserver(struct server_state **servers, int *nservers,
char *str)
{
@@ -2148,7 +2156,10 @@ static int config_nameserver(struct server_state **servers, int *nservers,
/* Convert textual address to binary format. */
if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
host.family = AF_INET;
- else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
+ else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1
+ /* Silently skip blacklisted IPv6 servers. */
+ && !ares_ipv6_server_blacklisted(
+ (const unsigned char *)&host.addrV6))
host.family = AF_INET6;
else
continue;
@@ -2271,61 +2282,22 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
static int set_search(ares_channel channel, const char *str)
{
- int n;
- const char *p, *q;
+ size_t cnt;
if(channel->ndomains != -1) {
/* LCOV_EXCL_START: all callers check ndomains == -1 */
/* if we already have some domains present, free them first */
- for(n=0; n < channel->ndomains; n++)
- ares_free(channel->domains[n]);
- ares_free(channel->domains);
+ ares_strsplit_free(channel->domains, channel->ndomains);
channel->domains = NULL;
channel->ndomains = -1;
} /* LCOV_EXCL_STOP */
- /* Count the domains given. */
- n = 0;
- p = str;
- while (*p)
- {
- while (*p && !ISSPACE(*p))
- p++;
- while (ISSPACE(*p))
- p++;
- n++;
- }
-
- if (!n)
- {
- channel->ndomains = 0;
- return ARES_SUCCESS;
- }
-
- channel->domains = ares_malloc(n * sizeof(char *));
- if (!channel->domains)
- return ARES_ENOMEM;
-
- /* Now copy the domains. */
- n = 0;
- p = str;
- while (*p)
- {
- channel->ndomains = n;
- q = p;
- while (*q && !ISSPACE(*q))
- q++;
- channel->domains[n] = ares_malloc(q - p + 1);
- if (!channel->domains[n])
- return ARES_ENOMEM;
- memcpy(channel->domains[n], p, q - p);
- channel->domains[n][q - p] = 0;
- p = q;
- while (ISSPACE(*p))
- p++;
- n++;
- }
- channel->ndomains = n;
+ channel->domains = ares_strsplit(str, ", ", 1, &cnt);
+ channel->ndomains = (int)cnt;
+ if (channel->domains == NULL || channel->ndomains == 0) {
+ channel->domains = NULL;
+ channel->ndomains = -1;
+ }
return ARES_SUCCESS;
}
diff --git a/deps/cares/src/ares_library_init.c b/deps/cares/src/ares_library_init.c
index 88e7a53748..67563499be 100644
--- a/deps/cares/src/ares_library_init.c
+++ b/deps/cares/src/ares_library_init.c
@@ -40,9 +40,19 @@ static unsigned int ares_initialized;
static int ares_init_flags;
/* library-private global vars with visibility across the whole library */
-void *(*ares_malloc)(size_t size) = malloc;
-void *(*ares_realloc)(void *ptr, size_t size) = realloc;
-void (*ares_free)(void *ptr) = free;
+#if defined(WIN32)
+/* We need indirections to handle Windows DLL rules. */
+static void *default_malloc(size_t size) { return malloc(size); }
+static void *default_realloc(void *p, size_t size) { return realloc(p, size); }
+static void default_free(void *p) { free(p); }
+#else
+# define default_malloc malloc
+# define default_realloc realloc
+# define default_free free
+#endif
+void *(*ares_malloc)(size_t size) = default_malloc;
+void *(*ares_realloc)(void *ptr, size_t size) = default_realloc;
+void (*ares_free)(void *ptr) = default_free;
#ifdef USE_WINSOCK
static HMODULE hnd_iphlpapi;
diff --git a/deps/cares/src/ares_options.c b/deps/cares/src/ares_options.c
index c3cbd1df70..de49de4625 100644
--- a/deps/cares/src/ares_options.c
+++ b/deps/cares/src/ares_options.c
@@ -153,6 +153,9 @@ int ares_set_servers(ares_channel channel,
if (!channel)
return ARES_ENODATA;
+ if (!ares__is_list_empty(&channel->all_queries))
+ return ARES_ENOTIMP;
+
ares__destroy_servers_state(channel);
for (srvr = servers; srvr; srvr = srvr->next)
@@ -202,6 +205,9 @@ int ares_set_servers_ports(ares_channel channel,
if (!channel)
return ARES_ENODATA;
+ if (!ares__is_list_empty(&channel->all_queries))
+ return ARES_ENOTIMP;
+
ares__destroy_servers_state(channel);
for (srvr = servers; srvr; srvr = srvr->next)
@@ -258,8 +264,6 @@ static int set_servers_csv(ares_channel channel,
if (!channel)
return ARES_ENODATA;
- ares__destroy_servers_state(channel);
-
i = strlen(_csv);
if (i == 0)
return ARES_SUCCESS; /* blank all servers */
diff --git a/deps/cares/src/ares_parse_ptr_reply.c b/deps/cares/src/ares_parse_ptr_reply.c
index 976a5311a2..29e22cb17b 100644
--- a/deps/cares/src/ares_parse_ptr_reply.c
+++ b/deps/cares/src/ares_parse_ptr_reply.c
@@ -52,6 +52,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
int aliascnt = 0;
int alias_alloc = 8;
char ** aliases;
+ size_t rr_data_len;
/* Set *host to NULL for all failure cases. */
*host = NULL;
@@ -124,14 +125,15 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
if (hostname)
ares_free(hostname);
hostname = rr_data;
- aliases[aliascnt] = ares_malloc((strlen(rr_data)+1) * sizeof(char));
+ rr_data_len = strlen(rr_data)+1;
+ aliases[aliascnt] = ares_malloc(rr_data_len * sizeof(char));
if (!aliases[aliascnt])
{
ares_free(rr_name);
status = ARES_ENOMEM;
break;
}
- strncpy(aliases[aliascnt], rr_data, strlen(rr_data)+1);
+ strncpy(aliases[aliascnt], rr_data, rr_data_len);
aliascnt++;
if (aliascnt >= alias_alloc) {
char **ptr;
diff --git a/deps/cares/src/ares_private.h b/deps/cares/src/ares_private.h
index 5d773869c7..1990f6902f 100644
--- a/deps/cares/src/ares_private.h
+++ b/deps/cares/src/ares_private.h
@@ -52,18 +52,19 @@
#if defined(WIN32) && !defined(WATT32)
-#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
-#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
-#define WIN_DNSCLIENT "Software\\Policies\\Microsoft\\System\\DNSClient"
-#define NAMESERVER "NameServer"
-#define DHCPNAMESERVER "DhcpNameServer"
-#define DATABASEPATH "DatabasePath"
-#define WIN_PATH_HOSTS "\\hosts"
-#define SEARCHLIST_KEY "SearchList"
+#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
+#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
+#define WIN_DNSCLIENT "Software\\Policies\\Microsoft\\System\\DNSClient"
+#define WIN_NT_DNSCLIENT "Software\\Policies\\Microsoft\\Windows NT\\DNSClient"
+#define NAMESERVER "NameServer"
+#define DHCPNAMESERVER "DhcpNameServer"
+#define DATABASEPATH "DatabasePath"
+#define WIN_PATH_HOSTS "\\hosts"
+#define SEARCHLIST_KEY "SearchList"
#define PRIMARYDNSSUFFIX_KEY "PrimaryDNSSuffix"
-#define INTERFACES_KEY "Interfaces"
-#define DOMAIN_KEY "Domain"
-#define DHCPDOMAIN_KEY "DhcpDomain"
+#define INTERFACES_KEY "Interfaces"
+#define DOMAIN_KEY "Domain"
+#define DHCPDOMAIN_KEY "DhcpDomain"
#elif defined(WATT32)
@@ -100,6 +101,7 @@
#endif
#include "ares_strdup.h"
+#include "ares_strsplit.h"
#ifndef HAVE_STRCASECMP
# include "ares_strcasecmp.h"
@@ -323,8 +325,14 @@ struct ares_channeldata {
const struct ares_socket_functions * sock_funcs;
void *sock_func_cb_data;
+
+ /* Path for resolv.conf file, configurable via ares_options */
+ char *resolvconf_path;
};
+/* Does the domain end in ".onion" or ".onion."? Case-insensitive. */
+int ares__is_onion_domain(const char *name);
+
/* Memory management functions */
extern void *(*ares_malloc)(size_t size);
extern void *(*ares_realloc)(void *ptr, size_t size);
diff --git a/deps/cares/src/ares_process.c b/deps/cares/src/ares_process.c
index df85524f62..df9f290bb1 100644
--- a/deps/cares/src/ares_process.c
+++ b/deps/cares/src/ares_process.c
@@ -53,6 +53,7 @@
#include <assert.h>
#include <fcntl.h>
+#include <limits.h>
#include "ares.h"
#include "ares_dns.h"
@@ -871,8 +872,32 @@ void ares__send_query(ares_channel channel, struct query *query,
return;
}
}
- timeplus = channel->timeout << (query->try_count / channel->nservers);
- timeplus = (timeplus * (9 + (rand () & 7))) / 16;
+
+ /* For each trip through the entire server list, double the channel's
+ * assigned timeout, avoiding overflow. If channel->timeout is negative,
+ * leave it as-is, even though that should be impossible here.
+ */
+ timeplus = channel->timeout;
+ {
+ /* How many times do we want to double it? Presume sane values here. */
+ const int shift = query->try_count / channel->nservers;
+
+ /* Is there enough room to shift timeplus left that many times?
+ *
+ * To find out, confirm that all of the bits we'll shift away are zero.
+ * Stop considering a shift if we get to the point where we could shift
+ * a 1 into the sign bit (i.e. when shift is within two of the bit
+ * count).
+ *
+ * This has the side benefit of leaving negative numbers unchanged.
+ */
+ if(shift <= (int)(sizeof(int) * CHAR_BIT - 1)
+ && (timeplus >> (sizeof(int) * CHAR_BIT - 1 - shift)) == 0)
+ {
+ timeplus <<= shift;
+ }
+ }
+
query->timeout = *now;
timeadd(&query->timeout, timeplus);
/* Keep track of queries bucketed by timeout, so we can process
diff --git a/deps/cares/src/ares_search.c b/deps/cares/src/ares_search.c
index 68e852574f..001c3482a7 100644
--- a/deps/cares/src/ares_search.c
+++ b/deps/cares/src/ares_search.c
@@ -54,6 +54,13 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
const char *p;
int status, ndots;
+ /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
+ if (ares__is_onion_domain(name))
+ {
+ callback(arg, ARES_ENOTFOUND, 0, NULL, 0);
+ return;
+ }
+
/* If name only yields one domain to search, then we don't have
* to keep extra state, so just do an ares_query().
*/
diff --git a/deps/cares/src/ares_send.c b/deps/cares/src/ares_send.c
index 88c0035520..f4f1f95119 100644
--- a/deps/cares/src/ares_send.c
+++ b/deps/cares/src/ares_send.c
@@ -60,6 +60,12 @@ void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
callback(arg, ARES_ENOMEM, 0, NULL, 0);
return;
}
+ if (channel->nservers < 1)
+ {
+ ares_free(query);
+ callback(arg, ARES_ESERVFAIL, 0, NULL, 0);
+ return;
+ }
query->server_info = ares_malloc(channel->nservers *
sizeof(query->server_info[0]));
if (!query->server_info)
diff --git a/deps/cares/src/ares_strsplit.c b/deps/cares/src/ares_strsplit.c
new file mode 100644
index 0000000000..b57a30f2a9
--- /dev/null
+++ b/deps/cares/src/ares_strsplit.c
@@ -0,0 +1,174 @@
+/* Copyright (C) 2018 by John Schember <john@nachtimwald.com>
+ *
+ * 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.
+ */
+
+#include "ares_setup.h"
+#include "ares_strsplit.h"
+#include "ares.h"
+#include "ares_private.h"
+
+static int list_contains(char * const *list, size_t num_elem, const char *str, int insensitive)
+{
+ size_t len;
+ size_t i;
+
+ len = strlen(str);
+ for (i=0; i<num_elem; i++)
+ {
+ if (insensitive)
+ {
+#ifdef WIN32
+ if (strnicmp(list[i], str, len) == 0)
+#else
+ if (strncasecmp(list[i], str, len) == 0)
+#endif
+ return 1;
+ }
+ else
+ {
+ if (strncmp(list[i], str, len) == 0)
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int is_delim(char c, const char *delims, size_t num_delims)
+{
+ size_t i;
+
+ for (i=0; i<num_delims; i++)
+ {
+ if (c == delims[i])
+ return 1;
+ }
+ return 0;
+}
+
+
+void ares_strsplit_free(char **elms, size_t num_elm)
+{
+ size_t i;
+
+ if (elms == NULL)
+ return;
+
+ for (i=0; i<num_elm; i++)
+ ares_free(elms[i]);
+ ares_free(elms);
+}
+
+
+char **ares_strsplit(const char *in, const char *delms, int make_set, size_t *num_elm)
+{
+ char *parsestr;
+ char **temp;
+ char **out;
+ size_t cnt;
+ size_t nelms;
+ size_t in_len;
+ size_t num_delims;
+ size_t i;
+
+ if (in == NULL || delms == NULL || num_elm == NULL)
+ return NULL;
+
+ *num_elm = 0;
+
+ in_len = strlen(in);
+ num_delims = strlen(delms);
+
+ /* Figure out how many elements. */
+ nelms = 1;
+ for (i=0; i<in_len; i++)
+ {
+ if (is_delim(in[i], delms, num_delims))
+ {
+ nelms++;
+ }
+ }
+
+ /* Copy of input so we can cut it up. */
+ parsestr = ares_strdup(in);
+ if (parsestr == NULL)
+ return NULL;
+
+ /* Temporary array to store locations of start of each element
+ * within parsestr. */
+ temp = ares_malloc(nelms * sizeof(*temp));
+ if (temp == NULL)
+ {
+ ares_free(parsestr);
+ return NULL;
+ }
+ temp[0] = parsestr;
+ cnt = 1;
+ for (i=0; i<in_len && cnt<nelms; i++)
+ {
+ if (!is_delim(parsestr[i], delms, num_delims))
+ continue;
+
+ /* Replace sep with NULL. */
+ parsestr[i] = '\0';
+ /* Add the pointer to the array of elements */
+ temp[cnt] = parsestr+i+1;
+ cnt++;
+ }
+
+ /* Copy each element to our output array. */
+ out = ares_malloc(nelms * sizeof(*out));
+ if (out == NULL)
+ {
+ ares_free(parsestr);
+ ares_free(temp);
+ return NULL;
+ }
+
+ nelms = 0;
+ for (i=0; i<cnt; i++)
+ {
+ if (temp[i][0] == '\0')
+ continue;
+
+ if (make_set && list_contains(out, nelms, temp[i], 1))
+ continue;
+
+ out[nelms] = ares_strdup(temp[i]);
+ if (out[nelms] == NULL)
+ {
+ ares_strsplit_free(out, nelms);
+ ares_free(parsestr);
+ ares_free(temp);
+ return NULL;
+ }
+ nelms++;
+ }
+
+
+ /* If there are no elements don't return an empty allocated
+ * array. */
+ if (nelms == 0)
+ {
+ ares_strsplit_free(out, nelms);
+ out = NULL;
+ }
+
+ /* Get the true number of elements (recalculated because of make_set) */
+ *num_elm = nelms;
+
+ ares_free(parsestr);
+ ares_free(temp);
+ return out;
+}
diff --git a/deps/cares/src/ares_strsplit.h b/deps/cares/src/ares_strsplit.h
new file mode 100644
index 0000000000..da286a9aef
--- /dev/null
+++ b/deps/cares/src/ares_strsplit.h
@@ -0,0 +1,42 @@
+#ifndef HEADER_CARES_STRSPLIT_H
+#define HEADER_CARES_STRSPLIT_H
+
+/* Copyright (C) 2018 by John Schember <john@nachtimwald.com>
+ *
+ * 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.
+ */
+
+#include "ares_setup.h"
+
+/* Split a string on delem skipping empty elements.
+ *
+ * param in String to split.
+ * param delims String of characters to treat as a delimitor.
+ * Each character in the string is a delimitor so
+ * there can be multiple delimitors to split on.
+ * E.g. ", " will split on all comma's and spaces.
+ * param make_set Have the list be a Set where there are no
+ * duplicate entries. 1 for true, 0 or false.
+ * param num_elm Return parameter of the number of elements
+ * in the result array.
+ *
+ * returns an allocated array of allocated string elements.
+ *
+ */
+char **ares_strsplit(const char *in, const char *delms, int make_set, size_t *num_elm);
+
+/* Frees the result returned from ares_strsplit(). */
+void ares_strsplit_free(char **elms, size_t num_elm);
+
+
+#endif /* HEADER_CARES_STRSPLIT_H */
diff --git a/deps/cares/src/inet_ntop.c b/deps/cares/src/inet_ntop.c
index ce3ce588d3..1935a871ce 100644
--- a/deps/cares/src/inet_ntop.c
+++ b/deps/cares/src/inet_ntop.c
@@ -180,8 +180,7 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
tp += sprintf(tp, "%x", words[i]);
}
/* Was it a trailing run of 0x00's? */
- if (best.base != -1 && (best.base + best.len) ==
- (NS_IN6ADDRSZ / NS_INT16SZ))
+ if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ))
*tp++ = ':';
*tp++ = '\0';