mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-03 16:15:27 +00:00
Partially working negative caching.
This commit is contained in:
@@ -31,6 +31,7 @@
|
|||||||
#include <dns/db.h>
|
#include <dns/db.h>
|
||||||
#include <dns/events.h>
|
#include <dns/events.h>
|
||||||
#include <dns/message.h>
|
#include <dns/message.h>
|
||||||
|
#include <dns/ncache.h>
|
||||||
#include <dns/dispatch.h>
|
#include <dns/dispatch.h>
|
||||||
#include <dns/resolver.h>
|
#include <dns/resolver.h>
|
||||||
#include <dns/rdata.h>
|
#include <dns/rdata.h>
|
||||||
@@ -1192,6 +1193,102 @@ cache_message(fetchctx_t *fctx) {
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline isc_result_t
|
||||||
|
ncache_message(fetchctx_t *fctx, dns_rdatatype_t covers) {
|
||||||
|
isc_result_t result, eresult;
|
||||||
|
dns_name_t *name;
|
||||||
|
dns_resolver_t *res;
|
||||||
|
dns_db_t **adbp;
|
||||||
|
dns_dbnode_t *node, **anodep;
|
||||||
|
dns_rdataset_t *ardataset;
|
||||||
|
isc_boolean_t need_validation;
|
||||||
|
dns_fixedname_t foundname;
|
||||||
|
dns_name_t *fname, *aname;
|
||||||
|
dns_fetchevent_t *event;
|
||||||
|
void *data;
|
||||||
|
isc_stdtime_t now;
|
||||||
|
|
||||||
|
result = isc_stdtime_get(&now);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
|
|
||||||
|
res = fctx->res;
|
||||||
|
need_validation = ISC_FALSE;
|
||||||
|
eresult = ISC_R_SUCCESS;
|
||||||
|
name = &fctx->name;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Is DNSSEC validation required for this name?
|
||||||
|
*/
|
||||||
|
dns_fixedname_init(&foundname);
|
||||||
|
fname = dns_fixedname_name(&foundname);
|
||||||
|
data = NULL;
|
||||||
|
result = dns_rbt_findname(res->view->secroots, name, fname, &data);
|
||||||
|
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
|
||||||
|
/*
|
||||||
|
* This name is at or below one of the view's security roots,
|
||||||
|
* so DNSSEC validation is required.
|
||||||
|
*/
|
||||||
|
need_validation = ISC_TRUE;
|
||||||
|
} else if (result != ISC_R_NOTFOUND) {
|
||||||
|
/*
|
||||||
|
* Something bad happened.
|
||||||
|
*/
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOCK(&res->buckets[fctx->bucketnum].lock);
|
||||||
|
|
||||||
|
adbp = NULL;
|
||||||
|
aname = NULL;
|
||||||
|
anodep = NULL;
|
||||||
|
ardataset = NULL;
|
||||||
|
event = ISC_LIST_HEAD(fctx->events);
|
||||||
|
if (event != NULL) {
|
||||||
|
adbp = &event->db;
|
||||||
|
aname = dns_fixedname_name(&event->foundname);
|
||||||
|
result = dns_name_concatenate(name, NULL, aname, NULL);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto unlock;
|
||||||
|
anodep = &event->node;
|
||||||
|
ardataset = event->rdataset;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = NULL;
|
||||||
|
result = dns_db_findnode(res->view->cachedb, name, ISC_TRUE,
|
||||||
|
&node);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto unlock;
|
||||||
|
result = dns_ncache_add(fctx->rmessage, res->view->cachedb, node,
|
||||||
|
covers, now, ardataset);
|
||||||
|
if (result == DNS_R_UNCHANGED) {
|
||||||
|
INSIST(0);
|
||||||
|
} else if (result == ISC_R_SUCCESS) {
|
||||||
|
if (covers == dns_rdatatype_any)
|
||||||
|
eresult = DNS_R_NCACHENXDOMAIN;
|
||||||
|
else
|
||||||
|
eresult = DNS_R_NCACHENXRRSET;
|
||||||
|
} else
|
||||||
|
goto unlock;
|
||||||
|
|
||||||
|
fctx->have_answer = ISC_TRUE;
|
||||||
|
if (event != NULL) {
|
||||||
|
event->result = eresult;
|
||||||
|
dns_db_attach(res->view->cachedb, adbp);
|
||||||
|
*anodep = node;
|
||||||
|
node = NULL;
|
||||||
|
clone_results(fctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
UNLOCK(&res->buckets[fctx->bucketnum].lock);
|
||||||
|
|
||||||
|
if (node != NULL)
|
||||||
|
dns_db_detachnode(res->view->cachedb, &node);
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
mark_related(dns_name_t *name, dns_rdataset_t *rdataset,
|
mark_related(dns_name_t *name, dns_rdataset_t *rdataset,
|
||||||
isc_boolean_t external)
|
isc_boolean_t external)
|
||||||
@@ -1644,6 +1741,7 @@ query_response(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_boolean_t keep_trying, broken_server, get_nameservers;
|
isc_boolean_t keep_trying, broken_server, get_nameservers;
|
||||||
dns_message_t *message;
|
dns_message_t *message;
|
||||||
fetchctx_t *fctx;
|
fetchctx_t *fctx;
|
||||||
|
dns_rdatatype_t covers;
|
||||||
|
|
||||||
REQUIRE(VALID_QUERY(query));
|
REQUIRE(VALID_QUERY(query));
|
||||||
fctx = query->fctx;
|
fctx = query->fctx;
|
||||||
@@ -1656,6 +1754,7 @@ query_response(isc_task_t *task, isc_event_t *event) {
|
|||||||
keep_trying = ISC_FALSE;
|
keep_trying = ISC_FALSE;
|
||||||
broken_server = ISC_FALSE;
|
broken_server = ISC_FALSE;
|
||||||
get_nameservers = ISC_FALSE;
|
get_nameservers = ISC_FALSE;
|
||||||
|
covers = 0;
|
||||||
|
|
||||||
LOCK(&fctx->res->lock);
|
LOCK(&fctx->res->lock);
|
||||||
INSIST(fctx->state == fetchstate_active);
|
INSIST(fctx->state == fetchstate_active);
|
||||||
@@ -1752,7 +1851,21 @@ query_response(isc_task_t *task, isc_event_t *event) {
|
|||||||
*/
|
*/
|
||||||
get_nameservers = ISC_TRUE;
|
get_nameservers = ISC_TRUE;
|
||||||
keep_trying = ISC_TRUE;
|
keep_trying = ISC_TRUE;
|
||||||
} else if (result != ISC_R_SUCCESS) {
|
} else if (result == ISC_R_SUCCESS) {
|
||||||
|
/*
|
||||||
|
* We have a negative response.
|
||||||
|
*/
|
||||||
|
if (message->rcode == dns_rcode_nxdomain)
|
||||||
|
covers = dns_rdatatype_any;
|
||||||
|
else
|
||||||
|
covers = fctx->type;
|
||||||
|
result = ncache_message(fctx, covers);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto done;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Something has gone wrong.
|
||||||
|
*/
|
||||||
if (result == DNS_R_FORMERR)
|
if (result == DNS_R_FORMERR)
|
||||||
broken_server = ISC_TRUE;
|
broken_server = ISC_TRUE;
|
||||||
keep_trying = ISC_TRUE;
|
keep_trying = ISC_TRUE;
|
||||||
|
Reference in New Issue
Block a user