From bbc16cc8e6e852afd7cd95f1824429f81b7de222 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 7 Nov 2024 10:52:19 +0100 Subject: [PATCH] Implement 'max-query-count' Add another option to configure how many outgoing queries per client request is allowed. The existing 'max-recursion-queries' is per restart, this one is a global limit. --- bin/named/config.c | 1 + bin/named/server.c | 5 +++++ bin/tests/system/checkconf/good.conf.in | 1 + doc/arm/reference.rst | 9 +++++++++ doc/misc/options | 2 ++ lib/dns/include/dns/view.h | 14 ++++++++++++++ lib/dns/resolver.c | 1 + lib/dns/view.c | 8 ++++++++ lib/isccfg/namedconf.c | 1 + 9 files changed, 42 insertions(+) diff --git a/bin/named/config.c b/bin/named/config.c index 975ea4938a..636b3393c2 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -169,6 +169,7 @@ options {\n\ max-ncache-ttl 10800; /* 3 hours */\n\ max-recursion-depth 7;\n\ max-recursion-queries 32;\n\ + max-query-count 200;\n\ max-query-restarts 11;\n\ max-stale-ttl 86400; /* 1 day */\n\ message-compression yes;\n\ diff --git a/bin/named/server.c b/bin/named/server.c index de1a4ba6e1..085d0baea2 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -5292,6 +5292,11 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config, INSIST(result == ISC_R_SUCCESS); dns_view_setmaxrestarts(view, cfg_obj_asuint32(obj)); + obj = NULL; + result = named_config_get(maps, "max-query-count", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_view_setmaxqueries(view, cfg_obj_asuint32(obj)); + obj = NULL; result = named_config_get(maps, "max-validations-per-fetch", &obj); if (result == ISC_R_SUCCESS) { diff --git a/bin/tests/system/checkconf/good.conf.in b/bin/tests/system/checkconf/good.conf.in index be3b462b5e..18b35c9efb 100644 --- a/bin/tests/system/checkconf/good.conf.in +++ b/bin/tests/system/checkconf/good.conf.in @@ -74,6 +74,7 @@ options { check-names primary warn; check-names secondary ignore; max-cache-size 20000000000000; + max-query-count 100; max-query-restarts 10; nta-lifetime 604800; nta-recheck 604800; diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index 8851c842c0..bd3133e142 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -4472,6 +4472,15 @@ Tuning format is more human-readable, and is thus suitable when a zone is to be edited by hand. The default is ``relative``. +.. namedconf:statement:: max-query-count + :tags: server, query + :short: Sets the maximum number of iterative queries while servicing a recursive query. + + This sets the maximum number of iterative queries that may be sent + by a resolver while looking up a single name. If more queries than this + need to be sent before an answer is reached, then recursion is terminated + and a SERVFAIL response is returned to the client. The default is ``200``. + .. namedconf:statement:: max-recursion-depth :tags: server :short: Sets the maximum number of levels of recursion permitted at any one time while servicing a recursive query. diff --git a/doc/misc/options b/doc/misc/options index b6d4e062e3..71486800ff 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -179,6 +179,7 @@ options { max-ixfr-ratio ( unlimited | ); max-journal-size ( default | unlimited | ); max-ncache-ttl ; + max-query-count ; max-query-restarts ; max-records ; max-records-per-type ; @@ -470,6 +471,7 @@ view [ ] { max-ixfr-ratio ( unlimited | ); max-journal-size ( default | unlimited | ); max-ncache-ttl ; + max-query-count ; max-query-restarts ; max-records ; max-records-per-type ; diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index c82708ca52..a82d860d98 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -185,6 +185,7 @@ struct dns_view { unsigned int udpsize; uint32_t maxrrperset; uint32_t maxtypepername; + uint16_t max_queries; uint8_t max_restarts; /* @@ -1335,4 +1336,17 @@ dns_view_setmaxrestarts(dns_view_t *view, uint8_t max_restarts); *\li 'max_restarts' is greater than 0. */ +void +dns_view_setmaxqueries(dns_view_t *view, uint16_t max_queries); +/*% + * Set the number of permissible outgoing queries before we give up. + * This defaults to 200. + * + * Requires: + * + *\li 'view' is valid; + *\li 'max_queries' is greater than 0. + */ + + ISC_LANG_ENDDECLS diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index e6f69c0fda..5d5b094743 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -566,6 +566,7 @@ struct dns_resolver { unsigned int query_timeout; unsigned int maxdepth; unsigned int maxqueries; + unsigned int maxquerycount; isc_result_t quotaresp[2]; isc_stats_t *stats; dns_stats_t *querystats; diff --git a/lib/dns/view.c b/lib/dns/view.c index 5251f7a405..f5dd2126c7 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -2447,3 +2447,11 @@ dns_view_setmaxrestarts(dns_view_t *view, uint8_t max_restarts) { view->max_restarts = max_restarts; } + +void +dns_view_setmaxqueries(dns_view_t *view, uint16_t max_queries) { + REQUIRE(DNS_VIEW_VALID(view)); + REQUIRE(max_queries > 0); + + view->max_queries = max_queries; +} diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 9c29016c8b..84367fc2f3 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -2108,6 +2108,7 @@ static cfg_clausedef_t view_clauses[] = { { "max-ncache-ttl", &cfg_type_duration, 0 }, { "max-recursion-depth", &cfg_type_uint32, 0 }, { "max-recursion-queries", &cfg_type_uint32, 0 }, + { "max-query-count", &cfg_type_uint32, 0 }, { "max-query-restarts", &cfg_type_uint32, 0 }, { "max-stale-ttl", &cfg_type_duration, 0 }, { "max-udp-size", &cfg_type_uint32, 0 },