From: Evan Hunt Date: Tue, 25 Jun 2024 21:30:20 +0000 (-0700) Subject: make "max_restarts" a configurable value X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=95376b45f5a101525dfd2d8c2634a3f4b099c71f;p=thirdparty%2Fbind9.git make "max_restarts" a configurable value 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) --- diff --git a/bin/delv/delv.c b/bin/delv/delv.c index daf0239dadd..6b3ee6563d8 100644 --- a/bin/delv/delv.c +++ b/bin/delv/delv.c @@ -85,6 +85,12 @@ #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); diff --git a/lib/dns/client.c b/lib/dns/client.c index 686b17c953d..f92427a6204 100644 --- a/lib/dns/client.c +++ b/lib/dns/client.c @@ -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; diff --git a/lib/dns/include/dns/client.h b/lib/dns/include/dns/client.h index fdcb6986c2e..7e268eb8fa2 100644 --- a/lib/dns/include/dns/client.h +++ b/lib/dns/include/dns/client.h @@ -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, diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 4151c1130dd..79ab409c012 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -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 */ diff --git a/lib/dns/view.c b/lib/dns/view.c index 0de880d2a66..c795c5a868d 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -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; +} diff --git a/lib/ns/include/ns/server.h b/lib/ns/include/ns/server.h index 6ace9f3e305..e9bf93994c7 100644 --- a/lib/ns/include/ns/server.h +++ b/lib/ns/include/ns/server.h @@ -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; diff --git a/lib/ns/query.c b/lib/ns/query.c index ce1d8f38ed9..cab1285312b 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -82,12 +82,6 @@ #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)); } diff --git a/lib/ns/server.c b/lib/ns/server.c index 63bea5dca4b..32c140a8e8b 100644 --- a/lib/ns/server.c +++ b/lib/ns/server.c @@ -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);