]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2126. [bug] Serialise validation of type ANY responses. [RT #16555]
authorMark Andrews <marka@isc.org>
Mon, 8 Jan 2007 01:37:53 +0000 (01:37 +0000)
committerMark Andrews <marka@isc.org>
Mon, 8 Jan 2007 01:37:53 +0000 (01:37 +0000)
CHANGES
lib/dns/include/dns/validator.h
lib/dns/resolver.c
lib/dns/validator.c

diff --git a/CHANGES b/CHANGES
index 862679b6201082904d8edc740468f467a212f84c..f78e19913f17144b675d527bf7e8082fcbadef6c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+2126.  [bug]           Serialise validation of type ANY responses. [RT #16555]
+
 2125.  [bug]           dns_zone_getzeronosoattl() REQUIRE failure if DLZ
                        was defined. [RT #16574]
 
index a202b548a7408346a026dcec96fa386a98ae26ee..96d125f38548ca6ada378d93e1e778e7be6138ba 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: validator.h,v 1.27.18.6 2005/11/03 00:58:00 marka Exp $ */
+/* $Id: validator.h,v 1.27.18.7 2007/01/08 01:37:53 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);
 /*%<
index cfaf24b06a25f9ea9eeb3845ca161539f9848b86..7693878e716ed81a95344f3caa4e6d8173a47cbd 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: resolver.c,v 1.284.18.54 2007/01/08 00:45:11 marka Exp $ */
+/* $Id: resolver.c,v 1.284.18.55 2007/01/08 01:37:53 marka Exp $ */
 
 /*! \file */
 
@@ -387,6 +387,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,
@@ -1029,6 +1032,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->buckets[fctx->bucketnum].mctx,
@@ -3290,13 +3295,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)
@@ -3431,7 +3444,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. */
@@ -3530,6 +3545,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;
        }
 
@@ -3842,6 +3858,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)
index 7a3229af16b9645798b39ef1d29419a4905b03d7..deeb07aa0472239d8f3ef985d089351a49b5d01f 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: validator.c,v 1.119.18.27 2006/12/07 06:50:34 marka Exp $ */
+/* $Id: validator.c,v 1.119.18.28 2007/01/08 01:37:53 marka Exp $ */
 
 /*! \file */
 
@@ -2877,7 +2877,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;
 
@@ -2894,6 +2895,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));
@@ -2908,6 +2924,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);
 }