mirror of https://github.com/nodejs/node.git
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>
This commit is contained in:
parent
d0d1eba872
commit
13c74706ef
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
c-ares
|
||||
======
|
||||
|
||||
[](https://travis-ci.org/c-ares/c-ares)
|
||||
[](https://ci.appveyor.com/project/c-ares/c-ares)
|
||||
[](https://coveralls.io/github/c-ares/c-ares?branch=master)
|
||||
[](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.
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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. */
|
||||
/* Set the Target to Vista. However, any symbols required above Win2000
|
||||
* should be loaded via LoadLibrary() */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
|
||||
# define VS2008_MIN_TARGET 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. */
|
||||
#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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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), \
|
||||
|
|
Loading…
Reference in New Issue