]> 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)
committerOndřej Surý <ondrej@isc.org>
Tue, 20 Aug 2024 17:35:07 +0000 (17:35 +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)
(cherry picked from commit bfbc6a6c840461a530077f2d5b02f9a53500f8ce)

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 daf0239dadd8e68fa964ddf99ed2339cec7eaae6..6b3ee6563d8c9842d09a4a2edbe67c6acb42d0ac 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;
 static isc_mem_t *mctx = NULL;
@@ -1791,6 +1797,8 @@ main(int argc, char *argv[]) {
                goto cleanup;
        }
 
+       dns_client_setmaxrestarts(client, MAX_RESTARTS);
+
        /* Set the nameserver */
        if (server != NULL) {
                addserver(client);
index 686b17c953d14b1855031bb78132707eeb31051c..f92427a6204f006c99890aefe685a7a452b71366 100644 (file)
@@ -61,8 +61,6 @@
 #define UCTX_MAGIC    ISC_MAGIC('U', 'c', 't', 'x')
 #define UCTX_VALID(c) ISC_MAGIC_VALID(c, UCTX_MAGIC)
 
-#define MAX_RESTARTS 11
-
 #ifdef TUNE_LARGE
 #define RESOLVER_NTASKS 523
 #else /* ifdef TUNE_LARGE */
@@ -96,6 +94,7 @@ struct dns_client {
 
        unsigned int find_timeout;
        unsigned int find_udpretries;
+       uint8_t max_restarts;
 
        isc_refcount_t references;
 
@@ -106,6 +105,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
@@ -328,6 +328,7 @@ dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
        client->taskmgr = taskmgr;
        client->socketmgr = socketmgr;
        client->timermgr = timermgr;
+       client->max_restarts = DEF_MAX_RESTARTS;
 
        client->task = NULL;
        result = isc_task_create(client->taskmgr, 0, &client->task);
@@ -520,6 +521,14 @@ dns_client_clearservers(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;
@@ -932,7 +941,9 @@ client_resfind(resctx_t *rctx, dns_fetchevent_t *event) {
                /*
                 * 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 fdcb6986c2e28a8a893249269a6d662b545c1d6d..7e268eb8fa2497bcfb80cc10795f0b06eefa4567 100644 (file)
@@ -236,6 +236,19 @@ dns_client_clearservers(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.
+ */
+
 isc_result_t
 dns_client_resolve(dns_client_t *client, const dns_name_t *name,
                   dns_rdataclass_t rdclass, dns_rdatatype_t type,
index 4151c1130ddd059827b86342fae57ce8c0230af8..79ab409c0121e770c508019d8b3102e7d99a3c6e 100644 (file)
@@ -190,6 +190,7 @@ struct dns_view {
        dns_badcache_t   *failcache;
        uint32_t          maxrrperset;
        uint32_t          maxtypepername;
+       uint8_t           max_restarts;
 
        /*
         * Configurable data for server use only,
@@ -1368,6 +1369,18 @@ dns_view_setmaxtypepername(dns_view_t *view, uint32_t value);
  * Set the maximum resource record types per owner name that can be cached.
  */
 
+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
 
 #endif /* DNS_VIEW_H */
index 0de880d2a661378b9afd7f466912bab84fe9613a..c795c5a868d7d948095f30c9f87319cd78aae4b4 100644 (file)
@@ -88,6 +88,12 @@ adb_shutdown(isc_task_t *task, isc_event_t *event);
 static void
 req_shutdown(isc_task_t *task, isc_event_t *event);
 
+/*%
+ * Default maximum number of chained queries before we give up
+ * to prevent CNAME loops.
+ */
+#define DEFAULT_MAX_RESTARTS 11
+
 isc_result_t
 dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *name,
                dns_view_t **viewp) {
@@ -264,6 +270,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *name,
        view->hooktable = NULL;
        view->hooktable_free = NULL;
 
+       view->max_restarts = DEFAULT_MAX_RESTARTS;
+
        isc_mutex_init(&view->new_zone_lock);
 
        result = dns_order_create(view->mctx, &view->order);
@@ -2661,3 +2669,11 @@ dns_view_setmaxtypepername(dns_view_t *view, uint32_t value) {
                dns_cache_setmaxtypepername(view->cache, value);
        }
 }
+
+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 6ace9f3e3058f8677350bc01a7d818382dc775d5..e9bf93994c7ff7567c59444585631d9c09a9f057 100644 (file)
@@ -97,6 +97,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 ce1d8f38ed9bdd6d71a97b55b0456cbd2631063c..cab1285312b981c0b7381bd8236709b1be8f6011 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;           \
@@ -2041,11 +2035,6 @@ addname:
        }
        fname = NULL;
 
-       /*
-        * 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.
-        */
        if (trdataset != NULL && dns_rdatatype_followadditional(type)) {
                eresult = dns_rdataset_additionaldata(
                        trdataset, query_additional_cb, qctx);
@@ -11509,7 +11498,9 @@ ns_query_done(query_ctx_t *qctx) {
        /*
         * Do we need to restart the query (e.g. for CNAME chaining)?
         */
-       if (qctx->want_restart && qctx->client->query.restarts < MAX_RESTARTS) {
+       if (qctx->want_restart && qctx->client->query.restarts <
+           qctx->client->view->max_restarts)
+       {
                qctx->client->query.restarts++;
                return (ns__query_start(qctx));
        }
index 63bea5dca4b980fb426cbc3cc1c4235a33179ef6..32c140a8e8b56ee71245f411855d215cde2f5d55 100644 (file)
@@ -38,7 +38,7 @@
 isc_result_t
 ns_server_create(isc_mem_t *mctx, ns_matchview_t matchingview,
                 ns_server_t **sctxp) {
-       ns_server_t *sctx;
+       ns_server_t *sctx = NULL;
        isc_result_t result;
 
        REQUIRE(sctxp != NULL && *sctxp == NULL);