]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Limit the additional processing for large RDATA sets
authorOndřej Surý <ondrej@isc.org>
Thu, 19 Dec 2024 15:40:52 +0000 (16:40 +0100)
committerNicki Křížek <nicki@isc.org>
Mon, 20 Jan 2025 16:11:21 +0000 (17:11 +0100)
When answering queries, don't add data to the additional section if
the answer has more than 13 names in the RDATA.  This limits the
number of lookups into the database(s) during a single client query,
reducing query processing load.

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

(cherry picked from commit a1982cf1bb95c818aa7b58988b5611dec80f2408)

bin/named/query.c
bin/tests/system/additional/tests.sh
bin/tests/system/resolver/tests.sh
lib/dns/include/dns/rdataset.h
lib/dns/rdataset.c
lib/dns/resolver.c

index 897beb7313ee3f0ca5eb0985037d66bfb66f110d..5cba4a22c6b14c5a2e16c6b3470b29e78a60adcc 100644 (file)
@@ -1827,7 +1827,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
                 */
                eresult = dns_rdataset_additionaldata(trdataset,
                                                      query_addadditional,
-                                                     client);
+                                                     client,
+                                                     DNS_RDATASET_MAXADDITIONAL);
        }
 
  cleanup:
@@ -2422,7 +2423,7 @@ query_addrdataset(ns_client_t *client, dns_name_t *fname,
                                                       rdataset->rdclass);
        rdataset->attributes |= DNS_RDATASETATTR_LOADORDER;
 
-       if (NOADDITIONAL(client))
+       if (NOADDITIONAL(client) || client->query.qtype == dns_rdatatype_any)
                return;
 
        /*
@@ -2433,7 +2434,8 @@ query_addrdataset(ns_client_t *client, dns_name_t *fname,
        additionalctx.client = client;
        additionalctx.rdataset = rdataset;
        (void)dns_rdataset_additionaldata(rdataset, query_addadditional2,
-                                         &additionalctx);
+                                         &additionalctx,
+                                         DNS_RDATASET_MAXADDITIONAL);
        CTRACE(ISC_LOG_DEBUG(3), "query_addrdataset: done");
 }
 
index 6400723a557265edb4292a893e8950d80227de24..a33cc8aed26db49fb4f6bf3e28af933b46c4933f 100644 (file)
@@ -261,7 +261,7 @@ n=`expr $n + 1`
 echo_i "testing with 'minimal-any no;' ($n)"
 ret=0
 $DIG $DIGOPTS -t ANY www.rt.example @10.53.0.1 > dig.out.$n || ret=1
-grep "ANSWER: 3, AUTHORITY: 1, ADDITIONAL: 2" dig.out.$n > /dev/null || ret=1
+grep "ANSWER: 3, AUTHORITY: 1, ADDITIONAL: 1" dig.out.$n > /dev/null || ret=1
 if [ $ret -eq 1 ] ; then
     echo_i "failed"; status=`expr status + 1`
 fi
index b3c9f2179c7bd127a8734969d8d9fc5141dc8662..e727c887bf2d3ce2232af244096a08ed28390d00 100755 (executable)
@@ -281,6 +281,10 @@ done
 if [ $ret != 0 ]; then echo_i "failed"; fi
 status=`expr $status + $ret`
 
+$PERL $SYSTEMTESTTOP/stop.pl resolver ns4
+touch ns4/named.noaa
+$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} resolver ns4 || ret=1
+
 n=`expr $n + 1`
 echo_i "RT21594 regression test check setup ($n)"
 ret=0
@@ -317,6 +321,10 @@ grep "status: NXDOMAIN" dig.ns5.out.${n} > /dev/null || ret=1
 if [ $ret != 0 ]; then echo_i "failed"; fi
 status=`expr $status + $ret`
 
+$PERL $SYSTEMTESTTOP/stop.pl resolver ns4
+rm ns4/named.noaa
+$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} resolver ns4 || ret=1
+
 n=`expr $n + 1`
 echo_i "check that replacement of additional data by a negative cache no data entry clears the additional RRSIGs ($n)"
 ret=0
index ed9119a62d4559be5280423fab75de25f2df4a0d..cd9b014205ee49aa17ab6315ee8d2c734a9f1c6a 100644 (file)
@@ -53,6 +53,8 @@
 #include <dns/types.h>
 #include <dns/rdatastruct.h>
 
+#define DNS_RDATASET_MAXADDITIONAL 13
+
 ISC_LANG_BEGINDECLS
 
 typedef enum {
@@ -471,7 +473,8 @@ dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
 
 isc_result_t
 dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
-                           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.
@@ -490,10 +493,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 'limit' is non-zero and the number of the rdatasets is larger
+ *     than 'limit', no additional data will be processed.
+ *
  * 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 b42dea5cd370c8fa0183029782feb8090828e88c..75f07c9e579945294619b73259be9bcff7d25327 100644 (file)
@@ -28,6 +28,7 @@
 #include <dns/ncache.h>
 #include <dns/rdata.h>
 #include <dns/rdataset.h>
+#include <dns/result.h>
 
 static const char *trustnames[] = {
        "none",
@@ -607,7 +608,8 @@ dns_rdataset_towire(dns_rdataset_t *rdataset,
 
 isc_result_t
 dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
-                           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;
@@ -620,6 +622,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 a4e4f4c6f6a48af380b2ea66caecd0d2f41c0cbf..ed3d0b1b95ff07d5300e3e3daa09f6d7f21b93fa 100644 (file)
@@ -6472,7 +6472,7 @@ chase_additional(fetchctx_t *fctx, dns_message_t *rmessage) {
                                rdataset->attributes &= ~DNS_RDATASETATTR_CHASE;
                                (void)dns_rdataset_additionaldata(rdataset,
                                                                  check_related,
-                                                                 &chkarg);
+                                                                 &chkarg, 0);
                                rescan = true;
                        }
                }
@@ -7106,8 +7106,12 @@ noanswer_response(fetchctx_t *fctx, dns_message_t *message,
                FCTX_ATTR_SET(fctx, FCTX_ATTR_GLUING);
                chkarg.fctx = fctx;
                chkarg.rmessage = message;
+
+               /*
+                * Mark the glue records in the additional section to be cached.
+                */
                (void)dns_rdataset_additionaldata(ns_rdataset, check_related,
-                                                 &chkarg);
+                                                 &chkarg, 0);
 #if CHECK_FOR_GLUE_IN_ANSWER
                /*
                 * Look in the answer section for "glue" that is incorrectly
@@ -7123,7 +7127,7 @@ noanswer_response(fetchctx_t *fctx, dns_message_t *message,
                        chkarg.fcx = fctx;
                        chkarg.rmessage = message;
                        (void)dns_rdataset_additionaldata(ns_rdataset,
-                                                         check_answer, &chkarg);
+                                                         check_answer, &chkarg, 0);
                }
 #endif
                FCTX_ATTR_CLR(fctx, FCTX_ATTR_GLUING);
@@ -7365,7 +7369,7 @@ answer_response(fetchctx_t *fctx, dns_message_t *message) {
                        chkarg.rmessage = message;
                        (void)dns_rdataset_additionaldata(rdataset,
                                                          check_related,
-                                                         &chkarg);
+                                                         &chkarg, 0);
                }
        } else if (aname != NULL) {
                dns_chkarg_t chkarg;
@@ -7393,7 +7397,7 @@ answer_response(fetchctx_t *fctx, dns_message_t *message) {
                chkarg.fctx = fctx;
                chkarg.rmessage = message;
                (void)dns_rdataset_additionaldata(ardataset, check_related,
-                                                 &chkarg);
+                                                 &chkarg, 0);
                for (sigrdataset = ISC_LIST_HEAD(aname->list);
                     sigrdataset != NULL;
                     sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
@@ -7556,7 +7560,7 @@ answer_response(fetchctx_t *fctx, dns_message_t *message) {
                                        (void)dns_rdataset_additionaldata(
                                                        rdataset,
                                                        check_related,
-                                                       &chkarg);
+                                                       &chkarg, 0);
                                        done = true;
                                }
                        }