File cares_172.patch of Package nodejs10.25441
diff --git a/deps/cares/src/AUTHORS b/deps/cares/AUTHORS
similarity index 100%
rename from deps/cares/src/AUTHORS
rename to deps/cares/AUTHORS
diff --git a/deps/cares/src/NEWS b/deps/cares/NEWS
similarity index 100%
rename from deps/cares/src/NEWS
rename to deps/cares/NEWS
diff --git a/deps/cares/src/README.cares b/deps/cares/README.cares
similarity index 100%
rename from deps/cares/src/README.cares
rename to deps/cares/README.cares
diff --git a/deps/cares/src/README.md b/deps/cares/README.md
similarity index 92%
rename from deps/cares/src/README.md
rename to deps/cares/README.md
index 93c1f5f812..148338f9e1 100644
--- a/deps/cares/src/README.md
+++ b/deps/cares/README.md
@@ -2,9 +2,10 @@ c-ares
======
[](https://travis-ci.org/c-ares/c-ares)
-[](https://ci.appveyor.com/project/c-ares/c-ares)
+[](https://ci.appveyor.com/project/c-ares/c-ares/branch/master)
[](https://coveralls.io/github/c-ares/c-ares?branch=master)
[](https://bestpractices.coreinfrastructure.org/projects/291)
+[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:c-ares)
[](https://coderelease.io/github/repository/c-ares/c-ares)
This is c-ares, an asynchronous resolver library. It is intended for
diff --git a/deps/cares/src/README.msvc b/deps/cares/README.msvc
similarity index 66%
rename from deps/cares/src/README.msvc
rename to deps/cares/README.msvc
index 4ff8700cb8..396f497db4 100644
--- a/deps/cares/src/README.msvc
+++ b/deps/cares/README.msvc
@@ -1,6 +1,6 @@
- ___ __ _ _ __ ___ ___
+ ___ __ _ _ __ ___ ___
/ __| ___ / _` | '__/ _ \/ __|
| (_ |___| (_| | | | __/\__ \
\___| \__,_|_| \___||___/
@@ -64,46 +64,6 @@
to c-ares source folder where Makefile.msvc file is located.
- How to build using Visual Studio 6 IDE
- --------------------------------------
-
- A VC++ 6.0 reference workspace (vc6aws.dsw) is available within the 'vc'
- folder to allow proper building of the library and sample programs.
-
- 1) Open the vc6aws.dsw workspace with MSVC6's IDE.
- 2) Select 'Build' from top menu.
- 3) Select 'Batch Build' from dropdown menu.
- 4) Make sure that the sixteen project configurations are 'checked'.
- 5) Click on the 'Build' button.
- 6) Once the sixteen project configurations are built you are done.
-
- Dynamic and static c-ares libraries are built in debug and release flavours,
- and can be located each one in its own subdirectory, dll-debug, dll-release,
- lib-debug and lib-release, all of them below the 'vc\cares' subdirectory.
-
- In the same way four executable versions of each sample program are built,
- each using its respective library. The resulting sample executables are
- located in its own subdirectory, dll-debug, dll-release, lib-debug and
- lib-release, below the 'vc\acountry', 'vc\adig' and 'vc\ahost'folders.
-
- These reference VC++ 6.0 configurations are generated using the dynamic CRT.
-
-
- How to build using Visual Studio 2003 or newer IDE
- --------------------------------------------------
-
- First you have to convert the VC++ 6.0 reference workspace and project files
- to the Visual Studio IDE version you are using, following next steps:
-
- 1) Open vc\vc6aws.dsw with VS20XX.
- 2) Allow VS20XX to update all projects and workspaces.
- 3) Save ALL and close VS20XX.
- 4) Open vc\vc6aws.sln with VS20XX.
- 5) Select batch build, check 'all' projects and click 'build' button.
-
- Same comments relative to generated files and folders as done above for
- Visual Studio 6 IDE apply here.
-
Relationship between c-ares library file names and versions
-----------------------------------------------------------
@@ -139,4 +99,4 @@
Have Fun!
-
+
diff --git a/deps/cares/RELEASE-NOTES b/deps/cares/RELEASE-NOTES
new file mode 100644
index 0000000000..e1885425ae
--- /dev/null
+++ b/deps/cares/RELEASE-NOTES
@@ -0,0 +1,68 @@
+c-ares version 1.17.1
+
+Due to a packaging issue with 1.17.0, we have released 1.17.1 to address that
+issue. See 1.17.0 release notes below..
+
+
+c-ares version 1.17.0
+
+Security:
+ o avoid read-heap-buffer-overflow in ares_parse_soa_reply found during
+ fuzzing [2] [3]
+ o Avoid theoretical buffer overflow in RC4 loop comparison [5]
+ o Empty hquery->name could lead to invalid memory access [15]
+ o ares_parse_{a,aaaa}_reply() could return a larger *naddrttls than was
+ passed in [17]
+
+Changes:
+ o Update help information for adig, acountry, and ahost [4]
+ o Test Suite now uses dynamic system-assigned ports rather than hardcoded
+ ports to prevent failures in containers [10]
+ o Detect remote DNS server does not support EDNS using rules from RFC 6891 [12]
+ o Source tree has been reorganized to use a more modern layout [13]
+ o Allow parsing of CAA Resource Record [14]
+
+Bug fixes:
+ o readaddrinfo bad sizeof() [1]
+ o Test cases should honor HAVE_WRITEV flag, not depend on WIN32 [6]
+ o FQDN with trailing period should be queried first [7]
+ o ares_getaddrinfo() was returning members of the struct as garbage values if
+ unset, and was not honoring ai_socktype and ai_protocol hints. [8] [9]
+ o ares_gethostbyname() with AF_UNSPEC and an ip address would fail [11]
+ o Properly document ares_set_local_ip4() uses host byte order [16]
+
+Thanks go to these friendly people for their efforts and contributions:
+ @anonymoushelpishere
+ Anthony Penniston (@apenn-msft)
+ Brad House (@bradh352)
+ Bulat Gaifullin (@bgaifullin)
+ Daniela Sonnenschein (@lxdicted)
+ Daniel Stenberg (@bagder)
+ David Hotham (@dimbleby)
+ Fionn Fitzmaurice (@fionn)
+ Gisle Vanem (@gavenm)
+ Ivan Baidakou (@basiliscos)
+ Jonathan Maye-Hobbs (@wheelpharoah)
+ Łukasz Marszał (@lmarszal)
+ lutianxiong (@ltx2018)
+ Seraphime Kirkovski (@Seraphime)
+(14 contributors)
+
+References to bug reports and discussions on issues:
+ [1] = https://github.com/c-ares/c-ares/pull/331
+ [2] = https://github.com/c-ares/c-ares/pull/332
+ [3] = https://github.com/c-ares/c-ares/issues/333
+ [4] = https://github.com/c-ares/c-ares/pull/334
+ [5] = https://github.com/c-ares/c-ares/pull/336
+ [6] = https://github.com/c-ares/c-ares/pull/344
+ [7] = https://github.com/c-ares/c-ares/pull/345
+ [8] = https://github.com/c-ares/c-ares/issues/343
+ [9] = https://github.com/c-ares/c-ares/issues/317
+ [10] = https://github.com/c-ares/c-ares/pull/346
+ [11] = https://github.com/c-ares/c-ares/pull/204
+ [12] = https://github.com/c-ares/c-ares/pull/244
+ [13] = https://github.com/c-ares/c-ares/pull/349
+ [14] = https://github.com/c-ares/c-ares/pull/360
+ [15] = https://github.com/c-ares/c-ares/pull/367
+ [16] = https://github.com/c-ares/c-ares/pull/368
+ [17] = https://github.com/c-ares/c-ares/issues/371
diff --git a/deps/cares/src/TODO b/deps/cares/TODO
similarity index 100%
rename from deps/cares/src/TODO
rename to deps/cares/TODO
diff --git a/deps/cares/cares.gyp b/deps/cares/cares.gyp
index be7931f774..643f9a133f 100644
--- a/deps/cares/cares.gyp
+++ b/deps/cares/cares.gyp
@@ -30,80 +30,85 @@
{
'target_name': 'cares',
'type': '<(library)',
- 'include_dirs': [ 'include', 'src' ],
+ 'include_dirs': [ 'include', 'src/lib' ],
'direct_dependent_settings': {
- 'include_dirs': [ 'include' ]
+ 'include_dirs': [ 'include', 'src/lib' ]
},
'sources': [
'include/ares.h',
+ 'include/ares_dns.h',
'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',
- 'src/ares_data.c',
- 'src/ares_data.h',
- 'src/ares_destroy.c',
- 'src/ares_dns.h',
- 'src/ares_expand_name.c',
- 'src/ares_expand_string.c',
- 'src/ares_fds.c',
- 'src/ares_free_hostent.c',
- 'src/ares_free_string.c',
- 'src/ares_getenv.h',
- 'src/ares_gethostbyaddr.c',
- 'src/ares_gethostbyname.c',
- 'src/ares__get_hostent.c',
- 'src/ares_getnameinfo.c',
- 'src/ares_getopt.c',
- 'src/ares_getopt.h',
- 'src/ares_getsock.c',
- 'src/ares_init.c',
- 'src/ares_ipv6.h',
- 'src/ares_library_init.c',
- 'src/ares_library_init.h',
- 'src/ares_llist.c',
- 'src/ares_llist.h',
- 'src/ares_mkquery.c',
- 'src/ares_nowarn.c',
- 'src/ares_nowarn.h',
- 'src/ares_options.c',
- 'src/ares_parse_aaaa_reply.c',
- 'src/ares_parse_a_reply.c',
- 'src/ares_parse_mx_reply.c',
- 'src/ares_parse_naptr_reply.c',
- 'src/ares_parse_ns_reply.c',
- 'src/ares_parse_ptr_reply.c',
- 'src/ares_parse_soa_reply.c',
- 'src/ares_parse_srv_reply.c',
- 'src/ares_parse_txt_reply.c',
- 'src/ares_platform.h',
- 'src/ares_private.h',
- 'src/ares_process.c',
- 'src/ares_query.c',
- 'src/ares__read_line.c',
- 'src/ares_search.c',
- 'src/ares_send.c',
- 'src/ares_setup.h',
- 'src/ares_strcasecmp.c',
- 'src/ares_strcasecmp.h',
- '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',
- 'src/ares_writev.c',
- 'src/ares_writev.h',
- 'src/bitncmp.c',
- 'src/bitncmp.h',
- 'src/inet_net_pton.c',
- 'src/inet_ntop.c',
- 'src/ares_inet_net_pton.h',
- 'src/setup_once.h',
+ 'src/lib/ares_android.c',
+ 'src/lib/ares_cancel.c',
+ 'src/lib/ares__close_sockets.c',
+ 'src/lib/ares_create_query.c',
+ 'src/lib/ares_data.c',
+ 'src/lib/ares_data.h',
+ 'src/lib/ares_destroy.c',
+ 'src/lib/ares_expand_name.c',
+ 'src/lib/ares_expand_string.c',
+ 'src/lib/ares_fds.c',
+ 'src/lib/ares_free_hostent.c',
+ 'src/lib/ares_free_string.c',
+ 'src/lib/ares_freeaddrinfo.c',
+ 'src/lib/ares_getenv.h',
+ 'src/lib/ares_getaddrinfo.c',
+ 'src/lib/ares_gethostbyaddr.c',
+ 'src/lib/ares_gethostbyname.c',
+ 'src/lib/ares__get_hostent.c',
+ 'src/lib/ares_getnameinfo.c',
+ 'src/lib/ares_getsock.c',
+ 'src/lib/ares_init.c',
+ 'src/lib/ares_ipv6.h',
+ 'src/lib/ares_library_init.c',
+ 'src/lib/ares_library_init.h',
+ 'src/lib/ares_llist.c',
+ 'src/lib/ares_llist.h',
+ 'src/lib/ares_mkquery.c',
+ 'src/lib/ares_nowarn.c',
+ 'src/lib/ares_nowarn.h',
+ 'src/lib/ares_options.c',
+ 'src/lib/ares__parse_into_addrinfo.c',
+ 'src/lib/ares_parse_aaaa_reply.c',
+ 'src/lib/ares_parse_a_reply.c',
+ 'src/lib/ares_parse_mx_reply.c',
+ 'src/lib/ares_parse_naptr_reply.c',
+ 'src/lib/ares_parse_ns_reply.c',
+ 'src/lib/ares_parse_ptr_reply.c',
+ 'src/lib/ares_parse_soa_reply.c',
+ 'src/lib/ares_parse_srv_reply.c',
+ 'src/lib/ares_parse_txt_reply.c',
+ 'src/lib/ares_platform.h',
+ 'src/lib/ares_private.h',
+ 'src/lib/ares_process.c',
+ 'src/lib/ares_query.c',
+ 'src/lib/ares__read_line.c',
+ 'src/lib/ares__readaddrinfo.c',
+ 'src/lib/ares_search.c',
+ 'src/lib/ares_send.c',
+ 'src/lib/ares_setup.h',
+ 'src/lib/ares__sortaddrinfo.c',
+ 'src/lib/ares_strcasecmp.c',
+ 'src/lib/ares_strcasecmp.h',
+ 'src/lib/ares_strdup.c',
+ 'src/lib/ares_strdup.h',
+ 'src/lib/ares_strerror.c',
+ 'src/lib/ares_strsplit.c',
+ 'src/lib/ares_timeout.c',
+ 'src/lib/ares__timeval.c',
+ 'src/lib/ares_version.c',
+ 'src/lib/ares_writev.c',
+ 'src/lib/ares_writev.h',
+ 'src/lib/bitncmp.c',
+ 'src/lib/bitncmp.h',
+ 'src/lib/inet_net_pton.c',
+ 'src/lib/inet_ntop.c',
+ 'src/lib/ares_inet_net_pton.h',
+ 'src/lib/nameser.h',
+ 'src/lib/setup_once.h',
+ 'src/tools/ares_getopt.c',
+ 'src/tools/ares_getopt.h',
],
'conditions': [
[ 'library=="static_library"', {
@@ -112,14 +117,17 @@
'defines': [ 'CARES_BUILDING_LIBRARY' ]
}],
[ 'OS=="win"', {
- 'defines': [ 'CARES_PULL_WS2TCPIP_H=1' ],
+ 'defines': [
+ 'CARES_PULL_WS2TCPIP_H=1',
+ '_WINSOCK_DEPRECATED_NO_WARNINGS',
+ ],
'include_dirs': [ 'config/win32' ],
'sources': [
- 'src/config-win32.h',
- 'src/windows_port.c',
- 'src/ares_getenv.c',
- 'src/ares_iphlpapi.h',
- 'src/ares_platform.c'
+ 'src/lib/config-win32.h',
+ 'src/lib/windows_port.c',
+ 'src/lib/ares_getenv.c',
+ 'src/lib/ares_iphlpapi.h',
+ 'src/lib/ares_platform.c'
],
'libraries': [
'-lws2_32.lib',
diff --git a/deps/cares/include/ares.h b/deps/cares/include/ares.h
index 06f60b3330..2c0925f84a 100644
--- a/deps/cares/include/ares.h
+++ b/deps/cares/include/ares.h
@@ -39,7 +39,7 @@
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
- defined(__QNXNTO__)
+ defined(__QNXNTO__) || defined(__MVS__)
#include <sys/select.h>
#endif
#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
@@ -135,6 +135,9 @@ extern "C" {
/* More error codes */
#define ARES_ECANCELLED 24 /* introduced in 1.7.0 */
+/* More ares_getaddrinfo error codes */
+#define ARES_ESERVICE 25 /* introduced in 1.?.0 */
+
/* Flag values */
#define ARES_FLAG_USEVC (1 << 0)
#define ARES_FLAG_PRIMARY (1 << 1)
@@ -192,6 +195,8 @@ extern "C" {
#define ARES_AI_V4MAPPED (1 << 4)
#define ARES_AI_ALL (1 << 5)
#define ARES_AI_ADDRCONFIG (1 << 6)
+#define ARES_AI_NOSORT (1 << 7)
+#define ARES_AI_ENVHOSTS (1 << 8)
/* Reserved for future use */
#define ARES_AI_IDN (1 << 10)
#define ARES_AI_IDN_ALLOW_UNASSIGNED (1 << 11)
@@ -278,6 +283,8 @@ struct hostent;
struct timeval;
struct sockaddr;
struct ares_channeldata;
+struct ares_addrinfo;
+struct ares_addrinfo_hints;
typedef struct ares_channeldata *ares_channel;
@@ -306,6 +313,11 @@ typedef int (*ares_sock_config_callback)(ares_socket_t socket_fd,
int type,
void *data);
+typedef void (*ares_addrinfo_callback)(void *arg,
+ int status,
+ int timeouts,
+ struct ares_addrinfo *res);
+
CARES_EXTERN int ares_library_init(int flags);
CARES_EXTERN int ares_library_init_mem(int flags,
@@ -369,6 +381,15 @@ CARES_EXTERN void ares_set_socket_configure_callback(ares_channel channel,
CARES_EXTERN int ares_set_sortlist(ares_channel channel,
const char *sortstr);
+CARES_EXTERN void ares_getaddrinfo(ares_channel channel,
+ const char* node,
+ const char* service,
+ const struct ares_addrinfo_hints* hints,
+ ares_addrinfo_callback callback,
+ void* arg);
+
+CARES_EXTERN void ares_freeaddrinfo(struct ares_addrinfo* ai);
+
/*
* Virtual function set to have user-managed socket IO.
* Note that all functions need to be defined, and when
@@ -558,6 +579,44 @@ struct ares_soa_reply {
unsigned int minttl;
};
+/*
+ * Similar to addrinfo, but with extra ttl and missing canonname.
+ */
+struct ares_addrinfo_node {
+ int ai_ttl;
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ ares_socklen_t ai_addrlen;
+ struct sockaddr *ai_addr;
+ struct ares_addrinfo_node *ai_next;
+};
+
+/*
+ * alias - label of the resource record.
+ * name - value (canonical name) of the resource record.
+ * See RFC2181 10.1.1. CNAME terminology.
+ */
+struct ares_addrinfo_cname {
+ int ttl;
+ char *alias;
+ char *name;
+ struct ares_addrinfo_cname *next;
+};
+
+struct ares_addrinfo {
+ struct ares_addrinfo_cname *cnames;
+ struct ares_addrinfo_node *nodes;
+};
+
+struct ares_addrinfo_hints {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+};
+
/*
** Parse the buffer, starting at *abuf and of length alen bytes, previously
** obtained from an ares_search call. Put the results in *host, if nonnull.
diff --git a/deps/cares/src/ares_dns.h b/deps/cares/include/ares_dns.h
similarity index 95%
rename from deps/cares/src/ares_dns.h
rename to deps/cares/include/ares_dns.h
index 79f993b904..bc8aa7b109 100644
--- a/deps/cares/src/ares_dns.h
+++ b/deps/cares/include/ares_dns.h
@@ -16,6 +16,15 @@
* without express or implied warranty.
*/
+/*
+ * NOTE TO INTEGRATORS:
+ *
+ * This header is made public due to legacy projects relying on it.
+ * Please do not use the macros within this header, or include this
+ * header in your project as it may be removed in the future.
+ */
+
+
/*
* Macro DNS__16BIT reads a network short (16 bit) given in network
* byte order, and returns its value as an unsigned short.
diff --git a/deps/cares/include/ares_version.h b/deps/cares/include/ares_version.h
index 3fe5b00a11..4b16a62cc6 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 - 2018 Daniel Stenberg, <daniel@haxx.se>."
+#define ARES_COPYRIGHT "2004 - 2020 Daniel Stenberg, <daniel@haxx.se>."
#define ARES_VERSION_MAJOR 1
-#define ARES_VERSION_MINOR 15
+#define ARES_VERSION_MINOR 17
#define ARES_VERSION_PATCH 0
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
(ARES_VERSION_MINOR<<8)|\
(ARES_VERSION_PATCH))
-#define ARES_VERSION_STR "1.15.0"
+#define ARES_VERSION_STR "1.17.0"
#if (ARES_VERSION >= 0x010700)
# define CARES_HAVE_ARES_LIBRARY_INIT 1
diff --git a/deps/cares/src/RELEASE-NOTES b/deps/cares/src/RELEASE-NOTES
deleted file mode 100644
index 62276fdf4e..0000000000
--- a/deps/cares/src/RELEASE-NOTES
+++ /dev/null
@@ -1,43 +0,0 @@
-c-ares version 1.15.0
-
-Changes:
- 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 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:
- @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
-
diff --git a/deps/cares/src/ares_parse_a_reply.c b/deps/cares/src/ares_parse_a_reply.c
deleted file mode 100644
index 0422bd3828..0000000000
--- a/deps/cares/src/ares_parse_a_reply.c
+++ /dev/null
@@ -1,264 +0,0 @@
-
-/* Copyright 1998 by the Massachusetts Institute of Technology.
- *
- * 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"
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-
-#include "ares.h"
-#include "ares_dns.h"
-#include "ares_private.h"
-
-int ares_parse_a_reply(const unsigned char *abuf, int alen,
- struct hostent **host,
- struct ares_addrttl *addrttls, int *naddrttls)
-{
- unsigned int qdcount, ancount;
- int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs;
- int cname_ttl = INT_MAX; /* the TTL imposed by the CNAME chain */
- int naliases;
- long len;
- const unsigned char *aptr;
- char *hostname, *rr_name, *rr_data, **aliases;
- struct in_addr *addrs;
- struct hostent *hostent;
- const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0;
-
- /* Set *host to NULL for all failure cases. */
- if (host)
- *host = NULL;
- /* Same with *naddrttls. */
- if (naddrttls)
- *naddrttls = 0;
-
- /* Give up if abuf doesn't have room for a header. */
- if (alen < HFIXEDSZ)
- return ARES_EBADRESP;
-
- /* Fetch the question and answer count from the header. */
- qdcount = DNS_HEADER_QDCOUNT(abuf);
- ancount = DNS_HEADER_ANCOUNT(abuf);
- if (qdcount != 1)
- return ARES_EBADRESP;
-
- /* Expand the name from the question, and skip past the question. */
- aptr = abuf + HFIXEDSZ;
- status = ares__expand_name_for_response(aptr, abuf, alen, &hostname, &len);
- if (status != ARES_SUCCESS)
- return status;
- if (aptr + len + QFIXEDSZ > abuf + alen)
- {
- ares_free(hostname);
- return ARES_EBADRESP;
- }
- aptr += len + QFIXEDSZ;
-
- if (host)
- {
- /* Allocate addresses and aliases; ancount gives an upper bound for
- both. */
- addrs = ares_malloc(ancount * sizeof(struct in_addr));
- if (!addrs)
- {
- ares_free(hostname);
- return ARES_ENOMEM;
- }
- aliases = ares_malloc((ancount + 1) * sizeof(char *));
- if (!aliases)
- {
- ares_free(hostname);
- ares_free(addrs);
- return ARES_ENOMEM;
- }
- }
- else
- {
- addrs = NULL;
- aliases = NULL;
- }
-
- naddrs = 0;
- naliases = 0;
-
- /* Examine each answer resource record (RR) in turn. */
- for (i = 0; i < (int)ancount; i++)
- {
- /* Decode the RR up to the data field. */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
- if (status != ARES_SUCCESS)
- break;
- aptr += len;
- if (aptr + RRFIXEDSZ > abuf + alen)
- {
- ares_free(rr_name);
- status = ARES_EBADRESP;
- break;
- }
- rr_type = DNS_RR_TYPE(aptr);
- rr_class = DNS_RR_CLASS(aptr);
- rr_len = DNS_RR_LEN(aptr);
- rr_ttl = DNS_RR_TTL(aptr);
- aptr += RRFIXEDSZ;
- if (aptr + rr_len > abuf + alen)
- {
- ares_free(rr_name);
- status = ARES_EBADRESP;
- break;
- }
-
- if (rr_class == C_IN && rr_type == T_A
- && rr_len == sizeof(struct in_addr)
- && strcasecmp(rr_name, hostname) == 0)
- {
- if (addrs)
- {
- if (aptr + sizeof(struct in_addr) > abuf + alen)
- { /* LCOV_EXCL_START: already checked above */
- ares_free(rr_name);
- status = ARES_EBADRESP;
- break;
- } /* LCOV_EXCL_STOP */
- memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr));
- }
- if (naddrs < max_addr_ttls)
- {
- struct ares_addrttl * const at = &addrttls[naddrs];
- if (aptr + sizeof(struct in_addr) > abuf + alen)
- { /* LCOV_EXCL_START: already checked above */
- ares_free(rr_name);
- status = ARES_EBADRESP;
- break;
- } /* LCOV_EXCL_STOP */
- memcpy(&at->ipaddr, aptr, sizeof(struct in_addr));
- at->ttl = rr_ttl;
- }
- naddrs++;
- status = ARES_SUCCESS;
- }
-
- if (rr_class == C_IN && rr_type == T_CNAME)
- {
- /* Record the RR name as an alias. */
- if (aliases)
- aliases[naliases] = rr_name;
- else
- ares_free(rr_name);
- naliases++;
-
- /* Decode the RR data and replace the hostname with it. */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
- &len);
- if (status != ARES_SUCCESS)
- break;
- ares_free(hostname);
- hostname = rr_data;
-
- /* Take the min of the TTLs we see in the CNAME chain. */
- if (cname_ttl > rr_ttl)
- cname_ttl = rr_ttl;
- }
- else
- ares_free(rr_name);
-
- aptr += rr_len;
- if (aptr > abuf + alen)
- { /* LCOV_EXCL_START: already checked above */
- status = ARES_EBADRESP;
- break;
- } /* LCOV_EXCL_STOP */
- }
-
- if (status == ARES_SUCCESS && naddrs == 0 && naliases == 0)
- /* the check for naliases to be zero is to make sure CNAME responses
- don't get caught here */
- status = ARES_ENODATA;
- if (status == ARES_SUCCESS)
- {
- /* We got our answer. */
- if (naddrttls)
- {
- const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls;
- for (i = 0; i < n; i++)
- {
- /* Ensure that each A TTL is no larger than the CNAME TTL. */
- if (addrttls[i].ttl > cname_ttl)
- addrttls[i].ttl = cname_ttl;
- }
- *naddrttls = n;
- }
- if (aliases)
- aliases[naliases] = NULL;
- if (host)
- {
- /* Allocate memory to build the host entry. */
- hostent = ares_malloc(sizeof(struct hostent));
- if (hostent)
- {
- hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *));
- if (hostent->h_addr_list)
- {
- /* Fill in the hostent and return successfully. */
- hostent->h_name = hostname;
- hostent->h_aliases = aliases;
- hostent->h_addrtype = AF_INET;
- hostent->h_length = sizeof(struct in_addr);
- for (i = 0; i < naddrs; i++)
- hostent->h_addr_list[i] = (char *) &addrs[i];
- hostent->h_addr_list[naddrs] = NULL;
- if (!naddrs && addrs)
- ares_free(addrs);
- *host = hostent;
- return ARES_SUCCESS;
- }
- ares_free(hostent);
- }
- status = ARES_ENOMEM;
- }
- }
- if (aliases)
- {
- for (i = 0; i < naliases; i++)
- ares_free(aliases[i]);
- ares_free(aliases);
- }
- ares_free(addrs);
- ares_free(hostname);
- return status;
-}
diff --git a/deps/cares/src/ares_parse_aaaa_reply.c b/deps/cares/src/ares_parse_aaaa_reply.c
deleted file mode 100644
index 5b38bb571e..0000000000
--- a/deps/cares/src/ares_parse_aaaa_reply.c
+++ /dev/null
@@ -1,264 +0,0 @@
-
-/* Copyright 1998 by the Massachusetts Institute of Technology.
- * Copyright 2005 Dominick Meglio
- *
- * 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"
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-
-#include "ares.h"
-#include "ares_dns.h"
-#include "ares_inet_net_pton.h"
-#include "ares_private.h"
-
-int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
- struct hostent **host, struct ares_addr6ttl *addrttls,
- int *naddrttls)
-{
- unsigned int qdcount, ancount;
- int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs;
- int cname_ttl = INT_MAX; /* the TTL imposed by the CNAME chain */
- int naliases;
- long len;
- const unsigned char *aptr;
- char *hostname, *rr_name, *rr_data, **aliases;
- struct ares_in6_addr *addrs;
- struct hostent *hostent;
- const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0;
-
- /* Set *host to NULL for all failure cases. */
- if (host)
- *host = NULL;
- /* Same with *naddrttls. */
- if (naddrttls)
- *naddrttls = 0;
-
- /* Give up if abuf doesn't have room for a header. */
- if (alen < HFIXEDSZ)
- return ARES_EBADRESP;
-
- /* Fetch the question and answer count from the header. */
- qdcount = DNS_HEADER_QDCOUNT(abuf);
- ancount = DNS_HEADER_ANCOUNT(abuf);
- if (qdcount != 1)
- return ARES_EBADRESP;
-
- /* Expand the name from the question, and skip past the question. */
- aptr = abuf + HFIXEDSZ;
- status = ares__expand_name_for_response(aptr, abuf, alen, &hostname, &len);
- if (status != ARES_SUCCESS)
- return status;
- if (aptr + len + QFIXEDSZ > abuf + alen)
- {
- ares_free(hostname);
- return ARES_EBADRESP;
- }
- aptr += len + QFIXEDSZ;
-
- /* Allocate addresses and aliases; ancount gives an upper bound for both. */
- if (host)
- {
- addrs = ares_malloc(ancount * sizeof(struct ares_in6_addr));
- if (!addrs)
- {
- ares_free(hostname);
- return ARES_ENOMEM;
- }
- aliases = ares_malloc((ancount + 1) * sizeof(char *));
- if (!aliases)
- {
- ares_free(hostname);
- ares_free(addrs);
- return ARES_ENOMEM;
- }
- }
- else
- {
- addrs = NULL;
- aliases = NULL;
- }
- naddrs = 0;
- naliases = 0;
-
- /* Examine each answer resource record (RR) in turn. */
- for (i = 0; i < (int)ancount; i++)
- {
- /* Decode the RR up to the data field. */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
- if (status != ARES_SUCCESS)
- break;
- aptr += len;
- if (aptr + RRFIXEDSZ > abuf + alen)
- {
- ares_free(rr_name);
- status = ARES_EBADRESP;
- break;
- }
- rr_type = DNS_RR_TYPE(aptr);
- rr_class = DNS_RR_CLASS(aptr);
- rr_len = DNS_RR_LEN(aptr);
- rr_ttl = DNS_RR_TTL(aptr);
- aptr += RRFIXEDSZ;
- if (aptr + rr_len > abuf + alen)
- {
- ares_free(rr_name);
- status = ARES_EBADRESP;
- break;
- }
-
- if (rr_class == C_IN && rr_type == T_AAAA
- && rr_len == sizeof(struct ares_in6_addr)
- && strcasecmp(rr_name, hostname) == 0)
- {
- if (addrs)
- {
- if (aptr + sizeof(struct ares_in6_addr) > abuf + alen)
- { /* LCOV_EXCL_START: already checked above */
- ares_free(rr_name);
- status = ARES_EBADRESP;
- break;
- } /* LCOV_EXCL_STOP */
- memcpy(&addrs[naddrs], aptr, sizeof(struct ares_in6_addr));
- }
- if (naddrs < max_addr_ttls)
- {
- struct ares_addr6ttl * const at = &addrttls[naddrs];
- if (aptr + sizeof(struct ares_in6_addr) > abuf + alen)
- { /* LCOV_EXCL_START: already checked above */
- ares_free(rr_name);
- status = ARES_EBADRESP;
- break;
- } /* LCOV_EXCL_STOP */
- memcpy(&at->ip6addr, aptr, sizeof(struct ares_in6_addr));
- at->ttl = rr_ttl;
- }
- naddrs++;
- status = ARES_SUCCESS;
- }
-
- if (rr_class == C_IN && rr_type == T_CNAME)
- {
- /* Record the RR name as an alias. */
- if (aliases)
- aliases[naliases] = rr_name;
- else
- ares_free(rr_name);
- naliases++;
-
- /* Decode the RR data and replace the hostname with it. */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
- &len);
- if (status != ARES_SUCCESS)
- break;
- ares_free(hostname);
- hostname = rr_data;
-
- /* Take the min of the TTLs we see in the CNAME chain. */
- if (cname_ttl > rr_ttl)
- cname_ttl = rr_ttl;
- }
- else
- ares_free(rr_name);
-
- aptr += rr_len;
- if (aptr > abuf + alen)
- { /* LCOV_EXCL_START: already checked above */
- status = ARES_EBADRESP;
- break;
- } /* LCOV_EXCL_STOP */
- }
-
- /* the check for naliases to be zero is to make sure CNAME responses
- don't get caught here */
- if (status == ARES_SUCCESS && naddrs == 0 && naliases == 0)
- status = ARES_ENODATA;
- if (status == ARES_SUCCESS)
- {
- /* We got our answer. */
- if (naddrttls)
- {
- const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls;
- for (i = 0; i < n; i++)
- {
- /* Ensure that each A TTL is no larger than the CNAME TTL. */
- if (addrttls[i].ttl > cname_ttl)
- addrttls[i].ttl = cname_ttl;
- }
- *naddrttls = n;
- }
- if (aliases)
- aliases[naliases] = NULL;
- if (host)
- {
- /* Allocate memory to build the host entry. */
- hostent = ares_malloc(sizeof(struct hostent));
- if (hostent)
- {
- hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *));
- if (hostent->h_addr_list)
- {
- /* Fill in the hostent and return successfully. */
- hostent->h_name = hostname;
- hostent->h_aliases = aliases;
- hostent->h_addrtype = AF_INET6;
- hostent->h_length = sizeof(struct ares_in6_addr);
- for (i = 0; i < naddrs; i++)
- hostent->h_addr_list[i] = (char *) &addrs[i];
- hostent->h_addr_list[naddrs] = NULL;
- if (!naddrs && addrs)
- ares_free(addrs);
- *host = hostent;
- return ARES_SUCCESS;
- }
- ares_free(hostent);
- }
- status = ARES_ENOMEM;
- }
- }
- if (aliases)
- {
- for (i = 0; i < naliases; i++)
- ares_free(aliases[i]);
- ares_free(aliases);
- }
- ares_free(addrs);
- ares_free(hostname);
- return status;
-}
diff --git a/deps/cares/src/ares_parse_soa_reply.c b/deps/cares/src/ares_parse_soa_reply.c
deleted file mode 100644
index 35af0a75c0..0000000000
--- a/deps/cares/src/ares_parse_soa_reply.c
+++ /dev/null
@@ -1,133 +0,0 @@
-
-/* Copyright 1998 by the Massachusetts Institute of Technology.
- * Copyright (C) 2012 Marko Kreen <markokr@gmail.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"
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-
-#include "ares.h"
-#include "ares_dns.h"
-#include "ares_data.h"
-#include "ares_private.h"
-
-int
-ares_parse_soa_reply(const unsigned char *abuf, int alen,
- struct ares_soa_reply **soa_out)
-{
- const unsigned char *aptr;
- long len;
- char *qname = NULL, *rr_name = NULL;
- struct ares_soa_reply *soa = NULL;
- int qdcount, ancount;
- int status;
-
- if (alen < HFIXEDSZ)
- return ARES_EBADRESP;
-
- /* parse message header */
- qdcount = DNS_HEADER_QDCOUNT(abuf);
- ancount = DNS_HEADER_ANCOUNT(abuf);
- if (qdcount != 1 || ancount != 1)
- return ARES_EBADRESP;
- aptr = abuf + HFIXEDSZ;
-
- /* query name */
- status = ares__expand_name_for_response(aptr, abuf, alen, &qname, &len);
- if (status != ARES_SUCCESS)
- goto failed_stat;
- aptr += len;
-
- /* skip qtype & qclass */
- if (aptr + QFIXEDSZ > abuf + alen)
- goto failed;
- aptr += QFIXEDSZ;
-
- /* rr_name */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
- if (status != ARES_SUCCESS)
- goto failed_stat;
- aptr += len;
-
- /* skip rr_type, rr_class, rr_ttl, rr_rdlen */
- if (aptr + RRFIXEDSZ > abuf + alen)
- goto failed;
- aptr += RRFIXEDSZ;
-
- /* allocate result struct */
- soa = ares_malloc_data(ARES_DATATYPE_SOA_REPLY);
- if (!soa)
- {
- status = ARES_ENOMEM;
- goto failed_stat;
- }
-
- /* nsname */
- status = ares__expand_name_for_response(aptr, abuf, alen, &soa->nsname, &len);
- if (status != ARES_SUCCESS)
- goto failed_stat;
- aptr += len;
-
- /* hostmaster */
- status = ares__expand_name_for_response(aptr, abuf, alen, &soa->hostmaster, &len);
- if (status != ARES_SUCCESS)
- goto failed_stat;
- aptr += len;
-
- /* integer fields */
- if (aptr + 5 * 4 > abuf + alen)
- goto failed;
- soa->serial = DNS__32BIT(aptr + 0 * 4);
- soa->refresh = DNS__32BIT(aptr + 1 * 4);
- soa->retry = DNS__32BIT(aptr + 2 * 4);
- soa->expire = DNS__32BIT(aptr + 3 * 4);
- soa->minttl = DNS__32BIT(aptr + 4 * 4);
-
- ares_free(qname);
- ares_free(rr_name);
-
- *soa_out = soa;
-
- return ARES_SUCCESS;
-
-failed:
- status = ARES_EBADRESP;
-
-failed_stat:
- ares_free_data(soa);
- if (qname)
- ares_free(qname);
- if (rr_name)
- ares_free(rr_name);
- return status;
-}
-
diff --git a/deps/cares/src/ares__close_sockets.c b/deps/cares/src/lib/ares__close_sockets.c
similarity index 94%
rename from deps/cares/src/ares__close_sockets.c
rename to deps/cares/src/lib/ares__close_sockets.c
index f07904e873..0477174e3e 100644
--- a/deps/cares/src/ares__close_sockets.c
+++ b/deps/cares/src/lib/ares__close_sockets.c
@@ -48,14 +48,14 @@ void ares__close_sockets(ares_channel channel, struct server_state *server)
if (server->tcp_socket != ARES_SOCKET_BAD)
{
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 0, 0);
- ares__socket_close(channel, server->tcp_socket);
+ ares__close_socket(channel, server->tcp_socket);
server->tcp_socket = ARES_SOCKET_BAD;
server->tcp_connection_generation = ++channel->tcp_connection_generation;
}
if (server->udp_socket != ARES_SOCKET_BAD)
{
SOCK_STATE_CALLBACK(channel, server->udp_socket, 0, 0);
- ares__socket_close(channel, server->udp_socket);
+ ares__close_socket(channel, server->udp_socket);
server->udp_socket = ARES_SOCKET_BAD;
}
}
diff --git a/deps/cares/src/ares__get_hostent.c b/deps/cares/src/lib/ares__get_hostent.c
similarity index 98%
rename from deps/cares/src/ares__get_hostent.c
rename to deps/cares/src/lib/ares__get_hostent.c
index d2f9503493..367f39037b 100644
--- a/deps/cares/src/ares__get_hostent.c
+++ b/deps/cares/src/lib/ares__get_hostent.c
@@ -138,8 +138,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
addr.addrV4.s_addr = INADDR_NONE;
if ((family == AF_INET) || (family == AF_UNSPEC))
{
- addr.addrV4.s_addr = inet_addr(txtaddr);
- if (addr.addrV4.s_addr != INADDR_NONE)
+ if (ares_inet_pton(AF_INET, txtaddr, &addr.addrV4) > 0)
{
/* Actual network address family and length. */
addr.family = AF_INET;
diff --git a/deps/cares/src/lib/ares__parse_into_addrinfo.c b/deps/cares/src/lib/ares__parse_into_addrinfo.c
new file mode 100644
index 0000000000..7550abab4a
--- /dev/null
+++ b/deps/cares/src/lib/ares__parse_into_addrinfo.c
@@ -0,0 +1,260 @@
+/* Copyright (C) 2019 by Andrew Selivanov
+ *
+ * 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"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#include "ares_nameser.h"
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_private.h"
+
+int ares__parse_into_addrinfo2(const unsigned char *abuf,
+ int alen,
+ char **question_hostname,
+ struct ares_addrinfo *ai)
+{
+ unsigned int qdcount, ancount;
+ int status, i, rr_type, rr_class, rr_len, rr_ttl;
+ int got_a = 0, got_aaaa = 0, got_cname = 0;
+ long len;
+ const unsigned char *aptr;
+ char *hostname, *rr_name = NULL, *rr_data;
+ struct ares_addrinfo_cname *cname, *cnames = NULL;
+ struct ares_addrinfo_node *node, *nodes = NULL;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ *question_hostname = NULL;
+
+ /* Give up if abuf doesn't have room for a header. */
+ if (alen < HFIXEDSZ)
+ return ARES_EBADRESP;
+
+ /* Fetch the question and answer count from the header. */
+ qdcount = DNS_HEADER_QDCOUNT(abuf);
+ ancount = DNS_HEADER_ANCOUNT(abuf);
+ if (qdcount != 1)
+ return ARES_EBADRESP;
+
+
+ /* Expand the name from the question, and skip past the question. */
+ aptr = abuf + HFIXEDSZ;
+ status = ares__expand_name_for_response(aptr, abuf, alen, question_hostname, &len, 0);
+ if (status != ARES_SUCCESS)
+ return status;
+ if (aptr + len + QFIXEDSZ > abuf + alen)
+ {
+ return ARES_EBADRESP;
+ }
+
+ hostname = *question_hostname;
+
+ aptr += len + QFIXEDSZ;
+
+ /* Examine each answer resource record (RR) in turn. */
+ for (i = 0; i < (int)ancount; i++)
+ {
+ /* Decode the RR up to the data field. */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len, 0);
+ if (status != ARES_SUCCESS)
+ {
+ rr_name = NULL;
+ goto failed_stat;
+ }
+
+ aptr += len;
+ if (aptr + RRFIXEDSZ > abuf + alen)
+ {
+ status = ARES_EBADRESP;
+ goto failed_stat;
+ }
+ rr_type = DNS_RR_TYPE(aptr);
+ rr_class = DNS_RR_CLASS(aptr);
+ rr_len = DNS_RR_LEN(aptr);
+ rr_ttl = DNS_RR_TTL(aptr);
+ aptr += RRFIXEDSZ;
+ if (aptr + rr_len > abuf + alen)
+ {
+ status = ARES_EBADRESP;
+ goto failed_stat;
+ }
+
+ if (rr_class == C_IN && rr_type == T_A
+ && rr_len == sizeof(struct in_addr)
+ && strcasecmp(rr_name, hostname) == 0)
+ {
+ got_a = 1;
+ if (aptr + sizeof(struct in_addr) > abuf + alen)
+ { /* LCOV_EXCL_START: already checked above */
+ status = ARES_EBADRESP;
+ goto failed_stat;
+ } /* LCOV_EXCL_STOP */
+
+ node = ares__append_addrinfo_node(&nodes);
+ if (!node)
+ {
+ status = ARES_ENOMEM;
+ goto failed_stat;
+ }
+
+ sin = ares_malloc(sizeof(struct sockaddr_in));
+ if (!sin)
+ {
+ status = ARES_ENOMEM;
+ goto failed_stat;
+ }
+ memset(sin, 0, sizeof(struct sockaddr_in));
+ memcpy(&sin->sin_addr.s_addr, aptr, sizeof(struct in_addr));
+ sin->sin_family = AF_INET;
+
+ node->ai_addr = (struct sockaddr *)sin;
+ node->ai_family = AF_INET;
+ node->ai_addrlen = sizeof(struct sockaddr_in);
+
+ node->ai_ttl = rr_ttl;
+
+ status = ARES_SUCCESS;
+ }
+ else if (rr_class == C_IN && rr_type == T_AAAA
+ && rr_len == sizeof(struct ares_in6_addr)
+ && strcasecmp(rr_name, hostname) == 0)
+ {
+ got_aaaa = 1;
+ if (aptr + sizeof(struct ares_in6_addr) > abuf + alen)
+ { /* LCOV_EXCL_START: already checked above */
+ status = ARES_EBADRESP;
+ goto failed_stat;
+ } /* LCOV_EXCL_STOP */
+
+ node = ares__append_addrinfo_node(&nodes);
+ if (!node)
+ {
+ status = ARES_ENOMEM;
+ goto failed_stat;
+ }
+
+ sin6 = ares_malloc(sizeof(struct sockaddr_in6));
+ if (!sin6)
+ {
+ status = ARES_ENOMEM;
+ goto failed_stat;
+ }
+
+ memset(sin6, 0, sizeof(struct sockaddr_in6));
+ memcpy(&sin6->sin6_addr.s6_addr, aptr, sizeof(struct ares_in6_addr));
+ sin6->sin6_family = AF_INET6;
+
+ node->ai_addr = (struct sockaddr *)sin6;
+ node->ai_family = AF_INET6;
+ node->ai_addrlen = sizeof(struct sockaddr_in6);
+
+ node->ai_ttl = rr_ttl;
+
+ status = ARES_SUCCESS;
+ }
+
+ if (rr_class == C_IN && rr_type == T_CNAME)
+ {
+ got_cname = 1;
+ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
+ &len, 1);
+ if (status != ARES_SUCCESS)
+ {
+ goto failed_stat;
+ }
+
+ /* Decode the RR data and replace the hostname with it. */
+ /* SA: Seems wrong as it introduses order dependency. */
+ hostname = rr_data;
+
+ cname = ares__append_addrinfo_cname(&cnames);
+ if (!cname)
+ {
+ status = ARES_ENOMEM;
+ ares_free(rr_data);
+ goto failed_stat;
+ }
+ cname->ttl = rr_ttl;
+ cname->alias = rr_name;
+ cname->name = rr_data;
+ }
+ else
+ {
+ ares_free(rr_name);
+ }
+
+
+ aptr += rr_len;
+ if (aptr > abuf + alen)
+ { /* LCOV_EXCL_START: already checked above */
+ status = ARES_EBADRESP;
+ goto failed_stat;
+ } /* LCOV_EXCL_STOP */
+ }
+
+ if (status == ARES_SUCCESS)
+ {
+ ares__addrinfo_cat_nodes(&ai->nodes, nodes);
+ if (got_cname)
+ {
+ ares__addrinfo_cat_cnames(&ai->cnames, cnames);
+ return status;
+ }
+ else if (got_a == 0 && got_aaaa == 0)
+ {
+ /* the check for naliases to be zero is to make sure CNAME responses
+ don't get caught here */
+ status = ARES_ENODATA;
+ }
+ }
+
+ return status;
+
+failed_stat:
+ ares_free(rr_name);
+ ares__freeaddrinfo_cnames(cnames);
+ ares__freeaddrinfo_nodes(nodes);
+ return status;
+}
+
+int ares__parse_into_addrinfo(const unsigned char *abuf,
+ int alen,
+ struct ares_addrinfo *ai)
+{
+ int status;
+ char *question_hostname;
+ status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, ai);
+ ares_free(question_hostname);
+ return status;
+}
diff --git a/deps/cares/src/ares__read_line.c b/deps/cares/src/lib/ares__read_line.c
similarity index 100%
rename from deps/cares/src/ares__read_line.c
rename to deps/cares/src/lib/ares__read_line.c
diff --git a/deps/cares/src/lib/ares__readaddrinfo.c b/deps/cares/src/lib/ares__readaddrinfo.c
new file mode 100644
index 0000000000..2b5bb40c3d
--- /dev/null
+++ b/deps/cares/src/lib/ares__readaddrinfo.c
@@ -0,0 +1,264 @@
+/* Copyright (C) 2019 by Andrew Selivanov
+ *
+ * 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"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#include "ares.h"
+#include "ares_inet_net_pton.h"
+#include "ares_nowarn.h"
+#include "ares_private.h"
+
+#define MAX_ALIASES 40
+
+int ares__readaddrinfo(FILE *fp,
+ const char *name,
+ unsigned short port,
+ const struct ares_addrinfo_hints *hints,
+ struct ares_addrinfo *ai)
+{
+ char *line = NULL, *p, *q;
+ char *txtaddr, *txthost, *txtalias;
+ char *aliases[MAX_ALIASES];
+ unsigned int i, alias_count;
+ int status;
+ size_t linesize;
+ ares_sockaddr addr;
+ struct ares_addrinfo_cname *cname = NULL, *cnames = NULL;
+ struct ares_addrinfo_node *node = NULL, *nodes = NULL;
+ int match_with_alias, match_with_canonical;
+ int want_cname = hints->ai_flags & ARES_AI_CANONNAME;
+
+ /* Validate family */
+ switch (hints->ai_family) {
+ case AF_INET:
+ case AF_INET6:
+ case AF_UNSPEC:
+ break;
+ default:
+ return ARES_EBADFAMILY;
+ }
+
+
+ while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
+ {
+ match_with_alias = 0;
+ match_with_canonical = 0;
+ alias_count = 0;
+ /* Trim line comment. */
+ p = line;
+ while (*p && (*p != '#'))
+ p++;
+ *p = '\0';
+
+ /* Trim trailing whitespace. */
+ q = p - 1;
+ while ((q >= line) && ISSPACE(*q))
+ q--;
+ *++q = '\0';
+
+ /* Skip leading whitespace. */
+ p = line;
+ while (*p && ISSPACE(*p))
+ p++;
+ if (!*p)
+ /* Ignore line if empty. */
+ continue;
+
+ /* Pointer to start of IPv4 or IPv6 address part. */
+ txtaddr = p;
+
+ /* Advance past address part. */
+ while (*p && !ISSPACE(*p))
+ p++;
+ if (!*p)
+ /* Ignore line if reached end of line. */
+ continue;
+
+ /* Null terminate address part. */
+ *p = '\0';
+
+ /* Advance to host name */
+ p++;
+ while (*p && ISSPACE(*p))
+ p++;
+ if (!*p)
+ /* Ignore line if reached end of line. */
+ continue; /* LCOV_EXCL_LINE: trailing whitespace already stripped */
+
+ /* Pointer to start of host name. */
+ txthost = p;
+
+ /* Advance past host name. */
+ while (*p && !ISSPACE(*p))
+ p++;
+
+ /* Pointer to start of first alias. */
+ txtalias = NULL;
+ if (*p)
+ {
+ q = p + 1;
+ while (*q && ISSPACE(*q))
+ q++;
+ if (*q)
+ txtalias = q;
+ }
+
+ /* Null terminate host name. */
+ *p = '\0';
+
+ /* Find out if host name matches with canonical host name. */
+ if (strcasecmp(txthost, name) == 0)
+ {
+ match_with_canonical = 1;
+ }
+
+ /* Find out if host name matches with one of the aliases. */
+ while (txtalias)
+ {
+ p = txtalias;
+ while (*p && !ISSPACE(*p))
+ p++;
+ q = p;
+ while (*q && ISSPACE(*q))
+ q++;
+ *p = '\0';
+ if (strcasecmp(txtalias, name) == 0)
+ {
+ match_with_alias = 1;
+ if (!want_cname)
+ break;
+ }
+ if (alias_count < MAX_ALIASES)
+ {
+ aliases[alias_count++] = txtalias;
+ }
+ txtalias = *q ? q : NULL;
+ }
+
+ /* Try next line if host does not match. */
+ if (!match_with_alias && !match_with_canonical)
+ {
+ continue;
+ }
+
+ /* Zero-out 'addr' struct, as there are members that we may not set, especially
+ * for ipv6. We don't want garbage data */
+ memset(&addr, 0, sizeof(addr));
+
+ /*
+ * Convert address string to network address for the requested families.
+ * Actual address family possible values are AF_INET and AF_INET6 only.
+ */
+ if ((hints->ai_family == AF_INET) || (hints->ai_family == AF_UNSPEC))
+ {
+ addr.sa4.sin_port = htons(port);
+ if (ares_inet_pton(AF_INET, txtaddr, &addr.sa4.sin_addr) > 0)
+ {
+ node = ares__append_addrinfo_node(&nodes);
+ if(!node)
+ {
+ goto enomem;
+ }
+
+ node->ai_family = addr.sa.sa_family = AF_INET;
+ node->ai_addrlen = sizeof(addr.sa4);
+ node->ai_addr = ares_malloc(sizeof(addr.sa4));
+ if (!node->ai_addr)
+ {
+ goto enomem;
+ }
+ memcpy(node->ai_addr, &addr.sa4, sizeof(addr.sa4));
+ }
+ }
+ if ((hints->ai_family == AF_INET6) || (hints->ai_family == AF_UNSPEC))
+ {
+ addr.sa6.sin6_port = htons(port);
+ if (ares_inet_pton(AF_INET6, txtaddr, &addr.sa6.sin6_addr) > 0)
+ {
+ node = ares__append_addrinfo_node(&nodes);
+ if (!node)
+ {
+ goto enomem;
+ }
+
+ node->ai_family = addr.sa.sa_family = AF_INET6;
+ node->ai_addrlen = sizeof(addr.sa6);
+ node->ai_addr = ares_malloc(sizeof(addr.sa6));
+ if (!node->ai_addr)
+ {
+ goto enomem;
+ }
+ memcpy(node->ai_addr, &addr.sa6, sizeof(addr.sa6));
+ }
+ }
+ if (!node)
+ /* Ignore line if invalid address string for the requested family. */
+ continue;
+
+ if (want_cname)
+ {
+ for (i = 0; i < alias_count; ++i)
+ {
+ cname = ares__append_addrinfo_cname(&cnames);
+ if (!cname)
+ {
+ goto enomem;
+ }
+ cname->alias = ares_strdup(aliases[i]);
+ cname->name = ares_strdup(txthost);
+ }
+ /* No aliases, cname only. */
+ if(!alias_count)
+ {
+ cname = ares__append_addrinfo_cname(&cnames);
+ if (!cname)
+ {
+ goto enomem;
+ }
+ cname->name = ares_strdup(txthost);
+ }
+ }
+ }
+
+ /* Last read failed. */
+ if (status == ARES_ENOMEM)
+ {
+ goto enomem;
+ }
+
+ /* Free line buffer. */
+ ares_free(line);
+
+ ares__addrinfo_cat_cnames(&ai->cnames, cnames);
+ ares__addrinfo_cat_nodes(&ai->nodes, nodes);
+
+ return node ? ARES_SUCCESS : ARES_ENOTFOUND;
+
+enomem:
+ ares_free(line);
+ ares__freeaddrinfo_cnames(cnames);
+ ares__freeaddrinfo_nodes(nodes);
+ return ARES_ENOMEM;
+}
diff --git a/deps/cares/src/lib/ares__sortaddrinfo.c b/deps/cares/src/lib/ares__sortaddrinfo.c
new file mode 100644
index 0000000000..6e56cc9023
--- /dev/null
+++ b/deps/cares/src/lib/ares__sortaddrinfo.c
@@ -0,0 +1,499 @@
+/*
+ * Original file name getaddrinfo.c
+ * Lifted from the 'Android Bionic' project with the BSD license.
+ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 by Andrew Selivanov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <assert.h>
+#include <limits.h>
+
+#include "ares.h"
+#include "ares_private.h"
+
+struct addrinfo_sort_elem
+{
+ struct ares_addrinfo_node *ai;
+ int has_src_addr;
+ ares_sockaddr src_addr;
+ int original_order;
+};
+
+#define ARES_IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f)
+
+#define ARES_IPV6_ADDR_SCOPE_NODELOCAL 0x01
+#define ARES_IPV6_ADDR_SCOPE_INTFACELOCAL 0x01
+#define ARES_IPV6_ADDR_SCOPE_LINKLOCAL 0x02
+#define ARES_IPV6_ADDR_SCOPE_SITELOCAL 0x05
+#define ARES_IPV6_ADDR_SCOPE_ORGLOCAL 0x08
+#define ARES_IPV6_ADDR_SCOPE_GLOBAL 0x0e
+
+#define ARES_IN_LOOPBACK(a) ((((long int)(a)) & 0xff000000) == 0x7f000000)
+
+/* RFC 4193. */
+#define ARES_IN6_IS_ADDR_ULA(a) (((a)->s6_addr[0] & 0xfe) == 0xfc)
+
+/* These macros are modelled after the ones in <netinet/in6.h>. */
+/* RFC 4380, section 2.6 */
+#define ARES_IN6_IS_ADDR_TEREDO(a) \
+ ((*(const unsigned int *)(const void *)(&(a)->s6_addr[0]) == ntohl(0x20010000)))
+/* RFC 3056, section 2. */
+#define ARES_IN6_IS_ADDR_6TO4(a) \
+ (((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02))
+/* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */
+#define ARES_IN6_IS_ADDR_6BONE(a) \
+ (((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe))
+
+
+static int get_scope(const struct sockaddr *addr)
+{
+ if (addr->sa_family == AF_INET6)
+ {
+ const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr);
+ if (IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr))
+ {
+ return ARES_IPV6_ADDR_MC_SCOPE(&addr6->sin6_addr);
+ }
+ else if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr) ||
+ IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr))
+ {
+ /*
+ * RFC 4291 section 2.5.3 says loopback is to be treated as having
+ * link-local scope.
+ */
+ return ARES_IPV6_ADDR_SCOPE_LINKLOCAL;
+ }
+ else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr))
+ {
+ return ARES_IPV6_ADDR_SCOPE_SITELOCAL;
+ }
+ else
+ {
+ return ARES_IPV6_ADDR_SCOPE_GLOBAL;
+ }
+ }
+ else if (addr->sa_family == AF_INET)
+ {
+ const struct sockaddr_in *addr4 = CARES_INADDR_CAST(const struct sockaddr_in *, addr);
+ unsigned long int na = ntohl(addr4->sin_addr.s_addr);
+ if (ARES_IN_LOOPBACK(na) || /* 127.0.0.0/8 */
+ (na & 0xffff0000) == 0xa9fe0000) /* 169.254.0.0/16 */
+ {
+ return ARES_IPV6_ADDR_SCOPE_LINKLOCAL;
+ }
+ else
+ {
+ /*
+ * RFC 6724 section 3.2. Other IPv4 addresses, including private
+ * addresses and shared addresses (100.64.0.0/10), are assigned global
+ * scope.
+ */
+ return ARES_IPV6_ADDR_SCOPE_GLOBAL;
+ }
+ }
+ else
+ {
+ /*
+ * This should never happen.
+ * Return a scope with low priority as a last resort.
+ */
+ return ARES_IPV6_ADDR_SCOPE_NODELOCAL;
+ }
+}
+
+static int get_label(const struct sockaddr *addr)
+{
+ if (addr->sa_family == AF_INET)
+ {
+ return 4;
+ }
+ else if (addr->sa_family == AF_INET6)
+ {
+ const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr);
+ if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr))
+ {
+ return 0;
+ }
+ else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr))
+ {
+ return 4;
+ }
+ else if (ARES_IN6_IS_ADDR_6TO4(&addr6->sin6_addr))
+ {
+ return 2;
+ }
+ else if (ARES_IN6_IS_ADDR_TEREDO(&addr6->sin6_addr))
+ {
+ return 5;
+ }
+ else if (ARES_IN6_IS_ADDR_ULA(&addr6->sin6_addr))
+ {
+ return 13;
+ }
+ else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr))
+ {
+ return 3;
+ }
+ else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr))
+ {
+ return 11;
+ }
+ else if (ARES_IN6_IS_ADDR_6BONE(&addr6->sin6_addr))
+ {
+ return 12;
+ }
+ else
+ {
+ /* All other IPv6 addresses, including global unicast addresses. */
+ return 1;
+ }
+ }
+ else
+ {
+ /*
+ * This should never happen.
+ * Return a semi-random label as a last resort.
+ */
+ return 1;
+ }
+}
+
+/*
+ * Get the precedence for a given IPv4/IPv6 address.
+ * RFC 6724, section 2.1.
+ */
+static int get_precedence(const struct sockaddr *addr)
+{
+ if (addr->sa_family == AF_INET)
+ {
+ return 35;
+ }
+ else if (addr->sa_family == AF_INET6)
+ {
+ const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr);
+ if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr))
+ {
+ return 50;
+ }
+ else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr))
+ {
+ return 35;
+ }
+ else if (ARES_IN6_IS_ADDR_6TO4(&addr6->sin6_addr))
+ {
+ return 30;
+ }
+ else if (ARES_IN6_IS_ADDR_TEREDO(&addr6->sin6_addr))
+ {
+ return 5;
+ }
+ else if (ARES_IN6_IS_ADDR_ULA(&addr6->sin6_addr))
+ {
+ return 3;
+ }
+ else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) ||
+ IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
+ ARES_IN6_IS_ADDR_6BONE(&addr6->sin6_addr))
+ {
+ return 1;
+ }
+ else
+ {
+ /* All other IPv6 addresses, including global unicast addresses. */
+ return 40;
+ }
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+/*
+ * Find number of matching initial bits between the two addresses a1 and a2.
+ */
+static int common_prefix_len(const struct in6_addr *a1,
+ const struct in6_addr *a2)
+{
+ const char *p1 = (const char *)a1;
+ const char *p2 = (const char *)a2;
+ unsigned i;
+ for (i = 0; i < sizeof(*a1); ++i)
+ {
+ int x, j;
+ if (p1[i] == p2[i])
+ {
+ continue;
+ }
+ x = p1[i] ^ p2[i];
+ for (j = 0; j < CHAR_BIT; ++j)
+ {
+ if (x & (1 << (CHAR_BIT - 1)))
+ {
+ return i * CHAR_BIT + j;
+ }
+ x <<= 1;
+ }
+ }
+ return sizeof(*a1) * CHAR_BIT;
+}
+
+/*
+ * Compare two source/destination address pairs.
+ * RFC 6724, section 6.
+ */
+static int rfc6724_compare(const void *ptr1, const void *ptr2)
+{
+ const struct addrinfo_sort_elem *a1 = (const struct addrinfo_sort_elem *)ptr1;
+ const struct addrinfo_sort_elem *a2 = (const struct addrinfo_sort_elem *)ptr2;
+ int scope_src1, scope_dst1, scope_match1;
+ int scope_src2, scope_dst2, scope_match2;
+ int label_src1, label_dst1, label_match1;
+ int label_src2, label_dst2, label_match2;
+ int precedence1, precedence2;
+ int prefixlen1, prefixlen2;
+
+ /* Rule 1: Avoid unusable destinations. */
+ if (a1->has_src_addr != a2->has_src_addr)
+ {
+ return a2->has_src_addr - a1->has_src_addr;
+ }
+
+ /* Rule 2: Prefer matching scope. */
+ scope_src1 = get_scope(&a1->src_addr.sa);
+ scope_dst1 = get_scope(a1->ai->ai_addr);
+ scope_match1 = (scope_src1 == scope_dst1);
+
+ scope_src2 = get_scope(&a2->src_addr.sa);
+ scope_dst2 = get_scope(a2->ai->ai_addr);
+ scope_match2 = (scope_src2 == scope_dst2);
+
+ if (scope_match1 != scope_match2)
+ {
+ return scope_match2 - scope_match1;
+ }
+
+ /* Rule 3: Avoid deprecated addresses. */
+
+ /* Rule 4: Prefer home addresses. */
+
+ /* Rule 5: Prefer matching label. */
+ label_src1 = get_label(&a1->src_addr.sa);
+ label_dst1 = get_label(a1->ai->ai_addr);
+ label_match1 = (label_src1 == label_dst1);
+
+ label_src2 = get_label(&a2->src_addr.sa);
+ label_dst2 = get_label(a2->ai->ai_addr);
+ label_match2 = (label_src2 == label_dst2);
+
+ if (label_match1 != label_match2)
+ {
+ return label_match2 - label_match1;
+ }
+
+ /* Rule 6: Prefer higher precedence. */
+ precedence1 = get_precedence(a1->ai->ai_addr);
+ precedence2 = get_precedence(a2->ai->ai_addr);
+ if (precedence1 != precedence2)
+ {
+ return precedence2 - precedence1;
+ }
+
+ /* Rule 7: Prefer native transport. */
+
+ /* Rule 8: Prefer smaller scope. */
+ if (scope_dst1 != scope_dst2)
+ {
+ return scope_dst1 - scope_dst2;
+ }
+
+ /* Rule 9: Use longest matching prefix. */
+ if (a1->has_src_addr && a1->ai->ai_addr->sa_family == AF_INET6 &&
+ a2->has_src_addr && a2->ai->ai_addr->sa_family == AF_INET6)
+ {
+ const struct sockaddr_in6 *a1_src = &a1->src_addr.sa6;
+ const struct sockaddr_in6 *a1_dst =
+ CARES_INADDR_CAST(const struct sockaddr_in6 *, a1->ai->ai_addr);
+ const struct sockaddr_in6 *a2_src = &a2->src_addr.sa6;
+ const struct sockaddr_in6 *a2_dst =
+ CARES_INADDR_CAST(const struct sockaddr_in6 *, a2->ai->ai_addr);
+ prefixlen1 = common_prefix_len(&a1_src->sin6_addr, &a1_dst->sin6_addr);
+ prefixlen2 = common_prefix_len(&a2_src->sin6_addr, &a2_dst->sin6_addr);
+ if (prefixlen1 != prefixlen2)
+ {
+ return prefixlen2 - prefixlen1;
+ }
+ }
+
+ /*
+ * Rule 10: Leave the order unchanged.
+ * We need this since qsort() is not necessarily stable.
+ */
+ return a1->original_order - a2->original_order;
+}
+
+/*
+ * Find the source address that will be used if trying to connect to the given
+ * address.
+ *
+ * Returns 1 if a source address was found, 0 if the address is unreachable,
+ * and -1 if a fatal error occurred. If 0 or 1, the contents of src_addr are
+ * undefined.
+ */
+static int find_src_addr(ares_channel channel,
+ const struct sockaddr *addr,
+ struct sockaddr *src_addr)
+{
+ ares_socket_t sock;
+ int ret;
+ ares_socklen_t len;
+
+ switch (addr->sa_family)
+ {
+ case AF_INET:
+ len = sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ len = sizeof(struct sockaddr_in6);
+ break;
+ default:
+ /* No known usable source address for non-INET families. */
+ return 0;
+ }
+
+ sock = ares__open_socket(channel, addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock == ARES_SOCKET_BAD)
+ {
+ if (errno == EAFNOSUPPORT)
+ {
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ do
+ {
+ ret = ares__connect_socket(channel, sock, addr, len);
+ }
+ while (ret == -1 && errno == EINTR);
+
+ if (ret == -1)
+ {
+ ares__close_socket(channel, sock);
+ return 0;
+ }
+
+ if (getsockname(sock, src_addr, &len) != 0)
+ {
+ ares__close_socket(channel, sock);
+ return -1;
+ }
+ ares__close_socket(channel, sock);
+ return 1;
+}
+
+/*
+ * Sort the linked list starting at sentinel->ai_next in RFC6724 order.
+ * Will leave the list unchanged if an error occurs.
+ */
+int ares__sortaddrinfo(ares_channel channel, struct ares_addrinfo_node *list_sentinel)
+{
+ struct ares_addrinfo_node *cur;
+ int nelem = 0, i;
+ int has_src_addr;
+ struct addrinfo_sort_elem *elems;
+
+ cur = list_sentinel->ai_next;
+ while (cur)
+ {
+ ++nelem;
+ cur = cur->ai_next;
+ }
+
+ if (!nelem)
+ return ARES_ENODATA;
+
+ elems = (struct addrinfo_sort_elem *)ares_malloc(
+ nelem * sizeof(struct addrinfo_sort_elem));
+ if (!elems)
+ {
+ return ARES_ENOMEM;
+ }
+
+ /*
+ * Convert the linked list to an array that also contains the candidate
+ * source address for each destination address.
+ */
+ for (i = 0, cur = list_sentinel->ai_next; i < nelem; ++i, cur = cur->ai_next)
+ {
+ assert(cur != NULL);
+ elems[i].ai = cur;
+ elems[i].original_order = i;
+ has_src_addr = find_src_addr(channel, cur->ai_addr, &elems[i].src_addr.sa);
+ if (has_src_addr == -1)
+ {
+ ares_free(elems);
+ return ARES_ENOTFOUND;
+ }
+ elems[i].has_src_addr = has_src_addr;
+ }
+
+ /* Sort the addresses, and rearrange the linked list so it matches the sorted
+ * order. */
+ qsort((void *)elems, nelem, sizeof(struct addrinfo_sort_elem),
+ rfc6724_compare);
+
+ list_sentinel->ai_next = elems[0].ai;
+ for (i = 0; i < nelem - 1; ++i)
+ {
+ elems[i].ai->ai_next = elems[i + 1].ai;
+ }
+ elems[nelem - 1].ai->ai_next = NULL;
+
+ ares_free(elems);
+ return ARES_SUCCESS;
+}
diff --git a/deps/cares/src/ares__timeval.c b/deps/cares/src/lib/ares__timeval.c
similarity index 100%
rename from deps/cares/src/ares__timeval.c
rename to deps/cares/src/lib/ares__timeval.c
diff --git a/deps/cares/src/ares_android.c b/deps/cares/src/lib/ares_android.c
similarity index 99%
rename from deps/cares/src/ares_android.c
rename to deps/cares/src/lib/ares_android.c
index bf77131b58..5b00b8065c 100644
--- a/deps/cares/src/ares_android.c
+++ b/deps/cares/src/lib/ares_android.c
@@ -360,8 +360,6 @@ char *ares_get_android_search_domains_list(void)
jstring domains = NULL;
const char *domain;
int res;
- size_t i;
- size_t cnt = 0;
char *domain_list = NULL;
int need_detatch = 0;
diff --git a/deps/cares/src/ares_android.h b/deps/cares/src/lib/ares_android.h
similarity index 100%
rename from deps/cares/src/ares_android.h
rename to deps/cares/src/lib/ares_android.h
diff --git a/deps/cares/src/ares_cancel.c b/deps/cares/src/lib/ares_cancel.c
similarity index 100%
rename from deps/cares/src/ares_cancel.c
rename to deps/cares/src/lib/ares_cancel.c
diff --git a/deps/cares/src/ares_create_query.c b/deps/cares/src/lib/ares_create_query.c
similarity index 94%
rename from deps/cares/src/ares_create_query.c
rename to deps/cares/src/lib/ares_create_query.c
index 9efce17cfa..e3d874b450 100644
--- a/deps/cares/src/ares_create_query.c
+++ b/deps/cares/src/lib/ares_create_query.c
@@ -19,22 +19,13 @@
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
#include "ares_private.h"
-#ifndef T_OPT
-# define T_OPT 41 /* EDNS0 option (meta-RR) */
-#endif
/* Header format, from RFC 1035:
* 1 1 1 1 1 1
@@ -57,7 +48,7 @@
* of the remaining fields:
* ID Identifier to match responses with queries
* QR Query (0) or response (1)
- * Opcode For our purposes, always QUERY
+ * Opcode For our purposes, always O_QUERY
* RD Recursion desired
* Z Reserved (zero)
* QDCOUNT Number of queries
@@ -116,7 +107,7 @@ int ares_create_query(const char *name, int dnsclass, int type,
q = buf;
memset(q, 0, HFIXEDSZ);
DNS_HEADER_SET_QID(q, id);
- DNS_HEADER_SET_OPCODE(q, QUERY);
+ DNS_HEADER_SET_OPCODE(q, O_QUERY);
if (rd) {
DNS_HEADER_SET_RD(q, 1);
}
diff --git a/deps/cares/src/ares_data.c b/deps/cares/src/lib/ares_data.c
similarity index 100%
rename from deps/cares/src/ares_data.c
rename to deps/cares/src/lib/ares_data.c
diff --git a/deps/cares/src/ares_data.h b/deps/cares/src/lib/ares_data.h
similarity index 100%
rename from deps/cares/src/ares_data.h
rename to deps/cares/src/lib/ares_data.h
diff --git a/deps/cares/src/ares_destroy.c b/deps/cares/src/lib/ares_destroy.c
similarity index 100%
rename from deps/cares/src/ares_destroy.c
rename to deps/cares/src/lib/ares_destroy.c
diff --git a/deps/cares/src/ares_expand_name.c b/deps/cares/src/lib/ares_expand_name.c
similarity index 65%
rename from deps/cares/src/ares_expand_name.c
rename to deps/cares/src/lib/ares_expand_name.c
index 3a38e6737e..a62c982e04 100644
--- a/deps/cares/src/ares_expand_name.c
+++ b/deps/cares/src/lib/ares_expand_name.c
@@ -19,14 +19,8 @@
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_nowarn.h"
@@ -36,7 +30,52 @@
#define MAX_INDIRS 50
static int name_length(const unsigned char *encoded, const unsigned char *abuf,
- int alen);
+ int alen, int is_hostname);
+
+/* Reserved characters for names that need to be escaped */
+static int is_reservedch(int ch)
+{
+ switch (ch) {
+ case '"':
+ case '.':
+ case ';':
+ case '\\':
+ case '(':
+ case ')':
+ case '@':
+ case '$':
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int ares__isprint(int ch)
+{
+ if (ch >= 0x20 && ch <= 0x7E)
+ return 1;
+ return 0;
+}
+
+/* Character set allowed by hostnames */
+static int is_hostnamech(int ch)
+{
+ /* [A-Za-z0-9-.]
+ * Don't use isalnum() as it is locale-specific
+ */
+ if (ch >= 'A' && ch <= 'Z')
+ return 1;
+ if (ch >= 'a' && ch <= 'z')
+ return 1;
+ if (ch >= '0' && ch <= '9')
+ return 1;
+ if (ch == '-' || ch == '.')
+ return 1;
+
+ return 0;
+}
/* Expand an RFC1035-encoded domain name given by encoded. The
* containing message is given by abuf and alen. The result given by
@@ -60,10 +99,15 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf,
*
* Since the expanded name uses '.' as a label separator, we use
* backslashes to escape periods or backslashes in the expanded name.
+ *
+ * If the result is expected to be a hostname, then no escaped data is allowed
+ * and will return error.
*/
-int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
- int alen, char **s, long *enclen)
+int ares__expand_name_validated(const unsigned char *encoded,
+ const unsigned char *abuf,
+ int alen, char **s, long *enclen,
+ int is_hostname)
{
int len, indir = 0;
char *q;
@@ -73,7 +117,7 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
size_t uns;
} nlen;
- nlen.sig = name_length(encoded, abuf, alen);
+ nlen.sig = name_length(encoded, abuf, alen, is_hostname);
if (nlen.sig < 0)
return ARES_EBADNAME;
@@ -113,18 +157,36 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
}
else
{
- len = *p;
+ int name_len = *p;
+ len = name_len;
p++;
+
while (len--)
{
- if (*p == '.' || *p == '\\')
- *q++ = '\\';
- *q++ = *p;
+ /* Output as \DDD for consistency with RFC1035 5.1, except
+ * for the special case of a root name response */
+ if (!ares__isprint(*p) && !(name_len == 1 && *p == 0))
+ {
+ *q++ = '\\';
+ *q++ = '0' + *p / 100;
+ *q++ = '0' + (*p % 100) / 10;
+ *q++ = '0' + (*p % 10);
+ }
+ else if (is_reservedch(*p))
+ {
+ *q++ = '\\';
+ *q++ = *p;
+ }
+ else
+ {
+ *q++ = *p;
+ }
p++;
}
*q++ = '.';
}
- }
+ }
+
if (!indir)
*enclen = aresx_uztosl(p + 1U - encoded);
@@ -137,11 +199,18 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
return ARES_SUCCESS;
}
+
+int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
+ int alen, char **s, long *enclen)
+{
+ return ares__expand_name_validated(encoded, abuf, alen, s, enclen, 0);
+}
+
/* Return the length of the expansion of an encoded domain name, or
* -1 if the encoding is invalid.
*/
static int name_length(const unsigned char *encoded, const unsigned char *abuf,
- int alen)
+ int alen, int is_hostname)
{
int n = 0, offset, indir = 0, top;
@@ -171,15 +240,35 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf,
}
else if (top == 0x00)
{
- offset = *encoded;
+ int name_len = *encoded;
+ offset = name_len;
if (encoded + offset + 1 >= abuf + alen)
return -1;
encoded++;
+
while (offset--)
{
- n += (*encoded == '.' || *encoded == '\\') ? 2 : 1;
+ if (!ares__isprint(*encoded) && !(name_len == 1 && *encoded == 0))
+ {
+ if (is_hostname)
+ return -1;
+ n += 4;
+ }
+ else if (is_reservedch(*encoded))
+ {
+ if (is_hostname)
+ return -1;
+ n += 2;
+ }
+ else
+ {
+ if (is_hostname && !is_hostnamech(*encoded))
+ return -1;
+ n += 1;
+ }
encoded++;
}
+
n++;
}
else
@@ -197,12 +286,14 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf,
return (n) ? n - 1 : n;
}
-/* Like ares_expand_name but returns EBADRESP in case of invalid input. */
+/* Like ares_expand_name_validated but returns EBADRESP in case of invalid
+ * input. */
int ares__expand_name_for_response(const unsigned char *encoded,
const unsigned char *abuf, int alen,
- char **s, long *enclen)
+ char **s, long *enclen, int is_hostname)
{
- int status = ares_expand_name(encoded, abuf, alen, s, enclen);
+ int status = ares__expand_name_validated(encoded, abuf, alen, s, enclen,
+ is_hostname);
if (status == ARES_EBADNAME)
status = ARES_EBADRESP;
return status;
diff --git a/deps/cares/src/ares_expand_string.c b/deps/cares/src/lib/ares_expand_string.c
similarity index 95%
rename from deps/cares/src/ares_expand_string.c
rename to deps/cares/src/lib/ares_expand_string.c
index d35df75248..03e3929975 100644
--- a/deps/cares/src/ares_expand_string.c
+++ b/deps/cares/src/lib/ares_expand_string.c
@@ -19,11 +19,8 @@
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_private.h" /* for the memdebug */
diff --git a/deps/cares/src/ares_fds.c b/deps/cares/src/lib/ares_fds.c
similarity index 100%
rename from deps/cares/src/ares_fds.c
rename to deps/cares/src/lib/ares_fds.c
diff --git a/deps/cares/src/ares_free_hostent.c b/deps/cares/src/lib/ares_free_hostent.c
similarity index 79%
rename from deps/cares/src/ares_free_hostent.c
rename to deps/cares/src/lib/ares_free_hostent.c
index cfc5f81feb..ea28ff0e2c 100644
--- a/deps/cares/src/ares_free_hostent.c
+++ b/deps/cares/src/lib/ares_free_hostent.c
@@ -31,11 +31,13 @@ void ares_free_hostent(struct hostent *host)
return;
ares_free((char *)(host->h_name));
- for (p = host->h_aliases; *p; p++)
+ for (p = host->h_aliases; p && *p; p++)
ares_free(*p);
ares_free(host->h_aliases);
- ares_free(host->h_addr_list[0]); /* no matter if there is one or many entries,
- there is only one malloc for all of them */
- ares_free(host->h_addr_list);
+ if (host->h_addr_list) {
+ ares_free(host->h_addr_list[0]); /* no matter if there is one or many entries,
+ there is only one malloc for all of them */
+ ares_free(host->h_addr_list);
+ }
ares_free(host);
}
diff --git a/deps/cares/src/ares_free_string.c b/deps/cares/src/lib/ares_free_string.c
similarity index 100%
rename from deps/cares/src/ares_free_string.c
rename to deps/cares/src/lib/ares_free_string.c
diff --git a/deps/cares/src/lib/ares_freeaddrinfo.c b/deps/cares/src/lib/ares_freeaddrinfo.c
new file mode 100644
index 0000000000..d8891bbf8a
--- /dev/null
+++ b/deps/cares/src/lib/ares_freeaddrinfo.c
@@ -0,0 +1,59 @@
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2019 by Andrew Selivanov
+ *
+ * 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"
+
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+
+#include "ares.h"
+#include "ares_private.h"
+
+void ares__freeaddrinfo_cnames(struct ares_addrinfo_cname *head)
+{
+ struct ares_addrinfo_cname *current;
+ while (head)
+ {
+ current = head;
+ head = head->next;
+ ares_free(current->alias);
+ ares_free(current->name);
+ ares_free(current);
+ }
+}
+
+void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *head)
+{
+ struct ares_addrinfo_node *current;
+ while (head)
+ {
+ current = head;
+ head = head->ai_next;
+ ares_free(current->ai_addr);
+ ares_free(current);
+ }
+}
+
+void ares_freeaddrinfo(struct ares_addrinfo *ai)
+{
+ if (ai == NULL)
+ return;
+ ares__freeaddrinfo_cnames(ai->cnames);
+ ares__freeaddrinfo_nodes(ai->nodes);
+ ares_free(ai);
+}
diff --git a/deps/cares/src/lib/ares_getaddrinfo.c b/deps/cares/src/lib/ares_getaddrinfo.c
new file mode 100644
index 0000000000..db17a67086
--- /dev/null
+++ b/deps/cares/src/lib/ares_getaddrinfo.c
@@ -0,0 +1,772 @@
+
+/* Copyright 1998, 2011, 2013 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2017 - 2018 by Christian Ammer
+ * Copyright (C) 2019 by Andrew Selivanov
+ *
+ * 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"
+
+#ifdef HAVE_GETSERVBYNAME_R
+# if !defined(GETSERVBYNAME_R_ARGS) || \
+ (GETSERVBYNAME_R_ARGS < 4) || (GETSERVBYNAME_R_ARGS > 6)
+# error "you MUST specifiy a valid number of arguments for getservbyname_r"
+# endif
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#include "ares_nameser.h"
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#include <assert.h>
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "ares.h"
+#include "bitncmp.h"
+#include "ares_private.h"
+
+#ifdef WATT32
+#undef WIN32
+#endif
+#ifdef WIN32
+# include "ares_platform.h"
+#endif
+
+struct host_query
+{
+ ares_channel channel;
+ char *name;
+ unsigned short port; /* in host order */
+ ares_addrinfo_callback callback;
+ void *arg;
+ struct ares_addrinfo_hints hints;
+ int sent_family; /* this family is what was is being used */
+ int timeouts; /* number of timeouts we saw for this request */
+ const char *remaining_lookups; /* types of lookup we need to perform ("fb" by
+ default, file and dns respectively) */
+ struct ares_addrinfo *ai; /* store results between lookups */
+ int remaining; /* number of DNS answers waiting for */
+ int next_domain; /* next search domain to try */
+};
+
+static const struct ares_addrinfo_hints default_hints = {
+ 0, /* ai_flags */
+ AF_UNSPEC, /* ai_family */
+ 0, /* ai_socktype */
+ 0, /* ai_protocol */
+};
+
+static const struct ares_addrinfo_cname empty_addrinfo_cname = {
+ INT_MAX, /* ttl */
+ NULL, /* alias */
+ NULL, /* name */
+ NULL, /* next */
+};
+
+static const struct ares_addrinfo_node empty_addrinfo_node = {
+ 0, /* ai_ttl */
+ 0, /* ai_flags */
+ 0, /* ai_family */
+ 0, /* ai_socktype */
+ 0, /* ai_protocol */
+ 0, /* ai_addrlen */
+ NULL, /* ai_addr */
+ NULL /* ai_next */
+};
+
+static const struct ares_addrinfo empty_addrinfo = {
+ NULL, /* cnames */
+ NULL /* nodes */
+};
+
+/* forward declarations */
+static void host_callback(void *arg, int status, int timeouts,
+ unsigned char *abuf, int alen);
+static int as_is_first(const struct host_query *hquery);
+static int next_dns_lookup(struct host_query *hquery);
+
+struct ares_addrinfo_cname *ares__malloc_addrinfo_cname()
+{
+ struct ares_addrinfo_cname *cname = ares_malloc(sizeof(struct ares_addrinfo_cname));
+ if (!cname)
+ return NULL;
+
+ *cname = empty_addrinfo_cname;
+ return cname;
+}
+
+struct ares_addrinfo_cname *ares__append_addrinfo_cname(struct ares_addrinfo_cname **head)
+{
+ struct ares_addrinfo_cname *tail = ares__malloc_addrinfo_cname();
+ struct ares_addrinfo_cname *last = *head;
+ if (!last)
+ {
+ *head = tail;
+ return tail;
+ }
+
+ while (last->next)
+ {
+ last = last->next;
+ }
+
+ last->next = tail;
+ return tail;
+}
+
+void ares__addrinfo_cat_cnames(struct ares_addrinfo_cname **head,
+ struct ares_addrinfo_cname *tail)
+{
+ struct ares_addrinfo_cname *last = *head;
+ if (!last)
+ {
+ *head = tail;
+ return;
+ }
+
+ while (last->next)
+ {
+ last = last->next;
+ }
+
+ last->next = tail;
+}
+
+struct ares_addrinfo *ares__malloc_addrinfo()
+{
+ struct ares_addrinfo *ai = ares_malloc(sizeof(struct ares_addrinfo));
+ if (!ai)
+ return NULL;
+
+ *ai = empty_addrinfo;
+ return ai;
+}
+
+struct ares_addrinfo_node *ares__malloc_addrinfo_node()
+{
+ struct ares_addrinfo_node *node =
+ ares_malloc(sizeof(struct ares_addrinfo_node));
+ if (!node)
+ return NULL;
+
+ *node = empty_addrinfo_node;
+ return node;
+}
+
+/* Allocate new addrinfo and append to the tail. */
+struct ares_addrinfo_node *ares__append_addrinfo_node(struct ares_addrinfo_node **head)
+{
+ struct ares_addrinfo_node *tail = ares__malloc_addrinfo_node();
+ struct ares_addrinfo_node *last = *head;
+ if (!last)
+ {
+ *head = tail;
+ return tail;
+ }
+
+ while (last->ai_next)
+ {
+ last = last->ai_next;
+ }
+
+ last->ai_next = tail;
+ return tail;
+}
+
+void ares__addrinfo_cat_nodes(struct ares_addrinfo_node **head,
+ struct ares_addrinfo_node *tail)
+{
+ struct ares_addrinfo_node *last = *head;
+ if (!last)
+ {
+ *head = tail;
+ return;
+ }
+
+ while (last->ai_next)
+ {
+ last = last->ai_next;
+ }
+
+ last->ai_next = tail;
+}
+
+/* Resolve service name into port number given in host byte order.
+ * If not resolved, return 0.
+ */
+static unsigned short lookup_service(const char *service, int flags)
+{
+ const char *proto;
+ struct servent *sep;
+#ifdef HAVE_GETSERVBYNAME_R
+ struct servent se;
+ char tmpbuf[4096];
+#endif
+
+ if (service)
+ {
+ if (flags & ARES_NI_UDP)
+ proto = "udp";
+ else if (flags & ARES_NI_SCTP)
+ proto = "sctp";
+ else if (flags & ARES_NI_DCCP)
+ proto = "dccp";
+ else
+ proto = "tcp";
+#ifdef HAVE_GETSERVBYNAME_R
+ memset(&se, 0, sizeof(se));
+ sep = &se;
+ memset(tmpbuf, 0, sizeof(tmpbuf));
+#if GETSERVBYNAME_R_ARGS == 6
+ if (getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf),
+ &sep) != 0)
+ sep = NULL; /* LCOV_EXCL_LINE: buffer large so this never fails */
+#elif GETSERVBYNAME_R_ARGS == 5
+ sep =
+ getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf));
+#elif GETSERVBYNAME_R_ARGS == 4
+ if (getservbyname_r(service, proto, &se, (void *)tmpbuf) != 0)
+ sep = NULL;
+#else
+ /* Lets just hope the OS uses TLS! */
+ sep = getservbyname(service, proto);
+#endif
+#else
+ /* Lets just hope the OS uses TLS! */
+#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
+ sep = getservbyname(service, (char *)proto);
+#else
+ sep = getservbyname(service, proto);
+#endif
+#endif
+ return (sep ? ntohs((unsigned short)sep->s_port) : 0);
+ }
+ return 0;
+}
+
+/* If the name looks like an IP address or an error occured,
+ * fake up a host entry, end the query immediately, and return true.
+ * Otherwise return false.
+ */
+static int fake_addrinfo(const char *name,
+ unsigned short port,
+ const struct ares_addrinfo_hints *hints,
+ struct ares_addrinfo *ai,
+ ares_addrinfo_callback callback,
+ void *arg)
+{
+ struct ares_addrinfo_cname *cname;
+ struct ares_addrinfo_node *node;
+ ares_sockaddr addr;
+ size_t addrlen;
+ int result = 0;
+ int family = hints->ai_family;
+ if (family == AF_INET || family == AF_INET6 || family == AF_UNSPEC)
+ {
+ /* It only looks like an IP address if it's all numbers and dots. */
+ int numdots = 0, valid = 1;
+ const char *p;
+ for (p = name; *p; p++)
+ {
+ if (!ISDIGIT(*p) && *p != '.')
+ {
+ valid = 0;
+ break;
+ }
+ else if (*p == '.')
+ {
+ numdots++;
+ }
+ }
+
+ memset(&addr, 0, sizeof(addr));
+
+ /* if we don't have 3 dots, it is illegal
+ * (although inet_pton doesn't think so).
+ */
+ if (numdots != 3 || !valid)
+ result = 0;
+ else
+ result =
+ (ares_inet_pton(AF_INET, name, &addr.sa4.sin_addr) < 1 ? 0 : 1);
+
+ if (result)
+ {
+ family = addr.sa.sa_family = AF_INET;
+ addr.sa4.sin_port = htons(port);
+ addrlen = sizeof(addr.sa4);
+ }
+ }
+
+ if (family == AF_INET6 || family == AF_UNSPEC)
+ {
+ result =
+ (ares_inet_pton(AF_INET6, name, &addr.sa6.sin6_addr) < 1 ? 0 : 1);
+ addr.sa6.sin6_family = AF_INET6;
+ addr.sa6.sin6_port = htons(port);
+ addrlen = sizeof(addr.sa6);
+ }
+
+ if (!result)
+ return 0;
+
+ node = ares__malloc_addrinfo_node();
+ if (!node)
+ {
+ ares_freeaddrinfo(ai);
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return 1;
+ }
+
+ ai->nodes = node;
+
+ node->ai_addr = ares_malloc(addrlen);
+ if (!node->ai_addr)
+ {
+ ares_freeaddrinfo(ai);
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return 1;
+ }
+
+ node->ai_addrlen = (unsigned int)addrlen;
+ node->ai_family = addr.sa.sa_family;
+ if (addr.sa.sa_family == AF_INET)
+ memcpy(node->ai_addr, &addr.sa4, sizeof(addr.sa4));
+ else
+ memcpy(node->ai_addr, &addr.sa6, sizeof(addr.sa6));
+
+ if (hints->ai_flags & ARES_AI_CANONNAME)
+ {
+ cname = ares__append_addrinfo_cname(&ai->cnames);
+ if (!cname)
+ {
+ ares_freeaddrinfo(ai);
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return 1;
+ }
+
+ /* Duplicate the name, to avoid a constness violation. */
+ cname->name = ares_strdup(name);
+ if (!cname->name)
+ {
+ ares_freeaddrinfo(ai);
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return 1;
+ }
+ }
+
+ node->ai_socktype = hints->ai_socktype;
+ node->ai_protocol = hints->ai_protocol;
+
+ callback(arg, ARES_SUCCESS, 0, ai);
+ return 1;
+}
+
+static void end_hquery(struct host_query *hquery, int status)
+{
+ struct ares_addrinfo_node sentinel;
+ struct ares_addrinfo_node *next;
+ if (status == ARES_SUCCESS)
+ {
+ if (!(hquery->hints.ai_flags & ARES_AI_NOSORT) && hquery->ai->nodes)
+ {
+ sentinel.ai_next = hquery->ai->nodes;
+ ares__sortaddrinfo(hquery->channel, &sentinel);
+ hquery->ai->nodes = sentinel.ai_next;
+ }
+ next = hquery->ai->nodes;
+ /* Set port into each address (resolved separately). */
+ while (next)
+ {
+ next->ai_socktype = hquery->hints.ai_socktype;
+ next->ai_protocol = hquery->hints.ai_protocol;
+ if (next->ai_family == AF_INET)
+ {
+ (CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr))->sin_port = htons(hquery->port);
+ }
+ else
+ {
+ (CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr))->sin6_port = htons(hquery->port);
+ }
+ next = next->ai_next;
+ }
+ }
+ else
+ {
+ /* Clean up what we have collected by so far. */
+ ares_freeaddrinfo(hquery->ai);
+ hquery->ai = NULL;
+ }
+
+ hquery->callback(hquery->arg, status, hquery->timeouts, hquery->ai);
+ ares_free(hquery->name);
+ ares_free(hquery);
+}
+
+static int file_lookup(struct host_query *hquery)
+{
+ FILE *fp;
+ int error;
+ int status;
+ const char *path_hosts = NULL;
+
+ if (hquery->hints.ai_flags & ARES_AI_ENVHOSTS)
+ {
+ path_hosts = getenv("CARES_HOSTS");
+ }
+
+ if (!path_hosts)
+ {
+#ifdef WIN32
+ char PATH_HOSTS[MAX_PATH];
+ win_platform platform;
+
+ PATH_HOSTS[0] = '\0';
+
+ platform = ares__getplatform();
+
+ if (platform == WIN_NT)
+ {
+ char tmp[MAX_PATH];
+ HKEY hkeyHosts;
+
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
+ &hkeyHosts) == ERROR_SUCCESS)
+ {
+ DWORD dwLength = MAX_PATH;
+ RegQueryValueExA(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp,
+ &dwLength);
+ ExpandEnvironmentStringsA(tmp, PATH_HOSTS, MAX_PATH);
+ RegCloseKey(hkeyHosts);
+ }
+ }
+ else if (platform == WIN_9X)
+ GetWindowsDirectoryA(PATH_HOSTS, MAX_PATH);
+ else
+ return ARES_ENOTFOUND;
+
+ strcat(PATH_HOSTS, WIN_PATH_HOSTS);
+ path_hosts = PATH_HOSTS;
+
+#elif defined(WATT32)
+ const char *PATH_HOSTS = _w32_GetHostsFile();
+
+ if (!PATH_HOSTS)
+ return ARES_ENOTFOUND;
+#endif
+ path_hosts = PATH_HOSTS;
+ }
+
+ fp = fopen(path_hosts, "r");
+ if (!fp)
+ {
+ error = ERRNO;
+ switch (error)
+ {
+ case ENOENT:
+ case ESRCH:
+ return ARES_ENOTFOUND;
+ default:
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error,
+ strerror(error)));
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n", path_hosts));
+ return ARES_EFILE;
+ }
+ }
+ status = ares__readaddrinfo(fp, hquery->name, hquery->port, &hquery->hints, hquery->ai);
+ fclose(fp);
+ return status;
+}
+
+static void next_lookup(struct host_query *hquery, int status)
+{
+ switch (*hquery->remaining_lookups)
+ {
+ case 'b':
+ /* DNS lookup */
+ if (next_dns_lookup(hquery))
+ break;
+ hquery->remaining_lookups++;
+ next_lookup(hquery, status);
+ break;
+
+ case 'f':
+ /* Host file lookup */
+ if (file_lookup(hquery) == ARES_SUCCESS)
+ {
+ end_hquery(hquery, ARES_SUCCESS);
+ break;
+ }
+ hquery->remaining_lookups++;
+ next_lookup(hquery, status);
+ break;
+ default:
+ /* No lookup left */
+ end_hquery(hquery, status);
+ break;
+ }
+}
+
+static void host_callback(void *arg, int status, int timeouts,
+ unsigned char *abuf, int alen)
+{
+ struct host_query *hquery = (struct host_query*)arg;
+ int addinfostatus = ARES_SUCCESS;
+ hquery->timeouts += timeouts;
+ hquery->remaining--;
+
+ if (status == ARES_SUCCESS)
+ {
+ addinfostatus = ares__parse_into_addrinfo(abuf, alen, hquery->ai);
+ }
+
+ if (!hquery->remaining)
+ {
+ if (addinfostatus != ARES_SUCCESS)
+ {
+ /* error in parsing result e.g. no memory */
+ end_hquery(hquery, addinfostatus);
+ }
+ else if (hquery->ai->nodes)
+ {
+ /* at least one query ended with ARES_SUCCESS */
+ end_hquery(hquery, ARES_SUCCESS);
+ }
+ else if (status == ARES_ENOTFOUND)
+ {
+ next_lookup(hquery, status);
+ }
+ else if (status == ARES_EDESTRUCTION)
+ {
+ /* NOTE: Could also be ARES_EDESTRUCTION. We need to only call this
+ * once all queries (there can be multiple for getaddrinfo) are
+ * terminated. */
+ end_hquery(hquery, status);
+ }
+ else
+ {
+ end_hquery(hquery, status);
+ }
+ }
+
+ /* at this point we keep on waiting for the next query to finish */
+}
+
+void ares_getaddrinfo(ares_channel channel,
+ const char* name, const char* service,
+ const struct ares_addrinfo_hints* hints,
+ ares_addrinfo_callback callback, void* arg)
+{
+ struct host_query *hquery;
+ unsigned short port = 0;
+ int family;
+ struct ares_addrinfo *ai;
+
+ if (!hints)
+ {
+ hints = &default_hints;
+ }
+
+ family = hints->ai_family;
+
+ /* Right now we only know how to look up Internet addresses
+ and unspec means try both basically. */
+ if (family != AF_INET &&
+ family != AF_INET6 &&
+ family != AF_UNSPEC)
+ {
+ callback(arg, ARES_ENOTIMP, 0, NULL);
+ return;
+ }
+
+ if (ares__is_onion_domain(name))
+ {
+ callback(arg, ARES_ENOTFOUND, 0, NULL);
+ return;
+ }
+
+ if (service)
+ {
+ if (hints->ai_flags & ARES_AI_NUMERICSERV)
+ {
+ port = (unsigned short)strtoul(service, NULL, 0);
+ if (!port)
+ {
+ callback(arg, ARES_ESERVICE, 0, NULL);
+ return;
+ }
+ }
+ else
+ {
+ port = lookup_service(service, 0);
+ if (!port)
+ {
+ port = (unsigned short)strtoul(service, NULL, 0);
+ if (!port)
+ {
+ callback(arg, ARES_ESERVICE, 0, NULL);
+ return;
+ }
+ }
+ }
+ }
+
+ ai = ares__malloc_addrinfo();
+ if (!ai)
+ {
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return;
+ }
+
+ if (fake_addrinfo(name, port, hints, ai, callback, arg))
+ {
+ return;
+ }
+
+ /* Allocate and fill in the host query structure. */
+ hquery = ares_malloc(sizeof(struct host_query));
+ if (!hquery)
+ {
+ ares_freeaddrinfo(ai);
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return;
+ }
+
+ hquery->name = ares_strdup(name);
+ if (!hquery->name)
+ {
+ ares_free(hquery);
+ ares_freeaddrinfo(ai);
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return;
+ }
+
+ hquery->port = port;
+ hquery->channel = channel;
+ hquery->hints = *hints;
+ hquery->sent_family = -1; /* nothing is sent yet */
+ hquery->callback = callback;
+ hquery->arg = arg;
+ hquery->remaining_lookups = channel->lookups;
+ hquery->timeouts = 0;
+ hquery->ai = ai;
+ hquery->next_domain = -1;
+ hquery->remaining = 0;
+
+ /* Start performing lookups according to channel->lookups. */
+ next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */);
+}
+
+static int next_dns_lookup(struct host_query *hquery)
+{
+ char *s = NULL;
+ int is_s_allocated = 0;
+ int status;
+
+ /* if next_domain == -1 and as_is_first is true, try hquery->name */
+ if (hquery->next_domain == -1)
+ {
+ if (as_is_first(hquery))
+ {
+ s = hquery->name;
+ }
+ hquery->next_domain = 0;
+ }
+
+ /* if as_is_first is false, try hquery->name at last */
+ if (!s && hquery->next_domain == hquery->channel->ndomains) {
+ if (!as_is_first(hquery))
+ {
+ s = hquery->name;
+ }
+ hquery->next_domain++;
+ }
+
+ if (!s && hquery->next_domain < hquery->channel->ndomains)
+ {
+ status = ares__cat_domain(
+ hquery->name,
+ hquery->channel->domains[hquery->next_domain++],
+ &s);
+ if (status == ARES_SUCCESS)
+ {
+ is_s_allocated = 1;
+ }
+ }
+
+ if (s)
+ {
+ switch (hquery->hints.ai_family)
+ {
+ case AF_INET:
+ hquery->remaining += 1;
+ ares_query(hquery->channel, s, C_IN, T_A, host_callback, hquery);
+ break;
+ case AF_INET6:
+ hquery->remaining += 1;
+ ares_query(hquery->channel, s, C_IN, T_AAAA, host_callback, hquery);
+ break;
+ case AF_UNSPEC:
+ hquery->remaining += 2;
+ ares_query(hquery->channel, s, C_IN, T_A, host_callback, hquery);
+ ares_query(hquery->channel, s, C_IN, T_AAAA, host_callback, hquery);
+ break;
+ default: break;
+ }
+ if (is_s_allocated)
+ {
+ ares_free(s);
+ }
+ return 1;
+ }
+ else
+ {
+ assert(!hquery->ai->nodes);
+ return 0;
+ }
+}
+
+static int as_is_first(const struct host_query* hquery)
+{
+ char* p;
+ int ndots = 0;
+ size_t nname = strlen(hquery->name);
+ for (p = hquery->name; *p; p++)
+ {
+ if (*p == '.')
+ {
+ ndots++;
+ }
+ }
+ if (nname && hquery->name[nname-1] == '.')
+ {
+ /* prevent ARES_EBADNAME for valid FQDN, where ndots < channel->ndots */
+ return 1;
+ }
+ return ndots >= hquery->channel->ndots;
+}
diff --git a/deps/cares/src/ares_getenv.c b/deps/cares/src/lib/ares_getenv.c
similarity index 97%
rename from deps/cares/src/ares_getenv.c
rename to deps/cares/src/lib/ares_getenv.c
index 1b2e85d2be..f6e4dc2952 100644
--- a/deps/cares/src/ares_getenv.c
+++ b/deps/cares/src/lib/ares_getenv.c
@@ -22,9 +22,7 @@
char *ares_getenv(const char *name)
{
-#ifdef _WIN32_WCE
return NULL;
-#endif
}
#endif
diff --git a/deps/cares/src/ares_getenv.h b/deps/cares/src/lib/ares_getenv.h
similarity index 100%
rename from deps/cares/src/ares_getenv.h
rename to deps/cares/src/lib/ares_getenv.h
diff --git a/deps/cares/src/ares_gethostbyaddr.c b/deps/cares/src/lib/ares_gethostbyaddr.c
similarity index 97%
rename from deps/cares/src/ares_gethostbyaddr.c
rename to deps/cares/src/lib/ares_gethostbyaddr.c
index a8ca0f5744..c62d230d96 100644
--- a/deps/cares/src/ares_gethostbyaddr.c
+++ b/deps/cares/src/lib/ares_gethostbyaddr.c
@@ -24,14 +24,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_inet_net_pton.h"
@@ -208,7 +202,6 @@ static int file_lookup(struct ares_addr *addr, struct hostent **host)
strcat(PATH_HOSTS, WIN_PATH_HOSTS);
#elif defined(WATT32)
- extern const char *_w32_GetHostsFile (void);
const char *PATH_HOSTS = _w32_GetHostsFile();
if (!PATH_HOSTS)
diff --git a/deps/cares/src/ares_gethostbyname.c b/deps/cares/src/lib/ares_gethostbyname.c
similarity index 95%
rename from deps/cares/src/ares_gethostbyname.c
rename to deps/cares/src/lib/ares_gethostbyname.c
index 8187746bb1..e09363632e 100644
--- a/deps/cares/src/ares_gethostbyname.c
+++ b/deps/cares/src/lib/ares_gethostbyname.c
@@ -25,14 +25,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
#include <strings.h>
@@ -211,6 +205,13 @@ static void host_callback(void *arg, int status, int timeouts,
if (host && channel->nsort)
sort6_addresses(host, channel->sortlist, channel->nsort);
}
+ if (status == ARES_SUCCESS && host && host->h_addr_list[0] == NULL)
+ {
+ /* The query returned something but had no A/AAAA record
+ (even after potentially retrying AAAA with A)
+ so we should treat this as an error */
+ status = ARES_ENODATA;
+ }
end_hquery(hquery, status, host);
}
else if ((status == ARES_ENODATA || status == ARES_EBADRESP ||
@@ -251,7 +252,7 @@ static int fake_hostent(const char *name, int family,
struct in_addr in;
struct ares_in6_addr in6;
- if (family == AF_INET || family == AF_INET6)
+ if (family == AF_INET || family == AF_UNSPEC)
{
/* It only looks like an IP address if it's all numbers and dots. */
int numdots = 0, valid = 1;
@@ -267,15 +268,19 @@ static int fake_hostent(const char *name, int family,
}
/* if we don't have 3 dots, it is illegal
- * (although inet_addr doesn't think so).
+ * (although inet_pton doesn't think so).
*/
- if (numdots != 3 || !valid)
+ if (numdots != 3 || !valid) {
result = 0;
- else
- result = ((in.s_addr = inet_addr(name)) == INADDR_NONE ? 0 : 1);
+ } else {
+ result = (ares_inet_pton(AF_INET, name, &in) < 1 ? 0 : 1);
+ }
- if (result)
- family = AF_INET;
+ /*
+ * Set address family in case of failure,
+ * as we will try to convert it later afterwards
+ */
+ family = result ? AF_INET : AF_INET6;
}
if (family == AF_INET6)
result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1);
@@ -346,10 +351,6 @@ 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;
@@ -380,13 +381,17 @@ static int file_lookup(const char *name, int family, struct hostent **host)
strcat(PATH_HOSTS, WIN_PATH_HOSTS);
#elif defined(WATT32)
- extern const char *_w32_GetHostsFile (void);
const char *PATH_HOSTS = _w32_GetHostsFile();
if (!PATH_HOSTS)
return ARES_ENOTFOUND;
#endif
+ /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
+ if (ares__is_onion_domain(name))
+ return ARES_ENOTFOUND;
+
+
fp = fopen(PATH_HOSTS, "r");
if (!fp)
{
diff --git a/deps/cares/src/ares_getnameinfo.c b/deps/cares/src/lib/ares_getnameinfo.c
similarity index 98%
rename from deps/cares/src/ares_getnameinfo.c
rename to deps/cares/src/lib/ares_getnameinfo.c
index aa08941706..966919ac23 100644
--- a/deps/cares/src/ares_getnameinfo.c
+++ b/deps/cares/src/lib/ares_getnameinfo.c
@@ -31,14 +31,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_NET_IF_H
#include <net/if.h>
@@ -92,13 +86,13 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
if ((sa->sa_family == AF_INET) &&
(salen == sizeof(struct sockaddr_in)))
{
- addr = (struct sockaddr_in *)sa;
+ addr = CARES_INADDR_CAST(struct sockaddr_in *, sa);
port = addr->sin_port;
}
else if ((sa->sa_family == AF_INET6) &&
(salen == sizeof(struct sockaddr_in6)))
{
- addr6 = (struct sockaddr_in6 *)sa;
+ addr6 = CARES_INADDR_CAST(struct sockaddr_in6 *, sa);
port = addr6->sin6_port;
}
else
diff --git a/deps/cares/src/ares_getsock.c b/deps/cares/src/lib/ares_getsock.c
similarity index 100%
rename from deps/cares/src/ares_getsock.c
rename to deps/cares/src/lib/ares_getsock.c
diff --git a/deps/cares/src/ares_inet_net_pton.h b/deps/cares/src/lib/ares_inet_net_pton.h
similarity index 100%
rename from deps/cares/src/ares_inet_net_pton.h
rename to deps/cares/src/lib/ares_inet_net_pton.h
diff --git a/deps/cares/src/ares_init.c b/deps/cares/src/lib/ares_init.c
similarity index 97%
rename from deps/cares/src/ares_init.c
rename to deps/cares/src/lib/ares_init.c
index c2c00d6523..0917dce2fe 100644
--- a/deps/cares/src/ares_init.c
+++ b/deps/cares/src/lib/ares_init.c
@@ -33,14 +33,7 @@
#include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+#include "ares_nameser.h"
#if defined(ANDROID) || defined(__ANDROID__)
#include <sys/system_properties.h>
@@ -115,20 +108,6 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
int status = ARES_SUCCESS;
struct timeval now;
-#ifdef CURLDEBUG
- const char *env = getenv("CARES_MEMDEBUG");
-
- if (env)
- curl_memdebug(env);
- env = getenv("CARES_MEMLIMIT");
- if (env) {
- char *endptr;
- long num = strtol(env, &endptr, 10);
- if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
- curl_memlimit(num);
- }
-#endif
-
if (ares_library_initialized() != ARES_SUCCESS)
return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */
@@ -1486,6 +1465,57 @@ static int init_by_resolv_conf(ares_channel channel)
/* Catch the case when all the above checks fail (which happens when there
is no network card or the cable is unplugged) */
status = ARES_EFILE;
+#elif defined(__MVS__)
+
+ struct __res_state *res = 0;
+ int count4, count6;
+ __STATEEXTIPV6 *v6;
+ struct server_state *pserver
+ if (0 == res) {
+ int rc = res_init();
+ while (rc == -1 && h_errno == TRY_AGAIN) {
+ rc = res_init();
+ }
+ if (rc == -1) {
+ return ARES_ENOMEM;
+ }
+ res = __res();
+ }
+
+ v6 = res->__res_extIPv6;
+ count4 = res->nscount;
+ if (v6) {
+ count6 = v6->__stat_nscount;
+ } else {
+ count6 = 0;
+ }
+
+ nservers = count4 + count6;
+ servers = ares_malloc(nservers * sizeof(struct server_state));
+ if (!servers)
+ return ARES_ENOMEM;
+
+ memset(servers, 0, nservers * sizeof(struct server_state));
+
+ pserver = servers;
+ for (int i = 0; i < count4; ++i, ++pserver) {
+ struct sockaddr_in *addr_in = &(res->nsaddr_list[i]);
+ pserver->addr.addrV4.s_addr = addr_in->sin_addr.s_addr;
+ pserver->addr.family = AF_INET;
+ pserver->addr.udp_port = addr_in->sin_port;
+ pserver->addr.tcp_port = addr_in->sin_port;
+ }
+
+ for (int j = 0; j < count6; ++j, ++pserver) {
+ struct sockaddr_in6 *addr_in = &(v6->__stat_nsaddr_list[j]);
+ memcpy(&(pserver->addr.addr.addr6), &(addr_in->sin6_addr),
+ sizeof(addr_in->sin6_addr));
+ pserver->addr.family = AF_INET6;
+ pserver->addr.udp_port = addr_in->sin6_port;
+ pserver->addr.tcp_port = addr_in->sin6_port;
+ }
+
+ status = ARES_EOF;
#elif defined(__riscos__)
@@ -1543,8 +1573,6 @@ static int init_by_resolv_conf(ares_channel channel)
#elif defined(ANDROID) || defined(__ANDROID__)
unsigned int i;
- char propname[PROP_NAME_MAX];
- char propvalue[PROP_VALUE_MAX]="";
char **dns_servers;
char *domains;
size_t num_servers;
@@ -1587,6 +1615,8 @@ static int init_by_resolv_conf(ares_channel channel)
* 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) {
+ char propname[PROP_NAME_MAX];
+ char propvalue[PROP_VALUE_MAX]="";
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) {
@@ -1611,7 +1641,8 @@ static int init_by_resolv_conf(ares_channel channel)
if (channel->nservers == -1) {
union res_sockaddr_union addr[MAXNS];
int nscount = res_getservers(&res, addr, MAXNS);
- for (int i = 0; i < nscount; ++i) {
+ int i;
+ for (i = 0; i < nscount; ++i) {
char str[INET6_ADDRSTRLEN];
int config_status;
sa_family_t family = addr[i].sin.sin_family;
@@ -1634,16 +1665,18 @@ static int init_by_resolv_conf(ares_channel channel)
int entries = 0;
while ((entries < MAXDNSRCH) && res.dnsrch[entries])
entries++;
-
- channel->domains = ares_malloc(entries * sizeof(char *));
- if (!channel->domains) {
- status = ARES_ENOMEM;
- } else {
- channel->ndomains = entries;
- for (int i = 0; i < channel->ndomains; ++i) {
- channel->domains[i] = ares_strdup(res.dnsrch[i]);
- if (!channel->domains[i])
- status = ARES_ENOMEM;
+ if(entries) {
+ channel->domains = ares_malloc(entries * sizeof(char *));
+ if (!channel->domains) {
+ status = ARES_ENOMEM;
+ } else {
+ int i;
+ channel->ndomains = entries;
+ for (i = 0; i < channel->ndomains; ++i) {
+ channel->domains[i] = ares_strdup(res.dnsrch[i]);
+ if (!channel->domains[i])
+ status = ARES_ENOMEM;
+ }
}
}
}
@@ -2024,6 +2057,7 @@ static int config_lookup(ares_channel channel, const char *str,
{
char lookups[3], *l;
const char *vqualifier p;
+ int found;
if (altbindch == NULL)
altbindch = bindch;
@@ -2034,17 +2068,21 @@ static int config_lookup(ares_channel channel, const char *str,
*/
l = lookups;
p = str;
+ found = 0;
while (*p)
{
if ((*p == *bindch || *p == *altbindch || *p == *filech) && l < lookups + 2) {
if (*p == *bindch || *p == *altbindch) *l++ = 'b';
else *l++ = 'f';
+ found = 1;
}
while (*p && !ISSPACE(*p) && (*p != ','))
p++;
while (*p && (ISSPACE(*p) || (*p == ',')))
p++;
}
+ if (!found)
+ return ARES_ENOTINITIALIZED;
*l = '\0';
channel->lookups = ares_strdup(lookups);
return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
@@ -2418,9 +2456,9 @@ static int ip_addr(const char *ipbuf, ares_ssize_t len, struct in_addr *addr)
if (len > 15)
return -1;
- addr->s_addr = inet_addr(ipbuf);
- if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
+ if (ares_inet_pton(AF_INET, ipbuf, addr) < 1)
return -1;
+
return 0;
}
@@ -2477,9 +2515,10 @@ static void randomize_key(unsigned char* key,int key_data_len)
randomized = 1;
}
#else /* !WIN32 */
-#ifdef RANDOM_FILE
- FILE *f = fopen(RANDOM_FILE, "rb");
+#ifdef CARES_RANDOM_FILE
+ FILE *f = fopen(CARES_RANDOM_FILE, "rb");
if(f) {
+ setvbuf(f, NULL, _IONBF, 0);
counter = aresx_uztosi(fread(key, 1, key_data_len, f));
fclose(f);
}
diff --git a/deps/cares/src/ares_iphlpapi.h b/deps/cares/src/lib/ares_iphlpapi.h
similarity index 100%
rename from deps/cares/src/ares_iphlpapi.h
rename to deps/cares/src/lib/ares_iphlpapi.h
diff --git a/deps/cares/src/ares_ipv6.h b/deps/cares/src/lib/ares_ipv6.h
similarity index 94%
rename from deps/cares/src/ares_ipv6.h
rename to deps/cares/src/lib/ares_ipv6.h
index b0017f16c7..fdbc21fe8f 100644
--- a/deps/cares/src/ares_ipv6.h
+++ b/deps/cares/src/lib/ares_ipv6.h
@@ -32,6 +32,13 @@ struct sockaddr_in6
};
#endif
+typedef union
+{
+ struct sockaddr sa;
+ struct sockaddr_in sa4;
+ struct sockaddr_in6 sa6;
+} ares_sockaddr;
+
#ifndef HAVE_STRUCT_ADDRINFO
struct addrinfo
{
diff --git a/deps/cares/src/ares_library_init.c b/deps/cares/src/lib/ares_library_init.c
similarity index 94%
rename from deps/cares/src/ares_library_init.c
rename to deps/cares/src/lib/ares_library_init.c
index 67563499be..e0055d44a1 100644
--- a/deps/cares/src/ares_library_init.c
+++ b/deps/cares/src/lib/ares_library_init.c
@@ -40,13 +40,18 @@ static unsigned int ares_initialized;
static int ares_init_flags;
/* library-private global vars with visibility across the whole library */
+
+/* Some systems may return either NULL or a valid pointer on malloc(0). c-ares should
+ * never call malloc(0) so lets return NULL so we're more likely to find an issue if it
+ * were to occur. */
+
+static void *default_malloc(size_t size) { if (size == 0) { return NULL; } return malloc(size); }
+
#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
diff --git a/deps/cares/src/ares_library_init.h b/deps/cares/src/lib/ares_library_init.h
similarity index 98%
rename from deps/cares/src/ares_library_init.h
rename to deps/cares/src/lib/ares_library_init.h
index 2a2ba118b5..b3896d9f7b 100644
--- a/deps/cares/src/ares_library_init.h
+++ b/deps/cares/src/lib/ares_library_init.h
@@ -23,7 +23,7 @@
#ifdef USE_WINSOCK
#include <iphlpapi.h>
-#include <ares_iphlpapi.h>
+#include "ares_iphlpapi.h"
typedef DWORD (WINAPI *fpGetNetworkParams_t) (FIXED_INFO*, DWORD*);
typedef BOOLEAN (APIENTRY *fpSystemFunction036_t) (void*, ULONG);
diff --git a/deps/cares/src/ares_llist.c b/deps/cares/src/lib/ares_llist.c
similarity index 100%
rename from deps/cares/src/ares_llist.c
rename to deps/cares/src/lib/ares_llist.c
diff --git a/deps/cares/src/ares_llist.h b/deps/cares/src/lib/ares_llist.h
similarity index 100%
rename from deps/cares/src/ares_llist.h
rename to deps/cares/src/lib/ares_llist.h
diff --git a/deps/cares/src/ares_mkquery.c b/deps/cares/src/lib/ares_mkquery.c
similarity index 100%
rename from deps/cares/src/ares_mkquery.c
rename to deps/cares/src/lib/ares_mkquery.c
diff --git a/deps/cares/src/lib/ares_nameser.h b/deps/cares/src/lib/ares_nameser.h
new file mode 100644
index 0000000000..5270e5a3a6
--- /dev/null
+++ b/deps/cares/src/lib/ares_nameser.h
@@ -0,0 +1,482 @@
+
+#ifndef ARES_NAMESER_H
+#define ARES_NAMESER_H
+
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
+#endif
+
+/* ============================================================================
+ * arpa/nameser.h may or may not provide ALL of the below defines, so check
+ * each one individually and set if not
+ * ============================================================================
+ */
+
+#ifndef NS_PACKETSZ
+# define NS_PACKETSZ 512 /* maximum packet size */
+#endif
+
+#ifndef NS_MAXDNAME
+# define NS_MAXDNAME 256 /* maximum domain name */
+#endif
+
+#ifndef NS_MAXCDNAME
+# define NS_MAXCDNAME 255 /* maximum compressed domain name */
+#endif
+
+#ifndef NS_MAXLABEL
+# define NS_MAXLABEL 63
+#endif
+
+#ifndef NS_HFIXEDSZ
+# define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */
+#endif
+
+#ifndef NS_QFIXEDSZ
+# define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */
+#endif
+
+#ifndef NS_RRFIXEDSZ
+# define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
+#endif
+
+#ifndef NS_INT16SZ
+# define NS_INT16SZ 2
+#endif
+
+#ifndef NS_INADDRSZ
+# define NS_INADDRSZ 4
+#endif
+
+#ifndef NS_IN6ADDRSZ
+# define NS_IN6ADDRSZ 16
+#endif
+
+#ifndef NS_CMPRSFLGS
+# define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */
+#endif
+
+#ifndef NS_DEFAULTPORT
+# define NS_DEFAULTPORT 53 /* For both TCP and UDP. */
+#endif
+
+/* ============================================================================
+ * arpa/nameser.h should provide these enumerations always, so if not found,
+ * provide them
+ * ============================================================================
+ */
+#ifndef HAVE_ARPA_NAMESER_H
+
+typedef enum __ns_class {
+ ns_c_invalid = 0, /* Cookie. */
+ ns_c_in = 1, /* Internet. */
+ ns_c_2 = 2, /* unallocated/unsupported. */
+ ns_c_chaos = 3, /* MIT Chaos-net. */
+ ns_c_hs = 4, /* MIT Hesiod. */
+ /* Query class values which do not appear in resource records */
+ ns_c_none = 254, /* for prereq. sections in update requests */
+ ns_c_any = 255, /* Wildcard match. */
+ ns_c_max = 65536
+} ns_class;
+
+typedef enum __ns_type {
+ ns_t_invalid = 0, /* Cookie. */
+ ns_t_a = 1, /* Host address. */
+ ns_t_ns = 2, /* Authoritative server. */
+ ns_t_md = 3, /* Mail destination. */
+ ns_t_mf = 4, /* Mail forwarder. */
+ ns_t_cname = 5, /* Canonical name. */
+ ns_t_soa = 6, /* Start of authority zone. */
+ ns_t_mb = 7, /* Mailbox domain name. */
+ ns_t_mg = 8, /* Mail group member. */
+ ns_t_mr = 9, /* Mail rename name. */
+ ns_t_null = 10, /* Null resource record. */
+ ns_t_wks = 11, /* Well known service. */
+ ns_t_ptr = 12, /* Domain name pointer. */
+ ns_t_hinfo = 13, /* Host information. */
+ ns_t_minfo = 14, /* Mailbox information. */
+ ns_t_mx = 15, /* Mail routing information. */
+ ns_t_txt = 16, /* Text strings. */
+ ns_t_rp = 17, /* Responsible person. */
+ ns_t_afsdb = 18, /* AFS cell database. */
+ ns_t_x25 = 19, /* X_25 calling address. */
+ ns_t_isdn = 20, /* ISDN calling address. */
+ ns_t_rt = 21, /* Router. */
+ ns_t_nsap = 22, /* NSAP address. */
+ ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */
+ ns_t_sig = 24, /* Security signature. */
+ ns_t_key = 25, /* Security key. */
+ ns_t_px = 26, /* X.400 mail mapping. */
+ ns_t_gpos = 27, /* Geographical position (withdrawn). */
+ ns_t_aaaa = 28, /* Ip6 Address. */
+ ns_t_loc = 29, /* Location Information. */
+ ns_t_nxt = 30, /* Next domain (security). */
+ ns_t_eid = 31, /* Endpoint identifier. */
+ ns_t_nimloc = 32, /* Nimrod Locator. */
+ ns_t_srv = 33, /* Server Selection. */
+ ns_t_atma = 34, /* ATM Address */
+ ns_t_naptr = 35, /* Naming Authority PoinTeR */
+ ns_t_kx = 36, /* Key Exchange */
+ ns_t_cert = 37, /* Certification record */
+ ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */
+ ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */
+ ns_t_sink = 40, /* Kitchen sink (experimentatl) */
+ ns_t_opt = 41, /* EDNS0 option (meta-RR) */
+ ns_t_apl = 42, /* Address prefix list (RFC3123) */
+ ns_t_ds = 43, /* Delegation Signer (RFC4034) */
+ ns_t_sshfp = 44, /* SSH Key Fingerprint (RFC4255) */
+ ns_t_rrsig = 46, /* Resource Record Signature (RFC4034) */
+ ns_t_nsec = 47, /* Next Secure (RFC4034) */
+ ns_t_dnskey = 48, /* DNS Public Key (RFC4034) */
+ ns_t_tkey = 249, /* Transaction key */
+ ns_t_tsig = 250, /* Transaction signature. */
+ ns_t_ixfr = 251, /* Incremental zone transfer. */
+ ns_t_axfr = 252, /* Transfer zone of authority. */
+ ns_t_mailb = 253, /* Transfer mailbox records. */
+ ns_t_maila = 254, /* Transfer mail agent records. */
+ ns_t_any = 255, /* Wildcard match. */
+ ns_t_zxfr = 256, /* BIND-specific, nonstandard. */
+ ns_t_caa = 257, /* Certification Authority Authorization. */
+ ns_t_max = 65536
+} ns_type;
+
+typedef enum __ns_opcode {
+ ns_o_query = 0, /* Standard query. */
+ ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */
+ ns_o_status = 2, /* Name server status query (unsupported). */
+ /* Opcode 3 is undefined/reserved. */
+ ns_o_notify = 4, /* Zone change notification. */
+ ns_o_update = 5, /* Zone update message. */
+ ns_o_max = 6
+} ns_opcode;
+
+typedef enum __ns_rcode {
+ ns_r_noerror = 0, /* No error occurred. */
+ ns_r_formerr = 1, /* Format error. */
+ ns_r_servfail = 2, /* Server failure. */
+ ns_r_nxdomain = 3, /* Name error. */
+ ns_r_notimpl = 4, /* Unimplemented. */
+ ns_r_refused = 5, /* Operation refused. */
+ /* these are for BIND_UPDATE */
+ ns_r_yxdomain = 6, /* Name exists */
+ ns_r_yxrrset = 7, /* RRset exists */
+ ns_r_nxrrset = 8, /* RRset does not exist */
+ ns_r_notauth = 9, /* Not authoritative for zone */
+ ns_r_notzone = 10, /* Zone of record different from zone section */
+ ns_r_max = 11,
+ /* The following are TSIG extended errors */
+ ns_r_badsig = 16,
+ ns_r_badkey = 17,
+ ns_r_badtime = 18
+} ns_rcode;
+
+#endif /* HAVE_ARPA_NAMESER_H */
+
+
+/* ============================================================================
+ * arpa/nameser_compat.h typically sets these. However on some systems
+ * arpa/nameser.h does, but may not set all of them. Lets conditionally
+ * define each
+ * ============================================================================
+ */
+
+#ifndef PACKETSZ
+# define PACKETSZ NS_PACKETSZ
+#endif
+
+#ifndef MAXDNAME
+# define MAXDNAME NS_MAXDNAME
+#endif
+
+#ifndef MAXCDNAME
+# define MAXCDNAME NS_MAXCDNAME
+#endif
+
+#ifndef MAXLABEL
+# define MAXLABEL NS_MAXLABEL
+#endif
+
+#ifndef HFIXEDSZ
+# define HFIXEDSZ NS_HFIXEDSZ
+#endif
+
+#ifndef QFIXEDSZ
+# define QFIXEDSZ NS_QFIXEDSZ
+#endif
+
+#ifndef RRFIXEDSZ
+# define RRFIXEDSZ NS_RRFIXEDSZ
+#endif
+
+#ifndef INDIR_MASK
+# define INDIR_MASK NS_CMPRSFLGS
+#endif
+
+#ifndef NAMESERVER_PORT
+# define NAMESERVER_PORT NS_DEFAULTPORT
+#endif
+
+
+/* opcodes */
+#ifndef O_QUERY
+# define O_QUERY 0 /* ns_o_query */
+#endif
+#ifndef O_IQUERY
+# define O_IQUERY 1 /* ns_o_iquery */
+#endif
+#ifndef O_STATUS
+# define O_STATUS 2 /* ns_o_status */
+#endif
+#ifndef O_NOTIFY
+# define O_NOTIFY 4 /* ns_o_notify */
+#endif
+#ifndef O_UPDATE
+# define O_UPDATE 5 /* ns_o_update */
+#endif
+
+
+/* response codes */
+#ifndef SERVFAIL
+# define SERVFAIL ns_r_servfail
+#endif
+#ifndef NOTIMP
+# define NOTIMP ns_r_notimpl
+#endif
+#ifndef REFUSED
+# define REFUSED ns_r_refused
+#endif
+#if defined(_WIN32) && !defined(HAVE_ARPA_NAMESER_COMPAT_H) && defined(NOERROR)
+# undef NOERROR /* it seems this is already defined in winerror.h */
+#endif
+#ifndef NOERROR
+# define NOERROR ns_r_noerror
+#endif
+#ifndef FORMERR
+# define FORMERR ns_r_formerr
+#endif
+#ifndef NXDOMAIN
+# define NXDOMAIN ns_r_nxdomain
+#endif
+/* Non-standard response codes, use numeric values */
+#ifndef YXDOMAIN
+# define YXDOMAIN 6 /* ns_r_yxdomain */
+#endif
+#ifndef YXRRSET
+# define YXRRSET 7 /* ns_r_yxrrset */
+#endif
+#ifndef NXRRSET
+# define NXRRSET 8 /* ns_r_nxrrset */
+#endif
+#ifndef NOTAUTH
+# define NOTAUTH 9 /* ns_r_notauth */
+#endif
+#ifndef NOTZONE
+# define NOTZONE 10 /* ns_r_notzone */
+#endif
+#ifndef TSIG_BADSIG
+# define TSIG_BADSIG 16 /* ns_r_badsig */
+#endif
+#ifndef TSIG_BADKEY
+# define TSIG_BADKEY 17 /* ns_r_badkey */
+#endif
+#ifndef TSIG_BADTIME
+# define TSIG_BADTIME 18 /* ns_r_badtime */
+#endif
+
+
+/* classes */
+#ifndef C_IN
+# define C_IN 1 /* ns_c_in */
+#endif
+#ifndef C_CHAOS
+# define C_CHAOS 3 /* ns_c_chaos */
+#endif
+#ifndef C_HS
+# define C_HS 4 /* ns_c_hs */
+#endif
+#ifndef C_NONE
+# define C_NONE 254 /* ns_c_none */
+#endif
+#ifndef C_ANY
+# define C_ANY 255 /* ns_c_any */
+#endif
+
+
+/* types */
+#ifndef T_A
+# define T_A 1 /* ns_t_a */
+#endif
+#ifndef T_NS
+# define T_NS 2 /* ns_t_ns */
+#endif
+#ifndef T_MD
+# define T_MD 3 /* ns_t_md */
+#endif
+#ifndef T_MF
+# define T_MF 4 /* ns_t_mf */
+#endif
+#ifndef T_CNAME
+# define T_CNAME 5 /* ns_t_cname */
+#endif
+#ifndef T_SOA
+# define T_SOA 6 /* ns_t_soa */
+#endif
+#ifndef T_MB
+# define T_MB 7 /* ns_t_mb */
+#endif
+#ifndef T_MG
+# define T_MG 8 /* ns_t_mg */
+#endif
+#ifndef T_MR
+# define T_MR 9 /* ns_t_mr */
+#endif
+#ifndef T_NULL
+# define T_NULL 10 /* ns_t_null */
+#endif
+#ifndef T_WKS
+# define T_WKS 11 /* ns_t_wks */
+#endif
+#ifndef T_PTR
+# define T_PTR 12 /* ns_t_ptr */
+#endif
+#ifndef T_HINFO
+# define T_HINFO 13 /* ns_t_hinfo */
+#endif
+#ifndef T_MINFO
+# define T_MINFO 14 /* ns_t_minfo */
+#endif
+#ifndef T_MX
+# define T_MX 15 /* ns_t_mx */
+#endif
+#ifndef T_TXT
+# define T_TXT 16 /* ns_t_txt */
+#endif
+#ifndef T_RP
+# define T_RP 17 /* ns_t_rp */
+#endif
+#ifndef T_AFSDB
+# define T_AFSDB 18 /* ns_t_afsdb */
+#endif
+#ifndef T_X25
+# define T_X25 19 /* ns_t_x25 */
+#endif
+#ifndef T_ISDN
+# define T_ISDN 20 /* ns_t_isdn */
+#endif
+#ifndef T_RT
+# define T_RT 21 /* ns_t_rt */
+#endif
+#ifndef T_NSAP
+# define T_NSAP 22 /* ns_t_nsap */
+#endif
+#ifndef T_NSAP_PTR
+# define T_NSAP_PTR 23 /* ns_t_nsap_ptr */
+#endif
+#ifndef T_SIG
+# define T_SIG 24 /* ns_t_sig */
+#endif
+#ifndef T_KEY
+# define T_KEY 25 /* ns_t_key */
+#endif
+#ifndef T_PX
+# define T_PX 26 /* ns_t_px */
+#endif
+#ifndef T_GPOS
+# define T_GPOS 27 /* ns_t_gpos */
+#endif
+#ifndef T_AAAA
+# define T_AAAA 28 /* ns_t_aaaa */
+#endif
+#ifndef T_LOC
+# define T_LOC 29 /* ns_t_loc */
+#endif
+#ifndef T_NXT
+# define T_NXT 30 /* ns_t_nxt */
+#endif
+#ifndef T_EID
+# define T_EID 31 /* ns_t_eid */
+#endif
+#ifndef T_NIMLOC
+# define T_NIMLOC 32 /* ns_t_nimloc */
+#endif
+#ifndef T_SRV
+# define T_SRV 33 /* ns_t_srv */
+#endif
+#ifndef T_ATMA
+# define T_ATMA 34 /* ns_t_atma */
+#endif
+#ifndef T_NAPTR
+# define T_NAPTR 35 /* ns_t_naptr */
+#endif
+#ifndef T_KX
+# define T_KX 36 /* ns_t_kx */
+#endif
+#ifndef T_CERT
+# define T_CERT 37 /* ns_t_cert */
+#endif
+#ifndef T_A6
+# define T_A6 38 /* ns_t_a6 */
+#endif
+#ifndef T_DNAME
+# define T_DNAME 39 /* ns_t_dname */
+#endif
+#ifndef T_SINK
+# define T_SINK 40 /* ns_t_sink */
+#endif
+#ifndef T_OPT
+# define T_OPT 41 /* ns_t_opt */
+#endif
+#ifndef T_APL
+# define T_APL 42 /* ns_t_apl */
+#endif
+#ifndef T_DS
+# define T_DS 43 /* ns_t_ds */
+#endif
+#ifndef T_SSHFP
+# define T_SSHFP 44 /* ns_t_sshfp */
+#endif
+#ifndef T_RRSIG
+# define T_RRSIG 46 /* ns_t_rrsig */
+#endif
+#ifndef T_NSEC
+# define T_NSEC 47 /* ns_t_nsec */
+#endif
+#ifndef T_DNSKEY
+# define T_DNSKEY 48 /* ns_t_dnskey */
+#endif
+#ifndef T_TKEY
+# define T_TKEY 249 /* ns_t_tkey */
+#endif
+#ifndef T_TSIG
+# define T_TSIG 250 /* ns_t_tsig */
+#endif
+#ifndef T_IXFR
+# define T_IXFR 251 /* ns_t_ixfr */
+#endif
+#ifndef T_AXFR
+# define T_AXFR 252 /* ns_t_axfr */
+#endif
+#ifndef T_MAILB
+# define T_MAILB 253 /* ns_t_mailb */
+#endif
+#ifndef T_MAILA
+# define T_MAILA 254 /* ns_t_maila */
+#endif
+#ifndef T_ANY
+# define T_ANY 255 /* ns_t_any */
+#endif
+#ifndef T_ZXFR
+# define T_ZXFR 256 /* ns_t_zxfr */
+#endif
+#ifndef T_CAA
+# define T_CAA 257 /* ns_t_caa */
+#endif
+#ifndef T_MAX
+# define T_MAX 65536 /* ns_t_max */
+#endif
+
+
+#endif /* ARES_NAMESER_H */
diff --git a/deps/cares/src/ares_nowarn.c b/deps/cares/src/lib/ares_nowarn.c
similarity index 100%
rename from deps/cares/src/ares_nowarn.c
rename to deps/cares/src/lib/ares_nowarn.c
diff --git a/deps/cares/src/ares_nowarn.h b/deps/cares/src/lib/ares_nowarn.h
similarity index 100%
rename from deps/cares/src/ares_nowarn.h
rename to deps/cares/src/lib/ares_nowarn.h
diff --git a/deps/cares/src/ares_options.c b/deps/cares/src/lib/ares_options.c
similarity index 100%
rename from deps/cares/src/ares_options.c
rename to deps/cares/src/lib/ares_options.c
diff --git a/deps/cares/src/lib/ares_parse_a_reply.c b/deps/cares/src/lib/ares_parse_a_reply.c
new file mode 100644
index 0000000000..b08ac8760f
--- /dev/null
+++ b/deps/cares/src/lib/ares_parse_a_reply.c
@@ -0,0 +1,209 @@
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2019 by Andrew Selivanov
+ *
+ * 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"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#include "ares_nameser.h"
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_private.h"
+
+int ares_parse_a_reply(const unsigned char *abuf, int alen,
+ struct hostent **host,
+ struct ares_addrttl *addrttls, int *naddrttls)
+{
+ struct ares_addrinfo ai;
+ struct ares_addrinfo_node *next;
+ struct ares_addrinfo_cname *next_cname;
+ char **aliases = NULL;
+ char *question_hostname = NULL;
+ struct hostent *hostent = NULL;
+ struct in_addr *addrs = NULL;
+ int naliases = 0, naddrs = 0, alias = 0, i;
+ int cname_ttl = INT_MAX;
+ int status;
+
+ memset(&ai, 0, sizeof(ai));
+
+ status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, &ai);
+ if (status != ARES_SUCCESS)
+ {
+ ares_free(question_hostname);
+
+ if (naddrttls)
+ {
+ *naddrttls = 0;
+ }
+
+ return status;
+ }
+
+ hostent = ares_malloc(sizeof(struct hostent));
+ if (!hostent)
+ {
+ goto enomem;
+ }
+
+ next = ai.nodes;
+ while (next)
+ {
+ if (next->ai_family == AF_INET)
+ {
+ ++naddrs;
+ }
+ next = next->ai_next;
+ }
+
+ next_cname = ai.cnames;
+ while (next_cname)
+ {
+ if(next_cname->alias)
+ ++naliases;
+ next_cname = next_cname->next;
+ }
+
+ aliases = ares_malloc((naliases + 1) * sizeof(char *));
+ if (!aliases)
+ {
+ goto enomem;
+ }
+
+ if (naliases)
+ {
+ next_cname = ai.cnames;
+ while (next_cname)
+ {
+ if(next_cname->alias)
+ aliases[alias++] = ares_strdup(next_cname->alias);
+ if(next_cname->ttl < cname_ttl)
+ cname_ttl = next_cname->ttl;
+ next_cname = next_cname->next;
+ }
+ }
+
+ aliases[alias] = NULL;
+
+ hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *));
+ if (!hostent->h_addr_list)
+ {
+ goto enomem;
+ }
+
+ for (i = 0; i < naddrs + 1; ++i)
+ {
+ hostent->h_addr_list[i] = NULL;
+ }
+
+ if (ai.cnames)
+ {
+ hostent->h_name = ares_strdup(ai.cnames->name);
+ ares_free(question_hostname);
+ }
+ else
+ {
+ hostent->h_name = question_hostname;
+ }
+
+ hostent->h_aliases = aliases;
+ hostent->h_addrtype = AF_INET;
+ hostent->h_length = sizeof(struct in_addr);
+
+ if (naddrs)
+ {
+ addrs = ares_malloc(naddrs * sizeof(struct in_addr));
+ if (!addrs)
+ {
+ goto enomem;
+ }
+
+ i = 0;
+ next = ai.nodes;
+ while (next)
+ {
+ if (next->ai_family == AF_INET)
+ {
+ hostent->h_addr_list[i] = (char *)&addrs[i];
+ memcpy(hostent->h_addr_list[i],
+ &(CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr)->sin_addr),
+ sizeof(struct in_addr));
+ if (naddrttls && i < *naddrttls)
+ {
+ if (next->ai_ttl > cname_ttl)
+ addrttls[i].ttl = cname_ttl;
+ else
+ addrttls[i].ttl = next->ai_ttl;
+
+ memcpy(&addrttls[i].ipaddr,
+ &(CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr)->sin_addr),
+ sizeof(struct in_addr));
+ }
+ ++i;
+ }
+ next = next->ai_next;
+ }
+ if (i == 0)
+ {
+ ares_free(addrs);
+ }
+ }
+
+ if (host)
+ {
+ *host = hostent;
+ }
+ else
+ {
+ ares_free_hostent(hostent);
+ }
+
+ if (naddrttls)
+ {
+ /* Truncated to at most *naddrttls entries */
+ *naddrttls = (naddrs > *naddrttls)?*naddrttls:naddrs;
+ }
+
+ ares__freeaddrinfo_cnames(ai.cnames);
+ ares__freeaddrinfo_nodes(ai.nodes);
+ return ARES_SUCCESS;
+
+enomem:
+ ares_free(aliases);
+ ares_free(hostent);
+ ares__freeaddrinfo_cnames(ai.cnames);
+ ares__freeaddrinfo_nodes(ai.nodes);
+ ares_free(question_hostname);
+ return ARES_ENOMEM;
+}
diff --git a/deps/cares/src/lib/ares_parse_aaaa_reply.c b/deps/cares/src/lib/ares_parse_aaaa_reply.c
new file mode 100644
index 0000000000..6f4744a8dc
--- /dev/null
+++ b/deps/cares/src/lib/ares_parse_aaaa_reply.c
@@ -0,0 +1,212 @@
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright 2005 Dominick Meglio
+ * Copyright (C) 2019 by Andrew Selivanov
+ *
+ * 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"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#include "ares_nameser.h"
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_inet_net_pton.h"
+#include "ares_private.h"
+
+int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
+ struct hostent **host, struct ares_addr6ttl *addrttls,
+ int *naddrttls)
+{
+ struct ares_addrinfo ai;
+ struct ares_addrinfo_node *next;
+ struct ares_addrinfo_cname *next_cname;
+ char **aliases = NULL;
+ char *question_hostname = NULL;
+ struct hostent *hostent = NULL;
+ struct ares_in6_addr *addrs = NULL;
+ int naliases = 0, naddrs = 0, alias = 0, i;
+ int cname_ttl = INT_MAX;
+ int status;
+
+ memset(&ai, 0, sizeof(ai));
+
+ status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, &ai);
+ if (status != ARES_SUCCESS)
+ {
+ ares_free(question_hostname);
+
+ if (naddrttls)
+ {
+ *naddrttls = 0;
+ }
+
+ return status;
+ }
+
+ hostent = ares_malloc(sizeof(struct hostent));
+ if (!hostent)
+ {
+ goto enomem;
+ }
+
+ next = ai.nodes;
+ while (next)
+ {
+ if(next->ai_family == AF_INET6)
+ {
+ ++naddrs;
+ }
+ next = next->ai_next;
+ }
+
+ next_cname = ai.cnames;
+ while (next_cname)
+ {
+ if(next_cname->alias)
+ ++naliases;
+ next_cname = next_cname->next;
+ }
+
+ aliases = ares_malloc((naliases + 1) * sizeof(char *));
+ if (!aliases)
+ {
+ goto enomem;
+ }
+
+ if (naliases)
+ {
+ next_cname = ai.cnames;
+ while (next_cname)
+ {
+ if(next_cname->alias)
+ aliases[alias++] = ares_strdup(next_cname->alias);
+ if(next_cname->ttl < cname_ttl)
+ cname_ttl = next_cname->ttl;
+ next_cname = next_cname->next;
+ }
+ }
+
+ aliases[alias] = NULL;
+
+ hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *));
+ if (!hostent->h_addr_list)
+ {
+ goto enomem;
+ }
+
+ for (i = 0; i < naddrs + 1; ++i)
+ {
+ hostent->h_addr_list[i] = NULL;
+ }
+
+ if (ai.cnames)
+ {
+ hostent->h_name = ares_strdup(ai.cnames->name);
+ ares_free(question_hostname);
+ }
+ else
+ {
+ hostent->h_name = question_hostname;
+ }
+
+ hostent->h_aliases = aliases;
+ hostent->h_addrtype = AF_INET6;
+ hostent->h_length = sizeof(struct ares_in6_addr);
+
+ if (naddrs)
+ {
+ addrs = ares_malloc(naddrs * sizeof(struct ares_in6_addr));
+ if (!addrs)
+ {
+ goto enomem;
+ }
+
+ i = 0;
+ next = ai.nodes;
+ while (next)
+ {
+ if(next->ai_family == AF_INET6)
+ {
+ hostent->h_addr_list[i] = (char*)&addrs[i];
+ memcpy(hostent->h_addr_list[i],
+ &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
+ sizeof(struct ares_in6_addr));
+ if (naddrttls && i < *naddrttls)
+ {
+ if(next->ai_ttl > cname_ttl)
+ addrttls[i].ttl = cname_ttl;
+ else
+ addrttls[i].ttl = next->ai_ttl;
+
+ memcpy(&addrttls[i].ip6addr,
+ &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
+ sizeof(struct ares_in6_addr));
+ }
+ ++i;
+ }
+ next = next->ai_next;
+ }
+
+ if (i == 0)
+ {
+ ares_free(addrs);
+ }
+ }
+
+ if (host)
+ {
+ *host = hostent;
+ }
+ else
+ {
+ ares_free_hostent(hostent);
+ }
+
+ if (naddrttls)
+ {
+ /* Truncated to at most *naddrttls entries */
+ *naddrttls = (naddrs > *naddrttls)?*naddrttls:naddrs;
+ }
+
+ ares__freeaddrinfo_cnames(ai.cnames);
+ ares__freeaddrinfo_nodes(ai.nodes);
+ return ARES_SUCCESS;
+
+enomem:
+ ares_free(aliases);
+ ares_free(hostent);
+ ares__freeaddrinfo_cnames(ai.cnames);
+ ares__freeaddrinfo_nodes(ai.nodes);
+ ares_free(question_hostname);
+ return ARES_ENOMEM;
+}
diff --git a/deps/cares/src/lib/ares_parse_caa_reply.c b/deps/cares/src/lib/ares_parse_caa_reply.c
new file mode 100644
index 0000000000..f6d4d3c61f
--- /dev/null
+++ b/deps/cares/src/lib/ares_parse_caa_reply.c
@@ -0,0 +1,199 @@
+
+/* Copyright 2020 by <danny.sonnenschein@platynum.ch>
+ *
+ * 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"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#include "ares_nameser.h"
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_data.h"
+#include "ares_private.h"
+
+int
+ares_parse_caa_reply (const unsigned char *abuf, int alen,
+ struct ares_caa_reply **caa_out)
+{
+ unsigned int qdcount, ancount, i;
+ const unsigned char *aptr;
+ const unsigned char *strptr;
+ int status, rr_type, rr_class, rr_len;
+ long len;
+ char *hostname = NULL, *rr_name = NULL;
+ struct ares_caa_reply *caa_head = NULL;
+ struct ares_caa_reply *caa_last = NULL;
+ struct ares_caa_reply *caa_curr;
+
+ /* Set *caa_out to NULL for all failure cases. */
+ *caa_out = NULL;
+
+ /* Give up if abuf doesn't have room for a header. */
+ if (alen < HFIXEDSZ)
+ return ARES_EBADRESP;
+
+ /* Fetch the question and answer count from the header. */
+ qdcount = DNS_HEADER_QDCOUNT (abuf);
+ ancount = DNS_HEADER_ANCOUNT (abuf);
+ if (qdcount != 1)
+ return ARES_EBADRESP;
+ if (ancount == 0)
+ return ARES_ENODATA;
+
+ /* Expand the name from the question, and skip past the question. */
+ aptr = abuf + HFIXEDSZ;
+ status = ares_expand_name (aptr, abuf, alen, &hostname, &len);
+ if (status != ARES_SUCCESS)
+ return status;
+
+ if (aptr + len + QFIXEDSZ > abuf + alen)
+ {
+ ares_free (hostname);
+ return ARES_EBADRESP;
+ }
+ aptr += len + QFIXEDSZ;
+
+ /* Examine each answer resource record (RR) in turn. */
+ for (i = 0; i < ancount; i++)
+ {
+ /* Decode the RR up to the data field. */
+ status = ares_expand_name (aptr, abuf, alen, &rr_name, &len);
+ if (status != ARES_SUCCESS)
+ {
+ break;
+ }
+ aptr += len;
+ if (aptr + RRFIXEDSZ > abuf + alen)
+ {
+ status = ARES_EBADRESP;
+ break;
+ }
+ rr_type = DNS_RR_TYPE (aptr);
+ rr_class = DNS_RR_CLASS (aptr);
+ rr_len = DNS_RR_LEN (aptr);
+ aptr += RRFIXEDSZ;
+ if (aptr + rr_len > abuf + alen)
+ {
+ status = ARES_EBADRESP;
+ break;
+ }
+
+ /* Check if we are really looking at a CAA record */
+ if ((rr_class == C_IN || rr_class == C_CHAOS) && rr_type == T_CAA)
+ {
+ strptr = aptr;
+
+ /* Allocate storage for this CAA answer appending it to the list */
+ caa_curr = ares_malloc_data(ARES_DATATYPE_CAA_REPLY);
+ if (!caa_curr)
+ {
+ status = ARES_ENOMEM;
+ break;
+ }
+ if (caa_last)
+ {
+ caa_last->next = caa_curr;
+ }
+ else
+ {
+ caa_head = caa_curr;
+ }
+ caa_last = caa_curr;
+ if (rr_len < 2)
+ {
+ status = ARES_EBADRESP;
+ break;
+ }
+ caa_curr->critical = (int)*strptr++;
+ caa_curr->plength = (int)*strptr++;
+ if (caa_curr->plength <= 0 || (int)caa_curr->plength >= rr_len - 2)
+ {
+ status = ARES_EBADRESP;
+ break;
+ }
+ caa_curr->property = ares_malloc (caa_curr->plength + 1/* Including null byte */);
+ if (caa_curr->property == NULL)
+ {
+ status = ARES_ENOMEM;
+ break;
+ }
+ memcpy ((char *) caa_curr->property, strptr, caa_curr->plength);
+ /* Make sure we NULL-terminate */
+ caa_curr->property[caa_curr->plength] = 0;
+ strptr += caa_curr->plength;
+
+ caa_curr->length = rr_len - caa_curr->plength - 2;
+ if (caa_curr->length <= 0)
+ {
+ status = ARES_EBADRESP;
+ break;
+ }
+ caa_curr->value = ares_malloc (caa_curr->length + 1/* Including null byte */);
+ if (caa_curr->value == NULL)
+ {
+ status = ARES_ENOMEM;
+ break;
+ }
+ memcpy ((char *) caa_curr->value, strptr, caa_curr->length);
+ /* Make sure we NULL-terminate */
+ caa_curr->value[caa_curr->length] = 0;
+ }
+
+ /* Propagate any failures */
+ if (status != ARES_SUCCESS)
+ {
+ break;
+ }
+
+ /* Don't lose memory in the next iteration */
+ ares_free (rr_name);
+ rr_name = NULL;
+
+ /* Move on to the next record */
+ aptr += rr_len;
+ }
+
+ if (hostname)
+ ares_free (hostname);
+ if (rr_name)
+ ares_free (rr_name);
+
+ /* clean up on error */
+ if (status != ARES_SUCCESS)
+ {
+ if (caa_head)
+ ares_free_data (caa_head);
+ return status;
+ }
+
+ /* everything looks fine, return the data */
+ *caa_out = caa_head;
+
+ return ARES_SUCCESS;
+}
diff --git a/deps/cares/src/ares_parse_mx_reply.c b/deps/cares/src/lib/ares_parse_mx_reply.c
similarity index 96%
rename from deps/cares/src/ares_parse_mx_reply.c
rename to deps/cares/src/lib/ares_parse_mx_reply.c
index e6336473e0..a497f55873 100644
--- a/deps/cares/src/ares_parse_mx_reply.c
+++ b/deps/cares/src/lib/ares_parse_mx_reply.c
@@ -26,14 +26,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
diff --git a/deps/cares/src/ares_parse_naptr_reply.c b/deps/cares/src/lib/ares_parse_naptr_reply.c
similarity index 94%
rename from deps/cares/src/ares_parse_naptr_reply.c
rename to deps/cares/src/lib/ares_parse_naptr_reply.c
index a14c226a9e..dd984c0fea 100644
--- a/deps/cares/src/ares_parse_naptr_reply.c
+++ b/deps/cares/src/lib/ares_parse_naptr_reply.c
@@ -26,25 +26,14 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
#include "ares_data.h"
#include "ares_private.h"
-/* AIX portability check */
-#ifndef T_NAPTR
- #define T_NAPTR 35 /* naming authority pointer */
-#endif
-
int
ares_parse_naptr_reply (const unsigned char *abuf, int alen,
struct ares_naptr_reply **naptr_out)
diff --git a/deps/cares/src/ares_parse_ns_reply.c b/deps/cares/src/lib/ares_parse_ns_reply.c
similarity index 95%
rename from deps/cares/src/ares_parse_ns_reply.c
rename to deps/cares/src/lib/ares_parse_ns_reply.c
index 7bb51429db..47d12994c9 100644
--- a/deps/cares/src/ares_parse_ns_reply.c
+++ b/deps/cares/src/lib/ares_parse_ns_reply.c
@@ -29,14 +29,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
@@ -68,7 +62,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
/* Expand the name from the question, and skip past the question. */
aptr = abuf + HFIXEDSZ;
- status = ares__expand_name_for_response( aptr, abuf, alen, &hostname, &len);
+ status = ares__expand_name_for_response( aptr, abuf, alen, &hostname, &len, 0);
if ( status != ARES_SUCCESS )
return status;
if ( aptr + len + QFIXEDSZ > abuf + alen )
@@ -91,7 +85,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
for ( i = 0; i < ( int ) ancount; i++ )
{
/* Decode the RR up to the data field. */
- status = ares__expand_name_for_response( aptr, abuf, alen, &rr_name, &len );
+ status = ares__expand_name_for_response( aptr, abuf, alen, &rr_name, &len, 0);
if ( status != ARES_SUCCESS )
break;
aptr += len;
@@ -116,7 +110,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
{
/* Decode the RR data and add it to the nameservers list */
status = ares__expand_name_for_response( aptr, abuf, alen, &rr_data,
- &len);
+ &len, 1);
if ( status != ARES_SUCCESS )
{
ares_free(rr_name);
diff --git a/deps/cares/src/ares_parse_ptr_reply.c b/deps/cares/src/lib/ares_parse_ptr_reply.c
similarity index 74%
rename from deps/cares/src/ares_parse_ptr_reply.c
rename to deps/cares/src/lib/ares_parse_ptr_reply.c
index 29e22cb17b..ae78edf195 100644
--- a/deps/cares/src/ares_parse_ptr_reply.c
+++ b/deps/cares/src/lib/ares_parse_ptr_reply.c
@@ -22,14 +22,8 @@
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
# include <strings.h>
@@ -48,7 +42,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
long len;
const unsigned char *aptr;
char *ptrname, *hostname, *rr_name, *rr_data;
- struct hostent *hostent;
+ struct hostent *hostent = NULL;
int aliascnt = 0;
int alias_alloc = 8;
char ** aliases;
@@ -69,7 +63,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
/* Expand the name from the question, and skip past the question. */
aptr = abuf + HFIXEDSZ;
- status = ares__expand_name_for_response(aptr, abuf, alen, &ptrname, &len);
+ status = ares__expand_name_for_response(aptr, abuf, alen, &ptrname, &len, 0);
if (status != ARES_SUCCESS)
return status;
if (aptr + len + QFIXEDSZ > abuf + alen)
@@ -90,7 +84,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
for (i = 0; i < (int)ancount; i++)
{
/* Decode the RR up to the data field. */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
+ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len, 0);
if (status != ARES_SUCCESS)
break;
aptr += len;
@@ -116,7 +110,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
{
/* Decode the RR data and set hostname to it. */
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
- &len);
+ &len, 1);
if (status != ARES_SUCCESS)
{
ares_free(rr_name);
@@ -152,7 +146,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
{
/* Decode the RR data and replace ptrname with it. */
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
- &len);
+ &len, 1);
if (status != ARES_SUCCESS)
{
ares_free(rr_name);
@@ -175,41 +169,54 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
status = ARES_ENODATA;
if (status == ARES_SUCCESS)
{
- /* We got our answer. Allocate memory to build the host entry. */
- hostent = ares_malloc(sizeof(struct hostent));
- if (hostent)
- {
- hostent->h_addr_list = ares_malloc(2 * sizeof(char *));
- if (hostent->h_addr_list)
- {
- hostent->h_addr_list[0] = ares_malloc(addrlen);
- if (hostent->h_addr_list[0])
- {
- hostent->h_aliases = ares_malloc((aliascnt+1) * sizeof (char *));
- if (hostent->h_aliases)
- {
- /* Fill in the hostent and return successfully. */
- hostent->h_name = hostname;
- for (i=0 ; i<aliascnt ; i++)
- hostent->h_aliases[i] = aliases[i];
- hostent->h_aliases[aliascnt] = NULL;
- hostent->h_addrtype = aresx_sitoss(family);
- hostent->h_length = aresx_sitoss(addrlen);
- memcpy(hostent->h_addr_list[0], addr, addrlen);
- hostent->h_addr_list[1] = NULL;
- *host = hostent;
- ares_free(aliases);
- ares_free(ptrname);
- return ARES_SUCCESS;
- }
- ares_free(hostent->h_addr_list[0]);
- }
- ares_free(hostent->h_addr_list);
- }
- ares_free(hostent);
- }
+ /* If we don't reach the end, we must have failed due to out of memory */
status = ARES_ENOMEM;
+
+ /* We got our answer. Allocate memory to build the host entry. */
+ hostent = ares_malloc(sizeof(*hostent));
+ if (!hostent)
+ goto fail;
+
+ /* If we don't memset here, cleanups may fail */
+ memset(hostent, 0, sizeof(*hostent));
+
+ hostent->h_addr_list = ares_malloc(2 * sizeof(char *));
+ if (!hostent->h_addr_list)
+ goto fail;
+
+
+ if (addr && addrlen) {
+ hostent->h_addr_list[0] = ares_malloc(addrlen);
+ if (!hostent->h_addr_list[0])
+ goto fail;
+ } else {
+ hostent->h_addr_list[0] = NULL;
+ }
+
+ hostent->h_aliases = ares_malloc((aliascnt+1) * sizeof (char *));
+ if (!hostent->h_aliases)
+ goto fail;
+
+ /* Fill in the hostent and return successfully. */
+ hostent->h_name = hostname;
+ for (i=0 ; i<aliascnt ; i++)
+ hostent->h_aliases[i] = aliases[i];
+ hostent->h_aliases[aliascnt] = NULL;
+ hostent->h_addrtype = aresx_sitoss(family);
+ hostent->h_length = aresx_sitoss(addrlen);
+ if (addr && addrlen)
+ memcpy(hostent->h_addr_list[0], addr, addrlen);
+ hostent->h_addr_list[1] = NULL;
+ *host = hostent;
+ ares_free(aliases);
+ ares_free(ptrname);
+
+ return ARES_SUCCESS;
}
+
+fail:
+ ares_free_hostent(hostent);
+
for (i=0 ; i<aliascnt ; i++)
if (aliases[i])
ares_free(aliases[i]);
diff --git a/deps/cares/src/lib/ares_parse_soa_reply.c b/deps/cares/src/lib/ares_parse_soa_reply.c
new file mode 100644
index 0000000000..3935eec9db
--- /dev/null
+++ b/deps/cares/src/lib/ares_parse_soa_reply.c
@@ -0,0 +1,179 @@
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2012 Marko Kreen <markokr@gmail.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"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#include "ares_nameser.h"
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_data.h"
+#include "ares_private.h"
+
+int
+ares_parse_soa_reply(const unsigned char *abuf, int alen,
+ struct ares_soa_reply **soa_out)
+{
+ const unsigned char *aptr;
+ long len;
+ char *qname = NULL, *rr_name = NULL;
+ struct ares_soa_reply *soa = NULL;
+ int qdcount, ancount, qclass;
+ int status, i, rr_type, rr_class, rr_len;
+
+ if (alen < HFIXEDSZ)
+ return ARES_EBADRESP;
+
+ /* parse message header */
+ qdcount = DNS_HEADER_QDCOUNT(abuf);
+ ancount = DNS_HEADER_ANCOUNT(abuf);
+
+ if (qdcount != 1)
+ return ARES_EBADRESP;
+ if (ancount == 0)
+ return ARES_EBADRESP;
+
+ aptr = abuf + HFIXEDSZ;
+
+ /* query name */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &qname, &len, 0);
+ if (status != ARES_SUCCESS)
+ goto failed_stat;
+
+ if (alen <= len + HFIXEDSZ + 1)
+ goto failed;
+ aptr += len;
+
+ qclass = DNS_QUESTION_TYPE(aptr);
+
+ /* skip qtype & qclass */
+ if (aptr + QFIXEDSZ > abuf + alen)
+ goto failed;
+ aptr += QFIXEDSZ;
+
+ /* qclass of SOA with multiple answers */
+ if (qclass == T_SOA && ancount > 1)
+ goto failed;
+
+ /* examine all the records, break and return if found soa */
+ for (i = 0; i < ancount; i++)
+ {
+ rr_name = NULL;
+ status = ares__expand_name_for_response (aptr, abuf, alen, &rr_name, &len, 0);
+ if (status != ARES_SUCCESS)
+ {
+ ares_free(rr_name);
+ goto failed_stat;
+ }
+
+ aptr += len;
+ if ( aptr + RRFIXEDSZ > abuf + alen )
+ {
+ ares_free(rr_name);
+ status = ARES_EBADRESP;
+ goto failed_stat;
+ }
+ rr_type = DNS_RR_TYPE( aptr );
+ rr_class = DNS_RR_CLASS( aptr );
+ rr_len = DNS_RR_LEN( aptr );
+ aptr += RRFIXEDSZ;
+ if (aptr + rr_len > abuf + alen)
+ {
+ ares_free(rr_name);
+ status = ARES_EBADRESP;
+ goto failed_stat;
+ }
+ if ( rr_class == C_IN && rr_type == T_SOA )
+ {
+ /* allocate result struct */
+ soa = ares_malloc_data(ARES_DATATYPE_SOA_REPLY);
+ if (!soa)
+ {
+ ares_free(rr_name);
+ status = ARES_ENOMEM;
+ goto failed_stat;
+ }
+
+ /* nsname */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &soa->nsname,
+ &len, 0);
+ if (status != ARES_SUCCESS)
+ {
+ ares_free(rr_name);
+ goto failed_stat;
+ }
+ aptr += len;
+
+ /* hostmaster */
+ status = ares__expand_name_for_response(aptr, abuf, alen,
+ &soa->hostmaster, &len, 0);
+ if (status != ARES_SUCCESS)
+ {
+ ares_free(rr_name);
+ goto failed_stat;
+ }
+ aptr += len;
+
+ /* integer fields */
+ if (aptr + 5 * 4 > abuf + alen)
+ {
+ ares_free(rr_name);
+ goto failed;
+ }
+ soa->serial = DNS__32BIT(aptr + 0 * 4);
+ soa->refresh = DNS__32BIT(aptr + 1 * 4);
+ soa->retry = DNS__32BIT(aptr + 2 * 4);
+ soa->expire = DNS__32BIT(aptr + 3 * 4);
+ soa->minttl = DNS__32BIT(aptr + 4 * 4);
+
+ ares_free(qname);
+ ares_free(rr_name);
+
+ *soa_out = soa;
+
+ return ARES_SUCCESS;
+ }
+ aptr += rr_len;
+
+ ares_free(rr_name);
+
+ if (aptr > abuf + alen)
+ goto failed_stat;
+ }
+ /* no SOA record found */
+ status = ARES_EBADRESP;
+ goto failed_stat;
+failed:
+ status = ARES_EBADRESP;
+
+failed_stat:
+ if (soa)
+ ares_free_data(soa);
+ if (qname)
+ ares_free(qname);
+ return status;
+}
diff --git a/deps/cares/src/ares_parse_srv_reply.c b/deps/cares/src/lib/ares_parse_srv_reply.c
similarity index 94%
rename from deps/cares/src/ares_parse_srv_reply.c
rename to deps/cares/src/lib/ares_parse_srv_reply.c
index 824ff3aedf..0d8f4d2098 100644
--- a/deps/cares/src/ares_parse_srv_reply.c
+++ b/deps/cares/src/lib/ares_parse_srv_reply.c
@@ -26,25 +26,14 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
#include "ares_data.h"
#include "ares_private.h"
-/* AIX portability check */
-#ifndef T_SRV
-# define T_SRV 33 /* server selection */
-#endif
-
int
ares_parse_srv_reply (const unsigned char *abuf, int alen,
struct ares_srv_reply **srv_out)
diff --git a/deps/cares/src/ares_parse_txt_reply.c b/deps/cares/src/lib/ares_parse_txt_reply.c
similarity index 96%
rename from deps/cares/src/ares_parse_txt_reply.c
rename to deps/cares/src/lib/ares_parse_txt_reply.c
index 4856b4cea3..6848a092bb 100644
--- a/deps/cares/src/ares_parse_txt_reply.c
+++ b/deps/cares/src/lib/ares_parse_txt_reply.c
@@ -26,14 +26,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
# include <strings.h>
@@ -113,7 +107,7 @@ ares__parse_txt_reply (const unsigned char *abuf, int alen,
}
/* Check if we are really looking at a TXT record */
- if (rr_class == C_IN && rr_type == T_TXT)
+ if ((rr_class == C_IN || rr_class == C_CHAOS) && rr_type == T_TXT)
{
/*
* There may be multiple substrings in a single TXT record. Each
diff --git a/deps/cares/src/ares_platform.c b/deps/cares/src/lib/ares_platform.c
similarity index 100%
rename from deps/cares/src/ares_platform.c
rename to deps/cares/src/lib/ares_platform.c
diff --git a/deps/cares/src/ares_platform.h b/deps/cares/src/lib/ares_platform.h
similarity index 100%
rename from deps/cares/src/ares_platform.h
rename to deps/cares/src/lib/ares_platform.h
diff --git a/deps/cares/src/ares_private.h b/deps/cares/src/lib/ares_private.h
similarity index 80%
rename from deps/cares/src/ares_private.h
rename to deps/cares/src/lib/ares_private.h
index 1990f6902f..09f65062f0 100644
--- a/deps/cares/src/ares_private.h
+++ b/deps/cares/src/lib/ares_private.h
@@ -50,6 +50,11 @@
#define STATIC_TESTABLE static
#endif
+/* By using a double cast, we can get rid of the bogus warning of
+ * warning: cast from 'const struct sockaddr *' to 'const struct sockaddr_in6 *' increases required alignment from 1 to 4 [-Wcast-align]
+ */
+#define CARES_INADDR_CAST(type, var) ((type)((void *)var))
+
#if defined(WIN32) && !defined(WATT32)
#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
@@ -69,6 +74,7 @@
#elif defined(WATT32)
#define PATH_RESOLV_CONF "/dev/ENV/etc/resolv.conf"
+W32_FUNC const char *_w32_GetHostsFile (void);
#elif defined(NETWARE)
@@ -350,16 +356,60 @@ int ares__read_line(FILE *fp, char **buf, size_t *bufsize);
void ares__free_query(struct query *query);
unsigned short ares__generate_new_id(rc4_key* key);
struct timeval ares__tvnow(void);
+int ares__expand_name_validated(const unsigned char *encoded,
+ const unsigned char *abuf,
+ int alen, char **s, long *enclen,
+ int is_hostname);
int ares__expand_name_for_response(const unsigned char *encoded,
const unsigned char *abuf, int alen,
- char **s, long *enclen);
+ char **s, long *enclen, int is_hostname);
void ares__init_servers_state(ares_channel channel);
void ares__destroy_servers_state(ares_channel channel);
+int ares__parse_qtype_reply(const unsigned char* abuf, int alen, int* qtype);
+int ares__single_domain(ares_channel channel, const char *name, char **s);
+int ares__cat_domain(const char *name, const char *domain, char **s);
+int ares__sortaddrinfo(ares_channel channel, struct ares_addrinfo_node *ai_node);
+int ares__readaddrinfo(FILE *fp, const char *name, unsigned short port,
+ const struct ares_addrinfo_hints *hints,
+ struct ares_addrinfo *ai);
+
+struct ares_addrinfo *ares__malloc_addrinfo(void);
+
+struct ares_addrinfo_node *ares__malloc_addrinfo_node(void);
+void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *ai_node);
+
+struct ares_addrinfo_node *ares__append_addrinfo_node(struct ares_addrinfo_node **ai_node);
+void ares__addrinfo_cat_nodes(struct ares_addrinfo_node **head,
+ struct ares_addrinfo_node *tail);
+
+struct ares_addrinfo_cname *ares__malloc_addrinfo_cname(void);
+void ares__freeaddrinfo_cnames(struct ares_addrinfo_cname *ai_cname);
+
+struct ares_addrinfo_cname *ares__append_addrinfo_cname(struct ares_addrinfo_cname **ai_cname);
+
+void ares__addrinfo_cat_cnames(struct ares_addrinfo_cname **head,
+ struct ares_addrinfo_cname *tail);
+
+int ares__parse_into_addrinfo(const unsigned char *abuf,
+ int alen,
+ struct ares_addrinfo *ai);
+
+int ares__parse_into_addrinfo2(const unsigned char *abuf,
+ int alen,
+ char **question_hostname,
+ struct ares_addrinfo *ai);
+
#if 0 /* Not used */
long ares__tvdiff(struct timeval t1, struct timeval t2);
#endif
-void ares__socket_close(ares_channel, ares_socket_t);
+ares_socket_t ares__open_socket(ares_channel channel,
+ int af, int type, int protocol);
+void ares__close_socket(ares_channel, ares_socket_t);
+int ares__connect_socket(ares_channel channel,
+ ares_socket_t sockfd,
+ const struct sockaddr *addr,
+ ares_socklen_t addrlen);
#define ARES_SWAP_BYTE(a,b) \
{ unsigned char swapByte = *(a); *(a) = *(b); *(b) = swapByte; }
@@ -370,13 +420,4 @@ void ares__socket_close(ares_channel, ares_socket_t);
(c)->sock_state_cb((c)->sock_state_cb_data, (s), (r), (w)); \
} WHILE_FALSE
-#ifdef CURLDEBUG
-/* This is low-level hard-hacking memory leak tracking and similar. Using the
- libcurl lowlevel code from within library is ugly and only works when
- c-ares is built and linked with a similarly curldebug-enabled libcurl,
- but we do this anyway for convenience. */
-#define HEADER_CURL_SETUP_ONCE_H
-#include "../lib/memdebug.h"
-#endif
-
#endif /* __ARES_PRIVATE_H */
diff --git a/deps/cares/src/ares_process.c b/deps/cares/src/lib/ares_process.c
similarity index 92%
rename from deps/cares/src/ares_process.c
rename to deps/cares/src/lib/ares_process.c
index df9f290bb1..87329e3588 100644
--- a/deps/cares/src/ares_process.c
+++ b/deps/cares/src/lib/ares_process.c
@@ -32,14 +32,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
# include <strings.h>
@@ -87,6 +81,7 @@ static int open_udp_socket(ares_channel channel, struct server_state *server);
static int same_questions(const unsigned char *qbuf, int qlen,
const unsigned char *abuf, int alen);
static int same_address(struct sockaddr *sa, struct ares_addr *aa);
+static int has_opt_rr(const unsigned char *abuf, int alen);
static void end_query(ares_channel channel, struct query *query, int status,
unsigned char *abuf, int alen);
@@ -608,14 +603,13 @@ static void process_answer(ares_channel channel, unsigned char *abuf,
return;
packetsz = PACKETSZ;
- /* If we use EDNS and server answers with one of these RCODES, the protocol
+ /* If we use EDNS and server answers with FORMERR without an OPT RR, the protocol
* extension is not understood by the responder. We must retry the query
- * without EDNS enabled.
- */
+ * without EDNS enabled. */
if (channel->flags & ARES_FLAG_EDNS)
{
packetsz = channel->ednspsz;
- if (rcode == NOTIMP || rcode == FORMERR || rcode == SERVFAIL)
+ if (rcode == FORMERR && has_opt_rr(abuf, alen) != 1)
{
int qlen = (query->tcplen - 2) - EDNSFIXEDSZ;
channel->flags ^= ARES_FLAG_EDNS;
@@ -1039,30 +1033,6 @@ static int configure_socket(ares_socket_t s, int family, ares_channel channel)
return 0;
}
-static ares_socket_t open_socket(ares_channel channel, int af, int type, int protocol)
-{
- if (channel->sock_funcs != 0)
- return channel->sock_funcs->asocket(af,
- type,
- protocol,
- channel->sock_func_cb_data);
-
- return socket(af, type, protocol);
-}
-
-static int connect_socket(ares_channel channel, ares_socket_t sockfd,
- const struct sockaddr * addr,
- ares_socklen_t addrlen)
-{
- if (channel->sock_funcs != 0)
- return channel->sock_funcs->aconnect(sockfd,
- addr,
- addrlen,
- channel->sock_func_cb_data);
-
- return connect(sockfd, addr, addrlen);
-}
-
static int open_tcp_socket(ares_channel channel, struct server_state *server)
{
ares_socket_t s;
@@ -1107,14 +1077,14 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
}
/* Acquire a socket. */
- s = open_socket(channel, server->addr.family, SOCK_STREAM, 0);
+ s = ares__open_socket(channel, server->addr.family, SOCK_STREAM, 0);
if (s == ARES_SOCKET_BAD)
return -1;
/* Configure it. */
if (configure_socket(s, server->addr.family, channel) < 0)
{
- ares__socket_close(channel, s);
+ ares__close_socket(channel, s);
return -1;
}
@@ -1131,7 +1101,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
(void *)&opt, sizeof(opt)) == -1)
{
- ares__socket_close(channel, s);
+ ares__close_socket(channel, s);
return -1;
}
#endif
@@ -1142,19 +1112,19 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
channel->sock_config_cb_data);
if (err < 0)
{
- ares__socket_close(channel, s);
+ ares__close_socket(channel, s);
return err;
}
}
/* Connect to the server. */
- if (connect_socket(channel, s, sa, salen) == -1)
+ if (ares__connect_socket(channel, s, sa, salen) == -1)
{
int err = SOCKERRNO;
if (err != EINPROGRESS && err != EWOULDBLOCK)
{
- ares__socket_close(channel, s);
+ ares__close_socket(channel, s);
return -1;
}
}
@@ -1165,7 +1135,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
channel->sock_create_cb_data);
if (err < 0)
{
- ares__socket_close(channel, s);
+ ares__close_socket(channel, s);
return err;
}
}
@@ -1220,14 +1190,14 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
}
/* Acquire a socket. */
- s = open_socket(channel, server->addr.family, SOCK_DGRAM, 0);
+ s = ares__open_socket(channel, server->addr.family, SOCK_DGRAM, 0);
if (s == ARES_SOCKET_BAD)
return -1;
/* Set the socket non-blocking. */
if (configure_socket(s, server->addr.family, channel) < 0)
{
- ares__socket_close(channel, s);
+ ares__close_socket(channel, s);
return -1;
}
@@ -1237,19 +1207,19 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
channel->sock_config_cb_data);
if (err < 0)
{
- ares__socket_close(channel, s);
+ ares__close_socket(channel, s);
return err;
}
}
/* Connect to the server. */
- if (connect_socket(channel, s, sa, salen) == -1)
+ if (ares__connect_socket(channel, s, sa, salen) == -1)
{
int err = SOCKERRNO;
if (err != EINPROGRESS && err != EWOULDBLOCK)
{
- ares__socket_close(channel, s);
+ ares__close_socket(channel, s);
return -1;
}
}
@@ -1260,7 +1230,7 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
channel->sock_create_cb_data);
if (err < 0)
{
- ares__socket_close(channel, s);
+ ares__close_socket(channel, s);
return err;
}
}
@@ -1361,13 +1331,13 @@ static int same_address(struct sockaddr *sa, struct ares_addr *aa)
{
case AF_INET:
addr1 = &aa->addrV4;
- addr2 = &((struct sockaddr_in *)sa)->sin_addr;
+ addr2 = &(CARES_INADDR_CAST(struct sockaddr_in *, sa))->sin_addr;
if (memcmp(addr1, addr2, sizeof(aa->addrV4)) == 0)
return 1; /* match */
break;
case AF_INET6:
addr1 = &aa->addrV6;
- addr2 = &((struct sockaddr_in6 *)sa)->sin6_addr;
+ addr2 = &(CARES_INADDR_CAST(struct sockaddr_in6 *, sa))->sin6_addr;
if (memcmp(addr1, addr2, sizeof(aa->addrV6)) == 0)
return 1; /* match */
break;
@@ -1378,6 +1348,85 @@ static int same_address(struct sockaddr *sa, struct ares_addr *aa)
return 0; /* different */
}
+/* search for an OPT RR in the response */
+static int has_opt_rr(const unsigned char *abuf, int alen)
+{
+ unsigned int qdcount, ancount, nscount, arcount, i;
+ const unsigned char *aptr;
+ int status;
+
+ if (alen < HFIXEDSZ)
+ return -1;
+
+ /* Parse the answer header. */
+ qdcount = DNS_HEADER_QDCOUNT(abuf);
+ ancount = DNS_HEADER_ANCOUNT(abuf);
+ nscount = DNS_HEADER_NSCOUNT(abuf);
+ arcount = DNS_HEADER_ARCOUNT(abuf);
+
+ aptr = abuf + HFIXEDSZ;
+
+ /* skip the questions */
+ for (i = 0; i < qdcount; i++)
+ {
+ char* name;
+ long len;
+ status = ares_expand_name(aptr, abuf, alen, &name, &len);
+ if (status != ARES_SUCCESS)
+ return -1;
+ ares_free_string(name);
+ if (aptr + len + QFIXEDSZ > abuf + alen)
+ return -1;
+ aptr += len + QFIXEDSZ;
+ }
+
+ /* skip the ancount and nscount */
+ for (i = 0; i < ancount + nscount; i++)
+ {
+ char* name;
+ long len;
+ int dlen;
+ status = ares_expand_name(aptr, abuf, alen, &name, &len);
+ if (status != ARES_SUCCESS)
+ return -1;
+ ares_free_string(name);
+ if (aptr + len + RRFIXEDSZ > abuf + alen)
+ return -1;
+ aptr += len;
+ dlen = DNS_RR_LEN(aptr);
+ aptr += RRFIXEDSZ;
+ if (aptr + dlen > abuf + alen)
+ return -1;
+ aptr += dlen;
+ }
+
+ /* search for rr type (41) - opt */
+ for (i = 0; i < arcount; i++)
+ {
+ char* name;
+ long len;
+ int dlen;
+ status = ares_expand_name(aptr, abuf, alen, &name, &len);
+ if (status != ARES_SUCCESS)
+ return -1;
+ ares_free_string(name);
+ if (aptr + len + RRFIXEDSZ > abuf + alen)
+ return -1;
+ aptr += len;
+
+ if (DNS_RR_TYPE(aptr) == T_OPT)
+ return 1;
+
+ dlen = DNS_RR_LEN(aptr);
+ aptr += RRFIXEDSZ;
+ if (aptr + dlen > abuf + alen)
+ return -1;
+ aptr += dlen;
+ }
+
+ return 0;
+}
+
static void end_query (ares_channel channel, struct query *query, int status,
unsigned char *abuf, int alen)
{
@@ -1464,7 +1513,33 @@ void ares__free_query(struct query *query)
ares_free(query);
}
-void ares__socket_close(ares_channel channel, ares_socket_t s)
+ares_socket_t ares__open_socket(ares_channel channel,
+ int af, int type, int protocol)
+{
+ if (channel->sock_funcs)
+ return channel->sock_funcs->asocket(af,
+ type,
+ protocol,
+ channel->sock_func_cb_data);
+ else
+ return socket(af, type, protocol);
+}
+
+int ares__connect_socket(ares_channel channel,
+ ares_socket_t sockfd,
+ const struct sockaddr *addr,
+ ares_socklen_t addrlen)
+{
+ if (channel->sock_funcs)
+ return channel->sock_funcs->aconnect(sockfd,
+ addr,
+ addrlen,
+ channel->sock_func_cb_data);
+ else
+ return connect(sockfd, addr, addrlen);
+}
+
+void ares__close_socket(ares_channel channel, ares_socket_t s)
{
if (channel->sock_funcs)
channel->sock_funcs->aclose(s, channel->sock_func_cb_data);
diff --git a/deps/cares/src/ares_query.c b/deps/cares/src/lib/ares_query.c
similarity index 96%
rename from deps/cares/src/ares_query.c
rename to deps/cares/src/lib/ares_query.c
index b38b8a6c22..508274db36 100644
--- a/deps/cares/src/ares_query.c
+++ b/deps/cares/src/lib/ares_query.c
@@ -19,14 +19,8 @@
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
@@ -45,7 +39,7 @@ static void rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len)
unsigned char y;
unsigned char* state;
unsigned char xorIndex;
- short counter;
+ int counter;
x = key->x;
y = key->y;
diff --git a/deps/cares/src/ares_search.c b/deps/cares/src/lib/ares_search.c
similarity index 95%
rename from deps/cares/src/ares_search.c
rename to deps/cares/src/lib/ares_search.c
index 001c3482a7..c4b0424f5b 100644
--- a/deps/cares/src/ares_search.c
+++ b/deps/cares/src/lib/ares_search.c
@@ -43,8 +43,6 @@ static void search_callback(void *arg, int status, int timeouts,
unsigned char *abuf, int alen);
static void end_squery(struct search_query *squery, int status,
unsigned char *abuf, int alen);
-static int cat_domain(const char *name, const char *domain, char **s);
-STATIC_TESTABLE int single_domain(ares_channel channel, const char *name, char **s);
void ares_search(ares_channel channel, const char *name, int dnsclass,
int type, ares_callback callback, void *arg)
@@ -64,7 +62,7 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
/* If name only yields one domain to search, then we don't have
* to keep extra state, so just do an ares_query().
*/
- status = single_domain(channel, name, &s);
+ status = ares__single_domain(channel, name, &s);
if (status != ARES_SUCCESS)
{
callback(arg, status, 0, NULL, 0);
@@ -126,7 +124,7 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
/* Try the name as-is last; start with the first search domain. */
squery->next_domain = 1;
squery->trying_as_is = 0;
- status = cat_domain(name, channel->domains[0], &s);
+ status = ares__cat_domain(name, channel->domains[0], &s);
if (status == ARES_SUCCESS)
{
ares_query(channel, s, dnsclass, type, search_callback, squery);
@@ -174,7 +172,7 @@ static void search_callback(void *arg, int status, int timeouts,
if (squery->next_domain < channel->ndomains)
{
/* Try the next domain. */
- status = cat_domain(squery->name,
+ status = ares__cat_domain(squery->name,
channel->domains[squery->next_domain], &s);
if (status != ARES_SUCCESS)
end_squery(squery, status, NULL, 0);
@@ -213,7 +211,7 @@ static void end_squery(struct search_query *squery, int status,
}
/* Concatenate two domains. */
-static int cat_domain(const char *name, const char *domain, char **s)
+int ares__cat_domain(const char *name, const char *domain, char **s)
{
size_t nlen = strlen(name);
size_t dlen = strlen(domain);
@@ -232,7 +230,7 @@ static int cat_domain(const char *name, const char *domain, char **s)
* the string we should query, in an allocated buffer. If not, set *s
* to NULL.
*/
-STATIC_TESTABLE int single_domain(ares_channel channel, const char *name, char **s)
+int ares__single_domain(ares_channel channel, const char *name, char **s)
{
size_t len = strlen(name);
const char *hostaliases;
diff --git a/deps/cares/src/ares_send.c b/deps/cares/src/lib/ares_send.c
similarity index 95%
rename from deps/cares/src/ares_send.c
rename to deps/cares/src/lib/ares_send.c
index f4f1f95119..75ba9e4cc6 100644
--- a/deps/cares/src/ares_send.c
+++ b/deps/cares/src/lib/ares_send.c
@@ -19,14 +19,8 @@
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
diff --git a/deps/cares/src/ares_setup.h b/deps/cares/src/lib/ares_setup.h
similarity index 95%
rename from deps/cares/src/ares_setup.h
rename to deps/cares/src/lib/ares_setup.h
index 4df796116a..6ad2cee6a8 100644
--- a/deps/cares/src/ares_setup.h
+++ b/deps/cares/src/lib/ares_setup.h
@@ -178,8 +178,11 @@
/*
* Android does have the arpa/nameser.h header which is detected by configure
* but it appears to be empty with recent NDK r7b / r7c, so we undefine here.
+ * z/OS does have the arpa/nameser.h header which is detected by configure
+ * but it is not fully implemented and missing identifiers, so udefine here.
*/
-#if (defined(ANDROID) || defined(__ANDROID__)) && defined(HAVE_ARPA_NAMESER_H)
+#if (defined(ANDROID) || defined(__ANDROID__) || defined(__MVS__)) && \
+ defined(HAVE_ARPA_NAMESER_H)
# undef HAVE_ARPA_NAMESER_H
#endif
diff --git a/deps/cares/src/ares_strcasecmp.c b/deps/cares/src/lib/ares_strcasecmp.c
similarity index 100%
rename from deps/cares/src/ares_strcasecmp.c
rename to deps/cares/src/lib/ares_strcasecmp.c
diff --git a/deps/cares/src/ares_strcasecmp.h b/deps/cares/src/lib/ares_strcasecmp.h
similarity index 100%
rename from deps/cares/src/ares_strcasecmp.h
rename to deps/cares/src/lib/ares_strcasecmp.h
diff --git a/deps/cares/src/ares_strdup.c b/deps/cares/src/lib/ares_strdup.c
similarity index 100%
rename from deps/cares/src/ares_strdup.c
rename to deps/cares/src/lib/ares_strdup.c
diff --git a/deps/cares/src/ares_strdup.h b/deps/cares/src/lib/ares_strdup.h
similarity index 100%
rename from deps/cares/src/ares_strdup.h
rename to deps/cares/src/lib/ares_strdup.h
diff --git a/deps/cares/src/ares_strerror.c b/deps/cares/src/lib/ares_strerror.c
similarity index 100%
rename from deps/cares/src/ares_strerror.c
rename to deps/cares/src/lib/ares_strerror.c
diff --git a/deps/cares/src/ares_strsplit.c b/deps/cares/src/lib/ares_strsplit.c
similarity index 98%
rename from deps/cares/src/ares_strsplit.c
rename to deps/cares/src/lib/ares_strsplit.c
index b57a30f2a9..97b4e5d5bb 100644
--- a/deps/cares/src/ares_strsplit.c
+++ b/deps/cares/src/lib/ares_strsplit.c
@@ -13,6 +13,10 @@
* without express or implied warranty.
*/
+#if defined(__MVS__)
+#include <strings.h>
+#endif
+
#include "ares_setup.h"
#include "ares_strsplit.h"
#include "ares.h"
diff --git a/deps/cares/src/ares_strsplit.h b/deps/cares/src/lib/ares_strsplit.h
similarity index 99%
rename from deps/cares/src/ares_strsplit.h
rename to deps/cares/src/lib/ares_strsplit.h
index da286a9aef..e00fd14dd5 100644
--- a/deps/cares/src/ares_strsplit.h
+++ b/deps/cares/src/lib/ares_strsplit.h
@@ -40,3 +40,4 @@ void ares_strsplit_free(char **elms, size_t num_elm);
#endif /* HEADER_CARES_STRSPLIT_H */
+
diff --git a/deps/cares/src/ares_timeout.c b/deps/cares/src/lib/ares_timeout.c
similarity index 100%
rename from deps/cares/src/ares_timeout.c
rename to deps/cares/src/lib/ares_timeout.c
diff --git a/deps/cares/src/ares_version.c b/deps/cares/src/lib/ares_version.c
similarity index 100%
rename from deps/cares/src/ares_version.c
rename to deps/cares/src/lib/ares_version.c
diff --git a/deps/cares/src/ares_writev.c b/deps/cares/src/lib/ares_writev.c
similarity index 100%
rename from deps/cares/src/ares_writev.c
rename to deps/cares/src/lib/ares_writev.c
diff --git a/deps/cares/src/ares_writev.h b/deps/cares/src/lib/ares_writev.h
similarity index 100%
rename from deps/cares/src/ares_writev.h
rename to deps/cares/src/lib/ares_writev.h
diff --git a/deps/cares/src/bitncmp.c b/deps/cares/src/lib/bitncmp.c
similarity index 100%
rename from deps/cares/src/bitncmp.c
rename to deps/cares/src/lib/bitncmp.c
diff --git a/deps/cares/src/bitncmp.h b/deps/cares/src/lib/bitncmp.h
similarity index 100%
rename from deps/cares/src/bitncmp.h
rename to deps/cares/src/lib/bitncmp.h
diff --git a/deps/cares/src/config-win32.h b/deps/cares/src/lib/config-win32.h
similarity index 100%
rename from deps/cares/src/config-win32.h
rename to deps/cares/src/lib/config-win32.h
diff --git a/deps/cares/src/inet_net_pton.c b/deps/cares/src/lib/inet_net_pton.c
similarity index 98%
rename from deps/cares/src/inet_net_pton.c
rename to deps/cares/src/lib/inet_net_pton.c
index af1a534a05..840de50652 100644
--- a/deps/cares/src/inet_net_pton.c
+++ b/deps/cares/src/lib/inet_net_pton.c
@@ -24,14 +24,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_ipv6.h"
diff --git a/deps/cares/src/inet_ntop.c b/deps/cares/src/lib/inet_ntop.c
similarity index 97%
rename from deps/cares/src/inet_ntop.c
rename to deps/cares/src/lib/inet_ntop.c
index 1935a871ce..6645c0a467 100644
--- a/deps/cares/src/inet_ntop.c
+++ b/deps/cares/src/lib/inet_ntop.c
@@ -23,14 +23,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_ipv6.h"
diff --git a/deps/cares/include/nameser.h b/deps/cares/src/lib/nameser.h
similarity index 97%
rename from deps/cares/include/nameser.h
rename to deps/cares/src/lib/nameser.h
index a0302fd398..d6c192c58f 100644
--- a/deps/cares/include/nameser.h
+++ b/deps/cares/src/lib/nameser.h
@@ -88,6 +88,7 @@ typedef enum __ns_type {
ns_t_maila = 254, /* Transfer mail agent records. */
ns_t_any = 255, /* Wildcard match. */
ns_t_zxfr = 256, /* BIND-specific, nonstandard. */
+ ns_t_caa = 257, /* Certification Authority Authorization. */
ns_t_max = 65536
} ns_type;
@@ -208,4 +209,9 @@ typedef enum __ns_rcode {
#endif /* HAVE_ARPA_NAMESER_COMPAT_H */
+/* Android's bionic arpa/nameser_compat.h, nor glibc versions prior to 2.25 have T_OPT defined */
+#ifndef T_OPT
+# define T_OPT ns_t_opt
+#endif
+
#endif /* ARES_NAMESER_H */
diff --git a/deps/cares/src/setup_once.h b/deps/cares/src/lib/setup_once.h
similarity index 100%
rename from deps/cares/src/setup_once.h
rename to deps/cares/src/lib/setup_once.h
diff --git a/deps/cares/src/windows_port.c b/deps/cares/src/lib/windows_port.c
similarity index 100%
rename from deps/cares/src/windows_port.c
rename to deps/cares/src/lib/windows_port.c
diff --git a/deps/cares/src/ares_getopt.c b/deps/cares/src/tools/ares_getopt.c
similarity index 100%
rename from deps/cares/src/ares_getopt.c
rename to deps/cares/src/tools/ares_getopt.c
diff --git a/deps/cares/src/ares_getopt.h b/deps/cares/src/tools/ares_getopt.h
similarity index 100%
rename from deps/cares/src/ares_getopt.h
rename to deps/cares/src/tools/ares_getopt.h