mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 22:15:20 +00:00
refactor dns_adb to use loop callbacks
The callbacks from dns_abd_createfind() are now posted using isc_async_run() instead of isc_task_send(). ADB event types have been replaced with a new dns_adbstatus_t type which is included as find->status. (The ADB still uses a task for dns_resolver_createfetch().)
This commit is contained in:
145
lib/dns/adb.c
145
lib/dns/adb.c
@@ -11,19 +11,13 @@
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
*
|
||||
* \note
|
||||
* In finds, if task == NULL, no events will be generated, and no events
|
||||
* have been sent. If task != NULL but taskaction == NULL, an event has been
|
||||
* posted but not yet freed. If neither are NULL, no event was posted.
|
||||
*
|
||||
*/
|
||||
/*! \file */
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <isc/async.h>
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/hashmap.h>
|
||||
#include <isc/list.h>
|
||||
@@ -364,13 +358,13 @@ clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *);
|
||||
static void
|
||||
clean_target(dns_adb_t *, dns_name_t *);
|
||||
static void
|
||||
clean_finds_at_name(dns_adbname_t *, isc_eventtype_t, unsigned int);
|
||||
clean_finds_at_name(dns_adbname_t *, dns_adbstatus_t, unsigned int);
|
||||
static void
|
||||
maybe_expire_namehooks(dns_adbname_t *, isc_stdtime_t);
|
||||
static bool
|
||||
maybe_expire_name(dns_adbname_t *adbname, isc_stdtime_t now);
|
||||
static void
|
||||
expire_name(dns_adbname_t *adbname, isc_eventtype_t evtype);
|
||||
expire_name(dns_adbname_t *adbname, dns_adbstatus_t astat);
|
||||
static bool
|
||||
entry_expired(dns_adbentry_t *adbentry, isc_stdtime_t now);
|
||||
static bool
|
||||
@@ -399,10 +393,8 @@ log_quota(dns_adbentry_t *entry, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
|
||||
/*
|
||||
* MUST NOT overlap DNS_ADBFIND_* flags!
|
||||
*/
|
||||
#define FIND_EVENT_SENT 0x40000000
|
||||
#define FIND_EVENT_FREED 0x80000000
|
||||
#define FIND_EVENTSENT(h) (((h)->flags & FIND_EVENT_SENT) != 0)
|
||||
#define FIND_EVENTFREED(h) (((h)->flags & FIND_EVENT_FREED) != 0)
|
||||
#define FIND_EVENT_SENT 0x40000000
|
||||
#define FIND_EVENTSENT(h) (((h)->flags & FIND_EVENT_SENT) != 0)
|
||||
|
||||
#define NAME_IS_DEAD 0x40000000
|
||||
#define NAME_STARTATZONE DNS_ADBFIND_STARTATZONE
|
||||
@@ -674,7 +666,7 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
|
||||
* Requires the name to be locked.
|
||||
*/
|
||||
static void
|
||||
expire_name(dns_adbname_t *adbname, isc_eventtype_t evtype) {
|
||||
expire_name(dns_adbname_t *adbname, dns_adbstatus_t astat) {
|
||||
REQUIRE(DNS_ADBNAME_VALID(adbname));
|
||||
REQUIRE(DNS_ADB_VALID(adbname->adb));
|
||||
|
||||
@@ -688,7 +680,7 @@ expire_name(dns_adbname_t *adbname, isc_eventtype_t evtype) {
|
||||
* are destructive in that they will always empty the lists
|
||||
* of finds and namehooks.
|
||||
*/
|
||||
clean_finds_at_name(adbname, evtype, DNS_ADBFIND_ADDRESSMASK);
|
||||
clean_finds_at_name(adbname, astat, DNS_ADBFIND_ADDRESSMASK);
|
||||
clean_namehooks(adb, &adbname->v4);
|
||||
clean_namehooks(adb, &adbname->v6);
|
||||
clean_target(adb, &adbname->target);
|
||||
@@ -777,7 +769,7 @@ shutdown_names(dns_adb_t *adb) {
|
||||
* all the fetches are canceled, the name will destroy
|
||||
* itself.
|
||||
*/
|
||||
expire_name(name, DNS_EVENT_ADBSHUTDOWN);
|
||||
expire_name(name, DNS_ADB_SHUTTINGDOWN);
|
||||
UNLOCK(&name->lock);
|
||||
dns_adbname_detach(&name);
|
||||
}
|
||||
@@ -904,33 +896,17 @@ set_target(dns_adb_t *adb, const dns_name_t *name, const dns_name_t *fname,
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
event_freefind(isc_event_t *event) {
|
||||
dns_adbfind_t *find = NULL;
|
||||
|
||||
REQUIRE(event != NULL);
|
||||
|
||||
find = event->ev_destroy_arg;
|
||||
|
||||
REQUIRE(DNS_ADBFIND_VALID(find));
|
||||
|
||||
LOCK(&find->lock);
|
||||
find->flags |= FIND_EVENT_FREED;
|
||||
event->ev_destroy_arg = NULL;
|
||||
UNLOCK(&find->lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* The name must be locked.
|
||||
*/
|
||||
static void
|
||||
clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
|
||||
clean_finds_at_name(dns_adbname_t *name, dns_adbstatus_t astat,
|
||||
unsigned int addrs) {
|
||||
dns_adbfind_t *find = NULL, *next = NULL;
|
||||
|
||||
DP(ENTER_LEVEL,
|
||||
"ENTER clean_finds_at_name, name %p, evtype %08x, addrs %08x", name,
|
||||
evtype, addrs);
|
||||
"ENTER clean_finds_at_name, name %p, astat %08x, addrs %08x", name,
|
||||
astat, addrs);
|
||||
|
||||
for (find = ISC_LIST_HEAD(name->finds); find != NULL; find = next) {
|
||||
bool process = false;
|
||||
@@ -942,16 +918,16 @@ clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
|
||||
wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
|
||||
notify = wanted & addrs;
|
||||
|
||||
switch (evtype) {
|
||||
case DNS_EVENT_ADBMOREADDRESSES:
|
||||
DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBMOREADDRESSES");
|
||||
switch (astat) {
|
||||
case DNS_ADB_MOREADDRESSES:
|
||||
DP(ISC_LOG_DEBUG(3), "more addresses");
|
||||
if ((notify) != 0) {
|
||||
find->flags &= ~addrs;
|
||||
process = true;
|
||||
}
|
||||
break;
|
||||
case DNS_EVENT_ADBNOMOREADDRESSES:
|
||||
DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBNOMOREADDRESSES");
|
||||
case DNS_ADB_NOMOREADDRESSES:
|
||||
DP(ISC_LOG_DEBUG(3), "no more addresses");
|
||||
find->flags &= ~addrs;
|
||||
wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
|
||||
if (wanted == 0) {
|
||||
@@ -964,9 +940,6 @@ clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
|
||||
}
|
||||
|
||||
if (process) {
|
||||
isc_task_t *task = NULL;
|
||||
isc_event_t *ev = NULL;
|
||||
|
||||
DP(DEF_LEVEL, "cfan: processing find %p", find);
|
||||
|
||||
/*
|
||||
@@ -979,21 +952,13 @@ clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
|
||||
|
||||
INSIST(!FIND_EVENTSENT(find));
|
||||
|
||||
ev = &find->event;
|
||||
task = ev->ev_sender;
|
||||
ev->ev_sender = find;
|
||||
find->result_v4 = find_err_map[name->fetch_err];
|
||||
find->result_v6 = find_err_map[name->fetch6_err];
|
||||
ev->ev_type = evtype;
|
||||
ev->ev_destroy = event_freefind;
|
||||
ev->ev_destroy_arg = find;
|
||||
find->status = astat;
|
||||
|
||||
DP(DEF_LEVEL,
|
||||
"cfan: sending event %p "
|
||||
"to task %p for find %p",
|
||||
ev, task, find);
|
||||
DP(DEF_LEVEL, "cfan: sending find %p to caller", find);
|
||||
|
||||
isc_task_sendanddetach(&task, (isc_event_t **)&ev);
|
||||
isc_async_run(find->loop, find->cb, find);
|
||||
find->flags |= FIND_EVENT_SENT;
|
||||
} else {
|
||||
DP(DEF_LEVEL, "cfan: skipping find %p", find);
|
||||
@@ -1218,14 +1183,13 @@ new_adbfind(dns_adb_t *adb, in_port_t port) {
|
||||
.port = port,
|
||||
.result_v4 = ISC_R_UNEXPECTED,
|
||||
.result_v6 = ISC_R_UNEXPECTED,
|
||||
.publink = ISC_LINK_INITIALIZER,
|
||||
.plink = ISC_LINK_INITIALIZER,
|
||||
.list = ISC_LIST_INITIALIZER,
|
||||
};
|
||||
|
||||
dns_adb_attach(adb, &find->adb);
|
||||
ISC_LINK_INIT(find, publink);
|
||||
ISC_LINK_INIT(find, plink);
|
||||
ISC_LIST_INIT(find->list);
|
||||
isc_mutex_init(&find->lock);
|
||||
ISC_EVENT_INIT(&find->event, sizeof(isc_event_t), 0, 0, NULL, NULL,
|
||||
NULL, NULL, find);
|
||||
|
||||
find->magic = DNS_ADBFIND_MAGIC;
|
||||
|
||||
@@ -1679,7 +1643,7 @@ maybe_expire_name(dns_adbname_t *adbname, isc_stdtime_t now) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
expire_name(adbname, DNS_EVENT_ADBEXPIRED);
|
||||
expire_name(adbname, DNS_ADB_EXPIRED);
|
||||
|
||||
return (true);
|
||||
}
|
||||
@@ -1779,13 +1743,13 @@ purge_stale_names(dns_adb_t *adb, isc_stdtime_t now) {
|
||||
}
|
||||
|
||||
if (overmem) {
|
||||
expire_name(adbname, DNS_EVENT_ADBCANCELED);
|
||||
expire_name(adbname, DNS_ADB_CANCELED);
|
||||
removed++;
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (adbname->last_used + ADB_STALE_MARGIN < now) {
|
||||
expire_name(adbname, DNS_EVENT_ADBCANCELED);
|
||||
expire_name(adbname, DNS_ADB_CANCELED);
|
||||
removed++;
|
||||
goto next;
|
||||
}
|
||||
@@ -2104,8 +2068,8 @@ dns_adb_shutdown(dns_adb_t *adb) {
|
||||
* more info coming later.
|
||||
*/
|
||||
isc_result_t
|
||||
dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
||||
void *arg, const dns_name_t *name, const dns_name_t *qname,
|
||||
dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
|
||||
const dns_name_t *name, const dns_name_t *qname,
|
||||
dns_rdatatype_t qtype, unsigned int options,
|
||||
isc_stdtime_t now, dns_name_t *target, in_port_t port,
|
||||
unsigned int depth, isc_counter_t *qc,
|
||||
@@ -2123,8 +2087,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
||||
char namebuf[DNS_NAME_FORMATSIZE] = { 0 };
|
||||
|
||||
REQUIRE(DNS_ADB_VALID(adb));
|
||||
if (task != NULL) {
|
||||
REQUIRE(action != NULL);
|
||||
if (loop != NULL) {
|
||||
REQUIRE(cb != NULL);
|
||||
}
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE(qname != NULL);
|
||||
@@ -2151,7 +2115,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
||||
find->options = options;
|
||||
find->flags |= wanted_addresses;
|
||||
if (FIND_WANTEVENT(find)) {
|
||||
REQUIRE(task != NULL);
|
||||
REQUIRE(loop != NULL);
|
||||
}
|
||||
|
||||
if (isc_log_wouldlog(dns_lctx, DEF_LEVEL)) {
|
||||
@@ -2384,7 +2348,7 @@ post_copy:
|
||||
*/
|
||||
find->query_pending = (query_pending & wanted_addresses);
|
||||
find->options &= ~DNS_ADBFIND_WANTEVENT;
|
||||
find->flags |= (FIND_EVENT_SENT | FIND_EVENT_FREED);
|
||||
find->flags |= FIND_EVENT_SENT;
|
||||
find->flags &= ~DNS_ADBFIND_ADDRESSMASK;
|
||||
}
|
||||
|
||||
@@ -2406,10 +2370,10 @@ post_copy:
|
||||
|
||||
if (want_event) {
|
||||
INSIST((find->flags & DNS_ADBFIND_ADDRESSMASK) != 0);
|
||||
isc_task_attach(task, &(isc_task_t *){ NULL });
|
||||
find->event.ev_sender = task;
|
||||
find->event.ev_action = action;
|
||||
find->event.ev_arg = arg;
|
||||
find->loop = loop;
|
||||
find->status = DNS_ADB_UNSET;
|
||||
find->cb = cb;
|
||||
find->cbarg = cbarg;
|
||||
}
|
||||
|
||||
*findp = find;
|
||||
@@ -2437,7 +2401,6 @@ dns_adb_destroyfind(dns_adbfind_t **findp) {
|
||||
|
||||
LOCK(&find->lock);
|
||||
|
||||
REQUIRE(FIND_EVENTFREED(find));
|
||||
REQUIRE(find->adbname == NULL);
|
||||
|
||||
/*
|
||||
@@ -2462,20 +2425,13 @@ dns_adb_destroyfind(dns_adbfind_t **findp) {
|
||||
static void
|
||||
find_sendevent(dns_adbfind_t *find) {
|
||||
if (!FIND_EVENTSENT(find)) {
|
||||
isc_event_t *ev = &find->event;
|
||||
isc_task_t *task = ev->ev_sender;
|
||||
|
||||
ev->ev_sender = find;
|
||||
ev->ev_type = DNS_EVENT_ADBCANCELED;
|
||||
ev->ev_destroy = event_freefind;
|
||||
ev->ev_destroy_arg = find;
|
||||
find->status = DNS_ADB_CANCELED;
|
||||
find->result_v4 = ISC_R_CANCELED;
|
||||
find->result_v6 = ISC_R_CANCELED;
|
||||
|
||||
DP(DEF_LEVEL, "sending event %p to task %p for find %p", ev,
|
||||
task, find);
|
||||
DP(DEF_LEVEL, "sending find %p to caller", find);
|
||||
|
||||
isc_task_sendanddetach(&task, (isc_event_t **)&ev);
|
||||
isc_async_run(find->loop, find->cb, find);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2489,7 +2445,6 @@ dns_adb_cancelfind(dns_adbfind_t *find) {
|
||||
REQUIRE(DNS_ADB_VALID(find->adb));
|
||||
|
||||
LOCK(&find->lock);
|
||||
REQUIRE(!FIND_EVENTFREED(find));
|
||||
REQUIRE(FIND_WANTEVENT(find));
|
||||
|
||||
adbname = find->adbname;
|
||||
@@ -2685,8 +2640,7 @@ dumpfind(dns_adbfind_t *find, FILE *f) {
|
||||
fprintf(f, ";\tqpending %08x partial %08x options %08x flags %08x\n",
|
||||
find->query_pending, find->partial_result, find->options,
|
||||
find->flags);
|
||||
fprintf(f, ";\name %p, event sender %p\n", find->adbname,
|
||||
find->event.ev_sender);
|
||||
fprintf(f, ";\tname %p\n", find->adbname);
|
||||
|
||||
ai = ISC_LIST_HEAD(find->list);
|
||||
if (ai != NULL) {
|
||||
@@ -2971,14 +2925,13 @@ fetch_callback(isc_task_t *task, isc_event_t *ev) {
|
||||
dns_adbname_t *name = NULL;
|
||||
dns_adb_t *adb = NULL;
|
||||
dns_adbfetch_t *fetch = NULL;
|
||||
isc_eventtype_t ev_status;
|
||||
dns_adbstatus_t astat = DNS_ADB_NOMOREADDRESSES;
|
||||
isc_stdtime_t now;
|
||||
isc_result_t result;
|
||||
unsigned int address_type;
|
||||
|
||||
UNUSED(task);
|
||||
|
||||
REQUIRE(ev->ev_type == DNS_EVENT_FETCHDONE);
|
||||
name = ev->ev_arg;
|
||||
|
||||
REQUIRE(DNS_ADBNAME_VALID(name));
|
||||
@@ -3006,8 +2959,6 @@ fetch_callback(isc_task_t *task, isc_event_t *ev) {
|
||||
|
||||
INSIST(address_type != 0 && fetch != NULL);
|
||||
|
||||
ev_status = DNS_EVENT_ADBNOMOREADDRESSES;
|
||||
|
||||
/*
|
||||
* Cleanup things we don't care about.
|
||||
*/
|
||||
@@ -3023,7 +2974,7 @@ fetch_callback(isc_task_t *task, isc_event_t *ev) {
|
||||
* potentially good data.
|
||||
*/
|
||||
if (NAME_DEAD(name)) {
|
||||
ev_status = DNS_EVENT_ADBCANCELED;
|
||||
astat = DNS_ADB_CANCELED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -3119,7 +3070,7 @@ fetch_callback(isc_task_t *task, isc_event_t *ev) {
|
||||
|
||||
check_result:
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
ev_status = DNS_EVENT_ADBMOREADDRESSES;
|
||||
astat = DNS_ADB_MOREADDRESSES;
|
||||
if (address_type == DNS_ADBFIND_INET) {
|
||||
name->fetch_err = FIND_ERR_SUCCESS;
|
||||
} else {
|
||||
@@ -3131,8 +3082,8 @@ out:
|
||||
dns_resolver_destroyfetch(&fetch->fetch);
|
||||
free_adbfetch(adb, &fetch);
|
||||
isc_event_free(&ev);
|
||||
if (ev_status != DNS_EVENT_ADBCANCELED) {
|
||||
clean_finds_at_name(name, ev_status, address_type);
|
||||
if (astat != DNS_ADB_CANCELED) {
|
||||
clean_finds_at_name(name, astat, address_type);
|
||||
}
|
||||
UNLOCK(&name->lock);
|
||||
dns_adbname_detach(&name);
|
||||
@@ -3678,7 +3629,7 @@ again:
|
||||
dns_adbname_ref(adbname);
|
||||
LOCK(&adbname->lock);
|
||||
if (dns_name_equal(name, &adbname->name)) {
|
||||
expire_name(adbname, DNS_EVENT_ADBCANCELED);
|
||||
expire_name(adbname, DNS_ADB_CANCELED);
|
||||
}
|
||||
UNLOCK(&adbname->lock);
|
||||
dns_adbname_detach(&adbname);
|
||||
@@ -3709,7 +3660,7 @@ dns_adb_flushnames(dns_adb_t *adb, const dns_name_t *name) {
|
||||
dns_adbname_ref(adbname);
|
||||
LOCK(&adbname->lock);
|
||||
if (dns_name_issubdomain(&adbname->name, name)) {
|
||||
expire_name(adbname, DNS_EVENT_ADBCANCELED);
|
||||
expire_name(adbname, DNS_ADB_CANCELED);
|
||||
}
|
||||
UNLOCK(&adbname->lock);
|
||||
dns_adbname_detach(&adbname);
|
||||
|
@@ -97,6 +97,15 @@ ISC_LANG_BEGINDECLS
|
||||
|
||||
typedef struct dns_adbname dns_adbname_t;
|
||||
|
||||
typedef enum {
|
||||
DNS_ADB_UNSET = 0,
|
||||
DNS_ADB_MOREADDRESSES,
|
||||
DNS_ADB_NOMOREADDRESSES,
|
||||
DNS_ADB_EXPIRED,
|
||||
DNS_ADB_CANCELED,
|
||||
DNS_ADB_SHUTTINGDOWN
|
||||
} dns_adbstatus_t;
|
||||
|
||||
/*!
|
||||
*\brief
|
||||
* Represents a lookup for a single name.
|
||||
@@ -117,12 +126,15 @@ struct dns_adbfind {
|
||||
ISC_LINK(dns_adbfind_t) publink; /*%< RW: client use */
|
||||
|
||||
/* Private */
|
||||
isc_mutex_t lock; /* locks all below */
|
||||
in_port_t port;
|
||||
unsigned int flags;
|
||||
dns_adbname_t *adbname;
|
||||
dns_adb_t *adb;
|
||||
isc_event_t event;
|
||||
isc_mutex_t lock; /* locks all below */
|
||||
in_port_t port;
|
||||
unsigned int flags;
|
||||
dns_adbname_t *adbname;
|
||||
dns_adb_t *adb;
|
||||
isc_loop_t *loop;
|
||||
dns_adbstatus_t status;
|
||||
isc_job_cb cb;
|
||||
void *cbarg;
|
||||
ISC_LINK(dns_adbfind_t) plink;
|
||||
};
|
||||
|
||||
@@ -214,23 +226,20 @@ struct dns_adbaddrinfo {
|
||||
};
|
||||
|
||||
/*!<
|
||||
* The event sent to the caller task is just a plain old isc_event_t. It
|
||||
* contains no data other than a simple status, passed in the "type" field
|
||||
* to indicate that another address resolved, or all partially resolved
|
||||
* addresses have failed to resolve.
|
||||
* When the caller recieves a callback from dns_adb_createfind(), the
|
||||
* argument will a pointer to the dns_adbfind_t structure, which includes
|
||||
* this includes a copy of the callback function and argument passed to
|
||||
* dns_adb_createfind(), and a dns_adbstatus_t in the 'status' field,
|
||||
* which indicates one of the following:
|
||||
*
|
||||
* "sender" is the dns_adbfind_t used to issue this query.
|
||||
*
|
||||
* This is simply a standard event, with the "type" set to:
|
||||
*
|
||||
*\li #DNS_EVENT_ADBMOREADDRESSES -- another address resolved.
|
||||
*\li #DNS_EVENT_ADBNOMOREADDRESSES -- all pending addresses failed,
|
||||
* were canceled, or otherwise will
|
||||
* not be usable.
|
||||
*\li #DNS_EVENT_ADBCANCELED -- The request was canceled by a
|
||||
* 3rd party.
|
||||
*\li #DNS_EVENT_ADBNAMEDELETED -- The name was deleted, so this request
|
||||
* was canceled.
|
||||
*\li #DNS_ADB_MOREADDRESSES -- another address resolved.
|
||||
*\li #DNS_ADB_NOMOREADDRESSES -- all pending addresses failed,
|
||||
* were canceled, or otherwise will
|
||||
* not be usable.
|
||||
*\li #DNS_ADB_CANCELED -- The request was canceled by a
|
||||
* 3rd party.
|
||||
*\li #DNS_ADB_EXPIRED -- The name was expired, so this request
|
||||
* was canceled.
|
||||
*
|
||||
* In each of these cases, the addresses returned by the initial call
|
||||
* to dns_adb_createfind() can still be used until they are no longer needed.
|
||||
@@ -289,8 +298,8 @@ dns_adb_shutdown(dns_adb_t *adb);
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
||||
void *arg, const dns_name_t *name, const dns_name_t *qname,
|
||||
dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
|
||||
const dns_name_t *name, const dns_name_t *qname,
|
||||
dns_rdatatype_t qtype, unsigned int options,
|
||||
isc_stdtime_t now, dns_name_t *target, in_port_t port,
|
||||
unsigned int depth, isc_counter_t *qc, dns_adbfind_t **find);
|
||||
@@ -299,9 +308,10 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
||||
* "name" and will build up a list of found addresses, and perhaps start
|
||||
* internal fetches to resolve names that are unknown currently.
|
||||
*
|
||||
* If other addresses resolve after this call completes, an event will
|
||||
* be sent to the <task, taskaction, arg> with the sender of that event
|
||||
* set to a pointer to the dns_adbfind_t returned by this function.
|
||||
* If other addresses resolve after this call completes, the 'cb' callback
|
||||
* will be called with a pointer to the dns_adbfind_t returned by this
|
||||
* structure, which in turn has a pointer to the callback argument passed
|
||||
* in as 'cbarg'. The caller is responsible for freeing the find object.
|
||||
*
|
||||
* If no events will be generated, the *find->result_v4 and/or result_v6
|
||||
* members may be examined for address lookup status. The usual #ISC_R_SUCCESS,
|
||||
@@ -334,15 +344,12 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
||||
* The caller may change them directly in the dns_adbaddrinfo_t since
|
||||
* they are copies of the internal address only.
|
||||
*
|
||||
* XXXMLG Document options, especially the flags which control how
|
||||
* events are sent.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li *adb be a valid isc_adb_t object.
|
||||
*
|
||||
*\li If events are to be sent, *task be a valid task,
|
||||
* and isc_taskaction_t != NULL.
|
||||
*\li If events are to be sent, *loop be a valid loop,
|
||||
* and cb != NULL.
|
||||
*
|
||||
*\li *name is a valid dns_name_t.
|
||||
*
|
||||
@@ -400,6 +407,16 @@ dns_adb_cancelfind(dns_adbfind_t *find);
|
||||
*\li The event was posted to the task.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_adbfind_done(dns_adbfind_t find);
|
||||
/*%<
|
||||
* Marks a find as ready to free.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'find' != NULL and *find be valid dns_adbfind_t pointer.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_adb_destroyfind(dns_adbfind_t **find);
|
||||
/*%<
|
||||
@@ -408,8 +425,7 @@ dns_adb_destroyfind(dns_adbfind_t **find);
|
||||
* Note:
|
||||
*
|
||||
*\li This can only be called after the event was delivered for a
|
||||
* find. Additionally, the event MUST have been freed via
|
||||
* isc_event_free() BEFORE this function is called.
|
||||
* find.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
|
@@ -3089,17 +3089,15 @@ detach:
|
||||
}
|
||||
|
||||
static void
|
||||
fctx_finddone(isc_task_t *task, isc_event_t *event) {
|
||||
fetchctx_t *fctx = event->ev_arg;
|
||||
dns_adbfind_t *find = event->ev_sender;
|
||||
fctx_finddone(void *arg) {
|
||||
dns_adbfind_t *find = (dns_adbfind_t *)arg;
|
||||
fetchctx_t *fctx = (fetchctx_t *)find->cbarg;
|
||||
bool want_try = false;
|
||||
bool want_done = false;
|
||||
uint_fast32_t pending;
|
||||
|
||||
REQUIRE(VALID_FCTX(fctx));
|
||||
|
||||
UNUSED(task);
|
||||
|
||||
FCTXTRACE("finddone");
|
||||
|
||||
REQUIRE(fctx->tid == isc_tid());
|
||||
@@ -3113,7 +3111,7 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
|
||||
* The fetch is waiting for a name to be found.
|
||||
*/
|
||||
INSIST(!SHUTTINGDOWN(fctx));
|
||||
if (event->ev_type == DNS_EVENT_ADBMOREADDRESSES) {
|
||||
if (find->status == DNS_ADB_MOREADDRESSES) {
|
||||
FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
|
||||
want_try = true;
|
||||
} else {
|
||||
@@ -3132,7 +3130,6 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
UNLOCK(&fctx->lock);
|
||||
|
||||
isc_event_free(&event);
|
||||
dns_adb_destroyfind(&find);
|
||||
|
||||
if (want_done) {
|
||||
@@ -3469,10 +3466,10 @@ findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
|
||||
*/
|
||||
INSIST(!SHUTTINGDOWN(fctx));
|
||||
fetchctx_ref(fctx);
|
||||
result = dns_adb_createfind(fctx->adb, fctx->restask, fctx_finddone,
|
||||
fctx, name, fctx->name, fctx->type, options,
|
||||
now, NULL, res->view->dstport,
|
||||
fctx->depth + 1, fctx->qc, &find);
|
||||
result = dns_adb_createfind(fctx->adb, fctx->loop, fctx_finddone, fctx,
|
||||
name, fctx->name, fctx->type, options, now,
|
||||
NULL, res->view->dstport, fctx->depth + 1,
|
||||
fctx->qc, &find);
|
||||
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
|
||||
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
|
||||
|
@@ -12103,27 +12103,30 @@ notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
|
||||
* XXXAG should check for DNS_ZONEFLG_EXITING
|
||||
*/
|
||||
static void
|
||||
process_adb_event(isc_task_t *task, isc_event_t *ev) {
|
||||
dns_notify_t *notify;
|
||||
isc_eventtype_t result;
|
||||
process_adb_event(void *arg) {
|
||||
dns_adbfind_t *find = (dns_adbfind_t *)arg;
|
||||
dns_notify_t *notify = (dns_notify_t *)find->cbarg;
|
||||
dns_adbstatus_t astat = find->status;
|
||||
|
||||
UNUSED(task);
|
||||
|
||||
notify = ev->ev_arg;
|
||||
REQUIRE(DNS_NOTIFY_VALID(notify));
|
||||
INSIST(task == notify->zone->task);
|
||||
result = ev->ev_type;
|
||||
isc_event_free(&ev);
|
||||
if (result == DNS_EVENT_ADBMOREADDRESSES) {
|
||||
REQUIRE(find == notify->find);
|
||||
|
||||
switch (astat) {
|
||||
case DNS_ADB_MOREADDRESSES:
|
||||
dns_adb_destroyfind(¬ify->find);
|
||||
notify_find_address(notify);
|
||||
return;
|
||||
}
|
||||
if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
|
||||
|
||||
case DNS_ADB_NOMOREADDRESSES:
|
||||
LOCK_ZONE(notify->zone);
|
||||
notify_send(notify);
|
||||
UNLOCK_ZONE(notify->zone);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
notify_destroy(notify, false);
|
||||
}
|
||||
|
||||
@@ -12141,7 +12144,7 @@ notify_find_address(dns_notify_t *notify) {
|
||||
}
|
||||
|
||||
result = dns_adb_createfind(
|
||||
notify->zone->view->adb, notify->zone->task, process_adb_event,
|
||||
notify->zone->view->adb, notify->zone->loop, process_adb_event,
|
||||
notify, ¬ify->ns, dns_rootname, 0, options, 0, NULL,
|
||||
notify->zone->view->dstport, 0, NULL, ¬ify->find);
|
||||
|
||||
|
Reference in New Issue
Block a user