]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Limit the additional processing for large RDATA sets
authorOndřej Surý <ondrej@isc.org>
Thu, 14 Nov 2024 09:37:29 +0000 (10:37 +0100)
committerAndoni Duarte <andoni@isc.org>
Tue, 14 Jan 2025 09:57:54 +0000 (09:57 +0000)
Limit the number of records appended to ADDITIONAL section to the names
that have less than 14 records in the RDATA.  This limits the number
of the lookups into the database(s) during single client query.

Also don't append any additional data to ANY queries.  The answer to ANY
is already big enough.

lib/dns/include/dns/rdataset.h
lib/dns/qpzone.c
lib/dns/rdataset.c
lib/dns/resolver.c
lib/ns/query.c

index ae835b961d27c7578cbb4213c5727d6f98976124..89518b0ebfcb5fd1f056e9467363d36d08b1a74b 100644 (file)
@@ -53,6 +53,8 @@
 #include <dns/rdatastruct.h>
 #include <dns/types.h>
 
+#define DNS_RDATASET_MAXADDITIONAL 13
+
 /* Fixed RRSet helper macros */
 
 #define DNS_RDATASET_LENGTH 2;
@@ -503,7 +505,8 @@ dns_rdataset_towirepartial(dns_rdataset_t   *rdataset,
 isc_result_t
 dns_rdataset_additionaldata(dns_rdataset_t         *rdataset,
                            const dns_name_t        *owner_name,
-                           dns_additionaldatafunc_t add, void *arg);
+                           dns_additionaldatafunc_t add, void *arg,
+                           size_t limit);
 /*%<
  * For each rdata in rdataset, call 'add' for each name and type in the
  * rdata which is subject to additional section processing.
@@ -522,10 +525,15 @@ dns_rdataset_additionaldata(dns_rdataset_t            *rdataset,
  *\li  If a call to dns_rdata_additionaldata() is not successful, the
  *     result returned will be the result of dns_rdataset_additionaldata().
  *
+ *\li  If the 'limit' is non-zero and the number of the rdatasets is larger
+ *     than the 'limit', no additional data will be generated.
+ *
  * Returns:
  *
  *\li  #ISC_R_SUCCESS
  *
+ *\li  #DNS_R_TOOMANYRECORDS in case rdataset count is larger than 'limit'
+ *
  *\li  Any error that dns_rdata_additionaldata() can return.
  */
 
index 7847d260f1e968add69868a831523b102705d9f9..fadc3bc9c2a4b80a6197f37177fbbe6ba26fefdf 100644 (file)
@@ -5261,7 +5261,7 @@ create_gluelist(qpzonedb_t *qpdb, qpz_version_t *version, qpznode_t *node,
         */
 
        (void)dns_rdataset_additionaldata(rdataset, dns_rootname,
-                                         glue_nsdname_cb, &ctx);
+                                         glue_nsdname_cb, &ctx, 0);
 
        CMM_STORE_SHARED(gluelist->glue, ctx.glue);
 
index b09ff3cf29a05c453785c5daf4ed3bbba4ee7200..dc6fc4d8679fdb6b99bd8a5e1d65c70155962c73 100644 (file)
@@ -479,7 +479,8 @@ dns_rdataset_towire(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
 isc_result_t
 dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
                            const dns_name_t *owner_name,
-                           dns_additionaldatafunc_t add, void *arg) {
+                           dns_additionaldatafunc_t add, void *arg,
+                           size_t limit) {
        dns_rdata_t rdata = DNS_RDATA_INIT;
        isc_result_t result;
 
@@ -491,6 +492,10 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
        REQUIRE(DNS_RDATASET_VALID(rdataset));
        REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0);
 
+       if (limit != 0 && dns_rdataset_count(rdataset) > limit) {
+               return DNS_R_TOOMANYRECORDS;
+       }
+
        result = dns_rdataset_first(rdataset);
        if (result != ISC_R_SUCCESS) {
                return result;
index 70900c4cc0c56a007575c5da3eb0a6ef54f5b276..6497582bea766e18c5214bf27b92ac9c6f83cbce 100644 (file)
@@ -8576,9 +8576,6 @@ rctx_answer_any(respctx_t *rctx) {
                rdataset->attributes |= DNS_RDATASETATTR_ANSWER;
                rdataset->attributes |= DNS_RDATASETATTR_CACHE;
                rdataset->trust = rctx->trust;
-
-               (void)dns_rdataset_additionaldata(rdataset, rctx->aname,
-                                                 check_related, rctx);
        }
 
        return ISC_R_SUCCESS;
@@ -8626,7 +8623,8 @@ rctx_answer_match(respctx_t *rctx) {
        rctx->ardataset->attributes |= DNS_RDATASETATTR_CACHE;
        rctx->ardataset->trust = rctx->trust;
        (void)dns_rdataset_additionaldata(rctx->ardataset, rctx->aname,
-                                         check_related, rctx);
+                                         check_related, rctx,
+                                         DNS_RDATASET_MAXADDITIONAL);
 
        for (sigrdataset = ISC_LIST_HEAD(rctx->aname->list);
             sigrdataset != NULL;
@@ -8833,7 +8831,8 @@ rctx_authority_positive(respctx_t *rctx) {
                                         */
                                        (void)dns_rdataset_additionaldata(
                                                rdataset, name, check_related,
-                                               rctx);
+                                               rctx,
+                                               DNS_RDATASET_MAXADDITIONAL);
                                        done = true;
                                }
                        }
@@ -9340,8 +9339,11 @@ rctx_referral(respctx_t *rctx) {
         */
        INSIST(rctx->ns_rdataset != NULL);
        FCTX_ATTR_SET(fctx, FCTX_ATTR_GLUING);
+       /*
+        * We want to append **all** the GLUE records here.
+        */
        (void)dns_rdataset_additionaldata(rctx->ns_rdataset, rctx->ns_name,
-                                         check_related, rctx);
+                                         check_related, rctx, 0);
 #if CHECK_FOR_GLUE_IN_ANSWER
        /*
         * Look in the answer section for "glue" that is incorrectly
@@ -9456,7 +9458,8 @@ again:
                        if (CHASE(rdataset)) {
                                rdataset->attributes &= ~DNS_RDATASETATTR_CHASE;
                                (void)dns_rdataset_additionaldata(
-                                       rdataset, name, check_related, rctx);
+                                       rdataset, name, check_related, rctx,
+                                       DNS_RDATASET_MAXADDITIONAL);
                                rescan = true;
                        }
                }
index 8464e782d9f34b84527d5a37fe746b93c68bc1bb..9757a256225dc4cb64f2fded2928ea4a59cf2701 100644 (file)
@@ -2143,7 +2143,8 @@ addname:
        if (trdataset != NULL && dns_rdatatype_followadditional(type)) {
                if (client->additionaldepth++ < client->view->max_restarts) {
                        eresult = dns_rdataset_additionaldata(
-                               trdataset, fname, query_additional_cb, qctx);
+                               trdataset, fname, query_additional_cb, qctx,
+                               DNS_RDATASET_MAXADDITIONAL);
                }
                client->additionaldepth--;
        }
@@ -2240,7 +2241,7 @@ regular:
         * We don't care if dns_rdataset_additionaldata() fails.
         */
        (void)dns_rdataset_additionaldata(rdataset, name, query_additional_cb,
-                                         qctx);
+                                         qctx, DNS_RDATASET_MAXADDITIONAL);
        CTRACE(ISC_LOG_DEBUG(3), "query_additional: done");
 }