]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add +maxtotalqueries option to delv
authorMatthijs Mekking <matthijs@isc.org>
Mon, 11 Nov 2024 13:06:28 +0000 (14:06 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Thu, 5 Dec 2024 13:17:08 +0000 (14:17 +0100)
The max-query-count value can now be set on the command line in delv
with +maxtotalqueries.

bin/delv/delv.c
bin/delv/delv.rst
lib/dns/client.c
lib/dns/include/dns/client.h

index d1ba814be18a56c58f038357ff5b4befe3797d77..2ecaeb3ed70e76c22a7866f8d10a5e0945eddd95 100644 (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);
index c32601e8b49b55970db818b5fa9cde52b7bdfb6c..f8c2da680609d58c6f036d5cbb3d93c001df23d2 100644 (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.
index 26c7acf8d41cfe2504bef18537648ff33dfbf1ee..fa4ba6ee84c0a376a20611b772f62f970b352000 100644 (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));
 }
 
index c065c0c705794ca853dc6a86c9c523d82e29dafc..75cbf8925000413b404aad4fc5faaa56bae631b0 100644 (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,