mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
refactor update processing to use loop callbacks
update processing now uses loop callbacks instead of task events.
This commit is contained in:
150
lib/ns/update.c
150
lib/ns/update.c
@@ -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;
|
||||
updatedone_action(void *arg) {
|
||||
update_t *uev = (update_t *)arg;
|
||||
ns_client_t *client = uev->client;
|
||||
|
||||
UNUSED(task);
|
||||
|
||||
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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user