From 7a78a85b351091c7d3d79db22285d005d73d87aa Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Thu, 27 Oct 2022 16:51:10 -0700 Subject: [PATCH] refactor dns_validator to use loop callbacks The validator now uses loop callbacks to post its completion events. (A task is still used for the fetches.) --- lib/dns/include/dns/validator.h | 69 +++-- lib/dns/resolver.c | 151 +++++----- lib/dns/validator.c | 501 ++++++++++++++------------------ 3 files changed, 331 insertions(+), 390 deletions(-) diff --git a/lib/dns/include/dns/validator.h b/lib/dns/include/dns/validator.h index 383dcb46e4..a87cfbeb82 100644 --- a/lib/dns/include/dns/validator.h +++ b/lib/dns/include/dns/validator.h @@ -60,7 +60,7 @@ #include /*% - * A dns_validatorevent_t is sent when a 'validation' completes. + * A dns_valstatus_t is sent when a 'validation' completes. * \brief * 'name', 'rdataset', 'sigrdataset', and 'message' are the values that were * supplied when dns_validator_create() was called. They are returned to the @@ -69,14 +69,19 @@ * If the RESULT is ISC_R_SUCCESS and the answer is secure then * proofs[] will contain the names of the NSEC records that hold the * various proofs. Note the same name may appear multiple times. + * + * The structure is freed by dns_validator_destroy(). */ -typedef struct dns_validatorevent { - ISC_EVENT_COMMON(struct dns_validatorevent); +typedef struct dns_valstatus { dns_validator_t *validator; isc_result_t result; + + isc_mem_t *mctx; + /* * Name and type of the response to be validated. */ + dns_fixedname_t fname; dns_name_t *name; dns_rdatatype_t type; /* @@ -101,7 +106,7 @@ typedef struct dns_validatorevent { * Answer is secure. */ bool secure; -} dns_validatorevent_t; +} dns_valstatus_t; #define DNS_VALIDATOR_NOQNAMEPROOF 0 #define DNS_VALIDATOR_NODATAPROOF 1 @@ -121,28 +126,29 @@ struct dns_validator { isc_mutex_t lock; dns_view_t *view; /* Locked by lock. */ - unsigned int options; - unsigned int attributes; - dns_validatorevent_t *event; - dns_fetch_t *fetch; - dns_validator_t *subvalidator; - dns_validator_t *parent; - dns_keytable_t *keytable; - dst_key_t *key; - dns_rdata_rrsig_t *siginfo; - isc_task_t *task; - isc_taskaction_t action; - void *arg; - unsigned int labels; - dns_rdataset_t *currentset; - dns_rdataset_t *keyset; - dns_rdataset_t *dsset; - dns_rdataset_t fdsset; - dns_rdataset_t frdataset; - dns_rdataset_t fsigrdataset; - dns_fixedname_t fname; - dns_fixedname_t wild; - dns_fixedname_t closest; + unsigned int options; + unsigned int attributes; + dns_valstatus_t *vstat; + dns_fetch_t *fetch; + dns_validator_t *subvalidator; + dns_validator_t *parent; + dns_keytable_t *keytable; + dst_key_t *key; + dns_rdata_rrsig_t *siginfo; + isc_task_t *task; + isc_loop_t *loop; + isc_job_cb cb; + void *arg; + unsigned int labels; + dns_rdataset_t *currentset; + dns_rdataset_t *keyset; + dns_rdataset_t *dsset; + dns_rdataset_t fdsset; + dns_rdataset_t frdataset; + dns_rdataset_t fsigrdataset; + dns_fixedname_t fname; + dns_fixedname_t wild; + dns_fixedname_t closest; ISC_LINK(dns_validator_t) link; bool mustbesecure; unsigned int depth; @@ -165,8 +171,8 @@ isc_result_t dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_message_t *message, unsigned int options, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_validator_t **validatorp); + isc_task_t *task, isc_loop_t *loop, isc_job_cb cb, + void *arg, dns_validator_t **validatorp); /*%< * Start a DNSSEC validation. * @@ -193,8 +199,11 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, * * The validation is performed in the context of 'view'. * - * When the validation finishes, a dns_validatorevent_t with - * the given 'action' and 'arg' are sent to 'task'. + * When the validation finishes, the callback function 'cb' is + * called, passing a dns_valstatus_t object which contains a + * poiner to 'arg'. The caller is responsible for freeing this + * object. + * * Its 'result' field will be ISC_R_SUCCESS iff the * response was successfully proven to be either secure or * part of a known insecure domain. diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index e3b72e0117..189ef15fbf 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -515,7 +515,6 @@ struct fetchctx { typedef struct { dns_adbaddrinfo_t *addrinfo; fetchctx_t *fctx; - dns_message_t *message; } dns_valarg_t; struct dns_fetch { @@ -669,7 +668,7 @@ ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_ttl_t maxttl, bool optout, bool secure, dns_rdataset_t *ardataset, isc_result_t *eresultp); static void -validated(isc_task_t *task, isc_event_t *event); +validated(void *arg); static void maybe_cancel_validators(fetchctx_t *fctx); static void @@ -970,19 +969,16 @@ static isc_result_t valcreate(fetchctx_t *fctx, dns_message_t *message, dns_adbaddrinfo_t *addrinfo, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, unsigned int valoptions, - isc_task_t *task) { + isc_task_t *task, isc_loop_t *loop) { dns_validator_t *validator = NULL; - dns_valarg_t *valarg; + dns_valarg_t *valarg = NULL; isc_result_t result; valarg = isc_mem_get(fctx->mctx, sizeof(*valarg)); - *valarg = (dns_valarg_t){ .addrinfo = addrinfo, }; - INSIST(!SHUTTINGDOWN(fctx)); - dns_message_attach(message, &valarg->message); fetchctx_attach(fctx, &valarg->fctx); if (!ISC_LIST_EMPTY(fctx->validators)) { @@ -993,14 +989,8 @@ valcreate(fetchctx_t *fctx, dns_message_t *message, dns_adbaddrinfo_t *addrinfo, result = dns_validator_create(fctx->res->view, name, type, rdataset, sigrdataset, message, valoptions, task, - validated, valarg, &validator); - if (result != ISC_R_SUCCESS) { - fetchctx_detach(&valarg->fctx); - dns_message_detach(&valarg->message); - isc_mem_put(fctx->mctx, valarg, sizeof(*valarg)); - return (result); - } - + loop, validated, valarg, &validator); + RUNTIME_CHECK(result == ISC_R_SUCCESS); inc_stats(fctx->res, dns_resstatscounter_val); if ((valoptions & DNS_VALIDATOR_DEFER) == 0) { INSIST(fctx->validator == NULL); @@ -5336,7 +5326,9 @@ has_000_label(dns_rdataset_t *nsecset) { * The validator has finished. */ static void -validated(isc_task_t *task, isc_event_t *event) { +validated(void *arg) { + dns_valstatus_t *vstat = (dns_valstatus_t *)arg; + dns_validator_t *val = vstat->validator; dns_adbaddrinfo_t *addrinfo = NULL; dns_dbnode_t *node = NULL; dns_dbnode_t *nsnode = NULL; @@ -5348,7 +5340,6 @@ validated(isc_task_t *task, isc_event_t *event) { dns_rdataset_t *sigrdataset = NULL; dns_resolver_t *res = NULL; dns_valarg_t *valarg = NULL; - dns_validatorevent_t *vevent = NULL; fetchctx_t *fctx = NULL; bool chaining; bool negative; @@ -5363,10 +5354,7 @@ validated(isc_task_t *task, isc_event_t *event) { dns_message_t *message = NULL; bool done = false; - UNUSED(task); /* for now */ - - REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE); - valarg = event->ev_arg; + valarg = val->arg; REQUIRE(VALID_FCTX(valarg->fctx)); REQUIRE(!ISC_LIST_EMPTY(valarg->fctx->validators)); @@ -5381,14 +5369,11 @@ validated(isc_task_t *task, isc_event_t *event) { res = fctx->res; addrinfo = valarg->addrinfo; - message = valarg->message; - valarg->message = NULL; - - vevent = (dns_validatorevent_t *)event; - fctx->vresult = vevent->result; + message = vstat->message; + fctx->vresult = vstat->result; LOCK(&fctx->lock); - ISC_LIST_UNLINK(fctx->validators, vevent->validator, link); + ISC_LIST_UNLINK(fctx->validators, val, link); fctx->validator = NULL; UNLOCK(&fctx->lock); @@ -5396,15 +5381,14 @@ validated(isc_task_t *task, isc_event_t *event) { * Destroy the validator early so that we can * destroy the fctx if necessary. Save the wildcard name. */ - if (vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) { + if (vstat->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) { wild = dns_fixedname_initname(&fwild); - dns_name_copy(dns_fixedname_name(&vevent->validator->wild), - wild); + dns_name_copy(dns_fixedname_name(&val->wild), wild); } - dns_validator_destroy(&vevent->validator); + isc_mem_put(fctx->mctx, valarg, sizeof(*valarg)); - negative = (vevent->rdataset == NULL); + negative = (vstat->rdataset == NULL); LOCK(&fctx->lock); sentresponse = ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0); @@ -5425,13 +5409,13 @@ validated(isc_task_t *task, isc_event_t *event) { * If chaining, we need to make sure that the right result code * is returned, and that the rdatasets are bound. */ - if (vevent->result == ISC_R_SUCCESS && !negative && - vevent->rdataset != NULL && CHAINING(vevent->rdataset)) + if (vstat->result == ISC_R_SUCCESS && !negative && + vstat->rdataset != NULL && CHAINING(vstat->rdataset)) { - if (vevent->rdataset->type == dns_rdatatype_cname) { + if (vstat->rdataset->type == dns_rdatatype_cname) { eresult = DNS_R_CNAME; } else { - INSIST(vevent->rdataset->type == dns_rdatatype_dname); + INSIST(vstat->rdataset->type == dns_rdatatype_dname); eresult = DNS_R_DNAME; } chaining = true; @@ -5462,28 +5446,28 @@ validated(isc_task_t *task, isc_event_t *event) { } } - if (vevent->result != ISC_R_SUCCESS) { + if (vstat->result != ISC_R_SUCCESS) { FCTXTRACE("validation failed"); inc_stats(res, dns_resstatscounter_valfail); fctx->valfail++; - fctx->vresult = vevent->result; + fctx->vresult = vstat->result; if (fctx->vresult != DNS_R_BROKENCHAIN) { result = ISC_R_NOTFOUND; - if (vevent->rdataset != NULL) { + if (vstat->rdataset != NULL) { result = dns_db_findnode( - fctx->cache, vevent->name, true, &node); + fctx->cache, vstat->name, true, &node); } if (result == ISC_R_SUCCESS) { (void)dns_db_deleterdataset(fctx->cache, node, - NULL, vevent->type, + NULL, vstat->type, 0); } if (result == ISC_R_SUCCESS && - vevent->sigrdataset != NULL) + vstat->sigrdataset != NULL) { (void)dns_db_deleterdataset( fctx->cache, node, NULL, - dns_rdatatype_rrsig, vevent->type); + dns_rdatatype_rrsig, vstat->type); } if (result == ISC_R_SUCCESS) { dns_db_detachnode(fctx->cache, &node); @@ -5495,21 +5479,21 @@ validated(isc_task_t *task, isc_event_t *event) { * validation. */ result = ISC_R_NOTFOUND; - if (vevent->rdataset != NULL) { + if (vstat->rdataset != NULL) { result = dns_db_findnode( - fctx->cache, vevent->name, true, &node); + fctx->cache, vstat->name, true, &node); } if (result == ISC_R_SUCCESS) { (void)dns_db_addrdataset( fctx->cache, node, NULL, now, - vevent->rdataset, 0, NULL); + vstat->rdataset, 0, NULL); } if (result == ISC_R_SUCCESS && - vevent->sigrdataset != NULL) + vstat->sigrdataset != NULL) { (void)dns_db_addrdataset( fctx->cache, node, NULL, now, - vevent->sigrdataset, 0, NULL); + vstat->sigrdataset, 0, NULL); } if (result == ISC_R_SUCCESS) { dns_db_detachnode(fctx->cache, &node); @@ -5569,8 +5553,7 @@ validated(isc_task_t *task, isc_event_t *event) { covers = fctx->type; } - result = dns_db_findnode(fctx->cache, vevent->name, true, - &node); + result = dns_db_findnode(fctx->cache, vstat->name, true, &node); if (result != ISC_R_SUCCESS) { /* fctx->lock unlocked in noanswer_response */ goto noanswer_response; @@ -5590,7 +5573,7 @@ validated(isc_task_t *task, isc_event_t *event) { result = ncache_adderesult(message, fctx->cache, node, covers, now, fctx->res->view->minncachettl, - ttl, vevent->optout, vevent->secure, + ttl, vstat->optout, vstat->secure, ardataset, &eresult); if (result != ISC_R_SUCCESS) { goto noanswer_response; @@ -5602,28 +5585,28 @@ validated(isc_task_t *task, isc_event_t *event) { FCTXTRACE("validation OK"); - if (vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) { + if (vstat->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) { result = dns_rdataset_addnoqname( - vevent->rdataset, - vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF]); + vstat->rdataset, + vstat->proofs[DNS_VALIDATOR_NOQNAMEPROOF]); RUNTIME_CHECK(result == ISC_R_SUCCESS); - INSIST(vevent->sigrdataset != NULL); - vevent->sigrdataset->ttl = vevent->rdataset->ttl; - if (vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER] != NULL) { + INSIST(vstat->sigrdataset != NULL); + vstat->sigrdataset->ttl = vstat->rdataset->ttl; + if (vstat->proofs[DNS_VALIDATOR_CLOSESTENCLOSER] != NULL) { result = dns_rdataset_addclosest( - vevent->rdataset, - vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER]); + vstat->rdataset, + vstat->proofs[DNS_VALIDATOR_CLOSESTENCLOSER]); RUNTIME_CHECK(result == ISC_R_SUCCESS); } - } else if (vevent->rdataset->trust == dns_trust_answer && - vevent->rdataset->type != dns_rdatatype_rrsig) + } else if (vstat->rdataset->trust == dns_trust_answer && + vstat->rdataset->type != dns_rdatatype_rrsig) { isc_result_t tresult; dns_name_t *noqname = NULL; - tresult = findnoqname(fctx, message, vevent->name, - vevent->rdataset->type, &noqname); + tresult = findnoqname(fctx, message, vstat->name, + vstat->rdataset->type, &noqname); if (tresult == ISC_R_SUCCESS && noqname != NULL) { - tresult = dns_rdataset_addnoqname(vevent->rdataset, + tresult = dns_rdataset_addnoqname(vstat->rdataset, noqname); RUNTIME_CHECK(tresult == ISC_R_SUCCESS); } @@ -5635,7 +5618,7 @@ validated(isc_task_t *task, isc_event_t *event) { * rdatasets to the first event on the fetch * event list. */ - result = dns_db_findnode(fctx->cache, vevent->name, true, &node); + result = dns_db_findnode(fctx->cache, vstat->name, true, &node); if (result != ISC_R_SUCCESS) { goto noanswer_response; } @@ -5645,7 +5628,7 @@ validated(isc_task_t *task, isc_event_t *event) { options = DNS_DBADD_PREFETCH; } result = dns_db_addrdataset(fctx->cache, node, NULL, now, - vevent->rdataset, options, ardataset); + vstat->rdataset, options, ardataset); if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) { goto noanswer_response; } @@ -5655,9 +5638,9 @@ validated(isc_task_t *task, isc_event_t *event) { } else { eresult = DNS_R_NCACHENXRRSET; } - } else if (vevent->sigrdataset != NULL) { + } else if (vstat->sigrdataset != NULL) { result = dns_db_addrdataset(fctx->cache, node, NULL, now, - vevent->sigrdataset, options, + vstat->sigrdataset, options, asigrdataset); if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) { goto noanswer_response; @@ -5788,25 +5771,25 @@ answer_response: /* * Add the wild card entry. */ - if (vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL && - vevent->rdataset != NULL && - dns_rdataset_isassociated(vevent->rdataset) && - vevent->rdataset->trust == dns_trust_secure && - vevent->sigrdataset != NULL && - dns_rdataset_isassociated(vevent->sigrdataset) && - vevent->sigrdataset->trust == dns_trust_secure && wild != NULL) + if (vstat->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL && + vstat->rdataset != NULL && + dns_rdataset_isassociated(vstat->rdataset) && + vstat->rdataset->trust == dns_trust_secure && + vstat->sigrdataset != NULL && + dns_rdataset_isassociated(vstat->sigrdataset) && + vstat->sigrdataset->trust == dns_trust_secure && wild != NULL) { dns_dbnode_t *wnode = NULL; result = dns_db_findnode(fctx->cache, wild, true, &wnode); if (result == ISC_R_SUCCESS) { result = dns_db_addrdataset(fctx->cache, wnode, NULL, - now, vevent->rdataset, 0, + now, vstat->rdataset, 0, NULL); } if (result == ISC_R_SUCCESS) { (void)dns_db_addrdataset(fctx->cache, wnode, NULL, now, - vevent->sigrdataset, 0, NULL); + vstat->sigrdataset, 0, NULL); } if (wnode != NULL) { dns_db_detachnode(fctx->cache, &wnode); @@ -5824,7 +5807,7 @@ answer_response: if (hevent != NULL) { /* - * Negative results must be indicated in event->result. + * Negative results must be indicated in vstat->result. */ INSIST(hevent->rdataset != NULL); if (dns_rdataset_isassociated(hevent->rdataset) && @@ -5835,7 +5818,7 @@ answer_response: } hevent->result = eresult; - dns_name_copy(vevent->name, hevent->foundname); + dns_name_copy(vstat->name, hevent->foundname); dns_db_attach(fctx->cache, &hevent->db); dns_db_transfernode(fctx->cache, &node, &hevent->node); clone_results(fctx); @@ -5856,8 +5839,7 @@ cleanup_fetchctx: fetchctx_detach(&fctx); INSIST(node == NULL); - dns_message_detach(&message); - isc_event_free(&event); + dns_validator_destroy(&val); } static void @@ -6350,7 +6332,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_message_t *message, fctx, message, addrinfo, name, rdataset->type, rdataset, sigrdataset, valoptions, - fctx->restask); + fctx->restask, fctx->loop); } } else if (CHAINING(rdataset)) { if (rdataset->type == dns_rdatatype_cname) { @@ -6459,7 +6441,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_message_t *message, result = valcreate(fctx, message, addrinfo, name, vtype, valrdataset, valsigrdataset, valoptions, - fctx->restask); + fctx->restask, fctx->loop); } if (result == ISC_R_SUCCESS && have_answer) { @@ -6681,7 +6663,8 @@ ncache_message(fetchctx_t *fctx, dns_message_t *message, * Do negative response validation. */ result = valcreate(fctx, message, addrinfo, name, fctx->type, - NULL, NULL, valoptions, fctx->restask); + NULL, NULL, valoptions, fctx->restask, + fctx->loop); /* * If validation is necessary, return now. Otherwise * continue to process the message, letting the diff --git a/lib/dns/validator.c b/lib/dns/validator.c index 9d5558012c..69f5a69dbf 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -69,6 +70,7 @@ #define VALATTR_TRIEDVERIFY \ 0x0004 /*%< We have found a key and \ * have attempted a verify. */ +#define VALATTR_COMPLETE 0x0008 /*%< Completion event sent. */ #define VALATTR_INSECURITY 0x0010 /*%< Attempting proveunsecure. */ /*! @@ -99,6 +101,7 @@ #define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0) #define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0) +#define COMPLETE(v) (((v)->attributes & VALATTR_COMPLETE) != 0) #define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) #define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) @@ -165,7 +168,7 @@ disassociate_rdatasets(dns_validator_t *val) { } /*% - * Mark the rdatasets in val->event with trust level "answer", + * Mark the rdatasets in val->vstat with trust level "answer", * indicating that they did not validate, but could be cached as insecure. * * If we are validating a name that is marked as "must be secure", log a @@ -180,11 +183,11 @@ markanswer(dns_validator_t *val, const char *where, const char *mbstext) { } validator_log(val, ISC_LOG_DEBUG(3), "marking as answer (%s)", where); - if (val->event->rdataset != NULL) { - dns_rdataset_settrust(val->event->rdataset, dns_trust_answer); + if (val->vstat->rdataset != NULL) { + dns_rdataset_settrust(val->vstat->rdataset, dns_trust_answer); } - if (val->event->sigrdataset != NULL) { - dns_rdataset_settrust(val->event->sigrdataset, + if (val->vstat->sigrdataset != NULL) { + dns_rdataset_settrust(val->vstat->sigrdataset, dns_trust_answer); } @@ -192,40 +195,32 @@ markanswer(dns_validator_t *val, const char *where, const char *mbstext) { } /*% - * Mark the RRsets in val->event with trust level secure. + * Mark the RRsets in val->vstat with trust level secure. */ static void -marksecure(dns_validatorevent_t *event) { - dns_rdataset_settrust(event->rdataset, dns_trust_secure); - if (event->sigrdataset != NULL) { - dns_rdataset_settrust(event->sigrdataset, dns_trust_secure); +marksecure(dns_valstatus_t *vstat) { + dns_rdataset_settrust(vstat->rdataset, dns_trust_secure); + if (vstat->sigrdataset != NULL) { + dns_rdataset_settrust(vstat->sigrdataset, dns_trust_secure); } - event->secure = true; + vstat->secure = true; } /* * Validator 'val' is finished; send the completion event to the task * that called dns_validator_create(), with result `result`. + * + * Caller must be holding the validator lock. */ static void validator_done(dns_validator_t *val, isc_result_t result) { - isc_task_t *task; - - if (val->event == NULL) { + if (COMPLETE(val)) { return; } - /* - * Caller must be holding the lock. - */ - - val->event->result = result; - task = val->event->ev_sender; - val->event->ev_sender = val; - val->event->ev_type = DNS_EVENT_VALIDATORDONE; - val->event->ev_action = val->action; - val->event->ev_arg = val->arg; - isc_task_sendanddetach(&task, (isc_event_t **)&val->event); + val->attributes |= VALATTR_COMPLETE; + val->vstat->result = result; + isc_async_run(val->loop, val->cb, val->vstat); } /* @@ -240,8 +235,6 @@ exit_check(dns_validator_t *val) { return (false); } - INSIST(val->event == NULL); - if (val->fetch != NULL || val->subvalidator != NULL) { return (false); } @@ -403,7 +396,7 @@ fetch_callback_dnskey(isc_task_t *task, isc_event_t *event) { } isc_event_free(&event); - INSIST(val->event != NULL); + INSIST(val->vstat != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_dnskey"); LOCK(&val->lock); @@ -507,7 +500,7 @@ fetch_callback_ds(isc_task_t *task, isc_event_t *event) { dns_rdataset_disassociate(&val->fsigrdataset); } - INSIST(val->event != NULL); + INSIST(val->vstat != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_ds"); LOCK(&val->lock); @@ -634,25 +627,16 @@ done: * Resumes the stalled validation process. */ static void -validator_callback_dnskey(isc_task_t *task, isc_event_t *event) { - dns_validatorevent_t *devent; - dns_validator_t *val; - bool want_destroy; +validator_callback_dnskey(void *arg) { + dns_valstatus_t *vstat = (dns_valstatus_t *)arg; + dns_validator_t *val = vstat->validator->arg; + dns_validator_t *subvalidator = val->subvalidator; isc_result_t result; - isc_result_t eresult; + isc_result_t eresult = vstat->result; isc_result_t saved_result; + bool want_destroy; - UNUSED(task); - INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE); - - devent = (dns_validatorevent_t *)event; - val = devent->ev_arg; - eresult = devent->result; - - isc_event_free(&event); - dns_validator_destroy(&val->subvalidator); - - INSIST(val->event != NULL); + val->subvalidator = NULL; validator_log(val, ISC_LOG_DEBUG(3), "in validator_callback_dnskey"); LOCK(&val->lock); @@ -692,6 +676,8 @@ validator_callback_dnskey(isc_task_t *task, isc_event_t *event) { validator_done(val, DNS_R_BROKENCHAIN); } + dns_validator_destroy(&subvalidator); + want_destroy = exit_check(val); UNLOCK(&val->lock); if (want_destroy) { @@ -705,24 +691,15 @@ validator_callback_dnskey(isc_task_t *task, isc_event_t *event) { * Resumes validation of the zone key or the unsecure zone proof. */ static void -validator_callback_ds(isc_task_t *task, isc_event_t *event) { - dns_validatorevent_t *devent; - dns_validator_t *val; - bool want_destroy; +validator_callback_ds(void *arg) { + dns_valstatus_t *vstat = (dns_valstatus_t *)arg; + dns_validator_t *val = vstat->validator->arg; + dns_validator_t *subvalidator = val->subvalidator; isc_result_t result; - isc_result_t eresult; + isc_result_t eresult = vstat->result; + bool want_destroy; - UNUSED(task); - INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE); - - devent = (dns_validatorevent_t *)event; - val = devent->ev_arg; - eresult = devent->result; - - isc_event_free(&event); - dns_validator_destroy(&val->subvalidator); - - INSIST(val->event != NULL); + val->subvalidator = NULL; validator_log(val, ISC_LOG_DEBUG(3), "in validator_callback_ds"); LOCK(&val->lock); @@ -732,11 +709,9 @@ validator_callback_ds(isc_task_t *task, isc_event_t *event) { bool have_dsset; dns_name_t *name; validator_log(val, ISC_LOG_DEBUG(3), "%s with trust %s", - val->frdataset.type == dns_rdatatype_ds ? "dsset" - : "ds " - "non-" - "existe" - "nce", + val->frdataset.type == dns_rdatatype_ds + ? "dsset" + : "ds non-existence", dns_trust_totext(val->frdataset.trust)); have_dsset = (val->frdataset.type == dns_rdatatype_ds); name = dns_fixedname_name(&val->fname); @@ -765,6 +740,8 @@ validator_callback_ds(isc_task_t *task, isc_event_t *event) { validator_done(val, DNS_R_BROKENCHAIN); } + dns_validator_destroy(&subvalidator); + want_destroy = exit_check(val); UNLOCK(&val->lock); if (want_destroy) { @@ -778,26 +755,18 @@ validator_callback_ds(isc_task_t *task, isc_event_t *event) { * Resumes validation of the unsecure zone proof. */ static void -validator_callback_cname(isc_task_t *task, isc_event_t *event) { - dns_validatorevent_t *devent; - dns_validator_t *val; - bool want_destroy; +validator_callback_cname(void *arg) { + dns_valstatus_t *vstat = (dns_valstatus_t *)arg; + dns_validator_t *val = vstat->validator->arg; + dns_validator_t *subvalidator = val->subvalidator; isc_result_t result; - isc_result_t eresult; + isc_result_t eresult = vstat->result; + bool want_destroy; - UNUSED(task); - INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE); - - devent = (dns_validatorevent_t *)event; - val = devent->ev_arg; - eresult = devent->result; - - isc_event_free(&event); - dns_validator_destroy(&val->subvalidator); - - INSIST(val->event != NULL); INSIST((val->attributes & VALATTR_INSECURITY) != 0); + val->subvalidator = NULL; + validator_log(val, ISC_LOG_DEBUG(3), "in validator_callback_cname"); LOCK(&val->lock); if (CANCELED(val)) { @@ -819,6 +788,8 @@ validator_callback_cname(isc_task_t *task, isc_event_t *event) { validator_done(val, DNS_R_BROKENCHAIN); } + dns_validator_destroy(&subvalidator); + want_destroy = exit_check(val); UNLOCK(&val->lock); if (want_destroy) { @@ -834,24 +805,16 @@ validator_callback_cname(isc_task_t *task, isc_event_t *event) { * Resumes the negative response validation by calling validate_nx(). */ static void -validator_callback_nsec(isc_task_t *task, isc_event_t *event) { - dns_validatorevent_t *devent; - dns_validator_t *val; - dns_rdataset_t *rdataset; - bool want_destroy; - isc_result_t result; +validator_callback_nsec(void *arg) { + dns_valstatus_t *vstat = (dns_valstatus_t *)arg; + dns_validator_t *val = vstat->validator->arg; + dns_validator_t *subvalidator = val->subvalidator; + dns_rdataset_t *rdataset = vstat->rdataset; + isc_result_t result = vstat->result; bool exists, data; + bool want_destroy; - UNUSED(task); - INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE); - - devent = (dns_validatorevent_t *)event; - rdataset = devent->rdataset; - val = devent->ev_arg; - result = devent->result; - dns_validator_destroy(&val->subvalidator); - - INSIST(val->event != NULL); + val->subvalidator = NULL; validator_log(val, ISC_LOG_DEBUG(3), "in validator_callback_nsec"); LOCK(&val->lock); @@ -873,15 +836,15 @@ validator_callback_nsec(isc_task_t *task, isc_event_t *event) { } } } else { - dns_name_t **proofs = val->event->proofs; + dns_name_t **proofs = val->vstat->proofs; dns_name_t *wild = dns_fixedname_name(&val->wild); if (rdataset->type == dns_rdatatype_nsec && rdataset->trust == dns_trust_secure && (NEEDNODATA(val) || NEEDNOQNAME(val)) && !FOUNDNODATA(val) && !FOUNDNOQNAME(val) && - dns_nsec_noexistnodata(val->event->type, val->event->name, - devent->name, rdataset, &exists, + dns_nsec_noexistnodata(val->vstat->type, val->vstat->name, + vstat->name, rdataset, &exists, &data, wild, validator_log, val) == ISC_R_SUCCESS) { @@ -889,11 +852,11 @@ validator_callback_nsec(isc_task_t *task, isc_event_t *event) { val->attributes |= VALATTR_FOUNDNODATA; if (NEEDNODATA(val)) { proofs[DNS_VALIDATOR_NODATAPROOF] = - devent->name; + vstat->name; } } if (!exists) { - dns_name_t *closest; + dns_name_t *closest = NULL; unsigned int clabels; val->attributes |= VALATTR_FOUNDNOQNAME; @@ -918,7 +881,7 @@ validator_callback_nsec(isc_task_t *task, isc_event_t *event) { */ if (NEEDNOQNAME(val)) { proofs[DNS_VALIDATOR_NOQNAMEPROOF] = - devent->name; + vstat->name; } } } @@ -929,16 +892,13 @@ validator_callback_nsec(isc_task_t *task, isc_event_t *event) { } } + dns_validator_destroy(&subvalidator); + want_destroy = exit_check(val); UNLOCK(&val->lock); if (want_destroy) { destroy(val); } - - /* - * Free stuff from the event. - */ - isc_event_free(&event); } /*% @@ -1009,18 +969,18 @@ check_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, dns_validator_t *parent; for (parent = val; parent != NULL; parent = parent->parent) { - if (parent->event != NULL && parent->event->type == type && - dns_name_equal(parent->event->name, name) && + if (parent->vstat != NULL && parent->vstat->type == type && + dns_name_equal(parent->vstat->name, name) && /* * As NSEC3 records are meta data you sometimes * need to prove a NSEC3 record which says that * itself doesn't exist. */ - (parent->event->type != dns_rdatatype_nsec3 || + (parent->vstat->type != dns_rdatatype_nsec3 || rdataset == NULL || sigrdataset == NULL || - parent->event->message == NULL || - parent->event->rdataset != NULL || - parent->event->sigrdataset != NULL)) + parent->vstat->message == NULL || + parent->vstat->rdataset != NULL || + parent->vstat->sigrdataset != NULL)) { validator_log(val, ISC_LOG_DEBUG(3), "continuing validation would lead to " @@ -1058,8 +1018,8 @@ create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, validator_logcreate(val, name, type, caller, "fetch"); return (dns_resolver_createfetch( val->view->resolver, name, type, NULL, NULL, NULL, NULL, 0, - fopts, 0, NULL, val->event->ev_sender, callback, val, - &val->frdataset, &val->fsigrdataset, &val->fetch)); + fopts, 0, NULL, val->task, callback, val, &val->frdataset, + &val->fsigrdataset, &val->fetch)); } /*% @@ -1068,7 +1028,7 @@ create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, static isc_result_t create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, - isc_taskaction_t action, const char *caller) { + isc_job_cb cb, const char *caller) { isc_result_t result; unsigned int vopts = 0; dns_rdataset_t *sig = NULL; @@ -1089,8 +1049,8 @@ create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, validator_logcreate(val, name, type, caller, "validator"); result = dns_validator_create(val->view, name, type, rdataset, sig, - NULL, vopts, val->task, action, val, - &val->subvalidator); + NULL, vopts, val->task, val->loop, cb, + val, &val->subvalidator); if (result == ISC_R_SUCCESS) { val->subvalidator->parent = val; val->subvalidator->depth = val->depth + 1; @@ -1190,7 +1150,7 @@ seek_dnskey(dns_validator_t *val) { * The signer name must be at the same level as the owner name * or closer to the DNS root. */ - namereln = dns_name_fullcompare(val->event->name, &siginfo->signer, + namereln = dns_name_fullcompare(val->vstat->name, &siginfo->signer, &order, &nlabels); if (namereln != dns_namereln_subdomain && namereln != dns_namereln_equal) @@ -1203,7 +1163,7 @@ seek_dnskey(dns_validator_t *val) { * If this is a self-signed keyset, it must not be a zone key * (since seek_dnskey is not called from validate_dnskey). */ - if (val->event->rdataset->type == dns_rdatatype_dnskey) { + if (val->vstat->rdataset->type == dns_rdatatype_dnskey) { return (DNS_R_CONTINUE); } @@ -1211,7 +1171,7 @@ seek_dnskey(dns_validator_t *val) { * Records appearing in the parent zone at delegation * points cannot be self-signed. */ - if (dns_rdatatype_atparent(val->event->rdataset->type)) { + if (dns_rdatatype_atparent(val->vstat->rdataset->type)) { return (DNS_R_CONTINUE); } } else { @@ -1219,12 +1179,12 @@ seek_dnskey(dns_validator_t *val) { * SOA and NS RRsets can only be signed by a key with * the same name. */ - if (val->event->rdataset->type == dns_rdatatype_soa || - val->event->rdataset->type == dns_rdatatype_ns) + if (val->vstat->rdataset->type == dns_rdatatype_soa || + val->vstat->rdataset->type == dns_rdatatype_ns) { const char *type; - if (val->event->rdataset->type == dns_rdatatype_soa) { + if (val->vstat->rdataset->type == dns_rdatatype_soa) { type = "SOA"; } else { type = "NS"; @@ -1348,13 +1308,13 @@ compute_keytag(dns_rdata_t *rdata) { } /*% - * Is the DNSKEY rrset in val->event->rdataset self-signed? + * Is the DNSKEY rrset in val->vstat->rdataset self-signed? */ static bool selfsigned_dnskey(dns_validator_t *val) { - dns_rdataset_t *rdataset = val->event->rdataset; - dns_rdataset_t *sigrdataset = val->event->sigrdataset; - dns_name_t *name = val->event->name; + dns_rdataset_t *rdataset = val->vstat->rdataset; + dns_rdataset_t *sigrdataset = val->vstat->sigrdataset; + dns_name_t *name = val->vstat->name; isc_result_t result; isc_mem_t *mctx = val->view->mctx; bool answer = false; @@ -1442,7 +1402,7 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata, val->attributes |= VALATTR_TRIEDVERIFY; wild = dns_fixedname_initname(&fixed); again: - result = dns_dnssec_verify(val->event->name, val->event->rdataset, key, + result = dns_dnssec_verify(val->vstat->name, val->vstat->rdataset, key, ignore, val->view->maxbits, val->view->mctx, rdata, wild); if ((result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE) && @@ -1469,7 +1429,7 @@ again: isc_result_totext(result)); } if (result == DNS_R_FROMWILDCARD) { - if (!dns_name_equal(val->event->name, wild)) { + if (!dns_name_equal(val->vstat->name, wild)) { dns_name_t *closest; unsigned int labels; @@ -1500,14 +1460,14 @@ again: static isc_result_t validate_answer(dns_validator_t *val, bool resume) { isc_result_t result, vresult = DNS_R_NOVALIDSIG; - dns_validatorevent_t *event; + dns_valstatus_t *vstat = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; /* * Caller must be holding the validator lock. */ - event = val->event; + vstat = val->vstat; if (resume) { /* @@ -1516,14 +1476,14 @@ validate_answer(dns_validator_t *val, bool resume) { result = ISC_R_SUCCESS; validator_log(val, ISC_LOG_DEBUG(3), "resuming validate"); } else { - result = dns_rdataset_first(event->sigrdataset); + result = dns_rdataset_first(vstat->sigrdataset); } for (; result == ISC_R_SUCCESS; - result = dns_rdataset_next(event->sigrdataset)) + result = dns_rdataset_next(vstat->sigrdataset)) { dns_rdata_reset(&rdata); - dns_rdataset_current(event->sigrdataset, &rdata); + dns_rdataset_current(vstat->sigrdataset, &rdata); if (val->siginfo == NULL) { val->siginfo = isc_mem_get(val->view->mctx, sizeof(*val->siginfo)); @@ -1538,7 +1498,7 @@ validate_answer(dns_validator_t *val, bool resume) { * was known and "sufficiently good". */ if (!dns_resolver_algorithm_supported(val->view->resolver, - event->name, + vstat->name, val->siginfo->algorithm)) { resume = false; @@ -1581,8 +1541,8 @@ validate_answer(dns_validator_t *val, bool resume) { validator_log(val, ISC_LOG_DEBUG(3), "failed to verify rdataset"); } else { - dns_rdataset_trimttl(event->rdataset, - event->sigrdataset, val->siginfo, + dns_rdataset_trimttl(vstat->rdataset, + vstat->sigrdataset, val->siginfo, val->start, val->view->acceptexpired); } @@ -1596,7 +1556,7 @@ validate_answer(dns_validator_t *val, bool resume) { } val->key = NULL; if (NEEDNOQNAME(val)) { - if (val->event->message == NULL) { + if (val->vstat->message == NULL) { validator_log(val, ISC_LOG_DEBUG(3), "no message available " "for noqname proof"); @@ -1606,7 +1566,7 @@ validate_answer(dns_validator_t *val, bool resume) { "looking for noqname proof"); return (validate_nx(val, false)); } else if (vresult == ISC_R_SUCCESS) { - marksecure(event); + marksecure(vstat); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure, " "noqname proof not needed"); @@ -1631,7 +1591,7 @@ validate_answer(dns_validator_t *val, bool resume) { /*% * Check whether this DNSKEY (keyrdata) signed the DNSKEY RRset - * (val->event->rdataset). + * (val->vstat->rdataset). */ static isc_result_t check_signer(dns_validator_t *val, dns_rdata_t *keyrdata, uint16_t keyid, @@ -1640,13 +1600,13 @@ check_signer(dns_validator_t *val, dns_rdata_t *keyrdata, uint16_t keyid, dst_key_t *dstkey = NULL; isc_result_t result; - for (result = dns_rdataset_first(val->event->sigrdataset); + for (result = dns_rdataset_first(val->vstat->sigrdataset); result == ISC_R_SUCCESS; - result = dns_rdataset_next(val->event->sigrdataset)) + result = dns_rdataset_next(val->vstat->sigrdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(val->event->sigrdataset, &rdata); + dns_rdataset_current(val->vstat->sigrdataset, &rdata); result = dns_rdata_tostruct(&rdata, &sig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (keyid != sig.keyid || algorithm != sig.algorithm) { @@ -1654,7 +1614,7 @@ check_signer(dns_validator_t *val, dns_rdata_t *keyrdata, uint16_t keyid, } if (dstkey == NULL) { result = dns_dnssec_keyfromrdata( - val->event->name, keyrdata, val->view->mctx, + val->vstat->name, keyrdata, val->view->mctx, &dstkey); if (result != ISC_R_SUCCESS) { /* @@ -1792,7 +1752,7 @@ validate_dnskey(dns_validator_t *val) { * a DS style trust anchor configured for this key. */ if (val->dsset == NULL) { - result = dns_keytable_find(val->keytable, val->event->name, + result = dns_keytable_find(val->keytable, val->vstat->name, &keynode); if (result == ISC_R_SUCCESS) { if (dns_keynode_dsset(keynode, &val->fdsset)) { @@ -1812,7 +1772,7 @@ validate_dnskey(dns_validator_t *val) { * If this is the root name and there was no trust anchor, * we can give up now, since there's no DS at the root. */ - if (dns_name_equal(val->event->name, dns_rootname)) { + if (dns_name_equal(val->vstat->name, dns_rootname)) { if ((val->attributes & VALATTR_TRIEDVERIFY) != 0) { validator_log(val, ISC_LOG_DEBUG(3), "root key failed to validate"); @@ -1827,7 +1787,7 @@ validate_dnskey(dns_validator_t *val) { /* * Look up the DS RRset for this name. */ - result = get_dsset(val, val->event->name, &tresult); + result = get_dsset(val, val->vstat->name, &tresult); if (result == ISC_R_COMPLETE) { result = tresult; goto cleanup; @@ -1868,14 +1828,14 @@ validate_dnskey(dns_validator_t *val) { RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!dns_resolver_ds_digest_supported(val->view->resolver, - val->event->name, + val->vstat->name, ds.digest_type)) { continue; } if (!dns_resolver_algorithm_supported(val->view->resolver, - val->event->name, + val->vstat->name, ds.algorithm)) { continue; @@ -1904,14 +1864,14 @@ validate_dnskey(dns_validator_t *val) { } if (!dns_resolver_ds_digest_supported(val->view->resolver, - val->event->name, + val->vstat->name, ds.digest_type)) { continue; } if (!dns_resolver_algorithm_supported(val->view->resolver, - val->event->name, + val->vstat->name, ds.algorithm)) { continue; @@ -1922,8 +1882,8 @@ validate_dnskey(dns_validator_t *val) { /* * Find the DNSKEY matching the DS... */ - result = dns_dnssec_matchdskey(val->event->name, &dsrdata, - val->event->rdataset, &keyrdata); + result = dns_dnssec_matchdskey(val->vstat->name, &dsrdata, + val->vstat->rdataset, &keyrdata); if (result != ISC_R_SUCCESS) { validator_log(val, ISC_LOG_DEBUG(3), "no DNSKEY matching DS"); @@ -1942,7 +1902,7 @@ validate_dnskey(dns_validator_t *val) { } if (result == ISC_R_SUCCESS) { - marksecure(val->event); + marksecure(val->vstat); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (DS)"); } else if (result == ISC_R_NOMORE && !supported_algorithm) { validator_log(val, ISC_LOG_DEBUG(3), @@ -1972,7 +1932,7 @@ cleanup: static isc_result_t val_rdataset_first(dns_validator_t *val, dns_name_t **namep, dns_rdataset_t **rdatasetp) { - dns_message_t *message = val->event->message; + dns_message_t *message = val->vstat->message; isc_result_t result; REQUIRE(rdatasetp != NULL); @@ -1994,9 +1954,9 @@ val_rdataset_first(dns_validator_t *val, dns_name_t **namep, *rdatasetp = ISC_LIST_HEAD((*namep)->list); INSIST(*rdatasetp != NULL); } else { - result = dns_rdataset_first(val->event->rdataset); + result = dns_rdataset_first(val->vstat->rdataset); if (result == ISC_R_SUCCESS) { - dns_ncache_current(val->event->rdataset, *namep, + dns_ncache_current(val->vstat->rdataset, *namep, *rdatasetp); } } @@ -2006,7 +1966,7 @@ val_rdataset_first(dns_validator_t *val, dns_name_t **namep, static isc_result_t val_rdataset_next(dns_validator_t *val, dns_name_t **namep, dns_rdataset_t **rdatasetp) { - dns_message_t *message = val->event->message; + dns_message_t *message = val->vstat->message; isc_result_t result = ISC_R_SUCCESS; REQUIRE(rdatasetp != NULL && *rdatasetp != NULL); @@ -2029,9 +1989,9 @@ val_rdataset_next(dns_validator_t *val, dns_name_t **namep, *rdatasetp = rdataset; } else { dns_rdataset_disassociate(*rdatasetp); - result = dns_rdataset_next(val->event->rdataset); + result = dns_rdataset_next(val->vstat->rdataset); if (result == ISC_R_SUCCESS) { - dns_ncache_current(val->event->rdataset, *namep, + dns_ncache_current(val->vstat->rdataset, *namep, *rdatasetp); } } @@ -2068,7 +2028,7 @@ checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_format(wild, namebuf, sizeof(namebuf)); validator_log(val, ISC_LOG_DEBUG(3), "in checkwildcard: %s", namebuf); - if (val->event->message == NULL) { + if (val->vstat->message == NULL) { name = &tname; rdataset = &trdataset; } else { @@ -2089,11 +2049,11 @@ checkwildcard(dns_validator_t *val, dns_rdatatype_t type, if (rdataset->type == dns_rdatatype_nsec && (NEEDNODATA(val) || NEEDNOWILDCARD(val)) && !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) && - dns_nsec_noexistnodata(val->event->type, wild, name, + dns_nsec_noexistnodata(val->vstat->type, wild, name, rdataset, &exists, &data, NULL, validator_log, val) == ISC_R_SUCCESS) { - dns_name_t **proofs = val->event->proofs; + dns_name_t **proofs = val->vstat->proofs; if (exists && !data) { val->attributes |= VALATTR_FOUNDNODATA; } @@ -2116,11 +2076,11 @@ checkwildcard(dns_validator_t *val, dns_rdatatype_t type, (NEEDNODATA(val) || NEEDNOWILDCARD(val)) && !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) && dns_nsec3_noexistnodata( - val->event->type, wild, name, rdataset, zonename, + val->vstat->type, wild, name, rdataset, zonename, &exists, &data, NULL, NULL, NULL, NULL, NULL, NULL, validator_log, val) == ISC_R_SUCCESS) { - dns_name_t **proofs = val->event->proofs; + dns_name_t **proofs = val->vstat->proofs; if (exists && !data) { val->attributes |= VALATTR_FOUNDNODATA; } @@ -2161,7 +2121,7 @@ findnsec3proofs(dns_validator_t *val) { bool setclosest, setnearest, *setclosestp; dns_fixedname_t fclosest, fnearest, fzonename; dns_name_t *closest, *nearest, *zonename, *closestp; - dns_name_t **proofs = val->event->proofs; + dns_name_t **proofs = val->vstat->proofs; dns_rdataset_t *rdataset, trdataset; dns_name_init(&tname, NULL); @@ -2170,7 +2130,7 @@ findnsec3proofs(dns_validator_t *val) { nearest = dns_fixedname_initname(&fnearest); zonename = dns_fixedname_initname(&fzonename); - if (val->event->message == NULL) { + if (val->vstat->message == NULL) { name = &tname; rdataset = &trdataset; } else { @@ -2189,7 +2149,7 @@ findnsec3proofs(dns_validator_t *val) { } result = dns_nsec3_noexistnodata( - val->event->type, val->event->name, name, rdataset, + val->vstat->type, val->vstat->name, name, rdataset, zonename, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, validator_log, val); if (result != ISC_R_IGNORE && result != ISC_R_SUCCESS) { @@ -2246,7 +2206,7 @@ findnsec3proofs(dns_validator_t *val) { optout = false; unknown = false; result = dns_nsec3_noexistnodata( - val->event->type, val->event->name, name, rdataset, + val->vstat->type, val->vstat->name, name, rdataset, zonename, &exists, &data, &optout, &unknown, setclosestp, &setnearest, closestp, nearest, validator_log, val); @@ -2357,9 +2317,9 @@ validate_neg_rrset(dns_validator_t *val, dns_name_t *name, * the first one is still in progress), and go into an * infinite loop. Avoid that. */ - if (val->event->type == dns_rdatatype_dnskey && + if (val->vstat->type == dns_rdatatype_dnskey && rdataset->type == dns_rdatatype_nsec && - dns_name_equal(name, val->event->name)) + dns_name_equal(name, val->vstat->name)) { dns_rdata_t nsec = DNS_RDATA_INIT; @@ -2391,7 +2351,7 @@ validate_neg_rrset(dns_validator_t *val, dns_name_t *name, static isc_result_t validate_authority(dns_validator_t *val, bool resume) { dns_name_t *name; - dns_message_t *message = val->event->message; + dns_message_t *message = val->vstat->message; isc_result_t result; if (!resume) { @@ -2455,13 +2415,13 @@ validate_ncache(dns_validator_t *val, bool resume) { isc_result_t result; if (!resume) { - result = dns_rdataset_first(val->event->rdataset); + result = dns_rdataset_first(val->vstat->rdataset); } else { - result = dns_rdataset_next(val->event->rdataset); + result = dns_rdataset_next(val->vstat->rdataset); } for (; result == ISC_R_SUCCESS; - result = dns_rdataset_next(val->event->rdataset)) + result = dns_rdataset_next(val->vstat->rdataset)) { dns_rdataset_t *rdataset, *sigrdataset = NULL; @@ -2469,13 +2429,13 @@ validate_ncache(dns_validator_t *val, bool resume) { name = dns_fixedname_initname(&val->fname); rdataset = &val->frdataset; - dns_ncache_current(val->event->rdataset, name, rdataset); + dns_ncache_current(val->vstat->rdataset, name, rdataset); if (val->frdataset.type == dns_rdatatype_rrsig) { continue; } - result = dns_ncache_getsigrdataset(val->event->rdataset, name, + result = dns_ncache_getsigrdataset(val->vstat->rdataset, name, rdataset->type, &val->fsigrdataset); if (result == ISC_R_SUCCESS) { @@ -2517,7 +2477,7 @@ validate_nx(dns_validator_t *val, bool resume) { validator_log(val, ISC_LOG_DEBUG(3), "resuming validate_nx"); } - if (val->event->message == NULL) { + if (val->vstat->message == NULL) { result = validate_ncache(val, resume); } else { result = validate_authority(val, resume); @@ -2546,7 +2506,7 @@ validate_nx(dns_validator_t *val, bool resume) { { validator_log(val, ISC_LOG_DEBUG(3), "marking as secure, noqname proof found"); - marksecure(val->event); + marksecure(val->vstat); return (ISC_R_SUCCESS); } else if (FOUNDOPTOUT(val) && dns_name_countlabels( @@ -2554,7 +2514,7 @@ validate_nx(dns_validator_t *val, bool resume) { { validator_log(val, ISC_LOG_DEBUG(3), "optout proof found"); - val->event->optout = true; + val->vstat->optout = true; markanswer(val, "validate_nx (1)", NULL); return (ISC_R_SUCCESS); } else if ((val->attributes & VALATTR_FOUNDUNKNOWN) != 0) { @@ -2595,14 +2555,14 @@ validate_nx(dns_validator_t *val, bool resume) { FOUNDNOWILDCARD(val) && FOUNDCLOSEST(val))) { if ((val->attributes & VALATTR_FOUNDOPTOUT) != 0) { - val->event->optout = true; + val->vstat->optout = true; } validator_log(val, ISC_LOG_DEBUG(3), "nonexistence proof(s) found"); - if (val->event->message == NULL) { - marksecure(val->event); + if (val->vstat->message == NULL) { + marksecure(val->vstat); } else { - val->event->secure = true; + val->vstat->secure = true; } return (ISC_R_SUCCESS); } @@ -2647,7 +2607,7 @@ check_ds_algs(dns_validator_t *val, dns_name_t *name, } /*% - * seek_ds is called to look up DS rrsets at the label of val->event->name + * seek_ds is called to look up DS rrsets at the label of val->vstat->name * indicated by val->labels. This is done while building an insecurity * proof, and so it will attempt validation of NXDOMAIN, NXRRSET or CNAME * responses. @@ -2668,10 +2628,10 @@ seek_ds(dns_validator_t *val, isc_result_t *resp) { dns_name_t *found = dns_fixedname_initname(&fixedfound); dns_name_t *tname = dns_fixedname_initname(&val->fname); - if (val->labels == dns_name_countlabels(val->event->name)) { - dns_name_copy(val->event->name, tname); + if (val->labels == dns_name_countlabels(val->vstat->name)) { + dns_name_copy(val->vstat->name, tname); } else { - dns_name_split(val->event->name, val->labels, NULL, tname); + dns_name_split(val->vstat->name, val->labels, NULL, tname); } dns_name_format(tname, namebuf, sizeof(namebuf)); @@ -2883,9 +2843,9 @@ seek_ds(dns_validator_t *val, isc_result_t *resp) { * no such endpoint is found, then the response should have been secure. * * Returns: - * \li ISC_R_SUCCESS val->event->name is in an unsecure zone + * \li ISC_R_SUCCESS val->vstat->name is in an unsecure zone * \li DNS_R_WAIT validation is in progress. - * \li DNS_R_MUSTBESECURE val->event->name is supposed to be secure + * \li DNS_R_MUSTBESECURE val->vstat->name is supposed to be secure * (policy) but we proved that it is unsecure. * \li DNS_R_NOVALIDSIG * \li DNS_R_NOVALIDNSEC @@ -2905,14 +2865,14 @@ proveunsecure(dns_validator_t *val, bool have_ds, bool resume) { */ val->attributes |= VALATTR_INSECURITY; - dns_name_copy(val->event->name, secroot); + dns_name_copy(val->vstat->name, secroot); /* * If this is a response to a DS query, we need to look in * the parent zone for the trust anchor. */ labels = dns_name_countlabels(secroot); - if (val->event->type == dns_rdatatype_ds && labels > 1U) { + if (val->vstat->type == dns_rdatatype_ds && labels > 1U) { dns_name_getlabelsequence(secroot, 1, labels - 1, secroot); } @@ -2959,7 +2919,7 @@ proveunsecure(dns_validator_t *val, bool have_ds, bool resume) { * Walk down through each of the remaining labels in the name, * looking for DS records. */ - while (val->labels <= dns_name_countlabels(val->event->name)) { + while (val->labels <= dns_name_countlabels(val->vstat->name)) { isc_result_t tresult; result = seek_ds(val, &tresult); @@ -2997,19 +2957,16 @@ out: * be an unsecure positive answer. */ static void -validator_start(isc_task_t *task, isc_event_t *event) { - dns_validator_t *val; - dns_validatorevent_t *vevent; +validator_start(void *arg) { + dns_valstatus_t *vstat = (dns_valstatus_t *)arg; + dns_validator_t *val = NULL; bool want_destroy = false; isc_result_t result = ISC_R_FAILURE; - UNUSED(task); - REQUIRE(event->ev_type == DNS_EVENT_VALIDATORSTART); - vevent = (dns_validatorevent_t *)event; - val = vevent->validator; + val = vstat->validator; - /* If the validator has been canceled, val->event == NULL */ - if (val->event == NULL) { + /* If the validator has been canceled, val->vstat == NULL */ + if (val->vstat == NULL) { return; } @@ -3017,7 +2974,7 @@ validator_start(isc_task_t *task, isc_event_t *event) { LOCK(&val->lock); - if (val->event->rdataset != NULL && val->event->sigrdataset != NULL) { + if (val->vstat->rdataset != NULL && val->vstat->sigrdataset != NULL) { isc_result_t saved_result; /* @@ -3027,8 +2984,8 @@ validator_start(isc_task_t *task, isc_event_t *event) { validator_log(val, ISC_LOG_DEBUG(3), "attempting positive response validation"); - INSIST(dns_rdataset_isassociated(val->event->rdataset)); - INSIST(dns_rdataset_isassociated(val->event->sigrdataset)); + INSIST(dns_rdataset_isassociated(val->vstat->rdataset)); + INSIST(dns_rdataset_isassociated(val->vstat->sigrdataset)); if (selfsigned_dnskey(val)) { result = validate_dnskey(val); } else { @@ -3045,14 +3002,14 @@ validator_start(isc_task_t *task, isc_event_t *event) { result = saved_result; } } - } else if (val->event->rdataset != NULL && - val->event->rdataset->type != 0) + } else if (val->vstat->rdataset != NULL && + val->vstat->rdataset->type != 0) { /* * This is either an unsecure subdomain or a response * from a broken server. */ - INSIST(dns_rdataset_isassociated(val->event->rdataset)); + INSIST(dns_rdataset_isassociated(val->vstat->rdataset)); validator_log(val, ISC_LOG_DEBUG(3), "attempting insecurity proof"); @@ -3062,8 +3019,8 @@ validator_start(isc_task_t *task, isc_event_t *event) { "got insecure response; " "parent indicates it should be secure"); } - } else if ((val->event->rdataset == NULL && - val->event->sigrdataset == NULL)) + } else if ((val->vstat->rdataset == NULL && + val->vstat->sigrdataset == NULL)) { /* * This is a validation of a negative response. @@ -3072,7 +3029,7 @@ validator_start(isc_task_t *task, isc_event_t *event) { "attempting negative response validation " "from message"); - if (val->event->message->rcode == dns_rcode_nxdomain) { + if (val->vstat->message->rcode == dns_rcode_nxdomain) { val->attributes |= VALATTR_NEEDNOQNAME; val->attributes |= VALATTR_NEEDNOWILDCARD; } else { @@ -3080,8 +3037,8 @@ validator_start(isc_task_t *task, isc_event_t *event) { } result = validate_nx(val, false); - } else if ((val->event->rdataset != NULL && - NEGATIVE(val->event->rdataset))) + } else if ((val->vstat->rdataset != NULL && + NEGATIVE(val->vstat->rdataset))) { /* * This is a delayed validation of a negative cache entry. @@ -3090,7 +3047,7 @@ validator_start(isc_task_t *task, isc_event_t *event) { "attempting negative response validation " "from cache"); - if (NXDOMAIN(val->event->rdataset)) { + if (NXDOMAIN(val->vstat->rdataset)) { val->attributes |= VALATTR_NEEDNOQNAME; val->attributes |= VALATTR_NEEDNOWILDCARD; } else { @@ -3117,40 +3074,38 @@ isc_result_t dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_message_t *message, unsigned int options, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_validator_t **validatorp) { + isc_task_t *task, isc_loop_t *loop, isc_job_cb cb, + void *arg, dns_validator_t **validatorp) { isc_result_t result = ISC_R_FAILURE; - dns_validator_t *val; - isc_task_t *tclone = NULL; - dns_validatorevent_t *event; + dns_validator_t *val = NULL; + dns_valstatus_t *vstat = NULL; REQUIRE(name != NULL); REQUIRE(rdataset != NULL || (rdataset == NULL && sigrdataset == NULL && message != NULL)); REQUIRE(validatorp != NULL && *validatorp == NULL); - event = (dns_validatorevent_t *)isc_event_allocate( - view->mctx, task, DNS_EVENT_VALIDATORSTART, validator_start, - NULL, sizeof(dns_validatorevent_t)); - - isc_task_attach(task, &tclone); - event->result = ISC_R_FAILURE; - event->name = name; - event->type = type; - event->rdataset = rdataset; - event->sigrdataset = sigrdataset; - event->message = message; - memset(event->proofs, 0, sizeof(event->proofs)); - event->optout = false; - event->secure = false; + vstat = isc_mem_get(view->mctx, sizeof(*vstat)); + *vstat = (dns_valstatus_t){ + .result = ISC_R_FAILURE, + .name = name, + .type = type, + .rdataset = rdataset, + .sigrdataset = sigrdataset, + }; + isc_mem_attach(view->mctx, &vstat->mctx); + if (message != NULL) { + dns_message_attach(message, &vstat->message); + } val = isc_mem_get(view->mctx, sizeof(*val)); - *val = (dns_validator_t){ .event = event, + *val = (dns_validator_t){ .vstat = vstat, .options = options, - .task = task, - .action = action, + .link = ISC_LINK_INITIALIZER, + .loop = loop, + .cb = cb, .arg = arg }; - + isc_task_attach(task, &val->task); dns_view_attach(view, &val->view); isc_mutex_init(&val->lock); @@ -3166,13 +3121,12 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, dns_fixedname_init(&val->wild); dns_fixedname_init(&val->closest); isc_stdtime_get(&val->start); - ISC_LINK_INIT(val, link); val->magic = VALIDATOR_MAGIC; - event->validator = val; + vstat->validator = val; if ((options & DNS_VALIDATOR_DEFER) == 0) { - isc_task_send(task, ISC_EVENT_PTR(&event)); + isc_async_run(loop, validator_start, vstat); } *validatorp = val; @@ -3181,9 +3135,8 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, cleanup: isc_mutex_destroy(&val->lock); - - isc_task_detach(&tclone); - isc_event_free(ISC_EVENT_PTR(&event)); + isc_task_detach(&val->task); + isc_mem_putanddetach(&vstat->mctx, vstat, sizeof(*vstat)); dns_view_detach(&val->view); isc_mem_put(view->mctx, val, sizeof(*val)); @@ -3193,59 +3146,47 @@ cleanup: 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)); + isc_async_run(validator->loop, validator_start, validator->vstat); } void dns_validator_cancel(dns_validator_t *validator) { - dns_fetch_t *fetch = NULL; - REQUIRE(VALID_VALIDATOR(validator)); LOCK(&validator->lock); validator_log(validator, ISC_LOG_DEBUG(3), "dns_validator_cancel"); - if ((validator->attributes & VALATTR_CANCELED) == 0) { - validator->attributes |= VALATTR_CANCELED; - if (validator->event != NULL) { - fetch = validator->fetch; - validator->fetch = NULL; - - if (validator->subvalidator != NULL) { - dns_validator_cancel(validator->subvalidator); - } - if ((validator->options & DNS_VALIDATOR_DEFER) != 0) { - validator->options &= ~DNS_VALIDATOR_DEFER; - validator_done(validator, ISC_R_CANCELED); - } + if (!CANCELED(validator)) { + if (validator->fetch != NULL) { + dns_resolver_cancelfetch(validator->fetch); } + if (validator->subvalidator != NULL) { + dns_validator_cancel(validator->subvalidator); + } + if (!COMPLETE(validator)) { + validator->options &= ~DNS_VALIDATOR_DEFER; + validator_done(validator, ISC_R_CANCELED); + } + + validator->attributes |= VALATTR_CANCELED; } UNLOCK(&validator->lock); - - /* Need to cancel and destroy the fetch outside validator lock */ - if (fetch != NULL) { - dns_resolver_cancelfetch(fetch); - dns_resolver_destroyfetch(&fetch); - } } static void destroy(dns_validator_t *val) { - isc_mem_t *mctx; + isc_mem_t *mctx = NULL; REQUIRE(SHUTDOWN(val)); - REQUIRE(val->event == NULL); REQUIRE(val->fetch == NULL); val->magic = 0; @@ -3265,17 +3206,25 @@ destroy(dns_validator_t *val) { } isc_mutex_destroy(&val->lock); dns_view_detach(&val->view); + isc_task_detach(&val->task); + if (val->vstat->message != NULL) { + dns_message_detach(&val->vstat->message); + } + isc_mem_putanddetach(&val->vstat->mctx, val->vstat, + sizeof(*val->vstat)); isc_mem_put(mctx, val, sizeof(*val)); } void dns_validator_destroy(dns_validator_t **validatorp) { - dns_validator_t *val; + dns_validator_t *val = NULL; bool want_destroy = false; REQUIRE(validatorp != NULL); + val = *validatorp; *validatorp = NULL; + REQUIRE(VALID_VALIDATOR(val)); LOCK(&val->lock); @@ -3323,12 +3272,12 @@ validator_logv(dns_validator_t *val, isc_logcategory_t *category, sep2 = ": "; } - if (val->event != NULL && val->event->name != NULL) { + if (val->vstat != NULL && val->vstat->name != NULL) { char namebuf[DNS_NAME_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; - dns_name_format(val->event->name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(val->event->type, typebuf, + dns_name_format(val->vstat->name, namebuf, sizeof(namebuf)); + dns_rdatatype_format(val->vstat->type, typebuf, sizeof(typebuf)); isc_log_write(dns_lctx, category, module, level, "%s%s%s%.*svalidating %s/%s: %s", sep1, viewname,