From: W.C.A. Wijngaards Date: Thu, 8 Aug 2024 07:27:45 +0000 (+0200) Subject: - Fix CAMP issues with global quota. Thanks to Huayi Duan, Marco X-Git-Tag: release-1.21.0rc1~2 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=ed883238fd347c8855a9eff53f54fa082c6d4d15;p=thirdparty%2Funbound.git - Fix CAMP issues with global quota. Thanks to Huayi Duan, Marco Bearzi, Jodok Vieli, and Cagin Tanir from NetSec group, ETH Zurich. --- diff --git a/doc/Changelog b/doc/Changelog index cec04793f..c1a3ab8ea 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +8 August 2024: Wouter + - Fix CAMP issues with global quota. Thanks to Huayi Duan, Marco + Bearzi, Jodok Vieli, and Cagin Tanir from NetSec group, ETH Zurich. + 2 August 2024: Wouter - Fix that alloc stats has strdup checks, it stops debuggers from complaining about mismatch at free time. diff --git a/iterator/iterator.c b/iterator/iterator.c index b348e9867..228f5dfae 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -760,6 +760,14 @@ target_count_increase_nx(struct iter_qstate* iq, int num) iq->target_count[TARGET_COUNT_NX] += num; } +static void +target_count_increase_global_quota(struct iter_qstate* iq, int num) +{ + target_count_create(iq); + if(iq->target_count) + iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] += num; +} + /** * Generate a subrequest. * Generate a local request event. Local events are tied to this module, and @@ -3013,6 +3021,17 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, } } + target_count_increase_global_quota(iq, 1); + if(iq->target_count && iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] + > MAX_GLOBAL_QUOTA) { + char s[LDNS_MAX_DOMAINLEN+1]; + dname_str(qstate->qinfo.qname, s); + verbose(VERB_QUERY, "request %s has exceeded the maximum " + "global quota on number of upstream queries %d", s, + iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]); + return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); + } + /* Do not check ratelimit for forwarding queries or if we already got a * pass. */ sq_check_ratelimit = (!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok); diff --git a/iterator/iterator.h b/iterator/iterator.h index e253f3f7e..70b11df7e 100644 --- a/iterator/iterator.h +++ b/iterator/iterator.h @@ -55,6 +55,9 @@ struct rbtree_type; /** max number of targets spawned for a query and its subqueries */ #define MAX_TARGET_COUNT 64 +/** max number of upstream queries for a query and its subqueries, it is + * never reset. */ +#define MAX_GLOBAL_QUOTA 128 /** max number of target lookups per qstate, per delegation point */ #define MAX_DP_TARGET_COUNT 16 /** max number of nxdomains allowed for target lookups for a query and @@ -248,6 +251,9 @@ enum target_count_variables { TARGET_COUNT_QUERIES, /** Number of nxdomain responses encountered. */ TARGET_COUNT_NX, + /** Global quota on number of queries to upstream servers per + * client request, that is never reset. */ + TARGET_COUNT_GLOBAL_QUOTA, /** This should stay last here, it is used for the allocation */ TARGET_COUNT_MAX,