]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix CAMP issues with global quota. Thanks to Huayi Duan, Marco
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 8 Aug 2024 07:27:45 +0000 (09:27 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 8 Aug 2024 07:27:45 +0000 (09:27 +0200)
  Bearzi, Jodok Vieli, and Cagin Tanir from NetSec group, ETH Zurich.

doc/Changelog
iterator/iterator.c
iterator/iterator.h

index cec04793f964ce1400a3ed144cfb224f34f1511f..c1a3ab8ea8f0474271f9eab6104407558f8e2ed6 100644 (file)
@@ -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.
index b348e98677f27363b4db52934ac293139fc90b42..228f5dfaef304f7de96c3074297c2eb91cf9645c 100644 (file)
@@ -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);
index e253f3f7e2bd36ddea96e9de58abb11f32c63919..70b11df7ebcf37d77f789af24a39b3cab49c9112 100644 (file)
@@ -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,