diff --git a/bin/delv/delv.c b/bin/delv/delv.c index d8f71d7e24..26adc81266 100644 --- a/bin/delv/delv.c +++ b/bin/delv/delv.c @@ -2165,7 +2165,7 @@ run_server(void *arg) { 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); diff --git a/bin/named/include/named/globals.h b/bin/named/include/named/globals.h index 03e35f2cd4..1f6edbc09e 100644 --- a/bin/named/include/named/globals.h +++ b/bin/named/include/named/globals.h @@ -50,7 +50,6 @@ 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); diff --git a/bin/named/main.c b/bin/named/main.c index 0e427a8b0e..521536caa1 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -949,9 +949,7 @@ parse_command_line(int argc, char *argv[]) { 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; @@ -1044,16 +1042,6 @@ create_managers(void) { 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); diff --git a/bin/named/server.c b/bin/named/server.c index 714c1b10b3..bd3ca9bb0e 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -4033,7 +4033,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config, 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; @@ -4685,9 +4685,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config, 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) { @@ -12148,10 +12147,6 @@ named_server_status(named_server_t *server, isc_buffer_t **text) { 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)); diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 3e673f493d..5746933935 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -798,7 +798,7 @@ create_name(const char *str, char *namedata, size_t len, dns_name_t *name) { } 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; @@ -3475,8 +3475,7 @@ main(int argc, char **argv) { 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); diff --git a/bin/tools/mdig.c b/bin/tools/mdig.c index f88edf49f6..6b2facf09b 100644 --- a/bin/tools/mdig.c +++ b/bin/tools/mdig.c @@ -116,6 +116,12 @@ static unsigned char cookie_secret[33]; 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 */ @@ -2069,43 +2075,42 @@ set_source_ports(dns_dispatchmgr_t *manager) { } static void -teardown_view(void *arg) { - dns_view_t *view = arg; +teardown(void *arg ISC_ATTR_UNUSED) { dns_view_detach(&view); -} - -static void -teardown_requestmgr(void *arg) { - dns_requestmgr_t *mgr = arg; - - dns_requestmgr_shutdown(mgr); - dns_requestmgr_detach(&mgr); -} - -static void -teardown_dispatch(void *arg) { - dns_dispatch_t *dispatchv4 = arg; - dns_dispatch_detach(&dispatchv4); -} - -static void -teardown_dispatchmgr(void *arg) { - dns_dispatchmgr_t *dispatchmgr = arg; + dns_requestmgr_shutdown(requestmgr); + dns_requestmgr_detach(&requestmgr); + dns_dispatch_detach(&dispatchvx); dns_dispatchmgr_detach(&dispatchmgr); } +static void +setup(void *arg ISC_ATTR_UNUSED) { + 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)); +} + /*% Main processing routine for mdig */ int 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; @@ -2151,30 +2156,10 @@ main(int argc, char *argv[]) { 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. diff --git a/lib/dns/client.c b/lib/dns/client.c index 205c9764bc..a8100f7ab6 100644 --- a/lib/dns/client.c +++ b/lib/dns/client.c @@ -215,9 +215,8 @@ createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_loopmgr_t *loopmgr, /* 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)); diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index 01562839bf..38b6577ed7 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -119,8 +118,6 @@ struct dns_dispatch { /*% 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; @@ -130,7 +127,7 @@ struct dns_dispatch { 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; }; @@ -188,7 +185,7 @@ static void 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 @@ -417,10 +414,8 @@ dispentry_destroy(dns_dispentry_t *resp) { */ dispentry_cancel(resp, ISC_R_CANCELED); - LOCK(&disp->lock); INSIST(disp->requests > 0); disp->requests--; - UNLOCK(&disp->lock); isc_refcount_destroy(&resp->references); @@ -504,7 +499,7 @@ udp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, disp = resp->disp; - LOCK(&disp->lock); + REQUIRE(disp->tid == isc_tid()); INSIST(resp->reading); resp->reading = false; @@ -518,7 +513,7 @@ udp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, 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) { @@ -617,8 +612,6 @@ next: 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)); @@ -781,11 +774,11 @@ tcp_recv(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region, 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); @@ -886,7 +879,6 @@ tcp_recv(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region, isc_nmhandle_settimeout(handle, timeout); } - UNLOCK(&disp->lock); rcu_read_unlock(); /* @@ -1082,7 +1074,7 @@ dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats) { * 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; @@ -1100,7 +1092,7 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type, .link = ISC_LINK_INITIALIZER, .active = ISC_LIST_INITIALIZER, .pending = ISC_LIST_INITIALIZER, - .tid = isc_tid(), + .tid = tid, .magic = DISPATCH_MAGIC, }; @@ -1110,7 +1102,6 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type, __func__, __FILE__, __LINE__, disp); #endif isc_refcount_init(&disp->references, 1); /* DISPATCH000 */ - isc_mutex_init(&disp->lock); *dispp = disp; } @@ -1125,7 +1116,7 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, LOCK(&mgr->lock); - dispatch_allocate(mgr, isc_socktype_tcp, &disp); + dispatch_allocate(mgr, isc_socktype_tcp, isc_tid(), &disp); disp->peer = *destaddr; @@ -1181,13 +1172,12 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *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); @@ -1207,7 +1197,6 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr, (localaddr != NULL && !isc_sockaddr_eqaddr(localaddr, &sockname))) { - UNLOCK(&disp->lock); continue; } @@ -1240,8 +1229,6 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr, UNREACHABLE(); } - UNLOCK(&disp->lock); - if (disp_connected != NULL) { break; } @@ -1281,7 +1268,7 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, 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; } @@ -1292,7 +1279,7 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, 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; @@ -1308,7 +1295,7 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, } } - 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]; @@ -1361,8 +1348,6 @@ dispatch_destroy(dns_dispatch_t *disp) { isc_nmhandle_detach(&disp->handle); } - isc_mutex_destroy(&disp->lock); - isc_mem_put(mgr->mctx, disp, sizeof(*disp)); /* @@ -1401,10 +1386,9 @@ dns_dispatch_add(dns_dispatch_t *disp, isc_loop_t *loop, unsigned int options, 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); } @@ -1436,7 +1420,6 @@ dns_dispatch_add(dns_dispatch_t *disp, isc_loop_t *loop, unsigned int options, 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); } @@ -1496,7 +1479,6 @@ fail: : dns_resstatscounter_dispreqtcp); rcu_read_unlock(); - UNLOCK(&disp->lock); *idp = resp->id; *respp = resp; @@ -1521,7 +1503,7 @@ dns_dispatch_getnext(dns_dispentry_t *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); @@ -1532,7 +1514,6 @@ dns_dispatch_getnext(dns_dispentry_t *resp) { default: UNREACHABLE(); } - UNLOCK(&disp->lock); return (result); } @@ -1549,10 +1530,10 @@ udp_dispentry_cancel(dns_dispentry_t *resp, isc_result_t 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), @@ -1593,8 +1574,6 @@ udp_dispentry_cancel(dns_dispentry_t *resp, isc_result_t result) { resp->state = DNS_DISPATCHSTATE_CANCELED; unlock: - UNLOCK(&disp->lock); - if (respond) { dispentry_log(resp, LVL(90), "read callback: %s", isc_result_totext(result)); @@ -1614,10 +1593,10 @@ tcp_dispentry_cancel(dns_dispentry_t *resp, isc_result_t 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), @@ -1692,7 +1671,6 @@ tcp_dispentry_cancel(dns_dispentry_t *resp, isc_result_t result) { resp->state = DNS_DISPATCHSTATE_CANCELED; unlock: - UNLOCK(&disp->lock); /* * NOTE: Calling the response callback directly from here should be done @@ -1797,7 +1775,7 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { localbuf, peerbuf, isc_result_totext(eresult)); } - LOCK(&disp->lock); + REQUIRE(disp->tid == isc_tid()); INSIST(disp->state == DNS_DISPATCHSTATE_CONNECTING); /* @@ -1833,8 +1811,6 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { 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); @@ -1856,8 +1832,7 @@ udp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { 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; @@ -1885,7 +1860,6 @@ udp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { /* 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; } @@ -1897,7 +1871,6 @@ udp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { break; } unlock: - UNLOCK(&disp->lock); dispentry_log(resp, LVL(90), "connect callback: %s", isc_result_totext(eresult)); @@ -1909,12 +1882,11 @@ detach: 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); @@ -1944,7 +1916,7 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) { } /* 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 */ @@ -1953,7 +1925,6 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) { 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]; @@ -1979,7 +1950,6 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) { 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: @@ -1996,7 +1966,6 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) { 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)); @@ -2105,7 +2074,7 @@ dns_dispatch_resume(dns_dispentry_t *resp, uint16_t timeout) { 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); @@ -2119,8 +2088,6 @@ dns_dispatch_resume(dns_dispentry_t *resp, uint16_t timeout) { default: UNREACHABLE(); } - - UNLOCK(&disp->lock); } void @@ -2180,31 +2147,25 @@ dns_dispentry_getlocaladdress(dns_dispentry_t *resp, isc_sockaddr_t *addrp) { 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); @@ -2213,21 +2174,19 @@ dns_dispatchset_create(isc_mem_t *mctx, dns_dispatch_t *source, 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; @@ -2242,34 +2201,28 @@ dns_dispatchset_create(isc_mem_t *mctx, dns_dispatch_t *source, 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)); } diff --git a/lib/dns/include/dns/dispatch.h b/lib/dns/include/dns/dispatch.h index d5caf9af78..0813224f8b 100644 --- a/lib/dns/include/dns/dispatch.h +++ b/lib/dns/include/dns/dispatch.h @@ -69,9 +69,7 @@ ISC_LANG_BEGINDECLS struct dns_dispatchset { isc_mem_t *mctx; dns_dispatch_t **dispatches; - int ndisp; - int cur; - isc_mutex_t lock; + uint32_t ndisp; }; /* @@ -358,7 +356,7 @@ dns_dispatchset_get(dns_dispatchset_t *dset); 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 diff --git a/lib/dns/include/dns/resolver.h b/lib/dns/include/dns/resolver.h index 0c6af9c816..01725a13ec 100644 --- a/lib/dns/include/dns/resolver.h +++ b/lib/dns/include/dns/resolver.h @@ -165,9 +165,8 @@ enum { #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); @@ -183,17 +182,15 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr, * *\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. * diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 7e1babaa16..8904a5a485 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -365,8 +365,8 @@ dns_view_weakdetach(dns_view_t **targetp); 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. diff --git a/lib/dns/request.c b/lib/dns/request.c index a5a7291570..46affed3f1 100644 --- a/lib/dns/request.c +++ b/lib/dns/request.c @@ -54,8 +54,8 @@ struct dns_requestmgr { 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; }; @@ -150,10 +150,14 @@ dns_requestmgr_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr, 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); @@ -232,11 +236,11 @@ requestmgr_destroy(dns_requestmgr_t *requestmgr) { 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); @@ -360,11 +364,11 @@ udp_dispatch(dns_requestmgr_t *requestmgr, const isc_sockaddr_t *srcaddr, 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: diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index c21513dda8..f65b7e4a92 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -9930,9 +9930,8 @@ spillattimer_countdown(void *arg) { } 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; @@ -9942,7 +9941,6 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr, */ REQUIRE(DNS_VIEW_VALID(view)); - REQUIRE(ndisp > 0); REQUIRE(resp != NULL && *resp == NULL); REQUIRE(tlsctx_cache != NULL); REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL); @@ -9989,12 +9987,12 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr, 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); diff --git a/lib/dns/view.c b/lib/dns/view.c index 6855d02eda..e07ff434eb 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -589,8 +589,8 @@ dns_view_weakdetach(dns_view_t **viewp) { 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; @@ -601,7 +601,7 @@ dns_view_createresolver(dns_view_t *view, isc_loopmgr_t *loopmgr, 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) { diff --git a/lib/isc/include/isc/tid.h b/lib/isc/include/isc/tid.h index 20bafac595..e630c4f24f 100644 --- a/lib/isc/include/isc/tid.h +++ b/lib/isc/include/isc/tid.h @@ -28,11 +28,11 @@ isc_tid_count(void); * 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. diff --git a/lib/isc/tid.c b/lib/isc/tid.c index 397fac1c8f..d19a413554 100644 --- a/lib/isc/tid.c +++ b/lib/isc/tid.c @@ -23,7 +23,7 @@ /** * 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; @@ -37,8 +37,8 @@ static uint32_t tid_count = 0; 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 diff --git a/lib/ns/include/ns/interfacemgr.h b/lib/ns/include/ns/interfacemgr.h index 651f4d429b..aea5b2dfac 100644 --- a/lib/ns/include/ns/interfacemgr.h +++ b/lib/ns/include/ns/interfacemgr.h @@ -65,9 +65,6 @@ #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. */ diff --git a/tests/dns/dispatch_test.c b/tests/dns/dispatch_test.c index 0780003bab..150ad405ac 100644 --- a/tests/dns/dispatch_test.c +++ b/tests/dns/dispatch_test.c @@ -261,11 +261,12 @@ ISC_LOOP_TEST_IMPL(dispatchset_create) { 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); @@ -291,10 +292,21 @@ ISC_LOOP_TEST_IMPL(dispatchset_get) { 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); diff --git a/tests/dns/resolver_test.c b/tests/dns/resolver_test.c index 09106aadd6..3f53f9f351 100644 --- a/tests/dns/resolver_test.c +++ b/tests/dns/resolver_test.c @@ -76,7 +76,7 @@ mkres(dns_resolver_t **resolverp) { 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); }