From e5585105cdfc9341b7526e8183f3556bf26de31d Mon Sep 17 00:00:00 2001 From: Brad House Date: Sat, 17 Feb 2024 05:52:10 -0500 Subject: [PATCH] Add ares_queue_active_queries() (#712) Add a function to request the number of active queries from an ares channel. This will return the number of inflight requests to dns servers. Some functions like `ares_getaddrinfo()` when using `AF_UNSPEC` may enqueue multiple queries which will be reflected in this count. In the future, if we implement support for queuing (e.g. for throttling purposes), and/or implement support for tracking user-requested queries (e.g. for cancelation), we can provide additional functions for inspecting those queues. Fix By: Brad House (@bradh352) --- docs/Makefile.inc | 2 ++ docs/ares_queue.3 | 53 ++++++++++++++++++++++++++++++++ docs/ares_queue_active_queries.3 | 3 ++ docs/ares_queue_wait_empty.3 | 45 ++------------------------- include/ares.h | 9 ++++++ src/lib/ares_send.c | 18 +++++++++++ 6 files changed, 87 insertions(+), 43 deletions(-) create mode 100644 docs/ares_queue.3 create mode 100644 docs/ares_queue_active_queries.3 diff --git a/docs/Makefile.inc b/docs/Makefile.inc index 5d5bb185..3645a7fc 100644 --- a/docs/Makefile.inc +++ b/docs/Makefile.inc @@ -105,6 +105,8 @@ MANPAGES = ares_cancel.3 \ ares_parse_uri_reply.3 \ ares_process.3 \ ares_query.3 \ + ares_queue.3 \ + ares_queue_active_queries.3 \ ares_queue_wait_empty.3 \ ares_reinit.3 \ ares_save_options.3 \ diff --git a/docs/ares_queue.3 b/docs/ares_queue.3 new file mode 100644 index 00000000..1212e8d3 --- /dev/null +++ b/docs/ares_queue.3 @@ -0,0 +1,53 @@ +.\" +.\" SPDX-License-Identifier: MIT +.\" +.TH ARES_QUEUE 3 "16 February 2024" +.SH NAME +ares_queue_wait_empty, ares_queue_active_queries \- Functions for checking the +c-ares queue status +.SH SYNOPSIS +.nf +#include + +size_t ares_queue_active_queries(ares_channel_t *channel); + +ares_status_t ares_queue_wait_empty(ares_channel_t *channel, + int timeout_ms); +.fi +.SH DESCRIPTION +The \fBares_queue_active_queries(3)\fP function retrieves the total number of +active queries pending answers from servers. Some c-ares requests may spawn +multiple queries, such as \fIares_getaddrinfo(3)\fP when using \fIAF_UNSPEC\fP, +which will be reflected in this number. The \fBchannel\fP parameter must be set +to an initialized channel. + +The \fBares_queue_wait_empty(3)\fP function blocks until notified that there are +no longer any queries in queue, or the specified timeout has expired. The +\fBchannel\fP parameter must be set to an initialized channel. The +\fBtimeout_ms\fP parameter is the number of milliseconds to wait for the queue +to be empty or -1 for Infinite. + +.SH RETURN VALUES +\fIares_queue_active_queries(3)\fP returns the active query count. + +\fIares_queue_wait_empty(3)\fP can return any of the following values: +.TP 14 +.B ARES_ENOTIMP +if not built with threading support +.TP 14 +.B ARES_ETIMEOUT +if requested timeout expired +.TP 14 +.B ARES_SUCCESS +when queue is empty. +.TP 14 + +.SH AVAILABILITY +This function was first introduced in c-ares version 1.27.0, and requires the +c-ares library to be built with threading support. + +.SH SEE ALSO +.BR ares_init_options (3), +.BR ares_threadsafety (3) +.SH AUTHOR +Copyright (C) 2024 The c-ares project and its members. diff --git a/docs/ares_queue_active_queries.3 b/docs/ares_queue_active_queries.3 new file mode 100644 index 00000000..c16c69dd --- /dev/null +++ b/docs/ares_queue_active_queries.3 @@ -0,0 +1,3 @@ +.\" Copyright (C) 2024 The c-ares project and its contributors. +.\" SPDX-License-Identifier: MIT +.so man3/ares_queue.3 diff --git a/docs/ares_queue_wait_empty.3 b/docs/ares_queue_wait_empty.3 index 59038fdc..c16c69dd 100644 --- a/docs/ares_queue_wait_empty.3 +++ b/docs/ares_queue_wait_empty.3 @@ -1,44 +1,3 @@ -.\" +.\" Copyright (C) 2024 The c-ares project and its contributors. .\" SPDX-License-Identifier: MIT -.\" -.TH ARES_QUEUE_WAIT_EMPTY 3 "12 February 2024" -.SH NAME -ares_queue_wait_empty \- Wait until all queries are complete for channel -.SH SYNOPSIS -.nf -#include - -ares_status_t ares_queue_wait_empty(ares_channel_t *channel, - int timeout_ms); -.fi -.SH DESCRIPTION -The \fBares_queue_wait_empty(3)\fP function blocks until notified that there are -no longer any queries in queue, or the specified timeout has expired. - -The \fBchannel\fP parameter must be set to an initialized channel. - -The \fBtimeout_ms\fP parameter is the number of milliseconds to wait for the -queue to be empty or -1 for Infinite. - -.SH RETURN VALUES -\fIares_queue_wait_empty(3)\fP can return any of the following values: -.TP 14 -.B ARES_ENOTIMP -if not built with threading support -.TP 14 -.B ARES_ETIMEOUT -if requested timeout expired -.TP 14 -.B ARES_SUCCESS -when queue is empty. -.TP 14 - -.SH AVAILABILITY -This function was first introduced in c-ares version 1.27.0, and requires the -c-ares library to be built with threading support. - -.SH SEE ALSO -.BR ares_init_options (3), -.BR ares_threadsafety (3) -.SH AUTHOR -Copyright (C) 2024 The c-ares project and its members. +.so man3/ares_queue.3 diff --git a/include/ares.h b/include/ares.h index 32c0191b..d7588e7e 100644 --- a/include/ares.h +++ b/include/ares.h @@ -787,6 +787,15 @@ CARES_EXTERN ares_status_t ares_queue_wait_empty(ares_channel_t *channel, int timeout_ms); +/*! Retrieve the total number of active queries pending answers from servers. + * Some c-ares requests may spawn multiple queries, such as ares_getaddrinfo() + * when using AF_UNSPEC, which will be reflected in this number. + * + * \param[in] channel Initialized ares channel + * \return Number of active queries to servers + */ +CARES_EXTERN size_t ares_queue_active_queries(ares_channel_t *channel); + #ifdef __cplusplus } #endif diff --git a/src/lib/ares_send.c b/src/lib/ares_send.c index 2510b1ed..d1885c44 100644 --- a/src/lib/ares_send.c +++ b/src/lib/ares_send.c @@ -163,3 +163,21 @@ void ares_send(ares_channel_t *channel, const unsigned char *qbuf, int qlen, ares__channel_unlock(channel); } + + +size_t ares_queue_active_queries(ares_channel_t *channel) +{ + size_t len; + + if (channel == NULL) { + return 0; + } + + ares__channel_lock(channel); + + len = ares__llist_len(channel->all_queries); + + ares__channel_unlock(channel); + + return len; +}