- cares_172.patch: update c-ares to 1.17.2. (bsc#1188881, CVE-2021-3672) OBS-URL: https://build.opensuse.org/package/show/devel:languages:nodejs/nodejs10?expand=0&rev=169
6443 lines
194 KiB
Diff
6443 lines
194 KiB
Diff
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
|