From 1258b0166dc6e68c2592be3410e54d5cb19bc04b Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Thu, 4 Feb 2016 16:34:47 -0500 Subject: deps: sync with upstream bagder/c-ares@2bae2d5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/5090 Reviewed-By: Saúl Ibarra Corretgé --- deps/cares/include/ares.h | 50 ++++- deps/cares/include/ares_build.h | 117 +++++++++++ deps/cares/include/ares_rules.h | 130 ++++++++++++ deps/cares/src/ares__close_sockets.c | 6 +- deps/cares/src/ares__get_hostent.c | 30 +-- deps/cares/src/ares__read_line.c | 7 +- deps/cares/src/ares__timeval.c | 2 +- deps/cares/src/ares_create_query.c | 2 +- deps/cares/src/ares_data.c | 44 ++-- deps/cares/src/ares_data.h | 16 +- deps/cares/src/ares_destroy.c | 22 +- deps/cares/src/ares_expand_name.c | 18 +- deps/cares/src/ares_expand_string.c | 2 +- deps/cares/src/ares_free_hostent.c | 12 +- deps/cares/src/ares_free_string.c | 2 +- deps/cares/src/ares_gethostbyaddr.c | 4 +- deps/cares/src/ares_gethostbyname.c | 16 +- deps/cares/src/ares_getnameinfo.c | 20 +- deps/cares/src/ares_init.c | 349 +++++++++++++++++++++----------- deps/cares/src/ares_library_init.c | 27 ++- deps/cares/src/ares_options.c | 157 ++++++++++++-- deps/cares/src/ares_parse_a_reply.c | 54 ++--- deps/cares/src/ares_parse_aaaa_reply.c | 54 ++--- deps/cares/src/ares_parse_mx_reply.c | 8 +- deps/cares/src/ares_parse_naptr_reply.c | 8 +- deps/cares/src/ares_parse_ns_reply.c | 38 ++-- deps/cares/src/ares_parse_ptr_reply.c | 58 +++--- deps/cares/src/ares_parse_soa_reply.c | 8 +- deps/cares/src/ares_parse_srv_reply.c | 8 +- deps/cares/src/ares_parse_txt_reply.c | 49 +++-- deps/cares/src/ares_private.h | 25 ++- deps/cares/src/ares_process.c | 89 ++++---- deps/cares/src/ares_query.c | 6 +- deps/cares/src/ares_rules.h | 130 ------------ deps/cares/src/ares_search.c | 36 ++-- deps/cares/src/ares_send.c | 14 +- deps/cares/src/ares_strdup.c | 35 ++-- deps/cares/src/ares_strdup.h | 2 - deps/cares/src/ares_writev.c | 4 +- deps/cares/src/bitncmp.c | 2 +- deps/cares/src/inet_net_pton.c | 2 +- 41 files changed, 1085 insertions(+), 578 deletions(-) create mode 100644 deps/cares/include/ares_build.h create mode 100644 deps/cares/include/ares_rules.h delete mode 100644 deps/cares/src/ares_rules.h (limited to 'deps/cares') diff --git a/deps/cares/include/ares.h b/deps/cares/include/ares.h index f9abe854d5..fcbcecfc49 100644 --- a/deps/cares/include/ares.h +++ b/deps/cares/include/ares.h @@ -19,6 +19,8 @@ #define ARES__H #include "ares_version.h" /* c-ares version defines */ +#include "ares_build.h" /* c-ares build definitions */ +#include "ares_rules.h" /* c-ares rules enforcement */ /* * Define WIN32 when build target is Win32 API @@ -29,9 +31,6 @@ # define WIN32 #endif -/* Data type definition of ares_socklen_t. */ -typedef unsigned ares_socklen_t; - #include /* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish @@ -297,6 +296,13 @@ typedef int (*ares_sock_create_callback)(ares_socket_t socket_fd, CARES_EXTERN int ares_library_init(int flags); +CARES_EXTERN int ares_library_init_mem(int flags, + void *(*amalloc)(size_t size), + void (*afree)(void *ptr), + void *(*arealloc)(void *ptr, size_t size)); + +CARES_EXTERN int ares_library_initialized(void); + CARES_EXTERN void ares_library_cleanup(void); CARES_EXTERN const char *ares_version(int *version); @@ -338,6 +344,9 @@ CARES_EXTERN void ares_set_socket_callback(ares_channel channel, ares_sock_create_callback callback, void *user_data); +CARES_EXTERN int ares_set_sortlist(ares_channel channel, + const char *sortstr); + CARES_EXTERN void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, @@ -473,8 +482,17 @@ struct ares_txt_reply { struct ares_txt_reply *next; unsigned char *txt; size_t length; /* length excludes null termination */ - unsigned char record_start; /* 1 - if start of new record - * 0 - if a chunk in the same record */ +}; + +/* NOTE: This structure is a superset of ares_txt_reply + */ +struct ares_txt_ext { + struct ares_txt_ext *next; + unsigned char *txt; + size_t length; + /* 1 - if start of new record + * 0 - if a chunk in the same record */ + unsigned char record_start; }; struct ares_naptr_reply { @@ -540,6 +558,10 @@ CARES_EXTERN int ares_parse_txt_reply(const unsigned char* abuf, int alen, struct ares_txt_reply** txt_out); +CARES_EXTERN int ares_parse_txt_reply_ext(const unsigned char* abuf, + int alen, + struct ares_txt_ext** txt_out); + CARES_EXTERN int ares_parse_naptr_reply(const unsigned char* abuf, int alen, struct ares_naptr_reply** naptr_out); @@ -556,7 +578,6 @@ CARES_EXTERN void ares_free_data(void *dataptr); CARES_EXTERN const char *ares_strerror(int code); -/* TODO: Hold port here as well. */ struct ares_addr_node { struct ares_addr_node *next; int family; @@ -566,15 +587,32 @@ struct ares_addr_node { } addr; }; +struct ares_addr_port_node { + struct ares_addr_port_node *next; + int family; + union { + struct in_addr addr4; + struct ares_in6_addr addr6; + } addr; + int udp_port; + int tcp_port; +}; + CARES_EXTERN int ares_set_servers(ares_channel channel, struct ares_addr_node *servers); +CARES_EXTERN int ares_set_servers_ports(ares_channel channel, + struct ares_addr_port_node *servers); /* Incomming string format: host[:port][,host[:port]]... */ CARES_EXTERN int ares_set_servers_csv(ares_channel channel, const char* servers); +CARES_EXTERN int ares_set_servers_ports_csv(ares_channel channel, + const char* servers); CARES_EXTERN int ares_get_servers(ares_channel channel, struct ares_addr_node **servers); +CARES_EXTERN int ares_get_servers_ports(ares_channel channel, + struct ares_addr_port_node **servers); CARES_EXTERN const char *ares_inet_ntop(int af, const void *src, char *dst, ares_socklen_t size); diff --git a/deps/cares/include/ares_build.h b/deps/cares/include/ares_build.h new file mode 100644 index 0000000000..199eae8b8e --- /dev/null +++ b/deps/cares/include/ares_build.h @@ -0,0 +1,117 @@ +/* ares_build.h. Generated from ares_build.h.in by configure. */ +#ifndef __CARES_BUILD_H +#define __CARES_BUILD_H + + +/* Copyright (C) 2009 by Daniel Stenberg et al + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * c-ares library user nor by the c-ares library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the c-ares development + * mailing list: http://cool.haxx.se/mailman/listinfo/c-ares/ + * + * This header file shall only export symbols which are 'cares' or 'CARES' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * Right now you might be staring at file ares_build.h.in or ares_build.h, + * this is due to the following reason: + * + * 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, which is generated + * from the ares_build.h.in template file. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CARES_SIZEOF_LONG +# error "CARES_SIZEOF_LONG shall not be defined except in ares_build.h" + Error Compilation_aborted_CARES_SIZEOF_LONG_already_defined +#endif + +#ifdef CARES_TYPEOF_ARES_SOCKLEN_T +# error "CARES_TYPEOF_ARES_SOCKLEN_T shall not be defined except in ares_build.h" + Error Compilation_aborted_CARES_TYPEOF_ARES_SOCKLEN_T_already_defined +#endif + +#ifdef CARES_SIZEOF_ARES_SOCKLEN_T +# error "CARES_SIZEOF_ARES_SOCKLEN_T shall not be defined except in ares_build.h" + Error Compilation_aborted_CARES_SIZEOF_ARES_SOCKLEN_T_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ +/* ================================================================ */ + +/* Configure process defines this to 1 when it finds out that system */ +/* header file ws2tcpip.h must be included by the external interface. */ + +#ifdef WIN32 +# define CARES_PULL_WS2TCPIP_H 1 +#else +# define CARES_PULL_SYS_TYPES_H 1 +# define CARES_PULL_SYS_SOCKET_H 1 +#endif + +/* #undef CARES_PULL_WS2TCPIP_H */ +#ifdef CARES_PULL_WS2TCPIP_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# include +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/types.h must be included by the external interface. */ +#ifdef CARES_PULL_SYS_TYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/socket.h must be included by the external interface. */ +#ifdef CARES_PULL_SYS_SOCKET_H +# include +#endif + +/* The size of `long', as computed by sizeof. */ +/* #undef CARES_SIZEOF_LONG */ + +/* Integral data type used for ares_socklen_t. */ +#define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t + +/* The size of `ares_socklen_t', as computed by sizeof. */ +#define CARES_SIZEOF_ARES_SOCKLEN_T 4 + +/* Data type definition of ares_socklen_t. */ +typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t; + +#endif /* __CARES_BUILD_H */ diff --git a/deps/cares/include/ares_rules.h b/deps/cares/include/ares_rules.h new file mode 100644 index 0000000000..44f08f807c --- /dev/null +++ b/deps/cares/include/ares_rules.h @@ -0,0 +1,130 @@ +#ifndef __CARES_RULES_H +#define __CARES_RULES_H + + +/* Copyright (C) 2009 by Daniel Stenberg et al + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +/* ================================================================ */ +/* COMPILE TIME SANITY CHECKS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * All checks done in this file are intentionally placed in a public + * header file which is pulled by ares.h when an application is + * being built using an already built c-ares library. Additionally + * this file is also included and used when building the library. + * + * If compilation fails on this file it is certainly sure that the + * problem is elsewhere. It could be a problem in the ares_build.h + * header file, or simply that you are using different compilation + * settings than those used to build the library. + * + * Nothing in this file is intended to be modified or adjusted by the + * c-ares library user nor by the c-ares library builder. + * + * Do not deactivate any check, these are done to make sure that the + * library is properly built and used. + * + * You can find further help on the c-ares development mailing list: + * http://cool.haxx.se/mailman/listinfo/c-ares/ + * + * NOTE 2 + * ------ + * + * Some of the following compile time checks are based on the fact + * that the dimension of a constant array can not be a negative one. + * In this way if the compile time verification fails, the compilation + * will fail issuing an error. The error description wording is compiler + * dependent but it will be quite similar to one of the following: + * + * "negative subscript or subscript is too large" + * "array must have at least one element" + * "-1 is an illegal array size" + * "size of array is negative" + * + * If you are building an application which tries to use an already + * built c-ares library and you are getting this kind of errors on + * this file, it is a clear indication that there is a mismatch between + * how the library was built and how you are trying to use it for your + * application. Your already compiled or binary library provider is the + * only one who can give you the details you need to properly use it. + */ + +/* + * Verify that some macros are actually defined. + */ + +#ifndef CARES_TYPEOF_ARES_SOCKLEN_T +# error "CARES_TYPEOF_ARES_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CARES_TYPEOF_ARES_SOCKLEN_T_is_missing +#endif + +#ifndef CARES_SIZEOF_ARES_SOCKLEN_T +# error "CARES_SIZEOF_ARES_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CARES_SIZEOF_ARES_SOCKLEN_T_is_missing +#endif + +/* + * Macros private to this header file. + */ + +#define CareschkszEQ(t, s) sizeof(t) == s ? 1 : -1 + +#define CareschkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 + +/* + * Verify that the size previously defined and expected for + * ares_socklen_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __cares_rule_02__ + [CareschkszEQ(ares_socklen_t, CARES_SIZEOF_ARES_SOCKLEN_T)]; + +/* + * Verify at compile time that the size of ares_socklen_t as reported + * by sizeof() is greater or equal than the one reported for int for + * the current compilation. + */ + +typedef char + __cares_rule_03__ + [CareschkszGE(ares_socklen_t, int)]; + +/* ================================================================ */ +/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ +/* ================================================================ */ + +/* + * Get rid of macros private to this header file. + */ + +#undef CareschkszEQ +#undef CareschkszGE + +/* + * Get rid of macros not intended to exist beyond this point. + */ + +#undef CARES_PULL_WS2TCPIP_H +#undef CARES_PULL_SYS_TYPES_H +#undef CARES_PULL_SYS_SOCKET_H + +#undef CARES_TYPEOF_ARES_SOCKLEN_T + +#endif /* __CARES_RULES_H */ diff --git a/deps/cares/src/ares__close_sockets.c b/deps/cares/src/ares__close_sockets.c index d3d85ff183..6c66483b03 100644 --- a/deps/cares/src/ares__close_sockets.c +++ b/deps/cares/src/ares__close_sockets.c @@ -30,14 +30,14 @@ void ares__close_sockets(ares_channel channel, struct server_state *server) sendreq = server->qhead; server->qhead = sendreq->next; if (sendreq->data_storage != NULL) - free(sendreq->data_storage); - free(sendreq); + ares_free(sendreq->data_storage); + ares_free(sendreq); } server->qtail = NULL; /* Reset any existing input buffer. */ if (server->tcp_buffer) - free(server->tcp_buffer); + ares_free(server->tcp_buffer); server->tcp_buffer = NULL; server->tcp_lenbuf_pos = 0; diff --git a/deps/cares/src/ares__get_hostent.c b/deps/cares/src/ares__get_hostent.c index 4497d60d0d..d2f9503493 100644 --- a/deps/cares/src/ares__get_hostent.c +++ b/deps/cares/src/ares__get_hostent.c @@ -94,7 +94,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) p++; if (!*p) /* Ignore line if reached end of line. */ - continue; + continue; /* LCOV_EXCL_LINE: trailing whitespace already stripped */ /* Pointer to start of host name. */ txthost = p; @@ -164,7 +164,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) */ /* Allocate memory for the hostent structure. */ - hostent = malloc(sizeof(struct hostent)); + hostent = ares_malloc(sizeof(struct hostent)); if (!hostent) break; @@ -173,16 +173,16 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) hostent->h_addr_list = NULL; /* Copy official host name. */ - hostent->h_name = strdup(txthost); + hostent->h_name = ares_strdup(txthost); if (!hostent->h_name) break; /* Copy network address. */ - hostent->h_addr_list = malloc(2 * sizeof(char *)); + hostent->h_addr_list = ares_malloc(2 * sizeof(char *)); if (!hostent->h_addr_list) break; hostent->h_addr_list[1] = NULL; - hostent->h_addr_list[0] = malloc(addrlen); + hostent->h_addr_list[0] = ares_malloc(addrlen); if (!hostent->h_addr_list[0]) break; if (addr.family == AF_INET) @@ -191,7 +191,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) memcpy(hostent->h_addr_list[0], &addr.addrV6, sizeof(addr.addrV6)); /* Copy aliases. */ - hostent->h_aliases = malloc((naliases + 1) * sizeof(char *)); + hostent->h_aliases = ares_malloc((naliases + 1) * sizeof(char *)); if (!hostent->h_aliases) break; alias = hostent->h_aliases; @@ -207,7 +207,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) while (*q && ISSPACE(*q)) q++; *p = '\0'; - if ((*alias = strdup(txtalias)) == NULL) + if ((*alias = ares_strdup(txtalias)) == NULL) break; alias++; txtalias = *q ? q : NULL; @@ -221,7 +221,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) hostent->h_length = aresx_uztoss(addrlen); /* Free line buffer. */ - free(line); + ares_free(line); /* Return hostent successfully */ *host = hostent; @@ -231,7 +231,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) /* If allocated, free line buffer. */ if (line) - free(line); + ares_free(line); if (status == ARES_SUCCESS) { @@ -239,20 +239,20 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) if (hostent) { if (hostent->h_name) - free((char *) hostent->h_name); + ares_free((char *) hostent->h_name); if (hostent->h_aliases) { for (alias = hostent->h_aliases; *alias; alias++) - free(*alias); - free(hostent->h_aliases); + ares_free(*alias); + ares_free(hostent->h_aliases); } if (hostent->h_addr_list) { if (hostent->h_addr_list[0]) - free(hostent->h_addr_list[0]); - free(hostent->h_addr_list); + ares_free(hostent->h_addr_list[0]); + ares_free(hostent->h_addr_list); } - free(hostent); + ares_free(hostent); } return ARES_ENOMEM; } diff --git a/deps/cares/src/ares__read_line.c b/deps/cares/src/ares__read_line.c index 6ebd42fe6e..c62ad2a2b4 100644 --- a/deps/cares/src/ares__read_line.c +++ b/deps/cares/src/ares__read_line.c @@ -36,7 +36,7 @@ int ares__read_line(FILE *fp, char **buf, size_t *bufsize) if (*buf == NULL) { - *buf = malloc(128); + *buf = ares_malloc(128); if (!*buf) return ARES_ENOMEM; *bufsize = 128; @@ -59,10 +59,11 @@ int ares__read_line(FILE *fp, char **buf, size_t *bufsize) continue; /* Allocate more space. */ - newbuf = realloc(*buf, *bufsize * 2); + newbuf = ares_realloc(*buf, *bufsize * 2); if (!newbuf) { - free(*buf); + ares_free(*buf); + *buf = NULL; return ARES_ENOMEM; } *buf = newbuf; diff --git a/deps/cares/src/ares__timeval.c b/deps/cares/src/ares__timeval.c index f7aa7883f9..94efb7db1e 100644 --- a/deps/cares/src/ares__timeval.c +++ b/deps/cares/src/ares__timeval.c @@ -56,7 +56,7 @@ struct timeval ares__tvnow(void) */ #ifdef HAVE_GETTIMEOFDAY else - (void)gettimeofday(&now, NULL); + (void)gettimeofday(&now, NULL); /* LCOV_EXCL_LINE */ #else else { now.tv_sec = (long)time(NULL); diff --git a/deps/cares/src/ares_create_query.c b/deps/cares/src/ares_create_query.c index 8624e2f589..a34dda7de6 100644 --- a/deps/cares/src/ares_create_query.c +++ b/deps/cares/src/ares_create_query.c @@ -130,7 +130,7 @@ int ares_create_query(const char *name, int dnsclass, int type, return ARES_EBADNAME; *buflen = len + HFIXEDSZ + QFIXEDSZ + (max_udp_size ? EDNSFIXEDSZ : 0); - *buf = malloc(*buflen); + *buf = ares_malloc(*buflen); if (!*buf) return ARES_ENOMEM; diff --git a/deps/cares/src/ares_data.c b/deps/cares/src/ares_data.c index b86ca90c2b..f891113815 100644 --- a/deps/cares/src/ares_data.c +++ b/deps/cares/src/ares_data.c @@ -67,7 +67,7 @@ void ares_free_data(void *dataptr) if (ptr->data.mx_reply.next) ares_free_data(ptr->data.mx_reply.next); if (ptr->data.mx_reply.host) - free(ptr->data.mx_reply.host); + ares_free(ptr->data.mx_reply.host); break; case ARES_DATATYPE_SRV_REPLY: @@ -75,15 +75,16 @@ void ares_free_data(void *dataptr) if (ptr->data.srv_reply.next) ares_free_data(ptr->data.srv_reply.next); if (ptr->data.srv_reply.host) - free(ptr->data.srv_reply.host); + ares_free(ptr->data.srv_reply.host); break; case ARES_DATATYPE_TXT_REPLY: + case ARES_DATATYPE_TXT_EXT: if (ptr->data.txt_reply.next) ares_free_data(ptr->data.txt_reply.next); if (ptr->data.txt_reply.txt) - free(ptr->data.txt_reply.txt); + ares_free(ptr->data.txt_reply.txt); break; case ARES_DATATYPE_ADDR_NODE: @@ -92,32 +93,38 @@ void ares_free_data(void *dataptr) ares_free_data(ptr->data.addr_node.next); break; + case ARES_DATATYPE_ADDR_PORT_NODE: + + if (ptr->data.addr_port_node.next) + ares_free_data(ptr->data.addr_port_node.next); + break; + case ARES_DATATYPE_NAPTR_REPLY: if (ptr->data.naptr_reply.next) ares_free_data(ptr->data.naptr_reply.next); if (ptr->data.naptr_reply.flags) - free(ptr->data.naptr_reply.flags); + ares_free(ptr->data.naptr_reply.flags); if (ptr->data.naptr_reply.service) - free(ptr->data.naptr_reply.service); + ares_free(ptr->data.naptr_reply.service); if (ptr->data.naptr_reply.regexp) - free(ptr->data.naptr_reply.regexp); + ares_free(ptr->data.naptr_reply.regexp); if (ptr->data.naptr_reply.replacement) - free(ptr->data.naptr_reply.replacement); + ares_free(ptr->data.naptr_reply.replacement); break; case ARES_DATATYPE_SOA_REPLY: if (ptr->data.soa_reply.nsname) - free(ptr->data.soa_reply.nsname); + ares_free(ptr->data.soa_reply.nsname); if (ptr->data.soa_reply.hostmaster) - free(ptr->data.soa_reply.hostmaster); + ares_free(ptr->data.soa_reply.hostmaster); break; default: return; } - free(ptr); + ares_free(ptr); } @@ -136,7 +143,7 @@ void *ares_malloc_data(ares_datatype type) { struct ares_data *ptr; - ptr = malloc(sizeof(struct ares_data)); + ptr = ares_malloc(sizeof(struct ares_data)); if (!ptr) return NULL; @@ -156,6 +163,10 @@ void *ares_malloc_data(ares_datatype type) ptr->data.srv_reply.port = 0; break; + case ARES_DATATYPE_TXT_EXT: + ptr->data.txt_ext.record_start = 0; + /* FALLTHROUGH */ + case ARES_DATATYPE_TXT_REPLY: ptr->data.txt_reply.next = NULL; ptr->data.txt_reply.txt = NULL; @@ -169,6 +180,15 @@ void *ares_malloc_data(ares_datatype type) sizeof(ptr->data.addr_node.addrV6)); break; + case ARES_DATATYPE_ADDR_PORT_NODE: + ptr->data.addr_port_node.next = NULL; + ptr->data.addr_port_node.family = 0; + ptr->data.addr_port_node.udp_port = 0; + ptr->data.addr_port_node.tcp_port = 0; + memset(&ptr->data.addr_port_node.addrV6, 0, + sizeof(ptr->data.addr_port_node.addrV6)); + break; + case ARES_DATATYPE_NAPTR_REPLY: ptr->data.naptr_reply.next = NULL; ptr->data.naptr_reply.flags = NULL; @@ -190,7 +210,7 @@ void *ares_malloc_data(ares_datatype type) break; default: - free(ptr); + ares_free(ptr); return NULL; } diff --git a/deps/cares/src/ares_data.h b/deps/cares/src/ares_data.h index 12e3b672df..ffee2be6ba 100644 --- a/deps/cares/src/ares_data.h +++ b/deps/cares/src/ares_data.h @@ -18,6 +18,7 @@ typedef enum { ARES_DATATYPE_UNKNOWN = 1, /* unknown data type - introduced in 1.7.0 */ ARES_DATATYPE_SRV_REPLY, /* struct ares_srv_reply - introduced in 1.7.0 */ ARES_DATATYPE_TXT_REPLY, /* struct ares_txt_reply - introduced in 1.7.0 */ + ARES_DATATYPE_TXT_EXT, /* struct ares_txt_ext - introduced in 1.11.0 */ ARES_DATATYPE_ADDR_NODE, /* struct ares_addr_node - introduced in 1.7.1 */ ARES_DATATYPE_MX_REPLY, /* struct ares_mx_reply - introduced in 1.7.2 */ ARES_DATATYPE_NAPTR_REPLY,/* struct ares_naptr_reply - introduced in 1.7.6 */ @@ -28,6 +29,7 @@ typedef enum { ARES_DATATYPE_HOSTENT, /* struct hostent */ ARES_DATATYPE_OPTIONS, /* struct ares_options */ #endif + ARES_DATATYPE_ADDR_PORT_NODE, /* struct ares_addr_port_node - introduced in 1.11.0 */ ARES_DATATYPE_LAST /* not used - introduced in 1.7.0 */ } ares_datatype; @@ -55,12 +57,14 @@ struct ares_data { ares_datatype type; /* Actual data type identifier. */ unsigned int mark; /* Private ares_data signature. */ union { - struct ares_txt_reply txt_reply; - struct ares_srv_reply srv_reply; - struct ares_addr_node addr_node; - struct ares_mx_reply mx_reply; - struct ares_naptr_reply naptr_reply; - struct ares_soa_reply soa_reply; + struct ares_txt_reply txt_reply; + struct ares_txt_ext txt_ext; + struct ares_srv_reply srv_reply; + struct ares_addr_node addr_node; + struct ares_addr_port_node addr_port_node; + struct ares_mx_reply mx_reply; + struct ares_naptr_reply naptr_reply; + struct ares_soa_reply soa_reply; } data; }; diff --git a/deps/cares/src/ares_destroy.c b/deps/cares/src/ares_destroy.c index 6c1f32442e..8aa42236ae 100644 --- a/deps/cares/src/ares_destroy.c +++ b/deps/cares/src/ares_destroy.c @@ -27,15 +27,15 @@ void ares_destroy_options(struct ares_options *options) int i; if(options->servers) - free(options->servers); + ares_free(options->servers); for (i = 0; i < options->ndomains; i++) - free(options->domains[i]); + ares_free(options->domains[i]); if(options->domains) - free(options->domains); + ares_free(options->domains); if(options->sortlist) - free(options->sortlist); + ares_free(options->sortlist); if(options->lookups) - free(options->lookups); + ares_free(options->lookups); } void ares_destroy(ares_channel channel) @@ -75,17 +75,17 @@ void ares_destroy(ares_channel channel) if (channel->domains) { for (i = 0; i < channel->ndomains; i++) - free(channel->domains[i]); - free(channel->domains); + ares_free(channel->domains[i]); + ares_free(channel->domains); } if(channel->sortlist) - free(channel->sortlist); + ares_free(channel->sortlist); if (channel->lookups) - free(channel->lookups); + ares_free(channel->lookups); - free(channel); + ares_free(channel); } void ares__destroy_servers_state(ares_channel channel) @@ -101,7 +101,7 @@ void ares__destroy_servers_state(ares_channel channel) ares__close_sockets(channel, server); assert(ares__is_list_empty(&server->queries_to_server)); } - free(channel->servers); + ares_free(channel->servers); channel->servers = NULL; } channel->nservers = -1; diff --git a/deps/cares/src/ares_expand_name.c b/deps/cares/src/ares_expand_name.c index 2aa12bc0ef..738be8dccb 100644 --- a/deps/cares/src/ares_expand_name.c +++ b/deps/cares/src/ares_expand_name.c @@ -74,7 +74,7 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, if (nlen.sig < 0) return ARES_EBADNAME; - *s = malloc(nlen.uns + 1); + *s = ares_malloc(nlen.uns + 1); if (!*s) return ARES_ENOMEM; q = *s; @@ -129,7 +129,7 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, if (q > *s) *(q - 1) = 0; else - *q = 0; /* zero terminate */ + *q = 0; /* zero terminate; LCOV_EXCL_LINE: empty names exit above */ return ARES_SUCCESS; } @@ -140,7 +140,7 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, static int name_length(const unsigned char *encoded, const unsigned char *abuf, int alen) { - int n = 0, offset, indir = 0; + int n = 0, offset, indir = 0, top; /* Allow the caller to pass us abuf + alen and have us check for it. */ if (encoded >= abuf + alen) @@ -148,7 +148,8 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf, while (*encoded) { - if ((*encoded & INDIR_MASK) == INDIR_MASK) + top = (*encoded & INDIR_MASK); + if (top == INDIR_MASK) { /* Check the offset and go there. */ if (encoded + 1 >= abuf + alen) @@ -164,7 +165,7 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf, if (++indir > alen) return -1; } - else + else if (top == 0x00) { offset = *encoded; if (encoded + offset + 1 >= abuf + alen) @@ -177,6 +178,13 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf, } n++; } + else + { + /* RFC 1035 4.1.4 says other options (01, 10) for top 2 + * bits are reserved. + */ + return -1; + } } /* If there were any labels at all, then the number of dots is one diff --git a/deps/cares/src/ares_expand_string.c b/deps/cares/src/ares_expand_string.c index 96d1be34b3..ed5476b91d 100644 --- a/deps/cares/src/ares_expand_string.c +++ b/deps/cares/src/ares_expand_string.c @@ -54,7 +54,7 @@ int ares_expand_string(const unsigned char *encoded, encoded++; - *s = malloc(elen.uns+1); + *s = ares_malloc(elen.uns+1); if (*s == NULL) return ARES_ENOMEM; q = *s; diff --git a/deps/cares/src/ares_free_hostent.c b/deps/cares/src/ares_free_hostent.c index 7f448828c8..cfc5f81feb 100644 --- a/deps/cares/src/ares_free_hostent.c +++ b/deps/cares/src/ares_free_hostent.c @@ -30,12 +30,12 @@ void ares_free_hostent(struct hostent *host) if (!host) return; - free((char *)(host->h_name)); + ares_free((char *)(host->h_name)); for (p = host->h_aliases; *p; p++) - free(*p); - free(host->h_aliases); - free(host->h_addr_list[0]); /* no matter if there is one or many entries, + ares_free(*p); + ares_free(host->h_aliases); + ares_free(host->h_addr_list[0]); /* no matter if there is one or many entries, there is only one malloc for all of them */ - free(host->h_addr_list); - free(host); + ares_free(host->h_addr_list); + ares_free(host); } diff --git a/deps/cares/src/ares_free_string.c b/deps/cares/src/ares_free_string.c index 9441089087..024992e1c2 100644 --- a/deps/cares/src/ares_free_string.c +++ b/deps/cares/src/ares_free_string.c @@ -21,5 +21,5 @@ void ares_free_string(void *str) { - free(str); + ares_free(str); } diff --git a/deps/cares/src/ares_gethostbyaddr.c b/deps/cares/src/ares_gethostbyaddr.c index 85862e2f85..9258919a38 100644 --- a/deps/cares/src/ares_gethostbyaddr.c +++ b/deps/cares/src/ares_gethostbyaddr.c @@ -79,7 +79,7 @@ void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, return; } - aquery = malloc(sizeof(struct addr_query)); + aquery = ares_malloc(sizeof(struct addr_query)); if (!aquery) { callback(arg, ARES_ENOMEM, 0, NULL); @@ -169,7 +169,7 @@ static void end_aquery(struct addr_query *aquery, int status, aquery->callback(aquery->arg, status, aquery->timeouts, host); if (host) ares_free_hostent(host); - free(aquery); + ares_free(aquery); } static int file_lookup(struct ares_addr *addr, struct hostent **host) diff --git a/deps/cares/src/ares_gethostbyname.c b/deps/cares/src/ares_gethostbyname.c index ba6b0f0f0c..caab6ae495 100644 --- a/deps/cares/src/ares_gethostbyname.c +++ b/deps/cares/src/ares_gethostbyname.c @@ -99,18 +99,18 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family, return; /* Allocate and fill in the host query structure. */ - hquery = malloc(sizeof(struct host_query)); + hquery = ares_malloc(sizeof(struct host_query)); if (!hquery) { callback(arg, ARES_ENOMEM, 0, NULL); return; } hquery->channel = channel; - hquery->name = strdup(name); + hquery->name = ares_strdup(name); hquery->want_family = family; hquery->sent_family = -1; /* nothing is sent yet */ if (!hquery->name) { - free(hquery); + ares_free(hquery); callback(arg, ARES_ENOMEM, 0, NULL); return; } @@ -194,6 +194,8 @@ static void host_callback(void *arg, int status, int timeouts, /* The query returned something but either there were no AAAA records (e.g. just CNAME) or the response was malformed. Try looking up A instead. */ + if (host) + ares_free_hostent(host); hquery->sent_family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); @@ -225,8 +227,8 @@ static void end_hquery(struct host_query *hquery, int status, hquery->callback(hquery->arg, status, hquery->timeouts, host); if (host) ares_free_hostent(host); - free(hquery->name); - free(hquery); + ares_free(hquery->name); + ares_free(hquery); } /* If the name looks like an IP address, fake up a host entry, end the @@ -285,7 +287,7 @@ static int fake_hostent(const char *name, int family, addrs[0] = (char *)&in6; } /* Duplicate the name, to avoid a constness violation. */ - hostent.h_name = strdup(name); + hostent.h_name = ares_strdup(name); if (!hostent.h_name) { callback(arg, ARES_ENOMEM, 0, NULL); @@ -299,7 +301,7 @@ static int fake_hostent(const char *name, int family, hostent.h_addr_list = addrs; callback(arg, ARES_SUCCESS, 0, &hostent); - free((char *)(hostent.h_name)); + ares_free((char *)(hostent.h_name)); return 1; } diff --git a/deps/cares/src/ares_getnameinfo.c b/deps/cares/src/ares_getnameinfo.c index b0bc6da868..d5571a7fd2 100644 --- a/deps/cares/src/ares_getnameinfo.c +++ b/deps/cares/src/ares_getnameinfo.c @@ -77,7 +77,7 @@ static char *lookup_service(unsigned short port, int flags, static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int scopeid, char *buf, size_t buflen); #endif -static char *ares_striendstr(const char *s1, const char *s2); +STATIC_TESTABLE char *ares_striendstr(const char *s1, const char *s2); void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, ares_socklen_t salen, @@ -163,7 +163,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, /* This is where a DNS lookup becomes necessary */ else { - niquery = malloc(sizeof(struct nameinfo_query)); + niquery = ares_malloc(sizeof(struct nameinfo_query)); if (!niquery) { callback(arg, ARES_ENOMEM, 0, NULL, NULL); @@ -234,7 +234,7 @@ static void nameinfo_callback(void *arg, int status, int timeouts, niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, (char *)(host->h_name), service); - free(niquery); + ares_free(niquery); return; } /* We couldn't find the host, but it's OK, we can use the IP */ @@ -265,11 +265,11 @@ static void nameinfo_callback(void *arg, int status, int timeouts, } niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, ipbuf, service); - free(niquery); + ares_free(niquery); return; } niquery->callback(niquery->arg, status, niquery->timeouts, NULL, NULL); - free(niquery); + ares_free(niquery); } static char *lookup_service(unsigned short port, int flags, @@ -304,7 +304,7 @@ static char *lookup_service(unsigned short port, int flags, #if GETSERVBYPORT_R_ARGS == 6 if (getservbyport_r(port, proto, &se, (void *)tmpbuf, sizeof(tmpbuf), &sep) != 0) - sep = NULL; + sep = NULL; /* LCOV_EXCL_LINE: buffer large so this never fails */ #elif GETSERVBYPORT_R_ARGS == 5 sep = getservbyport_r(port, proto, &se, (void *)tmpbuf, sizeof(tmpbuf)); @@ -341,7 +341,7 @@ static char *lookup_service(unsigned short port, int flags, memcpy(buf, name, name_len + 1); else /* avoid reusing previous one */ - buf[0] = '\0'; + buf[0] = '\0'; /* LCOV_EXCL_LINE: no real service names are too big */ return buf; } buf[0] = '\0'; @@ -391,7 +391,7 @@ static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags, #endif /* Determines if s1 ends with the string in s2 (case-insensitive) */ -static char *ares_striendstr(const char *s1, const char *s2) +STATIC_TESTABLE char *ares_striendstr(const char *s1, const char *s2) { const char *c1, *c2, *c1_begin; int lo1, lo2; @@ -417,7 +417,5 @@ static char *ares_striendstr(const char *s1, const char *s2) c2++; } } - if (c2 == c1 && c2 == NULL) - return (char *)c1_begin; - return NULL; + return (char *)c1_begin; } diff --git a/deps/cares/src/ares_init.c b/deps/cares/src/ares_init.c index bd3336e5d6..4607944879 100644 --- a/deps/cares/src/ares_init.c +++ b/deps/cares/src/ares_init.c @@ -49,6 +49,10 @@ #define MAX_DNS_PROPERTIES 8 #endif +#if defined(CARES_USE_LIBRESOLV) +#include +#endif + #include "ares.h" #include "ares_inet_net_pton.h" #include "ares_library_init.h" @@ -76,17 +80,17 @@ static int set_options(ares_channel channel, const char *str); static const char *try_option(const char *p, const char *q, const char *opt); static int init_id_key(rc4_key* key,int key_data_len); -#if !defined(WIN32) && !defined(WATT32) && \ - !defined(ANDROID) && !defined(__ANDROID__) +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 void natural_mask(struct apattern *pat); +#if !defined(WIN32) && !defined(WATT32) && \ + !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV) static int config_domain(ares_channel channel, char *str); static int config_lookup(ares_channel channel, const char *str, const char *bindch, const char *filech); -static int config_sortlist(struct apattern **sortlist, int *nsort, - const char *str); static char *try_config(char *s, const char *opt, char scc); #endif @@ -107,6 +111,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, ares_channel channel; int i; int status = ARES_SUCCESS; + int status2; struct timeval now; #ifdef CURLDEBUG @@ -124,9 +129,9 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, #endif if (ares_library_initialized() != ARES_SUCCESS) - return ARES_ENOTINITIALIZED; + return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */ - channel = malloc(sizeof(struct ares_channeldata)); + channel = ares_malloc(sizeof(struct ares_channeldata)); if (!channel) { *channelptr = NULL; return ARES_ENOMEM; @@ -205,10 +210,13 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, * No matter what failed or succeeded, seed defaults to provide * useful behavior for things that we missed. */ - status = init_by_defaults(channel); - if (status != ARES_SUCCESS) + status2 = init_by_defaults(channel); + if (status2 != ARES_SUCCESS) { DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n", ares_strerror(status))); + if (status == ARES_SUCCESS) + status = status2; + } /* Generate random key */ @@ -225,18 +233,18 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, { /* Something failed; clean up memory we may have allocated. */ if (channel->servers) - free(channel->servers); + ares_free(channel->servers); if (channel->domains) { for (i = 0; i < channel->ndomains; i++) - free(channel->domains[i]); - free(channel->domains); + ares_free(channel->domains[i]); + ares_free(channel->domains); } if (channel->sortlist) - free(channel->sortlist); + ares_free(channel->sortlist); if(channel->lookups) - free(channel->lookups); - free(channel); + ares_free(channel->lookups); + ares_free(channel); return status; } @@ -255,8 +263,8 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, int ares_dup(ares_channel *dest, ares_channel src) { struct ares_options opts; - struct ares_addr_node *servers; - int ipv6_nservers = 0; + struct ares_addr_port_node *servers; + int non_v4_default_port = 0; int i, rc; int optmask; @@ -289,22 +297,30 @@ int ares_dup(ares_channel *dest, ares_channel src) (*dest)->local_ip4 = src->local_ip4; memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6)); - /* Full name server cloning required when not all are IPv4 */ + /* Full name server cloning required if there is a non-IPv4, or non-default port, nameserver */ for (i = 0; i < src->nservers; i++) { - if (src->servers[i].addr.family != AF_INET) { - ipv6_nservers++; + if ((src->servers[i].addr.family != AF_INET) || + (src->servers[i].addr.udp_port != 0) || + (src->servers[i].addr.tcp_port != 0)) { + non_v4_default_port++; break; } } - if (ipv6_nservers) { - rc = ares_get_servers(src, &servers); - if (rc != ARES_SUCCESS) + if (non_v4_default_port) { + rc = ares_get_servers_ports(src, &servers); + if (rc != ARES_SUCCESS) { + ares_destroy(*dest); + *dest = NULL; return rc; - rc = ares_set_servers(*dest, servers); + } + rc = ares_set_servers_ports(*dest, servers); ares_free_data(servers); - if (rc != ARES_SUCCESS) + if (rc != ARES_SUCCESS) { + ares_destroy(*dest); + *dest = NULL; return rc; + } } return ARES_SUCCESS; /* everything went fine */ @@ -345,20 +361,24 @@ int ares_save_options(ares_channel channel, struct ares_options *options, options->sock_state_cb = channel->sock_state_cb; options->sock_state_cb_data = channel->sock_state_cb_data; - /* Copy IPv4 servers */ + /* Copy IPv4 servers that use the default port */ if (channel->nservers) { for (i = 0; i < channel->nservers; i++) { - if (channel->servers[i].addr.family == AF_INET) + if ((channel->servers[i].addr.family == AF_INET) && + (channel->servers[i].addr.udp_port == 0) && + (channel->servers[i].addr.tcp_port == 0)) ipv4_nservers++; } if (ipv4_nservers) { - options->servers = malloc(ipv4_nservers * sizeof(struct in_addr)); + options->servers = ares_malloc(ipv4_nservers * sizeof(struct in_addr)); if (!options->servers) return ARES_ENOMEM; for (i = j = 0; i < channel->nservers; i++) { - if (channel->servers[i].addr.family == AF_INET) + if ((channel->servers[i].addr.family == AF_INET) && + (channel->servers[i].addr.udp_port == 0) && + (channel->servers[i].addr.tcp_port == 0)) memcpy(&options->servers[j++], &channel->servers[i].addr.addrV4, sizeof(channel->servers[i].addr.addrV4)); @@ -369,14 +389,14 @@ int ares_save_options(ares_channel channel, struct ares_options *options, /* copy domains */ if (channel->ndomains) { - options->domains = malloc(channel->ndomains * sizeof(char *)); + options->domains = ares_malloc(channel->ndomains * sizeof(char *)); if (!options->domains) return ARES_ENOMEM; for (i = 0; i < channel->ndomains; i++) { options->ndomains = i; - options->domains[i] = strdup(channel->domains[i]); + options->domains[i] = ares_strdup(channel->domains[i]); if (!options->domains[i]) return ARES_ENOMEM; } @@ -385,14 +405,14 @@ int ares_save_options(ares_channel channel, struct ares_options *options, /* copy lookups */ if (channel->lookups) { - options->lookups = strdup(channel->lookups); + options->lookups = ares_strdup(channel->lookups); if (!options->lookups && channel->lookups) return ARES_ENOMEM; } /* copy sortlist */ if (channel->nsort) { - options->sortlist = malloc(channel->nsort * sizeof(struct apattern)); + options->sortlist = ares_malloc(channel->nsort * sizeof(struct apattern)); if (!options->sortlist) return ARES_ENOMEM; for (i = 0; i < channel->nsort; i++) @@ -448,12 +468,14 @@ static int init_by_options(ares_channel channel, if (options->nservers > 0) { channel->servers = - malloc(options->nservers * sizeof(struct server_state)); + ares_malloc(options->nservers * sizeof(struct server_state)); if (!channel->servers) return ARES_ENOMEM; for (i = 0; i < options->nservers; i++) { channel->servers[i].addr.family = AF_INET; + channel->servers[i].addr.udp_port = 0; + channel->servers[i].addr.tcp_port = 0; memcpy(&channel->servers[i].addr.addrV4, &options->servers[i], sizeof(channel->servers[i].addr.addrV4)); @@ -470,13 +492,13 @@ static int init_by_options(ares_channel channel, /* Avoid zero size allocations at any cost */ if (options->ndomains > 0) { - channel->domains = malloc(options->ndomains * sizeof(char *)); + channel->domains = ares_malloc(options->ndomains * sizeof(char *)); if (!channel->domains) return ARES_ENOMEM; for (i = 0; i < options->ndomains; i++) { channel->ndomains = i; - channel->domains[i] = strdup(options->domains[i]); + channel->domains[i] = ares_strdup(options->domains[i]); if (!channel->domains[i]) return ARES_ENOMEM; } @@ -487,7 +509,7 @@ static int init_by_options(ares_channel channel, /* Set lookups, if given. */ if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups) { - channel->lookups = strdup(options->lookups); + channel->lookups = ares_strdup(options->lookups); if (!channel->lookups) return ARES_ENOMEM; } @@ -495,7 +517,7 @@ static int init_by_options(ares_channel channel, /* copy sortlist */ if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) && (options->nsort>0)) { - channel->sortlist = malloc(options->nsort * sizeof(struct apattern)); + channel->sortlist = ares_malloc(options->nsort * sizeof(struct apattern)); if (!channel->sortlist) return ARES_ENOMEM; for (i = 0; i < options->nsort; i++) @@ -526,7 +548,7 @@ static int init_by_environment(ares_channel channel) { status = set_options(channel, res_options); if (status != ARES_SUCCESS) - return status; + return status; /* LCOV_EXCL_LINE: set_options() never fails */ } return ARES_SUCCESS; @@ -561,7 +583,7 @@ static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr) /* Allocate buffer of indicated size plus one given that string might have been stored without null termination */ - *outptr = malloc(size+1); + *outptr = ares_malloc(size+1); if (!*outptr) return 0; @@ -570,7 +592,7 @@ static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr) (unsigned char *)*outptr, &size); if ((res != ERROR_SUCCESS) || (size == 1)) { - free(*outptr); + ares_free(*outptr); *outptr = NULL; return 0; } @@ -603,7 +625,7 @@ static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr) /* Allocate buffer of indicated size plus one given that string might have been stored without null termination */ - *outptr = malloc(size+1); + *outptr = ares_malloc(size+1); if (!*outptr) return 0; @@ -612,7 +634,7 @@ static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr) (unsigned char *)*outptr, &size); if ((res != ERROR_SUCCESS) || (size == 1)) { - free(*outptr); + ares_free(*outptr); *outptr = NULL; return 0; } @@ -813,16 +835,16 @@ static void commajoin(char **dst, const char *src) if (*dst) { - tmp = malloc(strlen(*dst) + strlen(src) + 2); + tmp = ares_malloc(strlen(*dst) + strlen(src) + 2); if (!tmp) return; sprintf(tmp, "%s,%s", *dst, src); - free(*dst); + ares_free(*dst); *dst = tmp; } else { - *dst = malloc(strlen(src) + 1); + *dst = ares_malloc(strlen(src) + 1); if (!*dst) return; strcpy(*dst, src); @@ -860,7 +882,7 @@ static int get_DNS_NetworkParams(char **outptr) if (ares_fpGetNetworkParams == ZERO_NULL) return 0; - fi = malloc(size); + fi = ares_malloc(size); if (!fi) return 0; @@ -868,7 +890,7 @@ static int get_DNS_NetworkParams(char **outptr) if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS)) goto done; - newfi = realloc(fi, size); + newfi = ares_realloc(fi, size); if (!newfi) goto done; @@ -905,7 +927,7 @@ static int get_DNS_NetworkParams(char **outptr) done: if (fi) - free(fi); + ares_free(fi); if (!*outptr) return 0; @@ -953,7 +975,7 @@ static int get_DNS_AdaptersAddresses(char **outptr) if (ares_fpGetAdaptersAddresses == ZERO_NULL) return 0; - ipaa = malloc(Bufsz); + ipaa = ares_malloc(Bufsz); if (!ipaa) return 0; @@ -967,7 +989,7 @@ static int get_DNS_AdaptersAddresses(char **outptr) { if (Bufsz < ReqBufsz) { - newipaa = realloc(ipaa, ReqBufsz); + newipaa = ares_realloc(ipaa, ReqBufsz); if (!newipaa) goto done; Bufsz = ReqBufsz; @@ -983,6 +1005,9 @@ static int get_DNS_AdaptersAddresses(char **outptr) for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next) { + if(ipaaEntry->OperStatus != IfOperStatusUp) + continue; + for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress; ipaDNSAddr; ipaDNSAddr = ipaDNSAddr->Next) @@ -1000,11 +1025,6 @@ static int get_DNS_AdaptersAddresses(char **outptr) } else if (namesrvr.sa->sa_family == AF_INET6) { - /* Windows apparently always reports some IPv6 DNS servers that - * prefixed with fec0:0:0:ffff. These ususally do not point to - * working DNS servers, so we ignore them. */ - if (strncmp(txtaddr, "fec0:0:0:ffff:", 14) == 0) - continue; if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any, sizeof(namesrvr.sa6->sin6_addr)) == 0) continue; @@ -1024,7 +1044,7 @@ static int get_DNS_AdaptersAddresses(char **outptr) done: if (ipaa) - free(ipaa); + ares_free(ipaa); if (!*outptr) return 0; @@ -1048,14 +1068,20 @@ done: */ static int get_DNS_Windows(char **outptr) { - /* Try using IP helper API GetAdaptersAddresses() */ - if (get_DNS_AdaptersAddresses(outptr)) - return 1; - + /* + 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)) return 1; + /* Try using IP helper API GetAdaptersAddresses() */ + if (get_DNS_AdaptersAddresses(outptr)) + return 1; + /* Fall-back to registry information */ return get_DNS_Registry(outptr); } @@ -1063,7 +1089,8 @@ static int get_DNS_Windows(char **outptr) static int init_by_resolv_conf(ares_channel channel) { -#if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) +#if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) && \ + !defined(CARES_USE_LIBRESOLV) char *line = NULL; #endif int status = -1, nservers = 0, nsort = 0; @@ -1078,7 +1105,7 @@ static int init_by_resolv_conf(ares_channel channel) if (get_DNS_Windows(&line)) { status = config_nameserver(&servers, &nservers, line); - free(line); + ares_free(line); } if (status == ARES_SUCCESS) @@ -1096,7 +1123,7 @@ static int init_by_resolv_conf(ares_channel channel) line = getenv("Inet$Resolvers"); status = ARES_EOF; if (line) { - char *resolvers = strdup(line), *pos, *space; + char *resolvers = ares_strdup(line), *pos, *space; if (!resolvers) return ARES_ENOMEM; @@ -1115,7 +1142,7 @@ static int init_by_resolv_conf(ares_channel channel) if (status == ARES_SUCCESS) status = ARES_EOF; - free(resolvers); + ares_free(resolvers); } #elif defined(WATT32) @@ -1128,14 +1155,17 @@ static int init_by_resolv_conf(ares_channel channel) return ARES_SUCCESS; /* use localhost DNS server */ nservers = i; - servers = calloc(i, sizeof(struct server_state)); + servers = ares_malloc(sizeof(struct server_state)); if (!servers) return ARES_ENOMEM; + memset(servers, 0, sizeof(struct server_state)); for (i = 0; def_nameservers[i]; i++) { servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]); servers[i].addr.family = AF_INET; + servers[i].addr.udp_port = 0; + servers[i].addr.tcp_port = 0; } status = ARES_EOF; @@ -1155,6 +1185,63 @@ static int init_by_resolv_conf(ares_channel channel) break; status = ARES_EOF; } +#elif defined(CARES_USE_LIBRESOLV) + struct __res_state res; + memset(&res, 0, sizeof(res)); + int result = res_ninit(&res); + if (result == 0 && (res.options & RES_INIT)) { + status = ARES_EOF; + + if (channel->nservers == -1) { + union res_sockaddr_union addr[MAXNS]; + int nscount = res_getservers(&res, addr, MAXNS); + for (int i = 0; i < nscount; ++i) { + char str[INET6_ADDRSTRLEN]; + int config_status; + sa_family_t family = addr[i].sin.sin_family; + if (family == AF_INET) { + ares_inet_ntop(family, &addr[i].sin.sin_addr, str, sizeof(str)); + } else if (family == AF_INET6) { + ares_inet_ntop(family, &addr[i].sin6.sin6_addr, str, sizeof(str)); + } else { + continue; + } + + config_status = config_nameserver(&servers, &nservers, str); + if (config_status != ARES_SUCCESS) { + status = config_status; + break; + } + } + } + if (channel->ndomains == -1) { + int entries = 0; + while ((entries < MAXDNSRCH) && res.dnsrch[entries]) + entries++; + + channel->domains = ares_malloc(entries * sizeof(char *)); + if (!channel->domains) { + status = ARES_ENOMEM; + } else { + channel->ndomains = entries; + for (int i = 0; i < channel->ndomains; ++i) { + channel->domains[i] = ares_strdup(res.dnsrch[i]); + if (!channel->domains[i]) + status = ARES_ENOMEM; + } + } + } + if (channel->ndots == -1) + channel->ndots = res.ndots; + if (channel->tries == -1) + channel->tries = res.retry; + if (channel->rotate == -1) + channel->rotate = res.options & RES_ROTATE; + if (channel->timeout == -1) + channel->timeout = res.retrans * 1000; + + res_ndestroy(&res); + } #else { char *p; @@ -1300,7 +1387,7 @@ static int init_by_resolv_conf(ares_channel channel) } if(line) - free(line); + ares_free(line); } #endif @@ -1309,9 +1396,9 @@ static int init_by_resolv_conf(ares_channel channel) if (status != ARES_EOF) { if (servers != NULL) - free(servers); + ares_free(servers); if (sortlist != NULL) - free(sortlist); + ares_free(sortlist); return status; } @@ -1360,13 +1447,15 @@ static int init_by_defaults(ares_channel channel) if (channel->nservers == -1) { /* If nobody specified servers, try a local named. */ - channel->servers = malloc(sizeof(struct server_state)); + channel->servers = ares_malloc(sizeof(struct server_state)); if (!channel->servers) { rc = ARES_ENOMEM; goto error; } channel->servers[0].addr.family = AF_INET; channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK); + channel->servers[0].addr.udp_port = 0; + channel->servers[0].addr.tcp_port = 0; channel->nservers = 1; } @@ -1391,7 +1480,7 @@ static int init_by_defaults(ares_channel channel) int res; channel->ndomains = 0; /* default to none */ - hostname = malloc(len); + hostname = ares_malloc(len); if(!hostname) { rc = ARES_ENOMEM; goto error; @@ -1404,7 +1493,7 @@ static int init_by_defaults(ares_channel channel) char *p; len *= 2; lenv *= 2; - p = realloc(hostname, len); + p = ares_realloc(hostname, len); if(!p) { rc = ARES_ENOMEM; goto error; @@ -1422,12 +1511,12 @@ static int init_by_defaults(ares_channel channel) dot = strchr(hostname, '.'); if (dot) { /* a dot was found */ - channel->domains = malloc(sizeof(char *)); + channel->domains = ares_malloc(sizeof(char *)); if (!channel->domains) { rc = ARES_ENOMEM; goto error; } - channel->domains[0] = strdup(dot + 1); + channel->domains[0] = ares_strdup(dot + 1); if (!channel->domains[0]) { rc = ARES_ENOMEM; goto error; @@ -1443,7 +1532,7 @@ static int init_by_defaults(ares_channel channel) } if (!channel->lookups) { - channel->lookups = strdup("fb"); + channel->lookups = ares_strdup("fb"); if (!channel->lookups) rc = ARES_ENOMEM; } @@ -1451,31 +1540,31 @@ static int init_by_defaults(ares_channel channel) error: if(rc) { if(channel->servers) { - free(channel->servers); + ares_free(channel->servers); channel->servers = NULL; } if(channel->domains && channel->domains[0]) - free(channel->domains[0]); + ares_free(channel->domains[0]); if(channel->domains) { - free(channel->domains); + ares_free(channel->domains); channel->domains = NULL; } if(channel->lookups) { - free(channel->lookups); + ares_free(channel->lookups); channel->lookups = NULL; } } if(hostname) - free(hostname); + ares_free(hostname); return rc; } #if !defined(WIN32) && !defined(WATT32) && \ - !defined(ANDROID) && !defined(__ANDROID__) + !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV) static int config_domain(ares_channel channel, char *str) { char *q; @@ -1520,7 +1609,7 @@ static int config_lookup(ares_channel channel, const char *str, p++; } *l = '\0'; - channel->lookups = strdup(lookups); + channel->lookups = ares_strdup(lookups); return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM; } #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */ @@ -1566,13 +1655,15 @@ static int config_nameserver(struct server_state **servers, int *nservers, continue; /* Resize servers state array. */ - newserv = realloc(*servers, (*nservers + 1) * - sizeof(struct server_state)); + newserv = ares_realloc(*servers, (*nservers + 1) * + sizeof(struct server_state)); if (!newserv) return ARES_ENOMEM; /* Store address data. */ newserv[*nservers].addr.family = host.family; + newserv[*nservers].addr.udp_port = 0; + newserv[*nservers].addr.tcp_port = 0; if (host.family == AF_INET) memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4, sizeof(host.addrV4)); @@ -1587,8 +1678,8 @@ static int config_nameserver(struct server_state **servers, int *nservers, return ARES_SUCCESS; } +#endif /* !WATT32 */ -#if !defined(WIN32) && !defined(ANDROID) && !defined(__ANDROID__) static int config_sortlist(struct apattern **sortlist, int *nsort, const char *str) { @@ -1627,8 +1718,11 @@ static int config_sortlist(struct apattern **sortlist, int *nsort, pat.type = PATTERN_CIDR; pat.mask.bits = (unsigned short)bits; pat.family = AF_INET6; - if (!sortlist_alloc(sortlist, nsort, &pat)) + if (!sortlist_alloc(sortlist, nsort, &pat)) { + ares_free(*sortlist); + *sortlist = NULL; return ARES_ENOMEM; + } } else if (ipbufpfx[0] && (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4, @@ -1637,8 +1731,11 @@ static int config_sortlist(struct apattern **sortlist, int *nsort, pat.type = PATTERN_CIDR; pat.mask.bits = (unsigned short)bits; pat.family = AF_INET; - if (!sortlist_alloc(sortlist, nsort, &pat)) + if (!sortlist_alloc(sortlist, nsort, &pat)) { + ares_free(*sortlist); + *sortlist = NULL; return ARES_ENOMEM; + } } /* See if it is just a regular IP */ else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0) @@ -1654,8 +1751,11 @@ static int config_sortlist(struct apattern **sortlist, int *nsort, natural_mask(&pat); pat.family = AF_INET; pat.type = PATTERN_MASK; - if (!sortlist_alloc(sortlist, nsort, &pat)) + if (!sortlist_alloc(sortlist, nsort, &pat)) { + ares_free(*sortlist); + *sortlist = NULL; return ARES_ENOMEM; + } } else { @@ -1669,8 +1769,6 @@ static int config_sortlist(struct apattern **sortlist, int *nsort, return ARES_SUCCESS; } -#endif /* !WIN32 & !ANDROID & !__ANDROID__ */ -#endif /* !WATT32 */ static int set_search(ares_channel channel, const char *str) { @@ -1678,13 +1776,14 @@ static int set_search(ares_channel channel, const char *str) const char *p, *q; if(channel->ndomains != -1) { + /* LCOV_EXCL_START: all callers check ndomains == -1 */ /* if we already have some domains present, free them first */ for(n=0; n < channel->ndomains; n++) - free(channel->domains[n]); - free(channel->domains); + ares_free(channel->domains[n]); + ares_free(channel->domains); channel->domains = NULL; channel->ndomains = -1; - } + } /* LCOV_EXCL_STOP */ /* Count the domains given. */ n = 0; @@ -1704,7 +1803,7 @@ static int set_search(ares_channel channel, const char *str) return ARES_SUCCESS; } - channel->domains = malloc(n * sizeof(char *)); + channel->domains = ares_malloc(n * sizeof(char *)); if (!channel->domains) return ARES_ENOMEM; @@ -1717,7 +1816,7 @@ static int set_search(ares_channel channel, const char *str) q = p; while (*q && !ISSPACE(*q)) q++; - channel->domains[n] = malloc(q - p + 1); + channel->domains[n] = ares_malloc(q - p + 1); if (!channel->domains[n]) return ARES_ENOMEM; memcpy(channel->domains[n], p, q - p); @@ -1769,7 +1868,7 @@ static const char *try_option(const char *p, const char *q, const char *opt) } #if !defined(WIN32) && !defined(WATT32) && \ - !defined(ANDROID) && !defined(__ANDROID__) + !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV) static char *try_config(char *s, const char *opt, char scc) { size_t len; @@ -1778,7 +1877,7 @@ static char *try_config(char *s, const char *opt, char scc) if (!s || !opt) /* no line or no option */ - return NULL; + return NULL; /* LCOV_EXCL_LINE */ /* Hash '#' character is always used as primary comment char, additionally a not-NUL secondary comment char will be considered when specified. */ @@ -1810,7 +1909,7 @@ static char *try_config(char *s, const char *opt, char scc) if ((len = strlen(opt)) == 0) /* empty option */ - return NULL; + return NULL; /* LCOV_EXCL_LINE */ if (strncmp(p, opt, len) != 0) /* line and option do not match */ @@ -1821,7 +1920,7 @@ static char *try_config(char *s, const char *opt, char scc) if (!*p) /* no option value */ - return NULL; + return NULL; /* LCOV_EXCL_LINE */ if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p)) /* whitespace between option name and value is mandatory @@ -1839,19 +1938,7 @@ static char *try_config(char *s, const char *opt, char scc) /* return pointer to option value */ return p; } - -static int sortlist_alloc(struct apattern **sortlist, int *nsort, - struct apattern *pat) -{ - struct apattern *newsort; - newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern)); - if (!newsort) - return 0; - newsort[*nsort] = *pat; - *sortlist = newsort; - (*nsort)++; - return 1; -} +#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */ static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr) { @@ -1885,7 +1972,19 @@ static void natural_mask(struct apattern *pat) else pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET); } -#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */ + +static int sortlist_alloc(struct apattern **sortlist, int *nsort, + struct apattern *pat) +{ + struct apattern *newsort; + newsort = ares_realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern)); + if (!newsort) + return 0; + newsort[*nsort] = *pat; + *sortlist = newsort; + (*nsort)++; + return 1; +} /* initialize an rc4 key. If possible a cryptographically secure random key is generated using a suitable function (for example win32's RtlGenRandom as @@ -1918,7 +2017,7 @@ static void randomize_key(unsigned char* key,int key_data_len) if (!randomized) { for (;counterstate[0]; for(counter = 0; counter < 256; counter++) @@ -1951,7 +2051,7 @@ static int init_id_key(rc4_key* key,int key_data_len) index1 = (unsigned char)((index1 + 1) % key_data_len); } - free(key_data_ptr); + ares_free(key_data_ptr); return ARES_SUCCESS; } @@ -1985,6 +2085,25 @@ void ares_set_socket_callback(ares_channel channel, channel->sock_create_cb_data = data; } +int ares_set_sortlist(ares_channel channel, const char *sortstr) +{ + int nsort = 0; + struct apattern *sortlist = NULL; + int status; + + if (!channel) + return ARES_ENODATA; + + status = config_sortlist(&sortlist, &nsort, sortstr); + if (status == ARES_SUCCESS && sortlist) { + if (channel->sortlist) + ares_free(channel->sortlist); + channel->sortlist = sortlist; + channel->nsort = nsort; + } + return status; +} + void ares__init_servers_state(ares_channel channel) { struct server_state *server; diff --git a/deps/cares/src/ares_library_init.c b/deps/cares/src/ares_library_init.c index 9114f62614..049dc3d7fa 100644 --- a/deps/cares/src/ares_library_init.c +++ b/deps/cares/src/ares_library_init.c @@ -34,6 +34,11 @@ fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses = ZERO_NULL; static unsigned int ares_initialized; static int ares_init_flags; +/* library-private global vars with visibility across the whole library */ +void *(*ares_malloc)(size_t size) = malloc; +void *(*ares_realloc)(void *ptr, size_t size) = realloc; +void (*ares_free)(void *ptr) = free; + #ifdef USE_WINSOCK static HMODULE hnd_iphlpapi; static HMODULE hnd_advapi32; @@ -45,7 +50,7 @@ static int ares_win32_init(void) #ifdef USE_WINSOCK hnd_iphlpapi = 0; - hnd_iphlpapi = LoadLibraryW(L"iphlpapi.dll"); + hnd_iphlpapi = LoadLibrary("iphlpapi.dll"); if (!hnd_iphlpapi) return ARES_ELOADIPHLPAPI; @@ -73,7 +78,7 @@ static int ares_win32_init(void) */ hnd_advapi32 = 0; - hnd_advapi32 = LoadLibraryW(L"advapi32.dll"); + hnd_advapi32 = LoadLibrary("advapi32.dll"); if (hnd_advapi32) { ares_fpSystemFunction036 = (fpSystemFunction036_t) @@ -111,7 +116,7 @@ int ares_library_init(int flags) { res = ares_win32_init(); if (res != ARES_SUCCESS) - return res; + return res; /* LCOV_EXCL_LINE: can't test Win32 init failure */ } ares_init_flags = flags; @@ -119,6 +124,20 @@ int ares_library_init(int flags) return ARES_SUCCESS; } +int ares_library_init_mem(int flags, + void *(*amalloc)(size_t size), + void (*afree)(void *ptr), + void *(*arealloc)(void *ptr, size_t size)) +{ + if (amalloc) + ares_malloc = amalloc; + if (arealloc) + ares_realloc = arealloc; + if (afree) + ares_free = afree; + return ares_library_init(flags); +} + void ares_library_cleanup(void) { @@ -132,6 +151,8 @@ void ares_library_cleanup(void) ares_win32_cleanup(); ares_init_flags = ARES_LIB_INIT_NONE; + ares_malloc = malloc; + ares_free = free; } diff --git a/deps/cares/src/ares_options.c b/deps/cares/src/ares_options.c index cf88433a1b..c3cbd1df70 100644 --- a/deps/cares/src/ares_options.c +++ b/deps/cares/src/ares_options.c @@ -83,6 +83,62 @@ int ares_get_servers(ares_channel channel, return status; } +int ares_get_servers_ports(ares_channel channel, + struct ares_addr_port_node **servers) +{ + struct ares_addr_port_node *srvr_head = NULL; + struct ares_addr_port_node *srvr_last = NULL; + struct ares_addr_port_node *srvr_curr; + int status = ARES_SUCCESS; + int i; + + if (!channel) + return ARES_ENODATA; + + for (i = 0; i < channel->nservers; i++) + { + /* Allocate storage for this server node appending it to the list */ + srvr_curr = ares_malloc_data(ARES_DATATYPE_ADDR_PORT_NODE); + if (!srvr_curr) + { + status = ARES_ENOMEM; + break; + } + if (srvr_last) + { + srvr_last->next = srvr_curr; + } + else + { + srvr_head = srvr_curr; + } + srvr_last = srvr_curr; + + /* Fill this server node data */ + srvr_curr->family = channel->servers[i].addr.family; + srvr_curr->udp_port = ntohs((unsigned short)channel->servers[i].addr.udp_port); + srvr_curr->tcp_port = ntohs((unsigned short)channel->servers[i].addr.tcp_port); + if (srvr_curr->family == AF_INET) + memcpy(&srvr_curr->addrV4, &channel->servers[i].addr.addrV4, + sizeof(srvr_curr->addrV4)); + else + memcpy(&srvr_curr->addrV6, &channel->servers[i].addr.addrV6, + sizeof(srvr_curr->addrV6)); + } + + if (status != ARES_SUCCESS) + { + if (srvr_head) + { + ares_free_data(srvr_head); + srvr_head = NULL; + } + } + + *servers = srvr_head; + + return status; +} int ares_set_servers(ares_channel channel, struct ares_addr_node *servers) @@ -92,7 +148,56 @@ int ares_set_servers(ares_channel channel, int i; if (ares_library_initialized() != ARES_SUCCESS) - return ARES_ENOTINITIALIZED; + return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */ + + if (!channel) + return ARES_ENODATA; + + ares__destroy_servers_state(channel); + + for (srvr = servers; srvr; srvr = srvr->next) + { + num_srvrs++; + } + + if (num_srvrs > 0) + { + /* Allocate storage for servers state */ + channel->servers = ares_malloc(num_srvrs * sizeof(struct server_state)); + if (!channel->servers) + { + return ARES_ENOMEM; + } + channel->nservers = num_srvrs; + /* Fill servers state address data */ + for (i = 0, srvr = servers; srvr; i++, srvr = srvr->next) + { + channel->servers[i].addr.family = srvr->family; + channel->servers[i].addr.udp_port = 0; + channel->servers[i].addr.tcp_port = 0; + if (srvr->family == AF_INET) + memcpy(&channel->servers[i].addr.addrV4, &srvr->addrV4, + sizeof(srvr->addrV4)); + else + memcpy(&channel->servers[i].addr.addrV6, &srvr->addrV6, + sizeof(srvr->addrV6)); + } + /* Initialize servers state remaining data */ + ares__init_servers_state(channel); + } + + return ARES_SUCCESS; +} + +int ares_set_servers_ports(ares_channel channel, + struct ares_addr_port_node *servers) +{ + struct ares_addr_port_node *srvr; + int num_srvrs = 0; + int i; + + if (ares_library_initialized() != ARES_SUCCESS) + return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */ if (!channel) return ARES_ENODATA; @@ -107,7 +212,7 @@ int ares_set_servers(ares_channel channel, if (num_srvrs > 0) { /* Allocate storage for servers state */ - channel->servers = malloc(num_srvrs * sizeof(struct server_state)); + channel->servers = ares_malloc(num_srvrs * sizeof(struct server_state)); if (!channel->servers) { return ARES_ENOMEM; @@ -117,6 +222,8 @@ int ares_set_servers(ares_channel channel, for (i = 0, srvr = servers; srvr; i++, srvr = srvr->next) { channel->servers[i].addr.family = srvr->family; + channel->servers[i].addr.udp_port = htons((unsigned short)srvr->udp_port); + channel->servers[i].addr.tcp_port = htons((unsigned short)srvr->tcp_port); if (srvr->family == AF_INET) memcpy(&channel->servers[i].addr.addrV4, &srvr->addrV4, sizeof(srvr->addrV4)); @@ -133,8 +240,8 @@ int ares_set_servers(ares_channel channel, /* Incomming string format: host[:port][,host[:port]]... */ /* IPv6 addresses with ports require square brackets [fe80::1%lo0]:53 */ -int ares_set_servers_csv(ares_channel channel, - const char* _csv) +static int set_servers_csv(ares_channel channel, + const char* _csv, int use_port) { size_t i; char* csv = NULL; @@ -142,11 +249,11 @@ int ares_set_servers_csv(ares_channel channel, char* start_host; int cc = 0; int rv = ARES_SUCCESS; - struct ares_addr_node *servers = NULL; - struct ares_addr_node *last = NULL; + struct ares_addr_port_node *servers = NULL; + struct ares_addr_port_node *last = NULL; if (ares_library_initialized() != ARES_SUCCESS) - return ARES_ENOTINITIALIZED; + return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */ if (!channel) return ARES_ENODATA; @@ -157,7 +264,7 @@ int ares_set_servers_csv(ares_channel channel, if (i == 0) return ARES_SUCCESS; /* blank all servers */ - csv = malloc(i + 2); + csv = ares_malloc(i + 2); if (!csv) return ARES_ENOMEM; @@ -182,9 +289,10 @@ int ares_set_servers_csv(ares_channel channel, else if (*ptr == ',') { char* pp = ptr - 1; char* p = ptr; + int port = 0; struct in_addr in4; struct ares_in6_addr in6; - struct ares_addr_node *s = NULL; + struct ares_addr_port_node *s = NULL; *ptr = 0; /* null terminate host:port string */ /* Got an entry..see if the port was specified. */ @@ -213,7 +321,7 @@ int ares_set_servers_csv(ares_channel channel, if (*pp == ']') p++; /* move p before ':' */ /* p will point to the start of the port */ - (void)strtol(p, NULL, 10); + port = (int)strtol(p, NULL, 10); *pp = 0; /* null terminate host */ } } @@ -227,7 +335,7 @@ int ares_set_servers_csv(ares_channel channel, goto out; } /* was ipv6, add new server */ - s = malloc(sizeof(*s)); + s = ares_malloc(sizeof(*s)); if (!s) { rv = ARES_ENOMEM; goto out; @@ -237,7 +345,7 @@ int ares_set_servers_csv(ares_channel channel, } else { /* was ipv4, add new server */ - s = malloc(sizeof(*s)); + s = ares_malloc(sizeof(*s)); if (!s) { rv = ARES_ENOMEM; goto out; @@ -246,8 +354,8 @@ int ares_set_servers_csv(ares_channel channel, memcpy(&s->addr, &in4, sizeof(struct in_addr)); } if (s) { - /* TODO: Add port to ares_addr_node and assign it here. */ - + s->udp_port = use_port ? port: 0; + s->tcp_port = s->udp_port; s->next = NULL; if (last) { last->next = s; @@ -266,16 +374,29 @@ int ares_set_servers_csv(ares_channel channel, } } - rv = ares_set_servers(channel, servers); + rv = ares_set_servers_ports(channel, servers); out: if (csv) - free(csv); + ares_free(csv); while (servers) { - struct ares_addr_node *s = servers; + struct ares_addr_port_node *s = servers; servers = servers->next; - free(s); + ares_free(s); } return rv; } + +int ares_set_servers_csv(ares_channel channel, + const char* _csv) +{ + return set_servers_csv(channel, _csv, FALSE); +} + +int ares_set_servers_ports_csv(ares_channel channel, + const char* _csv) +{ + return set_servers_csv(channel, _csv, TRUE); +} + diff --git a/deps/cares/src/ares_parse_a_reply.c b/deps/cares/src/ares_parse_a_reply.c index a3ed69e1e9..0422bd3828 100644 --- a/deps/cares/src/ares_parse_a_reply.c +++ b/deps/cares/src/ares_parse_a_reply.c @@ -85,7 +85,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, return status; if (aptr + len + QFIXEDSZ > abuf + alen) { - free(hostname); + ares_free(hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; @@ -94,17 +94,17 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, { /* Allocate addresses and aliases; ancount gives an upper bound for both. */ - addrs = malloc(ancount * sizeof(struct in_addr)); + addrs = ares_malloc(ancount * sizeof(struct in_addr)); if (!addrs) { - free(hostname); + ares_free(hostname); return ARES_ENOMEM; } - aliases = malloc((ancount + 1) * sizeof(char *)); + aliases = ares_malloc((ancount + 1) * sizeof(char *)); if (!aliases) { - free(hostname); - free(addrs); + ares_free(hostname); + ares_free(addrs); return ARES_ENOMEM; } } @@ -127,7 +127,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, aptr += len; if (aptr + RRFIXEDSZ > abuf + alen) { - free(rr_name); + ares_free(rr_name); status = ARES_EBADRESP; break; } @@ -138,7 +138,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, aptr += RRFIXEDSZ; if (aptr + rr_len > abuf + alen) { - free(rr_name); + ares_free(rr_name); status = ARES_EBADRESP; break; } @@ -150,22 +150,22 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, if (addrs) { if (aptr + sizeof(struct in_addr) > abuf + alen) - { - free(rr_name); + { /* LCOV_EXCL_START: already checked above */ + ares_free(rr_name); status = ARES_EBADRESP; break; - } + } /* LCOV_EXCL_STOP */ memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr)); } if (naddrs < max_addr_ttls) { struct ares_addrttl * const at = &addrttls[naddrs]; if (aptr + sizeof(struct in_addr) > abuf + alen) - { - free(rr_name); + { /* LCOV_EXCL_START: already checked above */ + ares_free(rr_name); status = ARES_EBADRESP; break; - } + } /* LCOV_EXCL_STOP */ memcpy(&at->ipaddr, aptr, sizeof(struct in_addr)); at->ttl = rr_ttl; } @@ -179,7 +179,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, if (aliases) aliases[naliases] = rr_name; else - free(rr_name); + ares_free(rr_name); naliases++; /* Decode the RR data and replace the hostname with it. */ @@ -187,7 +187,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, &len); if (status != ARES_SUCCESS) break; - free(hostname); + ares_free(hostname); hostname = rr_data; /* Take the min of the TTLs we see in the CNAME chain. */ @@ -195,14 +195,14 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, cname_ttl = rr_ttl; } else - free(rr_name); + ares_free(rr_name); aptr += rr_len; if (aptr > abuf + alen) - { + { /* LCOV_EXCL_START: already checked above */ status = ARES_EBADRESP; break; - } + } /* LCOV_EXCL_STOP */ } if (status == ARES_SUCCESS && naddrs == 0 && naliases == 0) @@ -228,10 +228,10 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, if (host) { /* Allocate memory to build the host entry. */ - hostent = malloc(sizeof(struct hostent)); + hostent = ares_malloc(sizeof(struct hostent)); if (hostent) { - hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *)); + hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *)); if (hostent->h_addr_list) { /* Fill in the hostent and return successfully. */ @@ -243,11 +243,11 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, hostent->h_addr_list[i] = (char *) &addrs[i]; hostent->h_addr_list[naddrs] = NULL; if (!naddrs && addrs) - free(addrs); + ares_free(addrs); *host = hostent; return ARES_SUCCESS; } - free(hostent); + ares_free(hostent); } status = ARES_ENOMEM; } @@ -255,10 +255,10 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, if (aliases) { for (i = 0; i < naliases; i++) - free(aliases[i]); - free(aliases); + ares_free(aliases[i]); + ares_free(aliases); } - free(addrs); - free(hostname); + ares_free(addrs); + ares_free(hostname); return status; } diff --git a/deps/cares/src/ares_parse_aaaa_reply.c b/deps/cares/src/ares_parse_aaaa_reply.c index 31e4a8c375..5b38bb571e 100644 --- a/deps/cares/src/ares_parse_aaaa_reply.c +++ b/deps/cares/src/ares_parse_aaaa_reply.c @@ -87,7 +87,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, return status; if (aptr + len + QFIXEDSZ > abuf + alen) { - free(hostname); + ares_free(hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; @@ -95,17 +95,17 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, /* Allocate addresses and aliases; ancount gives an upper bound for both. */ if (host) { - addrs = malloc(ancount * sizeof(struct ares_in6_addr)); + addrs = ares_malloc(ancount * sizeof(struct ares_in6_addr)); if (!addrs) { - free(hostname); + ares_free(hostname); return ARES_ENOMEM; } - aliases = malloc((ancount + 1) * sizeof(char *)); + aliases = ares_malloc((ancount + 1) * sizeof(char *)); if (!aliases) { - free(hostname); - free(addrs); + ares_free(hostname); + ares_free(addrs); return ARES_ENOMEM; } } @@ -127,7 +127,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, aptr += len; if (aptr + RRFIXEDSZ > abuf + alen) { - free(rr_name); + ares_free(rr_name); status = ARES_EBADRESP; break; } @@ -138,7 +138,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, aptr += RRFIXEDSZ; if (aptr + rr_len > abuf + alen) { - free(rr_name); + ares_free(rr_name); status = ARES_EBADRESP; break; } @@ -150,22 +150,22 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, if (addrs) { if (aptr + sizeof(struct ares_in6_addr) > abuf + alen) - { - free(rr_name); + { /* LCOV_EXCL_START: already checked above */ + ares_free(rr_name); status = ARES_EBADRESP; break; - } + } /* LCOV_EXCL_STOP */ memcpy(&addrs[naddrs], aptr, sizeof(struct ares_in6_addr)); } if (naddrs < max_addr_ttls) { struct ares_addr6ttl * const at = &addrttls[naddrs]; if (aptr + sizeof(struct ares_in6_addr) > abuf + alen) - { - free(rr_name); + { /* LCOV_EXCL_START: already checked above */ + ares_free(rr_name); status = ARES_EBADRESP; break; - } + } /* LCOV_EXCL_STOP */ memcpy(&at->ip6addr, aptr, sizeof(struct ares_in6_addr)); at->ttl = rr_ttl; } @@ -179,7 +179,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, if (aliases) aliases[naliases] = rr_name; else - free(rr_name); + ares_free(rr_name); naliases++; /* Decode the RR data and replace the hostname with it. */ @@ -187,7 +187,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, &len); if (status != ARES_SUCCESS) break; - free(hostname); + ares_free(hostname); hostname = rr_data; /* Take the min of the TTLs we see in the CNAME chain. */ @@ -195,14 +195,14 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, cname_ttl = rr_ttl; } else - free(rr_name); + ares_free(rr_name); aptr += rr_len; if (aptr > abuf + alen) - { + { /* LCOV_EXCL_START: already checked above */ status = ARES_EBADRESP; break; - } + } /* LCOV_EXCL_STOP */ } /* the check for naliases to be zero is to make sure CNAME responses @@ -228,10 +228,10 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, if (host) { /* Allocate memory to build the host entry. */ - hostent = malloc(sizeof(struct hostent)); + hostent = ares_malloc(sizeof(struct hostent)); if (hostent) { - hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *)); + hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *)); if (hostent->h_addr_list) { /* Fill in the hostent and return successfully. */ @@ -243,11 +243,11 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, hostent->h_addr_list[i] = (char *) &addrs[i]; hostent->h_addr_list[naddrs] = NULL; if (!naddrs && addrs) - free(addrs); + ares_free(addrs); *host = hostent; return ARES_SUCCESS; } - free(hostent); + ares_free(hostent); } status = ARES_ENOMEM; } @@ -255,10 +255,10 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, if (aliases) { for (i = 0; i < naliases; i++) - free(aliases[i]); - free(aliases); + ares_free(aliases[i]); + ares_free(aliases); } - free(addrs); - free(hostname); + ares_free(addrs); + ares_free(hostname); return status; } diff --git a/deps/cares/src/ares_parse_mx_reply.c b/deps/cares/src/ares_parse_mx_reply.c index 95400dd317..e6336473e0 100644 --- a/deps/cares/src/ares_parse_mx_reply.c +++ b/deps/cares/src/ares_parse_mx_reply.c @@ -76,7 +76,7 @@ ares_parse_mx_reply (const unsigned char *abuf, int alen, if (aptr + len + QFIXEDSZ > abuf + alen) { - free (hostname); + ares_free (hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; @@ -143,7 +143,7 @@ ares_parse_mx_reply (const unsigned char *abuf, int alen, } /* Don't lose memory in the next iteration */ - free (rr_name); + ares_free (rr_name); rr_name = NULL; /* Move on to the next record */ @@ -151,9 +151,9 @@ ares_parse_mx_reply (const unsigned char *abuf, int alen, } if (hostname) - free (hostname); + ares_free (hostname); if (rr_name) - free (rr_name); + ares_free (rr_name); /* clean up on error */ if (status != ARES_SUCCESS) diff --git a/deps/cares/src/ares_parse_naptr_reply.c b/deps/cares/src/ares_parse_naptr_reply.c index 4935366478..11634df984 100644 --- a/deps/cares/src/ares_parse_naptr_reply.c +++ b/deps/cares/src/ares_parse_naptr_reply.c @@ -81,7 +81,7 @@ ares_parse_naptr_reply (const unsigned char *abuf, int alen, if (aptr + len + QFIXEDSZ > abuf + alen) { - free (hostname); + ares_free (hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; @@ -160,7 +160,7 @@ ares_parse_naptr_reply (const unsigned char *abuf, int alen, } /* Don't lose memory in the next iteration */ - free (rr_name); + ares_free (rr_name); rr_name = NULL; /* Move on to the next record */ @@ -168,9 +168,9 @@ ares_parse_naptr_reply (const unsigned char *abuf, int alen, } if (hostname) - free (hostname); + ares_free (hostname); if (rr_name) - free (rr_name); + ares_free (rr_name); /* clean up on error */ if (status != ARES_SUCCESS) diff --git a/deps/cares/src/ares_parse_ns_reply.c b/deps/cares/src/ares_parse_ns_reply.c index d331e67d5f..7bb51429db 100644 --- a/deps/cares/src/ares_parse_ns_reply.c +++ b/deps/cares/src/ares_parse_ns_reply.c @@ -73,16 +73,16 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen, return status; if ( aptr + len + QFIXEDSZ > abuf + alen ) { - free( hostname ); + ares_free( hostname ); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; /* Allocate nameservers array; ancount gives an upper bound */ - nameservers = malloc( ( ancount + 1 ) * sizeof( char * ) ); + nameservers = ares_malloc( ( ancount + 1 ) * sizeof( char * ) ); if ( !nameservers ) { - free( hostname ); + ares_free( hostname ); return ARES_ENOMEM; } nameservers_num = 0; @@ -98,7 +98,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen, if ( aptr + RRFIXEDSZ > abuf + alen ) { status = ARES_EBADRESP; - free(rr_name); + ares_free(rr_name); break; } rr_type = DNS_RR_TYPE( aptr ); @@ -107,7 +107,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen, aptr += RRFIXEDSZ; if (aptr + rr_len > abuf + alen) { - free(rr_name); + ares_free(rr_name); status = ARES_EBADRESP; break; } @@ -119,33 +119,33 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen, &len); if ( status != ARES_SUCCESS ) { - free(rr_name); + ares_free(rr_name); break; } - nameservers[nameservers_num] = malloc(strlen(rr_data)+1); + nameservers[nameservers_num] = ares_malloc(strlen(rr_data)+1); if (nameservers[nameservers_num]==NULL) { - free(rr_name); - free(rr_data); + ares_free(rr_name); + ares_free(rr_data); status=ARES_ENOMEM; break; } strcpy(nameservers[nameservers_num],rr_data); - free(rr_data); + ares_free(rr_data); nameservers_num++; } - free( rr_name ); + ares_free( rr_name ); aptr += rr_len; if ( aptr > abuf + alen ) - { + { /* LCOV_EXCL_START: already checked above */ status = ARES_EBADRESP; break; - } + } /* LCOV_EXCL_STOP */ } if ( status == ARES_SUCCESS && nameservers_num == 0 ) @@ -156,10 +156,10 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen, { /* We got our answer. Allocate memory to build the host entry. */ nameservers[nameservers_num] = NULL; - hostent = malloc( sizeof( struct hostent ) ); + hostent = ares_malloc( sizeof( struct hostent ) ); if ( hostent ) { - hostent->h_addr_list = malloc( 1 * sizeof( char * ) ); + hostent->h_addr_list = ares_malloc( 1 * sizeof( char * ) ); if ( hostent->h_addr_list ) { /* Fill in the hostent and return successfully. */ @@ -171,13 +171,13 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen, *host = hostent; return ARES_SUCCESS; } - free( hostent ); + ares_free( hostent ); } status = ARES_ENOMEM; } for ( i = 0; i < nameservers_num; i++ ) - free( nameservers[i] ); - free( nameservers ); - free( hostname ); + ares_free( nameservers[i] ); + ares_free( nameservers ); + ares_free( hostname ); return status; } diff --git a/deps/cares/src/ares_parse_ptr_reply.c b/deps/cares/src/ares_parse_ptr_reply.c index df21e40dc1..976a5311a2 100644 --- a/deps/cares/src/ares_parse_ptr_reply.c +++ b/deps/cares/src/ares_parse_ptr_reply.c @@ -73,17 +73,17 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, return status; if (aptr + len + QFIXEDSZ > abuf + alen) { - free(ptrname); + ares_free(ptrname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; /* Examine each answer resource record (RR) in turn. */ hostname = NULL; - aliases = malloc(alias_alloc * sizeof(char *)); + aliases = ares_malloc(alias_alloc * sizeof(char *)); if (!aliases) { - free(ptrname); + ares_free(ptrname); return ARES_ENOMEM; } for (i = 0; i < (int)ancount; i++) @@ -95,7 +95,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, aptr += len; if (aptr + RRFIXEDSZ > abuf + alen) { - free(rr_name); + ares_free(rr_name); status = ARES_EBADRESP; break; } @@ -105,7 +105,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, aptr += RRFIXEDSZ; if (aptr + rr_len > abuf + alen) { - free(rr_name); + ares_free(rr_name); status = ARES_EBADRESP; break; } @@ -118,16 +118,16 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, &len); if (status != ARES_SUCCESS) { - free(rr_name); + ares_free(rr_name); break; } if (hostname) - free(hostname); + ares_free(hostname); hostname = rr_data; - aliases[aliascnt] = malloc((strlen(rr_data)+1) * sizeof(char)); + aliases[aliascnt] = ares_malloc((strlen(rr_data)+1) * sizeof(char)); if (!aliases[aliascnt]) { - free(rr_name); + ares_free(rr_name); status = ARES_ENOMEM; break; } @@ -136,9 +136,9 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, if (aliascnt >= alias_alloc) { char **ptr; alias_alloc *= 2; - ptr = realloc(aliases, alias_alloc * sizeof(char *)); + ptr = ares_realloc(aliases, alias_alloc * sizeof(char *)); if(!ptr) { - free(rr_name); + ares_free(rr_name); status = ARES_ENOMEM; break; } @@ -153,20 +153,20 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, &len); if (status != ARES_SUCCESS) { - free(rr_name); + ares_free(rr_name); break; } - free(ptrname); + ares_free(ptrname); ptrname = rr_data; } - free(rr_name); + ares_free(rr_name); aptr += rr_len; if (aptr > abuf + alen) - { + { /* LCOV_EXCL_START: already checked above */ status = ARES_EBADRESP; break; - } + } /* LCOV_EXCL_STOP */ } if (status == ARES_SUCCESS && !hostname) @@ -174,16 +174,16 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, if (status == ARES_SUCCESS) { /* We got our answer. Allocate memory to build the host entry. */ - hostent = malloc(sizeof(struct hostent)); + hostent = ares_malloc(sizeof(struct hostent)); if (hostent) { - hostent->h_addr_list = malloc(2 * sizeof(char *)); + hostent->h_addr_list = ares_malloc(2 * sizeof(char *)); if (hostent->h_addr_list) { - hostent->h_addr_list[0] = malloc(addrlen); + hostent->h_addr_list[0] = ares_malloc(addrlen); if (hostent->h_addr_list[0]) { - hostent->h_aliases = malloc((aliascnt+1) * sizeof (char *)); + hostent->h_aliases = ares_malloc((aliascnt+1) * sizeof (char *)); if (hostent->h_aliases) { /* Fill in the hostent and return successfully. */ @@ -196,24 +196,24 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, memcpy(hostent->h_addr_list[0], addr, addrlen); hostent->h_addr_list[1] = NULL; *host = hostent; - free(aliases); - free(ptrname); + ares_free(aliases); + ares_free(ptrname); return ARES_SUCCESS; } - free(hostent->h_addr_list[0]); + ares_free(hostent->h_addr_list[0]); } - free(hostent->h_addr_list); + ares_free(hostent->h_addr_list); } - free(hostent); + ares_free(hostent); } status = ARES_ENOMEM; } for (i=0 ; iexpire = DNS__32BIT(aptr + 3 * 4); soa->minttl = DNS__32BIT(aptr + 4 * 4); - free(qname); - free(rr_name); + ares_free(qname); + ares_free(rr_name); *soa_out = soa; @@ -125,9 +125,9 @@ failed: failed_stat: ares_free_data(soa); if (qname) - free(qname); + ares_free(qname); if (rr_name) - free(rr_name); + ares_free(rr_name); return status; } diff --git a/deps/cares/src/ares_parse_srv_reply.c b/deps/cares/src/ares_parse_srv_reply.c index 0739c27684..824ff3aedf 100644 --- a/deps/cares/src/ares_parse_srv_reply.c +++ b/deps/cares/src/ares_parse_srv_reply.c @@ -81,7 +81,7 @@ ares_parse_srv_reply (const unsigned char *abuf, int alen, if (aptr + len + QFIXEDSZ > abuf + alen) { - free (hostname); + ares_free (hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; @@ -152,7 +152,7 @@ ares_parse_srv_reply (const unsigned char *abuf, int alen, } /* Don't lose memory in the next iteration */ - free (rr_name); + ares_free (rr_name); rr_name = NULL; /* Move on to the next record */ @@ -160,9 +160,9 @@ ares_parse_srv_reply (const unsigned char *abuf, int alen, } if (hostname) - free (hostname); + ares_free (hostname); if (rr_name) - free (rr_name); + ares_free (rr_name); /* clean up on error */ if (status != ARES_SUCCESS) diff --git a/deps/cares/src/ares_parse_txt_reply.c b/deps/cares/src/ares_parse_txt_reply.c index dabf73cd3f..4856b4cea3 100644 --- a/deps/cares/src/ares_parse_txt_reply.c +++ b/deps/cares/src/ares_parse_txt_reply.c @@ -44,9 +44,9 @@ #include "ares_data.h" #include "ares_private.h" -int -ares_parse_txt_reply (const unsigned char *abuf, int alen, - struct ares_txt_reply **txt_out) +static int +ares__parse_txt_reply (const unsigned char *abuf, int alen, + int ex, void **txt_out) { size_t substr_len; unsigned int qdcount, ancount, i; @@ -55,9 +55,9 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen, int status, rr_type, rr_class, rr_len; long len; char *hostname = NULL, *rr_name = NULL; - struct ares_txt_reply *txt_head = NULL; - struct ares_txt_reply *txt_last = NULL; - struct ares_txt_reply *txt_curr; + struct ares_txt_ext *txt_head = NULL; + struct ares_txt_ext *txt_last = NULL; + struct ares_txt_ext *txt_curr; /* Set *txt_out to NULL for all failure cases. */ *txt_out = NULL; @@ -82,7 +82,7 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen, if (aptr + len + QFIXEDSZ > abuf + alen) { - free (hostname); + ares_free (hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; @@ -134,7 +134,8 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen, } /* Allocate storage for this TXT answer appending it to the list */ - txt_curr = ares_malloc_data(ARES_DATATYPE_TXT_REPLY); + txt_curr = ares_malloc_data(ex ? ARES_DATATYPE_TXT_EXT : + ARES_DATATYPE_TXT_REPLY); if (!txt_curr) { status = ARES_ENOMEM; @@ -150,9 +151,10 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen, } txt_last = txt_curr; - txt_curr->record_start = strptr == aptr; + if (ex) + txt_curr->record_start = (strptr == aptr); txt_curr->length = substr_len; - txt_curr->txt = malloc (substr_len + 1/* Including null byte */); + txt_curr->txt = ares_malloc (substr_len + 1/* Including null byte */); if (txt_curr->txt == NULL) { status = ARES_ENOMEM; @@ -169,8 +171,14 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen, } } + /* Propagate any failures */ + if (status != ARES_SUCCESS) + { + break; + } + /* Don't lose memory in the next iteration */ - free (rr_name); + ares_free (rr_name); rr_name = NULL; /* Move on to the next record */ @@ -178,9 +186,9 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen, } if (hostname) - free (hostname); + ares_free (hostname); if (rr_name) - free (rr_name); + ares_free (rr_name); /* clean up on error */ if (status != ARES_SUCCESS) @@ -195,3 +203,18 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen, return ARES_SUCCESS; } + +int +ares_parse_txt_reply (const unsigned char *abuf, int alen, + struct ares_txt_reply **txt_out) +{ + return ares__parse_txt_reply(abuf, alen, 0, (void **) txt_out); +} + + +int +ares_parse_txt_reply_ext (const unsigned char *abuf, int alen, + struct ares_txt_ext **txt_out) +{ + return ares__parse_txt_reply(abuf, alen, 1, (void **) txt_out); +} diff --git a/deps/cares/src/ares_private.h b/deps/cares/src/ares_private.h index 8f486a449a..45f34ab72d 100644 --- a/deps/cares/src/ares_private.h +++ b/deps/cares/src/ares_private.h @@ -43,6 +43,13 @@ #define INADDR_NONE 0xffffffff #endif +#ifdef CARES_EXPOSE_STATICS +/* Make some internal functions visible for testing */ +#define STATIC_TESTABLE +#else +#define STATIC_TESTABLE static +#endif + #if defined(WIN32) && !defined(WATT32) #define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP" @@ -86,10 +93,7 @@ # define getenv(ptr) ares_getenv(ptr) #endif -#ifndef HAVE_STRDUP -# include "ares_strdup.h" -# define strdup(ptr) ares_strdup(ptr) -#endif +#include "ares_strdup.h" #ifndef HAVE_STRCASECMP # include "ares_strcasecmp.h" @@ -119,6 +123,8 @@ struct ares_addr { struct in_addr addr4; struct ares_in6_addr addr6; } addr; + int udp_port; /* stored in network order */ + int tcp_port; /* stored in network order */ }; #define addrV4 addr.addr4 #define addrV6 addr.addr6 @@ -251,8 +257,8 @@ struct ares_channeldata { int tries; int ndots; int rotate; /* if true, all servers specified are used */ - int udp_port; - int tcp_port; + int udp_port; /* stored in network order */ + int tcp_port; /* stored in network order */ int socket_send_buffer_size; int socket_receive_buffer_size; char **domains; @@ -307,12 +313,15 @@ struct ares_channeldata { void *sock_create_cb_data; }; +/* Memory management functions */ +extern void *(*ares_malloc)(size_t size); +extern void *(*ares_realloc)(void *ptr, size_t size); +extern void (*ares_free)(void *ptr); + /* return true if now is exactly check time or later */ int ares__timedout(struct timeval *now, struct timeval *check); -/* returns ARES_SUCCESS if library has been initialized */ -int ares_library_initialized(void); void ares__send_query(ares_channel channel, struct query *query, struct timeval *now); void ares__close_sockets(ares_channel channel, struct server_state *server); diff --git a/deps/cares/src/ares_process.c b/deps/cares/src/ares_process.c index 020a1319e5..c3ac77b00e 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-2013 by Daniel Stenberg + * Copyright (C) 2004-2016 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without @@ -227,7 +227,7 @@ static void write_tcp_data(ares_channel channel, n++; /* Allocate iovecs so we can send all our data at once. */ - vec = malloc(n * sizeof(struct iovec)); + vec = ares_malloc(n * sizeof(struct iovec)); if (vec) { /* Fill in the iovecs and send. */ @@ -239,7 +239,7 @@ static void write_tcp_data(ares_channel channel, n++; } wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n); - free(vec); + ares_free(vec); if (wcount < 0) { if (!try_again(SOCKERRNO)) @@ -281,8 +281,8 @@ static void advance_tcp_send_queue(ares_channel channel, int whichserver, num_bytes -= sendreq->len; server->qhead = sendreq->next; if (sendreq->data_storage) - free(sendreq->data_storage); - free(sendreq); + ares_free(sendreq->data_storage); + ares_free(sendreq); if (server->qhead == NULL) { SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0); server->qtail = NULL; @@ -361,9 +361,12 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, */ server->tcp_length = server->tcp_lenbuf[0] << 8 | server->tcp_lenbuf[1]; - server->tcp_buffer = malloc(server->tcp_length); - if (!server->tcp_buffer) + server->tcp_buffer = ares_malloc(server->tcp_length); + if (!server->tcp_buffer) { handle_error(channel, i, now); + return; /* bail out on malloc failure. TODO: make this + function return error codes */ + } server->tcp_buffer_pos = 0; } } @@ -388,8 +391,8 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, */ process_answer(channel, server->tcp_buffer, server->tcp_length, i, 1, now); - if (server->tcp_buffer) - free(server->tcp_buffer); + if (server->tcp_buffer) + ares_free(server->tcp_buffer); server->tcp_buffer = NULL; server->tcp_lenbuf_pos = 0; server->tcp_buffer_pos = 0; @@ -563,14 +566,15 @@ static void process_answer(ares_channel channel, unsigned char *abuf, packetsz = channel->ednspsz; if (rcode == NOTIMP || rcode == FORMERR || rcode == SERVFAIL) { - int qlen = alen - EDNSFIXEDSZ; + int qlen = (query->tcplen - 2) - EDNSFIXEDSZ; channel->flags ^= ARES_FLAG_EDNS; query->tcplen -= EDNSFIXEDSZ; query->qlen -= EDNSFIXEDSZ; query->tcpbuf[0] = (unsigned char)((qlen >> 8) & 0xff); query->tcpbuf[1] = (unsigned char)(qlen & 0xff); DNS_HEADER_SET_ARCOUNT(query->tcpbuf + 2, 0); - query->tcpbuf = realloc(query->tcpbuf, query->tcplen); + query->tcpbuf = ares_realloc(query->tcpbuf, query->tcplen); + query->qbuf = query->tcpbuf + 2; ares__send_query(channel, query, now); return; } @@ -769,12 +773,13 @@ void ares__send_query(ares_channel channel, struct query *query, return; } } - sendreq = calloc(1, sizeof(struct send_request)); + sendreq = ares_malloc(sizeof(struct send_request)); if (!sendreq) { end_query(channel, query, ARES_ENOMEM, NULL, 0); return; } + memset(sendreq, 0, sizeof(struct send_request)); /* To make the common case fast, we avoid copies by using the query's * tcpbuf for as long as the query is alive. In the rare case where the * query ends while it's queued for transmission, then we give the @@ -843,7 +848,7 @@ void ares__send_query(ares_channel channel, struct query *query, * portable. */ static int setsocknonblock(ares_socket_t sockfd, /* operate on this */ - int nonblock /* TRUE or FALSE */) + int nonblock /* TRUE or FALSE */) { #if defined(USE_BLOCKING_SOCKETS) @@ -857,7 +862,7 @@ static int setsocknonblock(ares_socket_t sockfd, /* operate on this */ if (FALSE != nonblock) return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); else - return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); + return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); /* LCOV_EXCL_LINE */ #elif defined(HAVE_IOCTL_FIONBIO) @@ -900,12 +905,12 @@ static int configure_socket(ares_socket_t s, int family, ares_channel channel) struct sockaddr_in6 sa6; } local; - setsocknonblock(s, TRUE); + (void)setsocknonblock(s, TRUE); #if defined(FD_CLOEXEC) && !defined(MSDOS) /* Configure the socket fd as close-on-exec. */ if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) - return -1; + return -1; /* LCOV_EXCL_LINE */ #endif /* Set the socket's send and receive buffer sizes. */ @@ -973,7 +978,11 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server) salen = sizeof(saddr.sa4); memset(sa, 0, salen); saddr.sa4.sin_family = AF_INET; - saddr.sa4.sin_port = aresx_sitous(channel->tcp_port); + if (server->addr.tcp_port) { + saddr.sa4.sin_port = aresx_sitous(server->addr.tcp_port); + } else { + saddr.sa4.sin_port = aresx_sitous(channel->tcp_port); + } memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4, sizeof(server->addr.addrV4)); break; @@ -982,12 +991,16 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server) salen = sizeof(saddr.sa6); memset(sa, 0, salen); saddr.sa6.sin6_family = AF_INET6; - saddr.sa6.sin6_port = aresx_sitous(channel->tcp_port); + if (server->addr.tcp_port) { + saddr.sa6.sin6_port = aresx_sitous(server->addr.tcp_port); + } else { + saddr.sa6.sin6_port = aresx_sitous(channel->tcp_port); + } memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6, sizeof(server->addr.addrV6)); break; default: - return -1; + return -1; /* LCOV_EXCL_LINE */ } /* Acquire a socket. */ @@ -1065,7 +1078,11 @@ static int open_udp_socket(ares_channel channel, struct server_state *server) salen = sizeof(saddr.sa4); memset(sa, 0, salen); saddr.sa4.sin_family = AF_INET; - saddr.sa4.sin_port = aresx_sitous(channel->udp_port); + if (server->addr.udp_port) { + saddr.sa4.sin_port = aresx_sitous(server->addr.udp_port); + } else { + saddr.sa4.sin_port = aresx_sitous(channel->udp_port); + } memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4, sizeof(server->addr.addrV4)); break; @@ -1074,12 +1091,16 @@ static int open_udp_socket(ares_channel channel, struct server_state *server) salen = sizeof(saddr.sa6); memset(sa, 0, salen); saddr.sa6.sin6_family = AF_INET6; - saddr.sa6.sin6_port = aresx_sitous(channel->udp_port); + if (server->addr.udp_port) { + saddr.sa6.sin6_port = aresx_sitous(server->addr.udp_port); + } else { + saddr.sa6.sin6_port = aresx_sitous(channel->udp_port); + } memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6, sizeof(server->addr.addrV6)); break; default: - return -1; + return -1; /* LCOV_EXCL_LINE */ } /* Acquire a socket. */ @@ -1156,7 +1177,7 @@ static int same_questions(const unsigned char *qbuf, int qlen, q.p += q.namelen; if (q.p + QFIXEDSZ > qbuf + qlen) { - free(q.name); + ares_free(q.name); return 0; } q.type = DNS_QUESTION_TYPE(q.p); @@ -1171,14 +1192,14 @@ static int same_questions(const unsigned char *qbuf, int qlen, if (ares_expand_name(a.p, abuf, alen, &a.name, &a.namelen) != ARES_SUCCESS) { - free(q.name); + ares_free(q.name); return 0; } a.p += a.namelen; if (a.p + QFIXEDSZ > abuf + alen) { - free(q.name); - free(a.name); + ares_free(q.name); + ares_free(a.name); return 0; } a.type = DNS_QUESTION_TYPE(a.p); @@ -1189,13 +1210,13 @@ static int same_questions(const unsigned char *qbuf, int qlen, if (strcasecmp(q.name, a.name) == 0 && q.type == a.type && q.dnsclass == a.dnsclass) { - free(a.name); + ares_free(a.name); break; } - free(a.name); + ares_free(a.name); } - free(q.name); + ares_free(q.name); if (j == a.qdcount) return 0; } @@ -1224,7 +1245,7 @@ static int same_address(struct sockaddr *sa, struct ares_addr *aa) return 1; /* match */ break; default: - break; + break; /* LCOV_EXCL_LINE */ } } return 0; /* different */ @@ -1261,7 +1282,7 @@ static void end_query (ares_channel channel, struct query *query, int status, * to the query's tcpbuf and handle these cases, we just give * such sendreqs their own copy of the query packet. */ - sendreq->data_storage = malloc(sendreq->len); + sendreq->data_storage = ares_malloc(sendreq->len); if (sendreq->data_storage != NULL) { memcpy(sendreq->data_storage, sendreq->data, sendreq->len); @@ -1311,7 +1332,7 @@ void ares__free_query(struct query *query) query->callback = NULL; query->arg = NULL; /* Deallocate the memory associated with the query */ - free(query->tcpbuf); - free(query->server_info); - free(query); + ares_free(query->tcpbuf); + ares_free(query->server_info); + ares_free(query); } diff --git a/deps/cares/src/ares_query.c b/deps/cares/src/ares_query.c index 4bc9c2560f..b38b8a6c22 100644 --- a/deps/cares/src/ares_query.c +++ b/deps/cares/src/ares_query.c @@ -121,7 +121,7 @@ void ares_query(ares_channel channel, const char *name, int dnsclass, &qlen, (channel->flags & ARES_FLAG_EDNS) ? channel->ednspsz : 0); if (status != ARES_SUCCESS) { - if (qbuf != NULL) free(qbuf); + if (qbuf != NULL) ares_free(qbuf); callback(arg, status, 0, NULL, 0); return; } @@ -129,7 +129,7 @@ void ares_query(ares_channel channel, const char *name, int dnsclass, channel->next_id = generate_unique_id(channel); /* Allocate and fill in the query structure. */ - qquery = malloc(sizeof(struct qquery)); + qquery = ares_malloc(sizeof(struct qquery)); if (!qquery) { ares_free_string(qbuf); @@ -182,5 +182,5 @@ static void qcallback(void *arg, int status, int timeouts, unsigned char *abuf, } qquery->callback(qquery->arg, status, timeouts, abuf, alen); } - free(qquery); + ares_free(qquery); } diff --git a/deps/cares/src/ares_rules.h b/deps/cares/src/ares_rules.h deleted file mode 100644 index 44f08f807c..0000000000 --- a/deps/cares/src/ares_rules.h +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef __CARES_RULES_H -#define __CARES_RULES_H - - -/* Copyright (C) 2009 by Daniel Stenberg et al - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of M.I.T. not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. M.I.T. makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - */ - -/* ================================================================ */ -/* COMPILE TIME SANITY CHECKS */ -/* ================================================================ */ - -/* - * NOTE 1: - * ------- - * - * All checks done in this file are intentionally placed in a public - * header file which is pulled by ares.h when an application is - * being built using an already built c-ares library. Additionally - * this file is also included and used when building the library. - * - * If compilation fails on this file it is certainly sure that the - * problem is elsewhere. It could be a problem in the ares_build.h - * header file, or simply that you are using different compilation - * settings than those used to build the library. - * - * Nothing in this file is intended to be modified or adjusted by the - * c-ares library user nor by the c-ares library builder. - * - * Do not deactivate any check, these are done to make sure that the - * library is properly built and used. - * - * You can find further help on the c-ares development mailing list: - * http://cool.haxx.se/mailman/listinfo/c-ares/ - * - * NOTE 2 - * ------ - * - * Some of the following compile time checks are based on the fact - * that the dimension of a constant array can not be a negative one. - * In this way if the compile time verification fails, the compilation - * will fail issuing an error. The error description wording is compiler - * dependent but it will be quite similar to one of the following: - * - * "negative subscript or subscript is too large" - * "array must have at least one element" - * "-1 is an illegal array size" - * "size of array is negative" - * - * If you are building an application which tries to use an already - * built c-ares library and you are getting this kind of errors on - * this file, it is a clear indication that there is a mismatch between - * how the library was built and how you are trying to use it for your - * application. Your already compiled or binary library provider is the - * only one who can give you the details you need to properly use it. - */ - -/* - * Verify that some macros are actually defined. - */ - -#ifndef CARES_TYPEOF_ARES_SOCKLEN_T -# error "CARES_TYPEOF_ARES_SOCKLEN_T definition is missing!" - Error Compilation_aborted_CARES_TYPEOF_ARES_SOCKLEN_T_is_missing -#endif - -#ifndef CARES_SIZEOF_ARES_SOCKLEN_T -# error "CARES_SIZEOF_ARES_SOCKLEN_T definition is missing!" - Error Compilation_aborted_CARES_SIZEOF_ARES_SOCKLEN_T_is_missing -#endif - -/* - * Macros private to this header file. - */ - -#define CareschkszEQ(t, s) sizeof(t) == s ? 1 : -1 - -#define CareschkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 - -/* - * Verify that the size previously defined and expected for - * ares_socklen_t is actually the the same as the one reported - * by sizeof() at compile time. - */ - -typedef char - __cares_rule_02__ - [CareschkszEQ(ares_socklen_t, CARES_SIZEOF_ARES_SOCKLEN_T)]; - -/* - * Verify at compile time that the size of ares_socklen_t as reported - * by sizeof() is greater or equal than the one reported for int for - * the current compilation. - */ - -typedef char - __cares_rule_03__ - [CareschkszGE(ares_socklen_t, int)]; - -/* ================================================================ */ -/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ -/* ================================================================ */ - -/* - * Get rid of macros private to this header file. - */ - -#undef CareschkszEQ -#undef CareschkszGE - -/* - * Get rid of macros not intended to exist beyond this point. - */ - -#undef CARES_PULL_WS2TCPIP_H -#undef CARES_PULL_SYS_TYPES_H -#undef CARES_PULL_SYS_SOCKET_H - -#undef CARES_TYPEOF_ARES_SOCKLEN_T - -#endif /* __CARES_RULES_H */ diff --git a/deps/cares/src/ares_search.c b/deps/cares/src/ares_search.c index f9558a9a50..68e852574f 100644 --- a/deps/cares/src/ares_search.c +++ b/deps/cares/src/ares_search.c @@ -44,7 +44,7 @@ static void search_callback(void *arg, int status, int timeouts, static void end_squery(struct search_query *squery, int status, unsigned char *abuf, int alen); static int cat_domain(const char *name, const char *domain, char **s); -static int single_domain(ares_channel channel, const char *name, char **s); +STATIC_TESTABLE int single_domain(ares_channel channel, const char *name, char **s); void ares_search(ares_channel channel, const char *name, int dnsclass, int type, ares_callback callback, void *arg) @@ -66,24 +66,24 @@ void ares_search(ares_channel channel, const char *name, int dnsclass, if (s) { ares_query(channel, s, dnsclass, type, callback, arg); - free(s); + ares_free(s); return; } /* Allocate a search_query structure to hold the state necessary for * doing multiple lookups. */ - squery = malloc(sizeof(struct search_query)); + squery = ares_malloc(sizeof(struct search_query)); if (!squery) { callback(arg, ARES_ENOMEM, 0, NULL, 0); return; } squery->channel = channel; - squery->name = strdup(name); + squery->name = ares_strdup(name); if (!squery->name) { - free(squery); + ares_free(squery); callback(arg, ARES_ENOMEM, 0, NULL, 0); return; } @@ -123,13 +123,13 @@ void ares_search(ares_channel channel, const char *name, int dnsclass, if (status == ARES_SUCCESS) { ares_query(channel, s, dnsclass, type, search_callback, squery); - free(s); + ares_free(s); } else { /* failed, free the malloc()ed memory */ - free(squery->name); - free(squery); + ares_free(squery->name); + ares_free(squery); callback(arg, status, 0, NULL, 0); } } @@ -177,7 +177,7 @@ static void search_callback(void *arg, int status, int timeouts, squery->next_domain++; ares_query(channel, s, squery->dnsclass, squery->type, search_callback, squery); - free(s); + ares_free(s); } } else if (squery->status_as_is == -1) @@ -201,8 +201,8 @@ static void end_squery(struct search_query *squery, int status, unsigned char *abuf, int alen) { squery->callback(squery->arg, status, squery->timeouts, abuf, alen); - free(squery->name); - free(squery); + ares_free(squery->name); + ares_free(squery); } /* Concatenate two domains. */ @@ -211,7 +211,7 @@ static int cat_domain(const char *name, const char *domain, char **s) size_t nlen = strlen(name); size_t dlen = strlen(domain); - *s = malloc(nlen + 1 + dlen + 1); + *s = ares_malloc(nlen + 1 + dlen + 1); if (!*s) return ARES_ENOMEM; memcpy(*s, name, nlen); @@ -225,7 +225,7 @@ static int cat_domain(const char *name, const char *domain, char **s) * the string we should query, in an allocated buffer. If not, set *s * to NULL. */ -static int single_domain(ares_channel channel, const char *name, char **s) +STATIC_TESTABLE int single_domain(ares_channel channel, const char *name, char **s) { size_t len = strlen(name); const char *hostaliases; @@ -241,7 +241,7 @@ static int single_domain(ares_channel channel, const char *name, char **s) */ if ((len > 0) && (name[len - 1] == '.')) { - *s = strdup(name); + *s = ares_strdup(name); return (*s) ? ARES_SUCCESS : ARES_ENOMEM; } @@ -268,18 +268,18 @@ static int single_domain(ares_channel channel, const char *name, char **s) q = p + 1; while (*q && !ISSPACE(*q)) q++; - *s = malloc(q - p + 1); + *s = ares_malloc(q - p + 1); if (*s) { memcpy(*s, p, q - p); (*s)[q - p] = 0; } - free(line); + ares_free(line); fclose(fp); return (*s) ? ARES_SUCCESS : ARES_ENOMEM; } } - free(line); + ares_free(line); fclose(fp); if (status != ARES_SUCCESS && status != ARES_EOF) return status; @@ -307,7 +307,7 @@ static int single_domain(ares_channel channel, const char *name, char **s) if (channel->flags & ARES_FLAG_NOSEARCH || channel->ndomains == 0) { /* No domain search to do; just try the name as-is. */ - *s = strdup(name); + *s = ares_strdup(name); return (*s) ? ARES_SUCCESS : ARES_ENOMEM; } diff --git a/deps/cares/src/ares_send.c b/deps/cares/src/ares_send.c index 1a450b1e6d..88c0035520 100644 --- a/deps/cares/src/ares_send.c +++ b/deps/cares/src/ares_send.c @@ -47,25 +47,25 @@ void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, } /* Allocate space for query and allocated fields. */ - query = malloc(sizeof(struct query)); + query = ares_malloc(sizeof(struct query)); if (!query) { callback(arg, ARES_ENOMEM, 0, NULL, 0); return; } - query->tcpbuf = malloc(qlen + 2); + query->tcpbuf = ares_malloc(qlen + 2); if (!query->tcpbuf) { - free(query); + ares_free(query); callback(arg, ARES_ENOMEM, 0, NULL, 0); return; } - query->server_info = malloc(channel->nservers * - sizeof(query->server_info[0])); + query->server_info = ares_malloc(channel->nservers * + sizeof(query->server_info[0])); if (!query->server_info) { - free(query->tcpbuf); - free(query); + ares_free(query->tcpbuf); + ares_free(query); callback(arg, ARES_ENOMEM, 0, NULL, 0); return; } diff --git a/deps/cares/src/ares_strdup.c b/deps/cares/src/ares_strdup.c index 18043274e9..0c3dcffc30 100644 --- a/deps/cares/src/ares_strdup.c +++ b/deps/cares/src/ares_strdup.c @@ -17,26 +17,33 @@ #include "ares_setup.h" #include "ares_strdup.h" +#include "ares.h" +#include "ares_private.h" -#ifndef HAVE_STRDUP char *ares_strdup(const char *s1) { - size_t sz; - char * s2; +#ifdef HAVE_STRDUP + if (ares_malloc == malloc) + return strdup(s1); + else +#endif + { + size_t sz; + char * s2; - if(s1) { - sz = strlen(s1); - if(sz < (size_t)-1) { - sz++; - if(sz < ((size_t)-1) / sizeof(char)) { - s2 = malloc(sz * sizeof(char)); - if(s2) { - memcpy(s2, s1, sz * sizeof(char)); - return s2; + if(s1) { + sz = strlen(s1); + if(sz < (size_t)-1) { + sz++; + if(sz < ((size_t)-1) / sizeof(char)) { + s2 = ares_malloc(sz * sizeof(char)); + if(s2) { + memcpy(s2, s1, sz * sizeof(char)); + return s2; + } } } } + return (char *)NULL; } - return (char *)NULL; } -#endif diff --git a/deps/cares/src/ares_strdup.h b/deps/cares/src/ares_strdup.h index c413a941c5..67f2a74f5f 100644 --- a/deps/cares/src/ares_strdup.h +++ b/deps/cares/src/ares_strdup.h @@ -19,8 +19,6 @@ #include "ares_setup.h" -#ifndef HAVE_STRDUP extern char *ares_strdup(const char *s1); -#endif #endif /* HEADER_CARES_STRDUP_H */ diff --git a/deps/cares/src/ares_writev.c b/deps/cares/src/ares_writev.c index 9e8e2d6574..008efddc57 100644 --- a/deps/cares/src/ares_writev.c +++ b/deps/cares/src/ares_writev.c @@ -54,7 +54,7 @@ ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt) return (0); /* Allocate a temporary buffer to hold the data */ - buffer = malloc(bytes); + buffer = ares_malloc(bytes); if (!buffer) { SET_ERRNO(ENOMEM); @@ -71,7 +71,7 @@ ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt) /* Send buffer contents */ result = swrite(s, buffer, bytes); - free(buffer); + ares_free(buffer); return (result); } diff --git a/deps/cares/src/bitncmp.c b/deps/cares/src/bitncmp.c index faedff9afd..1468d4923a 100644 --- a/deps/cares/src/bitncmp.c +++ b/deps/cares/src/bitncmp.c @@ -26,7 +26,7 @@ * bitncmp(l, r, n) * compare bit masks l and r, for n bits. * return: - * -1, 1, or 0 in the libc tradition. + * <0, >0, or 0 in the libc tradition. * note: * network byte order assumed. this means 192.5.5.240/28 has * 0x11110000 in its fourth octet. diff --git a/deps/cares/src/inet_net_pton.c b/deps/cares/src/inet_net_pton.c index 71c07c59ca..b64fc5b1d1 100644 --- a/deps/cares/src/inet_net_pton.c +++ b/deps/cares/src/inet_net_pton.c @@ -151,7 +151,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) /* If nothing was written to the destination, we found no address. */ if (dst == odst) - goto enoent; + goto enoent; /* LCOV_EXCL_LINE: all valid paths above increment dst */ /* If no CIDR spec was given, infer width from net class. */ if (bits == -1) { if (*odst >= 240) /* Class E */ -- cgit v1.2.3