]> 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 14:41:02 +0000 (16:41 +0200)
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.

(cherry picked from commit 8a96a3af6a36c0e1b324fe5a026f26ab4f12700b)

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

index 7c642553fd35e87b12e1d3726d3e510704031b23..ab957ca207b00e19bad52d80bb0f98bac4a8f252 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>
 #include <isc/string.h>
@@ -186,6 +189,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 +3222,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 +3260,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 814551d759e77993ef502e9218c45b4fbac6ad97..a46f17a80ee4c1ea2174d2d0bb1dd91dfc70b225 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/md.h>
 #include <isc/mem.h>
@@ -126,6 +127,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);
@@ -354,6 +357,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;
@@ -363,6 +369,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
@@ -421,9 +429,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);
                }
@@ -597,9 +604,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);
                }
@@ -1183,9 +1189,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;
 
@@ -1564,6 +1569,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;
@@ -1598,6 +1606,8 @@ validate_answer_signing_key(void *arg) {
        } else {
                INSIST(val->key == NULL);
        }
+
+       (void)validate_async_run(val, validate_answer_signing_key_done);
 }
 
 static void
@@ -1608,8 +1618,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;
        }
 
@@ -1671,8 +1680,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:
@@ -1793,6 +1801,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 &&
@@ -2027,6 +2041,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;
@@ -2041,6 +2058,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
@@ -2063,8 +2082,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;
        }
 
@@ -2086,8 +2104,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;
                }
        }
@@ -3383,7 +3401,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,
@@ -3480,6 +3498,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));
 }