You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
5.0 KiB
152 lines
5.0 KiB
From ca6c3446ef07d89fd3a28b6979d947af2ab5754f Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
|
|
Date: Thu, 14 Nov 2024 10:37:29 +0100
|
|
Subject: [PATCH] Limit the additional processing for large RDATA sets
|
|
|
|
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)
|
|
PatchNumber: 47
|
|
---
|
|
bin/named/query.c | 14 ++++++++------
|
|
bin/tests/system/additional/tests.sh | 2 +-
|
|
lib/dns/include/dns/rdataset.h | 12 ++++++++++++
|
|
lib/dns/rdataset.c | 12 ++++++++++++
|
|
4 files changed, 33 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/bin/named/query.c b/bin/named/query.c
|
|
index 51a29a8..e023d74 100644
|
|
--- a/bin/named/query.c
|
|
+++ b/bin/named/query.c
|
|
@@ -1835,9 +1835,10 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
|
|
* section, it's helpful if we add the SRV additional data
|
|
* as well.
|
|
*/
|
|
- eresult = dns_rdataset_additionaldata(trdataset,
|
|
- query_addadditional,
|
|
- client);
|
|
+ eresult = dns_rdataset_additionaldata2(trdataset,
|
|
+ query_addadditional,
|
|
+ client,
|
|
+ DNS_RDATASET_MAXADDITIONAL);
|
|
}
|
|
|
|
cleanup:
|
|
@@ -2432,7 +2433,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;
|
|
|
|
/*
|
|
@@ -2442,8 +2443,9 @@ query_addrdataset(ns_client_t *client, dns_name_t *fname,
|
|
*/
|
|
additionalctx.client = client;
|
|
additionalctx.rdataset = rdataset;
|
|
- (void)dns_rdataset_additionaldata(rdataset, query_addadditional2,
|
|
- &additionalctx);
|
|
+ (void)dns_rdataset_additionaldata2(rdataset, query_addadditional2,
|
|
+ &additionalctx,
|
|
+ DNS_RDATASET_MAXADDITIONAL);
|
|
CTRACE(ISC_LOG_DEBUG(3), "query_addrdataset: done");
|
|
}
|
|
|
|
diff --git a/bin/tests/system/additional/tests.sh b/bin/tests/system/additional/tests.sh
|
|
index 6400723..a33cc8a 100644
|
|
--- a/bin/tests/system/additional/tests.sh
|
|
+++ b/bin/tests/system/additional/tests.sh
|
|
@@ -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
|
|
diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h
|
|
index 710e97c..b3532f6 100644
|
|
--- a/lib/dns/include/dns/rdataset.h
|
|
+++ b/lib/dns/include/dns/rdataset.h
|
|
@@ -53,6 +53,8 @@
|
|
#include <dns/types.h>
|
|
#include <dns/rdatastruct.h>
|
|
|
|
+#define DNS_RDATASET_MAXADDITIONAL 13
|
|
+
|
|
ISC_LANG_BEGINDECLS
|
|
|
|
typedef enum {
|
|
@@ -501,13 +503,23 @@ 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.
|
|
*/
|
|
|
|
+isc_result_t
|
|
+dns_rdataset_additionaldata2(dns_rdataset_t *rdataset,
|
|
+ dns_additionaldatafunc_t add, void *arg,
|
|
+ size_t limit);
|
|
+
|
|
isc_result_t
|
|
dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
|
|
dns_rdataset_t *neg, dns_rdataset_t *negsig);
|
|
diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c
|
|
index b42dea5..5160acf 100644
|
|
--- a/lib/dns/rdataset.c
|
|
+++ b/lib/dns/rdataset.c
|
|
@@ -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",
|
|
@@ -608,6 +609,13 @@ dns_rdataset_towire(dns_rdataset_t *rdataset,
|
|
isc_result_t
|
|
dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
|
|
dns_additionaldatafunc_t add, void *arg)
|
|
+{
|
|
+ return dns_rdataset_additionaldata2(rdataset, add, arg, 0);
|
|
+}
|
|
+
|
|
+isc_result_t
|
|
+dns_rdataset_additionaldata2(dns_rdataset_t *rdataset,
|
|
+ dns_additionaldatafunc_t add, void *arg, size_t limit)
|
|
{
|
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
|
isc_result_t result;
|
|
@@ -620,6 +628,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);
|
|
--
|
|
2.48.1
|
|
|