* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.284.18.62 2007/08/28 07:20:05 tbox Exp $ */
+/* $Id: resolver.c,v 1.284.18.63 2007/09/14 05:52:49 marka Exp $ */
/*! \file */
isc_sockaddrlist_t bad;
isc_sockaddrlist_t edns;
isc_sockaddrlist_t edns512;
+ dns_validator_t *validator;
ISC_LIST(dns_validator_t) validators;
dns_db_t * cache;
dns_adb_t * adb;
sigrdataset, fctx->rmessage,
valoptions, task, validated, valarg,
&validator);
- if (result == ISC_R_SUCCESS)
+ if (result == ISC_R_SUCCESS) {
+ if ((valoptions & DNS_VALIDATOR_DEFER) == 0) {
+ INSIST(fctx->validator == NULL);
+ fctx->validator = validator;
+ }
ISC_LIST_APPEND(fctx->validators, validator, link);
- else
+ } else
isc_mem_put(fctx->res->buckets[fctx->bucketnum].mctx,
valarg, sizeof(*valarg));
return (result);
ISC_LIST_INIT(fctx->edns);
ISC_LIST_INIT(fctx->edns512);
ISC_LIST_INIT(fctx->validators);
+ fctx->validator = NULL;
fctx->find = NULL;
fctx->altfind = NULL;
fctx->pending = 0;
unsigned int bucketnum;
isc_boolean_t bucket_empty = ISC_FALSE;
dns_resolver_t *res = fctx->res;
- dns_validator_t *validator;
+ dns_validator_t *validator, *next_validator;
REQUIRE(SHUTTINGDOWN(fctx));
return;
for (validator = ISC_LIST_HEAD(fctx->validators);
- validator != NULL;
- validator = ISC_LIST_HEAD(fctx->validators)) {
- ISC_LIST_UNLINK(fctx->validators, validator, link);
+ validator != NULL; validator = next_validator) {
+ next_validator = ISC_LIST_NEXT(validator, link);
dns_validator_cancel(validator);
+ /*
+ * If this is a active validator wait for the cancel
+ * to complete before calling dns_validator_destroy().
+ */
+ if (validator == fctx->validator)
+ continue;
+ ISC_LIST_UNLINK(fctx->validators, validator, link);
dns_validator_destroy(&validator);
}
bucketnum = fctx->bucketnum;
LOCK(&res->buckets[bucketnum].lock);
- if (fctx->references == 0)
+ if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators))
bucket_empty = fctx_destroy(fctx);
UNLOCK(&res->buckets[bucketnum].lock);
FCTXTRACE("received validation completion event");
ISC_LIST_UNLINK(fctx->validators, vevent->validator, link);
+ fctx->validator = NULL;
/*
* Destroy the validator early so that we can
add_bad(fctx, addrinfo, result);
isc_event_free(&event);
UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
- if (!ISC_LIST_EMPTY(fctx->validators))
- dns_validator_send(ISC_LIST_HEAD(fctx->validators));
- else if (sentresponse)
+ INSIST(fctx->validator == NULL);
+ fctx->validator = ISC_LIST_HEAD(fctx->validators);
+ if (fctx->validator != NULL) {
+ dns_validator_send(fctx->validator);
+ } else if (sentresponse)
fctx_done(fctx, result); /* Locks bucket. */
else
fctx_try(fctx); /* Locks bucket. */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.c,v 1.119.18.33 2007/08/28 07:20:05 tbox Exp $ */
+/* $Id: validator.c,v 1.119.18.34 2007/09/14 05:52:50 marka Exp $ */
/*! \file */
#define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)
#define VALATTR_SHUTDOWN 0x0001 /*%< Shutting down. */
+#define VALATTR_CANCELED 0x0002 /*%< Cancelled. */
#define VALATTR_TRIEDVERIFY 0x0004 /*%< We have found a key and
* have attempted a verify. */
#define VALATTR_INSECURITY 0x0010 /*%< Attempting proveunsecure. */
#define DLVTRIED(val) ((val->attributes & VALATTR_DLVTRIED) != 0)
#define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
+#define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0)
static void
destroy(dns_validator_t *val);
validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_validator");
LOCK(&val->lock);
- if (eresult == ISC_R_SUCCESS) {
+ if (CANCELED(val)) {
+ validator_done(val, ISC_R_CANCELED);
+ } else if (eresult == ISC_R_SUCCESS) {
validator_log(val, ISC_LOG_DEBUG(3),
"keyset with trust %d", rdataset->trust);
/*
validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched");
LOCK(&val->lock);
- if (eresult == ISC_R_SUCCESS) {
+ if (CANCELED(val)) {
+ validator_done(val, ISC_R_CANCELED);
+ } else if (eresult == ISC_R_SUCCESS) {
validator_log(val, ISC_LOG_DEBUG(3),
"dsset with trust %d", rdataset->trust);
val->dsset = &val->frdataset;
validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2: %s",
dns_result_totext(eresult));
LOCK(&val->lock);
- if (eresult == DNS_R_NXRRSET || eresult == DNS_R_NCACHENXRRSET) {
+ if (CANCELED(val)) {
+ validator_done(val, ISC_R_CANCELED);
+ } else if (eresult == DNS_R_NXRRSET || eresult == DNS_R_NCACHENXRRSET) {
/*
* There is no DS. If this is a delegation, we're done.
*/
validator_log(val, ISC_LOG_DEBUG(3), "in keyvalidated");
LOCK(&val->lock);
- if (eresult == ISC_R_SUCCESS) {
+ if (CANCELED(val)) {
+ validator_done(val, ISC_R_CANCELED);
+ } else if (eresult == ISC_R_SUCCESS) {
validator_log(val, ISC_LOG_DEBUG(3),
"keyset with trust %d", val->frdataset.trust);
/*
validator_log(val, ISC_LOG_DEBUG(3), "in dsvalidated");
LOCK(&val->lock);
- if (eresult == ISC_R_SUCCESS) {
+ if (CANCELED(val)) {
+ validator_done(val, ISC_R_CANCELED);
+ } else if (eresult == ISC_R_SUCCESS) {
validator_log(val, ISC_LOG_DEBUG(3),
"dsset with trust %d", val->frdataset.trust);
if ((val->attributes & VALATTR_INSECURITY) != 0)
validator_log(val, ISC_LOG_DEBUG(3), "in authvalidated");
LOCK(&val->lock);
- if (result != ISC_R_SUCCESS) {
+ if (CANCELED(val)) {
+ validator_done(val, ISC_R_CANCELED);
+ } else if (result != ISC_R_SUCCESS) {
validator_log(val, ISC_LOG_DEBUG(3),
"authvalidated: got %s",
isc_result_totext(result));
isc_event_free((isc_event_t **)&validator->event);
isc_task_detach(&task);
}
+ validator->attributes |= VALATTR_CANCELED;
}
UNLOCK(&validator->lock);
}