From: Ondřej Surý Date: Mon, 9 Sep 2024 12:39:14 +0000 (+0200) Subject: Move offloaded DNSSEC operations to different helper threads X-Git-Tag: v9.21.2~40^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8a96a3af6a36c0e1b324fe5a026f26ab4f12700b;p=thirdparty%2Fbind9.git Move offloaded DNSSEC operations to different helper threads Currently, the isc_work API is overloaded. It runs both the CPU-intensive operations like DNSSEC validations and long-term tasks like RPZ processing, CATZ processing, zone file loading/dumping and few others. Under specific circumstances, when many large zones are being loaded, or RPZ zones processed, this stops the CPU-intensive tasks and the DNSSEC validation is practically stopped until the long-running tasks are finished. As this is undesireable, this commit moves the CPU-intensive operations from the isc_work API to the isc_helper API that only runs fast memory cleanups now. --- diff --git a/lib/dns/message.c b/lib/dns/message.c index 6565cbf09d0..a2f766ed159 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -21,9 +21,11 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -186,6 +188,7 @@ msgblock_allocate(isc_mem_t *, unsigned int, unsigned int); * asynchronously. */ typedef struct checksig_ctx { + isc_loop_t *loop; dns_message_t *msg; dns_view_t *view; dns_message_cb_t cb; @@ -3218,21 +3221,27 @@ dns_message_dumpsig(dns_message_t *msg, char *txt1) { } #endif /* ifdef SKAN_MSG_DEBUG */ +static void +checksig_done(void *arg); + static void checksig_run(void *arg) { checksig_ctx_t *chsigctx = arg; chsigctx->result = dns_message_checksig(chsigctx->msg, chsigctx->view); + + isc_async_run(chsigctx->loop, checksig_done, chsigctx); } static void -checksig_cb(void *arg) { +checksig_done(void *arg) { checksig_ctx_t *chsigctx = arg; dns_message_t *msg = chsigctx->msg; chsigctx->cb(chsigctx->cbarg, chsigctx->result); dns_view_detach(&chsigctx->view); + isc_loop_detach(&chsigctx->loop); isc_mem_put(msg->mctx, chsigctx, sizeof(*chsigctx)); dns_message_detach(&msg); } @@ -3250,12 +3259,13 @@ dns_message_checksig_async(dns_message_t *msg, dns_view_t *view, .cb = cb, .cbarg = cbarg, .result = ISC_R_UNSET, + .loop = isc_loop_ref(loop), }; dns_message_attach(msg, &chsigctx->msg); dns_view_attach(view, &chsigctx->view); dns_message_clonebuffer(msg); - isc_work_enqueue(loop, checksig_run, checksig_cb, chsigctx); + isc_helper_run(loop, checksig_run, chsigctx); return (DNS_R_WAIT); } diff --git a/lib/dns/validator.c b/lib/dns/validator.c index 62f60c7c420..ce5d04205d0 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -127,6 +128,8 @@ static void validate_async_done(dns_validator_t *val, isc_result_t result); static isc_result_t validate_async_run(dns_validator_t *val, isc_job_cb cb); +static isc_result_t +validate_helper_run(dns_validator_t *val, isc_job_cb cb); static void validate_dnskey(void *arg); @@ -355,6 +358,9 @@ trynsec3: return (found); } +static void +resume_answer_with_key_done(void *arg); + static void resume_answer_with_key(void *arg) { dns_validator_t *val = arg; @@ -364,6 +370,8 @@ resume_answer_with_key(void *arg) { if (result == ISC_R_SUCCESS) { val->keyset = &val->frdataset; } + + (void)validate_async_run(val, resume_answer_with_key_done); } static void @@ -422,9 +430,8 @@ fetch_callback_dnskey(void *arg) { if (eresult == ISC_R_SUCCESS && rdataset->trust >= dns_trust_secure) { - isc_work_enqueue(val->loop, resume_answer_with_key, - resume_answer, val); - result = DNS_R_WAIT; + result = validate_helper_run(val, + resume_answer_with_key); } else { result = validate_async_run(val, resume_answer); } @@ -598,9 +605,8 @@ validator_callback_dnskey(void *arg) { * Only extract the dst key if the keyset is secure. */ if (val->frdataset.trust >= dns_trust_secure) { - isc_work_enqueue(val->loop, resume_answer_with_key, - resume_answer_with_key_done, val); - result = DNS_R_WAIT; + result = validate_helper_run(val, + resume_answer_with_key); } else { result = validate_async_run(val, resume_answer); } @@ -1184,9 +1190,8 @@ seek_dnskey(dns_validator_t *val) { dns_rdataset_disassociate(&val->fsigrdataset); } - isc_work_enqueue(val->loop, resume_answer_with_key, - resume_answer_with_key_done, val); - return (DNS_R_WAIT); + return (validate_helper_run(val, + resume_answer_with_key)); } break; @@ -1565,6 +1570,9 @@ cleanup: static void validate_answer_finish(void *arg); +static void +validate_answer_signing_key_done(void *arg); + static void validate_answer_signing_key(void *arg) { dns_validator_t *val = arg; @@ -1599,6 +1607,8 @@ validate_answer_signing_key(void *arg) { } else { INSIST(val->key == NULL); } + + (void)validate_async_run(val, validate_answer_signing_key_done); } static void @@ -1609,8 +1619,7 @@ validate_answer_signing_key_done(void *arg) { val->result = ISC_R_CANCELED; } else if (val->key != NULL) { /* Process with next key if we selected one */ - isc_work_enqueue(val->loop, validate_answer_signing_key, - validate_answer_signing_key_done, val); + (void)validate_helper_run(val, validate_answer_signing_key); return; } @@ -1672,8 +1681,7 @@ validate_answer_process(void *arg) { goto next_key; } - isc_work_enqueue(val->loop, validate_answer_signing_key, - validate_answer_signing_key_done, val); + (void)validate_helper_run(val, validate_answer_signing_key); return; next_key: @@ -1794,6 +1802,12 @@ validate_async_run(dns_validator_t *val, isc_job_cb cb) { return (DNS_R_WAIT); } +static isc_result_t +validate_helper_run(dns_validator_t *val, isc_job_cb cb) { + isc_helper_run(val->loop, cb, val); + return (DNS_R_WAIT); +} + static void validate_async_done(dns_validator_t *val, isc_result_t result) { if (result == DNS_R_NOVALIDSIG && @@ -2028,6 +2042,9 @@ validate_dnskey_dsset(dns_validator_t *val) { return (ISC_R_SUCCESS); } +static void +validate_dnskey_dsset_next_done(void *arg); + static void validate_dnskey_dsset_next(void *arg) { dns_validator_t *val = arg; @@ -2042,6 +2059,8 @@ validate_dnskey_dsset_next(void *arg) { /* continue async run */ val->result = validate_dnskey_dsset(val); } + + validate_async_run(val, validate_dnskey_dsset_next_done); } static void @@ -2064,8 +2083,7 @@ validate_dnskey_dsset_next_done(void *arg) { break; default: /* Continue validation until we have success or no more data */ - isc_work_enqueue(val->loop, validate_dnskey_dsset_next, - validate_dnskey_dsset_next_done, val); + (void)validate_helper_run(val, validate_dnskey_dsset_next); return; } @@ -2087,8 +2105,8 @@ validate_dnskey_dsset_first(dns_validator_t *val) { /* continue async run */ result = validate_dnskey_dsset(val); if (result != ISC_R_SUCCESS) { - isc_work_enqueue(val->loop, validate_dnskey_dsset_next, - validate_dnskey_dsset_next_done, val); + (void)validate_helper_run(val, + validate_dnskey_dsset_next); return; } } @@ -3384,7 +3402,7 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, .options = options, .keytable = kt, .link = ISC_LINK_INITIALIZER, - .loop = loop, + .loop = isc_loop_ref(loop), .cb = cb, .arg = arg, .rdata = DNS_RDATA_INIT, @@ -3481,6 +3499,7 @@ destroy_validator(dns_validator_t *val) { isc_counter_detach(&val->qc); } dns_view_detach(&val->view); + isc_loop_detach(&val->loop); isc_mem_put(mctx, val, sizeof(*val)); }