summaryrefslogtreecommitdiff
path: root/deps/cares
diff options
context:
space:
mode:
authorRod Vagg <rod@vagg.org>2017-09-13 12:51:23 +1000
committerRuben Bridgewater <ruben@bridgewater.de>2017-10-02 01:16:11 -0300
commit13c74706ef872aa9ed5f17572b6466ce5af26b95 (patch)
treed096cf59846bb0941c564f3d462b7adc17f10fb8 /deps/cares
parentd0d1eba872f4b6165af4c39fb2f044de27695c48 (diff)
downloadandroid-node-v8-13c74706ef872aa9ed5f17572b6466ce5af26b95.tar.gz
android-node-v8-13c74706ef872aa9ed5f17572b6466ce5af26b95.tar.bz2
android-node-v8-13c74706ef872aa9ed5f17572b6466ce5af26b95.zip
deps: upgrade to c-ares v1.13.0
PR-URL: https://github.com/nodejs/node/pull/15378 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Diffstat (limited to 'deps/cares')
-rw-r--r--deps/cares/config/aix/ares_config.h9
-rw-r--r--deps/cares/config/android/ares_config.h9
-rw-r--r--deps/cares/config/cygwin/ares_config.h7
-rw-r--r--deps/cares/config/darwin/ares_config.h14
-rw-r--r--deps/cares/config/freebsd/ares_config.h9
-rw-r--r--deps/cares/config/linux/ares_config.h14
-rw-r--r--deps/cares/config/netbsd/ares_config.h9
-rw-r--r--deps/cares/config/openbsd/ares_config.h9
-rw-r--r--deps/cares/config/sunos/ares_config.h9
-rw-r--r--deps/cares/include/ares.h24
-rw-r--r--deps/cares/include/ares_build.h13
-rw-r--r--deps/cares/include/ares_version.h4
-rw-r--r--deps/cares/src/README58
-rw-r--r--deps/cares/src/README.md65
-rw-r--r--deps/cares/src/RELEASE-NOTES77
-rw-r--r--deps/cares/src/ares__close_sockets.c4
-rw-r--r--deps/cares/src/ares_create_query.c6
-rw-r--r--deps/cares/src/ares_expand_name.c8
-rw-r--r--deps/cares/src/ares_expand_string.c2
-rw-r--r--deps/cares/src/ares_gethostbyaddr.c2
-rw-r--r--deps/cares/src/ares_getnameinfo.c34
-rw-r--r--deps/cares/src/ares_init.c446
-rw-r--r--deps/cares/src/ares_library_init.c10
-rw-r--r--deps/cares/src/ares_library_init.h3
-rw-r--r--deps/cares/src/ares_nowarn.c12
-rw-r--r--deps/cares/src/ares_nowarn.h4
-rw-r--r--deps/cares/src/ares_parse_naptr_reply.c13
-rw-r--r--deps/cares/src/ares_private.h11
-rw-r--r--deps/cares/src/ares_process.c163
-rw-r--r--deps/cares/src/ares_writev.c4
-rw-r--r--deps/cares/src/ares_writev.h2
-rw-r--r--deps/cares/src/config-win32.h42
-rw-r--r--deps/cares/src/inet_net_pton.c4
-rw-r--r--deps/cares/src/setup_once.h10
34 files changed, 828 insertions, 282 deletions
diff --git a/deps/cares/config/aix/ares_config.h b/deps/cares/config/aix/ares_config.h
index 65cbab6cab..c79096a362 100644
--- a/deps/cares/config/aix/ares_config.h
+++ b/deps/cares/config/aix/ares_config.h
@@ -16,6 +16,9 @@
/* Defined for build with symbol hiding. */
/* #undef CARES_SYMBOL_HIDING */
+/* the signed version of size_t */
+#define CARES_TYPEOF_ARES_SSIZE_T ssize_t
+
/* Definition to make a library symbol externally visible. */
/* #undef CARES_SYMBOL_SCOPE_EXTERN */
@@ -363,7 +366,7 @@
#define PACKAGE_NAME "c-ares"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "c-ares 1.12.0"
+#define PACKAGE_STRING "c-ares 1.13.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "c-ares"
@@ -372,7 +375,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.12.0"
+#define PACKAGE_VERSION "1.13.0"
/* a suitable file/device to read random data from */
#define RANDOM_FILE "/dev/urandom"
@@ -456,7 +459,7 @@
/* #undef USE_BLOCKING_SOCKETS */
/* Version number of package */
-#define VERSION "1.12.0"
+#define VERSION "1.13.0"
/* Define to avoid automatic inclusion of winsock.h */
/* #undef WIN32_LEAN_AND_MEAN */
diff --git a/deps/cares/config/android/ares_config.h b/deps/cares/config/android/ares_config.h
index ab73c87d9f..1a5265a509 100644
--- a/deps/cares/config/android/ares_config.h
+++ b/deps/cares/config/android/ares_config.h
@@ -19,6 +19,9 @@
/* Definition to make a library symbol externally visible. */
#define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((__visibility__ ("default")))
+/* the signed version of size_t */
+#define CARES_TYPEOF_ARES_SSIZE_T ssize_t
+
/* Use resolver library to configure cares */
/* #undef CARES_USE_LIBRESOLV */
@@ -363,7 +366,7 @@
#define PACKAGE_NAME "c-ares"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "c-ares 1.12.0"
+#define PACKAGE_STRING "c-ares 1.13.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "c-ares"
@@ -372,7 +375,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.12.0"
+#define PACKAGE_VERSION "1.13.0"
/* a suitable file/device to read random data from */
#define RANDOM_FILE "/dev/urandom"
@@ -456,7 +459,7 @@
/* #undef USE_BLOCKING_SOCKETS */
/* Version number of package */
-#define VERSION "1.12.0"
+#define VERSION "1.13.0"
/* Define to avoid automatic inclusion of winsock.h */
/* #undef WIN32_LEAN_AND_MEAN */
diff --git a/deps/cares/config/cygwin/ares_config.h b/deps/cares/config/cygwin/ares_config.h
index 592a245985..3818ad0b46 100644
--- a/deps/cares/config/cygwin/ares_config.h
+++ b/deps/cares/config/cygwin/ares_config.h
@@ -22,6 +22,9 @@
/* Definition to make a library symbol externally visible. */
#define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((visibility ("default")))
+/* the signed version of size_t */
+#define CARES_TYPEOF_ARES_SSIZE_T ssize_t
+
/* if a /etc/inet dir is being used */
/* #undef ETC_INET */
@@ -364,7 +367,7 @@
#define PACKAGE_NAME "c-ares"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "c-ares 1.7.1"
+#define PACKAGE_STRING "c-ares 1.13.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "c-ares"
@@ -373,7 +376,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.7.1"
+#define PACKAGE_VERSION "1.13.0"
/* a suitable file/device to read random data from */
#define RANDOM_FILE "/dev/urandom"
diff --git a/deps/cares/config/darwin/ares_config.h b/deps/cares/config/darwin/ares_config.h
index 0a755e8bda..6625eccd6a 100644
--- a/deps/cares/config/darwin/ares_config.h
+++ b/deps/cares/config/darwin/ares_config.h
@@ -19,6 +19,9 @@
/* Definition to make a library symbol externally visible. */
#define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((__visibility__ ("default")))
+/* the signed version of size_t */
+#define CARES_TYPEOF_ARES_SSIZE_T ssize_t
+
/* Use resolver library to configure cares */
/* #undef CARES_USE_LIBRESOLV */
@@ -351,7 +354,7 @@
/* #undef NEED_THREAD_SAFE */
/* cpu-machine-OS */
-#define OS "x86_64-apple-darwin14.5.0"
+#define OS "x86_64-apple-darwin16.7.0"
/* Name of package */
#define PACKAGE "c-ares"
@@ -363,7 +366,7 @@
#define PACKAGE_NAME "c-ares"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "c-ares 1.12.0"
+#define PACKAGE_STRING "c-ares 1.13.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "c-ares"
@@ -372,7 +375,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.12.0"
+#define PACKAGE_VERSION "1.13.0"
/* a suitable file/device to read random data from */
#define RANDOM_FILE "/dev/urandom"
@@ -456,7 +459,7 @@
/* #undef USE_BLOCKING_SOCKETS */
/* Version number of package */
-#define VERSION "1.12.0"
+#define VERSION "1.13.0"
/* Define to avoid automatic inclusion of winsock.h */
/* #undef WIN32_LEAN_AND_MEAN */
@@ -497,6 +500,3 @@
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
-
-/* the signed version of size_t */
-/* #undef ssize_t */
diff --git a/deps/cares/config/freebsd/ares_config.h b/deps/cares/config/freebsd/ares_config.h
index 4685a3e046..1adaa8c32e 100644
--- a/deps/cares/config/freebsd/ares_config.h
+++ b/deps/cares/config/freebsd/ares_config.h
@@ -19,6 +19,9 @@
/* Definition to make a library symbol externally visible. */
#define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((__visibility__ ("default")))
+/* the signed version of size_t */
+#define CARES_TYPEOF_ARES_SSIZE_T ssize_t
+
/* Use resolver library to configure cares */
/* #undef CARES_USE_LIBRESOLV */
@@ -363,7 +366,7 @@
#define PACKAGE_NAME "c-ares"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "c-ares 1.12.0"
+#define PACKAGE_STRING "c-ares 1.13.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "c-ares"
@@ -372,7 +375,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.12.0"
+#define PACKAGE_VERSION "1.13.0"
/* a suitable file/device to read random data from */
#define RANDOM_FILE "/dev/urandom"
@@ -456,7 +459,7 @@
/* #undef USE_BLOCKING_SOCKETS */
/* Version number of package */
-#define VERSION "1.12.0"
+#define VERSION "1.13.0"
/* Define to avoid automatic inclusion of winsock.h */
/* #undef WIN32_LEAN_AND_MEAN */
diff --git a/deps/cares/config/linux/ares_config.h b/deps/cares/config/linux/ares_config.h
index ae254a0f0b..eb6239f637 100644
--- a/deps/cares/config/linux/ares_config.h
+++ b/deps/cares/config/linux/ares_config.h
@@ -19,6 +19,9 @@
/* Definition to make a library symbol externally visible. */
#define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((__visibility__ ("default")))
+/* the signed version of size_t */
+#define CARES_TYPEOF_ARES_SSIZE_T ssize_t
+
/* Use resolver library to configure cares */
/* #undef CARES_USE_LIBRESOLV */
@@ -351,7 +354,7 @@
/* #undef NEED_THREAD_SAFE */
/* cpu-machine-OS */
-#define OS "i686-pc-linux-gnu"
+#define OS "x86_64-pc-linux-gnu"
/* Name of package */
#define PACKAGE "c-ares"
@@ -363,7 +366,7 @@
#define PACKAGE_NAME "c-ares"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "c-ares 1.12.0"
+#define PACKAGE_STRING "c-ares 1.13.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "c-ares"
@@ -372,7 +375,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.12.0"
+#define PACKAGE_VERSION "1.13.0"
/* a suitable file/device to read random data from */
#define RANDOM_FILE "/dev/urandom"
@@ -456,7 +459,7 @@
/* #undef USE_BLOCKING_SOCKETS */
/* Version number of package */
-#define VERSION "1.12.0"
+#define VERSION "1.13.0"
/* Define to avoid automatic inclusion of winsock.h */
/* #undef WIN32_LEAN_AND_MEAN */
@@ -497,6 +500,3 @@
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
-
-/* the signed version of size_t */
-/* #undef ssize_t */
diff --git a/deps/cares/config/netbsd/ares_config.h b/deps/cares/config/netbsd/ares_config.h
index 552865e326..48512dc1a9 100644
--- a/deps/cares/config/netbsd/ares_config.h
+++ b/deps/cares/config/netbsd/ares_config.h
@@ -16,6 +16,9 @@
/* Defined for build with symbol hiding. */
/* #undef CARES_SYMBOL_HIDING */
+/* the signed version of size_t */
+#define CARES_TYPEOF_ARES_SSIZE_T ssize_t
+
/* Definition to make a library symbol externally visible. */
/* #undef CARES_SYMBOL_SCOPE_EXTERN */
@@ -363,7 +366,7 @@
#define PACKAGE_NAME "c-ares"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "c-ares 1.12.0"
+#define PACKAGE_STRING "c-ares 1.13.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "c-ares"
@@ -372,7 +375,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.12.0"
+#define PACKAGE_VERSION "1.13.0"
/* a suitable file/device to read random data from */
#define RANDOM_FILE "/dev/urandom"
@@ -456,7 +459,7 @@
/* #undef USE_BLOCKING_SOCKETS */
/* Version number of package */
-#define VERSION "1.12.0"
+#define VERSION "1.13.0"
/* Define to avoid automatic inclusion of winsock.h */
/* #undef WIN32_LEAN_AND_MEAN */
diff --git a/deps/cares/config/openbsd/ares_config.h b/deps/cares/config/openbsd/ares_config.h
index 552865e326..48512dc1a9 100644
--- a/deps/cares/config/openbsd/ares_config.h
+++ b/deps/cares/config/openbsd/ares_config.h
@@ -16,6 +16,9 @@
/* Defined for build with symbol hiding. */
/* #undef CARES_SYMBOL_HIDING */
+/* the signed version of size_t */
+#define CARES_TYPEOF_ARES_SSIZE_T ssize_t
+
/* Definition to make a library symbol externally visible. */
/* #undef CARES_SYMBOL_SCOPE_EXTERN */
@@ -363,7 +366,7 @@
#define PACKAGE_NAME "c-ares"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "c-ares 1.12.0"
+#define PACKAGE_STRING "c-ares 1.13.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "c-ares"
@@ -372,7 +375,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.12.0"
+#define PACKAGE_VERSION "1.13.0"
/* a suitable file/device to read random data from */
#define RANDOM_FILE "/dev/urandom"
@@ -456,7 +459,7 @@
/* #undef USE_BLOCKING_SOCKETS */
/* Version number of package */
-#define VERSION "1.12.0"
+#define VERSION "1.13.0"
/* Define to avoid automatic inclusion of winsock.h */
/* #undef WIN32_LEAN_AND_MEAN */
diff --git a/deps/cares/config/sunos/ares_config.h b/deps/cares/config/sunos/ares_config.h
index 32d4ac8ab2..b50814a103 100644
--- a/deps/cares/config/sunos/ares_config.h
+++ b/deps/cares/config/sunos/ares_config.h
@@ -19,6 +19,9 @@
/* Definition to make a library symbol externally visible. */
#define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((__visibility__ ("default")))
+/* the signed version of size_t */
+#define CARES_TYPEOF_ARES_SSIZE_T ssize_t
+
/* Use resolver library to configure cares */
/* #undef CARES_USE_LIBRESOLV */
@@ -363,7 +366,7 @@
#define PACKAGE_NAME "c-ares"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "c-ares 1.12.0"
+#define PACKAGE_STRING "c-ares 1.13.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "c-ares"
@@ -372,7 +375,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.12.0"
+#define PACKAGE_VERSION "1.13.0"
/* a suitable file/device to read random data from */
#define RANDOM_FILE "/dev/urandom"
@@ -456,7 +459,7 @@
/* #undef USE_BLOCKING_SOCKETS */
/* Version number of package */
-#define VERSION "1.12.0"
+#define VERSION "1.13.0"
/* Define to avoid automatic inclusion of winsock.h */
/* #undef WIN32_LEAN_AND_MEAN */
diff --git a/deps/cares/include/ares.h b/deps/cares/include/ares.h
index 8c80f0740b..cfd72b0c51 100644
--- a/deps/cares/include/ares.h
+++ b/deps/cares/include/ares.h
@@ -38,7 +38,8 @@
require it! */
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
- defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__)
+ defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
+ defined(__QNXNTO__)
#include <sys/select.h>
#endif
#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
@@ -356,6 +357,27 @@ CARES_EXTERN void ares_set_socket_configure_callback(ares_channel channel,
CARES_EXTERN int ares_set_sortlist(ares_channel channel,
const char *sortstr);
+/*
+ * Virtual function set to have user-managed socket IO.
+ * Note that all functions need to be defined, and when
+ * set, the library will not do any bind nor set any
+ * socket options, assuming the client handles these
+ * through either socket creation or the
+ * ares_sock_config_callback call.
+ */
+struct iovec;
+struct ares_socket_functions {
+ ares_socket_t(*asocket)(int, int, int, void *);
+ int(*aclose)(ares_socket_t, void *);
+ int(*aconnect)(ares_socket_t, const struct sockaddr *, ares_socklen_t, void *);
+ ares_ssize_t(*arecvfrom)(ares_socket_t, void *, size_t, int, struct sockaddr *, ares_socklen_t *, void *);
+ ares_ssize_t(*asendv)(ares_socket_t, const struct iovec *, int, void *);
+};
+
+CARES_EXTERN void ares_set_socket_functions(ares_channel channel,
+ const struct ares_socket_functions * funcs,
+ void *user_data);
+
CARES_EXTERN void ares_send(ares_channel channel,
const unsigned char *qbuf,
int qlen,
diff --git a/deps/cares/include/ares_build.h b/deps/cares/include/ares_build.h
index 9a865e3449..f94bb2962a 100644
--- a/deps/cares/include/ares_build.h
+++ b/deps/cares/include/ares_build.h
@@ -191,4 +191,17 @@
typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t;
#endif
+/* Data type definition of ares_ssize_t. */
+#ifdef _WIN32
+# ifdef _WIN64
+# define CARES_TYPEOF_ARES_SSIZE_T __int64
+# else
+# define CARES_TYPEOF_ARES_SSIZE_T long
+# endif
+#else
+# define CARES_TYPEOF_ARES_SSIZE_T ssize_t;
+#endif
+
+typedef CARES_TYPEOF_ARES_SSIZE_T ares_ssize_t;
+
#endif /* __CARES_BUILD_H */
diff --git a/deps/cares/include/ares_version.h b/deps/cares/include/ares_version.h
index 92c858415b..afa46c632f 100644
--- a/deps/cares/include/ares_version.h
+++ b/deps/cares/include/ares_version.h
@@ -6,12 +6,12 @@
#define ARES_COPYRIGHT "2004 - 2016 Daniel Stenberg, <daniel@haxx.se>."
#define ARES_VERSION_MAJOR 1
-#define ARES_VERSION_MINOR 12
+#define ARES_VERSION_MINOR 13
#define ARES_VERSION_PATCH 0
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
(ARES_VERSION_MINOR<<8)|\
(ARES_VERSION_PATCH))
-#define ARES_VERSION_STR "1.12.0"
+#define ARES_VERSION_STR "1.13.0"
#if (ARES_VERSION >= 0x010700)
# define CARES_HAVE_ARES_LIBRARY_INIT 1
diff --git a/deps/cares/src/README b/deps/cares/src/README
deleted file mode 100644
index 2c128c8d7e..0000000000
--- a/deps/cares/src/README
+++ /dev/null
@@ -1,58 +0,0 @@
-c-ares
-======
-
-This is c-ares, an asynchronous resolver library. It is intended for
-applications which need to perform DNS queries without blocking, or need to
-perform multiple DNS queries in parallel. The primary examples of such
-applications are servers which communicate with multiple clients and programs
-with graphical user interfaces.
-
-The full source code is available in the 'c-ares' release archives, and in a
-git repository: http://github.com/bagder/c-ares
-
-If you find bugs, correct flaws, have questions or have comments in general in
-regard to c-ares (or by all means the original ares too), get in touch with us
-on the c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares
-
-c-ares is of course distributed under the same MIT-style license as the
-original ares.
-
-You'll find all c-ares details and news here:
-
- http://c-ares.haxx.se/
-
-
-NOTES FOR C-ARES HACKERS
-
-* The distributed ares_build.h file is only intended to be used on systems
- which can not run the also distributed configure script.
-
-* The distributed ares_build.h file is generated as a copy of ares_build.h.dist
- when the c-ares source code distribution archive file is originally created.
-
-* If you check out from git on a non-configure platform, you must run the
- appropriate buildconf* script to set up ares_build.h and other local files
- before being able of compiling the library.
-
-* On systems capable of running the configure script, the configure process
- will overwrite the distributed ares_build.h file with one that is suitable
- and specific to the library being configured and built, this new file is
- generated from the ares_build.h.in template file.
-
-* If you intend to distribute an already compiled c-ares library you _MUST_
- also distribute along with it the generated ares_build.h which has been
- used to compile it. Otherwise the library will be of no use for the users of
- the library that you have built. It is _your_ responsibility to provide this
- file. No one at the c-ares project can know how you have built the library.
-
-* File ares_build.h includes platform and configuration dependent info,
- and must not be modified by anyone. Configure script generates it for you.
-
-* We cannot assume anything else but very basic compiler features being
- present. While c-ares requires an ANSI C compiler to build, some of the
- earlier ANSI compilers clearly can't deal with some preprocessor operators.
-
-* Newlines must remain unix-style for older compilers' sake.
-
-* Comments must be written in the old-style /* unnested C-fashion */
-
diff --git a/deps/cares/src/README.md b/deps/cares/src/README.md
new file mode 100644
index 0000000000..6ad0168dc9
--- /dev/null
+++ b/deps/cares/src/README.md
@@ -0,0 +1,65 @@
+c-ares
+======
+
+[![Build Status](https://travis-ci.org/c-ares/c-ares.svg?branch=master)](https://travis-ci.org/c-ares/c-ares)
+[![Windows Build Status](https://ci.appveyor.com/api/projects/status/03i7151772eq3wn3/branch/master?svg=true)](https://ci.appveyor.com/project/c-ares/c-ares)
+[![Coverage Status](https://coveralls.io/repos/c-ares/c-ares/badge.svg?branch=master&service=github)](https://coveralls.io/github/c-ares/c-ares?branch=master)
+[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/291/badge)](https://bestpractices.coreinfrastructure.org/projects/291)
+
+This is c-ares, an asynchronous resolver library. It is intended for
+applications which need to perform DNS queries without blocking, or need to
+perform multiple DNS queries in parallel. The primary examples of such
+applications are servers which communicate with multiple clients and programs
+with graphical user interfaces.
+
+The full source code is available in the ['c-ares' release archives](https://c-ares.haxx.se/download/),
+and in a git repository: http://github.com/c-ares/c-ares. See the
+[INSTALL.md](INSTALL.md) file for build information.
+
+If you find bugs, correct flaws, have questions or have comments in general in
+regard to c-ares (or by all means the original ares too), get in touch with us
+on the c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares
+
+c-ares is of course distributed under the same MIT-style license as the
+original ares.
+
+You'll find all c-ares details and news here:
+ https://c-ares.haxx.se/
+
+
+Notes for c-ares hackers
+------------------------
+
+* The distributed `ares_build.h` file is only intended to be used on systems
+ which can not run the also distributed configure script.
+
+* The distributed `ares_build.h` file is generated as a copy of `ares_build.h.dist`
+ when the c-ares source code distribution archive file is originally created.
+
+* If you check out from git on a non-configure platform, you must run the
+ appropriate `buildconf*` script to set up `ares_build.h` and other local files
+ before being able to compile the library.
+
+* On systems capable of running the `configure` script, the `configure` process
+ will overwrite the distributed `ares_build.h` file with one that is suitable
+ and specific to the library being configured and built, this new file is
+ generated from the `ares_build.h.in` template file.
+
+* If you intend to distribute an already compiled c-ares library you **MUST**
+ also distribute along with it the generated `ares_build.h` which has been
+ used to compile it. Otherwise the library will be of no use for the users of
+ the library that you have built. It is **your** responsibility to provide this
+ file. No one at the c-ares project can know how you have built the library.
+
+* File `ares_build.h` includes platform and configuration dependent info,
+ and must not be modified by anyone. Configure script generates it for you.
+
+* We cannot assume anything else but very basic compiler features being
+ present. While c-ares requires an ANSI C compiler to build, some of the
+ earlier ANSI compilers clearly can't deal with some preprocessor operators.
+
+* Newlines must remain unix-style for older compilers' sake.
+
+* Comments must be written in the old-style /* unnested C-fashion */
+
+* Try to keep line lengths below 80 columns.
diff --git a/deps/cares/src/RELEASE-NOTES b/deps/cares/src/RELEASE-NOTES
index f6a4f70b44..122390473a 100644
--- a/deps/cares/src/RELEASE-NOTES
+++ b/deps/cares/src/RELEASE-NOTES
@@ -1,46 +1,53 @@
-c-ares version 1.12.0
+c-ares version 1.13.0
Changes:
- o api: add ARES_OPT_NOROTATE optmask value
+ o cmake build system support added
+ o Add virtual function set for socket IO: ares_set_socket_functions [5]
Bug fixes:
- o CVE-2016-5180: ares_create_query single byte out of buffer write [4]
- o configure: acknowledge --disable-tests [1]
- o man pages: fix typos detected by Lintian
- o test: add missing #includes for dns-proto.cc
- o test: avoid in6addr_* constants
- o test: Build with MinGW on AppVeyor
- o Makefile.m32: add support for extra flags
- o Makefile.m32: add support for CROSSPREFIX
- o configure: check if tests can get built before enabled
- o ares_library_cleanup: reset ares_realloc too
- o ahost.c: add cast to fix C++ compile
- o test: Only pass unused args to GoogleTest
- o build: commonize MSVC version detection
- o msvc_ver.inc: support Visual Studio 2015 Update 1, 2, 3
- o test: for AF_UNSPEC, return CNAME only for AAAA, but valid A record
- o ares_getnameinfo: explicitly clear struct servent before use
- o test: Update fuzzing function prototype
- o init: fix nsort initialization
- o test: add fuzzing check script to tests
- o web: http => https
- o read_tcp_data: remove superfluous NULL check
- o LICENSE.md: add a stand-alone license file
- o SECURITY.md: suggested "security process" for the project
- o ares_init_options: only propagate init failures from options [2]
- o headers: remove checks for and defines of variable sizes
- o test: fix gMock to work with gcc >= 6.x [3]
-
+ o CVE-2017-1000381: c-ares NAPTR parser out of bounds access [1]
+ o macos: do not set HAVE_CLOCK_GETTIME_MONOTONIC
+ o test: check ares_create_query with too-long name
+ o dist: add ares_library_initialized.* to the tarball
+ o fix build on OpenBSD
+ o dist: ship msvc_ver.inc too [2]
+ o test: Add gTest/gMock files to SOURCES
+ o test: add fuzz entrypoint for ares_create_query()
+ o configure: clock_gettime workaround [3]
+ o docs: convert INSTALL to MarkDown & tweak [4]
+ o ares_process: fix return type of socket_create function (win32 warning)
+ o docs: fixed references to ares_set_local_ip4 and ares_set_local_ip6
+ o Windows DNS server sorting [6]
+ o Use ares_socklen_t instead of socket_t [7]
+ o ares_create_query: use ares_free not naked free
+ o msvc_ver.inc support most recent Visual Studio 2017 [8]
+ o acountry: Convert char from ISO-8859-1 to UTF-8 [9]
+ o ares_expand_name: limit number of indirections
+ o configure: do not check for ar if specified manually [10]
+ o Added support for Windows DNS Suffix Search List [11]
+ o ares.h: support compiling with QNX [12]
+
Thanks go to these friendly people for their efforts and contributions:
- Alexander Drachevskiy, Brad House, Chris Araman, Daniel Stenberg,
- David Drysdale, Gregor Jasny, Svante Karlsson, Viktor Szakats
+ Aaron Bieber, Andrew Sullivan, Brad House, Bruce Stephens, Calle Wilund,
+ Chris Araman, Christian Ammer, Daniel Stenberg, David Drysdale, David Hotham,
+ Dionna Glaze, Gregor Jasny, Michael Osei, Mulle kybernetiK, noiz at github,
+ Sergii Pylypenko, Stephen Sorley, Thomas Köckerbauer,
+ (18 contributors)
References to bug reports and discussions on issues:
- [1] = https://github.com/c-ares/c-ares/issues/44
- [2] = https://github.com/c-ares/c-ares/issues/60
- [3] = https://github.com/google/googletest/issues/705#issuecomment-235067917
- [4] = https://c-ares.haxx.se/adv_20160929.html
+ [1] = https://c-ares.haxx.se/adv_20170620.html
+ [2] = https://github.com/c-ares/c-ares/issues/69
+ [3] = https://github.com/c-ares/c-ares/issues/71
+ [4] = https://github.com/c-ares/c-ares/issues/83
+ [5] = https://github.com/c-ares/c-ares/issues/72
+ [6] = https://github.com/c-ares/c-ares/issues/81
+ [7] = https://github.com/c-ares/c-ares/issues/92
+ [8] = https://github.com/c-ares/c-ares/issues/101
+ [9] = https://github.com/c-ares/c-ares/issues/97
+ [10] = https://github.com/c-ares/c-ares/issues/62
+ [11] = https://github.com/c-ares/c-ares/issues/93
+ [12] = https://github.com/c-ares/c-ares/issues/113
diff --git a/deps/cares/src/ares__close_sockets.c b/deps/cares/src/ares__close_sockets.c
index 6c66483b03..f07904e873 100644
--- a/deps/cares/src/ares__close_sockets.c
+++ b/deps/cares/src/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);
- sclose(server->tcp_socket);
+ ares__socket_close(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);
- sclose(server->udp_socket);
+ ares__socket_close(channel, server->udp_socket);
server->udp_socket = ARES_SOCKET_BAD;
}
}
diff --git a/deps/cares/src/ares_create_query.c b/deps/cares/src/ares_create_query.c
index 7f4c52d41d..07d7570114 100644
--- a/deps/cares/src/ares_create_query.c
+++ b/deps/cares/src/ares_create_query.c
@@ -134,7 +134,7 @@ int ares_create_query(const char *name, int dnsclass, int type,
while (*name)
{
if (*name == '.') {
- free (buf);
+ ares_free (buf);
return ARES_EBADNAME;
}
@@ -147,7 +147,7 @@ int ares_create_query(const char *name, int dnsclass, int type,
len++;
}
if (len > MAXLABEL) {
- free (buf);
+ ares_free (buf);
return ARES_EBADNAME;
}
@@ -190,7 +190,7 @@ int ares_create_query(const char *name, int dnsclass, int type,
* to 255 octets or less."). */
if (buflen > (MAXCDNAME + HFIXEDSZ + QFIXEDSZ +
(max_udp_size ? EDNSFIXEDSZ : 0))) {
- free (buf);
+ ares_free (buf);
return ARES_EBADNAME;
}
diff --git a/deps/cares/src/ares_expand_name.c b/deps/cares/src/ares_expand_name.c
index 738be8dccb..3a38e6737e 100644
--- a/deps/cares/src/ares_expand_name.c
+++ b/deps/cares/src/ares_expand_name.c
@@ -32,6 +32,9 @@
#include "ares_nowarn.h"
#include "ares_private.h" /* for the memdebug */
+/* Maximum number of indirections allowed for a name */
+#define MAX_INDIRS 50
+
static int name_length(const unsigned char *encoded, const unsigned char *abuf,
int alen);
@@ -66,7 +69,7 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
char *q;
const unsigned char *p;
union {
- ssize_t sig;
+ ares_ssize_t sig;
size_t uns;
} nlen;
@@ -162,7 +165,8 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf,
/* If we've seen more indirects than the message length,
* then there's a loop.
*/
- if (++indir > alen)
+ ++indir;
+ if (indir > alen || indir > MAX_INDIRS)
return -1;
}
else if (top == 0x00)
diff --git a/deps/cares/src/ares_expand_string.c b/deps/cares/src/ares_expand_string.c
index ed5476b91d..d35df75248 100644
--- a/deps/cares/src/ares_expand_string.c
+++ b/deps/cares/src/ares_expand_string.c
@@ -41,7 +41,7 @@ int ares_expand_string(const unsigned char *encoded,
{
unsigned char *q;
union {
- ssize_t sig;
+ ares_ssize_t sig;
size_t uns;
} elen;
diff --git a/deps/cares/src/ares_gethostbyaddr.c b/deps/cares/src/ares_gethostbyaddr.c
index a0a90f6bb1..9258919a38 100644
--- a/deps/cares/src/ares_gethostbyaddr.c
+++ b/deps/cares/src/ares_gethostbyaddr.c
@@ -157,7 +157,7 @@ static void addr_callback(void *arg, int status, int timeouts,
}
end_aquery(aquery, status, host);
}
- else if (status == ARES_EDESTRUCTION || status == ARES_ECANCELLED)
+ else if (status == ARES_EDESTRUCTION)
end_aquery(aquery, status, NULL);
else
next_lookup(aquery);
diff --git a/deps/cares/src/ares_getnameinfo.c b/deps/cares/src/ares_getnameinfo.c
index 45161124ca..c77b1f8153 100644
--- a/deps/cares/src/ares_getnameinfo.c
+++ b/deps/cares/src/ares_getnameinfo.c
@@ -356,12 +356,9 @@ static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags,
#ifdef HAVE_IF_INDEXTONAME
int is_ll, is_mcll;
#endif
- static const char fmt_u[] = "%u";
- static const char fmt_lu[] = "%lu";
char tmpbuf[IF_NAMESIZE + 2];
size_t bufl;
- const char *fmt = (sizeof(addr6->sin6_scope_id) > sizeof(unsigned int))?
- fmt_lu:fmt_u;
+ int is_scope_long = sizeof(addr6->sin6_scope_id) > sizeof(unsigned int);
tmpbuf[0] = '%';
@@ -371,15 +368,38 @@ static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags,
if ((flags & ARES_NI_NUMERICSCOPE) ||
(!is_ll && !is_mcll))
{
- sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
+ if (is_scope_long)
+ {
+ sprintf(&tmpbuf[1], "%lu", (unsigned long)addr6->sin6_scope_id);
+ }
+ else
+ {
+ sprintf(&tmpbuf[1], "%u", (unsigned int)addr6->sin6_scope_id);
+ }
}
else
{
if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL)
- sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
+ {
+ if (is_scope_long)
+ {
+ sprintf(&tmpbuf[1], "%lu", (unsigned long)addr6->sin6_scope_id);
+ }
+ else
+ {
+ sprintf(&tmpbuf[1], "%u", (unsigned int)addr6->sin6_scope_id);
+ }
+ }
}
#else
- sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
+ if (is_scope_long)
+ {
+ sprintf(&tmpbuf[1], "%lu", (unsigned long)addr6->sin6_scope_id);
+ }
+ else
+ {
+ sprintf(&tmpbuf[1], "%u", (unsigned int)addr6->sin6_scope_id);
+ }
(void) flags;
#endif
tmpbuf[IF_NAMESIZE + 1] = '\0';
diff --git a/deps/cares/src/ares_init.c b/deps/cares/src/ares_init.c
index f557947aa1..dbc67ed441 100644
--- a/deps/cares/src/ares_init.c
+++ b/deps/cares/src/ares_init.c
@@ -84,7 +84,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
const char *str);
static int sortlist_alloc(struct apattern **sortlist, int *nsort,
struct apattern *pat);
-static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
+static int ip_addr(const char *s, ares_ssize_t len, struct in_addr *addr);
static void natural_mask(struct apattern *pat);
#if !defined(WIN32) && !defined(WATT32) && \
!defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
@@ -166,6 +166,8 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
channel->sock_create_cb_data = NULL;
channel->sock_config_cb = NULL;
channel->sock_config_cb_data = NULL;
+ channel->sock_funcs = NULL;
+ channel->sock_func_cb_data = NULL;
channel->last_server = 0;
channel->last_timeout_processed = (time_t)now.tv_sec;
@@ -292,6 +294,8 @@ int ares_dup(ares_channel *dest, ares_channel src)
(*dest)->sock_create_cb_data = src->sock_create_cb_data;
(*dest)->sock_config_cb = src->sock_config_cb;
(*dest)->sock_config_cb_data = src->sock_config_cb_data;
+ (*dest)->sock_funcs = src->sock_funcs;
+ (*dest)->sock_func_cb_data = src->sock_func_cb_data;
strncpy((*dest)->local_dev_name, src->local_dev_name,
sizeof(src->local_dev_name));
@@ -828,6 +832,24 @@ static int get_DNS_Registry(char **outptr)
return 1;
}
+static void commanjoin(char** dst, const char* const src, const size_t len)
+{
+ char *newbuf;
+ size_t newsize;
+
+ /* 1 for terminating 0 and 2 for , and terminating 0 */
+ newsize = len + (*dst ? (strlen(*dst) + 2) : 1);
+ newbuf = ares_realloc(*dst, newsize);
+ if (!newbuf)
+ return;
+ if (*dst == NULL)
+ *newbuf = '\0';
+ *dst = newbuf;
+ if (strlen(*dst) != 0)
+ strcat(*dst, ",");
+ strncat(*dst, src, len);
+}
+
/*
* commajoin()
*
@@ -835,24 +857,7 @@ static int get_DNS_Registry(char **outptr)
*/
static void commajoin(char **dst, const char *src)
{
- char *tmp;
-
- if (*dst)
- {
- tmp = ares_malloc(strlen(*dst) + strlen(src) + 2);
- if (!tmp)
- return;
- sprintf(tmp, "%s,%s", *dst, src);
- ares_free(*dst);
- *dst = tmp;
- }
- else
- {
- *dst = ares_malloc(strlen(src) + 1);
- if (!*dst)
- return;
- strcpy(*dst, src);
- }
+ commanjoin(dst, src, strlen(src));
}
/*
@@ -939,6 +944,116 @@ done:
return 1;
}
+static BOOL ares_IsWindowsVistaOrGreater(void)
+{
+ OSVERSIONINFO vinfo;
+ memset(&vinfo, 0, sizeof(vinfo));
+ vinfo.dwOSVersionInfoSize = sizeof(vinfo);
+ if (!GetVersionEx(&vinfo) || vinfo.dwMajorVersion < 6)
+ return FALSE;
+ return TRUE;
+}
+
+/* A structure to hold the string form of IPv4 and IPv6 addresses so we can
+ * sort them by a metric.
+ */
+typedef struct
+{
+ /* The metric we sort them by. */
+ ULONG metric;
+
+ /* Room enough for the string form of any IPv4 or IPv6 address that
+ * ares_inet_ntop() will create. Based on the existing c-ares practice.
+ */
+ char text[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
+} Address;
+
+/* Sort Address values \a left and \a right by metric, returning the usual
+ * indicators for qsort().
+ */
+static int compareAddresses(const void *arg1,
+ const void *arg2)
+{
+ const Address * const left = arg1;
+ const Address * const right = arg2;
+ if(left->metric < right->metric) return -1;
+ if(left->metric > right->metric) return 1;
+ return 0;
+}
+
+/* There can be multiple routes to "the Internet". And there can be different
+ * DNS servers associated with each of the interfaces that offer those routes.
+ * We have to assume that any DNS server can serve any request. But, some DNS
+ * servers may only respond if requested over their associated interface. But
+ * we also want to use "the preferred route to the Internet" whenever possible
+ * (and not use DNS servers on a non-preferred route even by forcing request
+ * to go out on the associated non-preferred interface). i.e. We want to use
+ * the DNS servers associated with the same interface that we would use to
+ * make a general request to anything else.
+ *
+ * But, Windows won't sort the DNS servers by the metrics associated with the
+ * routes and interfaces _even_ though it obviously sends IP packets based on
+ * those same routes and metrics. So, we must do it ourselves.
+ *
+ * So, we sort the DNS servers by the same metric values used to determine how
+ * an outgoing IP packet will go, thus effectively using the DNS servers
+ * associated with the interface that the DNS requests themselves will
+ * travel. This gives us optimal routing and avoids issues where DNS servers
+ * won't respond to requests that don't arrive via some specific subnetwork
+ * (and thus some specific interface).
+ *
+ * This function computes the metric we use to sort. On the interface
+ * identified by \a luid, it determines the best route to \a dest and combines
+ * that route's metric with \a interfaceMetric to compute a metric for the
+ * destination address on that interface. This metric can be used as a weight
+ * to sort the DNS server addresses associated with each interface (lower is
+ * better).
+ *
+ * Note that by restricting the route search to the specific interface with
+ * which the DNS servers are associated, this function asks the question "What
+ * is the metric for sending IP packets to this DNS server?" which allows us
+ * to sort the DNS servers correctly.
+ */
+static ULONG getBestRouteMetric(IF_LUID * const luid, /* Can't be const :( */
+ const SOCKADDR_INET * const dest,
+ const ULONG interfaceMetric)
+{
+ /* On this interface, get the best route to that destination. */
+ MIB_IPFORWARD_ROW2 row;
+ SOCKADDR_INET ignored;
+ if(!ares_fpGetBestRoute2 ||
+ ares_fpGetBestRoute2(/* The interface to use. The index is ignored since we are
+ * passing a LUID.
+ */
+ luid, 0,
+ /* No specific source address. */
+ NULL,
+ /* Our destination address. */
+ dest,
+ /* No options. */
+ 0,
+ /* The route row. */
+ &row,
+ /* The best source address, which we don't need. */
+ &ignored) != NO_ERROR
+ /* If the metric is "unused" (-1) or too large for us to add the two
+ * metrics, use the worst possible, thus sorting this last.
+ */
+ || row.Metric == (ULONG)-1
+ || row.Metric > ((ULONG)-1) - interfaceMetric) {
+ /* Return the worst possible metric. */
+ return (ULONG)-1;
+ }
+
+ /* Return the metric value from that row, plus the interface metric.
+ *
+ * See
+ * http://msdn.microsoft.com/en-us/library/windows/desktop/aa814494(v=vs.85).aspx
+ * which describes the combination as a "sum".
+ */
+ return row.Metric + interfaceMetric;
+}
+
/*
* get_DNS_AdaptersAddresses()
*
@@ -965,14 +1080,19 @@ static int get_DNS_AdaptersAddresses(char **outptr)
int trying = IPAA_MAX_TRIES;
int res;
+ /* The capacity of addresses, in elements. */
+ size_t addressesSize;
+ /* The number of elements in addresses. */
+ size_t addressesIndex = 0;
+ /* The addresses we will sort. */
+ Address *addresses;
+
union {
struct sockaddr *sa;
struct sockaddr_in *sa4;
struct sockaddr_in6 *sa6;
} namesrvr;
- char txtaddr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
-
*outptr = NULL;
/* Verify run-time availability of GetAdaptersAddresses() */
@@ -983,6 +1103,17 @@ static int get_DNS_AdaptersAddresses(char **outptr)
if (!ipaa)
return 0;
+ /* Start with enough room for a few DNS server addresses and we'll grow it
+ * as we encounter more.
+ */
+ addressesSize = 4;
+ addresses = (Address*)ares_malloc(sizeof(Address) * addressesSize);
+ if(addresses == NULL) {
+ /* We need room for at least some addresses to function. */
+ ares_free(ipaa);
+ return 0;
+ }
+
/* Usually this call suceeds with initial buffer size */
res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
ipaa, &ReqBufsz);
@@ -1012,6 +1143,12 @@ static int get_DNS_AdaptersAddresses(char **outptr)
if(ipaaEntry->OperStatus != IfOperStatusUp)
continue;
+ /* For each interface, find any associated DNS servers as IPv4 or IPv6
+ * addresses. For each found address, find the best route to that DNS
+ * server address _on_ _that_ _interface_ (at this moment in time) and
+ * compute the resulting total metric, just as Windows routing will do.
+ * Then, sort all the addresses found by the metric.
+ */
for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
ipaDNSAddr;
ipaDNSAddr = ipaDNSAddr->Next)
@@ -1023,35 +1160,117 @@ static int get_DNS_AdaptersAddresses(char **outptr)
if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) ||
(namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE))
continue;
+
+ /* Allocate room for another address, if necessary, else skip. */
+ if(addressesIndex == addressesSize) {
+ const size_t newSize = addressesSize + 4;
+ Address * const newMem =
+ (Address*)ares_realloc(addresses, sizeof(Address) * newSize);
+ if(newMem == NULL) {
+ continue;
+ }
+ addresses = newMem;
+ addressesSize = newSize;
+ }
+
+ /* Vista required for Luid or Ipv4Metric */
+ if (ares_IsWindowsVistaOrGreater())
+ {
+ /* Save the address as the next element in addresses. */
+ addresses[addressesIndex].metric =
+ getBestRouteMetric(&ipaaEntry->Luid,
+ (SOCKADDR_INET*)(namesrvr.sa),
+ ipaaEntry->Ipv4Metric);
+ }
+ else
+ {
+ addresses[addressesIndex].metric = -1;
+ }
+
if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
- txtaddr, sizeof(txtaddr)))
+ addresses[addressesIndex].text,
+ sizeof(addresses[0].text))) {
continue;
+ }
+ ++addressesIndex;
}
else if (namesrvr.sa->sa_family == AF_INET6)
{
if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
sizeof(namesrvr.sa6->sin6_addr)) == 0)
continue;
+
+ /* Allocate room for another address, if necessary, else skip. */
+ if(addressesIndex == addressesSize) {
+ const size_t newSize = addressesSize + 4;
+ Address * const newMem =
+ (Address*)ares_realloc(addresses, sizeof(Address) * newSize);
+ if(newMem == NULL) {
+ continue;
+ }
+ addresses = newMem;
+ addressesSize = newSize;
+ }
+
+ /* Vista required for Luid or Ipv4Metric */
+ if (ares_IsWindowsVistaOrGreater())
+ {
+ /* Save the address as the next element in addresses. */
+ addresses[addressesIndex].metric =
+ getBestRouteMetric(&ipaaEntry->Luid,
+ (SOCKADDR_INET*)(namesrvr.sa),
+ ipaaEntry->Ipv6Metric);
+ }
+ else
+ {
+ addresses[addressesIndex].metric = -1;
+ }
+
if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr,
- txtaddr, sizeof(txtaddr)))
+ addresses[addressesIndex].text,
+ sizeof(addresses[0].text))) {
continue;
+ }
+ ++addressesIndex;
}
- else
+ else {
+ /* Skip non-IPv4/IPv6 addresses completely. */
continue;
+ }
+ }
+ }
- commajoin(outptr, txtaddr);
+ /* Sort all of the textual addresses by their metric. */
+ qsort(addresses, addressesIndex, sizeof(*addresses), compareAddresses);
- if (!*outptr)
- goto done;
+ /* Join them all into a single string, removing duplicates. */
+ {
+ size_t i;
+ for(i = 0; i < addressesIndex; ++i) {
+ size_t j;
+ /* Look for this address text appearing previously in the results. */
+ for(j = 0; j < i; ++j) {
+ if(strcmp(addresses[j].text, addresses[i].text) == 0) {
+ break;
+ }
+ }
+ /* Iff we didn't emit this address already, emit it now. */
+ if(j == i) {
+ /* Add that to outptr (if we can). */
+ commajoin(outptr, addresses[i].text);
+ }
}
}
done:
+ ares_free(addresses);
+
if (ipaa)
ares_free(ipaa);
- if (!*outptr)
+ if (!*outptr) {
return 0;
+ }
return 1;
}
@@ -1072,23 +1291,158 @@ done:
*/
static int get_DNS_Windows(char **outptr)
{
- /*
- Use GetNetworkParams First in case of
- multiple adapter is enabled on this machine.
- GetAdaptersAddresses will retrive dummy dns servers.
- That will slowing DNS lookup.
- */
- /* Try using IP helper API GetNetworkParams() */
- if (get_DNS_NetworkParams(outptr))
+ /* Try using IP helper API GetAdaptersAddresses(). IPv4 + IPv6, also sorts
+ * DNS servers by interface route metrics to try to use the best DNS server. */
+ if (get_DNS_AdaptersAddresses(outptr))
return 1;
- /* Try using IP helper API GetAdaptersAddresses() */
- if (get_DNS_AdaptersAddresses(outptr))
+ /* Try using IP helper API GetNetworkParams(). IPv4 only. */
+ if (get_DNS_NetworkParams(outptr))
return 1;
/* Fall-back to registry information */
return get_DNS_Registry(outptr);
}
+
+static void replace_comma_by_space(char* str)
+{
+ /* replace ',' by ' ' to coincide with resolv.conf search parameter */
+ char *p;
+ for (p = str; *p != '\0'; p++)
+ {
+ if (*p == ',')
+ *p = ' ';
+ }
+}
+
+/* Search if 'suffix' is containted in the 'searchlist'. Returns true if yes,
+ * otherwise false. 'searchlist' is a comma separated list of domain suffixes,
+ * 'suffix' is one domain suffix, 'len' is the length of 'suffix'.
+ * The search ignores case. E.g.:
+ * contains_suffix("abc.def,ghi.jkl", "ghi.JKL") returns true */
+static bool contains_suffix(const char* const searchlist,
+ const char* const suffix, const size_t len)
+{
+ const char* beg = searchlist;
+ const char* end;
+ if (!*suffix)
+ return true;
+ for (;;)
+ {
+ while (*beg && (ISSPACE(*beg) || (*beg == ',')))
+ ++beg;
+ if (!*beg)
+ return false;
+ end = beg;
+ while (*end && !ISSPACE(*end) && (*end != ','))
+ ++end;
+ if (len == (end - beg) && !strnicmp(beg, suffix, len))
+ return true;
+ beg = end;
+ }
+}
+
+/* advances list to the next suffix within a comma separated search list.
+ * len is the length of the next suffix. */
+static size_t next_suffix(const char** list, const size_t advance)
+{
+ const char* beg = *list + advance;
+ const char* end;
+ while (*beg && (ISSPACE(*beg) || (*beg == ',')))
+ ++beg;
+ end = beg;
+ while (*end && !ISSPACE(*end) && (*end != ','))
+ ++end;
+ *list = beg;
+ return end - beg;
+}
+
+/*
+ * get_SuffixList_Windows()
+ *
+ * Reads the "DNS Suffix Search List" from registry and writes the list items
+ * whitespace separated to outptr. If the Search List is empty, the
+ * "Primary Dns Suffix" is written to outptr.
+ *
+ * Returns 0 and nullifies *outptr upon inability to return the suffix list.
+ *
+ * Returns 1 and sets *outptr when returning a dynamically allocated string.
+ *
+ * Implementation supports Windows Server 2003 and newer
+ */
+static int get_SuffixList_Windows(char **outptr)
+{
+ HKEY hKey, hKeyEnum;
+ char keyName[256];
+ DWORD keyNameBuffSize;
+ DWORD keyIdx = 0;
+ char *p = NULL;
+ char *pp;
+ size_t len = 0;
+
+ *outptr = NULL;
+
+ if (ares__getplatform() != WIN_NT)
+ return 0;
+
+ /* 1. Global DNS Suffix Search List */
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
+ KEY_READ, &hKey) == ERROR_SUCCESS)
+ {
+ if (get_REG_SZ(hKey, SEARCHLIST_KEY, outptr))
+ replace_comma_by_space(*outptr);
+ RegCloseKey(hKey);
+ if (*outptr)
+ return 1;
+ }
+
+ /* 2. Connection Specific Search List composed of:
+ * a. Primary DNS Suffix */
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_DNSCLIENT, 0,
+ KEY_READ, &hKey) == ERROR_SUCCESS)
+ {
+ get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, outptr);
+ RegCloseKey(hKey);
+ }
+ if (!*outptr)
+ return 0;
+
+ /* b. Interface SearchList, Domain, DhcpDomain */
+ if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY "\\" INTERFACES_KEY, 0,
+ KEY_READ, &hKey) == ERROR_SUCCESS)
+ return 0;
+ for(;;)
+ {
+ keyNameBuffSize = sizeof(keyName);
+ if (RegEnumKeyEx(hKey, keyIdx++, keyName, &keyNameBuffSize,
+ 0, NULL, NULL, NULL)
+ != ERROR_SUCCESS)
+ break;
+ if (RegOpenKeyEx(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum)
+ != ERROR_SUCCESS)
+ continue;
+ if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p) ||
+ get_REG_SZ(hKeyEnum, DOMAIN_KEY, &p) ||
+ get_REG_SZ(hKeyEnum, DHCPDOMAIN_KEY, &p))
+ {
+ /* p can be comma separated (SearchList) */
+ pp = p;
+ while (len = next_suffix(&pp, len))
+ {
+ if (!contains_suffix(*outptr, pp, len))
+ commanjoin(outptr, pp, len);
+ }
+ ares_free(p);
+ p = NULL;
+ }
+ RegCloseKey(hKeyEnum);
+ }
+ RegCloseKey(hKey);
+ if (*outptr)
+ replace_comma_by_space(*outptr);
+ return *outptr != NULL;
+}
+
#endif
static int init_by_resolv_conf(ares_channel channel)
@@ -1112,6 +1466,12 @@ static int init_by_resolv_conf(ares_channel channel)
ares_free(line);
}
+ if (channel->ndomains == -1 && get_SuffixList_Windows(&line))
+ {
+ status = set_search(channel, line);
+ ares_free(line);
+ }
+
if (status == ARES_SUCCESS)
status = ARES_EOF;
else
@@ -1950,7 +2310,7 @@ static char *try_config(char *s, const char *opt, char scc)
}
#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
-static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
+static int ip_addr(const char *ipbuf, ares_ssize_t len, struct in_addr *addr)
{
/* Four octets and three periods yields at most 15 characters. */
@@ -2103,6 +2463,14 @@ void ares_set_socket_configure_callback(ares_channel channel,
channel->sock_config_cb_data = data;
}
+void ares_set_socket_functions(ares_channel channel,
+ const struct ares_socket_functions * funcs,
+ void *data)
+{
+ channel->sock_funcs = funcs;
+ channel->sock_func_cb_data = data;
+}
+
int ares_set_sortlist(ares_channel channel, const char *sortstr)
{
int nsort = 0;
diff --git a/deps/cares/src/ares_library_init.c b/deps/cares/src/ares_library_init.c
index c885a16c80..0a853d72cf 100644
--- a/deps/cares/src/ares_library_init.c
+++ b/deps/cares/src/ares_library_init.c
@@ -27,6 +27,7 @@
fpGetNetworkParams_t ares_fpGetNetworkParams = ZERO_NULL;
fpSystemFunction036_t ares_fpSystemFunction036 = ZERO_NULL;
fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses = ZERO_NULL;
+fpGetBestRoute2_t ares_fpGetBestRoute2 = ZERO_NULL;
#endif
/* library-private global vars with source visibility restricted to this file */
@@ -71,6 +72,15 @@ static int ares_win32_init(void)
support Windows 2000 anymore */
}
+ ares_fpGetBestRoute2 = (fpGetBestRoute2_t)
+ GetProcAddress(hnd_iphlpapi, "GetBestRoute2");
+ if (!ares_fpGetBestRoute2)
+ {
+ /* This can happen on clients before Vista, I don't
+ think it should be an error, unless we don't want to
+ support Windows XP anymore */
+ }
+
/*
* When advapi32.dll is unavailable or advapi32.dll has no SystemFunction036,
* also known as RtlGenRandom, which is the case for Windows versions prior
diff --git a/deps/cares/src/ares_library_init.h b/deps/cares/src/ares_library_init.h
index 59e5cc5893..2a2ba118b5 100644
--- a/deps/cares/src/ares_library_init.h
+++ b/deps/cares/src/ares_library_init.h
@@ -28,13 +28,14 @@
typedef DWORD (WINAPI *fpGetNetworkParams_t) (FIXED_INFO*, DWORD*);
typedef BOOLEAN (APIENTRY *fpSystemFunction036_t) (void*, ULONG);
typedef ULONG (WINAPI *fpGetAdaptersAddresses_t) ( ULONG, ULONG, void*, IP_ADAPTER_ADDRESSES*, ULONG* );
-
+typedef NETIO_STATUS (WINAPI *fpGetBestRoute2_t) ( NET_LUID *, NET_IFINDEX, const SOCKADDR_INET *, const SOCKADDR_INET *, ULONG, PMIB_IPFORWARD_ROW2, SOCKADDR_INET * );
/* Forward-declaration of variables defined in ares_library_init.c */
/* that are global and unique instances for whole c-ares library. */
extern fpGetNetworkParams_t ares_fpGetNetworkParams;
extern fpSystemFunction036_t ares_fpSystemFunction036;
extern fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses;
+extern fpGetBestRoute2_t ares_fpGetBestRoute2;
#endif /* USE_WINSOCK */
diff --git a/deps/cares/src/ares_nowarn.c b/deps/cares/src/ares_nowarn.c
index 7f9035c1a1..f63d9135ec 100644
--- a/deps/cares/src/ares_nowarn.c
+++ b/deps/cares/src/ares_nowarn.c
@@ -151,10 +151,10 @@ int aresx_sltosi(long slnum)
}
/*
-** signed ssize_t to signed int
+** signed ares_ssize_t to signed int
*/
-int aresx_sztosi(ssize_t sznum)
+int aresx_sztosi(ares_ssize_t sznum)
{
#ifdef __INTEL_COMPILER
# pragma warning(push)
@@ -162,7 +162,7 @@ int aresx_sztosi(ssize_t sznum)
#endif
DEBUGASSERT(sznum >= 0);
- return (int)(sznum & (ssize_t) CARES_MASK_SINT);
+ return (int)(sznum & (ares_ssize_t) CARES_MASK_SINT);
#ifdef __INTEL_COMPILER
# pragma warning(pop)
@@ -170,10 +170,10 @@ int aresx_sztosi(ssize_t sznum)
}
/*
-** signed ssize_t to unsigned int
+** signed ares_ssize_t to unsigned int
*/
-unsigned int aresx_sztoui(ssize_t sznum)
+unsigned int aresx_sztoui(ares_ssize_t sznum)
{
#ifdef __INTEL_COMPILER
# pragma warning(push)
@@ -181,7 +181,7 @@ unsigned int aresx_sztoui(ssize_t sznum)
#endif
DEBUGASSERT(sznum >= 0);
- return (unsigned int)(sznum & (ssize_t) CARES_MASK_UINT);
+ return (unsigned int)(sznum & (ares_ssize_t) CARES_MASK_UINT);
#ifdef __INTEL_COMPILER
# pragma warning(pop)
diff --git a/deps/cares/src/ares_nowarn.h b/deps/cares/src/ares_nowarn.h
index 9b76d66325..505e622098 100644
--- a/deps/cares/src/ares_nowarn.h
+++ b/deps/cares/src/ares_nowarn.h
@@ -25,9 +25,9 @@ short aresx_sitoss(int sinum);
int aresx_sltosi(long slnum);
-int aresx_sztosi(ssize_t sznum);
+int aresx_sztosi(ares_ssize_t sznum);
-unsigned int aresx_sztoui(ssize_t sznum);
+unsigned int aresx_sztoui(ares_ssize_t sznum);
unsigned short aresx_sitous(int sinum);
diff --git a/deps/cares/src/ares_parse_naptr_reply.c b/deps/cares/src/ares_parse_naptr_reply.c
index a14c226a9e..717d355778 100644
--- a/deps/cares/src/ares_parse_naptr_reply.c
+++ b/deps/cares/src/ares_parse_naptr_reply.c
@@ -110,19 +110,18 @@ ares_parse_naptr_reply (const unsigned char *abuf, int alen,
status = ARES_EBADRESP;
break;
}
+ /* RR must contain at least 7 bytes = 2 x int16 + 3 x name */
+ if (rr_len < 7)
+ {
+ status = ARES_EBADRESP;
+ break;
+ }
/* Check if we are really looking at a NAPTR record */
if (rr_class == C_IN && rr_type == T_NAPTR)
{
/* parse the NAPTR record itself */
- /* RR must contain at least 7 bytes = 2 x int16 + 3 x name */
- if (rr_len < 7)
- {
- status = ARES_EBADRESP;
- break;
- }
-
/* Allocate storage for this NAPTR answer appending it to the list */
naptr_curr = ares_malloc_data(ARES_DATATYPE_NAPTR_REPLY);
if (!naptr_curr)
diff --git a/deps/cares/src/ares_private.h b/deps/cares/src/ares_private.h
index 33a23e76d1..5d773869c7 100644
--- a/deps/cares/src/ares_private.h
+++ b/deps/cares/src/ares_private.h
@@ -54,10 +54,16 @@
#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
+#define WIN_DNSCLIENT "Software\\Policies\\Microsoft\\System\\DNSClient"
#define NAMESERVER "NameServer"
#define DHCPNAMESERVER "DhcpNameServer"
#define DATABASEPATH "DatabasePath"
#define WIN_PATH_HOSTS "\\hosts"
+#define SEARCHLIST_KEY "SearchList"
+#define PRIMARYDNSSUFFIX_KEY "PrimaryDNSSuffix"
+#define INTERFACES_KEY "Interfaces"
+#define DOMAIN_KEY "Domain"
+#define DHCPDOMAIN_KEY "DhcpDomain"
#elif defined(WATT32)
@@ -314,6 +320,9 @@ struct ares_channeldata {
ares_sock_config_callback sock_config_cb;
void *sock_config_cb_data;
+
+ const struct ares_socket_functions * sock_funcs;
+ void *sock_func_cb_data;
};
/* Memory management functions */
@@ -342,6 +351,8 @@ void ares__destroy_servers_state(ares_channel channel);
long ares__tvdiff(struct timeval t1, struct timeval t2);
#endif
+void ares__socket_close(ares_channel, ares_socket_t);
+
#define ARES_SWAP_BYTE(a,b) \
{ unsigned char swapByte = *(a); *(a) = *(b); *(b) = swapByte; }
diff --git a/deps/cares/src/ares_process.c b/deps/cares/src/ares_process.c
index 1d1e7b8b85..df85524f62 100644
--- a/deps/cares/src/ares_process.c
+++ b/deps/cares/src/ares_process.c
@@ -1,6 +1,6 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
- * Copyright (C) 2004-2016 by Daniel Stenberg
+ * Copyright (C) 2004-2017 by Daniel Stenberg
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
@@ -29,6 +29,9 @@
#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
@@ -65,7 +68,7 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds,
static void read_udp_packets(ares_channel channel, fd_set *read_fds,
ares_socket_t read_fd, struct timeval *now);
static void advance_tcp_send_queue(ares_channel channel, int whichserver,
- ssize_t num_bytes);
+ ares_ssize_t num_bytes);
static void process_timeouts(ares_channel channel, struct timeval *now);
static void process_broken_connections(ares_channel channel,
struct timeval *now);
@@ -175,6 +178,26 @@ static int try_again(int errnum)
return 0;
}
+static ares_ssize_t socket_writev(ares_channel channel, ares_socket_t s, const struct iovec * vec, int len)
+{
+ if (channel->sock_funcs)
+ return channel->sock_funcs->asendv(s, vec, len, channel->sock_func_cb_data);
+
+ return writev(s, vec, len);
+}
+
+static ares_ssize_t socket_write(ares_channel channel, ares_socket_t s, const void * data, size_t len)
+{
+ if (channel->sock_funcs)
+ {
+ struct iovec vec;
+ vec.iov_base = (void*)data;
+ vec.iov_len = len;
+ return channel->sock_funcs->asendv(s, &vec, 1, channel->sock_func_cb_data);
+ }
+ return swrite(s, data, len);
+}
+
/* If any TCP sockets select true for writing, write out queued data
* we have for them.
*/
@@ -187,8 +210,8 @@ static void write_tcp_data(ares_channel channel,
struct send_request *sendreq;
struct iovec *vec;
int i;
- ssize_t scount;
- ssize_t wcount;
+ ares_ssize_t scount;
+ ares_ssize_t wcount;
size_t n;
if(!write_fds && (write_fd == ARES_SOCKET_BAD))
@@ -238,7 +261,7 @@ static void write_tcp_data(ares_channel channel,
vec[n].iov_len = sendreq->len;
n++;
}
- wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n);
+ wcount = socket_writev(channel, server->tcp_socket, vec, (int)n);
ares_free(vec);
if (wcount < 0)
{
@@ -255,7 +278,7 @@ static void write_tcp_data(ares_channel channel,
/* Can't allocate iovecs; just send the first request. */
sendreq = server->qhead;
- scount = swrite(server->tcp_socket, sendreq->data, sendreq->len);
+ scount = socket_write(channel, server->tcp_socket, sendreq->data, sendreq->len);
if (scount < 0)
{
if (!try_again(SOCKERRNO))
@@ -271,7 +294,7 @@ static void write_tcp_data(ares_channel channel,
/* Consume the given number of bytes from the head of the TCP send queue. */
static void advance_tcp_send_queue(ares_channel channel, int whichserver,
- ssize_t num_bytes)
+ ares_ssize_t num_bytes)
{
struct send_request *sendreq;
struct server_state *server = &channel->servers[whichserver];
@@ -299,6 +322,38 @@ static void advance_tcp_send_queue(ares_channel channel, int whichserver,
}
}
+static ares_ssize_t socket_recvfrom(ares_channel channel,
+ ares_socket_t s,
+ void * data,
+ size_t data_len,
+ int flags,
+ struct sockaddr *from,
+ ares_socklen_t *from_len)
+{
+ if (channel->sock_funcs)
+ return channel->sock_funcs->arecvfrom(s, data, data_len,
+ flags, from, from_len,
+ channel->sock_func_cb_data);
+
+#ifdef HAVE_RECVFROM
+ return recvfrom(s, data, data_len, flags, from, from_len);
+#else
+ return sread(s, data, data_len);
+#endif
+}
+
+static ares_ssize_t socket_recv(ares_channel channel,
+ ares_socket_t s,
+ void * data,
+ size_t data_len)
+{
+ if (channel->sock_funcs)
+ return channel->sock_funcs->arecvfrom(s, data, data_len, 0, 0, 0,
+ channel->sock_func_cb_data);
+
+ return sread(s, data, data_len);
+}
+
/* If any TCP socket selects true for reading, read some data,
* allocate a buffer if we finish reading the length word, and process
* a packet if we finish reading one.
@@ -308,7 +363,7 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds,
{
struct server_state *server;
int i;
- ssize_t count;
+ ares_ssize_t count;
if(!read_fds && (read_fd == ARES_SOCKET_BAD))
/* no possible action */
@@ -343,9 +398,9 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds,
/* We haven't yet read a length word, so read that (or
* what's left to read of it).
*/
- count = sread(server->tcp_socket,
- server->tcp_lenbuf + server->tcp_lenbuf_pos,
- 2 - server->tcp_lenbuf_pos);
+ count = socket_recv(channel, server->tcp_socket,
+ server->tcp_lenbuf + server->tcp_lenbuf_pos,
+ 2 - server->tcp_lenbuf_pos);
if (count <= 0)
{
if (!(count == -1 && try_again(SOCKERRNO)))
@@ -373,9 +428,9 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds,
else
{
/* Read data into the allocated buffer. */
- count = sread(server->tcp_socket,
- server->tcp_buffer + server->tcp_buffer_pos,
- server->tcp_length - server->tcp_buffer_pos);
+ count = socket_recv(channel, server->tcp_socket,
+ server->tcp_buffer + server->tcp_buffer_pos,
+ server->tcp_length - server->tcp_buffer_pos);
if (count <= 0)
{
if (!(count == -1 && try_again(SOCKERRNO)))
@@ -406,7 +461,7 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds,
{
struct server_state *server;
int i;
- ssize_t count;
+ ares_ssize_t count;
unsigned char buf[MAXENDSSZ + 1];
#ifdef HAVE_RECVFROM
ares_socklen_t fromlen;
@@ -453,16 +508,12 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds,
count = 0;
else {
-#ifdef HAVE_RECVFROM
if (server->addr.family == AF_INET)
fromlen = sizeof(from.sa4);
else
fromlen = sizeof(from.sa6);
- count = (ssize_t)recvfrom(server->udp_socket, (void *)buf,
- sizeof(buf), 0, &from.sa, &fromlen);
-#else
- count = sread(server->udp_socket, buf, sizeof(buf));
-#endif
+ count = socket_recvfrom(channel, server->udp_socket, (void *)buf,
+ sizeof(buf), 0, &from.sa, &fromlen);
}
if (count == -1 && try_again(SOCKERRNO))
@@ -812,7 +863,7 @@ void ares__send_query(ares_channel channel, struct query *query,
return;
}
}
- if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1)
+ if (socket_write(channel, server->udp_socket, query->qbuf, query->qlen) == -1)
{
/* FIXME: Handle EAGAIN here since it likely can happen. */
skip_server(channel, query, query->server);
@@ -904,6 +955,10 @@ static int configure_socket(ares_socket_t s, int family, ares_channel channel)
struct sockaddr_in6 sa6;
} local;
+ /* do not set options for user-managed sockets */
+ if (channel->sock_funcs)
+ return 0;
+
(void)setsocknonblock(s, TRUE);
#if defined(FD_CLOEXEC) && !defined(MSDOS)
@@ -959,6 +1014,30 @@ 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;
@@ -1003,14 +1082,14 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
}
/* Acquire a socket. */
- s = socket(server->addr.family, SOCK_STREAM, 0);
+ s = 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)
{
- sclose(s);
+ ares__socket_close(channel, s);
return -1;
}
@@ -1022,10 +1101,12 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
* so batching isn't very interesting.
*/
opt = 1;
- if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
- (void *)&opt, sizeof(opt)) == -1)
+ if (channel->sock_funcs == 0
+ &&
+ setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
+ (void *)&opt, sizeof(opt)) == -1)
{
- sclose(s);
+ ares__socket_close(channel, s);
return -1;
}
#endif
@@ -1036,19 +1117,19 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
channel->sock_config_cb_data);
if (err < 0)
{
- sclose(s);
+ ares__socket_close(channel, s);
return err;
}
}
/* Connect to the server. */
- if (connect(s, sa, salen) == -1)
+ if (connect_socket(channel, s, sa, salen) == -1)
{
int err = SOCKERRNO;
if (err != EINPROGRESS && err != EWOULDBLOCK)
{
- sclose(s);
+ ares__socket_close(channel, s);
return -1;
}
}
@@ -1059,7 +1140,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
channel->sock_create_cb_data);
if (err < 0)
{
- sclose(s);
+ ares__socket_close(channel, s);
return err;
}
}
@@ -1114,14 +1195,14 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
}
/* Acquire a socket. */
- s = socket(server->addr.family, SOCK_DGRAM, 0);
+ s = 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)
{
- sclose(s);
+ ares__socket_close(channel, s);
return -1;
}
@@ -1131,19 +1212,19 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
channel->sock_config_cb_data);
if (err < 0)
{
- sclose(s);
+ ares__socket_close(channel, s);
return err;
}
}
/* Connect to the server. */
- if (connect(s, sa, salen) == -1)
+ if (connect_socket(channel, s, sa, salen) == -1)
{
int err = SOCKERRNO;
if (err != EINPROGRESS && err != EWOULDBLOCK)
{
- sclose(s);
+ ares__socket_close(channel, s);
return -1;
}
}
@@ -1154,7 +1235,7 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
channel->sock_create_cb_data);
if (err < 0)
{
- sclose(s);
+ ares__socket_close(channel, s);
return err;
}
}
@@ -1357,3 +1438,11 @@ void ares__free_query(struct query *query)
ares_free(query->server_info);
ares_free(query);
}
+
+void ares__socket_close(ares_channel channel, ares_socket_t s)
+{
+ if (channel->sock_funcs)
+ channel->sock_funcs->aclose(s, channel->sock_func_cb_data);
+ else
+ sclose(s);
+}
diff --git a/deps/cares/src/ares_writev.c b/deps/cares/src/ares_writev.c
index 008efddc57..e812c09e1c 100644
--- a/deps/cares/src/ares_writev.c
+++ b/deps/cares/src/ares_writev.c
@@ -25,12 +25,12 @@
#include "ares_private.h"
#ifndef HAVE_WRITEV
-ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt)
+ares_ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt)
{
char *buffer, *bp;
int i;
size_t bytes = 0;
- ssize_t result;
+ ares_ssize_t result;
/* Validate iovcnt */
if (iovcnt <= 0)
diff --git a/deps/cares/src/ares_writev.h b/deps/cares/src/ares_writev.h
index 1a23a0f3d1..65cea8708f 100644
--- a/deps/cares/src/ares_writev.h
+++ b/deps/cares/src/ares_writev.h
@@ -29,7 +29,7 @@ struct iovec
size_t iov_len; /* Length of data. */
};
-extern ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt);
+extern ares_ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt);
#endif
diff --git a/deps/cares/src/config-win32.h b/deps/cares/src/config-win32.h
index dd955252bd..cc8e4430a4 100644
--- a/deps/cares/src/config-win32.h
+++ b/deps/cares/src/config-win32.h
@@ -216,20 +216,6 @@
#define HAVE_BOOL_T
#endif
-/* Define if ssize_t is not an available 'typedefed' type. */
-#ifndef _SSIZE_T_DEFINED
-# if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \
- defined(__POCC__) || \
- defined(__MINGW32__)
-# elif defined(_WIN64)
-# define _SSIZE_T_DEFINED
-# define ssize_t __int64
-# else
-# define _SSIZE_T_DEFINED
-# define ssize_t int
-# endif
-#endif
-
/* ---------------------------------------------------------------- */
/* TYPE SIZES */
/* ---------------------------------------------------------------- */
@@ -259,31 +245,19 @@
# define _CRT_NONSTDC_NO_DEPRECATE 1
#endif
-/* Officially, Microsoft's Windows SDK versions 6.X do not support Windows
- 2000 as a supported build target. VS2008 default installations provide
- an embedded Windows SDK v6.0A along with the claim that Windows 2000 is
- a valid build target for VS2008. Popular belief is that binaries built
- with VS2008 using Windows SDK versions 6.X and Windows 2000 as a build
- target are functional. */
-#if defined(_MSC_VER) && (_MSC_VER >= 1500)
-# define VS2008_MIN_TARGET 0x0500
-#endif
-
-/* When no build target is specified VS2008 default build target is Windows
- Vista, which leaves out even Winsows XP. If no build target has been given
- for VS2008 we will target the minimum Officially supported build target,
- which happens to be Windows XP. */
+/* Set the Target to Vista. However, any symbols required above Win2000
+ * should be loaded via LoadLibrary() */
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
-# define VS2008_DEF_TARGET 0x0501
+# define VS2008_MIN_TARGET 0x0600
#endif
/* VS2008 default target settings and minimum build target check. */
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
# ifndef _WIN32_WINNT
-# define _WIN32_WINNT VS2008_DEF_TARGET
+# define _WIN32_WINNT VS2008_MIN_TARGET
# endif
# ifndef WINVER
-# define WINVER VS2008_DEF_TARGET
+# define WINVER VS2008_MIN_TARGET
# endif
# if (_WIN32_WINNT < VS2008_MIN_TARGET) || (WINVER < VS2008_MIN_TARGET)
# error VS2008 does not support Windows build targets prior to Windows 2000
@@ -291,13 +265,13 @@
#endif
/* When no build target is specified Pelles C 5.00 and later default build
- target is Windows Vista. We override default target to be Windows 2000. */
+ target is Windows Vista. */
#if defined(__POCC__) && (__POCC__ >= 500)
# ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0500
+# define _WIN32_WINNT 0x0600
# endif
# ifndef WINVER
-# define WINVER 0x0500
+# define WINVER 0x0600
# endif
#endif
diff --git a/deps/cares/src/inet_net_pton.c b/deps/cares/src/inet_net_pton.c
index b64fc5b1d1..af1a534a05 100644
--- a/deps/cares/src/inet_net_pton.c
+++ b/deps/cares/src/inet_net_pton.c
@@ -357,8 +357,8 @@ inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size)
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
- const ssize_t n = tp - colonp;
- ssize_t i;
+ const ares_ssize_t n = tp - colonp;
+ ares_ssize_t i;
if (tp == endp)
goto enoent;
diff --git a/deps/cares/src/setup_once.h b/deps/cares/src/setup_once.h
index 25b144ae2f..a8cfe6becc 100644
--- a/deps/cares/src/setup_once.h
+++ b/deps/cares/src/setup_once.h
@@ -131,7 +131,7 @@ struct timeval {
#if defined(__minix)
/* Minix doesn't support recv on TCP sockets */
-#define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \
+#define sread(x,y,z) (ares_ssize_t)read((RECV_TYPE_ARG1)(x), \
(RECV_TYPE_ARG2)(y), \
(RECV_TYPE_ARG3)(z))
@@ -167,7 +167,7 @@ struct timeval {
Error Missing_definition_of_return_and_arguments_types_of_recv
/* */
#else
-#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
+#define sread(x,y,z) (ares_ssize_t)recv((RECV_TYPE_ARG1)(x), \
(RECV_TYPE_ARG2)(y), \
(RECV_TYPE_ARG3)(z), \
(RECV_TYPE_ARG4)(0))
@@ -183,7 +183,7 @@ struct timeval {
#if defined(__minix)
/* Minix doesn't support send on TCP sockets */
-#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \
+#define swrite(x,y,z) (ares_ssize_t)write((SEND_TYPE_ARG1)(x), \
(SEND_TYPE_ARG2)(y), \
(SEND_TYPE_ARG3)(z))
@@ -198,7 +198,7 @@ struct timeval {
Error Missing_definition_of_return_and_arguments_types_of_send
/* */
#else
-#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
+#define swrite(x,y,z) (ares_ssize_t)send((SEND_TYPE_ARG1)(x), \
(SEND_TYPE_ARG2)(y), \
(SEND_TYPE_ARG3)(z), \
(SEND_TYPE_ARG4)(SEND_4TH_ARG))
@@ -228,7 +228,7 @@ struct timeval {
Error Missing_definition_of_return_and_arguments_types_of_recvfrom
/* */
#else
-#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \
+#define sreadfrom(s,b,bl,f,fl) (ares_ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \
(RECVFROM_TYPE_ARG2 *)(b), \
(RECVFROM_TYPE_ARG3) (bl), \
(RECVFROM_TYPE_ARG4) (0), \