Compare commits

...
Author SHA1 Message Date
Ondřej Surý 7b0edd3f84 WIP: Instead of having hard task quantum, process all events that were scheduled before the task_run() was called 2022-05-25 09:22:41 +02:00
Ondřej Surý a6909a13c7 Instead of maintaining own set of resolver tasks use caller's task
Previously, the resolver has maintained many tasks that were randomly
used for resolution process.  After the last refactoring, this was
reduced to per-thread task.  Since the caller always needs to pass
the task for calling the callback, the resolver already have access
to the task object that's evenly distributed among the threads (via
ns_clientmgr), so change the logic to stop using the internal threads,
and use the task that has been passed when creating new fetch context.
2022-05-25 09:22:09 +02:00
Ondřej Surý ffb8f611d6 Make all tasks to be bound to a thread
Previously, the task could be created unbound or bound to a specific
thread (worker loop).  The unbound tasks would be assigned random thread
every time the isc_task_send() would be called.  Because there's no
logic that would assigned the task to the least busy worker, this just
creates an unpredictability.  Instead of the random assignment, bind all
the previously unbound tasks to worker 0 which must always exists.
2022-05-25 09:21:57 +02:00
Ondřej Surý 707741d78b Remove dns_lookup and unused functions in dns_byaddr
Clean up unused functions from the dns_byaddr API and completely remove
the dns_lookup API.
2022-05-25 09:21:42 +02:00
36 changed files with 113 additions and 1040 deletions
+1 -1
View File
@@ -1392,7 +1392,7 @@ setup_libs(void) {
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
result = isc_task_create(taskmgr, 0, &global_task);
result = isc_task_create(taskmgr, 0, &global_task, 0);
check_result(result, "isc_task_create");
isc_task_setname(global_task, "dig", NULL);
+2 -2
View File
@@ -4001,7 +4001,7 @@ main(int argc, char *argv[]) {
isc_managers_create(mctx, ntasks, 0, &netmgr, &taskmgr, NULL);
main_task = NULL;
result = isc_task_create(taskmgr, 0, &main_task);
result = isc_task_create(taskmgr, 0, &main_task, 0);
if (result != ISC_R_SUCCESS) {
fatal("failed to create task: %s", isc_result_totext(result));
}
@@ -4009,7 +4009,7 @@ main(int argc, char *argv[]) {
tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *));
for (i = 0; i < (int)ntasks; i++) {
tasks[i] = NULL;
result = isc_task_create(taskmgr, 0, &tasks[i]);
result = isc_task_create(taskmgr, 0, &tasks[i], i);
if (result != ISC_R_SUCCESS) {
fatal("failed to create task: %s",
isc_result_totext(result));
+1 -1
View File
@@ -10067,7 +10067,7 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
* startup and shutdown of the server, as well as all exclusive
* tasks.
*/
CHECKFATAL(isc_task_create_bound(named_g_taskmgr, 0, &server->task, 0),
CHECKFATAL(isc_task_create(named_g_taskmgr, 0, &server->task, 0),
"creating server task");
isc_task_setname(server->task, "server", server);
isc_taskmgr_setexcltask(named_g_taskmgr, server->task);
+1 -1
View File
@@ -911,7 +911,7 @@ setup_system(void) {
result = dns_dispatchmgr_create(gmctx, netmgr, &dispatchmgr);
check_result(result, "dns_dispatchmgr_create");
result = isc_task_create(taskmgr, 0, &global_task);
result = isc_task_create(taskmgr, 0, &global_task, 0);
check_result(result, "isc_task_create");
result = dst_lib_init(gmctx, NULL);
+1 -1
View File
@@ -1028,7 +1028,7 @@ main(int argc, char **argv) {
isc_mem_create(&rndc_mctx);
isc_managers_create(rndc_mctx, 1, 0, &netmgr, &taskmgr, NULL);
DO("create task", isc_task_create(taskmgr, 0, &rndc_task));
DO("create task", isc_task_create(taskmgr, 0, &rndc_task, 0));
isc_log_create(rndc_mctx, &log, &logconfig);
isc_log_setcontext(log);
isc_log_settag(logconfig, progname);
+1 -1
View File
@@ -263,7 +263,7 @@ main(int argc, char *argv[]) {
RUNCHECK(dst_lib_init(mctx, NULL));
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
RUNCHECK(isc_task_create(taskmgr, 0, &task));
RUNCHECK(isc_task_create(taskmgr, 0, &task, 0));
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
RUNCHECK(dns_dispatch_createudp(
+1 -1
View File
@@ -223,7 +223,7 @@ main(int argc, char *argv[]) {
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
RUNCHECK(isc_task_create(taskmgr, 0, &task));
RUNCHECK(isc_task_create(taskmgr, 0, &task, 0));
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
isc_sockaddr_any(&bind_any);
+1 -1
View File
@@ -167,7 +167,7 @@ main(int argc, char **argv) {
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
RUNCHECK(isc_task_create(taskmgr, 0, &task));
RUNCHECK(isc_task_create(taskmgr, 0, &task, 0));
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
isc_sockaddr_any(&bind_any);
RUNCHECK(dns_dispatch_createudp(dispatchmgr, &bind_any, &dispatchv4));
+1 -1
View File
@@ -2157,7 +2157,7 @@ main(int argc, char *argv[]) {
}
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
RUNCHECK(isc_task_create(taskmgr, 0, &task));
RUNCHECK(isc_task_create(taskmgr, 0, &task, 0));
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
set_source_ports(dispatchmgr);
-2
View File
@@ -87,7 +87,6 @@ libdns_la_HEADERS = \
include/dns/keytable.h \
include/dns/keyvalues.h \
include/dns/librpz.h \
include/dns/lookup.h \
include/dns/log.h \
include/dns/master.h \
include/dns/masterdump.h \
@@ -186,7 +185,6 @@ libdns_la_SOURCES = \
keymgr.c \
keytable.c \
log.c \
lookup.c \
master.c \
masterdump.c \
message.c \
+14 -28
View File
@@ -106,7 +106,6 @@ struct dns_adb {
dns_resolver_t *res;
isc_taskmgr_t *taskmgr;
isc_task_t *task;
isc_refcount_t references;
@@ -338,10 +337,10 @@ maybe_expire_namehooks(dns_adbname_t *, isc_stdtime_t);
static void
maybe_expire_entry(dns_adbentry_t **, isc_stdtime_t);
static isc_result_t
dbfind_name(dns_adbname_t *, isc_stdtime_t, dns_rdatatype_t);
dbfind_name(dns_adbname_t *, isc_task_t *task, isc_stdtime_t, dns_rdatatype_t);
static isc_result_t
fetch_name(dns_adbname_t *, bool, unsigned int, isc_counter_t *qc,
dns_rdatatype_t);
fetch_name(isc_task_t *task, dns_adbname_t *, bool, unsigned int,
isc_counter_t *qc, dns_rdatatype_t);
static void
destroy(dns_adb_t *);
static void
@@ -2079,7 +2078,6 @@ destroy(dns_adb_t *adb) {
isc_mutex_destroy(&adb->lock);
isc_task_detach(&adb->task);
isc_stats_detach(&adb->stats);
dns_resolver_detach(&adb->res);
dns_view_weakdetach(&adb->view);
@@ -2123,19 +2121,9 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_taskmgr_t *taskmgr,
isc_mutex_init(&adb->lock);
/*
* Allocate an internal task.
*/
result = isc_task_create(adb->taskmgr, 0, &adb->task);
if (result != ISC_R_SUCCESS) {
goto free_lock;
}
isc_task_setname(adb->task, "ADB", adb);
result = isc_stats_create(adb->mctx, &adb->stats, dns_adbstats_max);
if (result != ISC_R_SUCCESS) {
goto free_task;
goto free_lock;
}
set_adbstat(adb, isc_ht_count(adb->namebuckets), dns_adbstats_nnames);
@@ -2149,9 +2137,6 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_taskmgr_t *taskmgr,
*newadb = adb;
return (ISC_R_SUCCESS);
free_task:
isc_task_detach(&adb->task);
free_lock:
isc_mutex_destroy(&adb->lock);
@@ -2367,7 +2352,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
if (!NAME_HAS_V4(adbname) && EXPIRE_OK(adbname->expire_v4, now) &&
WANT_INET(wanted_addresses))
{
result = dbfind_name(adbname, now, dns_rdatatype_a);
result = dbfind_name(adbname, task, now, dns_rdatatype_a);
switch (result) {
case ISC_R_SUCCESS:
/* Found an A; now we proceed to check for AAAA */
@@ -2419,7 +2404,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
if (!NAME_HAS_V6(adbname) && EXPIRE_OK(adbname->expire_v6, now) &&
WANT_INET6(wanted_addresses))
{
result = dbfind_name(adbname, now, dns_rdatatype_aaaa);
result = dbfind_name(adbname, task, now, dns_rdatatype_aaaa);
switch (result) {
case ISC_R_SUCCESS:
DP(DEF_LEVEL,
@@ -2482,7 +2467,7 @@ fetch:
* Start V4.
*/
if (WANT_INET(wanted_fetches) &&
fetch_name(adbname, start_at_zone, depth, qc,
fetch_name(task, adbname, start_at_zone, depth, qc,
dns_rdatatype_a) == ISC_R_SUCCESS)
{
DP(DEF_LEVEL,
@@ -2495,7 +2480,7 @@ fetch:
* Start V6.
*/
if (WANT_INET6(wanted_fetches) &&
fetch_name(adbname, start_at_zone, depth, qc,
fetch_name(task, adbname, start_at_zone, depth, qc,
dns_rdatatype_aaaa) == ISC_R_SUCCESS)
{
DP(DEF_LEVEL,
@@ -2968,7 +2953,8 @@ print_find_list(FILE *f, dns_adbname_t *name) {
}
static isc_result_t
dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype) {
dbfind_name(dns_adbname_t *adbname, isc_task_t *task, isc_stdtime_t now,
dns_rdatatype_t rdtype) {
isc_result_t result;
dns_rdataset_t rdataset;
dns_adb_t *adb = NULL;
@@ -2999,7 +2985,7 @@ dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype) {
* matching static-stub zone without looking into the cache to honor
* the configuration on which server we should send queries to.
*/
result = dns_view_find(adb->view, &adbname->name, rdtype, now,
result = dns_view_find(adb->view, task, &adbname->name, rdtype, now,
NAME_GLUEOK(adbname) ? DNS_DBFIND_GLUEOK : 0,
NAME_HINTOK(adbname),
((adbname->flags & NAME_STARTATZONE) != 0), NULL,
@@ -3297,8 +3283,8 @@ out:
}
static isc_result_t
fetch_name(dns_adbname_t *adbname, bool start_at_zone, unsigned int depth,
isc_counter_t *qc, dns_rdatatype_t type) {
fetch_name(isc_task_t *task, dns_adbname_t *adbname, bool start_at_zone,
unsigned int depth, isc_counter_t *qc, dns_rdatatype_t type) {
isc_result_t result;
dns_adbfetch_t *fetch = NULL;
dns_adb_t *adb = NULL;
@@ -3348,7 +3334,7 @@ fetch_name(dns_adbname_t *adbname, bool start_at_zone, unsigned int depth,
*/
result = dns_resolver_createfetch(
adb->res, &adbname->name, type, name, nameservers, NULL, NULL,
0, options, depth, qc, adb->task, fetch_callback, adbname,
0, options, depth, qc, task, fetch_callback, adbname,
&fetch->rdataset, NULL, &fetch->fetch);
if (result != ISC_R_SUCCESS) {
DP(ENTER_LEVEL, "fetch_name: createfetch failed with %s",
-192
View File
@@ -26,7 +26,6 @@
#include <dns/byaddr.h>
#include <dns/db.h>
#include <dns/events.h>
#include <dns/lookup.h>
#include <dns/rdata.h>
#include <dns/rdataset.h>
#include <dns/rdatastruct.h>
@@ -88,194 +87,3 @@ dns_byaddr_createptrname(const isc_netaddr_t *address, unsigned int options,
isc_buffer_add(&buffer, len);
return (dns_name_fromtext(name, &buffer, dns_rootname, 0, NULL));
}
struct dns_byaddr {
/* Unlocked. */
unsigned int magic;
isc_mem_t *mctx;
isc_mutex_t lock;
dns_fixedname_t name;
/* Locked by lock. */
unsigned int options;
dns_lookup_t *lookup;
isc_task_t *task;
dns_byaddrevent_t *event;
bool canceled;
};
#define BYADDR_MAGIC ISC_MAGIC('B', 'y', 'A', 'd')
#define VALID_BYADDR(b) ISC_MAGIC_VALID(b, BYADDR_MAGIC)
#define MAX_RESTARTS 16
static isc_result_t
copy_ptr_targets(dns_byaddr_t *byaddr, dns_rdataset_t *rdataset) {
isc_result_t result;
dns_name_t *name;
dns_rdata_t rdata = DNS_RDATA_INIT;
/*
* The caller must be holding the byaddr's lock.
*/
result = dns_rdataset_first(rdataset);
while (result == ISC_R_SUCCESS) {
dns_rdata_ptr_t ptr;
dns_rdataset_current(rdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &ptr, NULL);
if (result != ISC_R_SUCCESS) {
return (result);
}
name = isc_mem_get(byaddr->mctx, sizeof(*name));
dns_name_init(name, NULL);
dns_name_dup(&ptr.ptr, byaddr->mctx, name);
dns_rdata_freestruct(&ptr);
ISC_LIST_APPEND(byaddr->event->names, name, link);
dns_rdata_reset(&rdata);
result = dns_rdataset_next(rdataset);
}
if (result == ISC_R_NOMORE) {
result = ISC_R_SUCCESS;
}
return (result);
}
static void
lookup_done(isc_task_t *task, isc_event_t *event) {
dns_byaddr_t *byaddr = event->ev_arg;
dns_lookupevent_t *levent;
isc_result_t result;
REQUIRE(event->ev_type == DNS_EVENT_LOOKUPDONE);
REQUIRE(VALID_BYADDR(byaddr));
REQUIRE(byaddr->task == task);
UNUSED(task);
levent = (dns_lookupevent_t *)event;
if (levent->result == ISC_R_SUCCESS) {
result = copy_ptr_targets(byaddr, levent->rdataset);
byaddr->event->result = result;
} else {
byaddr->event->result = levent->result;
}
isc_event_free(&event);
isc_task_sendanddetach(&byaddr->task, (isc_event_t **)&byaddr->event);
}
static void
bevent_destroy(isc_event_t *event) {
dns_byaddrevent_t *bevent;
dns_name_t *name, *next_name;
isc_mem_t *mctx;
REQUIRE(event->ev_type == DNS_EVENT_BYADDRDONE);
mctx = event->ev_destroy_arg;
bevent = (dns_byaddrevent_t *)event;
for (name = ISC_LIST_HEAD(bevent->names); name != NULL;
name = next_name) {
next_name = ISC_LIST_NEXT(name, link);
ISC_LIST_UNLINK(bevent->names, name, link);
dns_name_free(name, mctx);
isc_mem_put(mctx, name, sizeof(*name));
}
isc_mem_put(mctx, event, event->ev_size);
}
isc_result_t
dns_byaddr_create(isc_mem_t *mctx, const isc_netaddr_t *address,
dns_view_t *view, unsigned int options, isc_task_t *task,
isc_taskaction_t action, void *arg, dns_byaddr_t **byaddrp) {
isc_result_t result;
dns_byaddr_t *byaddr;
isc_event_t *ievent;
byaddr = isc_mem_get(mctx, sizeof(*byaddr));
byaddr->mctx = NULL;
isc_mem_attach(mctx, &byaddr->mctx);
byaddr->options = options;
byaddr->event = isc_mem_get(mctx, sizeof(*byaddr->event));
ISC_EVENT_INIT(byaddr->event, sizeof(*byaddr->event), 0, NULL,
DNS_EVENT_BYADDRDONE, action, arg, byaddr,
bevent_destroy, mctx);
byaddr->event->result = ISC_R_FAILURE;
ISC_LIST_INIT(byaddr->event->names);
byaddr->task = NULL;
isc_task_attach(task, &byaddr->task);
isc_mutex_init(&byaddr->lock);
dns_fixedname_init(&byaddr->name);
result = dns_byaddr_createptrname(address, options,
dns_fixedname_name(&byaddr->name));
if (result != ISC_R_SUCCESS) {
goto cleanup_lock;
}
byaddr->lookup = NULL;
result = dns_lookup_create(mctx, dns_fixedname_name(&byaddr->name),
dns_rdatatype_ptr, view, 0, task,
lookup_done, byaddr, &byaddr->lookup);
if (result != ISC_R_SUCCESS) {
goto cleanup_lock;
}
byaddr->canceled = false;
byaddr->magic = BYADDR_MAGIC;
*byaddrp = byaddr;
return (ISC_R_SUCCESS);
cleanup_lock:
isc_mutex_destroy(&byaddr->lock);
ievent = (isc_event_t *)byaddr->event;
isc_event_free(&ievent);
byaddr->event = NULL;
isc_task_detach(&byaddr->task);
isc_mem_putanddetach(&mctx, byaddr, sizeof(*byaddr));
return (result);
}
void
dns_byaddr_cancel(dns_byaddr_t *byaddr) {
REQUIRE(VALID_BYADDR(byaddr));
LOCK(&byaddr->lock);
if (!byaddr->canceled) {
byaddr->canceled = true;
if (byaddr->lookup != NULL) {
dns_lookup_cancel(byaddr->lookup);
}
}
UNLOCK(&byaddr->lock);
}
void
dns_byaddr_destroy(dns_byaddr_t **byaddrp) {
dns_byaddr_t *byaddr;
REQUIRE(byaddrp != NULL);
byaddr = *byaddrp;
*byaddrp = NULL;
REQUIRE(VALID_BYADDR(byaddr));
REQUIRE(byaddr->event == NULL);
REQUIRE(byaddr->task == NULL);
dns_lookup_destroy(&byaddr->lookup);
isc_mutex_destroy(&byaddr->lock);
byaddr->magic = 0;
isc_mem_putanddetach(&byaddr->mctx, byaddr, sizeof(*byaddr));
}
+2 -2
View File
@@ -258,7 +258,7 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
}
if (taskmgr != NULL) {
dbtask = NULL;
result = isc_task_create(taskmgr, 1, &dbtask);
result = isc_task_create(taskmgr, 1, &dbtask, 0);
if (result != ISC_R_SUCCESS) {
goto cleanup_db;
}
@@ -470,7 +470,7 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
}
if (taskmgr != NULL && timermgr != NULL) {
result = isc_task_create(taskmgr, 1, &cleaner->task);
result = isc_task_create(taskmgr, 1, &cleaner->task, 0);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_task_create() failed: %s",
+1 -1
View File
@@ -732,7 +732,7 @@ dns_catz_new_zones(dns_catz_zones_t **catzsp, dns_catz_zonemodmethods_t *zmm,
new_zones->timermgr = timermgr;
new_zones->taskmgr = taskmgr;
result = isc_task_create(taskmgr, 0, &new_zones->updater);
result = isc_task_create(taskmgr, 0, &new_zones->updater, 0);
if (result != ISC_R_SUCCESS) {
goto cleanup_ht;
}
+3 -3
View File
@@ -286,7 +286,7 @@ dns_client_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_nm_t *nm,
isc_mutex_init(&client->readylock);
isc_condition_init(&client->ready);
result = isc_task_create(client->taskmgr, 0, &client->task);
result = isc_task_create(client->taskmgr, 0, &client->task, 0);
if (result != ISC_R_SUCCESS) {
goto cleanup_lock;
}
@@ -564,8 +564,8 @@ view_find(resctx_t *rctx, dns_db_t **dbp, dns_dbnode_t **nodep,
type = rctx->type;
}
result = dns_view_find(rctx->view, name, type, 0, 0, false, false, dbp,
nodep, foundname, rctx->rdataset,
result = dns_view_find(rctx->view, rctx->task, name, type, 0, 0, false,
false, dbp, nodep, foundname, rctx->rdataset,
rctx->sigrdataset);
return (result);
-83
View File
@@ -47,89 +47,6 @@
ISC_LANG_BEGINDECLS
/*%
* A 'dns_byaddrevent_t' is returned when a byaddr completes.
* The sender field will be set to the byaddr that completed. If 'result'
* is ISC_R_SUCCESS, then 'names' will contain a list of names associated
* with the address. The recipient of the event must not change the list
* and must not refer to any of the name data after the event is freed.
*/
typedef struct dns_byaddrevent {
ISC_EVENT_COMMON(struct dns_byaddrevent);
isc_result_t result;
dns_namelist_t names;
} dns_byaddrevent_t;
isc_result_t
dns_byaddr_create(isc_mem_t *mctx, const isc_netaddr_t *address,
dns_view_t *view, unsigned int options, isc_task_t *task,
isc_taskaction_t action, void *arg, dns_byaddr_t **byaddrp);
/*%<
* Find the domain name of 'address'.
*
* Notes:
*
*\li There is a reverse lookup format for IPv6 addresses, 'nibble'
*
*\li The 'nibble' format for that address is
*
* \code
* 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa.
* \endcode
*
* Requires:
*
*\li 'mctx' is a valid mctx.
*
*\li 'address' is a valid IPv4 or IPv6 address.
*
*\li 'view' is a valid view which has a resolver.
*
*\li 'task' is a valid task.
*
*\li byaddrp != NULL && *byaddrp == NULL
*
* Returns:
*
*\li #ISC_R_SUCCESS
*\li #ISC_R_NOMEMORY
*
*\li Any resolver-related error (e.g. #ISC_R_SHUTTINGDOWN) may also be
* returned.
*/
void
dns_byaddr_cancel(dns_byaddr_t *byaddr);
/*%<
* Cancel 'byaddr'.
*
* Notes:
*
*\li If 'byaddr' has not completed, post its #DNS_EVENT_BYADDRDONE
* event with a result code of #ISC_R_CANCELED.
*
* Requires:
*
*\li 'byaddr' is a valid byaddr.
*/
void
dns_byaddr_destroy(dns_byaddr_t **byaddrp);
/*%<
* Destroy 'byaddr'.
*
* Requires:
*
*\li '*byaddrp' is a valid byaddr.
*
*\li The caller has received the #DNS_EVENT_BYADDRDONE event (either because
* the byaddr completed or because dns_byaddr_cancel() was called).
*
* Ensures:
*
*\li *byaddrp == NULL.
*/
isc_result_t
dns_byaddr_createptrname(const isc_netaddr_t *address, unsigned int options,
dns_name_t *name);
-128
View File
@@ -1,128 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#pragma once
/*****
***** Module Info
*****/
/*! \file dns/lookup.h
* \brief
* The lookup module performs simple DNS lookups. It implements
* the full resolver algorithm, both looking for local data and
* resolving external names as necessary.
*
* MP:
*\li The module ensures appropriate synchronization of data structures it
* creates and manipulates.
*
* Reliability:
*\li No anticipated impact.
*
* Resources:
*\li TBS
*
* Security:
*\li No anticipated impact.
*
* Standards:
*\li RFCs: 1034, 1035, 2181, TBS
*\li Drafts: TBS
*/
#include <isc/event.h>
#include <isc/lang.h>
#include <dns/types.h>
ISC_LANG_BEGINDECLS
/*%
* A 'dns_lookupevent_t' is returned when a lookup completes.
* The sender field will be set to the lookup that completed. If 'result'
* is ISC_R_SUCCESS, then 'names' will contain a list of names associated
* with the address. The recipient of the event must not change the list
* and must not refer to any of the name data after the event is freed.
*/
typedef struct dns_lookupevent {
ISC_EVENT_COMMON(struct dns_lookupevent);
isc_result_t result;
dns_name_t *name;
dns_rdataset_t *rdataset;
dns_rdataset_t *sigrdataset;
dns_db_t *db;
dns_dbnode_t *node;
} dns_lookupevent_t;
isc_result_t
dns_lookup_create(isc_mem_t *mctx, const dns_name_t *name, dns_rdatatype_t type,
dns_view_t *view, unsigned int options, isc_task_t *task,
isc_taskaction_t action, void *arg, dns_lookup_t **lookupp);
/*%<
* Finds the rrsets matching 'name' and 'type'.
*
* Requires:
*
*\li 'mctx' is a valid mctx.
*
*\li 'name' is a valid name.
*
*\li 'view' is a valid view which has a resolver.
*
*\li 'task' is a valid task.
*
*\li lookupp != NULL && *lookupp == NULL
*
* Returns:
*
*\li ISC_R_SUCCESS
*\li ISC_R_NOMEMORY
*
*\li Any resolver-related error (e.g. ISC_R_SHUTTINGDOWN) may also be
* returned.
*/
void
dns_lookup_cancel(dns_lookup_t *lookup);
/*%<
* Cancel 'lookup'.
*
* Notes:
*
*\li If 'lookup' has not completed, post its LOOKUPDONE event with a
* result code of ISC_R_CANCELED.
*
* Requires:
*
*\li 'lookup' is a valid lookup.
*/
void
dns_lookup_destroy(dns_lookup_t **lookupp);
/*%<
* Destroy 'lookup'.
*
* Requires:
*
*\li '*lookupp' is a valid lookup.
*
*\li The caller has received the LOOKUPDONE event (either because the
* lookup completed or because dns_lookup_cancel() was called).
*
* Ensures:
*
*\li *lookupp == NULL.
*/
ISC_LANG_ENDDECLS
+1 -1
View File
@@ -225,7 +225,7 @@ dns_resolver_freeze(dns_resolver_t *res);
*/
void
dns_resolver_prime(dns_resolver_t *res);
dns_resolver_prime(dns_resolver_t *res, isc_task_t *task);
/*%<
* Prime resolver.
*
+5 -5
View File
@@ -542,11 +542,11 @@ dns_view_thaw(dns_view_t *view);
*/
isc_result_t
dns_view_find(dns_view_t *view, const dns_name_t *name, dns_rdatatype_t type,
isc_stdtime_t now, unsigned int options, bool use_hints,
bool use_static_stub, dns_db_t **dbp, dns_dbnode_t **nodep,
dns_name_t *foundname, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset);
dns_view_find(dns_view_t *view, isc_task_t *task, const dns_name_t *name,
dns_rdatatype_t type, isc_stdtime_t now, unsigned int options,
bool use_hints, bool use_static_stub, dns_db_t **dbp,
dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
/*%<
* Find an rdataset whose owner name is 'name', and whose type is
* 'type'.
-445
View File
@@ -1,445 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*! \file */
#include <stdbool.h>
#include <isc/mem.h>
#include <isc/netaddr.h>
#include <isc/result.h>
#include <isc/string.h>
#include <isc/task.h>
#include <isc/util.h>
#include <dns/db.h>
#include <dns/events.h>
#include <dns/lookup.h>
#include <dns/rdata.h>
#include <dns/rdataset.h>
#include <dns/rdatastruct.h>
#include <dns/resolver.h>
#include <dns/view.h>
struct dns_lookup {
/* Unlocked. */
unsigned int magic;
isc_mem_t *mctx;
isc_mutex_t lock;
dns_rdatatype_t type;
dns_fixedname_t name;
/* Locked by lock. */
unsigned int options;
isc_task_t *task;
dns_view_t *view;
dns_lookupevent_t *event;
dns_fetch_t *fetch;
unsigned int restarts;
bool canceled;
dns_rdataset_t rdataset;
dns_rdataset_t sigrdataset;
};
#define LOOKUP_MAGIC ISC_MAGIC('l', 'o', 'o', 'k')
#define VALID_LOOKUP(l) ISC_MAGIC_VALID((l), LOOKUP_MAGIC)
#define MAX_RESTARTS 16
static void
lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event);
static void
fetch_done(isc_task_t *task, isc_event_t *event) {
dns_lookup_t *lookup = event->ev_arg;
dns_fetchevent_t *fevent;
UNUSED(task);
REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
REQUIRE(VALID_LOOKUP(lookup));
REQUIRE(lookup->task == task);
fevent = (dns_fetchevent_t *)event;
REQUIRE(fevent->fetch == lookup->fetch);
lookup_find(lookup, fevent);
}
static isc_result_t
start_fetch(dns_lookup_t *lookup) {
isc_result_t result;
/*
* The caller must be holding the lookup's lock.
*/
REQUIRE(lookup->fetch == NULL);
result = dns_resolver_createfetch(
lookup->view->resolver, dns_fixedname_name(&lookup->name),
lookup->type, NULL, NULL, NULL, NULL, 0, 0, 0, NULL,
lookup->task, fetch_done, lookup, &lookup->rdataset,
&lookup->sigrdataset, &lookup->fetch);
return (result);
}
static void
build_event(dns_lookup_t *lookup) {
dns_name_t *name = NULL;
dns_rdataset_t *rdataset = NULL;
dns_rdataset_t *sigrdataset = NULL;
name = isc_mem_get(lookup->mctx, sizeof(dns_name_t));
dns_name_init(name, NULL);
dns_name_dup(dns_fixedname_name(&lookup->name), lookup->mctx, name);
if (dns_rdataset_isassociated(&lookup->rdataset)) {
rdataset = isc_mem_get(lookup->mctx, sizeof(dns_rdataset_t));
dns_rdataset_init(rdataset);
dns_rdataset_clone(&lookup->rdataset, rdataset);
}
if (dns_rdataset_isassociated(&lookup->sigrdataset)) {
sigrdataset = isc_mem_get(lookup->mctx, sizeof(dns_rdataset_t));
dns_rdataset_init(sigrdataset);
dns_rdataset_clone(&lookup->sigrdataset, sigrdataset);
}
lookup->event->name = name;
lookup->event->rdataset = rdataset;
lookup->event->sigrdataset = sigrdataset;
}
static isc_result_t
view_find(dns_lookup_t *lookup, dns_name_t *foundname) {
isc_result_t result;
dns_name_t *name = dns_fixedname_name(&lookup->name);
dns_rdatatype_t type;
if (lookup->type == dns_rdatatype_rrsig) {
type = dns_rdatatype_any;
} else {
type = lookup->type;
}
result = dns_view_find(lookup->view, name, type, 0, 0, false, false,
&lookup->event->db, &lookup->event->node,
foundname, &lookup->rdataset,
&lookup->sigrdataset);
return (result);
}
static void
lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) {
isc_result_t result = ISC_R_SUCCESS;
bool want_restart;
bool send_event;
dns_name_t *name = NULL, *fname = NULL, *prefix = NULL;
dns_fixedname_t foundname, fixed;
dns_rdata_t rdata = DNS_RDATA_INIT;
unsigned int nlabels;
int order;
dns_namereln_t namereln;
dns_rdata_cname_t cname;
dns_rdata_dname_t dname;
REQUIRE(VALID_LOOKUP(lookup));
LOCK(&lookup->lock);
name = dns_fixedname_name(&lookup->name);
do {
lookup->restarts++;
want_restart = false;
send_event = true;
if (event == NULL && !lookup->canceled) {
fname = dns_fixedname_initname(&foundname);
INSIST(!dns_rdataset_isassociated(&lookup->rdataset));
INSIST(!dns_rdataset_isassociated(
&lookup->sigrdataset));
/*
* If we have restarted then clear the old node.
*/
if (lookup->event->node != NULL) {
INSIST(lookup->event->db != NULL);
dns_db_detachnode(lookup->event->db,
&lookup->event->node);
}
if (lookup->event->db != NULL) {
dns_db_detach(&lookup->event->db);
}
result = view_find(lookup, fname);
if (result == ISC_R_NOTFOUND) {
/*
* We don't know anything about the name.
* Launch a fetch.
*/
if (lookup->event->node != NULL) {
INSIST(lookup->event->db != NULL);
dns_db_detachnode(lookup->event->db,
&lookup->event->node);
}
if (lookup->event->db != NULL) {
dns_db_detach(&lookup->event->db);
}
result = start_fetch(lookup);
if (result == ISC_R_SUCCESS) {
send_event = false;
}
goto done;
}
} else if (event != NULL) {
result = event->result;
fname = event->foundname;
dns_resolver_destroyfetch(&lookup->fetch);
INSIST(event->rdataset == &lookup->rdataset);
INSIST(event->sigrdataset == &lookup->sigrdataset);
}
/*
* If we've been canceled, forget about the result.
*/
if (lookup->canceled) {
result = ISC_R_CANCELED;
}
switch (result) {
case ISC_R_SUCCESS:
build_event(lookup);
if (event == NULL) {
break;
}
if (event->db != NULL) {
dns_db_attach(event->db, &lookup->event->db);
}
if (event->node != NULL) {
dns_db_attachnode(lookup->event->db,
event->node,
&lookup->event->node);
}
break;
case DNS_R_CNAME:
/*
* Copy the CNAME's target into the lookup's
* query name and start over.
*/
result = dns_rdataset_first(&lookup->rdataset);
if (result != ISC_R_SUCCESS) {
break;
}
dns_rdataset_current(&lookup->rdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &cname, NULL);
dns_rdata_reset(&rdata);
if (result != ISC_R_SUCCESS) {
break;
}
dns_name_copy(&cname.cname, name);
dns_rdata_freestruct(&cname);
want_restart = true;
send_event = false;
break;
case DNS_R_DNAME:
namereln = dns_name_fullcompare(name, fname, &order,
&nlabels);
INSIST(namereln == dns_namereln_subdomain);
/*
* Get the target name of the DNAME.
*/
result = dns_rdataset_first(&lookup->rdataset);
if (result != ISC_R_SUCCESS) {
break;
}
dns_rdataset_current(&lookup->rdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &dname, NULL);
dns_rdata_reset(&rdata);
if (result != ISC_R_SUCCESS) {
break;
}
/*
* Construct the new query name and start over.
*/
prefix = dns_fixedname_initname(&fixed);
dns_name_split(name, nlabels, prefix, NULL);
result = dns_name_concatenate(prefix, &dname.dname,
name, NULL);
dns_rdata_freestruct(&dname);
if (result == ISC_R_SUCCESS) {
want_restart = true;
send_event = false;
}
break;
default:
send_event = true;
}
if (dns_rdataset_isassociated(&lookup->rdataset)) {
dns_rdataset_disassociate(&lookup->rdataset);
}
if (dns_rdataset_isassociated(&lookup->sigrdataset)) {
dns_rdataset_disassociate(&lookup->sigrdataset);
}
done:
if (event != NULL) {
if (event->node != NULL) {
dns_db_detachnode(event->db, &event->node);
}
if (event->db != NULL) {
dns_db_detach(&event->db);
}
isc_event_free(ISC_EVENT_PTR(&event));
}
/*
* Limit the number of restarts.
*/
if (want_restart && lookup->restarts == MAX_RESTARTS) {
want_restart = false;
result = ISC_R_QUOTA;
send_event = true;
}
} while (want_restart);
if (send_event) {
lookup->event->result = result;
lookup->event->ev_sender = lookup;
isc_task_sendanddetach(&lookup->task,
(isc_event_t **)&lookup->event);
dns_view_detach(&lookup->view);
}
UNLOCK(&lookup->lock);
}
static void
levent_destroy(isc_event_t *event) {
dns_lookupevent_t *levent;
isc_mem_t *mctx;
REQUIRE(event->ev_type == DNS_EVENT_LOOKUPDONE);
mctx = event->ev_destroy_arg;
levent = (dns_lookupevent_t *)event;
if (levent->name != NULL) {
if (dns_name_dynamic(levent->name)) {
dns_name_free(levent->name, mctx);
}
isc_mem_put(mctx, levent->name, sizeof(dns_name_t));
}
if (levent->rdataset != NULL) {
dns_rdataset_disassociate(levent->rdataset);
isc_mem_put(mctx, levent->rdataset, sizeof(dns_rdataset_t));
}
if (levent->sigrdataset != NULL) {
dns_rdataset_disassociate(levent->sigrdataset);
isc_mem_put(mctx, levent->sigrdataset, sizeof(dns_rdataset_t));
}
if (levent->node != NULL) {
dns_db_detachnode(levent->db, &levent->node);
}
if (levent->db != NULL) {
dns_db_detach(&levent->db);
}
isc_mem_put(mctx, event, event->ev_size);
}
isc_result_t
dns_lookup_create(isc_mem_t *mctx, const dns_name_t *name, dns_rdatatype_t type,
dns_view_t *view, unsigned int options, isc_task_t *task,
isc_taskaction_t action, void *arg, dns_lookup_t **lookupp) {
dns_lookup_t *lookup;
isc_event_t *ievent;
lookup = isc_mem_get(mctx, sizeof(*lookup));
lookup->mctx = NULL;
isc_mem_attach(mctx, &lookup->mctx);
lookup->options = options;
ievent = isc_event_allocate(mctx, lookup, DNS_EVENT_LOOKUPDONE, action,
arg, sizeof(*lookup->event));
lookup->event = (dns_lookupevent_t *)ievent;
lookup->event->ev_destroy = levent_destroy;
lookup->event->ev_destroy_arg = mctx;
lookup->event->result = ISC_R_FAILURE;
lookup->event->name = NULL;
lookup->event->rdataset = NULL;
lookup->event->sigrdataset = NULL;
lookup->event->db = NULL;
lookup->event->node = NULL;
lookup->task = NULL;
isc_task_attach(task, &lookup->task);
isc_mutex_init(&lookup->lock);
dns_fixedname_init(&lookup->name);
dns_name_copy(name, dns_fixedname_name(&lookup->name));
lookup->type = type;
lookup->view = NULL;
dns_view_attach(view, &lookup->view);
lookup->fetch = NULL;
lookup->restarts = 0;
lookup->canceled = false;
dns_rdataset_init(&lookup->rdataset);
dns_rdataset_init(&lookup->sigrdataset);
lookup->magic = LOOKUP_MAGIC;
*lookupp = lookup;
lookup_find(lookup, NULL);
return (ISC_R_SUCCESS);
}
void
dns_lookup_cancel(dns_lookup_t *lookup) {
REQUIRE(VALID_LOOKUP(lookup));
LOCK(&lookup->lock);
if (!lookup->canceled) {
lookup->canceled = true;
if (lookup->fetch != NULL) {
INSIST(lookup->view != NULL);
dns_resolver_cancelfetch(lookup->fetch);
}
}
UNLOCK(&lookup->lock);
}
void
dns_lookup_destroy(dns_lookup_t **lookupp) {
dns_lookup_t *lookup;
REQUIRE(lookupp != NULL);
lookup = *lookupp;
*lookupp = NULL;
REQUIRE(VALID_LOOKUP(lookup));
REQUIRE(lookup->event == NULL);
REQUIRE(lookup->task == NULL);
REQUIRE(lookup->view == NULL);
if (dns_rdataset_isassociated(&lookup->rdataset)) {
dns_rdataset_disassociate(&lookup->rdataset);
}
if (dns_rdataset_isassociated(&lookup->sigrdataset)) {
dns_rdataset_disassociate(&lookup->sigrdataset);
}
isc_mutex_destroy(&lookup->lock);
lookup->magic = 0;
isc_mem_putanddetach(&lookup->mctx, lookup, sizeof(*lookup));
}
+1 -1
View File
@@ -111,7 +111,7 @@ dns_ntatable_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
ntatable = isc_mem_get(view->mctx, sizeof(*ntatable));
ntatable->task = NULL;
result = isc_task_create(taskmgr, 0, &ntatable->task);
result = isc_task_create(taskmgr, 0, &ntatable->task, 0);
if (result != ISC_R_SUCCESS) {
goto cleanup_ntatable;
}
+23 -60
View File
@@ -331,8 +331,7 @@ struct fetchctx {
isc_mem_t *mctx;
isc_stdtime_t now;
isc_task_t *restask;
unsigned int tid;
isc_task_t *task;
/* Atomic */
isc_refcount_t references;
@@ -543,7 +542,6 @@ struct dns_resolver {
isc_ht_t *zonebuckets;
isc_rwlock_t zonehash_lock;
unsigned int ntasks;
isc_task_t **tasks;
uint32_t lame_ttl;
ISC_LIST(alternate_t) alternates;
uint16_t udpsize;
@@ -3367,10 +3365,10 @@ findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
* See what we know about this address.
*/
fctx_addref(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->task, 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),
@@ -4174,8 +4172,8 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
result = dns_resolver_createfetch(
fctx->res, fctx->qminname, fctx->qmintype, fctx->domain,
&fctx->nameservers, NULL, NULL, 0, options, 0, fctx->qc,
fctx->restask, resume_qmin, fctx, &fctx->qminrrset,
NULL, &fctx->qminfetch);
fctx->task, resume_qmin, fctx, &fctx->qminrrset, NULL,
&fctx->qminfetch);
if (result != ISC_R_SUCCESS) {
fctx_unref(fctx);
fctx_done_detach(&fctx, DNS_R_SERVFAIL);
@@ -4403,6 +4401,7 @@ fctx_destroy(fetchctx_t *fctx) {
isc_timer_destroy(&fctx->timer);
isc_task_detach(&fctx->task);
dns_resolver_detach(&fctx->res);
isc_mem_free(fctx->mctx, fctx->info);
@@ -4435,7 +4434,7 @@ fctx_shutdown(fetchctx_t *fctx) {
if (fctx->state != fetchstate_init) {
FCTXTRACE("posting control event");
cevent = &fctx->control_event;
isc_task_send(fctx->restask, &cevent);
isc_task_send(fctx->task, &cevent);
}
}
@@ -4661,7 +4660,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
const dns_name_t *domain, dns_rdataset_t *nameservers,
const isc_sockaddr_t *client, unsigned int options,
fctxbucket_t *bucket, unsigned int depth, isc_counter_t *qc,
fetchctx_t **fctxp) {
isc_task_t *task, fetchctx_t **fctxp) {
fetchctx_t *fctx = NULL;
isc_result_t result;
isc_result_t iresult;
@@ -4669,11 +4668,6 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
unsigned int findoptions = 0;
char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + 1];
size_t p;
int tid = isc_nm_tid();
if (tid == ISC_NETMGR_TID_UNKNOWN) {
tid = 0;
}
/*
* Caller must be holding the lock for 'bucket'
@@ -4686,8 +4680,6 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
.qmintype = type,
.options = options,
.bucket = bucket,
.tid = tid,
.restask = res->tasks[tid],
.state = fetchstate_init,
.depth = depth,
.qmin_labels = 1,
@@ -4697,6 +4689,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
};
dns_resolver_attach(res, &fctx->res);
isc_task_attach(task, &fctx->task);
if (qc != NULL) {
isc_counter_attach(qc, &fctx->qc);
@@ -4875,7 +4868,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
* lifetime. It will be made active when the fetch is
* started.
*/
isc_timer_create(res->timermgr, fctx->restask, fctx_expired, fctx,
isc_timer_create(res->timermgr, fctx->task, fctx_expired, fctx,
&fctx->timer);
/*
@@ -4965,6 +4958,7 @@ cleanup_nameservers:
isc_counter_detach(&fctx->qc);
cleanup_fetch:
isc_task_detach(&fctx->task);
dns_resolver_detach(&fctx->res);
isc_mem_put(res->mctx, fctx, sizeof(*fctx));
@@ -6335,7 +6329,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_message_t *message,
fctx, message, addrinfo, name,
rdataset->type, rdataset,
sigrdataset, valoptions,
fctx->restask);
fctx->task);
}
} else if (CHAINING(rdataset)) {
if (rdataset->type == dns_rdatatype_cname) {
@@ -6442,7 +6436,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_message_t *message,
result = valcreate(fctx, message, addrinfo, name, vtype,
valrdataset, valsigrdataset, valoptions,
fctx->restask);
fctx->task);
}
if (result == ISC_R_SUCCESS && have_answer) {
@@ -6662,7 +6656,7 @@ ncache_message(fetchctx_t *fctx, dns_message_t *message,
* Do negative response validation.
*/
result = valcreate(fctx, message, addrinfo, name, fctx->type,
NULL, NULL, valoptions, fctx->restask);
NULL, NULL, valoptions, fctx->task);
/*
* If validation is necessary, return now. Otherwise
* continue to process the message, letting the
@@ -9700,7 +9694,7 @@ rctx_chaseds(respctx_t *rctx, dns_message_t *message,
fctx_addref(fctx);
result = dns_resolver_createfetch(
fctx->res, fctx->nsname, dns_rdatatype_ns, NULL, NULL, NULL,
NULL, 0, fctx->options, 0, NULL, fctx->restask, resume_dslookup,
NULL, 0, fctx->options, 0, NULL, fctx->task, resume_dslookup,
fctx, &fctx->nsrrset, NULL, &fctx->nsfetch);
if (result != ISC_R_SUCCESS) {
if (result == DNS_R_DUPLICATE) {
@@ -10076,11 +10070,6 @@ destroy(dns_resolver_t *res) {
isc_mutex_destroy(&res->primelock);
isc_mutex_destroy(&res->lock);
for (size_t i = 0; i < res->ntasks; i++) {
isc_task_detach(&res->tasks[i]);
}
isc_mem_put(res->mctx, res->tasks, res->ntasks * sizeof(res->tasks[0]));
isc_ht_iter_create(res->buckets, &it);
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
result = isc_ht_iter_delcurrent_next(it))
@@ -10173,7 +10162,6 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
dns_resolver_t **resp) {
isc_result_t result = ISC_R_SUCCESS;
char name[sizeof("res4294967295")];
dns_resolver_t *res = NULL;
isc_task_t *task = NULL;
@@ -10222,23 +10210,6 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
goto cleanup_res;
}
res->tasks = isc_mem_get(view->mctx,
res->ntasks * sizeof(res->tasks[0]));
memset(res->tasks, 0, res->ntasks * sizeof(res->tasks[0]));
for (uint32_t i = 0; i < res->ntasks; i++) {
/*
* Since we have a pool of tasks we bind them to task
* queues to spread the load evenly
*/
result = isc_task_create_bound(taskmgr, 0, &res->tasks[i], i);
if (result != ISC_R_SUCCESS) {
goto cleanup_tasks;
}
snprintf(name, sizeof(name), "res%" PRIu32, i);
isc_task_setname(res->tasks[i], name, res);
}
isc_ht_init(&res->buckets, view->mctx, RES_DOMAIN_HASH_BITS,
ISC_HT_CASE_INSENSITIVE);
isc_rwlock_init(&res->hash_lock, 0, 0);
@@ -10260,7 +10231,7 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
isc_mutex_init(&res->lock);
isc_mutex_init(&res->primelock);
result = isc_task_create(taskmgr, 0, &task);
result = isc_task_create(taskmgr, 0, &task, 0);
if (result != ISC_R_SUCCESS) {
goto cleanup_primelock;
}
@@ -10293,15 +10264,6 @@ cleanup_primelock:
isc_rwlock_destroy(&res->hash_lock);
isc_ht_destroy(&res->buckets);
cleanup_tasks:
for (size_t i = 0; i < res->ntasks; i++) {
if (res->tasks[i] != NULL) {
isc_task_detach(&res->tasks[i]);
}
}
isc_mem_put(view->mctx, res->tasks,
res->ntasks * sizeof(res->tasks[0]));
dns_badcache_destroy(&res->badcache);
cleanup_res:
@@ -10363,7 +10325,7 @@ prime_done(isc_task_t *task, isc_event_t *event) {
}
void
dns_resolver_prime(dns_resolver_t *res) {
dns_resolver_prime(dns_resolver_t *res, isc_task_t *task) {
bool want_priming = false;
dns_rdataset_t *rdataset;
isc_result_t result;
@@ -10396,7 +10358,7 @@ dns_resolver_prime(dns_resolver_t *res) {
INSIST(res->primefetch == NULL);
result = dns_resolver_createfetch(
res, dns_rootname, dns_rdatatype_ns, NULL, NULL, NULL,
NULL, 0, DNS_FETCHOPT_NOFORWARD, 0, NULL, res->tasks[0],
NULL, 0, DNS_FETCHOPT_NOFORWARD, 0, NULL, task,
prime_done, res, rdataset, NULL, &res->primefetch);
UNLOCK(&res->primelock);
@@ -10754,7 +10716,8 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
if (fctx == NULL) {
result = fctx_create(res, name, type, domain, nameservers,
client, options, bucket, depth, qc, &fctx);
client, options, bucket, depth, qc, task,
&fctx);
if (result != ISC_R_SUCCESS) {
goto unlock;
}
@@ -10783,7 +10746,7 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
ISC_EVENT_INIT(event, sizeof(*event), 0, NULL,
DNS_EVENT_FETCHCONTROL, fctx_start, fctx,
NULL, NULL, NULL);
isc_task_send(fctx->restask, &event);
isc_task_send(fctx->task, &event);
} else {
dodestroy = true;
}
+1 -1
View File
@@ -1476,7 +1476,7 @@ dns_rpz_new_zones(dns_rpz_zones_t **rpzsp, char *rps_cstr, size_t rps_cstr_size,
goto cleanup_rbt;
}
result = isc_task_create(taskmgr, 0, &rpzs->updater);
result = isc_task_create(taskmgr, 0, &rpzs->updater, 0);
if (result != ISC_R_SUCCESS) {
goto cleanup_task;
}
+1 -1
View File
@@ -113,7 +113,7 @@ create_managers(void) {
ncpus = isc_os_ncpus();
isc_managers_create(dt_mctx, ncpus, 0, &netmgr, &taskmgr, &timermgr);
CHECK(isc_task_create(taskmgr, 0, &maintask));
CHECK(isc_task_create(taskmgr, 0, &maintask, 0));
return (ISC_R_SUCCESS);
cleanup:
+1 -1
View File
@@ -603,7 +603,7 @@ nta_test(void **state) {
result = dns_test_makeview("view", &myview);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_create(taskmgr, 0, &myview->task);
result = isc_task_create(taskmgr, 0, &myview->task, 0);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_view_initsecroots(myview, dt_mctx);
+3 -3
View File
@@ -974,9 +974,9 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
options = DNS_DBFIND_PENDINGOK;
foundname = dns_fixedname_initname(&fixedname);
result = dns_view_find(val->view, name, type, 0, options, false, false,
NULL, NULL, foundname, &val->frdataset,
&val->fsigrdataset);
result = dns_view_find(val->view, val->task, name, type, 0, options,
false, false, NULL, NULL, foundname,
&val->frdataset, &val->fsigrdataset);
if (result == DNS_R_NXDOMAIN) {
goto notfound;
+11 -10
View File
@@ -629,7 +629,7 @@ dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
REQUIRE(!view->frozen);
REQUIRE(view->resolver == NULL);
result = isc_task_create(taskmgr, 0, &view->task);
result = isc_task_create(taskmgr, 0, &view->task, 0);
if (result != ISC_R_SUCCESS) {
return (result);
}
@@ -826,11 +826,11 @@ dns_view_findzone(dns_view_t *view, const dns_name_t *name,
}
isc_result_t
dns_view_find(dns_view_t *view, const dns_name_t *name, dns_rdatatype_t type,
isc_stdtime_t now, unsigned int options, bool use_hints,
bool use_static_stub, dns_db_t **dbp, dns_dbnode_t **nodep,
dns_name_t *foundname, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset) {
dns_view_find(dns_view_t *view, isc_task_t *task, const dns_name_t *name,
dns_rdatatype_t type, isc_stdtime_t now, unsigned int options,
bool use_hints, bool use_static_stub, dns_db_t **dbp,
dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) {
isc_result_t result;
dns_db_t *db, *zdb;
dns_dbnode_t *node, *znode;
@@ -1003,7 +1003,7 @@ db_find:
* We just used a hint. Let the resolver know it
* should consider priming.
*/
dns_resolver_prime(view->resolver);
dns_resolver_prime(view->resolver, task);
dns_db_attach(view->hints, &db);
result = DNS_R_HINT;
} else if (result == DNS_R_NXRRSET) {
@@ -1069,9 +1069,10 @@ dns_view_simplefind(dns_view_t *view, const dns_name_t *name,
dns_fixedname_t foundname;
dns_fixedname_init(&foundname);
result = dns_view_find(view, name, type, now, options, use_hints, false,
NULL, NULL, dns_fixedname_name(&foundname),
rdataset, sigrdataset);
result = dns_view_find(view, view->task, name, type, now, options,
use_hints, false, NULL, NULL,
dns_fixedname_name(&foundname), rdataset,
sigrdataset);
if (result == DNS_R_NXDOMAIN) {
/*
* The rdataset and sigrdataset of the relevant NSEC record
+5 -5
View File
@@ -18742,7 +18742,7 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
isc_rwlock_init(&zmgr->urlock, 0, 0);
/* Create a single task for queueing of SOA queries. */
result = isc_task_create(taskmgr, 1, &zmgr->task);
result = isc_task_create(taskmgr, 1, &zmgr->task, 0);
if (result != ISC_R_SUCCESS) {
goto free_urlock;
}
@@ -18782,8 +18782,8 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
zmgr->mctx, zmgr->workers * sizeof(zmgr->zonetasks[0]));
memset(zmgr->zonetasks, 0, zmgr->workers * sizeof(zmgr->zonetasks[0]));
for (size_t i = 0; i < zmgr->workers; i++) {
result = isc_task_create_bound(zmgr->taskmgr, 2,
&zmgr->zonetasks[i], i);
result = isc_task_create(zmgr->taskmgr, 2, &zmgr->zonetasks[i],
i);
if (result != ISC_R_SUCCESS) {
goto free_zonetasks;
}
@@ -18794,8 +18794,8 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
zmgr->mctx, zmgr->workers * sizeof(zmgr->loadtasks[0]));
memset(zmgr->loadtasks, 0, zmgr->workers * sizeof(zmgr->loadtasks[0]));
for (size_t i = 0; i < zmgr->workers; i++) {
result = isc_task_create_bound(zmgr->taskmgr, UINT_MAX,
&zmgr->loadtasks[i], i);
result = isc_task_create(zmgr->taskmgr, UINT_MAX,
&zmgr->loadtasks[i], i);
if (result != ISC_R_SUCCESS) {
goto free_loadtasks;
}
+4 -6
View File
@@ -92,14 +92,12 @@ ISC_LANG_BEGINDECLS
*** Types
***/
#define isc_task_create(m, q, t) \
isc__task_create_bound(m, q, t, -1 ISC__TASKFILELINE)
#define isc_task_create_bound(m, q, t, i) \
isc__task_create_bound(m, q, t, i ISC__TASKFILELINE)
#define isc_task_create(m, q, t, i) \
isc__task_create(m, q, t, i ISC__TASKFILELINE)
isc_result_t
isc__task_create_bound(isc_taskmgr_t *manager, unsigned int quantum,
isc_task_t **taskp, int tid ISC__TASKFLARG);
isc__task_create(isc_taskmgr_t *manager, unsigned int quantum,
isc_task_t **taskp, int tid ISC__TASKFLARG);
/*%<
* Create a task, optionally bound to a particular tid.
*
+9 -33
View File
@@ -58,7 +58,7 @@
* locality on CPU.
*
* To make load even some tasks (from task pools) are bound to specific
* queues using isc_task_create_bound. This way load balancing between
* queues using isc_task_create. This way load balancing between
* CPUs/queues happens on the higher layer.
*/
@@ -118,7 +118,6 @@ struct isc_task {
isc_time_t tnow;
char name[16];
void *tag;
bool bound;
/* Protected by atomics */
atomic_bool shuttingdown;
/* Locked by task manager lock. */
@@ -198,18 +197,22 @@ task_destroy(isc_task_t *task) {
}
isc_result_t
isc__task_create_bound(isc_taskmgr_t *manager, unsigned int quantum,
isc_task_t **taskp, int tid ISC__TASKFLARG) {
isc__task_create(isc_taskmgr_t *manager, unsigned int quantum,
isc_task_t **taskp, int tid ISC__TASKFLARG) {
isc_task_t *task = NULL;
bool exiting;
REQUIRE(VALID_MANAGER(manager));
REQUIRE(taskp != NULL && *taskp == NULL);
REQUIRE(tid >= 0 && tid < (int)manager->nworkers);
XTRACE("isc_task_create");
task = isc_mem_get(manager->mctx, sizeof(*task));
*task = (isc_task_t){ 0 };
*task = (isc_task_t){
.state = task_state_idle,
.tid = tid,
};
#if TASKMGR_TRACE
strlcpy(task->func, func, sizeof(task->func));
@@ -221,34 +224,14 @@ isc__task_create_bound(isc_taskmgr_t *manager, unsigned int quantum,
isc_taskmgr_attach(manager, &task->manager);
if (tid == -1) {
/*
* Task is not pinned to a queue, it's tid will be
* randomly chosen when first task will be sent to it.
*/
task->bound = false;
task->tid = -1;
} else {
/*
* Task is pinned to a queue, it'll always be run
* by a specific thread.
*/
task->bound = true;
task->tid = tid % task->manager->nworkers;
}
isc_mutex_init(&task->lock);
task->state = task_state_idle;
isc_refcount_init(&task->references, 1);
INIT_LIST(task->events);
task->nevents = 0;
task->quantum = (quantum > 0) ? quantum : manager->default_quantum;
atomic_init(&task->shuttingdown, false);
task->now = 0;
isc_time_settoepoch(&task->tnow);
memset(task->name, 0, sizeof(task->name));
task->tag = NULL;
INIT_LINK(task, link);
task->magic = TASK_MAGIC;
@@ -304,9 +287,6 @@ task_ready(isc_task_t *task) {
isc_task_attach(task, &(isc_task_t *){ NULL });
LOCK(&task->lock);
if (task->tid < 0) {
task->tid = (int)isc_random_uniform(manager->nworkers);
}
isc_nm_task_enqueue(manager->netmgr, task, task->tid);
UNLOCK(&task->lock);
}
@@ -358,10 +338,6 @@ task_send(isc_task_t *task, isc_event_t **eventp) {
if (task->state == task_state_idle) {
was_idle = true;
if (!task->bound) {
task->tid = (int)isc_random_uniform(
task->manager->nworkers);
}
INSIST(EMPTY(task->events));
task->state = task_state_ready;
}
@@ -523,7 +499,7 @@ task_run(isc_task_t *task) {
REQUIRE(VALID_TASK(task));
LOCK(&task->lock);
quantum = task->quantum;
quantum = task->nevents;
if (task->state != task_state_ready) {
goto done;
+1 -1
View File
@@ -79,7 +79,7 @@ create_managers(unsigned int workers) {
isc_managers_create(test_mctx, workers, 0, &netmgr, &taskmgr,
&timermgr);
CHECK(isc_task_create_bound(taskmgr, 0, &maintask, 0));
CHECK(isc_task_create(taskmgr, 0, &maintask, 0));
isc_taskmgr_setexcltask(taskmgr, maintask);
return (ISC_R_SUCCESS);
+10 -11
View File
@@ -131,7 +131,7 @@ create_task(void **state) {
UNUSED(state);
result = isc_task_create(taskmgr, 0, &task);
result = isc_task_create(taskmgr, 0, &task, 0);
assert_int_equal(result, ISC_R_SUCCESS);
isc_task_detach(&task);
@@ -153,7 +153,7 @@ all_events(void **state) {
atomic_init(&a, 0);
atomic_init(&b, 0);
result = isc_task_create(taskmgr, 0, &task);
result = isc_task_create(taskmgr, 0, &task, 0);
assert_int_equal(result, ISC_R_SUCCESS);
/* First event */
@@ -240,13 +240,13 @@ basic(void **state) {
UNUSED(state);
result = isc_task_create(taskmgr, 0, &task1);
result = isc_task_create(taskmgr, 0, &task1, 0);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_create(taskmgr, 0, &task2);
result = isc_task_create(taskmgr, 0, &task2, 0);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_create(taskmgr, 0, &task3);
result = isc_task_create(taskmgr, 0, &task3, 0);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_create(taskmgr, 0, &task4);
result = isc_task_create(taskmgr, 0, &task4, 0);
assert_int_equal(result, ISC_R_SUCCESS);
isc_interval_set(&interval, 1, 0);
@@ -365,13 +365,12 @@ task_exclusive(void **state) {
if (i == 6) {
/* task chosen from the middle of the range */
result = isc_task_create_bound(taskmgr, 0, &tasks[i],
0);
result = isc_task_create(taskmgr, 0, &tasks[i], 0);
assert_int_equal(result, ISC_R_SUCCESS);
isc_taskmgr_setexcltask(taskmgr, tasks[6]);
} else {
result = isc_task_create(taskmgr, 0, &tasks[i]);
result = isc_task_create(taskmgr, 0, &tasks[i], 0);
assert_int_equal(result, ISC_R_SUCCESS);
}
@@ -415,7 +414,7 @@ maxtask_cb(isc_task_t *task, isc_event_t *event) {
/*
* Create a new task and forward the message.
*/
result = isc_task_create(taskmgr, 0, &task);
result = isc_task_create(taskmgr, 0, &task, 0);
assert_int_equal(result, ISC_R_SUCCESS);
isc_task_send(task, &event);
@@ -513,7 +512,7 @@ try_purgeevent(void) {
atomic_init(&done, false);
eventcnt = 0;
result = isc_task_create(taskmgr, 0, &task);
result = isc_task_create(taskmgr, 0, &task, 0);
assert_int_equal(result, ISC_R_SUCCESS);
/*
+3 -3
View File
@@ -114,7 +114,7 @@ setup_test(isc_timertype_t timertype, isc_interval_t *interval,
LOCK(&mx);
result = isc_task_create(taskmgr, 0, &task);
result = isc_task_create(taskmgr, 0, &task, 0);
assert_int_equal(result, ISC_R_SUCCESS);
isc_mutex_lock(&lasttime_mx);
@@ -493,10 +493,10 @@ purge(void **state) {
seconds = 1;
nanoseconds = 0;
result = isc_task_create(taskmgr, 0, &task1);
result = isc_task_create(taskmgr, 0, &task1, 0);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_create(taskmgr, 0, &task2);
result = isc_task_create(taskmgr, 0, &task2, 0);
assert_int_equal(result, ISC_R_SUCCESS);
isc_interval_set(&interval, seconds, 0);
+2 -2
View File
@@ -2436,8 +2436,8 @@ ns_clientmgr_create(ns_server_t *sctx, isc_taskmgr_t *taskmgr,
dns_aclenv_attach(aclenv, &manager->aclenv);
result = isc_task_create_bound(manager->taskmgr, 20, &manager->task,
manager->tid);
result = isc_task_create(manager->taskmgr, 20, &manager->task,
manager->tid);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
isc_task_setname(manager->task, "clientmgr", NULL);
+1 -1
View File
@@ -302,7 +302,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
isc_mutex_init(&mgr->lock);
result = isc_task_create_bound(taskmgr, 0, &mgr->task, 0);
result = isc_task_create(taskmgr, 0, &mgr->task, 0);
if (result != ISC_R_SUCCESS) {
goto cleanup_lock;
}
+1 -1
View File
@@ -228,7 +228,7 @@ create_managers(void) {
int ncpus = isc_os_ncpus();
isc_managers_create(mctx, ncpus, 0, &netmgr, &taskmgr, &timermgr);
CHECK(isc_task_create_bound(taskmgr, 0, &maintask, 0));
CHECK(isc_task_create(taskmgr, 0, &maintask, 0));
isc_taskmgr_setexcltask(taskmgr, maintask);
CHECK(ns_server_create(mctx, matchview, &sctx));