186 lines
5.6 KiB
Diff
186 lines
5.6 KiB
Diff
|
|
From 57cd34441a1b4ecc9874a4a106c2c95b8d7a3120 Mon Sep 17 00:00:00 2001
|
||
|
|
From: =?utf-8?b?T25kxZllaiBTdXLDvQ==?= <ondrej@isc.org>
|
||
|
|
Date: Mon, 17 Jun 2024 11:40:40 +0200
|
||
|
|
Subject: Be smarter about refusing to add many RR types to the database
|
||
|
|
|
||
|
|
Instead of outright refusing to add new RR types to the cache, be a bit
|
||
|
|
smarter:
|
||
|
|
|
||
|
|
1. If the new header type is in our priority list, we always add either
|
||
|
|
positive or negative entry at the beginning of the list.
|
||
|
|
|
||
|
|
2. If the new header type is negative entry, and we are over the limit,
|
||
|
|
we mark it as ancient immediately, so it gets evicted from the cache
|
||
|
|
as soon as possible.
|
||
|
|
|
||
|
|
3. Otherwise add the new header after the priority headers (or at the
|
||
|
|
head of the list).
|
||
|
|
|
||
|
|
4. If we are over the limit, evict the last entry on the normal header
|
||
|
|
list.
|
||
|
|
|
||
|
|
(cherry picked from commit 57cd34441a1b4ecc9874a4a106c2c95b8d7a3120)
|
||
|
|
|
||
|
|
Conflict:NA
|
||
|
|
Reference:https://gitlab.isc.org/isc-projects/bind9/-/commit/57cd34441a1b4ecc9874a4a106c2c95b8d7a3120
|
||
|
|
|
||
|
|
---
|
||
|
|
bind/bind-9.11.36/lib/dns/rbtdb.c | 71 +++++++++++++++++++++++++------
|
||
|
|
1 file changed, 59 insertions(+), 12 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/bind/bind-9.11.36/lib/dns/rbtdb.c b/bind/bind-9.11.36/lib/dns/rbtdb.c
|
||
|
|
index 0aed13c..d2c4097 100644
|
||
|
|
--- a/bind/bind-9.11.36/lib/dns/rbtdb.c
|
||
|
|
+++ b/bind/bind-9.11.36/lib/dns/rbtdb.c
|
||
|
|
@@ -6208,6 +6208,26 @@ update_recordsandbytes(bool add, rbtdb_version_t *rbtversion,
|
||
|
|
#define DNS_RBTDB_MAX_RTYPES 100
|
||
|
|
#endif /* DNS_RBTDB_MAX_RTYPES */
|
||
|
|
|
||
|
|
+static bool
|
||
|
|
+overmaxtype(dns_rbtdb_t *rbtdb, uint32_t ntypes) {
|
||
|
|
+ UNUSED(rbtdb);
|
||
|
|
+
|
||
|
|
+ if (DNS_RBTDB_MAX_RTYPES == 0) {
|
||
|
|
+ return (false);
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return (ntypes >= DNS_RBTDB_MAX_RTYPES);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static bool
|
||
|
|
+prio_header(rdatasetheader_t *header) {
|
||
|
|
+ if (NEGATIVE(header) && prio_type(RBTDB_RDATATYPE_EXT(header->type))) {
|
||
|
|
+ return (true);
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return (prio_type(header->type));
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
/*
|
||
|
|
* write lock on rbtnode must be held.
|
||
|
|
*/
|
||
|
|
@@ -6218,7 +6238,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||
|
|
{
|
||
|
|
rbtdb_changed_t *changed = NULL;
|
||
|
|
rdatasetheader_t *topheader, *topheader_prev, *header, *sigheader;
|
||
|
|
- rdatasetheader_t *prioheader = NULL;
|
||
|
|
+ rdatasetheader_t *prioheader = NULL, *expireheader = NULL;
|
||
|
|
unsigned char *merged;
|
||
|
|
isc_result_t result;
|
||
|
|
bool header_nx;
|
||
|
|
@@ -6228,7 +6248,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||
|
|
rbtdb_rdatatype_t negtype, sigtype;
|
||
|
|
dns_trust_t trust;
|
||
|
|
int idx;
|
||
|
|
- uint32_t ntypes;
|
||
|
|
+ uint32_t ntypes = 0;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Add an rdatasetheader_t to a node.
|
||
|
|
@@ -6291,7 +6311,6 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||
|
|
set_ttl(rbtdb, topheader, 0);
|
||
|
|
mark_stale_header(rbtdb, topheader);
|
||
|
|
}
|
||
|
|
- ntypes = 0;
|
||
|
|
goto find_header;
|
||
|
|
}
|
||
|
|
/*
|
||
|
|
@@ -6301,8 +6320,10 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||
|
|
for (topheader = rbtnode->data;
|
||
|
|
topheader != NULL;
|
||
|
|
topheader = topheader->next)
|
||
|
|
- if (topheader->type == sigtype)
|
||
|
|
+ if (topheader->type == sigtype) {
|
||
|
|
sigheader = topheader;
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
negtype = RBTDB_RDATATYPE_VALUE(covers, 0);
|
||
|
|
} else {
|
||
|
|
/*
|
||
|
|
@@ -6313,11 +6334,9 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||
|
|
* check for an extant non-stale NODATA ncache
|
||
|
|
* entry which covers the same type as the RRSIG.
|
||
|
|
*/
|
||
|
|
- ntypes = 0;
|
||
|
|
for (topheader = rbtnode->data;
|
||
|
|
topheader != NULL;
|
||
|
|
topheader = topheader->next) {
|
||
|
|
- ntypes++;
|
||
|
|
if ((topheader->type ==
|
||
|
|
RBTDB_RDATATYPE_NCACHEANY) ||
|
||
|
|
(newheader->type == sigtype &&
|
||
|
|
@@ -6361,12 +6380,16 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
- ntypes = 0;
|
||
|
|
for (topheader = rbtnode->data;
|
||
|
|
topheader != NULL;
|
||
|
|
topheader = topheader->next) {
|
||
|
|
- ntypes++;
|
||
|
|
- if (prio_type(topheader->type)) {
|
||
|
|
+ if (IS_CACHE(rbtdb) && ACTIVE(topheader, now)) {
|
||
|
|
+ ++ntypes;
|
||
|
|
+ expireheader = topheader;
|
||
|
|
+ } else if (!IS_CACHE(rbtdb)) {
|
||
|
|
+ ++ntypes;
|
||
|
|
+ }
|
||
|
|
+ if (prio_header(topheader)) {
|
||
|
|
prioheader = topheader;
|
||
|
|
}
|
||
|
|
if (topheader->type == newheader->type ||
|
||
|
|
@@ -6724,8 +6747,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||
|
|
/*
|
||
|
|
* No rdatasets of the given type exist at the node.
|
||
|
|
*/
|
||
|
|
-
|
||
|
|
- if (ntypes > DNS_RBTDB_MAX_RTYPES) {
|
||
|
|
+ if (!IS_CACHE(rbtdb) && overmaxtype(rbtdb, ntypes)) {
|
||
|
|
free_rdataset(rbtdb, rbtdb->common.mctx,
|
||
|
|
newheader);
|
||
|
|
return (ISC_R_QUOTA);
|
||
|
|
@@ -6733,7 +6755,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||
|
|
|
||
|
|
newheader->down = NULL;
|
||
|
|
|
||
|
|
- if (prio_type(newheader->type)) {
|
||
|
|
+ if (prio_header(newheader)) {
|
||
|
|
/* This is a priority type, prepend it */
|
||
|
|
newheader->next = rbtnode->data;
|
||
|
|
rbtnode->data = newheader;
|
||
|
|
@@ -6746,6 +6768,31 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||
|
|
newheader->next = rbtnode->data;
|
||
|
|
rbtnode->data = newheader;
|
||
|
|
}
|
||
|
|
+
|
||
|
|
+ if (IS_CACHE(rbtdb) && overmaxtype(rbtdb, ntypes)) {
|
||
|
|
+ if (expireheader == NULL) {
|
||
|
|
+ expireheader = newheader;
|
||
|
|
+ }
|
||
|
|
+ if (NEGATIVE(newheader) &&
|
||
|
|
+ !prio_header(newheader))
|
||
|
|
+ {
|
||
|
|
+ /*
|
||
|
|
+ * Add the new non-priority negative
|
||
|
|
+ * header to the database only
|
||
|
|
+ * temporarily.
|
||
|
|
+ */
|
||
|
|
+ expireheader = newheader;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ set_ttl(rbtdb, expireheader, 0);
|
||
|
|
+ mark_stale_header(rbtdb, expireheader);
|
||
|
|
+ /*
|
||
|
|
+ * FIXME: In theory, we should mark the RRSIG
|
||
|
|
+ * and the header at the same time, but there is
|
||
|
|
+ * no direct link between those two header, so
|
||
|
|
+ * we would have to check the whole list again.
|
||
|
|
+ */
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|