Add +maxtotalqueries option to delv

The max-query-count value can now be set on the command line in delv
with +maxtotalqueries.
This commit is contained in:
Matthijs Mekking
2024-11-11 14:06:28 +01:00
parent 16b3bd1cc7
commit 74f845d62f
4 changed files with 85 additions and 15 deletions

View File

@@ -94,6 +94,7 @@
#define MAXNAME (DNS_NAME_MAXTEXT + 1)
#define MAX_QUERIES 32
#define MAX_TOTAL 200
#define MAX_RESTARTS 11
/* Variables used internally by delv. */
@@ -138,6 +139,7 @@ static bool showcomments = true, showdnssec = true, showtrust = true,
yaml = false, fulltrace = false;
static uint32_t maxqueries = MAX_QUERIES;
static uint32_t maxtotal = MAX_TOTAL;
static uint32_t restarts = MAX_RESTARTS;
static bool resolve_trace = false, validator_trace = false,
@@ -1168,22 +1170,46 @@ plus_option(char *option) {
break;
case 'm':
switch (cmd[1]) {
case 'a': /* maxqueries */
FULLCHECK("maxqueries");
if (value == NULL) {
goto need_value;
}
if (!state) {
case 'a':
switch (cmd[3]) {
case 'q': /* maxqueries */
FULLCHECK("maxqueries");
if (value == NULL) {
goto need_value;
}
if (!state) {
goto invalid_option;
}
result = parse_uint(&maxqueries, value,
UINT_MAX, "maxqueries");
if (result != ISC_R_SUCCESS) {
fatal("Couldn't parse maxqueries");
}
if (maxqueries == 0) {
fatal("maxqueries must be nonzero");
}
break;
case 't': /* maxtotalqueries */
FULLCHECK("maxtotalqueries");
if (value == NULL) {
goto need_value;
}
if (!state) {
goto invalid_option;
}
result = parse_uint(&maxtotal, value, UINT_MAX,
"maxtotalqueries");
if (result != ISC_R_SUCCESS) {
fatal("Couldn't parse maxtotalqueries");
}
if (maxtotal == 0) {
fatal("maxtotalqueries must be "
"nonzero");
}
break;
default:
goto invalid_option;
}
result = parse_uint(&maxqueries, value, UINT_MAX,
"maxqueries");
if (result != ISC_R_SUCCESS) {
fatal("Couldn't parse maxqueries");
}
if (maxqueries == 0) {
fatal("maxqueries must be nonzero");
}
break;
case 't': /* mtrace */
FULLCHECK("mtrace");
@@ -1931,6 +1957,7 @@ run_resolve(void *arg) {
CHECK(dns_client_create(mctx, loopmgr, netmgr, 0, tlsctx_client_cache,
&client, srcaddr4, srcaddr6));
dns_client_setmaxrestarts(client, restarts);
dns_client_setmaxqueries(client, maxtotal);
/* Set the nameserver */
if (server != NULL) {
@@ -2196,6 +2223,7 @@ run_server(void *arg) {
dns_cache_detach(&cache);
dns_view_setdstport(view, destport);
dns_view_setmaxrestarts(view, restarts);
dns_view_setmaxqueries(view, maxtotal);
CHECK(dns_rootns_create(mctx, dns_rdataclass_in, hintfile, &roothints));
dns_view_sethints(view, roothints);

View File

@@ -353,6 +353,11 @@ assign values to options like the timeout interval. They have the form
This option specifies the maximum number of queries to send to resolve
a name before giving up. The default is 32.
.. option:: +maxtotalqueries
This option specifies the maximum number of queries to send to resolve
a client request before giving up. The default is 200.
.. option:: +trust, +notrust
This option controls whether to display the trust level when printing a record.

View File

@@ -16,6 +16,7 @@
#include <isc/async.h>
#include <isc/buffer.h>
#include <isc/counter.h>
#include <isc/loop.h>
#include <isc/md.h>
#include <isc/mem.h>
@@ -81,6 +82,7 @@ struct dns_client {
unsigned int find_timeout;
unsigned int find_udpretries;
uint8_t max_restarts;
uint8_t max_queries;
isc_refcount_t references;
@@ -91,6 +93,7 @@ struct dns_client {
#define DEF_FIND_TIMEOUT 5
#define DEF_FIND_UDPRETRIES 3
#define DEF_MAX_RESTARTS 11
#define DEF_MAX_QUERIES 200
/*%
* Internal state for a single name resolution procedure
@@ -111,6 +114,7 @@ typedef struct resctx {
dns_fetch_t *fetch;
dns_namelist_t namelist;
isc_result_t result;
isc_counter_t *qc;
dns_clientresume_t *rev;
dns_rdataset_t *rdataset;
dns_rdataset_t *sigrdataset;
@@ -252,6 +256,7 @@ dns_client_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr, isc_nm_t *nm,
.loop = isc_loop_get(loopmgr, 0),
.nm = nm,
.max_restarts = DEF_MAX_RESTARTS,
.max_queries = DEF_MAX_QUERIES,
};
result = dns_dispatchmgr_create(mctx, loopmgr, nm,
@@ -395,6 +400,14 @@ dns_client_setmaxrestarts(dns_client_t *client, uint8_t max_restarts) {
client->max_restarts = max_restarts;
}
void
dns_client_setmaxqueries(dns_client_t *client, uint8_t max_queries) {
REQUIRE(DNS_CLIENT_VALID(client));
REQUIRE(max_queries > 0);
client->max_queries = max_queries;
}
static isc_result_t
getrdataset(isc_mem_t *mctx, dns_rdataset_t **rdatasetp) {
dns_rdataset_t *rdataset;
@@ -456,7 +469,7 @@ start_fetch(resctx_t *rctx) {
result = dns_resolver_createfetch(
rctx->view->resolver, dns_fixedname_name(&rctx->name),
rctx->type, NULL, NULL, NULL, NULL, 0, fopts, 0, NULL, NULL,
rctx->type, NULL, NULL, NULL, NULL, 0, fopts, 0, NULL, rctx->qc,
rctx->client->loop, fetch_done, rctx, rctx->rdataset,
rctx->sigrdataset, &rctx->fetch);
@@ -935,6 +948,11 @@ startresolve(dns_client_t *client, const dns_name_t *name,
rctx->magic = RCTX_MAGIC;
isc_refcount_increment(&client->references);
result = isc_counter_create(mctx, client->max_queries, &rctx->qc);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
ISC_LIST_APPEND(client->resctxs, rctx, link);
*transp = (dns_clientrestrans_t *)rctx;
@@ -949,6 +967,9 @@ cleanup:
if (sigrdataset != NULL) {
putrdataset(client->mctx, &sigrdataset);
}
if (rctx->qc != NULL) {
isc_counter_detach(&rctx->qc);
}
isc_mem_put(mctx, rctx, sizeof(*rctx));
isc_mem_put(mctx, rev, sizeof(*rev));
@@ -1042,6 +1063,9 @@ destroyrestrans(dns_clientrestrans_t **transp) {
rctx->magic = 0;
if (rctx->qc != NULL) {
isc_counter_detach(&rctx->qc);
}
isc_mem_put(mctx, rctx, sizeof(*rctx));
}

View File

@@ -187,6 +187,19 @@ dns_client_setmaxrestarts(dns_client_t *client, uint8_t max_restarts);
*\li 'max_restarts' is greater than 0.
*/
void
dns_client_setmaxqueries(dns_client_t *client, uint8_t max_queries);
/*%<
* Set the number of permissible outgoing queries before we give up,
* This defaults to 200.
*
* Requires:
*
*\li 'client' is a valid client.
*\li 'max_queries' is greater than 0.
*/
typedef void (*dns_client_resolve_cb)(dns_client_t *client,
const dns_name_t *name,
dns_namelist_t *namelist,