]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
make "max_restarts" a configurable value
authorEvan Hunt <each@isc.org>
Tue, 25 Jun 2024 21:30:20 +0000 (14:30 -0700)
committerEvan Hunt <each@isc.org>
Wed, 7 Aug 2024 21:12:34 +0000 (21:12 +0000)
MAX_RESTARTS is no longer hard-coded; ns_server_setmaxrestarts()
and dns_client_setmaxrestarts() can now be used to modify the
max-restarts value at runtime. in both cases, the default is 11.

(cherry picked from commit c5588babaf89f3e3ad2edccaada716e55c135dd3)

bin/delv/delv.c
lib/dns/client.c
lib/dns/include/dns/client.h
lib/dns/include/dns/view.h
lib/dns/view.c
lib/ns/include/ns/server.h
lib/ns/query.c
lib/ns/server.c

index 549d1bde5ae2a216ad64513c1979c2e432257dc9..d41bbabf7294e6453247478e055baf810062522b 100644 (file)
 
 #define MAXNAME (DNS_NAME_MAXTEXT + 1)
 
+/*
+ * Default maximum number of chained queries before we give up
+ * to prevent CNAME loops.
+ */
+#define MAX_RESTARTS 11
+
 /* Variables used internally by delv. */
 char *progname = NULL;
 static isc_mem_t *mctx = NULL;
@@ -1898,6 +1904,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);
 
        /* Set the nameserver */
        if (server != NULL) {
@@ -2162,6 +2169,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);
 
        CHECK(dns_rootns_create(mctx, dns_rdataclass_in, hintfile, &roothints));
        dns_view_sethints(view, roothints);
index a945b93d79546658e9106263c537b9223ca4035f..bcd9e4c3e5871245fc36a961c6aeba66ac2fe6ab 100644 (file)
@@ -57,8 +57,6 @@
 #define UCTX_MAGIC    ISC_MAGIC('U', 'c', 't', 'x')
 #define UCTX_VALID(c) ISC_MAGIC_VALID(c, UCTX_MAGIC)
 
-#define MAX_RESTARTS 11
-
 #define CHECK(r)                             \
        do {                                 \
                result = (r);                \
@@ -81,6 +79,7 @@ struct dns_client {
 
        unsigned int find_timeout;
        unsigned int find_udpretries;
+       uint8_t max_restarts;
 
        isc_refcount_t references;
 
@@ -90,6 +89,7 @@ struct dns_client {
 
 #define DEF_FIND_TIMEOUT    5
 #define DEF_FIND_UDPRETRIES 3
+#define DEF_MAX_RESTARTS    11
 
 /*%
  * Internal state for a single name resolution procedure
@@ -250,6 +250,7 @@ dns_client_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr, isc_nm_t *nm,
        *client = (dns_client_t){
                .loop = isc_loop_get(loopmgr, 0),
                .nm = nm,
+               .max_restarts = DEF_MAX_RESTARTS,
        };
 
        result = dns_dispatchmgr_create(mctx, loopmgr, nm,
@@ -384,6 +385,14 @@ dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass,
        return (result);
 }
 
+void
+dns_client_setmaxrestarts(dns_client_t *client, uint8_t max_restarts) {
+       REQUIRE(DNS_CLIENT_VALID(client));
+       REQUIRE(max_restarts > 0);
+
+       client->max_restarts = max_restarts;
+}
+
 static isc_result_t
 getrdataset(isc_mem_t *mctx, dns_rdataset_t **rdatasetp) {
        dns_rdataset_t *rdataset;
@@ -778,7 +787,9 @@ client_resfind(resctx_t *rctx, dns_fetchresponse_t *resp) {
                /*
                 * Limit the number of restarts.
                 */
-               if (want_restart && rctx->restarts == MAX_RESTARTS) {
+               if (want_restart &&
+                   rctx->restarts == rctx->client->max_restarts)
+               {
                        want_restart = false;
                        result = ISC_R_QUOTA;
                        send_event = true;
index 148578f4b7aae42dd61be75975bafacb75a54800..c065c0c705794ca853dc6a86c9c523d82e29dafc 100644 (file)
@@ -174,6 +174,19 @@ dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass,
  *\li  Anything else                           Failure.
  */
 
+void
+dns_client_setmaxrestarts(dns_client_t *client, uint8_t max_restarts);
+/*%<
+ * Set the number of permissible chained queries before we give up,
+ * to prevent CNAME loops. This defaults to 11.
+ *
+ * Requires:
+ *
+ *\li  'client' is a valid client.
+
+ *\li  'max_restarts' is greater than 0.
+ */
+
 typedef void (*dns_client_resolve_cb)(dns_client_t     *client,
                                      const dns_name_t *name,
                                      dns_namelist_t   *namelist,
index ddba1e7401e80904c15470136039a1494269ef31..02932e8a94207366c4adc308b39ddcebb1ca41aa 100644 (file)
@@ -185,6 +185,7 @@ struct dns_view {
        unsigned int          udpsize;
        uint32_t              maxrrperset;
        uint32_t              maxtypepername;
+       uint8_t               max_restarts;
 
        /*
         * Configurable data for server use only,
@@ -1327,4 +1328,16 @@ dns_view_getadb(dns_view_t *view, dns_adb_t **adbp);
  *\li  'adbp' is non-NULL and '*adbp' is NULL.
  */
 
+void
+dns_view_setmaxrestarts(dns_view_t *view, uint8_t max_restarts);
+/*%<
+ * Set the number of permissible chained queries before we give up,
+ * to prevent CNAME loops. This defaults to 11.
+ *
+ * Requires:
+ *
+ *\li  'view' is valid;
+ *\li  'max_restarts' is greater than 0.
+ */
+
 ISC_LANG_ENDDECLS
index 99d8b61b592cf542d232d67669e144c261819b12..bcac41bb8055a31585f7e7420dd451d7dbd75af7 100644 (file)
 
 #define DNS_VIEW_DELONLYHASH 111
 
+/*%
+ * Default maximum number of chained queries before we give up
+ * to prevent CNAME loops.
+ */
+#define DEFAULT_MAX_RESTARTS 11
+
 /*%
  * Default EDNS0 buffer size
  */
@@ -116,6 +122,7 @@ dns_view_create(isc_mem_t *mctx, dns_dispatchmgr_t *dispatchmgr,
                .trust_anchor_telemetry = true,
                .root_key_sentinel = true,
                .udpsize = DEFAULT_EDNS_BUFSIZE,
+               .max_restarts = DEFAULT_MAX_RESTARTS,
        };
 
        isc_refcount_init(&view->references, 1);
@@ -2455,3 +2462,11 @@ dns_view_getadb(dns_view_t *view, dns_adb_t **adbp) {
        }
        rcu_read_unlock();
 }
+
+void
+dns_view_setmaxrestarts(dns_view_t *view, uint8_t max_restarts) {
+       REQUIRE(DNS_VIEW_VALID(view));
+       REQUIRE(max_restarts > 0);
+
+       view->max_restarts = max_restarts;
+}
index fc01ee2c62d9d32c8e3b7f3ab57de792325fc897..ec6636a0fdf6766566b8dd1d03dfebb89827419e 100644 (file)
@@ -103,6 +103,7 @@ struct ns_server {
        uint16_t       transfer_tcp_message_size;
        bool           interface_auto;
        dns_tkeyctx_t *tkeyctx;
+       uint8_t        max_restarts;
 
        /*% Server id for NSID */
        char *server_id;
index 4e66f7b7367542d810d0ff8d1f6f2474f792c09c..01b24dcdfa4f532b57b3523069d2e277655ad06e 100644 (file)
 #define dns64_bis_return_excluded_addresses 1
 #endif /* if 0 */
 
-/*%
- * Maximum number of chained queries before we give up
- * to prevent CNAME loops.
- */
-#define MAX_RESTARTS 11
-
 #define QUERY_ERROR(qctx, r)                  \
        do {                                  \
                (qctx)->result = r;           \
@@ -2046,10 +2040,10 @@ addname:
        /*
         * In some cases, a record that has been added as additional
         * data may *also* trigger the addition of additional data.
-        * This cannot go more than MAX_RESTARTS levels deep.
+        * This cannot go more than 'max-restarts' levels deep.
         */
        if (trdataset != NULL && dns_rdatatype_followadditional(type)) {
-               if (client->additionaldepth++ < MAX_RESTARTS) {
+               if (client->additionaldepth++ < client->view->max_restarts) {
                        eresult = dns_rdataset_additionaldata(
                                trdataset, fname, query_additional_cb, qctx);
                }
@@ -11580,7 +11574,9 @@ ns_query_done(query_ctx_t *qctx) {
         * Do we need to restart the query (e.g. for CNAME chaining)?
         */
        if (qctx->want_restart) {
-               if (qctx->client->query.restarts < MAX_RESTARTS) {
+               if (qctx->client->query.restarts <
+                   qctx->client->view->max_restarts)
+               {
                        query_ctx_t *saved_qctx = NULL;
                        qctx->client->query.restarts++;
                        saved_qctx = isc_mem_get(qctx->client->manager->mctx,
index ea4a588c1880d976848b3475d498d9870889cec7..94ee48b76c42a0d5973bf14fa4cd5094a8f5ce0c 100644 (file)
@@ -38,7 +38,7 @@
 void
 ns_server_create(isc_mem_t *mctx, ns_matchview_t matchingview,
                 ns_server_t **sctxp) {
-       ns_server_t *sctx;
+       ns_server_t *sctx = NULL;
 
        REQUIRE(sctxp != NULL && *sctxp == NULL);