mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-22 18:17:05 -04:00
remove find_deepest_zonecut() from qpcache
because the cache no longer stores delegation (parent-side) NS rrsets, and authoritative (child-side) NS rrsets don't affect recursion, it no longer makes sense for qpcache_find() to look for NS rrsets and return DNS_R_DELEGATION. that code has been removed. the cache still does search for covering DNAME records. the check_zonecut() function has been renamed to check_dname() for clarity. related changes: - one test case has been removed from the mirror system test, because it tested the behavior of a cached delegation. - query_checkrrl() and rpz_rrset_find() have been updated so they no longer expect cache responses to have DNS_R_DELEGATION response codes.
This commit is contained in:
parent
f20a612ae7
commit
dc6202479f
4 changed files with 25 additions and 148 deletions
|
|
@ -332,27 +332,6 @@ grep "foo.example.*IN.*A.*127.0.0.1" dig.out.ns3.test$n >/dev/null || ret=1
|
|||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
n=$((n + 1))
|
||||
echo_i "checking that delegations from cache which improve mirror zone delegations are properly handled ($n)"
|
||||
ret=0
|
||||
# First, issue a recursive query in order to cache an RRset which is not within
|
||||
# the mirror zone's bailiwick.
|
||||
$DIG $DIGOPTS @10.53.0.3 sub.example. NS >dig.out.ns3.test$n.1 2>&1 || ret=1
|
||||
# Ensure the child-side NS RRset is returned.
|
||||
grep "NOERROR" dig.out.ns3.test$n.1 >/dev/null || ret=1
|
||||
grep "ANSWER: 2" dig.out.ns3.test$n.1 >/dev/null || ret=1
|
||||
grep "sub.example.*IN.*NS" dig.out.ns3.test$n.1 >/dev/null || ret=1
|
||||
# Issue a non-recursive query for something below the cached zone cut.
|
||||
$DIG $DIGOPTS @10.53.0.3 +norec foo.sub.example. A >dig.out.ns3.test$n.2 2>&1 || ret=1
|
||||
# Ensure the cached NS RRset is returned in a delegation, along with the
|
||||
# parent-side DS RRset.
|
||||
grep "NOERROR" dig.out.ns3.test$n.2 >/dev/null || ret=1
|
||||
grep "ANSWER: 0" dig.out.ns3.test$n.2 >/dev/null || ret=1
|
||||
grep "sub.example.*IN.*NS" dig.out.ns3.test$n.2 >/dev/null || ret=1
|
||||
grep "sub.example.*IN.*DS" dig.out.ns3.test$n.2 >/dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
n=$((n + 1))
|
||||
echo_i "checking flags set in a DNSKEY response sourced from a mirror zone ($n)"
|
||||
ret=0
|
||||
|
|
|
|||
|
|
@ -932,9 +932,8 @@ dns__db_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
* a zone cut. node, foundname,
|
||||
* and rdataset reference the
|
||||
* NS RRset of the zone cut.
|
||||
* If 'db' is a cache database,
|
||||
* then this is the deepest known
|
||||
* delegation.
|
||||
* This result can only occur
|
||||
* if 'db' is a zone database.
|
||||
*
|
||||
* \li #DNS_R_ZONECUT type == dns_rdatatype_any, and
|
||||
* the desired node is a zonecut.
|
||||
|
|
@ -963,12 +962,10 @@ dns__db_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
* the desired type does not.
|
||||
*
|
||||
* \li #ISC_R_NOTFOUND The desired name does not
|
||||
* exist, and no delegation could
|
||||
* be found. This result can only
|
||||
* exist. This result can only
|
||||
* occur if 'db' is a cache
|
||||
* database. The caller should
|
||||
* use its nameserver(s) of last
|
||||
* resort (e.g. root hints).
|
||||
* recurse for the data.
|
||||
*
|
||||
* \li #DNS_R_NCACHENXDOMAIN The desired name does not
|
||||
* exist. 'node' is bound to the
|
||||
|
|
|
|||
|
|
@ -1364,7 +1364,7 @@ find_headers(qpcnode_t *node, qpc_search_t *search, dns_rdatatype_t type,
|
|||
}
|
||||
|
||||
static isc_result_t
|
||||
check_zonecut(qpcnode_t *node, void *arg DNS__DB_FLARG) {
|
||||
check_dname(qpcnode_t *node, void *arg DNS__DB_FLARG) {
|
||||
qpc_search_t *search = arg;
|
||||
dns_slabheader_t *found = NULL, *foundsig = NULL;
|
||||
isc_result_t result;
|
||||
|
|
@ -1404,66 +1404,6 @@ check_zonecut(qpcnode_t *node, void *arg DNS__DB_FLARG) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
find_deepest_zonecut(qpc_search_t *search, qpcnode_t *node,
|
||||
dns_dbnode_t **nodep, dns_name_t *foundname,
|
||||
dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
|
||||
isc_result_t result = ISC_R_NOTFOUND;
|
||||
qpcache_t *qpdb = NULL;
|
||||
|
||||
/*
|
||||
* Caller must be holding the tree lock.
|
||||
*/
|
||||
|
||||
qpdb = search->qpdb;
|
||||
|
||||
for (int i = dns_qpchain_length(&search->chain) - 1; i >= 0; i--) {
|
||||
dns_slabheader_t *found = NULL, *foundsig = NULL;
|
||||
isc_rwlock_t *nlock = NULL;
|
||||
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
|
||||
|
||||
dns_qpchain_node(&search->chain, i, (void **)&node, NULL);
|
||||
nlock = &qpdb->buckets[node->locknum].lock;
|
||||
|
||||
NODE_RDLOCK(nlock, &nlocktype);
|
||||
|
||||
/*
|
||||
* Look for NS and RRSIG NS rdatasets.
|
||||
*/
|
||||
find_headers(node, search, dns_rdatatype_ns, &found, &foundsig);
|
||||
|
||||
if (found != NULL) {
|
||||
/*
|
||||
* If we have to set foundname, we do it before
|
||||
* anything else.
|
||||
*/
|
||||
if (foundname != NULL) {
|
||||
dns_name_copy(&node->name, foundname);
|
||||
}
|
||||
result = DNS_R_DELEGATION;
|
||||
if (nodep != NULL) {
|
||||
qpcnode_acquire(
|
||||
search->qpdb, node, nlocktype,
|
||||
isc_rwlocktype_none DNS__DB_FLARG_PASS);
|
||||
*nodep = (dns_dbnode_t *)node;
|
||||
}
|
||||
bindrdatasets(search->qpdb, node, found, foundsig,
|
||||
search->now, nlocktype,
|
||||
isc_rwlocktype_none, rdataset,
|
||||
sigrdataset DNS__DB_FLARG_PASS);
|
||||
}
|
||||
|
||||
NODE_UNLOCK(nlock, &nlocktype);
|
||||
|
||||
if (found != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for a potentially covering NSEC in the cache where `name`
|
||||
* is known not to exist. This uses the auxiliary NSEC tree to find
|
||||
|
|
@ -1594,14 +1534,13 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
bool cname_ok = true;
|
||||
bool found_noqname = false;
|
||||
bool all_negative = true;
|
||||
bool empty_node;
|
||||
bool empty_node = true;
|
||||
isc_rwlock_t *nlock = NULL;
|
||||
isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
|
||||
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
|
||||
dns_slabheader_t *found = NULL, *foundsig = NULL;
|
||||
dns_slabheader_t *nsheader = NULL, *nssig = NULL;
|
||||
dns_slabheader_t *nsecheader = NULL, *nsecsig = NULL;
|
||||
dns_typepair_t typepair;
|
||||
dns_typepair_t typepair = DNS_TYPEPAIR(type);
|
||||
|
||||
if (type == dns_rdatatype_none) {
|
||||
/* We can't search negative cache directly */
|
||||
|
|
@ -1626,8 +1565,8 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
}
|
||||
|
||||
/*
|
||||
* Check the QP chain to see if there's a node above us with a
|
||||
* active DNAME or NS rdatasets.
|
||||
* Check the QP chain to see if there's a node above us with an
|
||||
* active DNAME rdataset.
|
||||
*
|
||||
* We're only interested in nodes above QNAME, so if the result
|
||||
* was success, then we skip the last item in the chain.
|
||||
|
|
@ -1638,14 +1577,14 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
}
|
||||
|
||||
for (unsigned int i = 0; i < len; i++) {
|
||||
isc_result_t zcresult;
|
||||
isc_result_t tresult;
|
||||
qpcnode_t *encloser = NULL;
|
||||
|
||||
dns_qpchain_node(&search.chain, i, (void **)&encloser, NULL);
|
||||
|
||||
zcresult = check_zonecut(encloser,
|
||||
(void *)&search DNS__DB_FLARG_PASS);
|
||||
if (zcresult != DNS_R_CONTINUE) {
|
||||
tresult = check_dname(encloser,
|
||||
(void *)&search DNS__DB_FLARG_PASS);
|
||||
if (tresult != DNS_R_CONTINUE) {
|
||||
result = DNS_R_PARTIALMATCH;
|
||||
search.chain.len = i - 1;
|
||||
node = encloser;
|
||||
|
|
@ -1678,10 +1617,7 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
tlocktype DNS__DB_FLARG_PASS);
|
||||
goto tree_exit;
|
||||
} else {
|
||||
find_ns:
|
||||
result = find_deepest_zonecut(
|
||||
&search, node, nodep, foundname, rdataset,
|
||||
sigrdataset DNS__DB_FLARG_PASS);
|
||||
result = ISC_R_NOTFOUND;
|
||||
goto tree_exit;
|
||||
}
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
|
|
@ -1705,19 +1641,6 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
nlock = &search.qpdb->buckets[node->locknum].lock;
|
||||
NODE_RDLOCK(nlock, &nlocktype);
|
||||
|
||||
/*
|
||||
* These pointers need to be reset here in case we did
|
||||
* 'goto find_ns' from somewhere below.
|
||||
*/
|
||||
found = NULL;
|
||||
foundsig = NULL;
|
||||
typepair = DNS_TYPEPAIR(type);
|
||||
nsheader = NULL;
|
||||
nsecheader = NULL;
|
||||
nssig = NULL;
|
||||
nsecsig = NULL;
|
||||
empty_node = true;
|
||||
|
||||
DNS_SLABTOP_FOREACH(top, node->data) {
|
||||
dns_slabheader_t *header = NULL, *sigheader = NULL;
|
||||
if (DNS_TYPEPAIR_TYPE(top->typepair) == dns_rdatatype_rrsig) {
|
||||
|
|
@ -1799,12 +1722,6 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
}
|
||||
break;
|
||||
|
||||
case dns_rdatatype_ns:
|
||||
case DNS_SIGTYPEPAIR(dns_rdatatype_ns):
|
||||
nsheader = header;
|
||||
nssig = sigheader;
|
||||
break;
|
||||
|
||||
case dns_rdatatype_nsec:
|
||||
case DNS_SIGTYPEPAIR(dns_rdatatype_nsec):
|
||||
nsecheader = header;
|
||||
|
|
@ -1839,7 +1756,9 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
goto tree_exit;
|
||||
}
|
||||
}
|
||||
goto find_ns;
|
||||
|
||||
result = ISC_R_NOTFOUND;
|
||||
goto tree_exit;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1874,34 +1793,14 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
result = find_coveringnsec(
|
||||
&search, name, nodep, foundname, rdataset,
|
||||
sigrdataset DNS__DB_FLARG_PASS);
|
||||
if (result == DNS_R_COVERINGNSEC) {
|
||||
goto tree_exit;
|
||||
if (result != DNS_R_COVERINGNSEC) {
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
goto find_ns;
|
||||
goto tree_exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is an NS rdataset at this node, then this is the
|
||||
* deepest zone cut.
|
||||
*/
|
||||
if (nsheader != NULL) {
|
||||
if (nodep != NULL) {
|
||||
qpcnode_acquire(search.qpdb, node, nlocktype,
|
||||
tlocktype DNS__DB_FLARG_PASS);
|
||||
*nodep = (dns_dbnode_t *)node;
|
||||
}
|
||||
bindrdatasets(search.qpdb, node, nsheader, nssig,
|
||||
search.now, nlocktype, tlocktype,
|
||||
rdataset, sigrdataset DNS__DB_FLARG_PASS);
|
||||
result = DNS_R_DELEGATION;
|
||||
goto node_exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Go find the deepest zone cut.
|
||||
*/
|
||||
NODE_UNLOCK(nlock, &nlocktype);
|
||||
goto find_ns;
|
||||
result = ISC_R_NOTFOUND;
|
||||
goto node_exit;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -3146,6 +3146,8 @@ rpz_rrset_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type,
|
|||
if (result == ISC_R_NOTFOUND) {
|
||||
result = DNS_R_DELEGATION;
|
||||
}
|
||||
} else if (result == ISC_R_NOTFOUND && !is_zone) {
|
||||
result = DNS_R_DELEGATION;
|
||||
}
|
||||
rpz_clean(NULL, dbp, &node, NULL);
|
||||
if (result == DNS_R_DELEGATION) {
|
||||
|
|
@ -6815,7 +6817,7 @@ query_checkrrl(query_ctx_t *qctx, isc_result_t result) {
|
|||
if (qctx->view->rrl != NULL && !HAVECOOKIE(qctx->client) &&
|
||||
((qctx->fname != NULL && dns_name_isabsolute(qctx->fname)) ||
|
||||
(result == ISC_R_NOTFOUND && !RECURSIONOK(qctx->client))) &&
|
||||
!(result == DNS_R_DELEGATION && !qctx->is_zone &&
|
||||
!(result == ISC_R_NOTFOUND && !qctx->is_zone &&
|
||||
RECURSIONOK(qctx->client)) &&
|
||||
(qctx->client->query.rpz_st == NULL ||
|
||||
(qctx->client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0) &&
|
||||
|
|
|
|||
Loading…
Reference in a new issue