]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
add +restarts and +maxqueries options to delv
authorEvan Hunt <each@isc.org>
Wed, 26 Jun 2024 01:48:18 +0000 (18:48 -0700)
committerEvan Hunt <each@isc.org>
Wed, 7 Aug 2024 21:12:34 +0000 (21:12 +0000)
max-query-restarts and max-recursion-queries values can now be set
on the command line in delv for testing purposes.

(cherry picked from commit 0d010ddebed574712796da1802bcff50dae3ffb5)

bin/delv/delv.c
bin/delv/delv.rst

index d41bbabf7294e6453247478e055baf810062522b..acd909965b0afae71d954a433255d9120125440b 100644 (file)
 
 #define MAXNAME (DNS_NAME_MAXTEXT + 1)
 
-/*
- * Default maximum number of chained queries before we give up
- * to prevent CNAME loops.
- */
+#define MAX_QUERIES  32
 #define MAX_RESTARTS 11
 
 /* Variables used internally by delv. */
@@ -136,6 +133,9 @@ static bool showcomments = true, showdnssec = true, showtrust = true,
            multiline = false, short_form = false, print_unknown_format = false,
            yaml = false, fulltrace = false;
 
+static uint32_t maxqueries = MAX_QUERIES;
+static uint32_t restarts = MAX_RESTARTS;
+
 static bool resolve_trace = false, validator_trace = false,
            message_trace = false, send_trace = false;
 
@@ -1197,6 +1197,23 @@ plus_option(char *option) {
                break;
        case 'm':
                switch (cmd[1]) {
+               case 'a': /* 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': /* mtrace */
                        FULLCHECK("mtrace");
                        message_trace = state;
@@ -1249,6 +1266,22 @@ plus_option(char *option) {
                break;
        case 'r':
                switch (cmd[1]) {
+               case 'e': /* restarts */
+                       FULLCHECK("restarts");
+                       if (value == NULL) {
+                               goto need_value;
+                       }
+                       if (!state) {
+                               goto invalid_option;
+                       }
+                       result = parse_uint(&restarts, value, 255, "restarts");
+                       if (result != ISC_R_SUCCESS) {
+                               fatal("Couldn't parse restarts");
+                       }
+                       if (restarts == 0) {
+                               fatal("restarts must be between 1..255");
+                       }
+                       break;
                case 'o': /* root */
                        FULLCHECK("root");
                        if (state && no_sigs) {
@@ -1376,10 +1409,7 @@ plus_option(char *option) {
                break;
        default:
        invalid_option:
-               /*
-                * We can also add a "need_value:" case here if we ever
-                * add a plus-option that requires a specified value
-                */
+       need_value:
                fprintf(stderr, "Invalid option: +%s\n", option);
                usage();
        }
@@ -1904,7 +1934,7 @@ run_resolve(void *arg) {
        /* Create client */
        CHECK(dns_client_create(mctx, loopmgr, netmgr, 0, tlsctx_client_cache,
                                &client, srcaddr4, srcaddr6));
-       dns_client_setmaxrestarts(client, MAX_RESTARTS);
+       dns_client_setmaxrestarts(client, restarts);
 
        /* Set the nameserver */
        if (server != NULL) {
@@ -2169,7 +2199,7 @@ run_server(void *arg) {
        dns_view_setcache(view, cache, false);
        dns_cache_detach(&cache);
        dns_view_setdstport(view, destport);
-       dns_view_setmaxrestarts(view, MAX_RESTARTS);
+       dns_view_setmaxrestarts(view, restarts);
 
        CHECK(dns_rootns_create(mctx, dns_rdataclass_in, hintfile, &roothints));
        dns_view_sethints(view, roothints);
@@ -2183,6 +2213,7 @@ run_server(void *arg) {
 
        CHECK(dns_view_createresolver(view, netmgr, 0, tlsctx_client_cache,
                                      dispatch, NULL));
+       dns_resolver_setmaxqueries(view->resolver, maxqueries);
 
        isc_stats_create(mctx, &resstats, dns_resstatscounter_max);
        dns_resolver_setstats(view->resolver, resstats);
index 2ab1f897f428315f02ce6bf2722256a6188a5dcc..74239c9bc1e21c00ad8b11183a816d27cc4c34c5 100644 (file)
@@ -337,6 +337,18 @@ assign values to options like the timeout interval. They have the form
    they are replaced by the string ``[omitted]`` or, in the DNSKEY case, the
    key ID is displayed as the replacement, e.g. ``[ key id = value ]``.
 
+.. option:: +restarts
+
+   When name server mode (``delv +ns``) is in use, this option sets the
+   maximum number of CNAME queries to follow before terminating resolution.
+   This prevents ``delv`` from hanging in the event of a CNAME loop.
+   The default is 11.
+
+.. option:: +maxqueries
+
+   This option specifies the maximum number of queries to send to resolve
+   a name before giving up. The default is 32.
+
 .. option:: +trust, +notrust
 
    This option controls whether to display the trust level when printing a record.