mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-27 12:13:20 -04:00
fix the cache findzonecut implementation
the search for the deepest known zone cut in the cache could
improperly reject a node containing stale data, even if the
NS rdataset wasn't the data that was stale.
this change also improves the efficiency of the search by
stopping it when both NS and RRSIG(NS) have been found.
(cherry picked from commit 1f095b902c)
This commit is contained in:
parent
0987d28643
commit
291d0d8d90
2 changed files with 31 additions and 31 deletions
|
|
@ -318,7 +318,7 @@ $DIG $DIGOPTS -x 2001:4f8::1 @10.53.0.6 >dig.out.test$n || ret=1
|
|||
grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
|
||||
grep "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa. 1 IN PTR nee.com." dig.out.test$n >/dev/null || ret=1
|
||||
sleep 1
|
||||
grep -v ADDR ans2/query.log >ans2/query.log.trimmed
|
||||
grep -F "ip6.arpa." ans2/query.log >ans2/query.log.trimmed
|
||||
cat <<__EOF | diff ans2/query.log.trimmed - >/dev/null || ret=1
|
||||
NS 1.0.0.2.ip6.arpa.
|
||||
NS 8.f.4.0.1.0.0.2.ip6.arpa.
|
||||
|
|
@ -493,18 +493,22 @@ n=$((n + 1))
|
|||
echo_i "query for .stale is properly minimized when qname-minimization is in strict mode (stale cache) ($n)"
|
||||
ret=0
|
||||
$CLEANQL
|
||||
$RNDCCMD 10.53.0.6 flush
|
||||
$DIG $DIGOPTS @10.53.0.6 txt a.b.stale. >dig.out.test$n || ret=1
|
||||
grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
|
||||
grep "a\.b\.stale\..*1.*IN.*TXT.*hooray" dig.out.test$n >/dev/null || ret=1
|
||||
sleep 1
|
||||
sort ans2/query.log >ans2/query.log.sorted
|
||||
cat <<__EOF | diff ans2/query.log.sorted - >/dev/null || ret=1
|
||||
ADDR ns.b.stale.
|
||||
ADDR ns2.stale.
|
||||
NS b.stale.
|
||||
NS stale.
|
||||
__EOF
|
||||
test -f ans3/query.log && ret=1
|
||||
sort ans4/query.log >ans4/query.log.sorted
|
||||
cat <<__EOF | diff ans4/query.log.sorted - >/dev/null || ret=1
|
||||
ADDR ns.b.stale.
|
||||
NS b.stale.
|
||||
TXT a.b.stale.
|
||||
__EOF
|
||||
|
|
@ -516,17 +520,21 @@ n=$((n + 1))
|
|||
echo_i "query for .stale is properly minimized when qname-minimization is in relaxed mode (stale cache) ($n)"
|
||||
ret=0
|
||||
$CLEANQL
|
||||
$RNDCCMD 10.53.0.7 flush
|
||||
$DIG $DIGOPTS @10.53.0.7 txt a.b.stale. >dig.out.test$n || ret=1
|
||||
grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
|
||||
grep "a\.b\.stale\..*1.*IN.*TXT.*hooray" dig.out.test$n >/dev/null || ret=1
|
||||
sleep 1
|
||||
sort ans2/query.log >ans2/query.log.sorted
|
||||
cat <<__EOF | diff ans2/query.log.sorted - >/dev/null || ret=1
|
||||
ADDR ns.b.stale.
|
||||
ADDR ns2.stale.
|
||||
NS b.stale.
|
||||
__EOF
|
||||
test -f ans3/query.log && ret=1
|
||||
sort ans4/query.log >ans4/query.log.sorted
|
||||
cat <<__EOF | diff ans4/query.log.sorted - >/dev/null || ret=1
|
||||
ADDR ns.b.stale.
|
||||
TXT a.b.stale.
|
||||
__EOF
|
||||
for ans in ans2 ans3 ans4; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null || true; done
|
||||
|
|
|
|||
|
|
@ -5519,43 +5519,33 @@ cache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
|||
header_prev = NULL;
|
||||
for (header = node->data; header != NULL; header = header_next) {
|
||||
header_next = header->next;
|
||||
bool ns = (header->type == dns_rdatatype_ns ||
|
||||
header->type == RBTDB_RDATATYPE_SIGNS);
|
||||
if (check_stale_header(node, header, &locktype, lock, &search,
|
||||
&header_prev))
|
||||
{
|
||||
/*
|
||||
* The function dns_rbt_findnode found us the a matching
|
||||
* node for 'name' and stored the result in 'dcname'.
|
||||
* This is the deepest known zonecut in our database.
|
||||
* However, this node may be stale and if serve-stale
|
||||
* is not enabled (in other words 'stale-answer-enable'
|
||||
* is set to no), this node may not be used as a
|
||||
* zonecut we know about. If so, find the deepest
|
||||
* zonecut from this node up and return that instead.
|
||||
*/
|
||||
NODE_UNLOCK(lock, locktype);
|
||||
result = find_deepest_zonecut(&search, node, nodep,
|
||||
foundname, rdataset,
|
||||
sigrdataset);
|
||||
dns_name_copy(foundname, dcname);
|
||||
goto tree_exit;
|
||||
if (ns) {
|
||||
/*
|
||||
* We found a cached NS, but it was either
|
||||
* ancient or it was stale and serve-stale
|
||||
* is disabled, so this node can't be used
|
||||
* as a zone cut we know about. Instead we
|
||||
* bail out and call find_deepest_zonecut()
|
||||
* below.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
} else if (EXISTS(header) && !ANCIENT(header)) {
|
||||
/*
|
||||
* If we found a type we were looking for, remember
|
||||
* it.
|
||||
*/
|
||||
if (header->type == dns_rdatatype_ns) {
|
||||
/*
|
||||
* Remember a NS rdataset even if we're
|
||||
* not specifically looking for it, because
|
||||
* we might need it later.
|
||||
*/
|
||||
found = header;
|
||||
if (foundsig != NULL) {
|
||||
break;
|
||||
}
|
||||
} else if (header->type == RBTDB_RDATATYPE_SIGNS) {
|
||||
/*
|
||||
* If we need the NS rdataset, we'll also
|
||||
* need its signature.
|
||||
*/
|
||||
foundsig = header;
|
||||
if (found != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
header_prev = header;
|
||||
} else {
|
||||
|
|
@ -5565,11 +5555,13 @@ cache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
|||
|
||||
if (found == NULL) {
|
||||
/*
|
||||
* No NS records here.
|
||||
* No active NS records found. Call find_deepest_zonecut()
|
||||
* to look for them in nodes above this one.
|
||||
*/
|
||||
NODE_UNLOCK(lock, locktype);
|
||||
result = find_deepest_zonecut(&search, node, nodep, foundname,
|
||||
rdataset, sigrdataset);
|
||||
dns_name_copy(foundname, dcname);
|
||||
goto tree_exit;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue