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