#include <inttypes.h>
#include <stdbool.h>
+#include <isc/async.h>
#include <isc/netaddr.h>
#include <isc/serial.h>
#include <isc/stats.h>
#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>
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;
*/
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
*/
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;
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);
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) {
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");
/*
* 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) {
}
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;
uint32_t maxrecords;
uint64_t records;
- INSIST(event->ev_type == DNS_EVENT_UPDATE);
-
dns_diff_init(mctx, &diff);
dns_diff_init(mctx, &temp);
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) {
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);
}
* 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),
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,
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);
}