2126. [bug] Serialise validation of type ANY responses. [RT #16555]

This commit is contained in:
Mark Andrews
2007-01-08 01:37:34 +00:00
parent 52c39ec75e
commit fcc4a3dd25
4 changed files with 64 additions and 7 deletions
+2
View File
@@ -1,3 +1,5 @@
2126. [bug] Serialise validation of type ANY responses. [RT #16555]
2124. [bug] It was possible to dereference a freed fetch
context. [RT #16584]
+11 -1
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: validator.h,v 1.18.12.11 2006/01/06 00:01:42 marka Exp $ */
/* $Id: validator.h,v 1.18.12.12 2007/01/08 01:37:34 marka Exp $ */
#ifndef DNS_VALIDATOR_H
#define DNS_VALIDATOR_H 1
@@ -144,6 +144,7 @@ struct dns_validator {
* dns_validator_create() options.
*/
#define DNS_VALIDATOR_DLV 1U
#define DNS_VALIDATOR_DEFER 2U
ISC_LANG_BEGINDECLS
@@ -191,6 +192,15 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
* the answer by looking for a appopriate DLV RRset.
*/
void
dns_validator_send(dns_validator_t *validator);
/*%<
* Send a deferred validation request
*
* Requires:
* 'validator' to points to a valid DNSSEC validator.
*/
void
dns_validator_cancel(dns_validator_t *validator);
/*%<
+27 -4
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: resolver.c,v 1.218.2.18.4.66 2007/01/08 00:44:25 marka Exp $ */
/* $Id: resolver.c,v 1.218.2.18.4.67 2007/01/08 01:37:34 marka Exp $ */
#include <config.h>
@@ -375,6 +375,9 @@ valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
valarg->fctx = fctx;
valarg->addrinfo = addrinfo;
if (!ISC_LIST_EMPTY(fctx->validators))
INSIST((valoptions & DNS_VALIDATOR_DEFER) != 0);
result = dns_validator_create(fctx->res->view, name, type, rdataset,
sigrdataset, fctx->rmessage,
valoptions, task, validated, valarg,
@@ -982,6 +985,8 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
if (result != ISC_R_SUCCESS)
return (result);
INSIST(ISC_LIST_EMPTY(fctx->validators));
dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE);
query = isc_mem_get(res->mctx, sizeof(*query));
@@ -3105,13 +3110,21 @@ maybe_destroy(fetchctx_t *fctx) {
unsigned int bucketnum;
isc_boolean_t bucket_empty = ISC_FALSE;
dns_resolver_t *res = fctx->res;
dns_validator_t *validator;
REQUIRE(SHUTTINGDOWN(fctx));
if (fctx->pending != 0 || fctx->nqueries != 0 ||
!ISC_LIST_EMPTY(fctx->validators))
if (fctx->pending != 0 || fctx->nqueries != 0)
return;
for (validator = ISC_LIST_HEAD(fctx->validators);
validator != NULL;
validator = ISC_LIST_HEAD(fctx->validators)) {
ISC_LIST_UNLINK(fctx->validators, validator, link);
dns_validator_cancel(validator);
dns_validator_destroy(&validator);
}
bucketnum = fctx->bucketnum;
LOCK(&res->buckets[bucketnum].lock);
if (fctx->references == 0)
@@ -3245,7 +3258,9 @@ validated(isc_task_t *task, isc_event_t *event) {
add_bad(fctx, &addrinfo->sockaddr, result);
isc_event_free(&event);
UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
if (sentresponse)
if (!ISC_LIST_EMPTY(fctx->validators))
dns_validator_send(ISC_LIST_HEAD(fctx->validators));
else if (sentresponse)
fctx_done(fctx, result); /* Locks bucket. */
else
fctx_try(fctx); /* Locks bucket. */
@@ -3343,6 +3358,7 @@ validated(isc_task_t *task, isc_event_t *event) {
* be validated.
*/
UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
dns_validator_send(ISC_LIST_HEAD(fctx->validators));
goto cleanup_event;
}
@@ -3653,6 +3669,13 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
rdataset,
sigrdataset,
valoptions, task);
/*
* Defer any further validations.
* This prevents multiple validators
* from manipulating fctx->rmessage
* simultaniously.
*/
valoptions |= DNS_VALIDATOR_DEFER;
}
} else if (CHAINING(rdataset)) {
if (rdataset->type == dns_rdatatype_cname)
+24 -2
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: validator.c,v 1.91.2.5.8.28 2006/12/07 06:50:38 marka Exp $ */
/* $Id: validator.c,v 1.91.2.5.8.29 2007/01/08 01:37:34 marka Exp $ */
#include <config.h>
@@ -2837,7 +2837,8 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
ISC_LINK_INIT(val, link);
val->magic = VALIDATOR_MAGIC;
isc_task_send(task, ISC_EVENT_PTR(&event));
if ((options & DNS_VALIDATOR_DEFER) == 0)
isc_task_send(task, ISC_EVENT_PTR(&event));
*validatorp = val;
@@ -2854,6 +2855,21 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
return (result);
}
void
dns_validator_send(dns_validator_t *validator) {
isc_event_t *event;
REQUIRE(VALID_VALIDATOR(validator));
LOCK(&validator->lock);
INSIST((validator->options & DNS_VALIDATOR_DEFER) != 0);
event = (isc_event_t *)validator->event;
validator->options &= ~DNS_VALIDATOR_DEFER;
UNLOCK(&validator->lock);
isc_task_send(validator->task, ISC_EVENT_PTR(&event));
}
void
dns_validator_cancel(dns_validator_t *validator) {
REQUIRE(VALID_VALIDATOR(validator));
@@ -2868,6 +2884,12 @@ dns_validator_cancel(dns_validator_t *validator) {
if (validator->subvalidator != NULL)
dns_validator_cancel(validator->subvalidator);
if ((validator->options & DNS_VALIDATOR_DEFER) != 0) {
isc_task_t *task = validator->event->ev_sender;
validator->options &= ~DNS_VALIDATOR_DEFER;
isc_event_free((isc_event_t **)&validator->event);
isc_task_detach(&task);
}
}
UNLOCK(&validator->lock);
}