mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-23 18:49:54 +00:00
Implement proper reference counting in dns_validator
use reference counting in dns_validator to prevent use after free.
This commit is contained in:
parent
b4715a34a0
commit
7da99414c0
@ -48,8 +48,10 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <isc/job.h>
|
||||||
#include <isc/lang.h>
|
#include <isc/lang.h>
|
||||||
#include <isc/mutex.h>
|
#include <isc/mutex.h>
|
||||||
|
#include <isc/refcount.h>
|
||||||
|
|
||||||
#include <dns/fixedname.h>
|
#include <dns/fixedname.h>
|
||||||
#include <dns/rdataset.h>
|
#include <dns/rdataset.h>
|
||||||
@ -71,43 +73,28 @@
|
|||||||
* whatever purpose the client desires.
|
* whatever purpose the client desires.
|
||||||
*/
|
*/
|
||||||
struct dns_validator {
|
struct dns_validator {
|
||||||
/* Unlocked. */
|
/* Unlocked: */
|
||||||
unsigned int magic;
|
unsigned int magic;
|
||||||
isc_mutex_t lock;
|
isc_mutex_t lock;
|
||||||
dns_view_t *view;
|
dns_view_t *view;
|
||||||
|
isc_loopmgr_t *loopmgr;
|
||||||
|
|
||||||
|
isc_refcount_t references;
|
||||||
|
|
||||||
/* Name and type of the response to be validated. */
|
/* Name and type of the response to be validated. */
|
||||||
dns_name_t *name;
|
dns_name_t *name;
|
||||||
dns_rdatatype_t type;
|
dns_rdatatype_t type;
|
||||||
|
|
||||||
/* Locked by lock. */
|
/*
|
||||||
unsigned int options;
|
* Callback and argument to use to inform the caller
|
||||||
unsigned int attributes;
|
* that validation is complete.
|
||||||
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_loop_t *loop;
|
|
||||||
isc_job_cb cb;
|
isc_job_cb cb;
|
||||||
void *arg;
|
void *arg;
|
||||||
unsigned int labels;
|
|
||||||
dns_rdataset_t *nxset;
|
/* Locked by 'lock': */
|
||||||
dns_rdataset_t *keyset;
|
/* Validation options (_DEFER, _NONTA, etc). */
|
||||||
dns_rdataset_t *dsset;
|
unsigned int options;
|
||||||
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;
|
|
||||||
unsigned int authcount;
|
|
||||||
unsigned int authfail;
|
|
||||||
isc_stdtime_t start;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Results of a completed validation.
|
* Results of a completed validation.
|
||||||
@ -136,6 +123,31 @@ struct dns_validator {
|
|||||||
* Answer is secure.
|
* Answer is secure.
|
||||||
*/
|
*/
|
||||||
bool secure;
|
bool secure;
|
||||||
|
|
||||||
|
/* Internal validator state */
|
||||||
|
unsigned int attributes;
|
||||||
|
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;
|
||||||
|
unsigned int labels;
|
||||||
|
dns_rdataset_t *nxset;
|
||||||
|
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;
|
||||||
|
unsigned int authcount;
|
||||||
|
unsigned int authfail;
|
||||||
|
isc_stdtime_t start;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
@ -152,7 +164,7 @@ isc_result_t
|
|||||||
dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
|
dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
|
||||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
|
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
|
||||||
dns_message_t *message, unsigned int options,
|
dns_message_t *message, unsigned int options,
|
||||||
isc_loop_t *loop, isc_job_cb cb, void *arg,
|
isc_loopmgr_t *loop, isc_job_cb cb, void *arg,
|
||||||
dns_validator_t **validatorp);
|
dns_validator_t **validatorp);
|
||||||
/*%<
|
/*%<
|
||||||
* Start a DNSSEC validation.
|
* Start a DNSSEC validation.
|
||||||
@ -227,4 +239,18 @@ dns_validator_destroy(dns_validator_t **validatorp);
|
|||||||
*\li All resources used by the validator are freed.
|
*\li All resources used by the validator are freed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if DNS_VALIDATOR_TRACE
|
||||||
|
#define dns_validator_ref(ptr) \
|
||||||
|
dns_validator__ref(ptr, __func__, __FILE__, __LINE__)
|
||||||
|
#define dns_validator_unref(ptr) \
|
||||||
|
dns_validator__unref(ptr, __func__, __FILE__, __LINE__)
|
||||||
|
#define dns_validator_attach(ptr, ptrp) \
|
||||||
|
dns_validator__attach(ptr, ptrp, __func__, __FILE__, __LINE__)
|
||||||
|
#define dns_validator_detach(ptrp) \
|
||||||
|
dns_validator__detach(ptrp, __func__, __FILE__, __LINE__)
|
||||||
|
ISC_REFCOUNT_TRACE_DECL(dns_validator);
|
||||||
|
#else
|
||||||
|
ISC_REFCOUNT_DECL(dns_validator);
|
||||||
|
#endif
|
||||||
|
|
||||||
ISC_LANG_ENDDECLS
|
ISC_LANG_ENDDECLS
|
||||||
|
@ -961,8 +961,7 @@ set_stats(dns_resolver_t *res, isc_statscounter_t counter, uint64_t val) {
|
|||||||
static isc_result_t
|
static isc_result_t
|
||||||
valcreate(fetchctx_t *fctx, dns_message_t *message, dns_adbaddrinfo_t *addrinfo,
|
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_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset,
|
||||||
dns_rdataset_t *sigrdataset, unsigned int valoptions,
|
dns_rdataset_t *sigrdataset, unsigned int valoptions) {
|
||||||
isc_loop_t *loop) {
|
|
||||||
dns_validator_t *validator = NULL;
|
dns_validator_t *validator = NULL;
|
||||||
dns_valarg_t *valarg = NULL;
|
dns_valarg_t *valarg = NULL;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
@ -980,9 +979,9 @@ valcreate(fetchctx_t *fctx, dns_message_t *message, dns_adbaddrinfo_t *addrinfo,
|
|||||||
valoptions &= ~DNS_VALIDATOR_DEFER;
|
valoptions &= ~DNS_VALIDATOR_DEFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = dns_validator_create(fctx->res->view, name, type, rdataset,
|
result = dns_validator_create(
|
||||||
sigrdataset, message, valoptions, loop,
|
fctx->res->view, name, type, rdataset, sigrdataset, message,
|
||||||
validated, valarg, &validator);
|
valoptions, fctx->res->loopmgr, validated, valarg, &validator);
|
||||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||||
inc_stats(fctx->res, dns_resstatscounter_val);
|
inc_stats(fctx->res, dns_resstatscounter_val);
|
||||||
if ((valoptions & DNS_VALIDATOR_DEFER) == 0) {
|
if ((valoptions & DNS_VALIDATOR_DEFER) == 0) {
|
||||||
@ -6314,8 +6313,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_message_t *message,
|
|||||||
result = valcreate(
|
result = valcreate(
|
||||||
fctx, message, addrinfo, name,
|
fctx, message, addrinfo, name,
|
||||||
rdataset->type, rdataset,
|
rdataset->type, rdataset,
|
||||||
sigrdataset, valoptions,
|
sigrdataset, valoptions);
|
||||||
fctx->loop);
|
|
||||||
}
|
}
|
||||||
} else if (CHAINING(rdataset)) {
|
} else if (CHAINING(rdataset)) {
|
||||||
if (rdataset->type == dns_rdatatype_cname) {
|
if (rdataset->type == dns_rdatatype_cname) {
|
||||||
@ -6423,8 +6421,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_message_t *message,
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = valcreate(fctx, message, addrinfo, name, vtype,
|
result = valcreate(fctx, message, addrinfo, name, vtype,
|
||||||
valrdataset, valsigrdataset, valoptions,
|
valrdataset, valsigrdataset, valoptions);
|
||||||
fctx->loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == ISC_R_SUCCESS && have_answer) {
|
if (result == ISC_R_SUCCESS && have_answer) {
|
||||||
@ -6646,7 +6643,7 @@ ncache_message(fetchctx_t *fctx, dns_message_t *message,
|
|||||||
* Do negative response validation.
|
* Do negative response validation.
|
||||||
*/
|
*/
|
||||||
result = valcreate(fctx, message, addrinfo, name, fctx->type,
|
result = valcreate(fctx, message, addrinfo, name, fctx->type,
|
||||||
NULL, NULL, valoptions, fctx->loop);
|
NULL, NULL, valoptions);
|
||||||
/*
|
/*
|
||||||
* If validation is necessary, return now. Otherwise
|
* If validation is necessary, return now. Otherwise
|
||||||
* continue to process the message, letting the
|
* continue to process the message, letting the
|
||||||
|
@ -16,8 +16,10 @@
|
|||||||
|
|
||||||
#include <isc/async.h>
|
#include <isc/async.h>
|
||||||
#include <isc/base32.h>
|
#include <isc/base32.h>
|
||||||
|
#include <isc/job.h>
|
||||||
#include <isc/md.h>
|
#include <isc/md.h>
|
||||||
#include <isc/mem.h>
|
#include <isc/mem.h>
|
||||||
|
#include <isc/refcount.h>
|
||||||
#include <isc/result.h>
|
#include <isc/result.h>
|
||||||
#include <isc/string.h>
|
#include <isc/string.h>
|
||||||
#include <isc/util.h>
|
#include <isc/util.h>
|
||||||
@ -63,7 +65,6 @@
|
|||||||
#define VALIDATOR_MAGIC ISC_MAGIC('V', 'a', 'l', '?')
|
#define VALIDATOR_MAGIC ISC_MAGIC('V', 'a', 'l', '?')
|
||||||
#define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)
|
#define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)
|
||||||
|
|
||||||
#define VALATTR_SHUTDOWN 0x0001 /*%< Shutting down. */
|
|
||||||
#define VALATTR_CANCELED 0x0002 /*%< Canceled. */
|
#define VALATTR_CANCELED 0x0002 /*%< Canceled. */
|
||||||
#define VALATTR_TRIEDVERIFY \
|
#define VALATTR_TRIEDVERIFY \
|
||||||
0x0004 /*%< We have found a key and \
|
0x0004 /*%< We have found a key and \
|
||||||
@ -97,7 +98,6 @@
|
|||||||
#define FOUNDCLOSEST(val) ((val->attributes & VALATTR_FOUNDCLOSEST) != 0)
|
#define FOUNDCLOSEST(val) ((val->attributes & VALATTR_FOUNDCLOSEST) != 0)
|
||||||
#define FOUNDOPTOUT(val) ((val->attributes & VALATTR_FOUNDOPTOUT) != 0)
|
#define FOUNDOPTOUT(val) ((val->attributes & VALATTR_FOUNDOPTOUT) != 0)
|
||||||
|
|
||||||
#define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
|
|
||||||
#define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0)
|
#define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0)
|
||||||
#define COMPLETE(v) (((v)->attributes & VALATTR_COMPLETE) != 0)
|
#define COMPLETE(v) (((v)->attributes & VALATTR_COMPLETE) != 0)
|
||||||
|
|
||||||
@ -105,7 +105,7 @@
|
|||||||
#define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
|
#define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy(dns_validator_t *val);
|
destroy_validator(dns_validator_t *val);
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
select_signing_key(dns_validator_t *val, dns_rdataset_t *rdataset);
|
select_signing_key(dns_validator_t *val, dns_rdataset_t *rdataset);
|
||||||
@ -203,6 +203,13 @@ marksecure(dns_validator_t *val) {
|
|||||||
val->secure = true;
|
val->secure = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
validator_done_cb(void *arg) {
|
||||||
|
dns_validator_t *val = arg;
|
||||||
|
val->cb(val);
|
||||||
|
dns_validator_detach(&val);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validator 'val' is finished; send the completion event to the loop
|
* Validator 'val' is finished; send the completion event to the loop
|
||||||
* that called dns_validator_create(), with result `result`.
|
* that called dns_validator_create(), with result `result`.
|
||||||
@ -217,26 +224,9 @@ validator_done(dns_validator_t *val, isc_result_t result) {
|
|||||||
|
|
||||||
val->attributes |= VALATTR_COMPLETE;
|
val->attributes |= VALATTR_COMPLETE;
|
||||||
val->result = result;
|
val->result = result;
|
||||||
isc_async_run(val->loop, val->cb, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
dns_validator_ref(val);
|
||||||
* Called when deciding whether to destroy validator 'val'.
|
isc_job_run(val->loopmgr, validator_done_cb, val);
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
exit_check(dns_validator_t *val) {
|
|
||||||
/*
|
|
||||||
* Caller must be holding the lock.
|
|
||||||
*/
|
|
||||||
if (!SHUTDOWN(val)) {
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val->fetch != NULL || val->subvalidator != NULL) {
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
@ -372,7 +362,6 @@ fetch_callback_dnskey(void *arg) {
|
|||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_result_t saved_result;
|
isc_result_t saved_result;
|
||||||
dns_fetch_t *fetch = NULL;
|
dns_fetch_t *fetch = NULL;
|
||||||
bool want_destroy;
|
|
||||||
|
|
||||||
INSIST(resp->type == FETCHDONE);
|
INSIST(resp->type == FETCHDONE);
|
||||||
|
|
||||||
@ -439,17 +428,13 @@ fetch_callback_dnskey(void *arg) {
|
|||||||
validator_done(val, DNS_R_BROKENCHAIN);
|
validator_done(val, DNS_R_BROKENCHAIN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
want_destroy = exit_check(val);
|
|
||||||
UNLOCK(&val->lock);
|
UNLOCK(&val->lock);
|
||||||
|
|
||||||
if (fetch != NULL) {
|
if (fetch != NULL) {
|
||||||
dns_resolver_destroyfetch(&fetch);
|
dns_resolver_destroyfetch(&fetch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (want_destroy) {
|
dns_validator_detach(&val);
|
||||||
destroy(val);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
@ -464,7 +449,7 @@ fetch_callback_ds(void *arg) {
|
|||||||
isc_result_t eresult = resp->result;
|
isc_result_t eresult = resp->result;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_fetch_t *fetch = NULL;
|
dns_fetch_t *fetch = NULL;
|
||||||
bool want_destroy, trustchain;
|
bool trustchain;
|
||||||
|
|
||||||
INSIST(resp->type == FETCHDONE);
|
INSIST(resp->type == FETCHDONE);
|
||||||
|
|
||||||
@ -592,16 +577,13 @@ fetch_callback_ds(void *arg) {
|
|||||||
done:
|
done:
|
||||||
|
|
||||||
isc_mem_putanddetach(&resp->mctx, resp, sizeof(*resp));
|
isc_mem_putanddetach(&resp->mctx, resp, sizeof(*resp));
|
||||||
want_destroy = exit_check(val);
|
|
||||||
UNLOCK(&val->lock);
|
UNLOCK(&val->lock);
|
||||||
|
|
||||||
if (fetch != NULL) {
|
if (fetch != NULL) {
|
||||||
dns_resolver_destroyfetch(&fetch);
|
dns_resolver_destroyfetch(&fetch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (want_destroy) {
|
dns_validator_detach(&val);
|
||||||
destroy(val);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
@ -616,9 +598,9 @@ validator_callback_dnskey(void *arg) {
|
|||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_result_t eresult = subvalidator->result;
|
isc_result_t eresult = subvalidator->result;
|
||||||
isc_result_t saved_result;
|
isc_result_t saved_result;
|
||||||
bool want_destroy;
|
|
||||||
|
|
||||||
val->subvalidator = NULL;
|
val->subvalidator = NULL;
|
||||||
|
subvalidator->parent = NULL;
|
||||||
|
|
||||||
validator_log(val, ISC_LOG_DEBUG(3), "in validator_callback_dnskey");
|
validator_log(val, ISC_LOG_DEBUG(3), "in validator_callback_dnskey");
|
||||||
LOCK(&val->lock);
|
LOCK(&val->lock);
|
||||||
@ -658,13 +640,10 @@ validator_callback_dnskey(void *arg) {
|
|||||||
validator_done(val, DNS_R_BROKENCHAIN);
|
validator_done(val, DNS_R_BROKENCHAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_validator_destroy(&subvalidator);
|
|
||||||
|
|
||||||
want_destroy = exit_check(val);
|
|
||||||
UNLOCK(&val->lock);
|
UNLOCK(&val->lock);
|
||||||
if (want_destroy) {
|
|
||||||
destroy(val);
|
dns_validator_destroy(&subvalidator);
|
||||||
}
|
dns_validator_detach(&val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
@ -678,9 +657,9 @@ validator_callback_ds(void *arg) {
|
|||||||
dns_validator_t *val = subvalidator->parent;
|
dns_validator_t *val = subvalidator->parent;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_result_t eresult = subvalidator->result;
|
isc_result_t eresult = subvalidator->result;
|
||||||
bool want_destroy;
|
|
||||||
|
|
||||||
val->subvalidator = NULL;
|
val->subvalidator = NULL;
|
||||||
|
subvalidator->parent = NULL;
|
||||||
|
|
||||||
validator_log(val, ISC_LOG_DEBUG(3), "in validator_callback_ds");
|
validator_log(val, ISC_LOG_DEBUG(3), "in validator_callback_ds");
|
||||||
LOCK(&val->lock);
|
LOCK(&val->lock);
|
||||||
@ -720,14 +699,10 @@ validator_callback_ds(void *arg) {
|
|||||||
isc_result_totext(eresult));
|
isc_result_totext(eresult));
|
||||||
validator_done(val, DNS_R_BROKENCHAIN);
|
validator_done(val, DNS_R_BROKENCHAIN);
|
||||||
}
|
}
|
||||||
|
UNLOCK(&val->lock);
|
||||||
|
|
||||||
dns_validator_destroy(&subvalidator);
|
dns_validator_destroy(&subvalidator);
|
||||||
|
dns_validator_detach(&val);
|
||||||
want_destroy = exit_check(val);
|
|
||||||
UNLOCK(&val->lock);
|
|
||||||
if (want_destroy) {
|
|
||||||
destroy(val);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
@ -741,7 +716,6 @@ validator_callback_cname(void *arg) {
|
|||||||
dns_validator_t *val = subvalidator->parent;
|
dns_validator_t *val = subvalidator->parent;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_result_t eresult = subvalidator->result;
|
isc_result_t eresult = subvalidator->result;
|
||||||
bool want_destroy;
|
|
||||||
|
|
||||||
INSIST((val->attributes & VALATTR_INSECURITY) != 0);
|
INSIST((val->attributes & VALATTR_INSECURITY) != 0);
|
||||||
|
|
||||||
@ -768,13 +742,10 @@ validator_callback_cname(void *arg) {
|
|||||||
validator_done(val, DNS_R_BROKENCHAIN);
|
validator_done(val, DNS_R_BROKENCHAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_validator_destroy(&subvalidator);
|
|
||||||
|
|
||||||
want_destroy = exit_check(val);
|
|
||||||
UNLOCK(&val->lock);
|
UNLOCK(&val->lock);
|
||||||
if (want_destroy) {
|
|
||||||
destroy(val);
|
dns_validator_destroy(&subvalidator);
|
||||||
}
|
dns_validator_detach(&val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
@ -791,7 +762,6 @@ validator_callback_nsec(void *arg) {
|
|||||||
dns_rdataset_t *rdataset = subvalidator->rdataset;
|
dns_rdataset_t *rdataset = subvalidator->rdataset;
|
||||||
isc_result_t result = subvalidator->result;
|
isc_result_t result = subvalidator->result;
|
||||||
bool exists, data;
|
bool exists, data;
|
||||||
bool want_destroy;
|
|
||||||
|
|
||||||
val->subvalidator = NULL;
|
val->subvalidator = NULL;
|
||||||
|
|
||||||
@ -871,13 +841,10 @@ validator_callback_nsec(void *arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_validator_destroy(&subvalidator);
|
|
||||||
|
|
||||||
want_destroy = exit_check(val);
|
|
||||||
UNLOCK(&val->lock);
|
UNLOCK(&val->lock);
|
||||||
if (want_destroy) {
|
|
||||||
destroy(val);
|
dns_validator_destroy(&subvalidator);
|
||||||
}
|
dns_validator_detach(&val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
@ -993,10 +960,12 @@ create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
validator_logcreate(val, name, type, caller, "fetch");
|
validator_logcreate(val, name, type, caller, "fetch");
|
||||||
|
|
||||||
|
dns_validator_ref(val);
|
||||||
return (dns_resolver_createfetch(
|
return (dns_resolver_createfetch(
|
||||||
val->view->resolver, name, type, NULL, NULL, NULL, NULL, 0,
|
val->view->resolver, name, type, NULL, NULL, NULL, NULL, 0,
|
||||||
fopts, 0, NULL, val->loop, callback, val, &val->frdataset,
|
fopts, 0, NULL, isc_loop_current(val->loopmgr), callback, val,
|
||||||
&val->fsigrdataset, &val->fetch));
|
&val->frdataset, &val->fsigrdataset, &val->fetch));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
@ -1026,10 +995,10 @@ create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
|
|
||||||
validator_logcreate(val, name, type, caller, "validator");
|
validator_logcreate(val, name, type, caller, "validator");
|
||||||
result = dns_validator_create(val->view, name, type, rdataset, sig,
|
result = dns_validator_create(val->view, name, type, rdataset, sig,
|
||||||
NULL, vopts, val->loop, cb, val,
|
NULL, vopts, val->loopmgr, cb, val,
|
||||||
&val->subvalidator);
|
&val->subvalidator);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
val->subvalidator->parent = val;
|
dns_validator_attach(val, &val->subvalidator->parent);
|
||||||
val->subvalidator->depth = val->depth + 1;
|
val->subvalidator->depth = val->depth + 1;
|
||||||
}
|
}
|
||||||
return (result);
|
return (result);
|
||||||
@ -1239,6 +1208,7 @@ seek_dnskey(dns_validator_t *val) {
|
|||||||
dns_rdatatype_dnskey,
|
dns_rdatatype_dnskey,
|
||||||
fetch_callback_dnskey, "seek_dnskey");
|
fetch_callback_dnskey, "seek_dnskey");
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
dns_validator_detach(&val);
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
return (DNS_R_WAIT);
|
return (DNS_R_WAIT);
|
||||||
@ -1668,6 +1638,7 @@ get_dsset(dns_validator_t *val, dns_name_t *tname, isc_result_t *resp) {
|
|||||||
fetch_callback_ds, "validate_dnskey");
|
fetch_callback_ds, "validate_dnskey");
|
||||||
*resp = DNS_R_WAIT;
|
*resp = DNS_R_WAIT;
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
dns_validator_detach(&val);
|
||||||
*resp = result;
|
*resp = result;
|
||||||
}
|
}
|
||||||
return (ISC_R_COMPLETE);
|
return (ISC_R_COMPLETE);
|
||||||
@ -2923,7 +2894,6 @@ out:
|
|||||||
static void
|
static void
|
||||||
validator_start(void *arg) {
|
validator_start(void *arg) {
|
||||||
dns_validator_t *val = (dns_validator_t *)arg;
|
dns_validator_t *val = (dns_validator_t *)arg;
|
||||||
bool want_destroy = false;
|
|
||||||
isc_result_t result = ISC_R_FAILURE;
|
isc_result_t result = ISC_R_FAILURE;
|
||||||
|
|
||||||
if (CANCELED(val)) {
|
if (CANCELED(val)) {
|
||||||
@ -3014,21 +2984,19 @@ validator_start(void *arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result != DNS_R_WAIT) {
|
if (result != DNS_R_WAIT) {
|
||||||
want_destroy = exit_check(val);
|
|
||||||
validator_done(val, result);
|
validator_done(val, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLOCK(&val->lock);
|
UNLOCK(&val->lock);
|
||||||
if (want_destroy) {
|
|
||||||
destroy(val);
|
dns_validator_detach(&val);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
|
dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
|
||||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
|
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
|
||||||
dns_message_t *message, unsigned int options,
|
dns_message_t *message, unsigned int options,
|
||||||
isc_loop_t *loop, isc_job_cb cb, void *arg,
|
isc_loopmgr_t *loopmgr, isc_job_cb cb, void *arg,
|
||||||
dns_validator_t **validatorp) {
|
dns_validator_t **validatorp) {
|
||||||
isc_result_t result = ISC_R_FAILURE;
|
isc_result_t result = ISC_R_FAILURE;
|
||||||
dns_validator_t *val = NULL;
|
dns_validator_t *val = NULL;
|
||||||
@ -3046,9 +3014,12 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
.type = type,
|
.type = type,
|
||||||
.options = options,
|
.options = options,
|
||||||
.link = ISC_LINK_INITIALIZER,
|
.link = ISC_LINK_INITIALIZER,
|
||||||
.loop = loop,
|
.loopmgr = loopmgr,
|
||||||
.cb = cb,
|
.cb = cb,
|
||||||
.arg = arg };
|
.arg = arg };
|
||||||
|
|
||||||
|
isc_refcount_init(&val->references, 1);
|
||||||
|
|
||||||
if (message != NULL) {
|
if (message != NULL) {
|
||||||
dns_message_attach(message, &val->message);
|
dns_message_attach(message, &val->message);
|
||||||
}
|
}
|
||||||
@ -3070,7 +3041,8 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
val->magic = VALIDATOR_MAGIC;
|
val->magic = VALIDATOR_MAGIC;
|
||||||
|
|
||||||
if ((options & DNS_VALIDATOR_DEFER) == 0) {
|
if ((options & DNS_VALIDATOR_DEFER) == 0) {
|
||||||
isc_async_run(loop, validator_start, val);
|
dns_validator_ref(val);
|
||||||
|
isc_job_run(val->loopmgr, validator_start, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
*validatorp = val;
|
*validatorp = val;
|
||||||
@ -3098,7 +3070,8 @@ dns_validator_send(dns_validator_t *validator) {
|
|||||||
validator->options &= ~DNS_VALIDATOR_DEFER;
|
validator->options &= ~DNS_VALIDATOR_DEFER;
|
||||||
UNLOCK(&validator->lock);
|
UNLOCK(&validator->lock);
|
||||||
|
|
||||||
isc_async_run(validator->loop, validator_start, validator);
|
dns_validator_ref(validator);
|
||||||
|
isc_job_run(validator->loopmgr, validator_start, validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -3127,11 +3100,11 @@ dns_validator_cancel(dns_validator_t *validator) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy(dns_validator_t *val) {
|
destroy_validator(dns_validator_t *val) {
|
||||||
isc_mem_t *mctx = NULL;
|
isc_mem_t *mctx = NULL;
|
||||||
|
|
||||||
REQUIRE(SHUTDOWN(val));
|
|
||||||
REQUIRE(val->fetch == NULL);
|
REQUIRE(val->fetch == NULL);
|
||||||
|
REQUIRE(val->subvalidator == NULL);
|
||||||
|
|
||||||
val->magic = 0;
|
val->magic = 0;
|
||||||
if (val->key != NULL) {
|
if (val->key != NULL) {
|
||||||
@ -3159,7 +3132,6 @@ destroy(dns_validator_t *val) {
|
|||||||
void
|
void
|
||||||
dns_validator_destroy(dns_validator_t **validatorp) {
|
dns_validator_destroy(dns_validator_t **validatorp) {
|
||||||
dns_validator_t *val = NULL;
|
dns_validator_t *val = NULL;
|
||||||
bool want_destroy = false;
|
|
||||||
|
|
||||||
REQUIRE(validatorp != NULL);
|
REQUIRE(validatorp != NULL);
|
||||||
|
|
||||||
@ -3169,15 +3141,10 @@ dns_validator_destroy(dns_validator_t **validatorp) {
|
|||||||
REQUIRE(VALID_VALIDATOR(val));
|
REQUIRE(VALID_VALIDATOR(val));
|
||||||
|
|
||||||
LOCK(&val->lock);
|
LOCK(&val->lock);
|
||||||
|
|
||||||
val->attributes |= VALATTR_SHUTDOWN;
|
|
||||||
validator_log(val, ISC_LOG_DEBUG(4), "dns_validator_destroy");
|
validator_log(val, ISC_LOG_DEBUG(4), "dns_validator_destroy");
|
||||||
|
|
||||||
want_destroy = exit_check(val);
|
|
||||||
UNLOCK(&val->lock);
|
UNLOCK(&val->lock);
|
||||||
if (want_destroy) {
|
|
||||||
destroy(val);
|
dns_validator_detach(&val);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -3256,3 +3223,9 @@ validator_logcreate(dns_validator_t *val, dns_name_t *name,
|
|||||||
validator_log(val, ISC_LOG_DEBUG(9), "%s: creating %s for %s %s",
|
validator_log(val, ISC_LOG_DEBUG(9), "%s: creating %s for %s %s",
|
||||||
caller, operation, namestr, typestr);
|
caller, operation, namestr, typestr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DNS_VALIDATOR_TRACE
|
||||||
|
ISC_REFCOUNT_TRACE_IMPL(dns_validator, destroy_validator);
|
||||||
|
#else
|
||||||
|
ISC_REFCOUNT_IMPL(dns_validator, destroy_validator);
|
||||||
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user