]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Move offloaded DNSSEC operations to different helper threads
authorOndřej Surý <ondrej@isc.org>
Mon, 9 Sep 2024 12:39:14 +0000 (14:39 +0200)
committerOndřej Surý <ondrej@isc.org>
Thu, 12 Sep 2024 12:09:45 +0000 (12:09 +0000)
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.

lib/dns/message.c
lib/dns/validator.c

index 6565cbf09d01adf22509a0fd87466101f6a9a132..a2f766ed159aab73cc0a8be71044320d5bd9002d 100644 (file)
 #include <inttypes.h>
 #include <stdbool.h>
 
+#include <isc/async.h>
 #include <isc/buffer.h>
 #include <isc/hash.h>
 #include <isc/hashmap.h>
+#include <isc/helper.h>
 #include <isc/log.h>
 #include <isc/mem.h>
 #include <isc/result.h>
@@ -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);
 }
index 62f60c7c42082660d8b5c4fd15d61c13d9c3a9c0..ce5d04205d04adc3220dfcfacc9d5a8ce4996d29 100644 (file)
@@ -17,6 +17,7 @@
 #include <isc/async.h>
 #include <isc/base32.h>
 #include <isc/counter.h>
+#include <isc/helper.h>
 #include <isc/job.h>
 #include <isc/log.h>
 #include <isc/md.h>
@@ -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));
 }