mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-04 00:25:29 +00:00
Clean up the search part in qpcache_find()
Slightly refactor the header search in qpcache_find(), so the scope level is reduced and the cname parts are logically grouped together.
This commit is contained in:
@@ -1315,59 +1315,55 @@ check_stale_header(qpcnode_t *node, dns_slabheader_t *header,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return true if we've found headers for both 'type' and RRSIG('type'),
|
||||||
|
* or (optionally, if 'negtype' is nonzero) if we've found a single
|
||||||
|
* negative header covering either 'negtype' or ANY.
|
||||||
|
*/
|
||||||
static bool
|
static bool
|
||||||
related_headers(dns_slabheader_t *header, dns_typepair_t type,
|
related_headers(dns_slabheader_t *header, dns_typepair_t type,
|
||||||
dns_typepair_t sigtype, dns_typepair_t negtype,
|
dns_typepair_t sigtype, dns_typepair_t negtype,
|
||||||
dns_slabheader_t **foundp, dns_slabheader_t **foundsigp) {
|
dns_slabheader_t **foundp, dns_slabheader_t **foundsigp,
|
||||||
|
bool *matchp) {
|
||||||
if (!EXISTS(header) || ANCIENT(header)) {
|
if (!EXISTS(header) || ANCIENT(header)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header->type == type) {
|
if (header->type == type) {
|
||||||
*foundp = header;
|
*foundp = header;
|
||||||
|
SET_IF_NOT_NULL(matchp, true);
|
||||||
if (*foundsigp != NULL) {
|
if (*foundsigp != NULL) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (header->type == sigtype) {
|
} else if (header->type == sigtype) {
|
||||||
*foundsigp = header;
|
*foundsigp = header;
|
||||||
|
SET_IF_NOT_NULL(matchp, true);
|
||||||
if (*foundp != NULL) {
|
if (*foundp != NULL) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} else if (negtype != 0 && (header->type == RDATATYPE_NCACHEANY ||
|
||||||
} else if (header->type == RDATATYPE_NCACHEANY ||
|
header->type == negtype))
|
||||||
header->type == negtype)
|
|
||||||
{
|
{
|
||||||
*foundp = header;
|
*foundp = header;
|
||||||
*foundsigp = NULL;
|
*foundsigp = NULL;
|
||||||
|
SET_IF_NOT_NULL(matchp, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return true if we've found headers for both 'type' and RRSIG('type').
|
||||||
|
*/
|
||||||
static bool
|
static bool
|
||||||
both_headers(dns_slabheader_t *header, dns_rdatatype_t type,
|
both_headers(dns_slabheader_t *header, dns_rdatatype_t type,
|
||||||
dns_slabheader_t **foundp, dns_slabheader_t **foundsigp) {
|
dns_slabheader_t **foundp, dns_slabheader_t **foundsigp) {
|
||||||
dns_typepair_t matchtype = DNS_TYPEPAIR_VALUE(type, 0);
|
dns_typepair_t matchtype = DNS_TYPEPAIR_VALUE(type, 0);
|
||||||
dns_typepair_t sigmatchtype = DNS_SIGTYPE(type);
|
dns_typepair_t sigmatchtype = DNS_SIGTYPE(type);
|
||||||
|
|
||||||
if (!EXISTS(header) || ANCIENT(header)) {
|
return related_headers(header, matchtype, sigmatchtype, 0, foundp,
|
||||||
return false;
|
foundsigp, NULL);
|
||||||
}
|
|
||||||
|
|
||||||
if (header->type == matchtype) {
|
|
||||||
*foundp = header;
|
|
||||||
if (*foundsigp != NULL) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (header->type == sigmatchtype) {
|
|
||||||
*foundsigp = header;
|
|
||||||
if (*foundp != NULL) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
@@ -1599,6 +1595,15 @@ find_coveringnsec(qpc_search_t *search, const dns_name_t *name,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MISSING_ANSWER(found, options) \
|
||||||
|
((found) == NULL || \
|
||||||
|
(DNS_TRUST_ADDITIONAL((found)->trust) && \
|
||||||
|
(((options) & DNS_DBFIND_ADDITIONALOK) == 0)) || \
|
||||||
|
((found)->trust == dns_trust_glue && \
|
||||||
|
(((options) & DNS_DBFIND_GLUEOK) == 0)) || \
|
||||||
|
(DNS_TRUST_PENDING((found)->trust) && \
|
||||||
|
(((options) & DNS_DBFIND_PENDINGOK) == 0)))
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
||||||
dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
|
dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
|
||||||
@@ -1753,91 +1758,92 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EXISTS(header) && !ANCIENT(header)) {
|
if (!EXISTS(header) || ANCIENT(header)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We now know that there is at least one active
|
||||||
|
* non-stale rdataset at this node.
|
||||||
|
*/
|
||||||
|
empty_node = false;
|
||||||
|
|
||||||
|
if (header->noqname != NULL &&
|
||||||
|
header->trust == dns_trust_secure)
|
||||||
|
{
|
||||||
|
found_noqname = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NEGATIVE(header)) {
|
||||||
|
all_negative = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool match = false;
|
||||||
|
if (related_headers(header, type, sigtype, negtype, &found,
|
||||||
|
&foundsig, &match) &&
|
||||||
|
!MISSING_ANSWER(found, options))
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* We now know that there is at least one active
|
* We can't exit early until we have an answer with
|
||||||
* non-stale rdataset at this node.
|
* sufficient trust level, see MISSING_ANSWER() macro
|
||||||
|
* for details, because we might need NS or NSEC
|
||||||
|
* records.
|
||||||
*/
|
*/
|
||||||
empty_node = false;
|
|
||||||
if (header->noqname != NULL &&
|
break;
|
||||||
header->trust == dns_trust_secure)
|
}
|
||||||
{
|
|
||||||
found_noqname = true;
|
if (match) {
|
||||||
}
|
/* We found something, continue with next header */
|
||||||
if (!NEGATIVE(header)) {
|
continue;
|
||||||
all_negative = false;
|
}
|
||||||
|
|
||||||
|
switch (header->type) {
|
||||||
|
case dns_rdatatype_cname:
|
||||||
|
if (!cname_ok) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
found = header;
|
||||||
* If we found a type we were looking for, remember
|
if (cnamesig != NULL) {
|
||||||
* it.
|
/* We already have CNAME signature */
|
||||||
*/
|
foundsig = cnamesig;
|
||||||
if (header->type == type ||
|
} else {
|
||||||
(type == dns_rdatatype_any &&
|
/* Look for CNAME signature instead */
|
||||||
DNS_TYPEPAIR_TYPE(header->type) != 0) ||
|
sigtype = DNS_SIGTYPE(dns_rdatatype_cname);
|
||||||
(cname_ok && header->type == dns_rdatatype_cname))
|
foundsig = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DNS_SIGTYPE(dns_rdatatype_cname):
|
||||||
|
if (!cname_ok) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cnamesig = header;
|
||||||
|
break;
|
||||||
|
case dns_rdatatype_ns:
|
||||||
|
/* Remember the NS rdataset */
|
||||||
|
nsheader = header;
|
||||||
|
break;
|
||||||
|
case DNS_SIGTYPE(dns_rdatatype_ns):
|
||||||
|
/* ...and its signature */
|
||||||
|
nssig = header;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dns_rdatatype_nsec:
|
||||||
|
nsecheader = header;
|
||||||
|
break;
|
||||||
|
case DNS_SIGTYPE(dns_rdatatype_nsec):
|
||||||
|
nsecsig = header;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (type == dns_rdatatype_any &&
|
||||||
|
DNS_TYPEPAIR_TYPE(header->type) != 0)
|
||||||
{
|
{
|
||||||
/*
|
/* QTYPE==ANY, so any anwers will do */
|
||||||
* We've found the answer.
|
|
||||||
*/
|
|
||||||
found = header;
|
found = header;
|
||||||
if (header->type == dns_rdatatype_cname &&
|
break;
|
||||||
cname_ok)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If we've already got the
|
|
||||||
* CNAME RRSIG, use it.
|
|
||||||
*/
|
|
||||||
if (cnamesig != NULL) {
|
|
||||||
foundsig = cnamesig;
|
|
||||||
} else {
|
|
||||||
sigtype = DNS_SIGTYPE(
|
|
||||||
dns_rdatatype_cname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (header->type == sigtype) {
|
|
||||||
/*
|
|
||||||
* We've found the RRSIG rdataset for our
|
|
||||||
* target type. Remember it.
|
|
||||||
*/
|
|
||||||
foundsig = header;
|
|
||||||
} else if (header->type == RDATATYPE_NCACHEANY ||
|
|
||||||
header->type == negtype)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We've found a negative cache entry.
|
|
||||||
*/
|
|
||||||
found = header;
|
|
||||||
} else 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.
|
|
||||||
*/
|
|
||||||
nsheader = header;
|
|
||||||
} else if (header->type ==
|
|
||||||
DNS_SIGTYPE(dns_rdatatype_ns))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If we need the NS rdataset, we'll also
|
|
||||||
* need its signature.
|
|
||||||
*/
|
|
||||||
nssig = header;
|
|
||||||
} else if (header->type == dns_rdatatype_nsec) {
|
|
||||||
nsecheader = header;
|
|
||||||
} else if (header->type ==
|
|
||||||
DNS_SIGTYPE(dns_rdatatype_nsec))
|
|
||||||
{
|
|
||||||
nsecsig = header;
|
|
||||||
} else if (cname_ok &&
|
|
||||||
header->type ==
|
|
||||||
DNS_SIGTYPE(dns_rdatatype_cname))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If we get a CNAME match, we'll also need
|
|
||||||
* its signature.
|
|
||||||
*/
|
|
||||||
cnamesig = header;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1863,14 +1869,7 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||||||
/*
|
/*
|
||||||
* If we didn't find what we were looking for...
|
* If we didn't find what we were looking for...
|
||||||
*/
|
*/
|
||||||
if (found == NULL ||
|
if (MISSING_ANSWER(found, options)) {
|
||||||
(DNS_TRUST_ADDITIONAL(found->trust) &&
|
|
||||||
((options & DNS_DBFIND_ADDITIONALOK) == 0)) ||
|
|
||||||
(found->trust == dns_trust_glue &&
|
|
||||||
((options & DNS_DBFIND_GLUEOK) == 0)) ||
|
|
||||||
(DNS_TRUST_PENDING(found->trust) &&
|
|
||||||
((options & DNS_DBFIND_PENDINGOK) == 0)))
|
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* Return covering NODATA NSEC record.
|
* Return covering NODATA NSEC record.
|
||||||
*/
|
*/
|
||||||
@@ -2195,7 +2194,7 @@ qpcache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (related_headers(header, matchtype, sigmatchtype, negtype,
|
if (related_headers(header, matchtype, sigmatchtype, negtype,
|
||||||
&found, &foundsig))
|
&found, &foundsig, NULL))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user