deps: update c-ares to v1.32.3
PR-URL: https://github.com/nodejs/node/pull/54020 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Richard Lau <rlau@redhat.com>
This commit is contained in:
parent
449529df02
commit
9272f02b4f
4
deps/cares/CMakeLists.txt
vendored
4
deps/cares/CMakeLists.txt
vendored
@ -12,7 +12,7 @@ INCLUDE (CheckCSourceCompiles)
|
||||
INCLUDE (CheckStructHasMember)
|
||||
INCLUDE (CheckLibraryExists)
|
||||
|
||||
PROJECT (c-ares LANGUAGES C VERSION "1.32.2" )
|
||||
PROJECT (c-ares LANGUAGES C VERSION "1.32.3" )
|
||||
|
||||
# Set this version before release
|
||||
SET (CARES_VERSION "${PROJECT_VERSION}")
|
||||
@ -30,7 +30,7 @@ INCLUDE (GNUInstallDirs) # include this *AFTER* PROJECT(), otherwise paths are w
|
||||
# For example, a version of 4:0:2 would generate output such as:
|
||||
# libname.so -> libname.so.2
|
||||
# libname.so.2 -> libname.so.2.2.0
|
||||
SET (CARES_LIB_VERSIONINFO "19:2:17")
|
||||
SET (CARES_LIB_VERSIONINFO "19:3:17")
|
||||
|
||||
|
||||
OPTION (CARES_STATIC "Build as a static library" OFF)
|
||||
|
26
deps/cares/RELEASE-NOTES.md
vendored
26
deps/cares/RELEASE-NOTES.md
vendored
@ -1,3 +1,29 @@
|
||||
## c-ares version 1.32.3 - July 24 2024
|
||||
|
||||
This is a bugfix release.
|
||||
|
||||
Changes:
|
||||
* Prevent complex recursion during query requeuing and connection cleanup for
|
||||
stability. [e8b32b8](https://github.com/c-ares/c-ares/commit/e8b32b8)
|
||||
* Better propagate error codes on requeue situations.
|
||||
[a9bc0a2](https://github.com/c-ares/c-ares/commit/a9bc0a2)
|
||||
* Try to prevent SIGPIPE from being generated and delivered to integrations.
|
||||
[de01baa](https://github.com/c-ares/c-ares/commit/de01baa)
|
||||
|
||||
Bugfixes:
|
||||
* Missing manpage for `ares_dns_record_set_id()`
|
||||
[aa462b3](https://github.com/c-ares/c-ares/commit/aa462b3)
|
||||
* Memory leak in `ares__hosts_entry_to_hostent()` due to allocation strategy.
|
||||
[PR #824](https://github.com/c-ares/c-ares/pull/824)
|
||||
* UDP write failure detected via ICMP unreachable should trigger faster
|
||||
failover. [PR #821](https://github.com/c-ares/c-ares/pull/821)
|
||||
* Fix pycares test case regression due to wrong error code being returned.
|
||||
Regression from 1.31.0. [PR #820](https://github.com/c-ares/c-ares/pull/820)
|
||||
* Fix possible Windows crash during `ares_destroy()` when using event threads.
|
||||
[5609bd4](https://github.com/c-ares/c-ares/commit/5609bd4)
|
||||
* `ARES_OPT_MAXTIMEOUTMS` wasn't being honored in all cases.
|
||||
[a649c60](https://github.com/c-ares/c-ares/commit/a649c60)
|
||||
|
||||
## c-ares version 1.32.2 - July 15 2024
|
||||
|
||||
This is a bugfix release.
|
||||
|
2
deps/cares/aminclude_static.am
vendored
2
deps/cares/aminclude_static.am
vendored
@ -1,6 +1,6 @@
|
||||
|
||||
# aminclude_static.am generated automatically by Autoconf
|
||||
# from AX_AM_MACROS_STATIC on Mon Jul 15 09:00:09 EDT 2024
|
||||
# from AX_AM_MACROS_STATIC on Wed Jul 24 05:40:58 EDT 2024
|
||||
|
||||
|
||||
# Code coverage
|
||||
|
22
deps/cares/configure
vendored
22
deps/cares/configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.72 for c-ares 1.32.2.
|
||||
# Generated by GNU Autoconf 2.72 for c-ares 1.32.3.
|
||||
#
|
||||
# Report bugs to <c-ares mailing list: http://lists.haxx.se/listinfo/c-ares>.
|
||||
#
|
||||
@ -614,8 +614,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='c-ares'
|
||||
PACKAGE_TARNAME='c-ares'
|
||||
PACKAGE_VERSION='1.32.2'
|
||||
PACKAGE_STRING='c-ares 1.32.2'
|
||||
PACKAGE_VERSION='1.32.3'
|
||||
PACKAGE_STRING='c-ares 1.32.3'
|
||||
PACKAGE_BUGREPORT='c-ares mailing list: http://lists.haxx.se/listinfo/c-ares'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@ -1415,7 +1415,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
'configure' configures c-ares 1.32.2 to adapt to many kinds of systems.
|
||||
'configure' configures c-ares 1.32.3 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1486,7 +1486,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of c-ares 1.32.2:";;
|
||||
short | recursive ) echo "Configuration of c-ares 1.32.3:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1623,7 +1623,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
c-ares configure 1.32.2
|
||||
c-ares configure 1.32.3
|
||||
generated by GNU Autoconf 2.72
|
||||
|
||||
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
@ -2267,7 +2267,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by c-ares $as_me 1.32.2, which was
|
||||
It was created by c-ares $as_me 1.32.3, which was
|
||||
generated by GNU Autoconf 2.72. Invocation command line was
|
||||
|
||||
$ $0$ac_configure_args_raw
|
||||
@ -3259,7 +3259,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
|
||||
|
||||
CARES_VERSION_INFO="19:2:17"
|
||||
CARES_VERSION_INFO="19:3:17"
|
||||
|
||||
|
||||
|
||||
@ -5999,7 +5999,7 @@ fi
|
||||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='c-ares'
|
||||
VERSION='1.32.2'
|
||||
VERSION='1.32.3'
|
||||
|
||||
|
||||
printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
|
||||
@ -26339,7 +26339,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by c-ares $as_me 1.32.2, which was
|
||||
This file was extended by c-ares $as_me 1.32.3, which was
|
||||
generated by GNU Autoconf 2.72. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -26407,7 +26407,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config='$ac_cs_config_escaped'
|
||||
ac_cs_version="\\
|
||||
c-ares config.status 1.32.2
|
||||
c-ares config.status 1.32.3
|
||||
configured by $0, generated by GNU Autoconf 2.72,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
4
deps/cares/configure.ac
vendored
4
deps/cares/configure.ac
vendored
@ -2,10 +2,10 @@ dnl Copyright (C) The c-ares project and its contributors
|
||||
dnl SPDX-License-Identifier: MIT
|
||||
AC_PREREQ([2.69])
|
||||
|
||||
AC_INIT([c-ares], [1.32.2],
|
||||
AC_INIT([c-ares], [1.32.3],
|
||||
[c-ares mailing list: http://lists.haxx.se/listinfo/c-ares])
|
||||
|
||||
CARES_VERSION_INFO="19:2:17"
|
||||
CARES_VERSION_INFO="19:3:17"
|
||||
dnl This flag accepts an argument of the form current[:revision[:age]]. So,
|
||||
dnl passing -version-info 3:12:1 sets current to 3, revision to 12, and age to
|
||||
dnl 1.
|
||||
|
1
deps/cares/docs/Makefile.in
vendored
1
deps/cares/docs/Makefile.in
vendored
@ -374,6 +374,7 @@ MANPAGES = ares_cancel.3 \
|
||||
ares_dns_record_rr_del.3 \
|
||||
ares_dns_record_rr_get.3 \
|
||||
ares_dns_record_rr_get_const.3 \
|
||||
ares_dns_record_set_id.3 \
|
||||
ares_dns_rec_type_fromstr.3 \
|
||||
ares_dns_rec_type_tostr.3 \
|
||||
ares_dns_rec_type_t.3 \
|
||||
|
1
deps/cares/docs/Makefile.inc
vendored
1
deps/cares/docs/Makefile.inc
vendored
@ -36,6 +36,7 @@ MANPAGES = ares_cancel.3 \
|
||||
ares_dns_record_rr_del.3 \
|
||||
ares_dns_record_rr_get.3 \
|
||||
ares_dns_record_rr_get_const.3 \
|
||||
ares_dns_record_set_id.3 \
|
||||
ares_dns_rec_type_fromstr.3 \
|
||||
ares_dns_rec_type_tostr.3 \
|
||||
ares_dns_rec_type_t.3 \
|
||||
|
23
deps/cares/docs/ares_dns_record.3
vendored
23
deps/cares/docs/ares_dns_record.3
vendored
@ -32,6 +32,9 @@ ares_dns_record_t *ares_dns_record_duplicate(const ares_dns_record_t *dnsrec);
|
||||
|
||||
unsigned short ares_dns_record_get_id(const ares_dns_record_t *dnsrec);
|
||||
|
||||
ares_bool_t ares_dns_record_set_id(ares_dns_record_t *dnsrec,
|
||||
unsigned short id);
|
||||
|
||||
unsigned short ares_dns_record_get_flags(const ares_dns_record_t *dnsrec);
|
||||
|
||||
ares_dns_opcode_t ares_dns_record_get_opcode(const ares_dns_record_t *dnsrec);
|
||||
@ -343,6 +346,14 @@ message id from the DNS record provided in the
|
||||
.IR dnsrec
|
||||
parameter.
|
||||
|
||||
The \fIares_dns_record_set_id(3)\fP function is used to set the DNS
|
||||
message id in the
|
||||
.IR id
|
||||
parameter from the DNS record provided in the
|
||||
.IR dnsrec
|
||||
parameter. This id will be overwritten when passing the record to c-ares,
|
||||
so mostly exists for external purposes.
|
||||
|
||||
The \fIares_dns_record_get_flags(3)\fP function is used to retrieve the DNS
|
||||
message flags from the DNS record provided in the
|
||||
.IR dnsrec
|
||||
@ -428,12 +439,12 @@ is returned on out of memory,
|
||||
.B ARES_EFORMERR
|
||||
is returned on misuse.
|
||||
|
||||
\fIares_dns_record_get_id(3)\fP, \fIares_dns_record_get_flags(3)\fP,
|
||||
\fIares_dns_record_get_opcode(3)\fP, \fIares_dns_record_get_rcode(3)\fP, and
|
||||
\fIares_dns_record_query_cnt(3)\fP all returned their prescribed datatype
|
||||
values and in general can't fail except for misuse cases, in which a 0 may
|
||||
be returned, however 0 can also be a valid return value for most of these
|
||||
functions.
|
||||
\fIares_dns_record_get_id(3)\fP, \fIares_dns_record_set_id(3)\fP,
|
||||
\fIares_dns_record_get_flags(3)\fP, \fIares_dns_record_get_opcode(3)\fP,
|
||||
\fIares_dns_record_get_rcode(3)\fP, and \fIares_dns_record_query_cnt(3)\fP
|
||||
all returned their prescribed datatype values and in general can't fail except
|
||||
for misuse cases, in which a 0 may be returned, however 0 can also be a valid
|
||||
return value for most of these functions.
|
||||
|
||||
|
||||
.SH AVAILABILITY
|
||||
|
3
deps/cares/docs/ares_dns_record_set_id.3
vendored
Normal file
3
deps/cares/docs/ares_dns_record_set_id.3
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.\" Copyright (C) 2023 The c-ares project and its contributors.
|
||||
.\" SPDX-License-Identifier: MIT
|
||||
.so man3/ares_dns_record.3
|
4
deps/cares/include/ares_version.h
vendored
4
deps/cares/include/ares_version.h
vendored
@ -32,11 +32,11 @@
|
||||
|
||||
#define ARES_VERSION_MAJOR 1
|
||||
#define ARES_VERSION_MINOR 32
|
||||
#define ARES_VERSION_PATCH 2
|
||||
#define ARES_VERSION_PATCH 3
|
||||
#define ARES_VERSION \
|
||||
((ARES_VERSION_MAJOR << 16) | (ARES_VERSION_MINOR << 8) | \
|
||||
(ARES_VERSION_PATCH))
|
||||
#define ARES_VERSION_STR "1.32.2"
|
||||
#define ARES_VERSION_STR "1.32.3"
|
||||
|
||||
#define CARES_HAVE_ARES_LIBRARY_INIT 1
|
||||
#define CARES_HAVE_ARES_LIBRARY_CLEANUP 1
|
||||
|
2
deps/cares/src/lib/Makefile.in
vendored
2
deps/cares/src/lib/Makefile.in
vendored
@ -15,7 +15,7 @@
|
||||
@SET_MAKE@
|
||||
|
||||
# aminclude_static.am generated automatically by Autoconf
|
||||
# from AX_AM_MACROS_STATIC on Mon Jul 15 09:00:09 EDT 2024
|
||||
# from AX_AM_MACROS_STATIC on Wed Jul 24 05:40:58 EDT 2024
|
||||
|
||||
# Copyright (C) The c-ares project and its contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
84
deps/cares/src/lib/ares__close_sockets.c
vendored
84
deps/cares/src/lib/ares__close_sockets.c
vendored
@ -28,7 +28,8 @@
|
||||
#include "ares_private.h"
|
||||
#include <assert.h>
|
||||
|
||||
static void ares__requeue_queries(struct server_connection *conn)
|
||||
static void ares__requeue_queries(struct server_connection *conn,
|
||||
ares_status_t requeue_status)
|
||||
{
|
||||
struct query *query;
|
||||
ares_timeval_t now;
|
||||
@ -36,11 +37,12 @@ static void ares__requeue_queries(struct server_connection *conn)
|
||||
ares__tvnow(&now);
|
||||
|
||||
while ((query = ares__llist_first_val(conn->queries_to_conn)) != NULL) {
|
||||
ares__requeue_query(query, &now);
|
||||
ares__requeue_query(query, &now, requeue_status);
|
||||
}
|
||||
}
|
||||
|
||||
void ares__close_connection(struct server_connection *conn)
|
||||
void ares__close_connection(struct server_connection *conn,
|
||||
ares_status_t requeue_status)
|
||||
{
|
||||
struct server_state *server = conn->server;
|
||||
ares_channel_t *channel = server->channel;
|
||||
@ -58,7 +60,7 @@ void ares__close_connection(struct server_connection *conn)
|
||||
}
|
||||
|
||||
/* Requeue queries to other connections */
|
||||
ares__requeue_queries(conn);
|
||||
ares__requeue_queries(conn, requeue_status);
|
||||
|
||||
ares__llist_destroy(conn->queries_to_conn);
|
||||
|
||||
@ -74,45 +76,63 @@ void ares__close_sockets(struct server_state *server)
|
||||
|
||||
while ((node = ares__llist_node_first(server->connections)) != NULL) {
|
||||
struct server_connection *conn = ares__llist_node_val(node);
|
||||
ares__close_connection(conn);
|
||||
ares__close_connection(conn, ARES_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
void ares__check_cleanup_conn(const ares_channel_t *channel,
|
||||
struct server_connection *conn)
|
||||
void ares__check_cleanup_conns(const ares_channel_t *channel)
|
||||
{
|
||||
ares_bool_t do_cleanup = ARES_FALSE;
|
||||
ares__slist_node_t *snode;
|
||||
|
||||
if (channel == NULL || conn == NULL) {
|
||||
if (channel == NULL) {
|
||||
return; /* LCOV_EXCL_LINE: DefensiveCoding */
|
||||
}
|
||||
|
||||
if (ares__llist_len(conn->queries_to_conn)) {
|
||||
return;
|
||||
}
|
||||
/* Iterate across each server */
|
||||
for (snode = ares__slist_node_first(channel->servers); snode != NULL;
|
||||
snode = ares__slist_node_next(snode)) {
|
||||
|
||||
/* If we are configured not to stay open, close it out */
|
||||
if (!(channel->flags & ARES_FLAG_STAYOPEN)) {
|
||||
do_cleanup = ARES_TRUE;
|
||||
}
|
||||
struct server_state *server = ares__slist_node_val(snode);
|
||||
ares__llist_node_t *cnode;
|
||||
|
||||
/* If the associated server has failures, close it out. Resetting the
|
||||
* connection (and specifically the source port number) can help resolve
|
||||
* situations where packets are being dropped.
|
||||
*/
|
||||
if (conn->server->consec_failures > 0) {
|
||||
do_cleanup = ARES_TRUE;
|
||||
}
|
||||
/* Iterate across each connection */
|
||||
cnode = ares__llist_node_first(server->connections);
|
||||
while (cnode != NULL) {
|
||||
ares__llist_node_t *next = ares__llist_node_next(cnode);
|
||||
struct server_connection *conn = ares__llist_node_val(cnode);
|
||||
ares_bool_t do_cleanup = ARES_FALSE;
|
||||
cnode = next;
|
||||
|
||||
/* If the udp connection hit its max queries, always close it */
|
||||
if (!conn->is_tcp && channel->udp_max_queries > 0 &&
|
||||
conn->total_queries >= channel->udp_max_queries) {
|
||||
do_cleanup = ARES_TRUE;
|
||||
}
|
||||
/* Has connections, not eligible */
|
||||
if (ares__llist_len(conn->queries_to_conn)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!do_cleanup) {
|
||||
return;
|
||||
}
|
||||
/* If we are configured not to stay open, close it out */
|
||||
if (!(channel->flags & ARES_FLAG_STAYOPEN)) {
|
||||
do_cleanup = ARES_TRUE;
|
||||
}
|
||||
|
||||
ares__close_connection(conn);
|
||||
/* If the associated server has failures, close it out. Resetting the
|
||||
* connection (and specifically the source port number) can help resolve
|
||||
* situations where packets are being dropped.
|
||||
*/
|
||||
if (conn->server->consec_failures > 0) {
|
||||
do_cleanup = ARES_TRUE;
|
||||
}
|
||||
|
||||
/* If the udp connection hit its max queries, always close it */
|
||||
if (!conn->is_tcp && channel->udp_max_queries > 0 &&
|
||||
conn->total_queries >= channel->udp_max_queries) {
|
||||
do_cleanup = ARES_TRUE;
|
||||
}
|
||||
|
||||
if (!do_cleanup) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Clean it up */
|
||||
ares__close_connection(conn, ARES_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
162
deps/cares/src/lib/ares__hosts_file.c
vendored
162
deps/cares/src/lib/ares__hosts_file.c
vendored
@ -767,126 +767,6 @@ ares_status_t ares__hosts_search_host(ares_channel_t *channel,
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
|
||||
ares_status_t ares__hosts_entry_to_hostent(const ares_hosts_entry_t *entry,
|
||||
int family, struct hostent **hostent)
|
||||
{
|
||||
ares_status_t status;
|
||||
size_t naliases;
|
||||
ares__llist_node_t *node;
|
||||
size_t idx;
|
||||
|
||||
*hostent = ares_malloc_zero(sizeof(**hostent));
|
||||
if (*hostent == NULL) {
|
||||
status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
}
|
||||
|
||||
(*hostent)->h_addrtype = (HOSTENT_ADDRTYPE_TYPE)family;
|
||||
|
||||
/* Copy IP addresses that match the address family */
|
||||
idx = 0;
|
||||
for (node = ares__llist_node_first(entry->ips); node != NULL;
|
||||
node = ares__llist_node_next(node)) {
|
||||
struct ares_addr addr;
|
||||
const void *ptr = NULL;
|
||||
size_t ptr_len = 0;
|
||||
const char *ipaddr = ares__llist_node_val(node);
|
||||
char **temp = NULL;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
addr.family = family;
|
||||
ptr = ares_dns_pton(ipaddr, &addr, &ptr_len);
|
||||
if (ptr == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If family == AF_UNSPEC, then we want to inherit this for future
|
||||
* conversions as we can only support a single address class */
|
||||
if (family == AF_UNSPEC) {
|
||||
family = addr.family;
|
||||
(*hostent)->h_addrtype = (HOSTENT_ADDRTYPE_TYPE)addr.family;
|
||||
}
|
||||
|
||||
temp = ares_realloc_zero((*hostent)->h_addr_list,
|
||||
(idx + 1) * sizeof(*(*hostent)->h_addr_list),
|
||||
(idx + 2) * sizeof(*(*hostent)->h_addr_list));
|
||||
if (temp == NULL) {
|
||||
status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
}
|
||||
|
||||
(*hostent)->h_addr_list = temp;
|
||||
|
||||
(*hostent)->h_addr_list[idx] = ares_malloc(ptr_len);
|
||||
if ((*hostent)->h_addr_list[idx] == NULL) {
|
||||
status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
}
|
||||
|
||||
memcpy((*hostent)->h_addr_list[idx], ptr, ptr_len);
|
||||
idx++;
|
||||
(*hostent)->h_length = (HOSTENT_LENGTH_TYPE)ptr_len;
|
||||
}
|
||||
|
||||
/* entry didn't match address class */
|
||||
if (idx == 0) {
|
||||
status = ARES_ENOTFOUND;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Copy main hostname */
|
||||
(*hostent)->h_name = ares_strdup(ares__llist_first_val(entry->hosts));
|
||||
if ((*hostent)->h_name == NULL) {
|
||||
status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
}
|
||||
|
||||
/* Copy aliases */
|
||||
naliases = ares__llist_len(entry->hosts) - 1;
|
||||
|
||||
/* Cap at 100, some people use https://github.com/StevenBlack/hosts and we
|
||||
* don't need 200k+ aliases */
|
||||
if (naliases > 100) {
|
||||
naliases = 100; /* LCOV_EXCL_LINE: DefensiveCoding */
|
||||
}
|
||||
|
||||
(*hostent)->h_aliases =
|
||||
ares_malloc_zero((naliases + 1) * sizeof(*(*hostent)->h_aliases));
|
||||
if ((*hostent)->h_aliases == NULL) {
|
||||
status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
}
|
||||
|
||||
/* Copy all entries to the alias except the first */
|
||||
idx = 0;
|
||||
node = ares__llist_node_first(entry->hosts);
|
||||
node = ares__llist_node_next(node);
|
||||
while (node != NULL) {
|
||||
(*hostent)->h_aliases[idx] = ares_strdup(ares__llist_node_val(node));
|
||||
if ((*hostent)->h_aliases[idx] == NULL) {
|
||||
status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
}
|
||||
idx++;
|
||||
|
||||
/* Break out if artificially capped */
|
||||
if (idx == naliases) {
|
||||
break;
|
||||
}
|
||||
node = ares__llist_node_next(node);
|
||||
}
|
||||
|
||||
return ARES_SUCCESS;
|
||||
|
||||
/* LCOV_EXCL_START: defensive coding */
|
||||
fail:
|
||||
ares_free_hostent(*hostent);
|
||||
*hostent = NULL;
|
||||
return status;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
static ares_status_t
|
||||
ares__hosts_ai_append_cnames(const ares_hosts_entry_t *entry,
|
||||
struct ares_addrinfo_cname **cnames_out)
|
||||
@ -980,10 +860,12 @@ ares_status_t ares__hosts_entry_to_addrinfo(const ares_hosts_entry_t *entry,
|
||||
return ARES_EBADFAMILY; /* LCOV_EXCL_LINE: DefensiveCoding */
|
||||
}
|
||||
|
||||
ai->name = ares_strdup(name);
|
||||
if (ai->name == NULL) {
|
||||
status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
goto done; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
if (name != NULL) {
|
||||
ai->name = ares_strdup(name);
|
||||
if (ai->name == NULL) {
|
||||
status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
goto done; /* LCOV_EXCL_LINE: OutOfMemory */
|
||||
}
|
||||
}
|
||||
|
||||
for (node = ares__llist_node_first(entry->ips); node != NULL;
|
||||
@ -1031,3 +913,35 @@ done:
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
ares_status_t ares__hosts_entry_to_hostent(const ares_hosts_entry_t *entry,
|
||||
int family, struct hostent **hostent)
|
||||
{
|
||||
ares_status_t status;
|
||||
struct ares_addrinfo *ai = ares_malloc_zero(sizeof(*ai));
|
||||
|
||||
*hostent = NULL;
|
||||
|
||||
if (ai == NULL) {
|
||||
return ARES_ENOMEM;
|
||||
}
|
||||
|
||||
status = ares__hosts_entry_to_addrinfo(entry, NULL, family, 0, ARES_TRUE, ai);
|
||||
if (status != ARES_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
status = ares__addrinfo2hostent(ai, family, hostent);
|
||||
if (status != ARES_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
ares_freeaddrinfo(ai);
|
||||
if (status != ARES_SUCCESS) {
|
||||
ares_free_hostent(*hostent);
|
||||
*hostent = NULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
8
deps/cares/src/lib/ares__socket.c
vendored
8
deps/cares/src/lib/ares__socket.c
vendored
@ -184,6 +184,14 @@ static int configure_socket(ares_socket_t s, struct server_state *server)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* No need to emit SIGPIPE on socket errors */
|
||||
#if defined(SO_NOSIGPIPE)
|
||||
{
|
||||
int opt = 1;
|
||||
setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (void *)&opt, sizeof(opt));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set the socket's send and receive buffer sizes. */
|
||||
if ((channel->socket_send_buffer_size > 0) &&
|
||||
setsockopt(s, SOL_SOCKET, SO_SNDBUF,
|
||||
|
8
deps/cares/src/lib/ares_cancel.c
vendored
8
deps/cares/src/lib/ares_cancel.c
vendored
@ -60,28 +60,26 @@ void ares_cancel(ares_channel_t *channel)
|
||||
node = ares__llist_node_first(list_copy);
|
||||
while (node != NULL) {
|
||||
struct query *query;
|
||||
struct server_connection *conn;
|
||||
|
||||
/* Cache next since this node is being deleted */
|
||||
next = ares__llist_node_next(node);
|
||||
|
||||
query = ares__llist_node_claim(node);
|
||||
conn = query->conn;
|
||||
query->node_all_queries = NULL;
|
||||
|
||||
/* NOTE: its possible this may enqueue new queries */
|
||||
query->callback(query->arg, ARES_ECANCELLED, 0, NULL);
|
||||
ares__free_query(query);
|
||||
|
||||
/* See if the connection should be cleaned up */
|
||||
ares__check_cleanup_conn(channel, conn);
|
||||
|
||||
node = next;
|
||||
}
|
||||
|
||||
ares__llist_destroy(list_copy);
|
||||
}
|
||||
|
||||
/* See if the connections should be cleaned up */
|
||||
ares__check_cleanup_conns(channel);
|
||||
|
||||
ares_queue_notify_empty(channel);
|
||||
|
||||
done:
|
||||
|
2
deps/cares/src/lib/ares_dns_private.h
vendored
2
deps/cares/src/lib/ares_dns_private.h
vendored
@ -26,6 +26,8 @@
|
||||
#ifndef __ARES_DNS_PRIVATE_H
|
||||
#define __ARES_DNS_PRIVATE_H
|
||||
|
||||
ares_status_t ares_dns_record_duplicate_ex(ares_dns_record_t **dest,
|
||||
const ares_dns_record_t *src);
|
||||
ares_bool_t ares_dns_rec_type_allow_name_compression(ares_dns_rec_type_t type);
|
||||
ares_bool_t ares_dns_opcode_isvalid(ares_dns_opcode_t opcode);
|
||||
ares_bool_t ares_dns_rcode_isvalid(ares_dns_rcode_t rcode);
|
||||
|
31
deps/cares/src/lib/ares_dns_record.c
vendored
31
deps/cares/src/lib/ares_dns_record.c
vendored
@ -296,6 +296,7 @@ ares_status_t ares_dns_record_query_set_name(ares_dns_record_t *dnsrec,
|
||||
if (dnsrec == NULL || idx >= dnsrec->qdcount || name == NULL) {
|
||||
return ARES_EFORMERR;
|
||||
}
|
||||
|
||||
orig_name = dnsrec->qd[idx].name;
|
||||
dnsrec->qd[idx].name = ares_strdup(name);
|
||||
if (dnsrec->qd[idx].name == NULL) {
|
||||
@ -1622,26 +1623,34 @@ done:
|
||||
return status;
|
||||
}
|
||||
|
||||
ares_dns_record_t *ares_dns_record_duplicate(const ares_dns_record_t *dnsrec)
|
||||
ares_status_t ares_dns_record_duplicate_ex(ares_dns_record_t **dest,
|
||||
const ares_dns_record_t *src)
|
||||
{
|
||||
unsigned char *data = NULL;
|
||||
size_t data_len = 0;
|
||||
ares_dns_record_t *out = NULL;
|
||||
ares_status_t status;
|
||||
|
||||
if (dnsrec == NULL) {
|
||||
return NULL;
|
||||
if (dest == NULL || src == NULL) {
|
||||
return ARES_EFORMERR;
|
||||
}
|
||||
|
||||
status = ares_dns_write(dnsrec, &data, &data_len);
|
||||
*dest = NULL;
|
||||
|
||||
status = ares_dns_write(src, &data, &data_len);
|
||||
if (status != ARES_SUCCESS) {
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
status = ares_dns_parse(data, data_len, 0, &out);
|
||||
status = ares_dns_parse(data, data_len, 0, dest);
|
||||
ares_free(data);
|
||||
if (status != ARES_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
return out;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
ares_dns_record_t *ares_dns_record_duplicate(const ares_dns_record_t *dnsrec)
|
||||
{
|
||||
ares_dns_record_t *dest = NULL;
|
||||
|
||||
ares_dns_record_duplicate_ex(&dest, dnsrec);
|
||||
return dest;
|
||||
}
|
||||
|
7
deps/cares/src/lib/ares_event_select.c
vendored
7
deps/cares/src/lib/ares_event_select.c
vendored
@ -81,12 +81,14 @@ static size_t ares_evsys_select_wait(ares_event_thread_t *e,
|
||||
size_t i;
|
||||
fd_set read_fds;
|
||||
fd_set write_fds;
|
||||
fd_set except_fds;
|
||||
int nfds = 0;
|
||||
struct timeval tv;
|
||||
struct timeval *tout = NULL;
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_ZERO(&write_fds);
|
||||
FD_ZERO(&except_fds);
|
||||
|
||||
for (i = 0; i < num_fds; i++) {
|
||||
const ares_event_t *ev =
|
||||
@ -97,6 +99,7 @@ static size_t ares_evsys_select_wait(ares_event_thread_t *e,
|
||||
if (ev->flags & ARES_EVENT_FLAG_WRITE) {
|
||||
FD_SET(ev->fd, &write_fds);
|
||||
}
|
||||
FD_SET(ev->fd, &except_fds);
|
||||
if (ev->fd + 1 > nfds) {
|
||||
nfds = ev->fd + 1;
|
||||
}
|
||||
@ -108,7 +111,7 @@ static size_t ares_evsys_select_wait(ares_event_thread_t *e,
|
||||
tout = &tv;
|
||||
}
|
||||
|
||||
rv = select(nfds, &read_fds, &write_fds, NULL, tout);
|
||||
rv = select(nfds, &read_fds, &write_fds, &except_fds, tout);
|
||||
if (rv > 0) {
|
||||
for (i = 0; i < num_fds; i++) {
|
||||
ares_event_t *ev;
|
||||
@ -119,7 +122,7 @@ static size_t ares_evsys_select_wait(ares_event_thread_t *e,
|
||||
continue; /* LCOV_EXCL_LINE: DefensiveCoding */
|
||||
}
|
||||
|
||||
if (FD_ISSET(fdlist[i], &read_fds)) {
|
||||
if (FD_ISSET(fdlist[i], &read_fds) || FD_ISSET(fdlist[i], &except_fds)) {
|
||||
flags |= ARES_EVENT_FLAG_READ;
|
||||
}
|
||||
|
||||
|
11
deps/cares/src/lib/ares_event_win32.c
vendored
11
deps/cares/src/lib/ares_event_win32.c
vendored
@ -337,7 +337,9 @@ typedef struct {
|
||||
static void ares_afd_handle_destroy(void *arg)
|
||||
{
|
||||
ares_afd_handle_t *hnd = arg;
|
||||
CloseHandle(hnd->afd_handle);
|
||||
if (hnd != NULL && hnd->afd_handle != NULL) {
|
||||
CloseHandle(hnd->afd_handle);
|
||||
}
|
||||
ares_free(hnd);
|
||||
}
|
||||
|
||||
@ -791,7 +793,11 @@ static void ares_evsys_win32_event_mod(ares_event_t *event,
|
||||
static ares_bool_t ares_evsys_win32_process_other_event(
|
||||
ares_evsys_win32_t *ew, ares_evsys_win32_eventdata_t *ed, size_t i)
|
||||
{
|
||||
ares_event_t *event = ed->event;
|
||||
ares_event_t *event;
|
||||
|
||||
/* NOTE: do NOT dereference 'ed' if during shutdown as this could be an
|
||||
* invalid pointer if the signal handle was cleaned up, but there was still a
|
||||
* pending event! */
|
||||
|
||||
if (ew->is_shutdown) {
|
||||
CARES_DEBUG_LOG("\t\t** i=%lu, skip non-socket handle during shutdown\n",
|
||||
@ -799,6 +805,7 @@ static ares_bool_t ares_evsys_win32_process_other_event(
|
||||
return ARES_FALSE;
|
||||
}
|
||||
|
||||
event = ed->event;
|
||||
CARES_DEBUG_LOG("\t\t** i=%lu, ed=%p (data)\n", (unsigned long)i, (void *)ed);
|
||||
|
||||
event->cb(event->e, event->fd, event->data, ARES_EVENT_FLAG_OTHER);
|
||||
|
9
deps/cares/src/lib/ares_metrics.c
vendored
9
deps/cares/src/lib/ares_metrics.c
vendored
@ -211,7 +211,7 @@ size_t ares_metrics_server_timeout(const struct server_state *server,
|
||||
const ares_channel_t *channel = server->channel;
|
||||
ares_server_bucket_t i;
|
||||
size_t timeout_ms = 0;
|
||||
|
||||
size_t max_timeout_ms;
|
||||
|
||||
for (i = 0; i < ARES_METRIC_COUNT; i++) {
|
||||
time_t ts = ares_metric_timestamp(i, now, ARES_FALSE);
|
||||
@ -252,10 +252,9 @@ size_t ares_metrics_server_timeout(const struct server_state *server,
|
||||
}
|
||||
|
||||
/* don't go above upper bounds */
|
||||
if (channel->maxtimeout && timeout_ms > channel->maxtimeout) {
|
||||
timeout_ms = channel->maxtimeout;
|
||||
} else if (timeout_ms > MAX_TIMEOUT_MS) {
|
||||
timeout_ms = MAX_TIMEOUT_MS;
|
||||
max_timeout_ms = channel->maxtimeout?channel->maxtimeout:MAX_TIMEOUT_MS;
|
||||
if (timeout_ms > max_timeout_ms) {
|
||||
timeout_ms = max_timeout_ms;
|
||||
}
|
||||
|
||||
return timeout_ms;
|
||||
|
9
deps/cares/src/lib/ares_private.h
vendored
9
deps/cares/src/lib/ares_private.h
vendored
@ -410,7 +410,8 @@ ares_bool_t ares__timedout(const ares_timeval_t *now,
|
||||
/* Returns one of the normal ares status codes like ARES_SUCCESS */
|
||||
ares_status_t ares__send_query(struct query *query, const ares_timeval_t *now);
|
||||
ares_status_t ares__requeue_query(struct query *query,
|
||||
const ares_timeval_t *now);
|
||||
const ares_timeval_t *now,
|
||||
ares_status_t status);
|
||||
|
||||
/*! Retrieve a list of names to use for searching. The first successful
|
||||
* query in the list wins. This function also uses the HOSTSALIASES file
|
||||
@ -438,10 +439,10 @@ void *ares__dnsrec_convert_arg(ares_callback callback, void *arg);
|
||||
void ares__dnsrec_convert_cb(void *arg, ares_status_t status, size_t timeouts,
|
||||
const ares_dns_record_t *dnsrec);
|
||||
|
||||
void ares__close_connection(struct server_connection *conn);
|
||||
void ares__close_connection(struct server_connection *conn,
|
||||
ares_status_t requeue_status);
|
||||
void ares__close_sockets(struct server_state *server);
|
||||
void ares__check_cleanup_conn(const ares_channel_t *channel,
|
||||
struct server_connection *conn);
|
||||
void ares__check_cleanup_conns(const ares_channel_t *channel);
|
||||
void ares__free_query(struct query *query);
|
||||
|
||||
ares_rand_state *ares__init_rand_state(void);
|
||||
|
118
deps/cares/src/lib/ares_process.c
vendored
118
deps/cares/src/lib/ares_process.c
vendored
@ -58,7 +58,8 @@ static ares_status_t process_answer(ares_channel_t *channel,
|
||||
struct server_connection *conn,
|
||||
ares_bool_t tcp, const ares_timeval_t *now);
|
||||
static void handle_conn_error(struct server_connection *conn,
|
||||
ares_bool_t critical_failure);
|
||||
ares_bool_t critical_failure,
|
||||
ares_status_t failure_status);
|
||||
|
||||
static ares_bool_t same_questions(const struct query *query,
|
||||
const ares_dns_record_t *arec);
|
||||
@ -68,6 +69,17 @@ static void end_query(ares_channel_t *channel, struct server_state *server,
|
||||
struct query *query, ares_status_t status,
|
||||
const ares_dns_record_t *dnsrec);
|
||||
|
||||
|
||||
static void ares__query_disassociate_from_conn(struct query *query)
|
||||
{
|
||||
/* If its not part of a connection, it can't be tracked for timeouts either */
|
||||
ares__slist_node_destroy(query->node_queries_by_timeout);
|
||||
ares__llist_node_destroy(query->node_queries_to_conn);
|
||||
query->node_queries_by_timeout = NULL;
|
||||
query->node_queries_to_conn = NULL;
|
||||
query->conn = NULL;
|
||||
}
|
||||
|
||||
/* Invoke the server state callback after a success or failure */
|
||||
static void invoke_server_state_cb(const struct server_state *server,
|
||||
ares_bool_t success, int flags)
|
||||
@ -202,6 +214,8 @@ static void processfds(ares_channel_t *channel, fd_set *read_fds,
|
||||
/* Write last as the other 2 operations might have triggered writes */
|
||||
write_tcp_data(channel, write_fds, write_fd);
|
||||
|
||||
/* See if any connections should be cleaned up */
|
||||
ares__check_cleanup_conns(channel);
|
||||
ares__channel_unlock(channel);
|
||||
}
|
||||
|
||||
@ -301,7 +315,7 @@ static void write_tcp_data(ares_channel_t *channel, fd_set *write_fds,
|
||||
count = ares__socket_write(channel, server->tcp_conn->fd, data, data_len);
|
||||
if (count <= 0) {
|
||||
if (!try_again(SOCKERRNO)) {
|
||||
handle_conn_error(server->tcp_conn, ARES_TRUE);
|
||||
handle_conn_error(server->tcp_conn, ARES_TRUE, ARES_ECONNREFUSED);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -334,7 +348,7 @@ static void read_tcp_data(ares_channel_t *channel,
|
||||
ptr = ares__buf_append_start(server->tcp_parser, &ptr_len);
|
||||
|
||||
if (ptr == NULL) {
|
||||
handle_conn_error(conn, ARES_FALSE /* not critical to connection */);
|
||||
handle_conn_error(conn, ARES_FALSE /* not critical to connection */, ARES_SUCCESS);
|
||||
return; /* bail out on malloc failure. TODO: make this
|
||||
function return error codes */
|
||||
}
|
||||
@ -344,7 +358,7 @@ static void read_tcp_data(ares_channel_t *channel,
|
||||
if (count <= 0) {
|
||||
ares__buf_append_finish(server->tcp_parser, 0);
|
||||
if (!(count == -1 && try_again(SOCKERRNO))) {
|
||||
handle_conn_error(conn, ARES_TRUE);
|
||||
handle_conn_error(conn, ARES_TRUE, ARES_ECONNREFUSED);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -388,15 +402,13 @@ static void read_tcp_data(ares_channel_t *channel,
|
||||
/* We finished reading this answer; process it */
|
||||
status = process_answer(channel, data, data_len, conn, ARES_TRUE, now);
|
||||
if (status != ARES_SUCCESS) {
|
||||
handle_conn_error(conn, ARES_TRUE);
|
||||
handle_conn_error(conn, ARES_TRUE, status);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Since we processed the answer, clear the tag so space can be reclaimed */
|
||||
ares__buf_tag_clear(server->tcp_parser);
|
||||
}
|
||||
|
||||
ares__check_cleanup_conn(channel, conn);
|
||||
}
|
||||
|
||||
static int socket_list_append(ares_socket_t **socketlist, ares_socket_t fd,
|
||||
@ -503,7 +515,7 @@ static void read_udp_packets_fd(ares_channel_t *channel,
|
||||
break;
|
||||
}
|
||||
|
||||
handle_conn_error(conn, ARES_TRUE);
|
||||
handle_conn_error(conn, ARES_TRUE, ARES_ECONNREFUSED);
|
||||
return;
|
||||
#ifdef HAVE_RECVFROM
|
||||
} else if (!same_address(&from.sa, &conn->server->addr)) {
|
||||
@ -520,8 +532,6 @@ static void read_udp_packets_fd(ares_channel_t *channel,
|
||||
/* Try to read again only if *we* set up the socket, otherwise it may be
|
||||
* a blocking socket and would cause recvfrom to hang. */
|
||||
} while (read_len >= 0 && channel->sock_funcs == NULL);
|
||||
|
||||
ares__check_cleanup_conn(channel, conn);
|
||||
}
|
||||
|
||||
static void read_packets(ares_channel_t *channel, fd_set *read_fds,
|
||||
@ -594,28 +604,26 @@ static void read_packets(ares_channel_t *channel, fd_set *read_fds,
|
||||
/* If any queries have timed out, note the timeout and move them on. */
|
||||
static void process_timeouts(ares_channel_t *channel, const ares_timeval_t *now)
|
||||
{
|
||||
ares__slist_node_t *node =
|
||||
ares__slist_node_first(channel->queries_by_timeout);
|
||||
while (node != NULL) {
|
||||
ares__slist_node_t *node;
|
||||
|
||||
/* Just keep popping off the first as this list will re-sort as things come
|
||||
* and go. We don't want to try to rely on 'next' as some operation might
|
||||
* cause a cleanup of that pointer and would become invalid */
|
||||
while ((node = ares__slist_node_first(channel->queries_by_timeout)) != NULL) {
|
||||
struct query *query = ares__slist_node_val(node);
|
||||
/* Node might be removed, cache next */
|
||||
ares__slist_node_t *next = ares__slist_node_next(node);
|
||||
struct server_connection *conn;
|
||||
|
||||
/* Since this is sorted, as soon as we hit a query that isn't timed out,
|
||||
* break */
|
||||
if (!ares__timedout(now, &query->timeout)) {
|
||||
break;
|
||||
}
|
||||
|
||||
query->error_status = ARES_ETIMEOUT;
|
||||
query->timeouts++;
|
||||
|
||||
conn = query->conn;
|
||||
server_increment_failures(conn->server, query->using_tcp);
|
||||
ares__requeue_query(query, now);
|
||||
ares__check_cleanup_conn(channel, conn);
|
||||
|
||||
node = next;
|
||||
ares__requeue_query(query, now, ARES_ETIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -733,20 +741,20 @@ static ares_status_t process_answer(ares_channel_t *channel,
|
||||
rcode == ARES_RCODE_REFUSED) {
|
||||
switch (rcode) {
|
||||
case ARES_RCODE_SERVFAIL:
|
||||
query->error_status = ARES_ESERVFAIL;
|
||||
status = ARES_ESERVFAIL;
|
||||
break;
|
||||
case ARES_RCODE_NOTIMP:
|
||||
query->error_status = ARES_ENOTIMP;
|
||||
status = ARES_ENOTIMP;
|
||||
break;
|
||||
case ARES_RCODE_REFUSED:
|
||||
query->error_status = ARES_EREFUSED;
|
||||
status = ARES_EREFUSED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
server_increment_failures(server, query->using_tcp);
|
||||
ares__requeue_query(query, now);
|
||||
ares__requeue_query(query, now, status);
|
||||
|
||||
/* Should any of these cause a connection termination?
|
||||
* Maybe SERVER_FAILURE? */
|
||||
@ -776,7 +784,8 @@ cleanup:
|
||||
}
|
||||
|
||||
static void handle_conn_error(struct server_connection *conn,
|
||||
ares_bool_t critical_failure)
|
||||
ares_bool_t critical_failure,
|
||||
ares_status_t failure_status)
|
||||
{
|
||||
struct server_state *server = conn->server;
|
||||
|
||||
@ -787,17 +796,23 @@ static void handle_conn_error(struct server_connection *conn,
|
||||
}
|
||||
|
||||
/* This will requeue any connections automatically */
|
||||
ares__close_connection(conn);
|
||||
ares__close_connection(conn, failure_status);
|
||||
}
|
||||
|
||||
ares_status_t ares__requeue_query(struct query *query,
|
||||
const ares_timeval_t *now)
|
||||
const ares_timeval_t *now,
|
||||
ares_status_t status)
|
||||
{
|
||||
ares_channel_t *channel = query->channel;
|
||||
size_t max_tries = ares__slist_len(channel->servers) * channel->tries;
|
||||
|
||||
query->try_count++;
|
||||
ares__query_disassociate_from_conn(query);
|
||||
|
||||
if (status != ARES_SUCCESS) {
|
||||
query->error_status = status;
|
||||
}
|
||||
|
||||
query->try_count++;
|
||||
if (query->try_count < max_tries && !query->no_retries) {
|
||||
return ares__send_query(query, now);
|
||||
}
|
||||
@ -947,7 +962,14 @@ static ares_status_t ares__write_udpbuf(ares_channel_t *channel,
|
||||
}
|
||||
|
||||
if (ares__socket_write(channel, fd, qbuf, qbuf_len) == -1) {
|
||||
status = ARES_ESERVFAIL;
|
||||
if (try_again(SOCKERRNO)) {
|
||||
status = ARES_ESERVFAIL;
|
||||
} else {
|
||||
/* UDP is connection-less, but we might receive an ICMP unreachable which
|
||||
* means we can't talk to the remote host at all and that will be
|
||||
* reflected here */
|
||||
status = ARES_ECONNREFUSED;
|
||||
}
|
||||
} else {
|
||||
status = ARES_SUCCESS;
|
||||
}
|
||||
@ -1018,8 +1040,6 @@ ares_status_t ares__send_query(struct query *query, const ares_timeval_t *now)
|
||||
ares_status_t status;
|
||||
ares_bool_t new_connection = ARES_FALSE;
|
||||
|
||||
query->conn = NULL;
|
||||
|
||||
/* Choose the server to send the query to */
|
||||
if (channel->rotate) {
|
||||
/* Pull random server */
|
||||
@ -1052,8 +1072,7 @@ ares_status_t ares__send_query(struct query *query, const ares_timeval_t *now)
|
||||
case ARES_ECONNREFUSED:
|
||||
case ARES_EBADFAMILY:
|
||||
server_increment_failures(server, query->using_tcp);
|
||||
query->error_status = status;
|
||||
return ares__requeue_query(query, now);
|
||||
return ares__requeue_query(query, now, status);
|
||||
|
||||
/* Anything else is not retryable, likely ENOMEM */
|
||||
default:
|
||||
@ -1073,7 +1092,7 @@ ares_status_t ares__send_query(struct query *query, const ares_timeval_t *now)
|
||||
/* Only safe to kill connection if it was new, otherwise it should be
|
||||
* cleaned up by another process later */
|
||||
if (new_connection) {
|
||||
ares__close_connection(conn);
|
||||
ares__close_connection(conn, status);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@ -1111,8 +1130,7 @@ ares_status_t ares__send_query(struct query *query, const ares_timeval_t *now)
|
||||
case ARES_ECONNREFUSED:
|
||||
case ARES_EBADFAMILY:
|
||||
server_increment_failures(server, query->using_tcp);
|
||||
query->error_status = status;
|
||||
return ares__requeue_query(query, now);
|
||||
return ares__requeue_query(query, now, status);
|
||||
|
||||
/* Anything else is not retryable, likely ENOMEM */
|
||||
default:
|
||||
@ -1132,14 +1150,27 @@ ares_status_t ares__send_query(struct query *query, const ares_timeval_t *now)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* FIXME: Handle EAGAIN here since it likely can happen. */
|
||||
if (status == ARES_ECONNREFUSED) {
|
||||
handle_conn_error(conn, ARES_TRUE, status);
|
||||
|
||||
/* This query wasn't yet bound to the connection, need to manually
|
||||
* requeue it and return an appropriate error */
|
||||
status = ares__requeue_query(query, now, status);
|
||||
if (status == ARES_ETIMEOUT) {
|
||||
status = ARES_ECONNREFUSED;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/* FIXME: Handle EAGAIN here since it likely can happen. Right now we
|
||||
* just requeue to a different server/connection. */
|
||||
server_increment_failures(server, query->using_tcp);
|
||||
status = ares__requeue_query(query, now);
|
||||
status = ares__requeue_query(query, now, status);
|
||||
|
||||
/* Only safe to kill connection if it was new, otherwise it should be
|
||||
* cleaned up by another process later */
|
||||
if (new_connection) {
|
||||
ares__close_connection(conn);
|
||||
ares__close_connection(conn, status);
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -1162,7 +1193,7 @@ ares_status_t ares__send_query(struct query *query, const ares_timeval_t *now)
|
||||
/* Only safe to kill connection if it was new, otherwise it should be
|
||||
* cleaned up by another process later */
|
||||
if (new_connection) {
|
||||
ares__close_connection(conn);
|
||||
ares__close_connection(conn, ARES_SUCCESS);
|
||||
}
|
||||
return ARES_ENOMEM;
|
||||
/* LCOV_EXCL_STOP */
|
||||
@ -1180,7 +1211,7 @@ ares_status_t ares__send_query(struct query *query, const ares_timeval_t *now)
|
||||
/* Only safe to kill connection if it was new, otherwise it should be
|
||||
* cleaned up by another process later */
|
||||
if (new_connection) {
|
||||
ares__close_connection(conn);
|
||||
ares__close_connection(conn, ARES_SUCCESS);
|
||||
}
|
||||
return ARES_ENOMEM;
|
||||
/* LCOV_EXCL_STOP */
|
||||
@ -1283,12 +1314,9 @@ static ares_bool_t same_address(const struct sockaddr *sa,
|
||||
static void ares_detach_query(struct query *query)
|
||||
{
|
||||
/* Remove the query from all the lists in which it is linked */
|
||||
ares__query_disassociate_from_conn(query);
|
||||
ares__htable_szvp_remove(query->channel->queries_by_qid, query->qid);
|
||||
ares__slist_node_destroy(query->node_queries_by_timeout);
|
||||
ares__llist_node_destroy(query->node_queries_to_conn);
|
||||
ares__llist_node_destroy(query->node_all_queries);
|
||||
query->node_queries_by_timeout = NULL;
|
||||
query->node_queries_to_conn = NULL;
|
||||
query->node_all_queries = NULL;
|
||||
}
|
||||
|
||||
|
8
deps/cares/src/lib/ares_send.c
vendored
8
deps/cares/src/lib/ares_send.c
vendored
@ -145,11 +145,11 @@ ares_status_t ares_send_nolock(ares_channel_t *channel,
|
||||
query->using_tcp = (channel->flags & ARES_FLAG_USEVC)?ARES_TRUE:ARES_FALSE;
|
||||
|
||||
/* Duplicate Query */
|
||||
query->query = ares_dns_record_duplicate(dnsrec);
|
||||
if (query->query == NULL) {
|
||||
status = ares_dns_record_duplicate_ex(&query->query, dnsrec);
|
||||
if (status != ARES_SUCCESS) {
|
||||
ares_free(query);
|
||||
callback(arg, ARES_ENOMEM, 0, NULL);
|
||||
return ARES_ENOMEM;
|
||||
callback(arg, status, 0, NULL);
|
||||
return status;
|
||||
}
|
||||
|
||||
ares_dns_record_set_id(query->query, id);
|
||||
|
3
deps/cares/src/tools/CMakeLists.txt
vendored
3
deps/cares/src/tools/CMakeLists.txt
vendored
@ -32,6 +32,9 @@ IF (CARES_BUILD_TOOLS)
|
||||
|
||||
# Build adig
|
||||
ADD_EXECUTABLE (adig adig.c ${SAMPLESOURCES})
|
||||
# Don't build adig and ahost in parallel. This is to prevent a Windows MSVC
|
||||
# build error due to them both using the same source files.
|
||||
ADD_DEPENDENCIES(adig ahost)
|
||||
TARGET_INCLUDE_DIRECTORIES (adig
|
||||
PUBLIC "$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>"
|
||||
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>"
|
||||
|
Loading…
x
Reference in New Issue
Block a user