* SOFTWARE.
*/
-/* $Id: resolver.c,v 1.152 2000/07/24 23:55:19 gson Exp $ */
+/* $Id: resolver.c,v 1.153 2000/07/25 22:03:25 bwelling Exp $ */
#include <config.h>
dns_rdataset_t *asigrdataset = NULL;
dns_dbnode_t *node = NULL;
isc_boolean_t negative;
+ isc_boolean_t sentresponse;
UNUSED(task); /* for now */
negative = ISC_TF(vevent->rdataset == NULL);
+ sentresponse = ISC_TF((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0);
+
/*
* If shutting down, ignore the results. Check to see if we're
* done waiting for validator completions and ADB pending events; if
* so, destroy the fctx.
*/
- if (SHUTTINGDOWN(fctx)) {
+ if (SHUTTINGDOWN(fctx) && !sentresponse ) {
maybe_destroy(fctx);
goto cleanup_event;
}
/*
- * We're not shutting down.
- */
+ * Either we're not shutting down, or we are shutting down but want
+ * to cache the result anyway (if this was a validation started by
+ * a query with cd set)
+ */
hevent = ISC_LIST_HEAD(fctx->events);
if (hevent != NULL) {
if (vevent->result != ISC_R_SUCCESS) {
FCTXTRACE("validation failed");
+ if (vevent->rdataset != NULL) {
+ result = dns_db_findnode(fctx->res->view->cachedb,
+ vevent->name, ISC_TRUE,
+ &node);
+ if (result != ISC_R_SUCCESS)
+ goto noanswer_response;
+ (void)dns_db_deleterdataset(fctx->res->view->cachedb,
+ node, NULL,
+ vevent->type, 0);
+ if (vevent->sigrdataset != NULL)
+ (void)dns_db_deleterdataset(
+ fctx->res->view->cachedb,
+ node, NULL,
+ dns_rdatatype_sig,
+ vevent->type);
+ }
result = vevent->result;
goto noanswer_response;
}
goto noanswer_response;
}
+ if (sentresponse) {
+ /*
+ * If we only deferred the destroy because we wanted to cache
+ * the data, destroy now.
+ */
+ if (SHUTTINGDOWN(fctx))
+ maybe_destroy(fctx);
+
+ goto cleanup_event;
+ }
+
if (fctx->validating > 0) {
INSIST(!negative);
INSIST(fctx->type == dns_rdatatype_any ||
dns_db_t **adbp;
dns_name_t *aname;
dns_resolver_t *res;
- isc_boolean_t need_validation, have_answer;
+ isc_boolean_t need_validation, secure_domain, have_answer;
isc_result_t result, eresult;
dns_fetchevent_t *event;
unsigned int options;
res = fctx->res;
need_validation = ISC_FALSE;
+ secure_domain = ISC_FALSE;
have_answer = ISC_FALSE;
eresult = ISC_R_SUCCESS;
task = res->buckets[fctx->bucketnum].task;
* Is DNSSEC validation required for this name?
*/
result = dns_keytable_issecuredomain(res->view->secroots, name,
- &need_validation);
+ &secure_domain);
if (result != ISC_R_SUCCESS)
return (result);
+ if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0)
+ need_validation = ISC_FALSE;
+ else
+ need_validation = secure_domain;
+
adbp = NULL;
aname = NULL;
anodep = NULL;
* If this rrset is in a secure domain, do DNSSEC validation
* for it, unless it is glue.
*/
- if (need_validation && rdataset->trust != dns_trust_glue) {
+ if (secure_domain && rdataset->trust != dns_trust_glue) {
/*
* SIGs are validated as part of validating the
* type they cover.
break;
}
if (sigrdataset == NULL) {
- if (!ANSWER(rdataset)) {
+ if (!ANSWER(rdataset) && need_validation) {
/*
* Ignore non-answer rdatasets that
* are missing signatures.
rdataset->trust = dns_trust_pending;
if (sigrdataset != NULL)
sigrdataset->trust = dns_trust_pending;
+ if (!need_validation)
+ addedrdataset = ardataset;
+ else
+ addedrdataset = NULL;
result = dns_db_addrdataset(res->view->cachedb,
node, NULL, now,
- rdataset, 0, NULL);
+ rdataset, 0,
+ addedrdataset);
if (result == DNS_R_UNCHANGED)
result = ISC_R_SUCCESS;
if (result != ISC_R_SUCCESS)
break;
if (sigrdataset != NULL) {
+ if (!need_validation)
+ addedrdataset = asigrdataset;
+ else
+ addedrdataset = NULL;
result = dns_db_addrdataset(res->view->cachedb,
node, NULL, now,
sigrdataset, 0,
- NULL);
+ addedrdataset);
if (result == DNS_R_UNCHANGED)
result = ISC_R_SUCCESS;
if (result != ISC_R_SUCCESS)
break;
- }
+ } else
+ continue;
+
if (ANSWER(rdataset)) {
if (fctx->type != dns_rdatatype_any &&
fctx->type != dns_rdatatype_sig) {