Browse Source

deps: sync with upstream bagder/c-ares@2bae2d5

PR-URL: https://github.com/nodejs/node/pull/5090
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
v5.x
Fedor Indutny 9 years ago
committed by Rod Vagg
parent
commit
f1a0827417
  1. 50
      deps/cares/include/ares.h
  2. 117
      deps/cares/include/ares_build.h
  3. 0
      deps/cares/include/ares_rules.h
  4. 6
      deps/cares/src/ares__close_sockets.c
  5. 30
      deps/cares/src/ares__get_hostent.c
  6. 7
      deps/cares/src/ares__read_line.c
  7. 2
      deps/cares/src/ares__timeval.c
  8. 2
      deps/cares/src/ares_create_query.c
  9. 44
      deps/cares/src/ares_data.c
  10. 16
      deps/cares/src/ares_data.h
  11. 22
      deps/cares/src/ares_destroy.c
  12. 18
      deps/cares/src/ares_expand_name.c
  13. 2
      deps/cares/src/ares_expand_string.c
  14. 12
      deps/cares/src/ares_free_hostent.c
  15. 2
      deps/cares/src/ares_free_string.c
  16. 4
      deps/cares/src/ares_gethostbyaddr.c
  17. 16
      deps/cares/src/ares_gethostbyname.c
  18. 20
      deps/cares/src/ares_getnameinfo.c
  19. 349
      deps/cares/src/ares_init.c
  20. 27
      deps/cares/src/ares_library_init.c
  21. 157
      deps/cares/src/ares_options.c
  22. 54
      deps/cares/src/ares_parse_a_reply.c
  23. 54
      deps/cares/src/ares_parse_aaaa_reply.c
  24. 8
      deps/cares/src/ares_parse_mx_reply.c
  25. 8
      deps/cares/src/ares_parse_naptr_reply.c
  26. 38
      deps/cares/src/ares_parse_ns_reply.c
  27. 58
      deps/cares/src/ares_parse_ptr_reply.c
  28. 8
      deps/cares/src/ares_parse_soa_reply.c
  29. 8
      deps/cares/src/ares_parse_srv_reply.c
  30. 49
      deps/cares/src/ares_parse_txt_reply.c
  31. 25
      deps/cares/src/ares_private.h
  32. 89
      deps/cares/src/ares_process.c
  33. 6
      deps/cares/src/ares_query.c
  34. 36
      deps/cares/src/ares_search.c
  35. 14
      deps/cares/src/ares_send.c
  36. 35
      deps/cares/src/ares_strdup.c
  37. 2
      deps/cares/src/ares_strdup.h
  38. 4
      deps/cares/src/ares_writev.c
  39. 2
      deps/cares/src/bitncmp.c
  40. 2
      deps/cares/src/inet_net_pton.c
  41. 6
      src/cares_wrap.cc

50
deps/cares/include/ares.h

@ -19,6 +19,8 @@
#define ARES__H #define ARES__H
#include "ares_version.h" /* c-ares version defines */ #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 * Define WIN32 when build target is Win32 API
@ -29,9 +31,6 @@
# define WIN32 # define WIN32
#endif #endif
/* Data type definition of ares_socklen_t. */
typedef unsigned ares_socklen_t;
#include <sys/types.h> #include <sys/types.h>
/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish /* 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(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 void ares_library_cleanup(void);
CARES_EXTERN const char *ares_version(int *version); 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, ares_sock_create_callback callback,
void *user_data); void *user_data);
CARES_EXTERN int ares_set_sortlist(ares_channel channel,
const char *sortstr);
CARES_EXTERN void ares_send(ares_channel channel, CARES_EXTERN void ares_send(ares_channel channel,
const unsigned char *qbuf, const unsigned char *qbuf,
int qlen, int qlen,
@ -473,8 +482,17 @@ struct ares_txt_reply {
struct ares_txt_reply *next; struct ares_txt_reply *next;
unsigned char *txt; unsigned char *txt;
size_t length; /* length excludes null termination */ 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 { struct ares_naptr_reply {
@ -540,6 +558,10 @@ CARES_EXTERN int ares_parse_txt_reply(const unsigned char* abuf,
int alen, int alen,
struct ares_txt_reply** txt_out); 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, CARES_EXTERN int ares_parse_naptr_reply(const unsigned char* abuf,
int alen, int alen,
struct ares_naptr_reply** naptr_out); 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); CARES_EXTERN const char *ares_strerror(int code);
/* TODO: Hold port here as well. */
struct ares_addr_node { struct ares_addr_node {
struct ares_addr_node *next; struct ares_addr_node *next;
int family; int family;
@ -566,15 +587,32 @@ struct ares_addr_node {
} addr; } 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, CARES_EXTERN int ares_set_servers(ares_channel channel,
struct ares_addr_node *servers); 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]]... */ /* Incomming string format: host[:port][,host[:port]]... */
CARES_EXTERN int ares_set_servers_csv(ares_channel channel, CARES_EXTERN int ares_set_servers_csv(ares_channel channel,
const char* servers); 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, CARES_EXTERN int ares_get_servers(ares_channel channel,
struct ares_addr_node **servers); 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, CARES_EXTERN const char *ares_inet_ntop(int af, const void *src, char *dst,
ares_socklen_t size); ares_socklen_t size);

117
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 <windows.h>
# include <winsock2.h>
# include <ws2tcpip.h>
#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 <sys/types.h>
#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 <sys/socket.h>
#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 */

0
deps/cares/src/ares_rules.h → deps/cares/include/ares_rules.h

6
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; sendreq = server->qhead;
server->qhead = sendreq->next; server->qhead = sendreq->next;
if (sendreq->data_storage != NULL) if (sendreq->data_storage != NULL)
free(sendreq->data_storage); ares_free(sendreq->data_storage);
free(sendreq); ares_free(sendreq);
} }
server->qtail = NULL; server->qtail = NULL;
/* Reset any existing input buffer. */ /* Reset any existing input buffer. */
if (server->tcp_buffer) if (server->tcp_buffer)
free(server->tcp_buffer); ares_free(server->tcp_buffer);
server->tcp_buffer = NULL; server->tcp_buffer = NULL;
server->tcp_lenbuf_pos = 0; server->tcp_lenbuf_pos = 0;

30
deps/cares/src/ares__get_hostent.c

@ -94,7 +94,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
p++; p++;
if (!*p) if (!*p)
/* Ignore line if reached end of line. */ /* Ignore line if reached end of line. */
continue; continue; /* LCOV_EXCL_LINE: trailing whitespace already stripped */
/* Pointer to start of host name. */ /* Pointer to start of host name. */
txthost = p; txthost = p;
@ -164,7 +164,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
*/ */
/* Allocate memory for the hostent structure. */ /* Allocate memory for the hostent structure. */
hostent = malloc(sizeof(struct hostent)); hostent = ares_malloc(sizeof(struct hostent));
if (!hostent) if (!hostent)
break; break;
@ -173,16 +173,16 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
hostent->h_addr_list = NULL; hostent->h_addr_list = NULL;
/* Copy official host name. */ /* Copy official host name. */
hostent->h_name = strdup(txthost); hostent->h_name = ares_strdup(txthost);
if (!hostent->h_name) if (!hostent->h_name)
break; break;
/* Copy network address. */ /* 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) if (!hostent->h_addr_list)
break; break;
hostent->h_addr_list[1] = NULL; 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]) if (!hostent->h_addr_list[0])
break; break;
if (addr.family == AF_INET) 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)); memcpy(hostent->h_addr_list[0], &addr.addrV6, sizeof(addr.addrV6));
/* Copy aliases. */ /* Copy aliases. */
hostent->h_aliases = malloc((naliases + 1) * sizeof(char *)); hostent->h_aliases = ares_malloc((naliases + 1) * sizeof(char *));
if (!hostent->h_aliases) if (!hostent->h_aliases)
break; break;
alias = hostent->h_aliases; alias = hostent->h_aliases;
@ -207,7 +207,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
while (*q && ISSPACE(*q)) while (*q && ISSPACE(*q))
q++; q++;
*p = '\0'; *p = '\0';
if ((*alias = strdup(txtalias)) == NULL) if ((*alias = ares_strdup(txtalias)) == NULL)
break; break;
alias++; alias++;
txtalias = *q ? q : NULL; 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); hostent->h_length = aresx_uztoss(addrlen);
/* Free line buffer. */ /* Free line buffer. */
free(line); ares_free(line);
/* Return hostent successfully */ /* Return hostent successfully */
*host = hostent; *host = hostent;
@ -231,7 +231,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
/* If allocated, free line buffer. */ /* If allocated, free line buffer. */
if (line) if (line)
free(line); ares_free(line);
if (status == ARES_SUCCESS) if (status == ARES_SUCCESS)
{ {
@ -239,20 +239,20 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
if (hostent) if (hostent)
{ {
if (hostent->h_name) if (hostent->h_name)
free((char *) hostent->h_name); ares_free((char *) hostent->h_name);
if (hostent->h_aliases) if (hostent->h_aliases)
{ {
for (alias = hostent->h_aliases; *alias; alias++) for (alias = hostent->h_aliases; *alias; alias++)
free(*alias); ares_free(*alias);
free(hostent->h_aliases); ares_free(hostent->h_aliases);
} }
if (hostent->h_addr_list) if (hostent->h_addr_list)
{ {
if (hostent->h_addr_list[0]) if (hostent->h_addr_list[0])
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);
} }
return ARES_ENOMEM; return ARES_ENOMEM;
} }

7
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) if (*buf == NULL)
{ {
*buf = malloc(128); *buf = ares_malloc(128);
if (!*buf) if (!*buf)
return ARES_ENOMEM; return ARES_ENOMEM;
*bufsize = 128; *bufsize = 128;
@ -59,10 +59,11 @@ int ares__read_line(FILE *fp, char **buf, size_t *bufsize)
continue; continue;
/* Allocate more space. */ /* Allocate more space. */
newbuf = realloc(*buf, *bufsize * 2); newbuf = ares_realloc(*buf, *bufsize * 2);
if (!newbuf) if (!newbuf)
{ {
free(*buf); ares_free(*buf);
*buf = NULL;
return ARES_ENOMEM; return ARES_ENOMEM;
} }
*buf = newbuf; *buf = newbuf;

2
deps/cares/src/ares__timeval.c

@ -56,7 +56,7 @@ struct timeval ares__tvnow(void)
*/ */
#ifdef HAVE_GETTIMEOFDAY #ifdef HAVE_GETTIMEOFDAY
else else
(void)gettimeofday(&now, NULL); (void)gettimeofday(&now, NULL); /* LCOV_EXCL_LINE */
#else #else
else { else {
now.tv_sec = (long)time(NULL); now.tv_sec = (long)time(NULL);

2
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; return ARES_EBADNAME;
*buflen = len + HFIXEDSZ + QFIXEDSZ + (max_udp_size ? EDNSFIXEDSZ : 0); *buflen = len + HFIXEDSZ + QFIXEDSZ + (max_udp_size ? EDNSFIXEDSZ : 0);
*buf = malloc(*buflen); *buf = ares_malloc(*buflen);
if (!*buf) if (!*buf)
return ARES_ENOMEM; return ARES_ENOMEM;

44
deps/cares/src/ares_data.c

@ -67,7 +67,7 @@ void ares_free_data(void *dataptr)
if (ptr->data.mx_reply.next) if (ptr->data.mx_reply.next)
ares_free_data(ptr->data.mx_reply.next); ares_free_data(ptr->data.mx_reply.next);
if (ptr->data.mx_reply.host) if (ptr->data.mx_reply.host)
free(ptr->data.mx_reply.host); ares_free(ptr->data.mx_reply.host);
break; break;
case ARES_DATATYPE_SRV_REPLY: case ARES_DATATYPE_SRV_REPLY:
@ -75,15 +75,16 @@ void ares_free_data(void *dataptr)
if (ptr->data.srv_reply.next) if (ptr->data.srv_reply.next)
ares_free_data(ptr->data.srv_reply.next); ares_free_data(ptr->data.srv_reply.next);
if (ptr->data.srv_reply.host) if (ptr->data.srv_reply.host)
free(ptr->data.srv_reply.host); ares_free(ptr->data.srv_reply.host);
break; break;
case ARES_DATATYPE_TXT_REPLY: case ARES_DATATYPE_TXT_REPLY:
case ARES_DATATYPE_TXT_EXT:
if (ptr->data.txt_reply.next) if (ptr->data.txt_reply.next)
ares_free_data(ptr->data.txt_reply.next); ares_free_data(ptr->data.txt_reply.next);
if (ptr->data.txt_reply.txt) if (ptr->data.txt_reply.txt)
free(ptr->data.txt_reply.txt); ares_free(ptr->data.txt_reply.txt);
break; break;
case ARES_DATATYPE_ADDR_NODE: case ARES_DATATYPE_ADDR_NODE:
@ -92,32 +93,38 @@ void ares_free_data(void *dataptr)
ares_free_data(ptr->data.addr_node.next); ares_free_data(ptr->data.addr_node.next);
break; 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: case ARES_DATATYPE_NAPTR_REPLY:
if (ptr->data.naptr_reply.next) if (ptr->data.naptr_reply.next)
ares_free_data(ptr->data.naptr_reply.next); ares_free_data(ptr->data.naptr_reply.next);
if (ptr->data.naptr_reply.flags) 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) 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) 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) if (ptr->data.naptr_reply.replacement)
free(ptr->data.naptr_reply.replacement); ares_free(ptr->data.naptr_reply.replacement);
break; break;
case ARES_DATATYPE_SOA_REPLY: case ARES_DATATYPE_SOA_REPLY:
if (ptr->data.soa_reply.nsname) 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) if (ptr->data.soa_reply.hostmaster)
free(ptr->data.soa_reply.hostmaster); ares_free(ptr->data.soa_reply.hostmaster);
break; break;
default: default:
return; return;
} }
free(ptr); ares_free(ptr);
} }
@ -136,7 +143,7 @@ void *ares_malloc_data(ares_datatype type)
{ {
struct ares_data *ptr; struct ares_data *ptr;
ptr = malloc(sizeof(struct ares_data)); ptr = ares_malloc(sizeof(struct ares_data));
if (!ptr) if (!ptr)
return NULL; return NULL;
@ -156,6 +163,10 @@ void *ares_malloc_data(ares_datatype type)
ptr->data.srv_reply.port = 0; ptr->data.srv_reply.port = 0;
break; break;
case ARES_DATATYPE_TXT_EXT:
ptr->data.txt_ext.record_start = 0;
/* FALLTHROUGH */
case ARES_DATATYPE_TXT_REPLY: case ARES_DATATYPE_TXT_REPLY:
ptr->data.txt_reply.next = NULL; ptr->data.txt_reply.next = NULL;
ptr->data.txt_reply.txt = NULL; ptr->data.txt_reply.txt = NULL;
@ -169,6 +180,15 @@ void *ares_malloc_data(ares_datatype type)
sizeof(ptr->data.addr_node.addrV6)); sizeof(ptr->data.addr_node.addrV6));
break; 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: case ARES_DATATYPE_NAPTR_REPLY:
ptr->data.naptr_reply.next = NULL; ptr->data.naptr_reply.next = NULL;
ptr->data.naptr_reply.flags = NULL; ptr->data.naptr_reply.flags = NULL;
@ -190,7 +210,7 @@ void *ares_malloc_data(ares_datatype type)
break; break;
default: default:
free(ptr); ares_free(ptr);
return NULL; return NULL;
} }

16
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_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_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_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_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_MX_REPLY, /* struct ares_mx_reply - introduced in 1.7.2 */
ARES_DATATYPE_NAPTR_REPLY,/* struct ares_naptr_reply - introduced in 1.7.6 */ 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_HOSTENT, /* struct hostent */
ARES_DATATYPE_OPTIONS, /* struct ares_options */ ARES_DATATYPE_OPTIONS, /* struct ares_options */
#endif #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_LAST /* not used - introduced in 1.7.0 */
} ares_datatype; } ares_datatype;
@ -55,12 +57,14 @@ struct ares_data {
ares_datatype type; /* Actual data type identifier. */ ares_datatype type; /* Actual data type identifier. */
unsigned int mark; /* Private ares_data signature. */ unsigned int mark; /* Private ares_data signature. */
union { union {
struct ares_txt_reply txt_reply; struct ares_txt_reply txt_reply;
struct ares_srv_reply srv_reply; struct ares_txt_ext txt_ext;
struct ares_addr_node addr_node; struct ares_srv_reply srv_reply;
struct ares_mx_reply mx_reply; struct ares_addr_node addr_node;
struct ares_naptr_reply naptr_reply; struct ares_addr_port_node addr_port_node;
struct ares_soa_reply soa_reply; struct ares_mx_reply mx_reply;
struct ares_naptr_reply naptr_reply;
struct ares_soa_reply soa_reply;
} data; } data;
}; };

22
deps/cares/src/ares_destroy.c

@ -27,15 +27,15 @@ void ares_destroy_options(struct ares_options *options)
int i; int i;
if(options->servers) if(options->servers)
free(options->servers); ares_free(options->servers);
for (i = 0; i < options->ndomains; i++) for (i = 0; i < options->ndomains; i++)
free(options->domains[i]); ares_free(options->domains[i]);
if(options->domains) if(options->domains)
free(options->domains); ares_free(options->domains);
if(options->sortlist) if(options->sortlist)
free(options->sortlist); ares_free(options->sortlist);
if(options->lookups) if(options->lookups)
free(options->lookups); ares_free(options->lookups);
} }
void ares_destroy(ares_channel channel) void ares_destroy(ares_channel channel)
@ -75,17 +75,17 @@ void ares_destroy(ares_channel channel)
if (channel->domains) { if (channel->domains) {
for (i = 0; i < channel->ndomains; i++) for (i = 0; i < channel->ndomains; i++)
free(channel->domains[i]); ares_free(channel->domains[i]);
free(channel->domains); ares_free(channel->domains);
} }
if(channel->sortlist) if(channel->sortlist)
free(channel->sortlist); ares_free(channel->sortlist);
if (channel->lookups) if (channel->lookups)
free(channel->lookups); ares_free(channel->lookups);
free(channel); ares_free(channel);
} }
void ares__destroy_servers_state(ares_channel 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); ares__close_sockets(channel, server);
assert(ares__is_list_empty(&server->queries_to_server)); assert(ares__is_list_empty(&server->queries_to_server));
} }
free(channel->servers); ares_free(channel->servers);
channel->servers = NULL; channel->servers = NULL;
} }
channel->nservers = -1; channel->nservers = -1;

18
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) if (nlen.sig < 0)
return ARES_EBADNAME; return ARES_EBADNAME;
*s = malloc(nlen.uns + 1); *s = ares_malloc(nlen.uns + 1);
if (!*s) if (!*s)
return ARES_ENOMEM; return ARES_ENOMEM;
q = *s; q = *s;
@ -129,7 +129,7 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
if (q > *s) if (q > *s)
*(q - 1) = 0; *(q - 1) = 0;
else else
*q = 0; /* zero terminate */ *q = 0; /* zero terminate; LCOV_EXCL_LINE: empty names exit above */
return ARES_SUCCESS; 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, static int name_length(const unsigned char *encoded, const unsigned char *abuf,
int alen) 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. */ /* Allow the caller to pass us abuf + alen and have us check for it. */
if (encoded >= abuf + alen) if (encoded >= abuf + alen)
@ -148,7 +148,8 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf,
while (*encoded) while (*encoded)
{ {
if ((*encoded & INDIR_MASK) == INDIR_MASK) top = (*encoded & INDIR_MASK);
if (top == INDIR_MASK)
{ {
/* Check the offset and go there. */ /* Check the offset and go there. */
if (encoded + 1 >= abuf + alen) if (encoded + 1 >= abuf + alen)
@ -164,7 +165,7 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf,
if (++indir > alen) if (++indir > alen)
return -1; return -1;
} }
else else if (top == 0x00)
{ {
offset = *encoded; offset = *encoded;
if (encoded + offset + 1 >= abuf + alen) if (encoded + offset + 1 >= abuf + alen)
@ -177,6 +178,13 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf,
} }
n++; 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 /* If there were any labels at all, then the number of dots is one

2
deps/cares/src/ares_expand_string.c

@ -54,7 +54,7 @@ int ares_expand_string(const unsigned char *encoded,
encoded++; encoded++;
*s = malloc(elen.uns+1); *s = ares_malloc(elen.uns+1);
if (*s == NULL) if (*s == NULL)
return ARES_ENOMEM; return ARES_ENOMEM;
q = *s; q = *s;

12
deps/cares/src/ares_free_hostent.c

@ -30,12 +30,12 @@ void ares_free_hostent(struct hostent *host)
if (!host) if (!host)
return; return;
free((char *)(host->h_name)); ares_free((char *)(host->h_name));
for (p = host->h_aliases; *p; p++) for (p = host->h_aliases; *p; p++)
free(*p); ares_free(*p);
free(host->h_aliases); ares_free(host->h_aliases);
free(host->h_addr_list[0]); /* no matter if there is one or many entries, 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 */ there is only one malloc for all of them */
free(host->h_addr_list); ares_free(host->h_addr_list);
free(host); ares_free(host);
} }

2
deps/cares/src/ares_free_string.c

@ -21,5 +21,5 @@
void ares_free_string(void *str) void ares_free_string(void *str)
{ {
free(str); ares_free(str);
} }

4
deps/cares/src/ares_gethostbyaddr.c

@ -79,7 +79,7 @@ void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
return; return;
} }
aquery = malloc(sizeof(struct addr_query)); aquery = ares_malloc(sizeof(struct addr_query));
if (!aquery) if (!aquery)
{ {
callback(arg, ARES_ENOMEM, 0, NULL); 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); aquery->callback(aquery->arg, status, aquery->timeouts, host);
if (host) if (host)
ares_free_hostent(host); ares_free_hostent(host);
free(aquery); ares_free(aquery);
} }
static int file_lookup(struct ares_addr *addr, struct hostent **host) static int file_lookup(struct ares_addr *addr, struct hostent **host)

16
deps/cares/src/ares_gethostbyname.c

@ -99,18 +99,18 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
return; return;
/* Allocate and fill in the host query structure. */ /* Allocate and fill in the host query structure. */
hquery = malloc(sizeof(struct host_query)); hquery = ares_malloc(sizeof(struct host_query));
if (!hquery) if (!hquery)
{ {
callback(arg, ARES_ENOMEM, 0, NULL); callback(arg, ARES_ENOMEM, 0, NULL);
return; return;
} }
hquery->channel = channel; hquery->channel = channel;
hquery->name = strdup(name); hquery->name = ares_strdup(name);
hquery->want_family = family; hquery->want_family = family;
hquery->sent_family = -1; /* nothing is sent yet */ hquery->sent_family = -1; /* nothing is sent yet */
if (!hquery->name) { if (!hquery->name) {
free(hquery); ares_free(hquery);
callback(arg, ARES_ENOMEM, 0, NULL); callback(arg, ARES_ENOMEM, 0, NULL);
return; 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 /* The query returned something but either there were no AAAA
records (e.g. just CNAME) or the response was malformed. Try records (e.g. just CNAME) or the response was malformed. Try
looking up A instead. */ looking up A instead. */
if (host)
ares_free_hostent(host);
hquery->sent_family = AF_INET; hquery->sent_family = AF_INET;
ares_search(hquery->channel, hquery->name, C_IN, T_A, ares_search(hquery->channel, hquery->name, C_IN, T_A,
host_callback, hquery); 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); hquery->callback(hquery->arg, status, hquery->timeouts, host);
if (host) if (host)
ares_free_hostent(host); ares_free_hostent(host);
free(hquery->name); ares_free(hquery->name);
free(hquery); ares_free(hquery);
} }
/* If the name looks like an IP address, fake up a host entry, end the /* 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; addrs[0] = (char *)&in6;
} }
/* Duplicate the name, to avoid a constness violation. */ /* Duplicate the name, to avoid a constness violation. */
hostent.h_name = strdup(name); hostent.h_name = ares_strdup(name);
if (!hostent.h_name) if (!hostent.h_name)
{ {
callback(arg, ARES_ENOMEM, 0, NULL); callback(arg, ARES_ENOMEM, 0, NULL);
@ -299,7 +301,7 @@ static int fake_hostent(const char *name, int family,
hostent.h_addr_list = addrs; hostent.h_addr_list = addrs;
callback(arg, ARES_SUCCESS, 0, &hostent); callback(arg, ARES_SUCCESS, 0, &hostent);
free((char *)(hostent.h_name)); ares_free((char *)(hostent.h_name));
return 1; return 1;
} }

20
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, static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int scopeid,
char *buf, size_t buflen); char *buf, size_t buflen);
#endif #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, void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
ares_socklen_t salen, 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 */ /* This is where a DNS lookup becomes necessary */
else else
{ {
niquery = malloc(sizeof(struct nameinfo_query)); niquery = ares_malloc(sizeof(struct nameinfo_query));
if (!niquery) if (!niquery)
{ {
callback(arg, ARES_ENOMEM, 0, NULL, NULL); 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, niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts,
(char *)(host->h_name), (char *)(host->h_name),
service); service);
free(niquery); ares_free(niquery);
return; return;
} }
/* We couldn't find the host, but it's OK, we can use the IP */ /* 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, niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, ipbuf,
service); service);
free(niquery); ares_free(niquery);
return; return;
} }
niquery->callback(niquery->arg, status, niquery->timeouts, NULL, NULL); niquery->callback(niquery->arg, status, niquery->timeouts, NULL, NULL);
free(niquery); ares_free(niquery);
} }
static char *lookup_service(unsigned short port, int flags, 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_ARGS == 6
if (getservbyport_r(port, proto, &se, (void *)tmpbuf, if (getservbyport_r(port, proto, &se, (void *)tmpbuf,
sizeof(tmpbuf), &sep) != 0) sizeof(tmpbuf), &sep) != 0)
sep = NULL; sep = NULL; /* LCOV_EXCL_LINE: buffer large so this never fails */
#elif GETSERVBYPORT_R_ARGS == 5 #elif GETSERVBYPORT_R_ARGS == 5
sep = getservbyport_r(port, proto, &se, (void *)tmpbuf, sep = getservbyport_r(port, proto, &se, (void *)tmpbuf,
sizeof(tmpbuf)); sizeof(tmpbuf));
@ -341,7 +341,7 @@ static char *lookup_service(unsigned short port, int flags,
memcpy(buf, name, name_len + 1); memcpy(buf, name, name_len + 1);
else else
/* avoid reusing previous one */ /* avoid reusing previous one */
buf[0] = '\0'; buf[0] = '\0'; /* LCOV_EXCL_LINE: no real service names are too big */
return buf; return buf;
} }
buf[0] = '\0'; buf[0] = '\0';
@ -391,7 +391,7 @@ static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags,
#endif #endif
/* Determines if s1 ends with the string in s2 (case-insensitive) */ /* 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; const char *c1, *c2, *c1_begin;
int lo1, lo2; int lo1, lo2;
@ -417,7 +417,5 @@ static char *ares_striendstr(const char *s1, const char *s2)
c2++; c2++;
} }
} }
if (c2 == c1 && c2 == NULL) return (char *)c1_begin;
return (char *)c1_begin;
return NULL;
} }

349
deps/cares/src/ares_init.c

@ -49,6 +49,10 @@
#define MAX_DNS_PROPERTIES 8 #define MAX_DNS_PROPERTIES 8
#endif #endif
#if defined(CARES_USE_LIBRESOLV)
#include <resolv.h>
#endif
#include "ares.h" #include "ares.h"
#include "ares_inet_net_pton.h" #include "ares_inet_net_pton.h"
#include "ares_library_init.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 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); static int init_id_key(rc4_key* key,int key_data_len);
#if !defined(WIN32) && !defined(WATT32) && \ static int config_sortlist(struct apattern **sortlist, int *nsort,
!defined(ANDROID) && !defined(__ANDROID__) const char *str);
static int sortlist_alloc(struct apattern **sortlist, int *nsort, static int sortlist_alloc(struct apattern **sortlist, int *nsort,
struct apattern *pat); struct apattern *pat);
static int ip_addr(const char *s, ssize_t len, struct in_addr *addr); static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
static void natural_mask(struct apattern *pat); 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_domain(ares_channel channel, char *str);
static int config_lookup(ares_channel channel, const char *str, static int config_lookup(ares_channel channel, const char *str,
const char *bindch, const char *filech); 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); static char *try_config(char *s, const char *opt, char scc);
#endif #endif
@ -107,6 +111,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
ares_channel channel; ares_channel channel;
int i; int i;
int status = ARES_SUCCESS; int status = ARES_SUCCESS;
int status2;
struct timeval now; struct timeval now;
#ifdef CURLDEBUG #ifdef CURLDEBUG
@ -124,9 +129,9 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
#endif #endif
if (ares_library_initialized() != ARES_SUCCESS) 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) { if (!channel) {
*channelptr = NULL; *channelptr = NULL;
return ARES_ENOMEM; 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 * No matter what failed or succeeded, seed defaults to provide
* useful behavior for things that we missed. * useful behavior for things that we missed.
*/ */
status = init_by_defaults(channel); status2 = init_by_defaults(channel);
if (status != ARES_SUCCESS) if (status2 != ARES_SUCCESS) {
DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n", DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
ares_strerror(status))); ares_strerror(status)));
if (status == ARES_SUCCESS)
status = status2;
}
/* Generate random key */ /* 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. */ /* Something failed; clean up memory we may have allocated. */
if (channel->servers) if (channel->servers)
free(channel->servers); ares_free(channel->servers);
if (channel->domains) if (channel->domains)
{ {
for (i = 0; i < channel->ndomains; i++) for (i = 0; i < channel->ndomains; i++)
free(channel->domains[i]); ares_free(channel->domains[i]);
free(channel->domains); ares_free(channel->domains);
} }
if (channel->sortlist) if (channel->sortlist)
free(channel->sortlist); ares_free(channel->sortlist);
if(channel->lookups) if(channel->lookups)
free(channel->lookups); ares_free(channel->lookups);
free(channel); ares_free(channel);
return status; 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) int ares_dup(ares_channel *dest, ares_channel src)
{ {
struct ares_options opts; struct ares_options opts;
struct ares_addr_node *servers; struct ares_addr_port_node *servers;
int ipv6_nservers = 0; int non_v4_default_port = 0;
int i, rc; int i, rc;
int optmask; int optmask;
@ -289,22 +297,30 @@ int ares_dup(ares_channel *dest, ares_channel src)
(*dest)->local_ip4 = src->local_ip4; (*dest)->local_ip4 = src->local_ip4;
memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6)); 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++) for (i = 0; i < src->nservers; i++)
{ {
if (src->servers[i].addr.family != AF_INET) { if ((src->servers[i].addr.family != AF_INET) ||
ipv6_nservers++; (src->servers[i].addr.udp_port != 0) ||
(src->servers[i].addr.tcp_port != 0)) {
non_v4_default_port++;
break; break;
} }
} }
if (ipv6_nservers) { if (non_v4_default_port) {
rc = ares_get_servers(src, &servers); rc = ares_get_servers_ports(src, &servers);
if (rc != ARES_SUCCESS) if (rc != ARES_SUCCESS) {
ares_destroy(*dest);
*dest = NULL;
return rc; return rc;
rc = ares_set_servers(*dest, servers); }
rc = ares_set_servers_ports(*dest, servers);
ares_free_data(servers); ares_free_data(servers);
if (rc != ARES_SUCCESS) if (rc != ARES_SUCCESS) {
ares_destroy(*dest);
*dest = NULL;
return rc; return rc;
}
} }
return ARES_SUCCESS; /* everything went fine */ 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 = channel->sock_state_cb;
options->sock_state_cb_data = channel->sock_state_cb_data; options->sock_state_cb_data = channel->sock_state_cb_data;
/* Copy IPv4 servers */ /* Copy IPv4 servers that use the default port */
if (channel->nservers) { if (channel->nservers) {
for (i = 0; i < channel->nservers; i++) 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++; ipv4_nservers++;
} }
if (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) if (!options->servers)
return ARES_ENOMEM; return ARES_ENOMEM;
for (i = j = 0; i < channel->nservers; i++) 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++], memcpy(&options->servers[j++],
&channel->servers[i].addr.addrV4, &channel->servers[i].addr.addrV4,
sizeof(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 */ /* copy domains */
if (channel->ndomains) { if (channel->ndomains) {
options->domains = malloc(channel->ndomains * sizeof(char *)); options->domains = ares_malloc(channel->ndomains * sizeof(char *));
if (!options->domains) if (!options->domains)
return ARES_ENOMEM; return ARES_ENOMEM;
for (i = 0; i < channel->ndomains; i++) for (i = 0; i < channel->ndomains; i++)
{ {
options->ndomains = i; options->ndomains = i;
options->domains[i] = strdup(channel->domains[i]); options->domains[i] = ares_strdup(channel->domains[i]);
if (!options->domains[i]) if (!options->domains[i])
return ARES_ENOMEM; return ARES_ENOMEM;
} }
@ -385,14 +405,14 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
/* copy lookups */ /* copy lookups */
if (channel->lookups) { if (channel->lookups) {
options->lookups = strdup(channel->lookups); options->lookups = ares_strdup(channel->lookups);
if (!options->lookups && channel->lookups) if (!options->lookups && channel->lookups)
return ARES_ENOMEM; return ARES_ENOMEM;
} }
/* copy sortlist */ /* copy sortlist */
if (channel->nsort) { if (channel->nsort) {
options->sortlist = malloc(channel->nsort * sizeof(struct apattern)); options->sortlist = ares_malloc(channel->nsort * sizeof(struct apattern));
if (!options->sortlist) if (!options->sortlist)
return ARES_ENOMEM; return ARES_ENOMEM;
for (i = 0; i < channel->nsort; i++) for (i = 0; i < channel->nsort; i++)
@ -448,12 +468,14 @@ static int init_by_options(ares_channel channel,
if (options->nservers > 0) if (options->nservers > 0)
{ {
channel->servers = channel->servers =
malloc(options->nservers * sizeof(struct server_state)); ares_malloc(options->nservers * sizeof(struct server_state));
if (!channel->servers) if (!channel->servers)
return ARES_ENOMEM; return ARES_ENOMEM;
for (i = 0; i < options->nservers; i++) for (i = 0; i < options->nservers; i++)
{ {
channel->servers[i].addr.family = AF_INET; 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, memcpy(&channel->servers[i].addr.addrV4,
&options->servers[i], &options->servers[i],
sizeof(channel->servers[i].addr.addrV4)); 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 */ /* Avoid zero size allocations at any cost */
if (options->ndomains > 0) if (options->ndomains > 0)
{ {
channel->domains = malloc(options->ndomains * sizeof(char *)); channel->domains = ares_malloc(options->ndomains * sizeof(char *));
if (!channel->domains) if (!channel->domains)
return ARES_ENOMEM; return ARES_ENOMEM;
for (i = 0; i < options->ndomains; i++) for (i = 0; i < options->ndomains; i++)
{ {
channel->ndomains = i; channel->ndomains = i;
channel->domains[i] = strdup(options->domains[i]); channel->domains[i] = ares_strdup(options->domains[i]);
if (!channel->domains[i]) if (!channel->domains[i])
return ARES_ENOMEM; return ARES_ENOMEM;
} }
@ -487,7 +509,7 @@ static int init_by_options(ares_channel channel,
/* Set lookups, if given. */ /* Set lookups, if given. */
if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups) if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
{ {
channel->lookups = strdup(options->lookups); channel->lookups = ares_strdup(options->lookups);
if (!channel->lookups) if (!channel->lookups)
return ARES_ENOMEM; return ARES_ENOMEM;
} }
@ -495,7 +517,7 @@ static int init_by_options(ares_channel channel,
/* copy sortlist */ /* copy sortlist */
if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) && if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) &&
(options->nsort>0)) { (options->nsort>0)) {
channel->sortlist = malloc(options->nsort * sizeof(struct apattern)); channel->sortlist = ares_malloc(options->nsort * sizeof(struct apattern));
if (!channel->sortlist) if (!channel->sortlist)
return ARES_ENOMEM; return ARES_ENOMEM;
for (i = 0; i < options->nsort; i++) 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); status = set_options(channel, res_options);
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
return status; return status; /* LCOV_EXCL_LINE: set_options() never fails */
} }
return ARES_SUCCESS; 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 /* Allocate buffer of indicated size plus one given that string
might have been stored without null termination */ might have been stored without null termination */
*outptr = malloc(size+1); *outptr = ares_malloc(size+1);
if (!*outptr) if (!*outptr)
return 0; return 0;
@ -570,7 +592,7 @@ static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr)
(unsigned char *)*outptr, &size); (unsigned char *)*outptr, &size);
if ((res != ERROR_SUCCESS) || (size == 1)) if ((res != ERROR_SUCCESS) || (size == 1))
{ {
free(*outptr); ares_free(*outptr);
*outptr = NULL; *outptr = NULL;
return 0; 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 /* Allocate buffer of indicated size plus one given that string
might have been stored without null termination */ might have been stored without null termination */
*outptr = malloc(size+1); *outptr = ares_malloc(size+1);
if (!*outptr) if (!*outptr)
return 0; return 0;
@ -612,7 +634,7 @@ static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr)
(unsigned char *)*outptr, &size); (unsigned char *)*outptr, &size);
if ((res != ERROR_SUCCESS) || (size == 1)) if ((res != ERROR_SUCCESS) || (size == 1))
{ {
free(*outptr); ares_free(*outptr);
*outptr = NULL; *outptr = NULL;
return 0; return 0;
} }
@ -813,16 +835,16 @@ static void commajoin(char **dst, const char *src)
if (*dst) if (*dst)
{ {
tmp = malloc(strlen(*dst) + strlen(src) + 2); tmp = ares_malloc(strlen(*dst) + strlen(src) + 2);
if (!tmp) if (!tmp)
return; return;
sprintf(tmp, "%s,%s", *dst, src); sprintf(tmp, "%s,%s", *dst, src);
free(*dst); ares_free(*dst);
*dst = tmp; *dst = tmp;
} }
else else
{ {
*dst = malloc(strlen(src) + 1); *dst = ares_malloc(strlen(src) + 1);
if (!*dst) if (!*dst)
return; return;
strcpy(*dst, src); strcpy(*dst, src);
@ -860,7 +882,7 @@ static int get_DNS_NetworkParams(char **outptr)
if (ares_fpGetNetworkParams == ZERO_NULL) if (ares_fpGetNetworkParams == ZERO_NULL)
return 0; return 0;
fi = malloc(size); fi = ares_malloc(size);
if (!fi) if (!fi)
return 0; return 0;
@ -868,7 +890,7 @@ static int get_DNS_NetworkParams(char **outptr)
if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS)) if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
goto done; goto done;
newfi = realloc(fi, size); newfi = ares_realloc(fi, size);
if (!newfi) if (!newfi)
goto done; goto done;
@ -905,7 +927,7 @@ static int get_DNS_NetworkParams(char **outptr)
done: done:
if (fi) if (fi)
free(fi); ares_free(fi);
if (!*outptr) if (!*outptr)
return 0; return 0;
@ -953,7 +975,7 @@ static int get_DNS_AdaptersAddresses(char **outptr)
if (ares_fpGetAdaptersAddresses == ZERO_NULL) if (ares_fpGetAdaptersAddresses == ZERO_NULL)
return 0; return 0;
ipaa = malloc(Bufsz); ipaa = ares_malloc(Bufsz);
if (!ipaa) if (!ipaa)
return 0; return 0;
@ -967,7 +989,7 @@ static int get_DNS_AdaptersAddresses(char **outptr)
{ {
if (Bufsz < ReqBufsz) if (Bufsz < ReqBufsz)
{ {
newipaa = realloc(ipaa, ReqBufsz); newipaa = ares_realloc(ipaa, ReqBufsz);
if (!newipaa) if (!newipaa)
goto done; goto done;
Bufsz = ReqBufsz; Bufsz = ReqBufsz;
@ -983,6 +1005,9 @@ static int get_DNS_AdaptersAddresses(char **outptr)
for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next) for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next)
{ {
if(ipaaEntry->OperStatus != IfOperStatusUp)
continue;
for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress; for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
ipaDNSAddr; ipaDNSAddr;
ipaDNSAddr = ipaDNSAddr->Next) ipaDNSAddr = ipaDNSAddr->Next)
@ -1000,11 +1025,6 @@ static int get_DNS_AdaptersAddresses(char **outptr)
} }
else if (namesrvr.sa->sa_family == AF_INET6) 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, if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
sizeof(namesrvr.sa6->sin6_addr)) == 0) sizeof(namesrvr.sa6->sin6_addr)) == 0)
continue; continue;
@ -1024,7 +1044,7 @@ static int get_DNS_AdaptersAddresses(char **outptr)
done: done:
if (ipaa) if (ipaa)
free(ipaa); ares_free(ipaa);
if (!*outptr) if (!*outptr)
return 0; return 0;
@ -1048,14 +1068,20 @@ done:
*/ */
static int get_DNS_Windows(char **outptr) static int get_DNS_Windows(char **outptr)
{ {
/* Try using IP helper API GetAdaptersAddresses() */ /*
if (get_DNS_AdaptersAddresses(outptr)) Use GetNetworkParams First in case of
return 1; multiple adapter is enabled on this machine.
GetAdaptersAddresses will retrive dummy dns servers.
That will slowing DNS lookup.
*/
/* Try using IP helper API GetNetworkParams() */ /* Try using IP helper API GetNetworkParams() */
if (get_DNS_NetworkParams(outptr)) if (get_DNS_NetworkParams(outptr))
return 1; return 1;
/* Try using IP helper API GetAdaptersAddresses() */
if (get_DNS_AdaptersAddresses(outptr))
return 1;
/* Fall-back to registry information */ /* Fall-back to registry information */
return get_DNS_Registry(outptr); 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) 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; char *line = NULL;
#endif #endif
int status = -1, nservers = 0, nsort = 0; 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)) if (get_DNS_Windows(&line))
{ {
status = config_nameserver(&servers, &nservers, line); status = config_nameserver(&servers, &nservers, line);
free(line); ares_free(line);
} }
if (status == ARES_SUCCESS) if (status == ARES_SUCCESS)
@ -1096,7 +1123,7 @@ static int init_by_resolv_conf(ares_channel channel)
line = getenv("Inet$Resolvers"); line = getenv("Inet$Resolvers");
status = ARES_EOF; status = ARES_EOF;
if (line) { if (line) {
char *resolvers = strdup(line), *pos, *space; char *resolvers = ares_strdup(line), *pos, *space;
if (!resolvers) if (!resolvers)
return ARES_ENOMEM; return ARES_ENOMEM;
@ -1115,7 +1142,7 @@ static int init_by_resolv_conf(ares_channel channel)
if (status == ARES_SUCCESS) if (status == ARES_SUCCESS)
status = ARES_EOF; status = ARES_EOF;
free(resolvers); ares_free(resolvers);
} }
#elif defined(WATT32) #elif defined(WATT32)
@ -1128,14 +1155,17 @@ static int init_by_resolv_conf(ares_channel channel)
return ARES_SUCCESS; /* use localhost DNS server */ return ARES_SUCCESS; /* use localhost DNS server */
nservers = i; nservers = i;
servers = calloc(i, sizeof(struct server_state)); servers = ares_malloc(sizeof(struct server_state));
if (!servers) if (!servers)
return ARES_ENOMEM; return ARES_ENOMEM;
memset(servers, 0, sizeof(struct server_state));
for (i = 0; def_nameservers[i]; i++) for (i = 0; def_nameservers[i]; i++)
{ {
servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]); servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
servers[i].addr.family = AF_INET; servers[i].addr.family = AF_INET;
servers[i].addr.udp_port = 0;
servers[i].addr.tcp_port = 0;
} }
status = ARES_EOF; status = ARES_EOF;
@ -1155,6 +1185,63 @@ static int init_by_resolv_conf(ares_channel channel)
break; break;
status = ARES_EOF; 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 #else
{ {
char *p; char *p;
@ -1300,7 +1387,7 @@ static int init_by_resolv_conf(ares_channel channel)
} }
if(line) if(line)
free(line); ares_free(line);
} }
#endif #endif
@ -1309,9 +1396,9 @@ static int init_by_resolv_conf(ares_channel channel)
if (status != ARES_EOF) if (status != ARES_EOF)
{ {
if (servers != NULL) if (servers != NULL)
free(servers); ares_free(servers);
if (sortlist != NULL) if (sortlist != NULL)
free(sortlist); ares_free(sortlist);
return status; return status;
} }
@ -1360,13 +1447,15 @@ static int init_by_defaults(ares_channel channel)
if (channel->nservers == -1) { if (channel->nservers == -1) {
/* If nobody specified servers, try a local named. */ /* 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) { if (!channel->servers) {
rc = ARES_ENOMEM; rc = ARES_ENOMEM;
goto error; goto error;
} }
channel->servers[0].addr.family = AF_INET; channel->servers[0].addr.family = AF_INET;
channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK); 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; channel->nservers = 1;
} }
@ -1391,7 +1480,7 @@ static int init_by_defaults(ares_channel channel)
int res; int res;
channel->ndomains = 0; /* default to none */ channel->ndomains = 0; /* default to none */
hostname = malloc(len); hostname = ares_malloc(len);
if(!hostname) { if(!hostname) {
rc = ARES_ENOMEM; rc = ARES_ENOMEM;
goto error; goto error;
@ -1404,7 +1493,7 @@ static int init_by_defaults(ares_channel channel)
char *p; char *p;
len *= 2; len *= 2;
lenv *= 2; lenv *= 2;
p = realloc(hostname, len); p = ares_realloc(hostname, len);
if(!p) { if(!p) {
rc = ARES_ENOMEM; rc = ARES_ENOMEM;
goto error; goto error;
@ -1422,12 +1511,12 @@ static int init_by_defaults(ares_channel channel)
dot = strchr(hostname, '.'); dot = strchr(hostname, '.');
if (dot) { if (dot) {
/* a dot was found */ /* a dot was found */
channel->domains = malloc(sizeof(char *)); channel->domains = ares_malloc(sizeof(char *));
if (!channel->domains) { if (!channel->domains) {
rc = ARES_ENOMEM; rc = ARES_ENOMEM;
goto error; goto error;
} }
channel->domains[0] = strdup(dot + 1); channel->domains[0] = ares_strdup(dot + 1);
if (!channel->domains[0]) { if (!channel->domains[0]) {
rc = ARES_ENOMEM; rc = ARES_ENOMEM;
goto error; goto error;
@ -1443,7 +1532,7 @@ static int init_by_defaults(ares_channel channel)
} }
if (!channel->lookups) { if (!channel->lookups) {
channel->lookups = strdup("fb"); channel->lookups = ares_strdup("fb");
if (!channel->lookups) if (!channel->lookups)
rc = ARES_ENOMEM; rc = ARES_ENOMEM;
} }
@ -1451,31 +1540,31 @@ static int init_by_defaults(ares_channel channel)
error: error:
if(rc) { if(rc) {
if(channel->servers) { if(channel->servers) {
free(channel->servers); ares_free(channel->servers);
channel->servers = NULL; channel->servers = NULL;
} }
if(channel->domains && channel->domains[0]) if(channel->domains && channel->domains[0])
free(channel->domains[0]); ares_free(channel->domains[0]);
if(channel->domains) { if(channel->domains) {
free(channel->domains); ares_free(channel->domains);
channel->domains = NULL; channel->domains = NULL;
} }
if(channel->lookups) { if(channel->lookups) {
free(channel->lookups); ares_free(channel->lookups);
channel->lookups = NULL; channel->lookups = NULL;
} }
} }
if(hostname) if(hostname)
free(hostname); ares_free(hostname);
return rc; return rc;
} }
#if !defined(WIN32) && !defined(WATT32) && \ #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) static int config_domain(ares_channel channel, char *str)
{ {
char *q; char *q;
@ -1520,7 +1609,7 @@ static int config_lookup(ares_channel channel, const char *str,
p++; p++;
} }
*l = '\0'; *l = '\0';
channel->lookups = strdup(lookups); channel->lookups = ares_strdup(lookups);
return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM; return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
} }
#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */ #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
@ -1566,13 +1655,15 @@ static int config_nameserver(struct server_state **servers, int *nservers,
continue; continue;
/* Resize servers state array. */ /* Resize servers state array. */
newserv = realloc(*servers, (*nservers + 1) * newserv = ares_realloc(*servers, (*nservers + 1) *
sizeof(struct server_state)); sizeof(struct server_state));
if (!newserv) if (!newserv)
return ARES_ENOMEM; return ARES_ENOMEM;
/* Store address data. */ /* Store address data. */
newserv[*nservers].addr.family = host.family; newserv[*nservers].addr.family = host.family;
newserv[*nservers].addr.udp_port = 0;
newserv[*nservers].addr.tcp_port = 0;
if (host.family == AF_INET) if (host.family == AF_INET)
memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4, memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
sizeof(host.addrV4)); sizeof(host.addrV4));
@ -1587,8 +1678,8 @@ static int config_nameserver(struct server_state **servers, int *nservers,
return ARES_SUCCESS; return ARES_SUCCESS;
} }
#endif /* !WATT32 */
#if !defined(WIN32) && !defined(ANDROID) && !defined(__ANDROID__)
static int config_sortlist(struct apattern **sortlist, int *nsort, static int config_sortlist(struct apattern **sortlist, int *nsort,
const char *str) const char *str)
{ {
@ -1627,8 +1718,11 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
pat.type = PATTERN_CIDR; pat.type = PATTERN_CIDR;
pat.mask.bits = (unsigned short)bits; pat.mask.bits = (unsigned short)bits;
pat.family = AF_INET6; pat.family = AF_INET6;
if (!sortlist_alloc(sortlist, nsort, &pat)) if (!sortlist_alloc(sortlist, nsort, &pat)) {
ares_free(*sortlist);
*sortlist = NULL;
return ARES_ENOMEM; return ARES_ENOMEM;
}
} }
else if (ipbufpfx[0] && else if (ipbufpfx[0] &&
(bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4, (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.type = PATTERN_CIDR;
pat.mask.bits = (unsigned short)bits; pat.mask.bits = (unsigned short)bits;
pat.family = AF_INET; pat.family = AF_INET;
if (!sortlist_alloc(sortlist, nsort, &pat)) if (!sortlist_alloc(sortlist, nsort, &pat)) {
ares_free(*sortlist);
*sortlist = NULL;
return ARES_ENOMEM; return ARES_ENOMEM;
}
} }
/* See if it is just a regular IP */ /* See if it is just a regular IP */
else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0) 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); natural_mask(&pat);
pat.family = AF_INET; pat.family = AF_INET;
pat.type = PATTERN_MASK; pat.type = PATTERN_MASK;
if (!sortlist_alloc(sortlist, nsort, &pat)) if (!sortlist_alloc(sortlist, nsort, &pat)) {
ares_free(*sortlist);
*sortlist = NULL;
return ARES_ENOMEM; return ARES_ENOMEM;
}
} }
else else
{ {
@ -1669,8 +1769,6 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
return ARES_SUCCESS; return ARES_SUCCESS;
} }
#endif /* !WIN32 & !ANDROID & !__ANDROID__ */
#endif /* !WATT32 */
static int set_search(ares_channel channel, const char *str) 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; const char *p, *q;
if(channel->ndomains != -1) { if(channel->ndomains != -1) {
/* LCOV_EXCL_START: all callers check ndomains == -1 */
/* if we already have some domains present, free them first */ /* if we already have some domains present, free them first */
for(n=0; n < channel->ndomains; n++) for(n=0; n < channel->ndomains; n++)
free(channel->domains[n]); ares_free(channel->domains[n]);
free(channel->domains); ares_free(channel->domains);
channel->domains = NULL; channel->domains = NULL;
channel->ndomains = -1; channel->ndomains = -1;
} } /* LCOV_EXCL_STOP */
/* Count the domains given. */ /* Count the domains given. */
n = 0; n = 0;
@ -1704,7 +1803,7 @@ static int set_search(ares_channel channel, const char *str)
return ARES_SUCCESS; return ARES_SUCCESS;
} }
channel->domains = malloc(n * sizeof(char *)); channel->domains = ares_malloc(n * sizeof(char *));
if (!channel->domains) if (!channel->domains)
return ARES_ENOMEM; return ARES_ENOMEM;
@ -1717,7 +1816,7 @@ static int set_search(ares_channel channel, const char *str)
q = p; q = p;
while (*q && !ISSPACE(*q)) while (*q && !ISSPACE(*q))
q++; q++;
channel->domains[n] = malloc(q - p + 1); channel->domains[n] = ares_malloc(q - p + 1);
if (!channel->domains[n]) if (!channel->domains[n])
return ARES_ENOMEM; return ARES_ENOMEM;
memcpy(channel->domains[n], p, q - p); 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) && \ #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) static char *try_config(char *s, const char *opt, char scc)
{ {
size_t len; size_t len;
@ -1778,7 +1877,7 @@ static char *try_config(char *s, const char *opt, char scc)
if (!s || !opt) if (!s || !opt)
/* no line or no option */ /* no line or no option */
return NULL; return NULL; /* LCOV_EXCL_LINE */
/* Hash '#' character is always used as primary comment char, additionally /* Hash '#' character is always used as primary comment char, additionally
a not-NUL secondary comment char will be considered when specified. */ 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) if ((len = strlen(opt)) == 0)
/* empty option */ /* empty option */
return NULL; return NULL; /* LCOV_EXCL_LINE */
if (strncmp(p, opt, len) != 0) if (strncmp(p, opt, len) != 0)
/* line and option do not match */ /* line and option do not match */
@ -1821,7 +1920,7 @@ static char *try_config(char *s, const char *opt, char scc)
if (!*p) if (!*p)
/* no option value */ /* no option value */
return NULL; return NULL; /* LCOV_EXCL_LINE */
if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p)) if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
/* whitespace between option name and value is mandatory /* 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 pointer to option value */
return p; return p;
} }
#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
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;
}
static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr) 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 else
pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET); 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 /* initialize an rc4 key. If possible a cryptographically secure random key
is generated using a suitable function (for example win32's RtlGenRandom as 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) { if (!randomized) {
for (;counter<key_data_len;counter++) for (;counter<key_data_len;counter++)
key[counter]=(unsigned char)(rand() % 256); key[counter]=(unsigned char)(rand() % 256); /* LCOV_EXCL_LINE */
} }
} }
@ -1930,9 +2029,10 @@ static int init_id_key(rc4_key* key,int key_data_len)
short counter; short counter;
unsigned char *key_data_ptr = 0; unsigned char *key_data_ptr = 0;
key_data_ptr = calloc(1,key_data_len); key_data_ptr = ares_malloc(key_data_len);
if (!key_data_ptr) if (!key_data_ptr)
return ARES_ENOMEM; return ARES_ENOMEM;
memset(key_data_ptr, 0, key_data_len);
state = &key->state[0]; state = &key->state[0];
for(counter = 0; counter < 256; counter++) 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); index1 = (unsigned char)((index1 + 1) % key_data_len);
} }
free(key_data_ptr); ares_free(key_data_ptr);
return ARES_SUCCESS; return ARES_SUCCESS;
} }
@ -1985,6 +2085,25 @@ void ares_set_socket_callback(ares_channel channel,
channel->sock_create_cb_data = data; 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) void ares__init_servers_state(ares_channel channel)
{ {
struct server_state *server; struct server_state *server;

27
deps/cares/src/ares_library_init.c

@ -34,6 +34,11 @@ fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses = ZERO_NULL;
static unsigned int ares_initialized; static unsigned int ares_initialized;
static int ares_init_flags; 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 #ifdef USE_WINSOCK
static HMODULE hnd_iphlpapi; static HMODULE hnd_iphlpapi;
static HMODULE hnd_advapi32; static HMODULE hnd_advapi32;
@ -45,7 +50,7 @@ static int ares_win32_init(void)
#ifdef USE_WINSOCK #ifdef USE_WINSOCK
hnd_iphlpapi = 0; hnd_iphlpapi = 0;
hnd_iphlpapi = LoadLibraryW(L"iphlpapi.dll"); hnd_iphlpapi = LoadLibrary("iphlpapi.dll");
if (!hnd_iphlpapi) if (!hnd_iphlpapi)
return ARES_ELOADIPHLPAPI; return ARES_ELOADIPHLPAPI;
@ -73,7 +78,7 @@ static int ares_win32_init(void)
*/ */
hnd_advapi32 = 0; hnd_advapi32 = 0;
hnd_advapi32 = LoadLibraryW(L"advapi32.dll"); hnd_advapi32 = LoadLibrary("advapi32.dll");
if (hnd_advapi32) if (hnd_advapi32)
{ {
ares_fpSystemFunction036 = (fpSystemFunction036_t) ares_fpSystemFunction036 = (fpSystemFunction036_t)
@ -111,7 +116,7 @@ int ares_library_init(int flags)
{ {
res = ares_win32_init(); res = ares_win32_init();
if (res != ARES_SUCCESS) if (res != ARES_SUCCESS)
return res; return res; /* LCOV_EXCL_LINE: can't test Win32 init failure */
} }
ares_init_flags = flags; ares_init_flags = flags;
@ -119,6 +124,20 @@ int ares_library_init(int flags)
return ARES_SUCCESS; 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) void ares_library_cleanup(void)
{ {
@ -132,6 +151,8 @@ void ares_library_cleanup(void)
ares_win32_cleanup(); ares_win32_cleanup();
ares_init_flags = ARES_LIB_INIT_NONE; ares_init_flags = ARES_LIB_INIT_NONE;
ares_malloc = malloc;
ares_free = free;
} }

157
deps/cares/src/ares_options.c

@ -83,6 +83,62 @@ int ares_get_servers(ares_channel channel,
return status; 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, int ares_set_servers(ares_channel channel,
struct ares_addr_node *servers) struct ares_addr_node *servers)
@ -92,7 +148,56 @@ int ares_set_servers(ares_channel channel,
int i; int i;
if (ares_library_initialized() != ARES_SUCCESS) 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) if (!channel)
return ARES_ENODATA; return ARES_ENODATA;
@ -107,7 +212,7 @@ int ares_set_servers(ares_channel channel,
if (num_srvrs > 0) if (num_srvrs > 0)
{ {
/* Allocate storage for servers state */ /* 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) if (!channel->servers)
{ {
return ARES_ENOMEM; return ARES_ENOMEM;
@ -117,6 +222,8 @@ int ares_set_servers(ares_channel channel,
for (i = 0, srvr = servers; srvr; i++, srvr = srvr->next) for (i = 0, srvr = servers; srvr; i++, srvr = srvr->next)
{ {
channel->servers[i].addr.family = srvr->family; 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) if (srvr->family == AF_INET)
memcpy(&channel->servers[i].addr.addrV4, &srvr->addrV4, memcpy(&channel->servers[i].addr.addrV4, &srvr->addrV4,
sizeof(srvr->addrV4)); sizeof(srvr->addrV4));
@ -133,8 +240,8 @@ int ares_set_servers(ares_channel channel,
/* Incomming string format: host[:port][,host[:port]]... */ /* Incomming string format: host[:port][,host[:port]]... */
/* IPv6 addresses with ports require square brackets [fe80::1%lo0]:53 */ /* IPv6 addresses with ports require square brackets [fe80::1%lo0]:53 */
int ares_set_servers_csv(ares_channel channel, static int set_servers_csv(ares_channel channel,
const char* _csv) const char* _csv, int use_port)
{ {
size_t i; size_t i;
char* csv = NULL; char* csv = NULL;
@ -142,11 +249,11 @@ int ares_set_servers_csv(ares_channel channel,
char* start_host; char* start_host;
int cc = 0; int cc = 0;
int rv = ARES_SUCCESS; int rv = ARES_SUCCESS;
struct ares_addr_node *servers = NULL; struct ares_addr_port_node *servers = NULL;
struct ares_addr_node *last = NULL; struct ares_addr_port_node *last = NULL;
if (ares_library_initialized() != ARES_SUCCESS) if (ares_library_initialized() != ARES_SUCCESS)
return ARES_ENOTINITIALIZED; return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */
if (!channel) if (!channel)
return ARES_ENODATA; return ARES_ENODATA;
@ -157,7 +264,7 @@ int ares_set_servers_csv(ares_channel channel,
if (i == 0) if (i == 0)
return ARES_SUCCESS; /* blank all servers */ return ARES_SUCCESS; /* blank all servers */
csv = malloc(i + 2); csv = ares_malloc(i + 2);
if (!csv) if (!csv)
return ARES_ENOMEM; return ARES_ENOMEM;
@ -182,9 +289,10 @@ int ares_set_servers_csv(ares_channel channel,
else if (*ptr == ',') { else if (*ptr == ',') {
char* pp = ptr - 1; char* pp = ptr - 1;
char* p = ptr; char* p = ptr;
int port = 0;
struct in_addr in4; struct in_addr in4;
struct ares_in6_addr in6; 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 */ *ptr = 0; /* null terminate host:port string */
/* Got an entry..see if the port was specified. */ /* Got an entry..see if the port was specified. */
@ -213,7 +321,7 @@ int ares_set_servers_csv(ares_channel channel,
if (*pp == ']') if (*pp == ']')
p++; /* move p before ':' */ p++; /* move p before ':' */
/* p will point to the start of the port */ /* 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 */ *pp = 0; /* null terminate host */
} }
} }
@ -227,7 +335,7 @@ int ares_set_servers_csv(ares_channel channel,
goto out; goto out;
} }
/* was ipv6, add new server */ /* was ipv6, add new server */
s = malloc(sizeof(*s)); s = ares_malloc(sizeof(*s));
if (!s) { if (!s) {
rv = ARES_ENOMEM; rv = ARES_ENOMEM;
goto out; goto out;
@ -237,7 +345,7 @@ int ares_set_servers_csv(ares_channel channel,
} }
else { else {
/* was ipv4, add new server */ /* was ipv4, add new server */
s = malloc(sizeof(*s)); s = ares_malloc(sizeof(*s));
if (!s) { if (!s) {
rv = ARES_ENOMEM; rv = ARES_ENOMEM;
goto out; goto out;
@ -246,8 +354,8 @@ int ares_set_servers_csv(ares_channel channel,
memcpy(&s->addr, &in4, sizeof(struct in_addr)); memcpy(&s->addr, &in4, sizeof(struct in_addr));
} }
if (s) { 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; s->next = NULL;
if (last) { if (last) {
last->next = s; 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: out:
if (csv) if (csv)
free(csv); ares_free(csv);
while (servers) { while (servers) {
struct ares_addr_node *s = servers; struct ares_addr_port_node *s = servers;
servers = servers->next; servers = servers->next;
free(s); ares_free(s);
} }
return rv; 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);
}

54
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; return status;
if (aptr + len + QFIXEDSZ > abuf + alen) if (aptr + len + QFIXEDSZ > abuf + alen)
{ {
free(hostname); ares_free(hostname);
return ARES_EBADRESP; return ARES_EBADRESP;
} }
aptr += len + QFIXEDSZ; 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 /* Allocate addresses and aliases; ancount gives an upper bound for
both. */ both. */
addrs = malloc(ancount * sizeof(struct in_addr)); addrs = ares_malloc(ancount * sizeof(struct in_addr));
if (!addrs) if (!addrs)
{ {
free(hostname); ares_free(hostname);
return ARES_ENOMEM; return ARES_ENOMEM;
} }
aliases = malloc((ancount + 1) * sizeof(char *)); aliases = ares_malloc((ancount + 1) * sizeof(char *));
if (!aliases) if (!aliases)
{ {
free(hostname); ares_free(hostname);
free(addrs); ares_free(addrs);
return ARES_ENOMEM; return ARES_ENOMEM;
} }
} }
@ -127,7 +127,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
aptr += len; aptr += len;
if (aptr + RRFIXEDSZ > abuf + alen) if (aptr + RRFIXEDSZ > abuf + alen)
{ {
free(rr_name); ares_free(rr_name);
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} }
@ -138,7 +138,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
aptr += RRFIXEDSZ; aptr += RRFIXEDSZ;
if (aptr + rr_len > abuf + alen) if (aptr + rr_len > abuf + alen)
{ {
free(rr_name); ares_free(rr_name);
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} }
@ -150,22 +150,22 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
if (addrs) if (addrs)
{ {
if (aptr + sizeof(struct in_addr) > abuf + alen) if (aptr + sizeof(struct in_addr) > abuf + alen)
{ { /* LCOV_EXCL_START: already checked above */
free(rr_name); ares_free(rr_name);
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} } /* LCOV_EXCL_STOP */
memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr)); memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr));
} }
if (naddrs < max_addr_ttls) if (naddrs < max_addr_ttls)
{ {
struct ares_addrttl * const at = &addrttls[naddrs]; struct ares_addrttl * const at = &addrttls[naddrs];
if (aptr + sizeof(struct in_addr) > abuf + alen) if (aptr + sizeof(struct in_addr) > abuf + alen)
{ { /* LCOV_EXCL_START: already checked above */
free(rr_name); ares_free(rr_name);
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} } /* LCOV_EXCL_STOP */
memcpy(&at->ipaddr, aptr, sizeof(struct in_addr)); memcpy(&at->ipaddr, aptr, sizeof(struct in_addr));
at->ttl = rr_ttl; at->ttl = rr_ttl;
} }
@ -179,7 +179,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
if (aliases) if (aliases)
aliases[naliases] = rr_name; aliases[naliases] = rr_name;
else else
free(rr_name); ares_free(rr_name);
naliases++; naliases++;
/* Decode the RR data and replace the hostname with it. */ /* 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); &len);
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
break; break;
free(hostname); ares_free(hostname);
hostname = rr_data; hostname = rr_data;
/* Take the min of the TTLs we see in the CNAME chain. */ /* 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; cname_ttl = rr_ttl;
} }
else else
free(rr_name); ares_free(rr_name);
aptr += rr_len; aptr += rr_len;
if (aptr > abuf + alen) if (aptr > abuf + alen)
{ { /* LCOV_EXCL_START: already checked above */
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} } /* LCOV_EXCL_STOP */
} }
if (status == ARES_SUCCESS && naddrs == 0 && naliases == 0) 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) if (host)
{ {
/* Allocate memory to build the host entry. */ /* Allocate memory to build the host entry. */
hostent = malloc(sizeof(struct hostent)); hostent = ares_malloc(sizeof(struct hostent));
if (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) if (hostent->h_addr_list)
{ {
/* Fill in the hostent and return successfully. */ /* 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[i] = (char *) &addrs[i];
hostent->h_addr_list[naddrs] = NULL; hostent->h_addr_list[naddrs] = NULL;
if (!naddrs && addrs) if (!naddrs && addrs)
free(addrs); ares_free(addrs);
*host = hostent; *host = hostent;
return ARES_SUCCESS; return ARES_SUCCESS;
} }
free(hostent); ares_free(hostent);
} }
status = ARES_ENOMEM; status = ARES_ENOMEM;
} }
@ -255,10 +255,10 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
if (aliases) if (aliases)
{ {
for (i = 0; i < naliases; i++) for (i = 0; i < naliases; i++)
free(aliases[i]); ares_free(aliases[i]);
free(aliases); ares_free(aliases);
} }
free(addrs); ares_free(addrs);
free(hostname); ares_free(hostname);
return status; return status;
} }

54
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; return status;
if (aptr + len + QFIXEDSZ > abuf + alen) if (aptr + len + QFIXEDSZ > abuf + alen)
{ {
free(hostname); ares_free(hostname);
return ARES_EBADRESP; return ARES_EBADRESP;
} }
aptr += len + QFIXEDSZ; 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. */ /* Allocate addresses and aliases; ancount gives an upper bound for both. */
if (host) if (host)
{ {
addrs = malloc(ancount * sizeof(struct ares_in6_addr)); addrs = ares_malloc(ancount * sizeof(struct ares_in6_addr));
if (!addrs) if (!addrs)
{ {
free(hostname); ares_free(hostname);
return ARES_ENOMEM; return ARES_ENOMEM;
} }
aliases = malloc((ancount + 1) * sizeof(char *)); aliases = ares_malloc((ancount + 1) * sizeof(char *));
if (!aliases) if (!aliases)
{ {
free(hostname); ares_free(hostname);
free(addrs); ares_free(addrs);
return ARES_ENOMEM; return ARES_ENOMEM;
} }
} }
@ -127,7 +127,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
aptr += len; aptr += len;
if (aptr + RRFIXEDSZ > abuf + alen) if (aptr + RRFIXEDSZ > abuf + alen)
{ {
free(rr_name); ares_free(rr_name);
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} }
@ -138,7 +138,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
aptr += RRFIXEDSZ; aptr += RRFIXEDSZ;
if (aptr + rr_len > abuf + alen) if (aptr + rr_len > abuf + alen)
{ {
free(rr_name); ares_free(rr_name);
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} }
@ -150,22 +150,22 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
if (addrs) if (addrs)
{ {
if (aptr + sizeof(struct ares_in6_addr) > abuf + alen) if (aptr + sizeof(struct ares_in6_addr) > abuf + alen)
{ { /* LCOV_EXCL_START: already checked above */
free(rr_name); ares_free(rr_name);
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} } /* LCOV_EXCL_STOP */
memcpy(&addrs[naddrs], aptr, sizeof(struct ares_in6_addr)); memcpy(&addrs[naddrs], aptr, sizeof(struct ares_in6_addr));
} }
if (naddrs < max_addr_ttls) if (naddrs < max_addr_ttls)
{ {
struct ares_addr6ttl * const at = &addrttls[naddrs]; struct ares_addr6ttl * const at = &addrttls[naddrs];
if (aptr + sizeof(struct ares_in6_addr) > abuf + alen) if (aptr + sizeof(struct ares_in6_addr) > abuf + alen)
{ { /* LCOV_EXCL_START: already checked above */
free(rr_name); ares_free(rr_name);
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} } /* LCOV_EXCL_STOP */
memcpy(&at->ip6addr, aptr, sizeof(struct ares_in6_addr)); memcpy(&at->ip6addr, aptr, sizeof(struct ares_in6_addr));
at->ttl = rr_ttl; at->ttl = rr_ttl;
} }
@ -179,7 +179,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
if (aliases) if (aliases)
aliases[naliases] = rr_name; aliases[naliases] = rr_name;
else else
free(rr_name); ares_free(rr_name);
naliases++; naliases++;
/* Decode the RR data and replace the hostname with it. */ /* 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); &len);
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
break; break;
free(hostname); ares_free(hostname);
hostname = rr_data; hostname = rr_data;
/* Take the min of the TTLs we see in the CNAME chain. */ /* 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; cname_ttl = rr_ttl;
} }
else else
free(rr_name); ares_free(rr_name);
aptr += rr_len; aptr += rr_len;
if (aptr > abuf + alen) if (aptr > abuf + alen)
{ { /* LCOV_EXCL_START: already checked above */
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} } /* LCOV_EXCL_STOP */
} }
/* the check for naliases to be zero is to make sure CNAME responses /* 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) if (host)
{ {
/* Allocate memory to build the host entry. */ /* Allocate memory to build the host entry. */
hostent = malloc(sizeof(struct hostent)); hostent = ares_malloc(sizeof(struct hostent));
if (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) if (hostent->h_addr_list)
{ {
/* Fill in the hostent and return successfully. */ /* 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[i] = (char *) &addrs[i];
hostent->h_addr_list[naddrs] = NULL; hostent->h_addr_list[naddrs] = NULL;
if (!naddrs && addrs) if (!naddrs && addrs)
free(addrs); ares_free(addrs);
*host = hostent; *host = hostent;
return ARES_SUCCESS; return ARES_SUCCESS;
} }
free(hostent); ares_free(hostent);
} }
status = ARES_ENOMEM; status = ARES_ENOMEM;
} }
@ -255,10 +255,10 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
if (aliases) if (aliases)
{ {
for (i = 0; i < naliases; i++) for (i = 0; i < naliases; i++)
free(aliases[i]); ares_free(aliases[i]);
free(aliases); ares_free(aliases);
} }
free(addrs); ares_free(addrs);
free(hostname); ares_free(hostname);
return status; return status;
} }

8
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) if (aptr + len + QFIXEDSZ > abuf + alen)
{ {
free (hostname); ares_free (hostname);
return ARES_EBADRESP; return ARES_EBADRESP;
} }
aptr += len + QFIXEDSZ; 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 */ /* Don't lose memory in the next iteration */
free (rr_name); ares_free (rr_name);
rr_name = NULL; rr_name = NULL;
/* Move on to the next record */ /* Move on to the next record */
@ -151,9 +151,9 @@ ares_parse_mx_reply (const unsigned char *abuf, int alen,
} }
if (hostname) if (hostname)
free (hostname); ares_free (hostname);
if (rr_name) if (rr_name)
free (rr_name); ares_free (rr_name);
/* clean up on error */ /* clean up on error */
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)

8
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) if (aptr + len + QFIXEDSZ > abuf + alen)
{ {
free (hostname); ares_free (hostname);
return ARES_EBADRESP; return ARES_EBADRESP;
} }
aptr += len + QFIXEDSZ; 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 */ /* Don't lose memory in the next iteration */
free (rr_name); ares_free (rr_name);
rr_name = NULL; rr_name = NULL;
/* Move on to the next record */ /* Move on to the next record */
@ -168,9 +168,9 @@ ares_parse_naptr_reply (const unsigned char *abuf, int alen,
} }
if (hostname) if (hostname)
free (hostname); ares_free (hostname);
if (rr_name) if (rr_name)
free (rr_name); ares_free (rr_name);
/* clean up on error */ /* clean up on error */
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)

38
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; return status;
if ( aptr + len + QFIXEDSZ > abuf + alen ) if ( aptr + len + QFIXEDSZ > abuf + alen )
{ {
free( hostname ); ares_free( hostname );
return ARES_EBADRESP; return ARES_EBADRESP;
} }
aptr += len + QFIXEDSZ; aptr += len + QFIXEDSZ;
/* Allocate nameservers array; ancount gives an upper bound */ /* Allocate nameservers array; ancount gives an upper bound */
nameservers = malloc( ( ancount + 1 ) * sizeof( char * ) ); nameservers = ares_malloc( ( ancount + 1 ) * sizeof( char * ) );
if ( !nameservers ) if ( !nameservers )
{ {
free( hostname ); ares_free( hostname );
return ARES_ENOMEM; return ARES_ENOMEM;
} }
nameservers_num = 0; nameservers_num = 0;
@ -98,7 +98,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
if ( aptr + RRFIXEDSZ > abuf + alen ) if ( aptr + RRFIXEDSZ > abuf + alen )
{ {
status = ARES_EBADRESP; status = ARES_EBADRESP;
free(rr_name); ares_free(rr_name);
break; break;
} }
rr_type = DNS_RR_TYPE( aptr ); rr_type = DNS_RR_TYPE( aptr );
@ -107,7 +107,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
aptr += RRFIXEDSZ; aptr += RRFIXEDSZ;
if (aptr + rr_len > abuf + alen) if (aptr + rr_len > abuf + alen)
{ {
free(rr_name); ares_free(rr_name);
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} }
@ -119,33 +119,33 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
&len); &len);
if ( status != ARES_SUCCESS ) if ( status != ARES_SUCCESS )
{ {
free(rr_name); ares_free(rr_name);
break; break;
} }
nameservers[nameservers_num] = malloc(strlen(rr_data)+1); nameservers[nameservers_num] = ares_malloc(strlen(rr_data)+1);
if (nameservers[nameservers_num]==NULL) if (nameservers[nameservers_num]==NULL)
{ {
free(rr_name); ares_free(rr_name);
free(rr_data); ares_free(rr_data);
status=ARES_ENOMEM; status=ARES_ENOMEM;
break; break;
} }
strcpy(nameservers[nameservers_num],rr_data); strcpy(nameservers[nameservers_num],rr_data);
free(rr_data); ares_free(rr_data);
nameservers_num++; nameservers_num++;
} }
free( rr_name ); ares_free( rr_name );
aptr += rr_len; aptr += rr_len;
if ( aptr > abuf + alen ) if ( aptr > abuf + alen )
{ { /* LCOV_EXCL_START: already checked above */
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} } /* LCOV_EXCL_STOP */
} }
if ( status == ARES_SUCCESS && nameservers_num == 0 ) 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. */ /* We got our answer. Allocate memory to build the host entry. */
nameservers[nameservers_num] = NULL; nameservers[nameservers_num] = NULL;
hostent = malloc( sizeof( struct hostent ) ); hostent = ares_malloc( sizeof( struct hostent ) );
if ( 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 ) if ( hostent->h_addr_list )
{ {
/* Fill in the hostent and return successfully. */ /* Fill in the hostent and return successfully. */
@ -171,13 +171,13 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
*host = hostent; *host = hostent;
return ARES_SUCCESS; return ARES_SUCCESS;
} }
free( hostent ); ares_free( hostent );
} }
status = ARES_ENOMEM; status = ARES_ENOMEM;
} }
for ( i = 0; i < nameservers_num; i++ ) for ( i = 0; i < nameservers_num; i++ )
free( nameservers[i] ); ares_free( nameservers[i] );
free( nameservers ); ares_free( nameservers );
free( hostname ); ares_free( hostname );
return status; return status;
} }

58
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; return status;
if (aptr + len + QFIXEDSZ > abuf + alen) if (aptr + len + QFIXEDSZ > abuf + alen)
{ {
free(ptrname); ares_free(ptrname);
return ARES_EBADRESP; return ARES_EBADRESP;
} }
aptr += len + QFIXEDSZ; aptr += len + QFIXEDSZ;
/* Examine each answer resource record (RR) in turn. */ /* Examine each answer resource record (RR) in turn. */
hostname = NULL; hostname = NULL;
aliases = malloc(alias_alloc * sizeof(char *)); aliases = ares_malloc(alias_alloc * sizeof(char *));
if (!aliases) if (!aliases)
{ {
free(ptrname); ares_free(ptrname);
return ARES_ENOMEM; return ARES_ENOMEM;
} }
for (i = 0; i < (int)ancount; i++) 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; aptr += len;
if (aptr + RRFIXEDSZ > abuf + alen) if (aptr + RRFIXEDSZ > abuf + alen)
{ {
free(rr_name); ares_free(rr_name);
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} }
@ -105,7 +105,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
aptr += RRFIXEDSZ; aptr += RRFIXEDSZ;
if (aptr + rr_len > abuf + alen) if (aptr + rr_len > abuf + alen)
{ {
free(rr_name); ares_free(rr_name);
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} }
@ -118,16 +118,16 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
&len); &len);
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
{ {
free(rr_name); ares_free(rr_name);
break; break;
} }
if (hostname) if (hostname)
free(hostname); ares_free(hostname);
hostname = rr_data; 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]) if (!aliases[aliascnt])
{ {
free(rr_name); ares_free(rr_name);
status = ARES_ENOMEM; status = ARES_ENOMEM;
break; break;
} }
@ -136,9 +136,9 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
if (aliascnt >= alias_alloc) { if (aliascnt >= alias_alloc) {
char **ptr; char **ptr;
alias_alloc *= 2; alias_alloc *= 2;
ptr = realloc(aliases, alias_alloc * sizeof(char *)); ptr = ares_realloc(aliases, alias_alloc * sizeof(char *));
if(!ptr) { if(!ptr) {
free(rr_name); ares_free(rr_name);
status = ARES_ENOMEM; status = ARES_ENOMEM;
break; break;
} }
@ -153,20 +153,20 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
&len); &len);
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
{ {
free(rr_name); ares_free(rr_name);
break; break;
} }
free(ptrname); ares_free(ptrname);
ptrname = rr_data; ptrname = rr_data;
} }
free(rr_name); ares_free(rr_name);
aptr += rr_len; aptr += rr_len;
if (aptr > abuf + alen) if (aptr > abuf + alen)
{ { /* LCOV_EXCL_START: already checked above */
status = ARES_EBADRESP; status = ARES_EBADRESP;
break; break;
} } /* LCOV_EXCL_STOP */
} }
if (status == ARES_SUCCESS && !hostname) 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) if (status == ARES_SUCCESS)
{ {
/* We got our answer. Allocate memory to build the host entry. */ /* We got our answer. Allocate memory to build the host entry. */
hostent = malloc(sizeof(struct hostent)); hostent = ares_malloc(sizeof(struct hostent));
if (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) 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]) 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) if (hostent->h_aliases)
{ {
/* Fill in the hostent and return successfully. */ /* 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); memcpy(hostent->h_addr_list[0], addr, addrlen);
hostent->h_addr_list[1] = NULL; hostent->h_addr_list[1] = NULL;
*host = hostent; *host = hostent;
free(aliases); ares_free(aliases);
free(ptrname); ares_free(ptrname);
return ARES_SUCCESS; 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; status = ARES_ENOMEM;
} }
for (i=0 ; i<aliascnt ; i++) for (i=0 ; i<aliascnt ; i++)
if (aliases[i]) if (aliases[i])
free(aliases[i]); ares_free(aliases[i]);
free(aliases); ares_free(aliases);
if (hostname) if (hostname)
free(hostname); ares_free(hostname);
free(ptrname); ares_free(ptrname);
return status; return status;
} }

8
deps/cares/src/ares_parse_soa_reply.c

@ -112,8 +112,8 @@ ares_parse_soa_reply(const unsigned char *abuf, int alen,
soa->expire = DNS__32BIT(aptr + 3 * 4); soa->expire = DNS__32BIT(aptr + 3 * 4);
soa->minttl = DNS__32BIT(aptr + 4 * 4); soa->minttl = DNS__32BIT(aptr + 4 * 4);
free(qname); ares_free(qname);
free(rr_name); ares_free(rr_name);
*soa_out = soa; *soa_out = soa;
@ -125,9 +125,9 @@ failed:
failed_stat: failed_stat:
ares_free_data(soa); ares_free_data(soa);
if (qname) if (qname)
free(qname); ares_free(qname);
if (rr_name) if (rr_name)
free(rr_name); ares_free(rr_name);
return status; return status;
} }

8
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) if (aptr + len + QFIXEDSZ > abuf + alen)
{ {
free (hostname); ares_free (hostname);
return ARES_EBADRESP; return ARES_EBADRESP;
} }
aptr += len + QFIXEDSZ; 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 */ /* Don't lose memory in the next iteration */
free (rr_name); ares_free (rr_name);
rr_name = NULL; rr_name = NULL;
/* Move on to the next record */ /* Move on to the next record */
@ -160,9 +160,9 @@ ares_parse_srv_reply (const unsigned char *abuf, int alen,
} }
if (hostname) if (hostname)
free (hostname); ares_free (hostname);
if (rr_name) if (rr_name)
free (rr_name); ares_free (rr_name);
/* clean up on error */ /* clean up on error */
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)

49
deps/cares/src/ares_parse_txt_reply.c

@ -44,9 +44,9 @@
#include "ares_data.h" #include "ares_data.h"
#include "ares_private.h" #include "ares_private.h"
int static int
ares_parse_txt_reply (const unsigned char *abuf, int alen, ares__parse_txt_reply (const unsigned char *abuf, int alen,
struct ares_txt_reply **txt_out) int ex, void **txt_out)
{ {
size_t substr_len; size_t substr_len;
unsigned int qdcount, ancount, i; 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; int status, rr_type, rr_class, rr_len;
long len; long len;
char *hostname = NULL, *rr_name = NULL; char *hostname = NULL, *rr_name = NULL;
struct ares_txt_reply *txt_head = NULL; struct ares_txt_ext *txt_head = NULL;
struct ares_txt_reply *txt_last = NULL; struct ares_txt_ext *txt_last = NULL;
struct ares_txt_reply *txt_curr; struct ares_txt_ext *txt_curr;
/* Set *txt_out to NULL for all failure cases. */ /* Set *txt_out to NULL for all failure cases. */
*txt_out = NULL; *txt_out = NULL;
@ -82,7 +82,7 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
if (aptr + len + QFIXEDSZ > abuf + alen) if (aptr + len + QFIXEDSZ > abuf + alen)
{ {
free (hostname); ares_free (hostname);
return ARES_EBADRESP; return ARES_EBADRESP;
} }
aptr += len + QFIXEDSZ; 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 */ /* 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) if (!txt_curr)
{ {
status = ARES_ENOMEM; status = ARES_ENOMEM;
@ -150,9 +151,10 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
} }
txt_last = txt_curr; 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->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) if (txt_curr->txt == NULL)
{ {
status = ARES_ENOMEM; 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 */ /* Don't lose memory in the next iteration */
free (rr_name); ares_free (rr_name);
rr_name = NULL; rr_name = NULL;
/* Move on to the next record */ /* Move on to the next record */
@ -178,9 +186,9 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
} }
if (hostname) if (hostname)
free (hostname); ares_free (hostname);
if (rr_name) if (rr_name)
free (rr_name); ares_free (rr_name);
/* clean up on error */ /* clean up on error */
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
@ -195,3 +203,18 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
return ARES_SUCCESS; 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);
}

25
deps/cares/src/ares_private.h

@ -43,6 +43,13 @@
#define INADDR_NONE 0xffffffff #define INADDR_NONE 0xffffffff
#endif #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) #if defined(WIN32) && !defined(WATT32)
#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP" #define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
@ -86,10 +93,7 @@
# define getenv(ptr) ares_getenv(ptr) # define getenv(ptr) ares_getenv(ptr)
#endif #endif
#ifndef HAVE_STRDUP #include "ares_strdup.h"
# include "ares_strdup.h"
# define strdup(ptr) ares_strdup(ptr)
#endif
#ifndef HAVE_STRCASECMP #ifndef HAVE_STRCASECMP
# include "ares_strcasecmp.h" # include "ares_strcasecmp.h"
@ -119,6 +123,8 @@ struct ares_addr {
struct in_addr addr4; struct in_addr addr4;
struct ares_in6_addr addr6; struct ares_in6_addr addr6;
} addr; } addr;
int udp_port; /* stored in network order */
int tcp_port; /* stored in network order */
}; };
#define addrV4 addr.addr4 #define addrV4 addr.addr4
#define addrV6 addr.addr6 #define addrV6 addr.addr6
@ -251,8 +257,8 @@ struct ares_channeldata {
int tries; int tries;
int ndots; int ndots;
int rotate; /* if true, all servers specified are used */ int rotate; /* if true, all servers specified are used */
int udp_port; int udp_port; /* stored in network order */
int tcp_port; int tcp_port; /* stored in network order */
int socket_send_buffer_size; int socket_send_buffer_size;
int socket_receive_buffer_size; int socket_receive_buffer_size;
char **domains; char **domains;
@ -307,12 +313,15 @@ struct ares_channeldata {
void *sock_create_cb_data; 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 */ /* return true if now is exactly check time or later */
int ares__timedout(struct timeval *now, int ares__timedout(struct timeval *now,
struct timeval *check); 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, void ares__send_query(ares_channel channel, struct query *query,
struct timeval *now); struct timeval *now);
void ares__close_sockets(ares_channel channel, struct server_state *server); void ares__close_sockets(ares_channel channel, struct server_state *server);

89
deps/cares/src/ares_process.c

@ -1,6 +1,6 @@
/* Copyright 1998 by the Massachusetts Institute of Technology. /* 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 * Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without * software and its documentation for any purpose and without
@ -227,7 +227,7 @@ static void write_tcp_data(ares_channel channel,
n++; n++;
/* Allocate iovecs so we can send all our data at once. */ /* 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) if (vec)
{ {
/* Fill in the iovecs and send. */ /* Fill in the iovecs and send. */
@ -239,7 +239,7 @@ static void write_tcp_data(ares_channel channel,
n++; n++;
} }
wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n); wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n);
free(vec); ares_free(vec);
if (wcount < 0) if (wcount < 0)
{ {
if (!try_again(SOCKERRNO)) if (!try_again(SOCKERRNO))
@ -281,8 +281,8 @@ static void advance_tcp_send_queue(ares_channel channel, int whichserver,
num_bytes -= sendreq->len; num_bytes -= sendreq->len;
server->qhead = sendreq->next; server->qhead = sendreq->next;
if (sendreq->data_storage) if (sendreq->data_storage)
free(sendreq->data_storage); ares_free(sendreq->data_storage);
free(sendreq); ares_free(sendreq);
if (server->qhead == NULL) { if (server->qhead == NULL) {
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0); SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
server->qtail = NULL; 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_length = server->tcp_lenbuf[0] << 8
| server->tcp_lenbuf[1]; | server->tcp_lenbuf[1];
server->tcp_buffer = malloc(server->tcp_length); server->tcp_buffer = ares_malloc(server->tcp_length);
if (!server->tcp_buffer) if (!server->tcp_buffer) {
handle_error(channel, i, now); handle_error(channel, i, now);
return; /* bail out on malloc failure. TODO: make this
function return error codes */
}
server->tcp_buffer_pos = 0; 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, process_answer(channel, server->tcp_buffer, server->tcp_length,
i, 1, now); i, 1, now);
if (server->tcp_buffer) if (server->tcp_buffer)
free(server->tcp_buffer); ares_free(server->tcp_buffer);
server->tcp_buffer = NULL; server->tcp_buffer = NULL;
server->tcp_lenbuf_pos = 0; server->tcp_lenbuf_pos = 0;
server->tcp_buffer_pos = 0; server->tcp_buffer_pos = 0;
@ -563,14 +566,15 @@ static void process_answer(ares_channel channel, unsigned char *abuf,
packetsz = channel->ednspsz; packetsz = channel->ednspsz;
if (rcode == NOTIMP || rcode == FORMERR || rcode == SERVFAIL) if (rcode == NOTIMP || rcode == FORMERR || rcode == SERVFAIL)
{ {
int qlen = alen - EDNSFIXEDSZ; int qlen = (query->tcplen - 2) - EDNSFIXEDSZ;
channel->flags ^= ARES_FLAG_EDNS; channel->flags ^= ARES_FLAG_EDNS;
query->tcplen -= EDNSFIXEDSZ; query->tcplen -= EDNSFIXEDSZ;
query->qlen -= EDNSFIXEDSZ; query->qlen -= EDNSFIXEDSZ;
query->tcpbuf[0] = (unsigned char)((qlen >> 8) & 0xff); query->tcpbuf[0] = (unsigned char)((qlen >> 8) & 0xff);
query->tcpbuf[1] = (unsigned char)(qlen & 0xff); query->tcpbuf[1] = (unsigned char)(qlen & 0xff);
DNS_HEADER_SET_ARCOUNT(query->tcpbuf + 2, 0); 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); ares__send_query(channel, query, now);
return; return;
} }
@ -769,12 +773,13 @@ void ares__send_query(ares_channel channel, struct query *query,
return; return;
} }
} }
sendreq = calloc(1, sizeof(struct send_request)); sendreq = ares_malloc(sizeof(struct send_request));
if (!sendreq) if (!sendreq)
{ {
end_query(channel, query, ARES_ENOMEM, NULL, 0); end_query(channel, query, ARES_ENOMEM, NULL, 0);
return; return;
} }
memset(sendreq, 0, sizeof(struct send_request));
/* To make the common case fast, we avoid copies by using the query's /* 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 * 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 * 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. * portable.
*/ */
static int setsocknonblock(ares_socket_t sockfd, /* operate on this */ 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) #if defined(USE_BLOCKING_SOCKETS)
@ -857,7 +862,7 @@ static int setsocknonblock(ares_socket_t sockfd, /* operate on this */
if (FALSE != nonblock) if (FALSE != nonblock)
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
else 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) #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; struct sockaddr_in6 sa6;
} local; } local;
setsocknonblock(s, TRUE); (void)setsocknonblock(s, TRUE);
#if defined(FD_CLOEXEC) && !defined(MSDOS) #if defined(FD_CLOEXEC) && !defined(MSDOS)
/* Configure the socket fd as close-on-exec. */ /* Configure the socket fd as close-on-exec. */
if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1)
return -1; return -1; /* LCOV_EXCL_LINE */
#endif #endif
/* Set the socket's send and receive buffer sizes. */ /* 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); salen = sizeof(saddr.sa4);
memset(sa, 0, salen); memset(sa, 0, salen);
saddr.sa4.sin_family = AF_INET; 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, memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4,
sizeof(server->addr.addrV4)); sizeof(server->addr.addrV4));
break; break;
@ -982,12 +991,16 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
salen = sizeof(saddr.sa6); salen = sizeof(saddr.sa6);
memset(sa, 0, salen); memset(sa, 0, salen);
saddr.sa6.sin6_family = AF_INET6; 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, memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6,
sizeof(server->addr.addrV6)); sizeof(server->addr.addrV6));
break; break;
default: default:
return -1; return -1; /* LCOV_EXCL_LINE */
} }
/* Acquire a socket. */ /* Acquire a socket. */
@ -1065,7 +1078,11 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
salen = sizeof(saddr.sa4); salen = sizeof(saddr.sa4);
memset(sa, 0, salen); memset(sa, 0, salen);
saddr.sa4.sin_family = AF_INET; 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, memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4,
sizeof(server->addr.addrV4)); sizeof(server->addr.addrV4));
break; break;
@ -1074,12 +1091,16 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
salen = sizeof(saddr.sa6); salen = sizeof(saddr.sa6);
memset(sa, 0, salen); memset(sa, 0, salen);
saddr.sa6.sin6_family = AF_INET6; 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, memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6,
sizeof(server->addr.addrV6)); sizeof(server->addr.addrV6));
break; break;
default: default:
return -1; return -1; /* LCOV_EXCL_LINE */
} }
/* Acquire a socket. */ /* Acquire a socket. */
@ -1156,7 +1177,7 @@ static int same_questions(const unsigned char *qbuf, int qlen,
q.p += q.namelen; q.p += q.namelen;
if (q.p + QFIXEDSZ > qbuf + qlen) if (q.p + QFIXEDSZ > qbuf + qlen)
{ {
free(q.name); ares_free(q.name);
return 0; return 0;
} }
q.type = DNS_QUESTION_TYPE(q.p); 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) if (ares_expand_name(a.p, abuf, alen, &a.name, &a.namelen)
!= ARES_SUCCESS) != ARES_SUCCESS)
{ {
free(q.name); ares_free(q.name);
return 0; return 0;
} }
a.p += a.namelen; a.p += a.namelen;
if (a.p + QFIXEDSZ > abuf + alen) if (a.p + QFIXEDSZ > abuf + alen)
{ {
free(q.name); ares_free(q.name);
free(a.name); ares_free(a.name);
return 0; return 0;
} }
a.type = DNS_QUESTION_TYPE(a.p); 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 if (strcasecmp(q.name, a.name) == 0 && q.type == a.type
&& q.dnsclass == a.dnsclass) && q.dnsclass == a.dnsclass)
{ {
free(a.name); ares_free(a.name);
break; break;
} }
free(a.name); ares_free(a.name);
} }
free(q.name); ares_free(q.name);
if (j == a.qdcount) if (j == a.qdcount)
return 0; return 0;
} }
@ -1224,7 +1245,7 @@ static int same_address(struct sockaddr *sa, struct ares_addr *aa)
return 1; /* match */ return 1; /* match */
break; break;
default: default:
break; break; /* LCOV_EXCL_LINE */
} }
} }
return 0; /* different */ 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 * to the query's tcpbuf and handle these cases, we just give
* such sendreqs their own copy of the query packet. * 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) if (sendreq->data_storage != NULL)
{ {
memcpy(sendreq->data_storage, sendreq->data, sendreq->len); memcpy(sendreq->data_storage, sendreq->data, sendreq->len);
@ -1311,7 +1332,7 @@ void ares__free_query(struct query *query)
query->callback = NULL; query->callback = NULL;
query->arg = NULL; query->arg = NULL;
/* Deallocate the memory associated with the query */ /* Deallocate the memory associated with the query */
free(query->tcpbuf); ares_free(query->tcpbuf);
free(query->server_info); ares_free(query->server_info);
free(query); ares_free(query);
} }

6
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); &qlen, (channel->flags & ARES_FLAG_EDNS) ? channel->ednspsz : 0);
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
{ {
if (qbuf != NULL) free(qbuf); if (qbuf != NULL) ares_free(qbuf);
callback(arg, status, 0, NULL, 0); callback(arg, status, 0, NULL, 0);
return; return;
} }
@ -129,7 +129,7 @@ void ares_query(ares_channel channel, const char *name, int dnsclass,
channel->next_id = generate_unique_id(channel); channel->next_id = generate_unique_id(channel);
/* Allocate and fill in the query structure. */ /* Allocate and fill in the query structure. */
qquery = malloc(sizeof(struct qquery)); qquery = ares_malloc(sizeof(struct qquery));
if (!qquery) if (!qquery)
{ {
ares_free_string(qbuf); 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); qquery->callback(qquery->arg, status, timeouts, abuf, alen);
} }
free(qquery); ares_free(qquery);
} }

36
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, static void end_squery(struct search_query *squery, int status,
unsigned char *abuf, int alen); unsigned char *abuf, int alen);
static int cat_domain(const char *name, const char *domain, char **s); 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, void ares_search(ares_channel channel, const char *name, int dnsclass,
int type, ares_callback callback, void *arg) int type, ares_callback callback, void *arg)
@ -66,24 +66,24 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
if (s) if (s)
{ {
ares_query(channel, s, dnsclass, type, callback, arg); ares_query(channel, s, dnsclass, type, callback, arg);
free(s); ares_free(s);
return; return;
} }
/* Allocate a search_query structure to hold the state necessary for /* Allocate a search_query structure to hold the state necessary for
* doing multiple lookups. * doing multiple lookups.
*/ */
squery = malloc(sizeof(struct search_query)); squery = ares_malloc(sizeof(struct search_query));
if (!squery) if (!squery)
{ {
callback(arg, ARES_ENOMEM, 0, NULL, 0); callback(arg, ARES_ENOMEM, 0, NULL, 0);
return; return;
} }
squery->channel = channel; squery->channel = channel;
squery->name = strdup(name); squery->name = ares_strdup(name);
if (!squery->name) if (!squery->name)
{ {
free(squery); ares_free(squery);
callback(arg, ARES_ENOMEM, 0, NULL, 0); callback(arg, ARES_ENOMEM, 0, NULL, 0);
return; return;
} }
@ -123,13 +123,13 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
if (status == ARES_SUCCESS) if (status == ARES_SUCCESS)
{ {
ares_query(channel, s, dnsclass, type, search_callback, squery); ares_query(channel, s, dnsclass, type, search_callback, squery);
free(s); ares_free(s);
} }
else else
{ {
/* failed, free the malloc()ed memory */ /* failed, free the malloc()ed memory */
free(squery->name); ares_free(squery->name);
free(squery); ares_free(squery);
callback(arg, status, 0, NULL, 0); callback(arg, status, 0, NULL, 0);
} }
} }
@ -177,7 +177,7 @@ static void search_callback(void *arg, int status, int timeouts,
squery->next_domain++; squery->next_domain++;
ares_query(channel, s, squery->dnsclass, squery->type, ares_query(channel, s, squery->dnsclass, squery->type,
search_callback, squery); search_callback, squery);
free(s); ares_free(s);
} }
} }
else if (squery->status_as_is == -1) 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) unsigned char *abuf, int alen)
{ {
squery->callback(squery->arg, status, squery->timeouts, abuf, alen); squery->callback(squery->arg, status, squery->timeouts, abuf, alen);
free(squery->name); ares_free(squery->name);
free(squery); ares_free(squery);
} }
/* Concatenate two domains. */ /* 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 nlen = strlen(name);
size_t dlen = strlen(domain); size_t dlen = strlen(domain);
*s = malloc(nlen + 1 + dlen + 1); *s = ares_malloc(nlen + 1 + dlen + 1);
if (!*s) if (!*s)
return ARES_ENOMEM; return ARES_ENOMEM;
memcpy(*s, name, nlen); 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 * the string we should query, in an allocated buffer. If not, set *s
* to NULL. * 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); size_t len = strlen(name);
const char *hostaliases; 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] == '.')) if ((len > 0) && (name[len - 1] == '.'))
{ {
*s = strdup(name); *s = ares_strdup(name);
return (*s) ? ARES_SUCCESS : ARES_ENOMEM; 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; q = p + 1;
while (*q && !ISSPACE(*q)) while (*q && !ISSPACE(*q))
q++; q++;
*s = malloc(q - p + 1); *s = ares_malloc(q - p + 1);
if (*s) if (*s)
{ {
memcpy(*s, p, q - p); memcpy(*s, p, q - p);
(*s)[q - p] = 0; (*s)[q - p] = 0;
} }
free(line); ares_free(line);
fclose(fp); fclose(fp);
return (*s) ? ARES_SUCCESS : ARES_ENOMEM; return (*s) ? ARES_SUCCESS : ARES_ENOMEM;
} }
} }
free(line); ares_free(line);
fclose(fp); fclose(fp);
if (status != ARES_SUCCESS && status != ARES_EOF) if (status != ARES_SUCCESS && status != ARES_EOF)
return status; 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) if (channel->flags & ARES_FLAG_NOSEARCH || channel->ndomains == 0)
{ {
/* No domain search to do; just try the name as-is. */ /* No domain search to do; just try the name as-is. */
*s = strdup(name); *s = ares_strdup(name);
return (*s) ? ARES_SUCCESS : ARES_ENOMEM; return (*s) ? ARES_SUCCESS : ARES_ENOMEM;
} }

14
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. */ /* Allocate space for query and allocated fields. */
query = malloc(sizeof(struct query)); query = ares_malloc(sizeof(struct query));
if (!query) if (!query)
{ {
callback(arg, ARES_ENOMEM, 0, NULL, 0); callback(arg, ARES_ENOMEM, 0, NULL, 0);
return; return;
} }
query->tcpbuf = malloc(qlen + 2); query->tcpbuf = ares_malloc(qlen + 2);
if (!query->tcpbuf) if (!query->tcpbuf)
{ {
free(query); ares_free(query);
callback(arg, ARES_ENOMEM, 0, NULL, 0); callback(arg, ARES_ENOMEM, 0, NULL, 0);
return; return;
} }
query->server_info = malloc(channel->nservers * query->server_info = ares_malloc(channel->nservers *
sizeof(query->server_info[0])); sizeof(query->server_info[0]));
if (!query->server_info) if (!query->server_info)
{ {
free(query->tcpbuf); ares_free(query->tcpbuf);
free(query); ares_free(query);
callback(arg, ARES_ENOMEM, 0, NULL, 0); callback(arg, ARES_ENOMEM, 0, NULL, 0);
return; return;
} }

35
deps/cares/src/ares_strdup.c

@ -17,26 +17,33 @@
#include "ares_setup.h" #include "ares_setup.h"
#include "ares_strdup.h" #include "ares_strdup.h"
#include "ares.h"
#include "ares_private.h"
#ifndef HAVE_STRDUP
char *ares_strdup(const char *s1) char *ares_strdup(const char *s1)
{ {
size_t sz; #ifdef HAVE_STRDUP
char * s2; if (ares_malloc == malloc)
return strdup(s1);
else
#endif
{
size_t sz;
char * s2;
if(s1) { if(s1) {
sz = strlen(s1); sz = strlen(s1);
if(sz < (size_t)-1) { if(sz < (size_t)-1) {
sz++; sz++;
if(sz < ((size_t)-1) / sizeof(char)) { if(sz < ((size_t)-1) / sizeof(char)) {
s2 = malloc(sz * sizeof(char)); s2 = ares_malloc(sz * sizeof(char));
if(s2) { if(s2) {
memcpy(s2, s1, sz * sizeof(char)); memcpy(s2, s1, sz * sizeof(char));
return s2; return s2;
}
} }
} }
} }
return (char *)NULL;
} }
return (char *)NULL;
} }
#endif

2
deps/cares/src/ares_strdup.h

@ -19,8 +19,6 @@
#include "ares_setup.h" #include "ares_setup.h"
#ifndef HAVE_STRDUP
extern char *ares_strdup(const char *s1); extern char *ares_strdup(const char *s1);
#endif
#endif /* HEADER_CARES_STRDUP_H */ #endif /* HEADER_CARES_STRDUP_H */

4
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); return (0);
/* Allocate a temporary buffer to hold the data */ /* Allocate a temporary buffer to hold the data */
buffer = malloc(bytes); buffer = ares_malloc(bytes);
if (!buffer) if (!buffer)
{ {
SET_ERRNO(ENOMEM); SET_ERRNO(ENOMEM);
@ -71,7 +71,7 @@ ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt)
/* Send buffer contents */ /* Send buffer contents */
result = swrite(s, buffer, bytes); result = swrite(s, buffer, bytes);
free(buffer); ares_free(buffer);
return (result); return (result);
} }

2
deps/cares/src/bitncmp.c

@ -26,7 +26,7 @@
* bitncmp(l, r, n) * bitncmp(l, r, n)
* compare bit masks l and r, for n bits. * compare bit masks l and r, for n bits.
* return: * return:
* -1, 1, or 0 in the libc tradition. * <0, >0, or 0 in the libc tradition.
* note: * note:
* network byte order assumed. this means 192.5.5.240/28 has * network byte order assumed. this means 192.5.5.240/28 has
* 0x11110000 in its fourth octet. * 0x11110000 in its fourth octet.

2
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 nothing was written to the destination, we found no address. */
if (dst == odst) 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 no CIDR spec was given, infer width from net class. */
if (bits == -1) { if (bits == -1) {
if (*odst >= 240) /* Class E */ if (*odst >= 240) /* Class E */

6
src/cares_wrap.cc

@ -607,9 +607,9 @@ class QueryTxtWrap: public QueryWrap {
void Parse(unsigned char* buf, int len) override { void Parse(unsigned char* buf, int len) override {
HandleScope handle_scope(env()->isolate()); HandleScope handle_scope(env()->isolate());
Context::Scope context_scope(env()->context()); Context::Scope context_scope(env()->context());
struct ares_txt_reply* txt_out; struct ares_txt_ext* txt_out;
int status = ares_parse_txt_reply(buf, len, &txt_out); int status = ares_parse_txt_reply_ext(buf, len, &txt_out);
if (status != ARES_SUCCESS) { if (status != ARES_SUCCESS) {
ParseError(status); ParseError(status);
return; return;
@ -618,7 +618,7 @@ class QueryTxtWrap: public QueryWrap {
Local<Array> txt_records = Array::New(env()->isolate()); Local<Array> txt_records = Array::New(env()->isolate());
Local<Array> txt_chunk; Local<Array> txt_chunk;
ares_txt_reply* current = txt_out; struct ares_txt_ext* current = txt_out;
uint32_t i = 0; uint32_t i = 0;
for (uint32_t j = 0; current != nullptr; current = current->next) { for (uint32_t j = 0; current != nullptr; current = current->next) {
Local<String> txt = OneByteString(env()->isolate(), current->txt); Local<String> txt = OneByteString(env()->isolate(), current->txt);

Loading…
Cancel
Save