dns_view_initsecroots(view);
CHECK(setup_dnsseckeys(NULL, view));
- CHECK(dns_view_createresolver(view, loopmgr, 1, netmgr, 0,
+ CHECK(dns_view_createresolver(view, loopmgr, netmgr, 0,
tlsctx_client_cache, dispatch, NULL));
isc_stats_create(mctx, &resstats, dns_resstatscounter_max);
EXTERN isc_mem_t *named_g_mctx INIT(NULL);
EXTERN unsigned int named_g_cpus INIT(0);
-EXTERN unsigned int named_g_udpdisp INIT(0);
EXTERN isc_loop_t *named_g_mainloop INIT(NULL);
EXTERN isc_loopmgr_t *named_g_loopmgr INIT(NULL);
EXTERN bool named_g_loopmgr_running INIT(false);
parse_T_opt(isc_commandline_argument);
break;
case 'U':
- named_g_udpdisp = parse_int(isc_commandline_argument,
- "number of UDP listeners "
- "per interface");
+ /* Obsolete. No longer in use. Ignore. */
break;
case 'u':
named_g_username = isc_commandline_argument;
ISC_LOG_INFO, "found %u CPU%s, using %u worker thread%s",
named_g_cpus_detected, named_g_cpus_detected == 1 ? "" : "s",
named_g_cpus, named_g_cpus == 1 ? "" : "s");
- if (named_g_udpdisp == 0) {
- named_g_udpdisp = named_g_cpus_detected;
- }
- if (named_g_udpdisp > named_g_cpus) {
- named_g_udpdisp = named_g_cpus;
- }
- isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
- NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
- "using %u UDP listener%s per interface", named_g_udpdisp,
- named_g_udpdisp == 1 ? "" : "s");
isc_managers_create(&named_g_mctx, named_g_cpus, &named_g_loopmgr,
&named_g_netmgr);
named_cache_t *nsc;
bool zero_no_soattl;
dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL;
- unsigned int query_timeout, ndisp;
+ unsigned int query_timeout;
bool old_rpz_ok = false;
dns_dyndbctx_t *dctx = NULL;
unsigned int resolver_param;
goto cleanup;
}
- ndisp = 4 * ISC_MIN(named_g_udpdisp, MAX_UDP_DISPATCH);
CHECK(dns_view_createresolver(
- view, named_g_loopmgr, ndisp, named_g_netmgr, resopts,
+ view, named_g_loopmgr, named_g_netmgr, resopts,
named_g_server->tlsctx_client_cache, dispatch4, dispatch6));
if (resstats == NULL) {
snprintf(line, sizeof(line), "worker threads: %u\n", named_g_cpus);
CHECK(putstr(text, line));
- snprintf(line, sizeof(line), "UDP listeners per interface: %u\n",
- named_g_udpdisp);
- CHECK(putstr(text, line));
-
snprintf(line, sizeof(line), "number of zones: %u (%u automatic)\n",
zonecount, automatic);
CHECK(putstr(text, line));
}
static void
-setup_system(void) {
+setup_system(void *arg ISC_ATTR_UNUSED) {
isc_result_t result;
isc_sockaddr_t bind_any, bind_any6;
isc_sockaddrlist_t *nslist;
timeoutms = timeout * 1000;
isc_nm_settimeouts(netmgr, timeoutms, timeoutms, timeoutms, timeoutms);
- setup_system();
-
+ isc_loopmgr_setup(loopmgr, setup_system, NULL);
isc_loopmgr_setup(loopmgr, getinput, NULL);
isc_loopmgr_teardown(loopmgr, shutdown_program, NULL);
isc_loopmgr_run(loopmgr);
static int onfly = 0;
static char hexcookie[81];
+static isc_sockaddr_t bind_any;
+static isc_nm_t *netmgr = NULL;
+static dns_dispatchmgr_t *dispatchmgr = NULL;
+static dns_dispatch_t *dispatchvx = NULL;
+static dns_view_t *view = NULL;
+
struct query {
char textname[MXNAME]; /*% Name we're going to be
* looking up */
}
static void
-teardown_view(void *arg) {
- dns_view_t *view = arg;
+teardown(void *arg ISC_ATTR_UNUSED) {
dns_view_detach(&view);
+ dns_requestmgr_shutdown(requestmgr);
+ dns_requestmgr_detach(&requestmgr);
+ dns_dispatch_detach(&dispatchvx);
+ dns_dispatchmgr_detach(&dispatchmgr);
}
static void
-teardown_requestmgr(void *arg) {
- dns_requestmgr_t *mgr = arg;
+setup(void *arg ISC_ATTR_UNUSED) {
+ RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
- dns_requestmgr_shutdown(mgr);
- dns_requestmgr_detach(&mgr);
-}
+ set_source_ports(dispatchmgr);
-static void
-teardown_dispatch(void *arg) {
- dns_dispatch_t *dispatchv4 = arg;
- dns_dispatch_detach(&dispatchv4);
-}
+ if (have_ipv4) {
+ isc_sockaddr_any(&bind_any);
+ } else {
+ isc_sockaddr_any6(&bind_any);
+ }
+ RUNCHECK(dns_dispatch_createudp(
+ dispatchmgr, have_src ? &srcaddr : &bind_any, &dispatchvx));
-static void
-teardown_dispatchmgr(void *arg) {
- dns_dispatchmgr_t *dispatchmgr = arg;
- dns_dispatchmgr_detach(&dispatchmgr);
+ RUNCHECK(dns_requestmgr_create(
+ mctx, loopmgr, dispatchmgr, have_ipv4 ? dispatchvx : NULL,
+ have_ipv6 ? dispatchvx : NULL, &requestmgr));
+
+ RUNCHECK(dns_view_create(mctx, NULL, 0, "_mdig", &view));
}
/*% Main processing routine for mdig */
main(int argc, char *argv[]) {
struct query *query = NULL;
isc_result_t result;
- isc_sockaddr_t bind_any;
isc_log_t *lctx = NULL;
isc_logconfig_t *lcfg = NULL;
- isc_nm_t *netmgr = NULL;
- dns_dispatchmgr_t *dispatchmgr = NULL;
- dns_dispatch_t *dispatchvx = NULL;
- dns_view_t *view = NULL;
unsigned int i;
int ns;
fatal("can't choose between IPv4 and IPv6");
}
- RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
-
- set_source_ports(dispatchmgr);
-
- if (have_ipv4) {
- isc_sockaddr_any(&bind_any);
- } else {
- isc_sockaddr_any6(&bind_any);
- }
- RUNCHECK(dns_dispatch_createudp(
- dispatchmgr, have_src ? &srcaddr : &bind_any, &dispatchvx));
-
- RUNCHECK(dns_requestmgr_create(
- mctx, loopmgr, dispatchmgr, have_ipv4 ? dispatchvx : NULL,
- have_ipv6 ? dispatchvx : NULL, &requestmgr));
-
- RUNCHECK(dns_view_create(mctx, NULL, 0, "_mdig", &view));
-
query = ISC_LIST_HEAD(queries);
+ isc_loopmgr_setup(loopmgr, setup, NULL);
isc_loopmgr_setup(loopmgr, sendqueries, query);
- isc_loopmgr_teardown(loopmgr, teardown_view, view);
- isc_loopmgr_teardown(loopmgr, teardown_requestmgr, requestmgr);
- isc_loopmgr_teardown(loopmgr, teardown_dispatch, dispatchvx);
- isc_loopmgr_teardown(loopmgr, teardown_dispatchmgr, dispatchmgr);
+ isc_loopmgr_teardown(loopmgr, teardown, NULL);
/*
* Stall to the start of a new second.
/* Initialize view security roots */
dns_view_initsecroots(view);
- CHECK(dns_view_createresolver(view, loopmgr, 1, nm, 0,
- tlsctx_client_cache, dispatchv4,
- dispatchv6));
+ CHECK(dns_view_createresolver(view, loopmgr, nm, 0, tlsctx_client_cache,
+ dispatchv4, dispatchv6));
CHECK(dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_cache,
rdclass, 0, NULL, &view->cachedb));
#include <sys/types.h>
#include <unistd.h>
-#include <isc/atomic.h>
#include <isc/hash.h>
#include <isc/hashmap.h>
#include <isc/loop.h>
/*% Locked by mgr->lock. */
ISC_LINK(dns_dispatch_t) link;
- /* Locked by "lock". */
- isc_mutex_t lock; /*%< locks all below */
isc_socktype_t socktype;
dns_dispatchstate_t state;
isc_refcount_t references;
dns_displist_t pending;
dns_displist_t active;
- unsigned int requests; /*%< how many requests we have */
+ uint_fast32_t requests; /*%< how many requests we have */
unsigned int timedout;
};
dispentry_cancel(dns_dispentry_t *resp, isc_result_t result);
static isc_result_t
dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
- dns_dispatch_t **dispp);
+ uint32_t tid, dns_dispatch_t **dispp);
static void
udp_startrecv(isc_nmhandle_t *handle, dns_dispentry_t *resp);
static void
*/
dispentry_cancel(resp, ISC_R_CANCELED);
- LOCK(&disp->lock);
INSIST(disp->requests > 0);
disp->requests--;
- UNLOCK(&disp->lock);
isc_refcount_destroy(&resp->references);
disp = resp->disp;
- LOCK(&disp->lock);
+ REQUIRE(disp->tid == isc_tid());
INSIST(resp->reading);
resp->reading = false;
eresult = ISC_R_CANCELED;
}
- dispentry_log(resp, LVL(90), "read callback:%s, requests %d",
+ dispentry_log(resp, LVL(90), "read callback:%s, requests %" PRIuFAST32,
isc_result_totext(eresult), disp->requests);
if (eresult != ISC_R_SUCCESS) {
udp_dispatch_getnext(resp, timeout);
done:
- UNLOCK(&disp->lock);
-
if (respond) {
dispentry_log(resp, LVL(90), "UDP read callback on %p: %s",
handle, isc_result_totext(eresult));
REQUIRE(VALID_DISPATCH(disp));
- LOCK(&disp->lock);
+ REQUIRE(disp->tid == isc_tid());
INSIST(disp->reading);
disp->reading = false;
- dispatch_log(disp, LVL(90), "TCP read:%s:requests %u",
+ dispatch_log(disp, LVL(90), "TCP read:%s:requests %" PRIuFAST32,
isc_result_totext(result), disp->requests);
peer = isc_nmhandle_peeraddr(handle);
isc_nmhandle_settimeout(handle, timeout);
}
- UNLOCK(&disp->lock);
rcu_read_unlock();
/*
* Allocate and set important limits.
*/
static void
-dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type,
+dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type, uint32_t tid,
dns_dispatch_t **dispp) {
dns_dispatch_t *disp = NULL;
.link = ISC_LINK_INITIALIZER,
.active = ISC_LIST_INITIALIZER,
.pending = ISC_LIST_INITIALIZER,
- .tid = isc_tid(),
+ .tid = tid,
.magic = DISPATCH_MAGIC,
};
__func__, __FILE__, __LINE__, disp);
#endif
isc_refcount_init(&disp->references, 1); /* DISPATCH000 */
- isc_mutex_init(&disp->lock);
*dispp = disp;
}
LOCK(&mgr->lock);
- dispatch_allocate(mgr, isc_socktype_tcp, &disp);
+ dispatch_allocate(mgr, isc_socktype_tcp, isc_tid(), &disp);
disp->peer = *destaddr;
isc_sockaddr_t sockname;
isc_sockaddr_t peeraddr;
- LOCK(&disp->lock);
-
if (disp->tid != isc_tid()) {
- UNLOCK(&disp->lock);
continue;
}
+ REQUIRE(disp->tid == isc_tid());
+
if (disp->handle != NULL) {
sockname = isc_nmhandle_localaddr(disp->handle);
peeraddr = isc_nmhandle_peeraddr(disp->handle);
(localaddr != NULL &&
!isc_sockaddr_eqaddr(localaddr, &sockname)))
{
- UNLOCK(&disp->lock);
continue;
}
UNREACHABLE();
}
- UNLOCK(&disp->lock);
-
if (disp_connected != NULL) {
break;
}
REQUIRE(dispp != NULL && *dispp == NULL);
LOCK(&mgr->lock);
- result = dispatch_createudp(mgr, localaddr, &disp);
+ result = dispatch_createudp(mgr, localaddr, isc_tid(), &disp);
if (result == ISC_R_SUCCESS) {
*dispp = disp;
}
static isc_result_t
dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
- dns_dispatch_t **dispp) {
+ uint32_t tid, dns_dispatch_t **dispp) {
isc_result_t result = ISC_R_SUCCESS;
dns_dispatch_t *disp = NULL;
isc_sockaddr_t sa_any;
}
}
- dispatch_allocate(mgr, isc_socktype_udp, &disp);
+ dispatch_allocate(mgr, isc_socktype_udp, tid, &disp);
if (isc_log_wouldlog(dns_lctx, 90)) {
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
isc_nmhandle_detach(&disp->handle);
}
- isc_mutex_destroy(&disp->lock);
-
isc_mem_put(mgr->mctx, disp, sizeof(*disp));
/*
REQUIRE(sent != NULL);
REQUIRE(loop != NULL);
- LOCK(&disp->lock);
+ REQUIRE(disp->tid == isc_tid());
if (disp->state == DNS_DISPATCHSTATE_CANCELED) {
- UNLOCK(&disp->lock);
return (ISC_R_CANCELED);
}
result = setup_socket(disp, resp, dest, &localport);
if (result != ISC_R_SUCCESS) {
isc_mem_put(disp->mgr->mctx, resp, sizeof(*resp));
- UNLOCK(&disp->lock);
inc_stats(disp->mgr, dns_resstatscounter_dispsockfail);
return (result);
}
: dns_resstatscounter_dispreqtcp);
rcu_read_unlock();
- UNLOCK(&disp->lock);
*idp = resp->id;
*respp = resp;
return (ISC_R_TIMEDOUT);
}
- LOCK(&disp->lock);
+ REQUIRE(disp->tid == isc_tid());
switch (disp->socktype) {
case isc_socktype_udp:
udp_dispatch_getnext(resp, timeout);
default:
UNREACHABLE();
}
- UNLOCK(&disp->lock);
return (result);
}
dns_dispatch_t *disp = resp->disp;
bool respond = false;
- LOCK(&disp->lock);
+ REQUIRE(disp->tid == isc_tid());
dispentry_log(resp, LVL(90),
"canceling response: %s, %s/%s (%s/%s), "
- "requests %u",
+ "requests %" PRIuFAST32,
isc_result_totext(result), state2str(resp->state),
resp->reading ? "reading" : "not reading",
state2str(disp->state),
resp->state = DNS_DISPATCHSTATE_CANCELED;
unlock:
- UNLOCK(&disp->lock);
-
if (respond) {
dispentry_log(resp, LVL(90), "read callback: %s",
isc_result_totext(result));
dns_dispatch_t *disp = resp->disp;
dns_displist_t resps = ISC_LIST_INITIALIZER;
- LOCK(&disp->lock);
+ REQUIRE(disp->tid == isc_tid());
dispentry_log(resp, LVL(90),
"canceling response: %s, %s/%s (%s/%s), "
- "requests %u",
+ "requests %" PRIuFAST32,
isc_result_totext(result), state2str(resp->state),
resp->reading ? "reading" : "not reading",
state2str(disp->state),
resp->state = DNS_DISPATCHSTATE_CANCELED;
unlock:
- UNLOCK(&disp->lock);
/*
* NOTE: Calling the response callback directly from here should be done
localbuf, peerbuf, isc_result_totext(eresult));
}
- LOCK(&disp->lock);
+ REQUIRE(disp->tid == isc_tid());
INSIST(disp->state == DNS_DISPATCHSTATE_CONNECTING);
/*
disp->state = DNS_DISPATCHSTATE_NONE;
}
- UNLOCK(&disp->lock);
-
for (resp = ISC_LIST_HEAD(resps); resp != NULL; resp = next) {
next = ISC_LIST_NEXT(resp, rlink);
ISC_LIST_UNLINK(resps, resp, rlink);
dispentry_log(resp, LVL(90), "connected: %s",
isc_result_totext(eresult));
- LOCK(&disp->lock);
-
+ REQUIRE(disp->tid == isc_tid());
switch (resp->state) {
case DNS_DISPATCHSTATE_CANCELED:
eresult = ISC_R_CANCELED;
/* probably a port collision; try a different one */
result = setup_socket(disp, resp, &resp->peer, &localport);
if (result == ISC_R_SUCCESS) {
- UNLOCK(&disp->lock);
udp_dispatch_connect(disp, resp);
goto detach;
}
break;
}
unlock:
- UNLOCK(&disp->lock);
dispentry_log(resp, LVL(90), "connect callback: %s",
isc_result_totext(eresult));
static void
udp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) {
- LOCK(&disp->lock);
+ REQUIRE(disp->tid == isc_tid());
resp->state = DNS_DISPATCHSTATE_CONNECTING;
resp->start = isc_loop_now(resp->loop);
dns_dispentry_ref(resp); /* DISPENTRY004 */
ISC_LIST_APPEND(disp->pending, resp, plink);
- UNLOCK(&disp->lock);
isc_nm_udpconnect(disp->mgr->nm, &resp->local, &resp->peer,
udp_connected, resp, resp->timeout);
}
/* Check whether the dispatch is already connecting or connected. */
- LOCK(&disp->lock);
+ REQUIRE(disp->tid == isc_tid());
switch (disp->state) {
case DNS_DISPATCHSTATE_NONE:
/* First connection, continue with connecting */
resp->start = isc_loop_now(resp->loop);
dns_dispentry_ref(resp); /* DISPENTRY005 */
ISC_LIST_APPEND(disp->pending, resp, plink);
- UNLOCK(&disp->lock);
char localbuf[ISC_SOCKADDR_FORMATSIZE];
char peerbuf[ISC_SOCKADDR_FORMATSIZE];
resp->start = isc_loop_now(resp->loop);
dns_dispentry_ref(resp); /* DISPENTRY005 */
ISC_LIST_APPEND(disp->pending, resp, plink);
- UNLOCK(&disp->lock);
break;
case DNS_DISPATCHSTATE_CONNECTED:
tcp_startrecv(disp, resp);
}
- UNLOCK(&disp->lock);
/* We are already connected; call the connected cb */
dispentry_log(resp, LVL(90), "connect callback: %s",
isc_result_totext(ISC_R_SUCCESS));
dispentry_log(resp, LVL(90), "resume");
- LOCK(&disp->lock);
+ REQUIRE(disp->tid == isc_tid());
switch (disp->socktype) {
case isc_socktype_udp: {
udp_dispatch_getnext(resp, timeout);
default:
UNREACHABLE();
}
-
- UNLOCK(&disp->lock);
}
void
dns_dispatch_t *
dns_dispatchset_get(dns_dispatchset_t *dset) {
- dns_dispatch_t *disp = NULL;
+ uint32_t tid = isc_tid();
/* check that dispatch set is configured */
if (dset == NULL || dset->ndisp == 0) {
return (NULL);
}
- LOCK(&dset->lock);
- disp = dset->dispatches[dset->cur];
- dset->cur++;
- if (dset->cur == dset->ndisp) {
- dset->cur = 0;
- }
- UNLOCK(&dset->lock);
+ INSIST(tid < dset->ndisp);
- return (disp);
+ return (dset->dispatches[tid]);
}
isc_result_t
dns_dispatchset_create(isc_mem_t *mctx, dns_dispatch_t *source,
- dns_dispatchset_t **dsetp, int n) {
+ dns_dispatchset_t **dsetp, uint32_t ndisp) {
isc_result_t result;
dns_dispatchset_t *dset = NULL;
dns_dispatchmgr_t *mgr = NULL;
- int i, j;
+ size_t i;
REQUIRE(VALID_DISPATCH(source));
REQUIRE(source->socktype == isc_socktype_udp);
mgr = source->mgr;
dset = isc_mem_get(mctx, sizeof(dns_dispatchset_t));
- *dset = (dns_dispatchset_t){ .ndisp = n };
-
- isc_mutex_init(&dset->lock);
-
- dset->dispatches = isc_mem_cget(mctx, n, sizeof(dns_dispatch_t *));
+ *dset = (dns_dispatchset_t){ .ndisp = ndisp };
isc_mem_attach(mctx, &dset->mctx);
+ dset->dispatches = isc_mem_cget(dset->mctx, ndisp,
+ sizeof(dns_dispatch_t *));
+
dset->dispatches[0] = NULL;
dns_dispatch_attach(source, &dset->dispatches[0]); /* DISPATCH004 */
LOCK(&mgr->lock);
- for (i = 1; i < n; i++) {
- dset->dispatches[i] = NULL;
- result = dispatch_createudp(mgr, &source->local,
+ for (i = 1; i < dset->ndisp; i++) {
+ result = dispatch_createudp(mgr, &source->local, i,
&dset->dispatches[i]);
if (result != ISC_R_SUCCESS) {
goto fail;
fail:
UNLOCK(&mgr->lock);
- for (j = 0; j < i; j++) {
+ for (size_t j = 0; j < i; j++) {
dns_dispatch_detach(&(dset->dispatches[j])); /* DISPATCH004 */
}
- isc_mem_cput(mctx, dset->dispatches, n, sizeof(dns_dispatch_t *));
- if (dset->mctx == mctx) {
- isc_mem_detach(&dset->mctx);
- }
+ isc_mem_cput(dset->mctx, dset->dispatches, ndisp,
+ sizeof(dns_dispatch_t *));
- isc_mutex_destroy(&dset->lock);
- isc_mem_put(mctx, dset, sizeof(dns_dispatchset_t));
+ isc_mem_putanddetach(&dset->mctx, dset, sizeof(dns_dispatchset_t));
return (result);
}
void
dns_dispatchset_destroy(dns_dispatchset_t **dsetp) {
- dns_dispatchset_t *dset = NULL;
- int i;
-
REQUIRE(dsetp != NULL && *dsetp != NULL);
- dset = *dsetp;
+ dns_dispatchset_t *dset = *dsetp;
*dsetp = NULL;
- for (i = 0; i < dset->ndisp; i++) {
+
+ for (size_t i = 0; i < dset->ndisp; i++) {
dns_dispatch_detach(&(dset->dispatches[i])); /* DISPATCH004 */
}
isc_mem_cput(dset->mctx, dset->dispatches, dset->ndisp,
sizeof(dns_dispatch_t *));
- isc_mutex_destroy(&dset->lock);
isc_mem_putanddetach(&dset->mctx, dset, sizeof(dns_dispatchset_t));
}
struct dns_dispatchset {
isc_mem_t *mctx;
dns_dispatch_t **dispatches;
- int ndisp;
- int cur;
- isc_mutex_t lock;
+ uint32_t ndisp;
};
/*
isc_result_t
dns_dispatchset_create(isc_mem_t *mctx, dns_dispatch_t *source,
- dns_dispatchset_t **dsetp, int n);
+ dns_dispatchset_t **dsetp, uint32_t n);
/*%<
* Given a valid dispatch 'source', create a dispatch set containing
* 'n' UDP dispatches, with the remainder filled out by clones of the
#define DNS_QMIN_MAX_NO_DELEGATION 3
isc_result_t
-dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
- unsigned int ndisp, isc_nm_t *nm, unsigned int options,
- isc_tlsctx_cache_t *tlsctx_cache,
+dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr, isc_nm_t *nm,
+ unsigned int options, isc_tlsctx_cache_t *tlsctx_cache,
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
dns_resolver_t **resp);
*
*\li 'view' is a valid view.
*
- *\li 'ndisp' > 0.
- *
*\li 'nm' is a valid network manager.
*
*\li 'tlsctx_cache' != NULL.
*
*\li 'dispatchv4' is a dispatch with an IPv4 UDP socket, or is NULL.
- * If not NULL, 'ndisp' clones of it will be created by the resolver.
+ * If not NULL, clones per loop of it will be created by the resolver.
*
*\li 'dispatchv6' is a dispatch with an IPv6 UDP socket, or is NULL.
- * If not NULL, 'ndisp' clones of it will be created by the resolver.
+ * If not NULL, clones per loop of it will be created by the resolver.
*
*\li resp != NULL && *resp == NULL.
*
isc_result_t
dns_view_createresolver(dns_view_t *view, isc_loopmgr_t *loopmgr,
- unsigned int ndisp, isc_nm_t *netmgr,
- unsigned int options, isc_tlsctx_cache_t *tlsctx_cache,
+ isc_nm_t *netmgr, unsigned int options,
+ isc_tlsctx_cache_t *tlsctx_cache,
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6);
/*%<
* Create a resolver and address database for the view.
atomic_bool shuttingdown;
dns_dispatchmgr_t *dispatchmgr;
- dns_dispatch_t *dispatchv4;
- dns_dispatch_t *dispatchv6;
+ dns_dispatchset_t *dispatches4;
+ dns_dispatchset_t *dispatches6;
dns_requestlist_t *requests;
};
dns_dispatchmgr_attach(dispatchmgr, &requestmgr->dispatchmgr);
if (dispatchv4 != NULL) {
- dns_dispatch_attach(dispatchv4, &requestmgr->dispatchv4);
+ dns_dispatchset_create(requestmgr->mctx, dispatchv4,
+ &requestmgr->dispatches4,
+ isc_loopmgr_nloops(requestmgr->loopmgr));
}
if (dispatchv6 != NULL) {
- dns_dispatch_attach(dispatchv6, &requestmgr->dispatchv6);
+ dns_dispatchset_create(requestmgr->mctx, dispatchv6,
+ &requestmgr->dispatches6,
+ isc_loopmgr_nloops(requestmgr->loopmgr));
}
isc_refcount_init(&requestmgr->references, 1);
isc_mem_cput(requestmgr->mctx, requestmgr->requests, nloops,
sizeof(requestmgr->requests[0]));
- if (requestmgr->dispatchv4 != NULL) {
- dns_dispatch_detach(&requestmgr->dispatchv4);
+ if (requestmgr->dispatches4 != NULL) {
+ dns_dispatchset_destroy(&requestmgr->dispatches4);
}
- if (requestmgr->dispatchv6 != NULL) {
- dns_dispatch_detach(&requestmgr->dispatchv6);
+ if (requestmgr->dispatches6 != NULL) {
+ dns_dispatchset_destroy(&requestmgr->dispatches6);
}
if (requestmgr->dispatchmgr != NULL) {
dns_dispatchmgr_detach(&requestmgr->dispatchmgr);
if (srcaddr == NULL) {
switch (isc_sockaddr_pf(destaddr)) {
case PF_INET:
- disp = requestmgr->dispatchv4;
+ disp = dns_dispatchset_get(requestmgr->dispatches4);
break;
case PF_INET6:
- disp = requestmgr->dispatchv6;
+ disp = dns_dispatchset_get(requestmgr->dispatches6);
break;
default:
}
isc_result_t
-dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
- unsigned int ndisp, isc_nm_t *nm, unsigned int options,
- isc_tlsctx_cache_t *tlsctx_cache,
+dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr, isc_nm_t *nm,
+ unsigned int options, isc_tlsctx_cache_t *tlsctx_cache,
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
dns_resolver_t **resp) {
dns_resolver_t *res = NULL;
*/
REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(ndisp > 0);
REQUIRE(resp != NULL && *resp == NULL);
REQUIRE(tlsctx_cache != NULL);
REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL);
if (dispatchv4 != NULL) {
dns_dispatchset_create(res->mctx, dispatchv4, &res->dispatches4,
- ndisp);
+ isc_loopmgr_nloops(res->loopmgr));
}
if (dispatchv6 != NULL) {
dns_dispatchset_create(res->mctx, dispatchv6, &res->dispatches6,
- ndisp);
+ isc_loopmgr_nloops(res->loopmgr));
}
isc_mutex_init(&res->lock);
isc_result_t
dns_view_createresolver(dns_view_t *view, isc_loopmgr_t *loopmgr,
- unsigned int ndisp, isc_nm_t *netmgr,
- unsigned int options, isc_tlsctx_cache_t *tlsctx_cache,
+ isc_nm_t *netmgr, unsigned int options,
+ isc_tlsctx_cache_t *tlsctx_cache,
dns_dispatch_t *dispatchv4,
dns_dispatch_t *dispatchv6) {
isc_result_t result;
REQUIRE(view->resolver == NULL);
REQUIRE(view->dispatchmgr != NULL);
- result = dns_resolver_create(view, loopmgr, ndisp, netmgr, options,
+ result = dns_resolver_create(view, loopmgr, netmgr, options,
tlsctx_cache, dispatchv4, dispatchv6,
&view->resolver);
if (result != ISC_R_SUCCESS) {
* Returns the number of threads.
*/
-extern thread_local uint32_t tid_local;
+extern thread_local uint32_t isc__tid_local;
static inline uint32_t
isc_tid(void) {
- return (tid_local);
+ return (isc__tid_local);
}
/*%<
* Returns the thread ID of the currently-running loop.
/**
* Private
*/
-thread_local uint32_t tid_local = ISC_TID_UNKNOWN;
+thread_local uint32_t isc__tid_local = ISC_TID_UNKNOWN;
/*
* Zero is a better nonsense value in this case than ISC_TID_UNKNOWN;
void
isc__tid_init(uint32_t tid) {
- REQUIRE(tid_local == ISC_TID_UNKNOWN || tid_local == tid);
- tid_local = tid;
+ REQUIRE(isc__tid_local == ISC_TID_UNKNOWN || isc__tid_local == tid);
+ isc__tid_local = tid;
}
void
#define NS_INTERFACEFLAG_ANYADDR 0x01U /*%< bound to "any" address */
#define NS_INTERFACEFLAG_LISTENING 0x02U /*%< listening */
-#define MAX_UDP_DISPATCH \
- 128 /*%< Maximum number of UDP dispatchers \
- * to start per interface */
/*% The nameserver interface structure */
struct ns_interface {
unsigned int magic; /*%< Magic number. */
isc_loopmgr_shutdown(loopmgr);
}
-/* test dispatch set round-robin */
+/* test dispatch set per-loop dispatch */
ISC_LOOP_TEST_IMPL(dispatchset_get) {
isc_result_t result;
dns_dispatchset_t *dset = NULL;
dns_dispatch_t *d1, *d2, *d3, *d4, *d5;
+ uint32_t tid_saved;
UNUSED(arg);
result = make_dispatchset(4, &dset);
assert_int_equal(result, ISC_R_SUCCESS);
+ /*
+ * Temporarily modify and then restore the current thread's
+ * ID value, in order to confirm that different threads get
+ * different dispatch sets but the same thread gets the same
+ * one.
+ */
+ tid_saved = isc__tid_local;
d1 = dns_dispatchset_get(dset);
+ isc__tid_local++;
d2 = dns_dispatchset_get(dset);
+ isc__tid_local++;
d3 = dns_dispatchset_get(dset);
+ isc__tid_local++;
d4 = dns_dispatchset_get(dset);
+ isc__tid_local = tid_saved;
d5 = dns_dispatchset_get(dset);
assert_ptr_equal(d1, d5);
isc_result_t result;
isc_tlsctx_cache_create(mctx, &tlsctx_cache);
- result = dns_resolver_create(view, loopmgr, 1, netmgr, 0, tlsctx_cache,
+ result = dns_resolver_create(view, loopmgr, netmgr, 0, tlsctx_cache,
dispatch, NULL, resolverp);
assert_int_equal(result, ISC_R_SUCCESS);
}