]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
refactor update processing to use loop callbacks
authorEvan Hunt <each@isc.org>
Thu, 27 Oct 2022 06:35:47 +0000 (23:35 -0700)
committerOndřej Surý <ondrej@isc.org>
Thu, 16 Feb 2023 15:34:20 +0000 (16:34 +0100)
update processing now uses loop callbacks instead of task events.

lib/ns/client.c
lib/ns/include/ns/client.h
lib/ns/update.c

index 54e44e2f5134f088dde4f1ca19f7e6259fe575c5..335508d65b28f9c8d6cfc7cadff6303ac7607e15 100644 (file)
@@ -2432,6 +2432,7 @@ ns_clientmgr_create(ns_server_t *sctx, isc_taskmgr_t *taskmgr,
        manager->taskmgr = taskmgr;
        manager->loopmgr = loopmgr;
        manager->tid = tid;
+       manager->loop = isc_loop_get(loopmgr, tid);
 
        dns_aclenv_attach(aclenv, &manager->aclenv);
 
index 1f92486f61ac4bf4c7be40144439df1b7fc9e9d4..e1701371d59b7a9b2db7d3b67b90a64b81280848 100644 (file)
@@ -149,9 +149,8 @@ struct ns_clientmgr {
        isc_loopmgr_t *loopmgr;
        isc_refcount_t references;
        uint32_t       tid;
-
-       /* Attached by clients, needed for e.g. recursion */
-       isc_task_t *task;
+       isc_task_t    *task;
+       isc_loop_t    *loop;
 
        dns_aclenv_t *aclenv;
 
index 8ad4ea7f4f2ff3c9de74719d9618716264bb6929..9b0e325a985a53e0e54824e62d917fdfb4046bab 100644 (file)
@@ -14,6 +14,7 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
+#include <isc/async.h>
 #include <isc/netaddr.h>
 #include <isc/serial.h>
 #include <isc/stats.h>
@@ -24,7 +25,6 @@
 #include <dns/dbiterator.h>
 #include <dns/diff.h>
 #include <dns/dnssec.h>
-#include <dns/events.h>
 #include <dns/fixedname.h>
 #include <dns/journal.h>
 #include <dns/keyvalues.h>
@@ -222,11 +222,11 @@ struct rr {
        dns_rdata_t rdata;
 };
 
-typedef struct update_event update_event_t;
+typedef struct update update_t;
 
-struct update_event {
-       ISC_EVENT_COMMON(update_event_t);
+struct update {
        dns_zone_t *zone;
+       ns_client_t *client;
        isc_result_t result;
        dns_message_t *answer;
        const dns_ssurule_t **rules;
@@ -261,13 +261,13 @@ typedef struct {
  */
 
 static void
-update_action(isc_task_t *task, isc_event_t *event);
+update_action(void *arg);
 static void
-updatedone_action(isc_task_t *task, isc_event_t *event);
+updatedone_action(void *arg);
 static isc_result_t
-send_forward_event(ns_client_t *client, dns_zone_t *zone);
+send_forward(ns_client_t *client, dns_zone_t *zone);
 static void
-forward_done(isc_task_t *task, isc_event_t *event);
+forward_done(void *arg);
 static isc_result_t
 add_rr_prepare_action(void *data, rr_t *rr);
 static isc_result_t
@@ -1644,10 +1644,8 @@ check_soa_increment(dns_db_t *db, dns_dbversion_t *ver,
  */
 
 static isc_result_t
-send_update_event(ns_client_t *client, dns_zone_t *zone) {
+send_update(ns_client_t *client, dns_zone_t *zone) {
        isc_result_t result = ISC_R_SUCCESS;
-       update_event_t *event = NULL;
-       isc_task_t *zonetask = NULL;
        dns_ssutable_t *ssutable = NULL;
        dns_message_t *request = client->message;
        isc_mem_t *mctx = client->manager->mctx;
@@ -1660,6 +1658,7 @@ send_update_event(ns_client_t *client, dns_zone_t *zone) {
        dns_zoneopt_t options;
        dns_db_t *db = NULL;
        dns_dbversion_t *ver = NULL;
+       update_t *uev = NULL;
 
        CHECK(dns_zone_getdb(zone, &db));
        zonename = dns_db_origin(db);
@@ -1894,18 +1893,18 @@ send_update_event(ns_client_t *client, dns_zone_t *zone) {
                CHECK(DNS_R_DROP);
        }
 
-       event = (update_event_t *)isc_event_allocate(
-               client->manager->mctx, client, DNS_EVENT_UPDATE, update_action,
-               client, sizeof(*event));
-       event->zone = zone;
-       event->result = ISC_R_SUCCESS;
-       event->rules = rules;
-       event->ruleslen = ruleslen;
-       rules = NULL;
+       uev = isc_mem_get(client->manager->mctx, sizeof(*uev));
+       *uev = (update_t){
+               .zone = zone,
+               .client = client,
+               .rules = rules,
+               .ruleslen = ruleslen,
+               .result = ISC_R_SUCCESS,
+       };
 
        isc_nmhandle_attach(client->handle, &client->updatehandle);
-       dns_zone_gettask(zone, &zonetask);
-       isc_task_send(zonetask, ISC_EVENT_PTR(&event));
+       isc_async_run(dns_zone_getloop(zone), update_action, uev);
+       rules = NULL;
 
 failure:
        if (db != NULL) {
@@ -2024,12 +2023,12 @@ ns_update_start(ns_client_t *client, isc_nmhandle_t *handle,
                        FAIL(sigresult);
                }
                dns_message_clonebuffer(client->message);
-               CHECK(send_update_event(client, zone));
+               CHECK(send_update(client, zone));
                break;
        case dns_zone_secondary:
        case dns_zone_mirror:
                dns_message_clonebuffer(client->message);
-               CHECK(send_forward_event(client, zone));
+               CHECK(send_forward(client, zone));
                break;
        default:
                FAILC(DNS_R_NOTAUTH, "not authoritative for update zone");
@@ -2043,7 +2042,7 @@ failure:
 
        /*
         * We failed without having sent an update event to the zone.
-        * We are still in the client task context, so we can
+        * We are still in the client context, so we can
         * simply give an error response without switching tasks.
         */
        if (result == DNS_R_DROP) {
@@ -2882,10 +2881,10 @@ isdnssec(dns_db_t *db, dns_dbversion_t *ver, dns_rdatatype_t privatetype) {
 }
 
 static void
-update_action(isc_task_t *task, isc_event_t *event) {
-       update_event_t *uev = (update_event_t *)event;
+update_action(void *arg) {
+       update_t *uev = (update_t *)arg;
        dns_zone_t *zone = uev->zone;
-       ns_client_t *client = (ns_client_t *)event->ev_arg;
+       ns_client_t *client = uev->client;
        const dns_ssurule_t **rules = uev->rules;
        size_t rule = 0, ruleslen = uev->ruleslen;
        isc_result_t result;
@@ -2910,8 +2909,6 @@ update_action(isc_task_t *task, isc_event_t *event) {
        uint32_t maxrecords;
        uint64_t records;
 
-       INSIST(event->ev_type == DNS_EVENT_UPDATE);
-
        dns_diff_init(mctx, &diff);
        dns_diff_init(mctx, &temp);
 
@@ -3588,29 +3585,20 @@ common:
                dns_ssutable_detach(&ssutable);
        }
 
-       isc_task_detach(&task);
        uev->result = result;
        if (zone != NULL) {
                INSIST(uev->zone == zone); /* we use this later */
        }
-       uev->ev_type = DNS_EVENT_UPDATEDONE;
-       uev->ev_action = updatedone_action;
-
-       isc_task_send(client->manager->task, &event);
 
+       isc_async_run(client->manager->loop, updatedone_action, uev);
        INSIST(ver == NULL);
-       INSIST(event == NULL);
 }
 
 static void
-updatedone_action(isc_task_t *task, isc_event_t *event) {
-       update_event_t *uev = (update_event_t *)event;
-       ns_client_t *client = (ns_client_t *)event->ev_arg;
-
-       UNUSED(task);
+updatedone_action(void *arg) {
+       update_t *uev = (update_t *)arg;
+       ns_client_t *client = uev->client;
 
-       REQUIRE(event->ev_type == DNS_EVENT_UPDATEDONE);
-       REQUIRE(task == client->manager->task);
        REQUIRE(client->updatehandle == client->handle);
 
        switch (uev->result) {
@@ -3624,14 +3612,14 @@ updatedone_action(isc_task_t *task, isc_event_t *event) {
                inc_stats(client, uev->zone, ns_statscounter_updatefail);
                break;
        }
-       if (uev->zone != NULL) {
-               dns_zone_detach(&uev->zone);
-       }
 
        respond(client, uev->result);
 
        isc_quota_detach(&(isc_quota_t *){ &client->manager->sctx->updquota });
-       isc_event_free(&event);
+       if (uev->zone != NULL) {
+               dns_zone_detach(&uev->zone);
+       }
+       isc_mem_put(client->manager->mctx, uev, sizeof(*uev));
        isc_nmhandle_detach(&client->updatehandle);
 }
 
@@ -3639,85 +3627,74 @@ updatedone_action(isc_task_t *task, isc_event_t *event) {
  * Update forwarding support.
  */
 static void
-forward_fail(isc_task_t *task, isc_event_t *event) {
-       ns_client_t *client = (ns_client_t *)event->ev_arg;
-
-       UNUSED(task);
+forward_fail(void *arg) {
+       update_t *uev = (update_t *)arg;
+       ns_client_t *client = uev->client;
 
        respond(client, DNS_R_SERVFAIL);
 
        isc_quota_detach(&(isc_quota_t *){ &client->manager->sctx->updquota });
-       isc_event_free(&event);
+       isc_mem_put(client->manager->mctx, uev, sizeof(*uev));
        isc_nmhandle_detach(&client->updatehandle);
 }
 
 static void
 forward_callback(void *arg, isc_result_t result, dns_message_t *answer) {
-       update_event_t *uev = arg;
-       ns_client_t *client = uev->ev_arg;
+       update_t *uev = (update_t *)arg;
+       ns_client_t *client = uev->client;
        dns_zone_t *zone = uev->zone;
 
        if (result != ISC_R_SUCCESS) {
                INSIST(answer == NULL);
-               uev->ev_type = DNS_EVENT_UPDATEDONE;
-               uev->ev_action = forward_fail;
                inc_stats(client, zone, ns_statscounter_updatefwdfail);
+               isc_async_run(client->manager->loop, forward_fail, uev);
        } else {
-               uev->ev_type = DNS_EVENT_UPDATEDONE;
-               uev->ev_action = forward_done;
                uev->answer = answer;
                inc_stats(client, zone, ns_statscounter_updaterespfwd);
+               isc_async_run(client->manager->loop, forward_done, uev);
        }
 
-       isc_task_send(client->manager->task, ISC_EVENT_PTR(&uev));
        dns_zone_detach(&zone);
 }
 
 static void
-forward_done(isc_task_t *task, isc_event_t *event) {
-       update_event_t *uev = (update_event_t *)event;
-       ns_client_t *client = (ns_client_t *)event->ev_arg;
-
-       UNUSED(task);
+forward_done(void *arg) {
+       update_t *uev = (update_t *)arg;
+       ns_client_t *client = uev->client;
 
        ns_client_sendraw(client, uev->answer);
        dns_message_detach(&uev->answer);
 
        isc_quota_detach(&(isc_quota_t *){ &client->manager->sctx->updquota });
-       isc_event_free(&event);
+       isc_mem_put(client->manager->mctx, uev, sizeof(*uev));
        isc_nmhandle_detach(&client->reqhandle);
        isc_nmhandle_detach(&client->updatehandle);
 }
 
 static void
-forward_action(isc_task_t *task, isc_event_t *event) {
-       update_event_t *uev = (update_event_t *)event;
+forward_action(void *arg) {
+       update_t *uev = (update_t *)arg;
        dns_zone_t *zone = uev->zone;
-       ns_client_t *client = (ns_client_t *)event->ev_arg;
+       ns_client_t *client = uev->client;
        isc_result_t result;
 
        result = dns_zone_forwardupdate(zone, client->message, forward_callback,
-                                       event);
+                                       uev);
        if (result != ISC_R_SUCCESS) {
-               uev->ev_type = DNS_EVENT_UPDATEDONE;
-               uev->ev_action = forward_fail;
-               isc_task_send(client->manager->task, &event);
+               isc_async_run(client->manager->loop, forward_fail, uev);
                inc_stats(client, zone, ns_statscounter_updatefwdfail);
                dns_zone_detach(&zone);
        } else {
                inc_stats(client, zone, ns_statscounter_updatereqfwd);
        }
-
-       isc_task_detach(&task);
 }
 
 static isc_result_t
-send_forward_event(ns_client_t *client, dns_zone_t *zone) {
+send_forward(ns_client_t *client, dns_zone_t *zone) {
+       isc_result_t result = ISC_R_SUCCESS;
        char namebuf[DNS_NAME_FORMATSIZE];
        char classbuf[DNS_RDATACLASS_FORMATSIZE];
-       isc_result_t result = ISC_R_SUCCESS;
-       update_event_t *event = NULL;
-       isc_task_t *zonetask = NULL;
+       update_t *uev = NULL;
 
        result = checkupdateacl(client, dns_zone_getforwardacl(zone),
                                "update forwarding", dns_zone_getorigin(zone),
@@ -3737,13 +3714,12 @@ send_forward_event(ns_client_t *client, dns_zone_t *zone) {
                return (DNS_R_DROP);
        }
 
-       event = (update_event_t *)isc_event_allocate(
-               client->manager->mctx, client, DNS_EVENT_UPDATE, forward_action,
-               NULL, sizeof(*event));
-       event->zone = zone;
-       event->result = ISC_R_SUCCESS;
-
-       event->ev_arg = client;
+       uev = isc_mem_get(client->manager->mctx, sizeof(*uev));
+       *uev = (update_t){
+               .zone = zone,
+               .client = client,
+               .result = ISC_R_SUCCESS,
+       };
 
        dns_name_format(dns_zone_getorigin(zone), namebuf, sizeof(namebuf));
        dns_rdataclass_format(dns_zone_getclass(zone), classbuf,
@@ -3753,12 +3729,8 @@ send_forward_event(ns_client_t *client, dns_zone_t *zone) {
                      LOGLEVEL_PROTOCOL, "forwarding update for zone '%s/%s'",
                      namebuf, classbuf);
 
-       dns_zone_gettask(zone, &zonetask);
        isc_nmhandle_attach(client->handle, &client->updatehandle);
-       isc_task_send(zonetask, ISC_EVENT_PTR(&event));
+       isc_async_run(dns_zone_getloop(zone), forward_action, uev);
 
-       if (event != NULL) {
-               isc_event_free(ISC_EVENT_PTR(&event));
-       }
        return (result);
 }