2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

split out helper functions

- fctx_setresult() sets the event result in a fetch response
  according to the rdataset being returned - DNS_R_NCACHENXDOMAIN or
  DNS_R_NXRRSET for negative responses, ISC_R_SUCCESS, DNS_R_CNAME,
  or DNS_R_DNAME for positive ones.
- cache_rrset() looks up a node and adds an rdataset.
- delete_rrset() looks up a node and removes rdatasets of a specified
  type and, optionally, the associated signatures.
- gettrust() returns the trust level of an rdataset, or dns_trust_none
  if the rdataset is NULL or not associated.
- getrrsig() scans the rdatasets associated with a name for the
  RRSIG covering a given type.
This commit is contained in:
Evan Hunt
2025-03-02 01:24:08 -08:00
committed by Ondřej Surý
parent 723d167f26
commit 9f674c43cf

View File

@@ -665,7 +665,7 @@ fctx_destroy(fetchctx_t *fctx);
static isc_result_t
negcache(dns_message_t *message, fetchctx_t *fctx, const dns_name_t *name,
isc_stdtime_t now, bool optout, bool secure, dns_rdataset_t *added,
dns_dbnode_t **nodep, isc_result_t *eresultp);
dns_dbnode_t **nodep);
static void
validated(void *arg);
static void
@@ -5175,69 +5175,183 @@ has_000_label(dns_rdataset_t *nsecset) {
return false;
}
static isc_result_t
fctx_setresult(fetchctx_t *fctx, dns_rdataset_t *rdataset) {
isc_result_t eresult = ISC_R_SUCCESS;
if (NEGATIVE(rdataset)) {
eresult = NXDOMAIN(rdataset) ? DNS_R_NCACHENXDOMAIN
: DNS_R_NCACHENXRRSET;
} else if (eresult == ISC_R_SUCCESS && rdataset->type != fctx->type) {
switch (rdataset->type) {
case dns_rdatatype_cname:
eresult = DNS_R_CNAME;
break;
case dns_rdatatype_dname:
eresult = DNS_R_DNAME;
break;
default:
break;
}
}
return eresult;
}
static inline dns_trust_t
gettrust(dns_rdataset_t *rdataset) {
if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
return dns_trust_none;
}
return rdataset->trust;
}
static inline dns_rdataset_t *
getrrsig(dns_name_t *name, dns_rdatatype_t type) {
for (dns_rdataset_t *sig = ISC_LIST_HEAD(name->list); sig != NULL;
sig = ISC_LIST_NEXT(sig, link))
{
if (dns_rdataset_issigtype(sig, type)) {
return sig;
}
}
return NULL;
}
static isc_result_t
cache_rrset(fetchctx_t *fctx, isc_stdtime_t now, dns_name_t *name,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
dns_dbnode_t **nodep, dns_rdataset_t *added,
dns_rdataset_t *addedsig) {
isc_result_t result = ISC_R_SUCCESS;
unsigned int options = 0;
dns_dbnode_t *node = NULL;
if (rdataset == NULL) {
return ISC_R_NOTFOUND;
}
/*
* If the trust level is glue, we must be caching a referral.
* New referral data always takes precedence over the existing
* cache contents. We also force a cache update if the fctx
* has the _NOCACHED option.
*/
if ((gettrust(rdataset) == dns_trust_glue &&
dns_rdataset_matchestype(rdataset, dns_rdatatype_ns)) ||
(fctx->options & DNS_FETCHOPT_NOCACHED) != 0)
{
options = DNS_DBADD_FORCE;
} else if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) {
options = DNS_DBADD_PREFETCH;
}
/*
* If the node pointer points to a node, attach to it.
*
* If it points to NULL, find or create the node and pass
* it back to the caller.
*
* If there's no node pointer at all, find the node, but
* detach it before returning.
*/
if (nodep != NULL && *nodep != NULL) {
dns_db_attachnode(fctx->cache, *nodep, &node);
} else {
result = dns_db_findnode(fctx->cache, name, true, &node);
}
if (result == ISC_R_SUCCESS) {
result = dns_db_addrdataset(fctx->cache, node, NULL, now,
rdataset, options, added);
}
if ((result == ISC_R_SUCCESS || result == DNS_R_UNCHANGED) &&
sigrdataset != NULL)
{
result = dns_db_addrdataset(fctx->cache, node, NULL, now,
sigrdataset, options, addedsig);
if (result == DNS_R_UNCHANGED) {
result = ISC_R_SUCCESS;
}
}
/*
* If we're passing a node that we looked up back to the
* caller, then we don't detach it.
*/
if (nodep != NULL && *nodep == NULL) {
*nodep = node;
} else if (node != NULL) {
dns_db_detachnode(fctx->cache, &node);
}
return result;
}
static void
delete_rrset(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type,
bool delrrsig) {
isc_result_t result;
dns_dbnode_t *node = NULL;
result = dns_db_findnode(fctx->cache, name, false, &node);
if (result == ISC_R_SUCCESS) {
dns_db_deleterdataset(fctx->cache, node, NULL, type, 0);
if (delrrsig) {
dns_db_deleterdataset(fctx->cache, node, NULL,
dns_rdatatype_rrsig, type);
}
}
if (node != NULL) {
dns_db_detachnode(fctx->cache, &node);
}
}
/*
* The validator has finished.
*/
static void
validated(void *arg) {
isc_result_t result = ISC_R_SUCCESS;
dns_validator_t *val = (dns_validator_t *)arg;
dns_valarg_t *valarg = val->arg;
dns_validator_t *nextval = NULL;
dns_adbaddrinfo_t *addrinfo = NULL;
dns_dbnode_t *node = NULL;
dns_dbnode_t *nsnode = NULL;
dns_fetchresponse_t *resp = NULL;
dns_rdataset_t *ardataset = NULL;
dns_rdataset_t *asigrdataset = NULL;
dns_resolver_t *res = NULL;
dns_valarg_t *valarg = NULL;
fetchctx_t *fctx = NULL;
bool chaining;
bool negative;
bool sentresponse;
isc_result_t eresult = ISC_R_SUCCESS;
isc_result_t result = ISC_R_SUCCESS;
isc_stdtime_t now;
unsigned int options = 0;
dns_fixedname_t fwild;
dns_name_t *wild = NULL;
dns_rdataset_t *ardataset = NULL, *asigrdataset = NULL;
dns_message_t *message = NULL;
bool done = false;
valarg = val->arg;
REQUIRE(VALID_FCTX(valarg->fctx));
REQUIRE(!ISC_LIST_EMPTY(valarg->fctx->validators));
fetchctx_t *fctx = NULL;
dns_resolver_t *res = NULL;
isc_stdtime_t now;
bool sentresponse, done = false;
bool negative = (val->rdataset == NULL);
bool chaining = (val->result == ISC_R_SUCCESS) && !negative &&
CHAINING(val->rdataset);
fctx = valarg->fctx;
valarg->fctx = NULL;
REQUIRE(VALID_FCTX(fctx));
REQUIRE(fctx->tid == isc_tid());
FCTXTRACE("received validation completion event");
res = fctx->res;
addrinfo = valarg->addrinfo;
message = val->message;
fctx->vresult = val->result;
FCTXTRACE("received validation completion event");
LOCK(&fctx->lock);
ISC_LIST_UNLINK(fctx->validators, val, link);
UNLOCK(&fctx->lock);
/*
* Destroy the validator early so that we can
* destroy the fctx if necessary. Save the wildcard name.
*/
if (val->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) {
wild = dns_fixedname_initname(&fwild);
dns_name_copy(dns_fixedname_name(&val->wild), wild);
}
isc_mem_put(fctx->mctx, valarg, sizeof(*valarg));
negative = (val->rdataset == NULL);
LOCK(&fctx->lock);
sentresponse = ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0);
@@ -5247,30 +5361,11 @@ validated(void *arg) {
* events; if so, destroy the fctx.
*/
if (SHUTTINGDOWN(fctx) && !sentresponse) {
UNLOCK(&fctx->lock);
goto cleanup_fetchctx;
goto unlock;
}
now = isc_stdtime_now();
/*
* If chaining, we need to make sure that the right result code
* is returned, and that the rdatasets are bound.
*/
if (val->result == ISC_R_SUCCESS && !negative &&
val->rdataset != NULL && CHAINING(val->rdataset))
{
if (val->rdataset->type == dns_rdatatype_cname) {
eresult = DNS_R_CNAME;
} else {
INSIST(val->rdataset->type == dns_rdatatype_dname);
eresult = DNS_R_DNAME;
}
chaining = true;
} else {
chaining = false;
}
/*
* Either we're not shutting down, or we are shutting down but
* want to cache the result anyway (if this was a validation
@@ -5297,53 +5392,20 @@ validated(void *arg) {
fctx->valfail++;
fctx->vresult = val->result;
if (fctx->vresult != DNS_R_BROKENCHAIN) {
result = ISC_R_NOTFOUND;
if (val->rdataset != NULL) {
result = dns_db_findnode(fctx->cache, val->name,
false, &node);
delete_rrset(fctx, val->name, val->type,
(val->sigrdataset != NULL));
}
if (result == ISC_R_SUCCESS) {
(void)dns_db_deleterdataset(fctx->cache, node,
NULL, val->type, 0);
}
if (result == ISC_R_SUCCESS && val->sigrdataset != NULL)
{
(void)dns_db_deleterdataset(
fctx->cache, node, NULL,
dns_rdatatype_rrsig, val->type);
}
if (result == ISC_R_SUCCESS) {
dns_db_detachnode(fctx->cache, &node);
}
}
if (fctx->vresult == DNS_R_BROKENCHAIN && !negative) {
} else if (!negative) {
/*
* Cache the data as pending for later
* validation.
*/
result = ISC_R_NOTFOUND;
if (val->rdataset != NULL) {
result = dns_db_findnode(fctx->cache, val->name,
true, &node);
}
if (result == ISC_R_SUCCESS) {
(void)dns_db_addrdataset(
fctx->cache, node, NULL, now,
val->rdataset, 0, NULL);
}
if (result == ISC_R_SUCCESS && val->sigrdataset != NULL)
{
(void)dns_db_addrdataset(
fctx->cache, node, NULL, now,
val->sigrdataset, 0, NULL);
}
if (result == ISC_R_SUCCESS) {
dns_db_detachnode(fctx->cache, &node);
}
cache_rrset(fctx, now, val->name, val->rdataset,
val->sigrdataset, NULL, NULL, NULL);
}
result = fctx->vresult;
add_bad(fctx, message, addrinfo, result, badns_validation);
add_bad(fctx, message, addrinfo, result, badns_validation);
UNLOCK(&fctx->lock);
nextval = ISC_LIST_HEAD(fctx->validators);
@@ -5369,16 +5431,15 @@ validated(void *arg) {
inc_stats(res, dns_resstatscounter_valnegsuccess);
result = negcache(message, fctx, val->name, now, val->optout,
val->secure, ardataset, &node, &eresult);
val->secure, ardataset, &node);
if (result != ISC_R_SUCCESS) {
goto noanswer_response;
}
goto answer_response;
} else {
inc_stats(res, dns_resstatscounter_valsuccess);
}
FCTXTRACE("validation OK");
inc_stats(res, dns_resstatscounter_valsuccess);
if (val->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) {
result = dns_rdataset_addnoqname(
@@ -5392,42 +5453,21 @@ validated(void *arg) {
val->proofs[DNS_VALIDATOR_CLOSESTENCLOSER]);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
}
} else if (val->rdataset->trust == dns_trust_answer) {
} else if (gettrust(val->rdataset) == dns_trust_answer) {
findnoqname(fctx, message, val->name, val->rdataset);
}
/*
* The data was already cached as pending data.
* Re-cache it as secure and bind the cached
* rdatasets to the first event on the fetch
* event list.
* The data was already cached as pending data. Re-cache it as
* secure and bind the cached rdatasets to the first event on the
* fetch event list.
*/
result = dns_db_findnode(fctx->cache, val->name, true, &node);
result = cache_rrset(fctx, now, val->name, val->rdataset,
val->sigrdataset, &node, ardataset, asigrdataset);
if (result != ISC_R_SUCCESS) {
goto noanswer_response;
}
if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) {
options = DNS_DBADD_PREFETCH;
}
result = dns_db_addrdataset(fctx->cache, node, NULL, now, val->rdataset,
options, ardataset);
if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) {
goto noanswer_response;
}
if (ardataset != NULL && NEGATIVE(ardataset)) {
eresult = NXDOMAIN(ardataset) ? DNS_R_NCACHENXDOMAIN
: DNS_R_NCACHENXRRSET;
} else if (val->sigrdataset != NULL) {
result = dns_db_addrdataset(fctx->cache, node, NULL, now,
val->sigrdataset, options,
asigrdataset);
if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) {
goto noanswer_response;
}
}
if (sentresponse) {
/*
* If we only deferred the destroy because we wanted to
@@ -5437,8 +5477,7 @@ validated(void *arg) {
if (SHUTTINGDOWN(fctx)) {
maybe_cancel_validators(fctx);
}
UNLOCK(&fctx->lock);
goto cleanup_fetchctx;
goto unlock;
}
if (!ISC_LIST_EMPTY(fctx->validators)) {
@@ -5456,7 +5495,6 @@ validated(void *arg) {
}
answer_response:
/*
* Cache any SOA/NS/NSEC records that happened to be validated.
*/
@@ -5467,23 +5505,14 @@ answer_response:
if ((rdataset->type != dns_rdatatype_ns &&
rdataset->type != dns_rdatatype_soa &&
rdataset->type != dns_rdatatype_nsec) ||
rdataset->trust != dns_trust_secure)
gettrust(rdataset) != dns_trust_secure)
{
continue;
}
ISC_LIST_FOREACH (name->list, s, link) {
if (dns_rdataset_issigtype(sigrdataset,
rdataset->type))
{
sigrdataset = s;
break;
}
}
sigrdataset = getrrsig(name, rdataset->type);
if (sigrdataset == NULL ||
sigrdataset->trust != dns_trust_secure)
{
if (gettrust(sigrdataset) != dns_trust_secure) {
continue;
}
@@ -5525,21 +5554,11 @@ answer_response:
continue;
}
result = dns_db_findnode(fctx->cache, name, true,
&nsnode);
if (result != ISC_R_SUCCESS) {
continue;
}
result = dns_db_addrdataset(fctx->cache, nsnode, NULL,
now, rdataset, 0, NULL);
if (result == ISC_R_SUCCESS) {
result = dns_db_addrdataset(
fctx->cache, nsnode, NULL, now,
sigrdataset, 0, NULL);
}
dns_db_detachnode(fctx->cache, &nsnode);
if (result != ISC_R_SUCCESS) {
result = cache_rrset(fctx, now, name, rdataset,
sigrdataset, NULL, NULL, NULL);
if (result != ISC_R_SUCCESS &&
result != DNS_R_UNCHANGED)
{
continue;
}
}
@@ -5548,78 +5567,40 @@ answer_response:
/*
* Add the wild card entry.
*/
if (val->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL &&
val->rdataset != NULL && dns_rdataset_isassociated(val->rdataset) &&
val->rdataset->trust == dns_trust_secure &&
val->sigrdataset != NULL &&
dns_rdataset_isassociated(val->sigrdataset) &&
val->sigrdataset->trust == dns_trust_secure && wild != NULL)
gettrust(val->rdataset) == dns_trust_secure &&
gettrust(val->sigrdataset) == dns_trust_secure)
{
dns_dbnode_t *wnode = NULL;
result = dns_db_findnode(fctx->cache, wild, true, &wnode);
if (result == ISC_R_SUCCESS) {
result = dns_db_addrdataset(fctx->cache, wnode, NULL,
now, val->rdataset, 0,
NULL);
}
if (result == ISC_R_SUCCESS) {
(void)dns_db_addrdataset(fctx->cache, wnode, NULL, now,
val->sigrdataset, 0, NULL);
}
if (wnode != NULL) {
dns_db_detachnode(fctx->cache, &wnode);
}
}
result = ISC_R_SUCCESS;
if (HAVE_ANSWER(fctx) || resp == NULL) {
goto noanswer_response;
cache_rrset(fctx, now, dns_fixedname_name(&val->wild),
val->rdataset, val->sigrdataset, NULL, NULL, NULL);
}
/*
* Respond with an answer, positive or negative,
* as opposed to an error. 'node' must be non-NULL.
* Respond with an answer, positive or negative, as
* opposed to an error.
*/
FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER);
INSIST(resp->rdataset != NULL);
if (dns_rdataset_isassociated(resp->rdataset)) {
if (NEGATIVE(resp->rdataset)) {
INSIST(eresult == DNS_R_NCACHENXDOMAIN ||
eresult == DNS_R_NCACHENXRRSET);
} else if (eresult == ISC_R_SUCCESS &&
resp->rdataset->type != fctx->type)
{
switch (resp->rdataset->type) {
case dns_rdatatype_cname:
eresult = DNS_R_CNAME;
break;
case dns_rdatatype_dname:
eresult = DNS_R_DNAME;
break;
default:
break;
}
}
}
resp->result = eresult;
INSIST(resp != NULL && resp->rdataset != NULL);
resp->result = fctx_setresult(fctx, resp->rdataset);
dns_name_copy(val->name, resp->foundname);
dns_db_attach(fctx->cache, &resp->db);
dns_db_transfernode(fctx->cache, &node, &resp->node);
clone_results(fctx);
result = ISC_R_SUCCESS;
noanswer_response:
if (node != NULL) {
dns_db_detachnode(fctx->cache, &node);
}
UNLOCK(&fctx->lock);
done = true;
unlock:
UNLOCK(&fctx->lock);
cleanup_fetchctx:
if (done) {
fctx_done_unref(fctx, result);
@@ -5676,13 +5657,7 @@ findnoqname(fetchctx_t *fctx, dns_message_t *message, dns_name_t *name,
/*
* Find the SIG for this rdataset, if we have it.
*/
ISC_LIST_FOREACH (name->list, sig, link) {
if (dns_rdataset_issigtype(sig, type)) {
sigrdataset = sig;
break;
}
}
sigrdataset = getrrsig(name, type);
if (sigrdataset == NULL) {
return;
}
@@ -5753,12 +5728,7 @@ findnoqname(fetchctx_t *fctx, dns_message_t *message, dns_name_t *name,
}
if (noqname != NULL) {
ISC_LIST_FOREACH (noqname->list, sig, link) {
if (dns_rdataset_issigtype(sig, found)) {
sigrdataset = sig;
break;
}
}
sigrdataset = getrrsig(noqname, found);
if (sigrdataset == NULL) {
noqname = NULL;
}
@@ -5852,7 +5822,6 @@ rctx_cache_secure(respctx_t *rctx, dns_message_t *message, dns_name_t *name,
resquery_t *query = rctx->query;
dns_rdataset_t *ardataset = NULL, *asigset = NULL;
dns_fetchresponse_t *resp = ISC_LIST_HEAD(fctx->resps);
unsigned int options = 0;
/*
* RRSIGs are validated as part of validating the type they cover.
@@ -5926,15 +5895,13 @@ rctx_cache_secure(respctx_t *rctx, dns_message_t *message, dns_name_t *name,
}
}
if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) {
options = DNS_DBADD_PREFETCH;
}
if ((fctx->options & DNS_FETCHOPT_NOCACHED) != 0) {
options |= DNS_DBADD_FORCE;
}
result = dns_db_addrdataset(fctx->cache, node, NULL, rctx->now,
rdataset, options, ardataset);
/*
* In this case we cache the rdataset and sigrdataset
* (if any) in two steps, so we can do an extra check
* in-between.
*/
result = cache_rrset(fctx, rctx->now, name, rdataset, NULL,
&node, ardataset, NULL);
if (result != DNS_R_UNCHANGED && result != ISC_R_SUCCESS) {
return result;
}
@@ -5957,8 +5924,8 @@ rctx_cache_secure(respctx_t *rctx, dns_message_t *message, dns_name_t *name,
return ISC_R_SUCCESS;
}
result = dns_db_addrdataset(fctx->cache, node, NULL, rctx->now,
sigrdataset, options, asigset);
result = cache_rrset(fctx, rctx->now, name, sigrdataset, NULL,
&node, asigset, NULL);
if (result != DNS_R_UNCHANGED && result != ISC_R_SUCCESS) {
return result;
}
@@ -5990,21 +5957,6 @@ rctx_cache_insecure(respctx_t *rctx, dns_message_t *message, dns_name_t *name,
}
}
/*
* If the trust level is glue, then we are adding data from a
* referral we got while executing the search algorithm. New
* referral data always takes precedence over the existing cache
* contents.
*/
unsigned int options = 0;
if (rdataset->trust == dns_trust_glue &&
dns_rdataset_matchestype(rdataset, dns_rdatatype_ns))
{
options = DNS_DBADD_FORCE;
} else if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) {
options = DNS_DBADD_PREFETCH;
}
/*
* Look for the NOQNAME proof.
*/
@@ -6015,8 +5967,8 @@ rctx_cache_insecure(respctx_t *rctx, dns_message_t *message, dns_name_t *name,
/*
* Cache the rdataset.
*/
result = dns_db_addrdataset(fctx->cache, node, NULL, rctx->now,
rdataset, options, added);
result = cache_rrset(fctx, rctx->now, name, rdataset, NULL, &node,
added, NULL);
if (result == DNS_R_UNCHANGED) {
result = ISC_R_SUCCESS;
}
@@ -6072,12 +6024,7 @@ rctx_cachename(respctx_t *rctx, dns_message_t *message, dns_name_t *name) {
/*
* Find the RRSIG for this rdataset, if we have it.
*/
ISC_LIST_FOREACH (name->list, sig, link) {
if (dns_rdataset_issigtype(sig, rdataset->type)) {
sigrdataset = sig;
break;
}
}
sigrdataset = getrrsig(name, rdataset->type);
/*
* Make the TTLs consistent with the configured
@@ -6090,7 +6037,7 @@ rctx_cachename(respctx_t *rctx, dns_message_t *message, dns_name_t *name) {
* glue, start validators as needed. Otherwise, cache
* cache now.
*/
if (secure_domain && rdataset->trust != dns_trust_glue) {
if (secure_domain && gettrust(rdataset) != dns_trust_glue) {
result = rctx_cache_secure(rctx, message, name, node,
rdataset, sigrdataset,
need_validation);
@@ -6121,30 +6068,13 @@ rctx_cachename(respctx_t *rctx, dns_message_t *message, dns_name_t *name) {
{
resp = ISC_LIST_HEAD(fctx->resps);
if (resp != NULL) {
/*
* Negative results must be indicated in
* resp->result.
*/
resp->result = ISC_R_SUCCESS;
isc_result_t eresult = ISC_R_SUCCESS;
if (dns_rdataset_isassociated(resp->rdataset)) {
if (NXDOMAIN(resp->rdataset)) {
resp->result = DNS_R_NCACHENXDOMAIN;
} else if (NEGATIVE(resp->rdataset)) {
resp->result = DNS_R_NCACHENXRRSET;
} else if (resp->rdataset->type != fctx->type) {
switch (resp->rdataset->type) {
case dns_rdatatype_cname:
resp->result = DNS_R_CNAME;
break;
case dns_rdatatype_dname:
resp->result = DNS_R_DNAME;
break;
default:
break;
}
}
eresult = fctx_setresult(fctx, resp->rdataset);
}
resp->result = eresult;
dns_name_copy(name, resp->foundname);
dns_db_attach(fctx->cache, &resp->db);
dns_db_transfernode(fctx->cache, &node, &resp->node);
@@ -6199,7 +6129,7 @@ cleanup:
static isc_result_t
negcache(dns_message_t *message, fetchctx_t *fctx, const dns_name_t *name,
isc_stdtime_t now, bool optout, bool secure, dns_rdataset_t *added,
dns_dbnode_t **nodep, isc_result_t *eresultp) {
dns_dbnode_t **nodep) {
isc_result_t result;
dns_ttl_t minttl = fctx->res->view->minncachettl;
dns_ttl_t maxttl = fctx->res->view->maxncachettl;
@@ -6254,24 +6184,7 @@ negcache(dns_message_t *message, fetchctx_t *fctx, const dns_name_t *name,
result = dns_ncache_add(message, cache, node, covers, now, minttl,
maxttl, optout, secure, added);
if (result == DNS_R_UNCHANGED || result == ISC_R_SUCCESS) {
/*
* The cache now either contains the negative entry we
* were adding, or a pre-existing entry (positive or
* negative) that was left alone. Set the event result
* accordingly.
*/
if (NXDOMAIN(added)) {
*eresultp = DNS_R_NCACHENXDOMAIN;
} else if (NEGATIVE(added)) {
*eresultp = DNS_R_NCACHENXRRSET;
} else if (added->type == dns_rdatatype_cname) {
*eresultp = DNS_R_CNAME;
} else if (added->type == dns_rdatatype_dname) {
*eresultp = DNS_R_DNAME;
} else {
*eresultp = ISC_R_SUCCESS;
}
if (result == DNS_R_UNCHANGED) {
result = ISC_R_SUCCESS;
}
@@ -6291,7 +6204,6 @@ negcache(dns_message_t *message, fetchctx_t *fctx, const dns_name_t *name,
static void
rctx_ncache(respctx_t *rctx) {
isc_result_t result = ISC_R_SUCCESS;
isc_result_t eresult = ISC_R_SUCCESS;
fetchctx_t *fctx = rctx->fctx;
dns_name_t *name = fctx->name;
dns_message_t *message = rctx->query->rmessage;
@@ -6356,14 +6268,14 @@ rctx_ncache(respctx_t *rctx) {
}
result = negcache(message, fctx, name, rctx->now, false, false, added,
&node, &eresult);
&node);
if (result != ISC_R_SUCCESS || HAVE_ANSWER(fctx)) {
goto unlock;
}
FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER);
if (resp != NULL) {
resp->result = eresult;
resp->result = fctx_setresult(fctx, resp->rdataset);
dns_name_copy(name, resp->foundname);
dns_db_attach(fctx->cache, &resp->db);
dns_db_transfernode(fctx->cache, &node, &resp->node);