From 8b532d2e642c58c4234004600ddda82b81ac887e Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Mon, 26 Jul 2021 20:23:18 -0700 Subject: [PATCH] dispatch: Refactor to eliminate dns_dispatchevent - Responses received by the dispatch are no longer sent to the caller via a task event, but via a netmgr-style recv callback. the 'action' parameter to dns_dispatch_addresponse() is now called 'response' and is called directly from udp_recv() or tcp_recv() when a valid response has been received. - All references to isc_task and isc_taskmgr have been removed from dispatch functions. - All references to dns_dispatchevent_t have been removed and the type has been deleted. - Added a task to the resolver response context, to be used for fctx events. - When the caller cancels an operation, the response handler will be called with ISC_R_CANCELED; it can abort immediately since the caller will presumably have taken care of cleanup already. - Cleaned up attach/detach in resquery and request. --- bin/named/server.c | 12 +- bin/nsupdate/nsupdate.c | 8 +- bin/tests/system/pipelined/pipequeries.c | 5 +- bin/tests/system/tkey/keycreate.c | 4 +- bin/tests/system/tkey/keydelete.c | 4 +- bin/tools/mdig.c | 5 +- lib/dns/client.c | 10 +- lib/dns/dispatch.c | 433 ++++------------------- lib/dns/include/dns/dispatch.h | 75 +--- lib/dns/include/dns/types.h | 1 - lib/dns/include/dns/zone.h | 4 +- lib/dns/request.c | 78 ++-- lib/dns/resolver.c | 264 +++++++------- lib/dns/zone.c | 6 +- lib/isc/include/isc/types.h | 1 - lib/ns/client.c | 1 + lib/ns/include/ns/interfacemgr.h | 2 - lib/ns/interfacemgr.c | 4 - 18 files changed, 288 insertions(+), 629 deletions(-) diff --git a/bin/named/server.c b/bin/named/server.c index 7957591281..dd929b881b 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -1315,8 +1315,7 @@ get_view_querysource_dispatch(const cfg_obj_t **maps, int af, } } - result = dns_dispatch_createudp(named_g_dispatchmgr, named_g_taskmgr, - &sa, attrs, &disp); + result = dns_dispatch_createudp(named_g_dispatchmgr, &sa, attrs, &disp); if (result != ISC_R_SUCCESS) { isc_sockaddr_t any; char buf[ISC_SOCKADDR_FORMATSIZE]; @@ -10145,8 +10144,8 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) { server->heartbeat_interval = 0; CHECKFATAL(dns_zonemgr_create(named_g_mctx, named_g_taskmgr, - named_g_timermgr, named_g_socketmgr, - named_g_netmgr, &server->zonemgr), + named_g_timermgr, named_g_netmgr, + &server->zonemgr), "dns_zonemgr_create"); CHECKFATAL(dns_zonemgr_setsize(server->zonemgr, 1000), "dns_zonemgr_" "setsize"); @@ -10358,9 +10357,8 @@ named_add_reserved_dispatch(named_server_t *server, dispatch->dispatchgen = server->dispatchgen; dispatch->dispatch = NULL; - result = dns_dispatch_createudp(named_g_dispatchmgr, named_g_taskmgr, - &dispatch->addr, attrs, - &dispatch->dispatch); + result = dns_dispatch_createudp(named_g_dispatchmgr, &dispatch->addr, + attrs, &dispatch->dispatch); if (result != ISC_R_SUCCESS) { goto cleanup; } diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 0690676db4..9502fc8299 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -935,15 +935,15 @@ setup_system(void) { if (have_ipv6) { isc_sockaddr_any6(&bind_any6); - result = dns_dispatch_createudp(dispatchmgr, taskmgr, - &bind_any6, 0, &dispatchv6); + result = dns_dispatch_createudp(dispatchmgr, &bind_any6, 0, + &dispatchv6); check_result(result, "dns_dispatch_createudp (v6)"); } if (have_ipv4) { isc_sockaddr_any(&bind_any); - result = dns_dispatch_createudp(dispatchmgr, taskmgr, &bind_any, - 0, &dispatchv4); + result = dns_dispatch_createudp(dispatchmgr, &bind_any, 0, + &dispatchv4); check_result(result, "dns_dispatch_createudp (v4)"); } diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c index e41f14a566..238e04c0f1 100644 --- a/bin/tests/system/pipelined/pipequeries.c +++ b/bin/tests/system/pipelined/pipequeries.c @@ -269,9 +269,8 @@ main(int argc, char *argv[]) { RUNCHECK(isc_task_create(taskmgr, 0, &task)); RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr)); - RUNCHECK(dns_dispatch_createudp(dispatchmgr, taskmgr, - have_src ? &srcaddr : &bind_any, 0, - &dispatchv4)); + RUNCHECK(dns_dispatch_createudp( + dispatchmgr, have_src ? &srcaddr : &bind_any, 0, &dispatchv4)); RUNCHECK(dns_requestmgr_create(mctx, taskmgr, dispatchmgr, dispatchv4, NULL, &requestmgr)); diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c index b83d613f82..ab10793a12 100644 --- a/bin/tests/system/tkey/keycreate.c +++ b/bin/tests/system/tkey/keycreate.c @@ -228,8 +228,8 @@ main(int argc, char *argv[]) { RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr)); isc_sockaddr_any(&bind_any); - RUNCHECK(dns_dispatch_createudp(dispatchmgr, taskmgr, &bind_any, 0, - &dispatchv4)); + RUNCHECK( + dns_dispatch_createudp(dispatchmgr, &bind_any, 0, &dispatchv4)); RUNCHECK(dns_requestmgr_create(mctx, taskmgr, dispatchmgr, dispatchv4, NULL, &requestmgr)); diff --git a/bin/tests/system/tkey/keydelete.c b/bin/tests/system/tkey/keydelete.c index 9b32e2930e..c81c306a8c 100644 --- a/bin/tests/system/tkey/keydelete.c +++ b/bin/tests/system/tkey/keydelete.c @@ -171,8 +171,8 @@ main(int argc, char **argv) { RUNCHECK(isc_task_create(taskmgr, 0, &task)); RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr)); isc_sockaddr_any(&bind_any); - RUNCHECK(dns_dispatch_createudp(dispatchmgr, taskmgr, &bind_any, 0, - &dispatchv4)); + RUNCHECK( + dns_dispatch_createudp(dispatchmgr, &bind_any, 0, &dispatchv4)); RUNCHECK(dns_requestmgr_create(mctx, taskmgr, dispatchmgr, dispatchv4, NULL, &requestmgr)); diff --git a/bin/tools/mdig.c b/bin/tools/mdig.c index ca3acb8eac..5be81925d9 100644 --- a/bin/tools/mdig.c +++ b/bin/tools/mdig.c @@ -2128,9 +2128,8 @@ main(int argc, char *argv[]) { } else { isc_sockaddr_any6(&bind_any); } - RUNCHECK(dns_dispatch_createudp(dispatchmgr, taskmgr, - have_src ? &srcaddr : &bind_any, 0, - &dispatchvx)); + RUNCHECK(dns_dispatch_createudp( + dispatchmgr, have_src ? &srcaddr : &bind_any, 0, &dispatchvx)); RUNCHECK(dns_requestmgr_create( mctx, taskmgr, dispatchmgr, have_ipv4 ? dispatchvx : NULL, diff --git a/lib/dns/client.c b/lib/dns/client.c index 030fa035b6..83b21bb12e 100644 --- a/lib/dns/client.c +++ b/lib/dns/client.c @@ -202,8 +202,7 @@ cleanup: static isc_result_t getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr, - isc_taskmgr_t *taskmgr, dns_dispatch_t **dispp, - const isc_sockaddr_t *localaddr) { + dns_dispatch_t **dispp, const isc_sockaddr_t *localaddr) { dns_dispatch_t *disp = NULL; isc_result_t result; isc_sockaddr_t anyaddr; @@ -213,8 +212,7 @@ getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr, localaddr = &anyaddr; } - result = dns_dispatch_createudp(dispatchmgr, taskmgr, localaddr, 0, - &disp); + result = dns_dispatch_createudp(dispatchmgr, localaddr, 0, &disp); if (result == ISC_R_SUCCESS) { *dispp = disp; } @@ -304,7 +302,7 @@ dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr, */ client->dispatchv4 = NULL; if (localaddr4 != NULL || localaddr6 == NULL) { - result = getudpdispatch(AF_INET, client->dispatchmgr, taskmgr, + result = getudpdispatch(AF_INET, client->dispatchmgr, &dispatchv4, localaddr4); if (result == ISC_R_SUCCESS) { client->dispatchv4 = dispatchv4; @@ -313,7 +311,7 @@ dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr, client->dispatchv6 = NULL; if (localaddr6 != NULL || localaddr4 == NULL) { - result = getudpdispatch(AF_INET6, client->dispatchmgr, taskmgr, + result = getudpdispatch(AF_INET6, client->dispatchmgr, &dispatchv6, localaddr6); if (result == ISC_R_SUCCESS) { client->dispatchv6 = dispatchv6; diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index a839164a7b..08936b43c2 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -25,13 +25,11 @@ #include #include #include -#include #include #include #include #include -#include #include #include #include @@ -79,7 +77,6 @@ struct dns_dispentry { unsigned int magic; isc_refcount_t references; dns_dispatch_t *disp; - isc_task_t *task; isc_nmhandle_t *handle; /*%< netmgr handle for UDP connection */ unsigned int bucket; unsigned int timeout; @@ -89,11 +86,10 @@ struct dns_dispentry { dns_messageid_t id; isc_nm_cb_t connected; isc_nm_cb_t sent; + isc_nm_recv_cb_t response; isc_nm_cb_t timedout; - isc_taskaction_t action; void *arg; bool canceled; - ISC_LIST(dns_dispatchevent_t) items; ISC_LINK(dns_dispentry_t) link; ISC_LINK(dns_dispentry_t) alink; }; @@ -109,7 +105,6 @@ struct dns_dispatch { /* Unlocked. */ unsigned int magic; /*%< magic */ dns_dispatchmgr_t *mgr; /*%< dispatch manager */ - isc_task_t *task; isc_nmhandle_t *handle; /*%< netmgr handle for TCP connection */ isc_sockaddr_t local; /*%< local address */ in_port_t localport; /*%< local UDP port */ @@ -123,8 +118,7 @@ struct dns_dispatch { isc_socktype_t socktype; unsigned int attributes; isc_refcount_t references; - dns_dispatchevent_t failsafe_ev; /*%< failsafe cancel event */ - unsigned int shutdown_out : 1, recv_pending : 1; + unsigned int shutdown_out : 1; ISC_LIST(dns_dispentry_t) active; unsigned int nsockets; @@ -159,14 +153,6 @@ struct dns_dispatch { #define DNS_DISPATCH_SOCKSQUOTA 3072 #endif /* ifndef DNS_DISPATCH_SOCKSQUOTA */ -/*% - * Number of buffers available for all dispatches in the buffer - * memory pool. - */ -#ifndef DNS_DISPATCH_MAXBUFFERS -#define DNS_DISPATCH_MAXBUFFERS 37268 -#endif /* ifndef DNS_DISPATCH_MAXBUFFERS */ - /*% * Quota to control the number of concurrent requests that can be handled * by each TCP dispatch. (UDP dispatches do not currently support socket @@ -206,16 +192,11 @@ tcp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, void *arg); static uint32_t dns_hash(dns_qid_t *, const isc_sockaddr_t *, dns_messageid_t, in_port_t); -static inline void -free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev); -static inline dns_dispatchevent_t * -allocate_devent(dns_dispatch_t *disp); static void dispatch_free(dns_dispatch_t **dispp); static isc_result_t -dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr, - const isc_sockaddr_t *localaddr, unsigned int attributes, - dns_dispatch_t **dispp); +dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, + unsigned int attributes, dns_dispatch_t **dispp); static void qid_allocate(dns_dispatchmgr_t *mgr, dns_qid_t **qidp); static void @@ -285,39 +266,6 @@ dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...) { msgbuf); } -static void -request_log(dns_dispatch_t *disp, dns_dispentry_t *resp, int level, - const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5); - -static void -request_log(dns_dispatch_t *disp, dns_dispentry_t *resp, int level, - const char *fmt, ...) { - char msgbuf[2048]; - va_list ap; - - if (!isc_log_wouldlog(dns_lctx, level)) { - return; - } - - va_start(ap, fmt); - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - va_end(ap); - - if (VALID_RESPONSE(resp)) { - char peerbuf[256]; - isc_sockaddr_format(&resp->peer, peerbuf, sizeof(peerbuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH, - DNS_LOGMODULE_DISPATCH, level, - "dispatch %p response %p %s: %s", disp, resp, - peerbuf, msgbuf); - } else { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH, - DNS_LOGMODULE_DISPATCH, level, - "dispatch %p req/resp %p: %s", disp, resp, - msgbuf); - } -} - /* * Return a hash of the destination and message id. */ @@ -381,10 +329,12 @@ deactivate_dispentry(dns_dispatch_t *disp, dns_dispentry_t *resp) { if (ISC_LINK_LINKED(resp, alink)) { ISC_LIST_UNLINK(disp->active, resp, alink); } + if (resp->handle != NULL) { isc_nm_cancelread(resp->handle); isc_nmhandle_detach(&resp->handle); } + disp->nsockets--; } @@ -414,79 +364,6 @@ entry_search(dns_qid_t *qid, const isc_sockaddr_t *dest, dns_messageid_t id, return (NULL); } -static void -free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) { - REQUIRE(buf != NULL && len != 0); - - switch (disp->socktype) { - case isc_socktype_tcp: - INSIST(disp->tcpbuffers > 0); - disp->tcpbuffers--; - isc_mem_put(disp->mgr->mctx, buf, len); - break; - case isc_socktype_udp: - LOCK(&disp->mgr->buffer_lock); - INSIST(disp->mgr->buffers > 0); - INSIST(len == DNS_DISPATCH_UDPBUFSIZE); - disp->mgr->buffers--; - UNLOCK(&disp->mgr->buffer_lock); - isc_mem_put(disp->mgr->mctx, buf, len); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } -} - -static void * -allocate_udp_buffer(dns_dispatch_t *disp) { - LOCK(&disp->mgr->buffer_lock); - if (disp->mgr->buffers >= DNS_DISPATCH_MAXBUFFERS) { - UNLOCK(&disp->mgr->buffer_lock); - return (NULL); - } - disp->mgr->buffers++; - UNLOCK(&disp->mgr->buffer_lock); - - return (isc_mem_get(disp->mgr->mctx, DNS_DISPATCH_UDPBUFSIZE)); -} - -static inline void -free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev) { - /* failsafe_ev is not allocated */ - if (&(disp->failsafe_ev) == ev) { - INSIST(disp->shutdown_out == 1); - disp->shutdown_out = 0; - - return; - } - - if (ev->region.base != NULL) { - free_buffer(disp, ev->region.base, ev->region.length); - ev->region.base = NULL; - ev->region.length = 0; - } - - isc_mem_put(disp->mgr->mctx, ev, sizeof(*ev)); - - dns_dispatch_detach(&disp); -} - -static inline dns_dispatchevent_t * -allocate_devent(dns_dispatch_t *disp) { - dns_dispatchevent_t *ev = NULL; - - ev = isc_mem_get(disp->mgr->mctx, sizeof(*ev)); - - *ev = (dns_dispatchevent_t){ 0 }; - - dns_dispatch_attach(disp, &ev->dispatch); - - ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, 0, NULL, NULL, NULL, NULL, - NULL); - return (ev); -} - static void dispentry_attach(dns_dispentry_t *resp, dns_dispentry_t **respp) { REQUIRE(VALID_RESPONSE(resp)); @@ -509,7 +386,6 @@ dispentry_destroy(dns_dispentry_t *resp) { isc_refcount_destroy(&resp->references); - isc_task_detach(&resp->task); isc_mem_put(disp->mgr->mctx, resp, sizeof(*resp)); dns_dispatch_detach(&disp); @@ -554,14 +430,14 @@ udp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, isc_result_t dres; isc_buffer_t source; unsigned int flags; - dns_dispatchevent_t *rev = NULL; isc_sockaddr_t peer; isc_netaddr_t netaddr; int match; - isc_taskaction_t action = NULL; + isc_nm_recv_cb_t response = NULL; bool nomore = true; REQUIRE(VALID_RESPONSE(resp)); + REQUIRE(VALID_DISPATCH(resp->disp)); disp = resp->disp; @@ -569,8 +445,8 @@ udp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, if (isc_log_wouldlog(dns_lctx, LVL(90))) { LOCK(&disp->mgr->buffer_lock); - dispatch_log(disp, LVL(90), "got packet: requests %d, recvs %d", - disp->requests, disp->recv_pending); + dispatch_log(disp, LVL(90), "got packet: requests %d", + disp->requests); UNLOCK(&disp->mgr->buffer_lock); } @@ -578,7 +454,7 @@ udp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, /* * This dispatcher is shutting down. */ - goto unlock; + goto sendevent; } if (!ISC_LINK_LINKED(resp, alink)) { @@ -661,43 +537,24 @@ udp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, } sendevent: - rev = allocate_devent(disp); - /* * At this point, rev contains the event we want to fill in, and * resp contains the information on the place to send it to. * Send the event off. */ - rev->result = eresult; - if (region != NULL) { - rev->region.base = allocate_udp_buffer(disp); - rev->region.length = DNS_DISPATCH_UDPBUFSIZE; - memmove(rev->region.base, region->base, region->length); - isc_buffer_init(&rev->buffer, rev->region.base, - rev->region.length); - isc_buffer_add(&rev->buffer, rev->region.length); - } - ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH, - resp->action, resp->arg, resp, NULL, NULL); - - request_log(disp, resp, LVL(90), - "[a] Sent event %p buffer %p len %d to task %p", rev, - rev->buffer.base, rev->buffer.length, resp->task); - - action = resp->action; + response = resp->response; unlock: UNLOCK(&disp->lock); - if (action != NULL) { - action(resp->task, (isc_event_t *)rev); + if (response != NULL) { + response(handle, eresult, region, resp->arg); } if (nomore) { dispentry_detach(&resp); } - return; } /* @@ -718,32 +575,30 @@ unlock: static void tcp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, void *arg) { - dns_dispatch_t *disp = (dns_dispatch_t *)arg; + dns_dispentry_t *resp0 = (dns_dispentry_t *)arg; + dns_dispentry_t *resp = NULL; + dns_dispatch_t *disp = NULL; dns_messageid_t id; isc_result_t dres; unsigned int flags; - dns_dispentry_t *resp = NULL; - dns_dispatchevent_t *rev = NULL; unsigned int bucket; dns_qid_t *qid = NULL; int level; char buf[ISC_SOCKADDR_FORMATSIZE]; isc_buffer_t source; isc_sockaddr_t peer; - isc_taskaction_t action = NULL; - REQUIRE(VALID_DISPATCH(disp)); + REQUIRE(VALID_RESPONSE(resp0)); + REQUIRE(VALID_DISPATCH(resp0->disp)); + + disp = resp0->disp; qid = disp->mgr->qid; LOCK(&disp->lock); - dispatch_log(disp, LVL(90), - "got TCP packet: requests %d, buffers %d, recvs %d", - disp->requests, disp->tcpbuffers, disp->recv_pending); - - INSIST(disp->recv_pending != 0); - disp->recv_pending = 0; + dispatch_log(disp, LVL(90), "got TCP packet: requests %d, buffers %d", + disp->requests, disp->tcpbuffers); peer = isc_nmhandle_peeraddr(handle); @@ -761,13 +616,14 @@ tcp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, /* * Time out the first active response for which * no event has already been sent. + * FIXME: The code doesn't match the description */ for (resp = ISC_LIST_HEAD(disp->active); resp != NULL; resp = ISC_LIST_NEXT(resp, alink)) { ISC_LIST_UNLINK(disp->active, resp, alink); ISC_LIST_APPEND(disp->active, resp, alink); - goto sendevent; + break; } break; @@ -832,48 +688,22 @@ tcp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, dispatch_log(disp, LVL(90), "search for response in bucket %d: %s", bucket, (resp == NULL ? "not found" : "found")); UNLOCK(&qid->lock); + if (resp == NULL) { - goto next; + goto unlock; } -sendevent: - rev = allocate_devent(disp); - - /* - * At this point, rev contains the event we want to fill in, and - * resp contains the information on the place to send it to. - * Send the event off. - */ - rev->result = eresult; - if (region != NULL) { - disp->tcpbuffers++; - rev->region.base = isc_mem_get(disp->mgr->mctx, region->length); - rev->region.length = region->length; - memmove(rev->region.base, region->base, region->length); - isc_buffer_init(&rev->buffer, rev->region.base, - rev->region.length); - isc_buffer_add(&rev->buffer, rev->region.length); - } - - ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH, - resp->action, resp->arg, resp, NULL, NULL); - request_log(disp, resp, LVL(90), - "[b] Sent event %p buffer %p len %d to task %p", rev, - rev->buffer.base, rev->buffer.length, resp->task); - - action = resp->action; - next: - startrecv(disp, NULL); + startrecv(disp, resp0); unlock: isc_nmhandle_detach(&handle); UNLOCK(&disp->lock); - dns_dispatch_detach(&disp); + dispentry_detach(&resp0); - if (action != NULL) { - action(resp->task, (isc_event_t *)rev); + if (resp != NULL) { + resp->response(handle, eresult, region, resp->arg); } } @@ -1168,10 +998,6 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type, int pf, isc_mutex_init(&disp->lock); - /* failsafe_ev is not allocated */ - ISC_EVENT_INIT(&disp->failsafe_ev, sizeof(disp->failsafe_ev), 0, NULL, - 0, NULL, NULL, NULL, NULL, NULL); - disp->magic = DISPATCH_MAGIC; *dispp = disp; @@ -1195,7 +1021,6 @@ dispatch_free(dns_dispatch_t **dispp) { REQUIRE(VALID_DISPATCHMGR(mgr)); INSIST(disp->requests == 0); - INSIST(disp->recv_pending == 0); INSIST(ISC_LIST_EMPTY(disp->active)); isc_mutex_destroy(&disp->lock); @@ -1204,11 +1029,9 @@ dispatch_free(dns_dispatch_t **dispp) { } isc_result_t -dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr, - const isc_sockaddr_t *localaddr, +dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, const isc_sockaddr_t *destaddr, unsigned int attributes, isc_dscp_t dscp, dns_dispatch_t **dispp) { - isc_result_t result; dns_dispatch_t *disp = NULL; int pf; @@ -1231,13 +1054,6 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr, isc_sockaddr_setport(&disp->local, 0); } - result = isc_task_create(taskmgr, 50, &disp->task); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - isc_task_setname(disp->task, "tcpdispatch", disp); - /* * Append it to the dispatcher list. */ @@ -1248,18 +1064,10 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr, mgr_log(mgr, LVL(90), "dns_dispatch_createtcp: created TCP dispatch %p", disp); - dispatch_log(disp, LVL(90), "created task %p", disp->task); } *dispp = disp; return (ISC_R_SUCCESS); - -cleanup: - dispatch_free(&disp); - - UNLOCK(&mgr->lock); - - return (result); } #define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask))) @@ -1333,19 +1141,17 @@ again: } isc_result_t -dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr, - const isc_sockaddr_t *localaddr, unsigned int attributes, - dns_dispatch_t **dispp) { +dns_dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, + unsigned int attributes, dns_dispatch_t **dispp) { isc_result_t result; dns_dispatch_t *disp = NULL; REQUIRE(VALID_DISPATCHMGR(mgr)); REQUIRE(localaddr != NULL); - REQUIRE(taskmgr != NULL); REQUIRE(dispp != NULL && *dispp == NULL); LOCK(&mgr->lock); - result = dispatch_createudp(mgr, taskmgr, localaddr, attributes, &disp); + result = dispatch_createudp(mgr, localaddr, attributes, &disp); if (result == ISC_R_SUCCESS) { *dispp = disp; } @@ -1355,9 +1161,8 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr, } static isc_result_t -dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr, - const isc_sockaddr_t *localaddr, unsigned int attributes, - dns_dispatch_t **dispp) { +dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, + unsigned int attributes, dns_dispatch_t **dispp) { isc_result_t result = ISC_R_SUCCESS; dns_dispatch_t *disp = NULL; isc_sockaddr_t sa_any; @@ -1388,10 +1193,6 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr, } disp->local = *localaddr; - result = isc_task_create(taskmgr, 0, &disp->task); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } /* * Append it to the dispatcher list. @@ -1399,7 +1200,6 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr, ISC_LIST_APPEND(mgr->list, disp, link); mgr_log(mgr, LVL(90), "created UDP dispatcher %p", disp); - dispatch_log(disp, LVL(90), "created task %p", disp->task); *dispp = disp; @@ -1429,8 +1229,6 @@ dns_dispatch_destroy(dns_dispatch_t *disp) { isc_nmhandle_detach(&disp->handle); } - isc_task_detach(&disp->task); - dispatch_free(&disp); /* Because dispatch uses mgr->mctx, we must detach after freeing @@ -1463,7 +1261,6 @@ dns_dispatch_detach(dns_dispatch_t **dispp) { dispatch_log(disp, LVL(90), "detach: refcount %" PRIuFAST32, ref - 1); if (ref == 1) { LOCK(&disp->lock); - REQUIRE(disp->recv_pending == 0); REQUIRE(ISC_LIST_EMPTY(disp->active)); UNLOCK(&disp->lock); @@ -1474,9 +1271,9 @@ dns_dispatch_detach(dns_dispatch_t **dispp) { isc_result_t dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, unsigned int timeout, const isc_sockaddr_t *dest, - isc_task_t *task, isc_nm_cb_t connected, - isc_nm_cb_t sent, isc_taskaction_t action, - isc_nm_cb_t timedout, void *arg, dns_messageid_t *idp, + isc_nm_cb_t connected, isc_nm_cb_t sent, + isc_nm_recv_cb_t response, isc_nm_cb_t timedout, + void *arg, dns_messageid_t *idp, dns_dispentry_t **resp) { dns_dispentry_t *res = NULL; dns_qid_t *qid = NULL; @@ -1485,12 +1282,9 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, unsigned int bucket; bool ok = false; int i = 0; - isc_taskaction_t oldest_action = NULL; - isc_task_t *oldest_task = NULL; - isc_event_t *oldest_ev = NULL; + isc_nm_recv_cb_t oldest_response = NULL; REQUIRE(VALID_DISPATCH(disp)); - REQUIRE(task != NULL); REQUIRE(dest != NULL); REQUIRE(resp != NULL && *resp == NULL); REQUIRE(idp != NULL); @@ -1510,7 +1304,6 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, disp->nsockets > DNS_DISPATCH_SOCKSQUOTA) { dns_dispentry_t *oldest = NULL; - dns_dispatchevent_t *rev = NULL; /* * Kill oldest outstanding query if the number of sockets @@ -1518,17 +1311,7 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, */ oldest = ISC_LIST_HEAD(disp->active); if (oldest != NULL) { - rev = allocate_devent(oldest->disp); - rev->buffer.base = NULL; - rev->result = ISC_R_CANCELED; - ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, - DNS_EVENT_DISPATCH, oldest->action, - oldest->arg, oldest, NULL, NULL); - - oldest_action = oldest->action; - oldest_task = oldest->task; - oldest_ev = (isc_event_t *)rev; - + oldest_response = oldest->response; inc_stats(disp->mgr, dns_resstatscounter_dispabort); } } @@ -1541,12 +1324,11 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, .connected = connected, .sent = sent, .timedout = timedout, - .action = action, + .response = response, .arg = arg }; isc_refcount_init(&res->references, 1); - ISC_LIST_INIT(res->items); ISC_LINK_INIT(res, link); ISC_LINK_INIT(res, alink); @@ -1593,8 +1375,6 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, dns_dispatch_attach(disp, &res->disp); - isc_task_attach(task, &res->task); - res->id = id; res->bucket = bucket; res->magic = RESPONSE_MAGIC; @@ -1605,8 +1385,6 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, ISC_LIST_APPEND(qid->qid_table[bucket], res, link); UNLOCK(&qid->lock); - request_log(disp, res, LVL(90), "attached to task %p", res->task); - inc_stats(disp->mgr, (disp->socktype == isc_socktype_udp) ? dns_resstatscounter_disprequdp : dns_resstatscounter_dispreqtcp); @@ -1615,8 +1393,8 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, UNLOCK(&disp->lock); - if (oldest_action != NULL) { - oldest_action(oldest_task, oldest_ev); + if (oldest_response != NULL) { + oldest_response(res->handle, ISC_R_CANCELED, NULL, res->arg); } *idp = id; @@ -1626,54 +1404,28 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, } isc_result_t -dns_dispatch_getnext(dns_dispentry_t *resp, dns_dispatchevent_t **sockevent) { +dns_dispatch_getnext(dns_dispentry_t *resp) { dns_dispatch_t *disp = NULL; - dns_dispatchevent_t *ev = NULL; - isc_taskaction_t action = NULL; REQUIRE(VALID_RESPONSE(resp)); - REQUIRE(sockevent != NULL && *sockevent != NULL); disp = resp->disp; REQUIRE(VALID_DISPATCH(disp)); - ev = *sockevent; - *sockevent = NULL; - LOCK(&disp->lock); - free_devent(disp, ev); - - ev = ISC_LIST_HEAD(resp->items); - if (ev != NULL) { - ISC_LIST_UNLINK(resp->items, ev, ev_link); - ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, DNS_EVENT_DISPATCH, - resp->action, resp->arg, resp, NULL, NULL); - request_log(disp, resp, LVL(90), - "[c] Sent event %p buffer %p len %d to task %p", ev, - ev->buffer.base, ev->buffer.length, resp->task); - - action = resp->action; - } - startrecv(disp, resp); UNLOCK(&disp->lock); - if (action != NULL) { - action(resp->task, (isc_event_t *)ev); - } - return (ISC_R_SUCCESS); } void -dns_dispatch_removeresponse(dns_dispentry_t **respp, - dns_dispatchevent_t **sockevent) { +dns_dispatch_removeresponse(dns_dispentry_t **respp) { dns_dispatchmgr_t *mgr = NULL; dns_dispatch_t *disp = NULL; dns_dispentry_t *resp = NULL; - dns_dispatchevent_t *ev = NULL; dns_qid_t *qid = NULL; REQUIRE(respp != NULL); @@ -1692,14 +1444,6 @@ dns_dispatch_removeresponse(dns_dispentry_t **respp, qid = mgr->qid; - if (sockevent != NULL) { - REQUIRE(*sockevent != NULL); - ev = *sockevent; - *sockevent = NULL; - } else { - ev = NULL; - } - LOCK(&disp->lock); INSIST(disp->requests > 0); disp->requests--; @@ -1715,20 +1459,6 @@ dns_dispatch_removeresponse(dns_dispentry_t **respp, UNLOCK(&qid->lock); UNLOCK(&disp->lock); - if (ev != NULL) { - free_devent(disp, ev); - } - - /* - * Free any buffered responses as well - */ - ev = ISC_LIST_HEAD(resp->items); - while (ev != NULL) { - ISC_LIST_UNLINK(resp->items, ev, ev_link); - free_devent(disp, ev); - ev = ISC_LIST_HEAD(resp->items); - } - dispentry_detach(respp); } @@ -1737,32 +1467,28 @@ dns_dispatch_removeresponse(dns_dispentry_t **respp, */ static void startrecv(dns_dispatch_t *disp, dns_dispentry_t *resp) { - isc_nmhandle_t *handle = NULL; - dns_dispentry_t *tmp_resp = NULL; - dns_dispatch_t *tmp_disp = NULL; - switch (disp->socktype) { case isc_socktype_udp: - REQUIRE(resp != NULL); - REQUIRE(resp->handle != NULL); + REQUIRE(resp != NULL && resp->handle != NULL); - dispentry_attach(resp, &tmp_resp); - - /* resp->handle is detached in _removeresponse() */ + dispentry_attach(resp, &(dns_dispentry_t *){ NULL }); isc_nm_read(resp->handle, udp_recv, resp); - break; + case isc_socktype_tcp: - if (resp != NULL) { - REQUIRE(resp->handle == NULL); + REQUIRE(resp != NULL && resp->handle == NULL); + REQUIRE(disp->handle != NULL); + + if (isc_nmhandle_timer_running(disp->handle)) { + isc_nmhandle_settimeout(disp->handle, resp->timeout); + break; } - isc_nmhandle_attach(disp->handle, &handle); - dns_dispatch_attach(disp, &tmp_disp); - isc_nm_read(handle, tcp_recv, disp); - INSIST(disp->recv_pending == 0); - disp->recv_pending = 1; + isc_nmhandle_attach(disp->handle, &(isc_nmhandle_t *){ NULL }); + dispentry_attach(resp, &(dns_dispentry_t *){ NULL }); + isc_nm_read(disp->handle, tcp_recv, resp); break; + default: INSIST(0); ISC_UNREACHABLE(); @@ -1779,13 +1505,6 @@ disp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { goto detach; } - if (MGR_IS_SHUTTINGDOWN(disp->mgr)) { - eresult = ISC_R_SHUTTINGDOWN; - } - - /* - * Start listening on success - */ if (eresult == ISC_R_SUCCESS) { switch (disp->socktype) { case isc_socktype_udp: @@ -1793,13 +1512,12 @@ disp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { startrecv(disp, resp); break; case isc_socktype_tcp: - if (disp->handle == NULL) { - LOCK(&disp->lock); - isc_nmhandle_attach(handle, &disp->handle); - disp->attributes |= DNS_DISPATCHATTR_CONNECTED; - UNLOCK(&disp->lock); - startrecv(disp, resp); - } + REQUIRE(disp->handle == NULL); + LOCK(&disp->lock); + isc_nmhandle_attach(handle, &disp->handle); + disp->attributes |= DNS_DISPATCHATTR_CONNECTED; + UNLOCK(&disp->lock); + startrecv(disp, resp); break; default: INSIST(0); @@ -1807,6 +1525,10 @@ disp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { } } + if (MGR_IS_SHUTTINGDOWN(disp->mgr)) { + eresult = ISC_R_SHUTTINGDOWN; + } + if (resp->connected != NULL) { resp->connected(handle, eresult, resp->arg); } @@ -1829,11 +1551,6 @@ dns_dispatch_connect(dns_dispentry_t *resp) { switch (disp->socktype) { case isc_socktype_tcp: INSIST(disp->handle == NULL); - if (disp->handle != NULL) { - /* We are already connected */ - break; - } - isc_nm_tcpdnsconnect(disp->mgr->nm, &disp->local, &disp->peer, disp_connected, resp, resp->timeout, 0); break; @@ -1866,7 +1583,6 @@ send_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { void dns_dispatch_send(dns_dispentry_t *resp, isc_region_t *r, isc_dscp_t dscp) { isc_nmhandle_t *handle = NULL; - dns_dispentry_t *tmp = NULL; REQUIRE(VALID_RESPONSE(resp)); @@ -1888,7 +1604,7 @@ dns_dispatch_send(dns_dispentry_t *resp, isc_region_t *r, isc_dscp_t dscp) { } #endif - dispentry_attach(resp, &tmp); /* detached in send_done() */ + dispentry_attach(resp, &(dns_dispentry_t *){ NULL }); isc_nm_send(handle, r, send_done, resp); } @@ -1996,9 +1712,8 @@ dns_dispatchset_get(dns_dispatchset_t *dset) { } isc_result_t -dns_dispatchset_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - dns_dispatch_t *source, dns_dispatchset_t **dsetp, - int n) { +dns_dispatchset_create(isc_mem_t *mctx, dns_dispatch_t *source, + dns_dispatchset_t **dsetp, int n) { isc_result_t result; dns_dispatchset_t *dset = NULL; dns_dispatchmgr_t *mgr = NULL; @@ -2025,7 +1740,7 @@ dns_dispatchset_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, LOCK(&mgr->lock); for (i = 1; i < n; i++) { dset->dispatches[i] = NULL; - result = dispatch_createudp(mgr, taskmgr, &source->local, + result = dispatch_createudp(mgr, &source->local, source->attributes, &dset->dispatches[i]); if (result != ISC_R_SUCCESS) { diff --git a/lib/dns/include/dns/dispatch.h b/lib/dns/include/dns/dispatch.h index 70a6f42623..e467c964e7 100644 --- a/lib/dns/include/dns/dispatch.h +++ b/lib/dns/include/dns/dispatch.h @@ -60,31 +60,6 @@ ISC_LANG_BEGINDECLS -/*% - * This event is sent to a task when a response comes in. - * No part of this structure should ever be modified by the caller, - * other than parts of the buffer. The holy parts of the buffer are - * the base and size of the buffer. All other parts of the buffer may - * be used. On event delivery the used region contains the packet. - * - * "id" is the received message id, - * - * "addr" is the host that sent it to us, - * - * "buffer" holds state on the received data. - * - * The "free" routine for this event will clean up itself as well as - * any buffer space allocated from common pools. - */ - -struct dns_dispatchevent { - ISC_EVENT_COMMON(dns_dispatchevent_t); /*%< standard event common */ - isc_result_t result; /*%< result code */ - isc_region_t region; /*%< data region */ - isc_buffer_t buffer; /*%< data buffer */ - dns_dispatch_t *dispatch; -}; - /*% * This is a set of one or more dispatches which can be retrieved * round-robin fashion. @@ -219,9 +194,8 @@ dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats); */ isc_result_t -dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr, - const isc_sockaddr_t *localaddr, unsigned int attributes, - dns_dispatch_t **dispp); +dns_dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, + unsigned int attributes, dns_dispatch_t **dispp); /*%< * Create a new UDP dispatch. * @@ -237,8 +211,7 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr, */ isc_result_t -dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr, - const isc_sockaddr_t *localaddr, +dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, const isc_sockaddr_t *destaddr, unsigned int attributes, isc_dscp_t dscp, dns_dispatch_t **dispp); /*%< @@ -250,8 +223,6 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr, * *\li sock is a valid. * - *\li task is a valid task that can be used internally to this dispatcher. - * * Returns: *\li ISC_R_SUCCESS -- success. * @@ -320,33 +291,28 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr, isc_result_t dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, unsigned int timeout, const isc_sockaddr_t *dest, - isc_task_t *task, isc_nm_cb_t connected, - isc_nm_cb_t sent, isc_taskaction_t action, - isc_nm_cb_t timedout, void *arg, dns_messageid_t *idp, + isc_nm_cb_t connected, isc_nm_cb_t sent, + isc_nm_recv_cb_t response, isc_nm_cb_t timedout, + void *arg, dns_messageid_t *idp, dns_dispentry_t **resp); /*%< * Add a response entry for this dispatch. * * "*idp" is filled in with the assigned message ID, and *resp is filled in - * to contain the magic token used to request event flow stop. + * with the dispatch entry object. * * The 'connected' and 'sent' callbacks are run to inform the caller when * the connect and send functions are complete. The 'timedout' callback * is run to inform the caller that a read has timed out; it may optionally - * reset the read timer. + * reset the read timer. The 'response' callback is run for recv results + * (response packets, timeouts, or cancellations). * - * The specified 'task' is sent the 'action' callback for response packets. - * (Later, this should be updated to a network manager callback function, - * but for now we still use isc_task for this.) When the event is delivered, - * it must be returned using dns_dispatch_freeevent() or through - * dns_dispatch_removeresponse() for another to be delivered. - * - * All three callback functions are sent 'arg' as a parameter. + * All the callback functions are sent 'arg' as a parameter. * * Requires: *\li "idp" be non-NULL. * - *\li "task" "action" and "arg" be set as appropriate. + *\li "response" and "arg" be set as appropriate. * *\li "dest" be non-NULL and valid. * @@ -366,19 +332,13 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, */ void -dns_dispatch_removeresponse(dns_dispentry_t ** resp, - dns_dispatchevent_t **sockevent); +dns_dispatch_removeresponse(dns_dispentry_t **resp); /*%< * Stops the flow of responses for the provided id and destination. - * If "sockevent" is non-NULL, the dispatch event and associated buffer is - * also returned to the system. * * Requires: *\li "resp" != NULL and "*resp" contain a value previously allocated * by dns_dispatch_addresponse(); - * - *\li May only be called from within the task given as the 'task' - * argument to dns_dispatch_addresponse() when allocating '*resp'. */ isc_result_t @@ -456,9 +416,8 @@ dns_dispatchset_get(dns_dispatchset_t *dset); */ isc_result_t -dns_dispatchset_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - dns_dispatch_t *source, dns_dispatchset_t **dsetp, - int n); +dns_dispatchset_create(isc_mem_t *mctx, dns_dispatch_t *source, + dns_dispatchset_t **dsetp, int n); /*%< * Given a valid dispatch 'source', create a dispatch set containing * 'n' UDP dispatches, with the remainder filled out by clones of the @@ -480,14 +439,12 @@ dns_dispatchset_destroy(dns_dispatchset_t **dsetp); */ isc_result_t -dns_dispatch_getnext(dns_dispentry_t *resp, dns_dispatchevent_t **sockevent); +dns_dispatch_getnext(dns_dispentry_t *resp); /*%< - * Free the sockevent and trigger the sending of the next item off the - * dispatch queue if present. + * Trigger the sending of the next item off the dispatch queue if present. * * Requires: *\li resp is valid - *\li *sockevent to be valid */ ISC_LANG_ENDDECLS diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h index 6192731846..59d2fb28bd 100644 --- a/lib/dns/include/dns/types.h +++ b/lib/dns/include/dns/types.h @@ -65,7 +65,6 @@ typedef struct dns_dyndbctx dns_dyndbctx_t; typedef struct dns_sdlzimplementation dns_sdlzimplementation_t; typedef struct dns_decompress dns_decompress_t; typedef struct dns_dispatch dns_dispatch_t; -typedef struct dns_dispatchevent dns_dispatchevent_t; typedef struct dns_dispatchlist dns_dispatchlist_t; typedef struct dns_dispatchset dns_dispatchset_t; typedef struct dns_dispatchmgr dns_dispatchmgr_t; diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 354ee64659..10f977cc5a 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -1780,8 +1780,8 @@ dns_zone_getdnsseckeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, isc_result_t dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, - isc_nm_t *netmgr, dns_zonemgr_t **zmgrp); + isc_timermgr_t *timermgr, isc_nm_t *netmgr, + dns_zonemgr_t **zmgrp); /*%< * Create a zone manager. Note: the zone manager will not be able to * manage any zones until dns_zonemgr_setsize() has been run. diff --git a/lib/dns/request.c b/lib/dns/request.c index 9d4bb57f3d..9e00932f79 100644 --- a/lib/dns/request.c +++ b/lib/dns/request.c @@ -108,7 +108,8 @@ static isc_result_t req_render(dns_message_t *message, isc_buffer_t **buffer, unsigned int options, isc_mem_t *mctx); static void -req_response(isc_task_t *task, isc_event_t *event); +req_response(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region, + void *arg); static void req_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *arg); static void @@ -418,9 +419,8 @@ tcp_dispatch(bool newtcp, dns_requestmgr_t *requestmgr, } } - result = dns_dispatch_createtcp(requestmgr->dispatchmgr, - requestmgr->taskmgr, srcaddr, destaddr, - 0, dscp, dispatchp); + result = dns_dispatch_createtcp(requestmgr->dispatchmgr, srcaddr, + destaddr, 0, dscp, dispatchp); return (result); } @@ -449,8 +449,7 @@ udp_dispatch(dns_requestmgr_t *requestmgr, const isc_sockaddr_t *srcaddr, return (ISC_R_SUCCESS); } - return (dns_dispatch_createudp(requestmgr->dispatchmgr, - requestmgr->taskmgr, srcaddr, 0, + return (dns_dispatch_createudp(requestmgr->dispatchmgr, srcaddr, 0, dispatchp)); } @@ -479,8 +478,9 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, dns_request_t **requestp) { dns_request_t *request = NULL; isc_task_t *tclone = NULL; + dns_request_t *rclone = NULL; isc_result_t result; - isc_mem_t *mctx; + isc_mem_t *mctx = NULL; dns_messageid_t id; bool tcp = false; bool newtcp = false; @@ -511,7 +511,6 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, return (DNS_R_BLACKHOLED); } - request = NULL; result = new_request(mctx, &request); if (result != ISC_R_SUCCESS) { return (result); @@ -565,17 +564,16 @@ again: dispopt |= DNS_DISPATCHOPT_FIXEDID; } - dns_request_t *tmp = NULL; - req_attach(request, &tmp); - + req_attach(request, &rclone); result = dns_dispatch_addresponse( - request->dispatch, dispopt, request->timeout, destaddr, task, + request->dispatch, dispopt, request->timeout, destaddr, req_connected, req_senddone, req_response, req_timeout, request, &id, &request->dispentry); if (result != ISC_R_SUCCESS) { if ((options & DNS_REQUESTOPT_FIXEDID) != 0 && !newtcp) { newtcp = true; connected = false; + req_detach(&rclone); dns_dispatch_detach(&request->dispatch); goto again; } @@ -602,6 +600,7 @@ again: request->flags |= DNS_REQUEST_F_CONNECTING | DNS_REQUEST_F_TCP; } else { req_send(request); + req_detach(&rclone); } req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: request %p", request); @@ -645,8 +644,9 @@ dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message, dns_request_t **requestp) { dns_request_t *request = NULL; isc_task_t *tclone = NULL; + dns_request_t *rclone = NULL; isc_result_t result; - isc_mem_t *mctx; + isc_mem_t *mctx = NULL; dns_messageid_t id; bool tcp = false; bool connected = false; @@ -720,13 +720,11 @@ use_tcp: goto cleanup; } - dns_request_t *tmp = NULL; - req_attach(request, &tmp); - + req_attach(request, &rclone); result = dns_dispatch_addresponse( - request->dispatch, 0, request->timeout, destaddr, task, - req_connected, req_senddone, req_response, req_timeout, request, - &id, &request->dispentry); + request->dispatch, 0, request->timeout, destaddr, req_connected, + req_senddone, req_response, req_timeout, request, &id, + &request->dispentry); if (result != ISC_R_SUCCESS) { goto cleanup; } @@ -737,8 +735,9 @@ use_tcp: /* * Try again using TCP. */ + req_detach(&rclone); dns_message_renderreset(message); - dns_dispatch_removeresponse(&request->dispentry, NULL); + dns_dispatch_removeresponse(&request->dispentry); dns_dispatch_detach(&request->dispatch); options |= DNS_REQUESTOPT_TCP; tcp = true; @@ -768,6 +767,7 @@ use_tcp: request->flags |= DNS_REQUEST_F_CONNECTING | DNS_REQUEST_F_TCP; } else { req_send(request); + req_detach(&rclone); } req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: request %p", request); @@ -783,6 +783,9 @@ cleanup: if (tclone != NULL) { isc_task_detach(&tclone); } + if (rclone != NULL) { + req_detach(&rclone); + } req_detach(&request); req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: failed %s", dns_result_totext(result)); @@ -909,7 +912,7 @@ request_cancel(dns_request_t *request) { if (request->dispentry != NULL) { dns_dispatch_cancel(request->dispentry); - dns_dispatch_removeresponse(&request->dispentry, NULL); + dns_dispatch_removeresponse(&request->dispentry); } dns_dispatch_detach(&request->dispatch); @@ -1024,7 +1027,7 @@ req_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { request->flags &= ~DNS_REQUEST_F_CONNECTING; if (eresult == ISC_R_TIMEDOUT) { - dns_dispatch_removeresponse(&request->dispentry, NULL); + dns_dispatch_removeresponse(&request->dispentry); dns_dispatch_detach(&request->dispatch); send_if_done(request, eresult); } else if (DNS_REQUEST_CANCELED(request)) { @@ -1089,32 +1092,31 @@ req_timeout(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { } static void -req_response(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - dns_request_t *request = event->ev_arg; - dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event; - isc_region_t r; +req_response(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region, + void *arg) { + dns_request_t *request = (dns_request_t *)arg; + + UNUSED(handle); + + if (result == ISC_R_CANCELED) { + return; + } REQUIRE(VALID_REQUEST(request)); - REQUIRE(event->ev_type == DNS_EVENT_DISPATCH); - - UNUSED(task); req_log(ISC_LOG_DEBUG(3), "req_response: request %p: %s", request, - dns_result_totext(devent->result)); + dns_result_totext(result)); LOCK(&request->requestmgr->locks[request->hash]); - result = devent->result; if (result != ISC_R_SUCCESS) { goto done; } /* - * Copy buffer to request. + * Copy region to request. */ - isc_buffer_usedregion(&devent->buffer, &r); - isc_buffer_allocate(request->mctx, &request->answer, r.length); - result = isc_buffer_copyregion(request->answer, &r); + isc_buffer_allocate(request->mctx, &request->answer, region->length); + result = isc_buffer_copyregion(request->answer, region); if (result != ISC_R_SUCCESS) { isc_buffer_free(&request->answer); } @@ -1122,7 +1124,7 @@ done: /* * Cleanup. */ - dns_dispatch_removeresponse(&request->dispentry, &devent); + dns_dispatch_removeresponse(&request->dispentry); request_cancel(request); /* @@ -1206,7 +1208,7 @@ req_destroy(dns_request_t *request) { isc_event_free((isc_event_t **)&request->event); } if (request->dispentry != NULL) { - dns_dispatch_removeresponse(&request->dispentry, NULL); + dns_dispatch_removeresponse(&request->dispentry); } if (request->dispatch != NULL) { dns_dispatch_detach(&request->dispatch); diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index ff24608062..406d91118d 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -287,6 +287,7 @@ struct fetchctx { char *info; isc_mem_t *mctx; isc_stdtime_t now; + isc_task_t *task; /* Atomic */ isc_refcount_t references; @@ -608,7 +609,8 @@ empty_bucket(dns_resolver_t *res); static isc_result_t resquery_send(resquery_t *query); static void -resquery_response(isc_task_t *task, isc_event_t *event); +resquery_response(isc_nmhandle_t *handle, isc_result_t eresult, + isc_region_t *region, void *arg); static void resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg); static void @@ -709,11 +711,10 @@ resume_qmin(isc_task_t *task, isc_event_t *event); */ typedef struct respctx { - isc_task_t *task; - dns_dispatchevent_t *devent; resquery_t *query; fetchctx_t *fctx; isc_result_t result; + isc_buffer_t buffer; unsigned int retryopts; /* updated options to pass to * fctx_query() when resending */ @@ -775,8 +776,8 @@ typedef struct respctx { } respctx_t; static void -rctx_respinit(isc_task_t *task, dns_dispatchevent_t *devent, resquery_t *query, - fetchctx_t *fctx, respctx_t *rctx); +rctx_respinit(resquery_t *query, fetchctx_t *fctx, isc_result_t result, + isc_region_t *region, respctx_t *rctx); static void rctx_answer_init(respctx_t *rctx); @@ -1138,6 +1139,10 @@ resquery_destroy(resquery_t *query) { dns_tsigkey_detach(&query->tsigkey); } + if (query->dispentry != NULL) { + dns_dispatch_removeresponse(&query->dispentry); + } + if (query->dispatch != NULL) { dns_dispatch_detach(&query->dispatch); } @@ -1211,8 +1216,8 @@ update_edns_stats(resquery_t *query) { } static void -fctx_cancelquery(resquery_t *query, dns_dispatchevent_t **deventp, - isc_time_t *finish, bool no_response, bool age_untried) { +fctx_cancelquery(resquery_t *query, isc_time_t *finish, bool no_response, + bool age_untried) { fetchctx_t *fctx = NULL; unsigned int rtt, rttms; unsigned int factor; @@ -1394,7 +1399,7 @@ fctx_cancelquery(resquery_t *query, dns_dispatchevent_t **deventp, */ if (query->dispentry != NULL) { dns_dispatch_cancel(query->dispentry); - dns_dispatch_removeresponse(&query->dispentry, deventp); + dns_dispatch_removeresponse(&query->dispentry); } if (ISC_LINK_LINKED(query, link)) { @@ -1407,14 +1412,14 @@ fctx_cancelquery(resquery_t *query, dns_dispatchevent_t **deventp, static void fctx_cancelqueries(fetchctx_t *fctx, bool no_response, bool age_untried) { - resquery_t *query, *next_query; + resquery_t *query = NULL, *next_query = NULL; FCTXTRACE("cancelqueries"); for (query = ISC_LIST_HEAD(fctx->queries); query != NULL; query = next_query) { next_query = ISC_LIST_NEXT(query, link); - fctx_cancelquery(query, NULL, NULL, no_response, age_untried); + fctx_cancelquery(query, NULL, no_response, age_untried); } } @@ -1764,8 +1769,7 @@ resquery_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { switch (eresult) { case ISC_R_SUCCESS: - /* Don't detach from resquery */ - return; + goto detach; case ISC_R_HOSTUNREACH: case ISC_R_NETUNREACH: @@ -1781,22 +1785,24 @@ resquery_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { */ add_bad(fctx, query->rmessage, query->addrinfo, eresult, badns_unreachable); - fctx_cancelquery(query, NULL, NULL, true, false); + fctx_cancelquery(query, NULL, true, false); FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT); fctx_try(fctx, true, false); break; + case ISC_R_CANCELED: + break; default: FCTXTRACE3("query canceled in resquery_senddone() " "due to unexpected result; responding", eresult); - fctx_cancelquery(query, NULL, NULL, false, false); + fctx_cancelquery(query, NULL, false, false); fctx_done(fctx, eresult, __LINE__); break; } detach: - resquery_detach(&query); + resquery_detach(&query); /* Detach dispatch query */ } static inline isc_result_t @@ -1954,7 +1960,6 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, unsigned int options) { isc_result_t result; dns_resolver_t *res = NULL; - isc_task_t *task = NULL; resquery_t *query = NULL; isc_sockaddr_t addr; bool have_addr = false; @@ -1964,7 +1969,6 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, FCTXTRACE("query"); res = fctx->res; - task = res->buckets[fctx->bucketnum].task; srtt = addrinfo->srtt; @@ -2069,8 +2073,8 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, query->dscp = dscp; } - result = dns_dispatch_createtcp(res->dispatchmgr, res->taskmgr, - &addr, &addrinfo->sockaddr, 0, + result = dns_dispatch_createtcp(res->dispatchmgr, &addr, + &addrinfo->sockaddr, 0, query->dscp, &query->dispatch); if (result != ISC_R_SUCCESS) { goto cleanup_query; @@ -2090,9 +2094,8 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, result = ISC_R_NOTIMPLEMENTED; goto cleanup_query; } - result = dns_dispatch_createudp(res->dispatchmgr, - res->taskmgr, &addr, 0, - &query->dispatch); + result = dns_dispatch_createudp(res->dispatchmgr, &addr, + 0, &query->dispatch); if (result != ISC_R_SUCCESS) { goto cleanup_query; } @@ -2147,13 +2150,10 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, fctx->nqueries++; UNLOCK(&res->buckets[fctx->bucketnum].lock); - resquery_t *tmp = NULL; - resquery_attach(query, &tmp); - /* Set up the dispatch and set the query ID */ result = dns_dispatch_addresponse( query->dispatch, 0, isc_interval_ms(&fctx->interval), - &query->addrinfo->sockaddr, task, resquery_connected, + &query->addrinfo->sockaddr, resquery_connected, resquery_senddone, resquery_response, resquery_timeout, query, &query->id, &query->dispentry); if (result != ISC_R_SUCCESS) { @@ -2161,9 +2161,11 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, } /* Connect the socket */ - fctx_increference(fctx); - + resquery_attach(query, &(resquery_t *){ NULL }); /* dispatch query */ result = dns_dispatch_connect(query->dispentry); + + RUNTIME_CHECK(result == ISC_R_SUCCESS); + return (result); cleanup_dispatch: @@ -2720,6 +2722,7 @@ resquery_send(resquery_t *query) { isc_buffer_usedregion(&buffer, &r); + resquery_attach(query, &(resquery_t *){ NULL }); dns_dispatch_send(query->dispentry, &r, query->dscp); QTRACE("sent"); @@ -2755,7 +2758,7 @@ cleanup_message: /* * Stop the dispatcher from listening. */ - dns_dispatch_removeresponse(&query->dispentry, NULL); + dns_dispatch_removeresponse(&query->dispentry); cleanup_temps: if (qname != NULL) { @@ -2771,12 +2774,9 @@ cleanup_temps: static void resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { resquery_t *query = (resquery_t *)arg; - resquery_t *connquery = query; isc_result_t result; fetchctx_t *fctx = NULL; dns_resolver_t *res = NULL; - unsigned int bucketnum; - bool bucket_empty; int pf; REQUIRE(VALID_QUERY(query)); @@ -2788,16 +2788,23 @@ resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { fctx = query->fctx; res = fctx->res; - bucketnum = fctx->bucketnum; - - if (atomic_load_acquire(&res->exiting)) { - eresult = ISC_R_SHUTTINGDOWN; - } - if (RESQUERY_CANCELED(query)) { goto detach; } + if (atomic_load_acquire(&fctx->res->exiting)) { + if (eresult == ISC_R_SUCCESS) { + /* + * The reading from the socket has already started at + * this point, so we need to properly cancel the reading + * and then detach the final resquery_t + */ + resquery_attach(query, &(resquery_t *){ NULL }); + dns_dispatch_cancel(query->dispentry); + } + eresult = ISC_R_SHUTTINGDOWN; + } + switch (eresult) { case ISC_R_SUCCESS: /* @@ -2814,8 +2821,9 @@ resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { "resquery_send() failed; " "responding"); - fctx_cancelquery(query, NULL, NULL, false, false); + fctx_cancelquery(query, NULL, false, false); fctx_done(fctx, result, __LINE__); + break; } fctx->querysent++; @@ -2831,7 +2839,7 @@ resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { dns_rdatatypestats_increment(res->view->resquerystats, fctx->type); } - break; + goto detach; case ISC_R_NETUNREACH: case ISC_R_HOSTUNREACH: @@ -2852,31 +2860,28 @@ resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { */ add_bad(fctx, query->rmessage, query->addrinfo, eresult, badns_unreachable); - fctx_cancelquery(query, NULL, NULL, true, false); + fctx_cancelquery(query, NULL, true, false); FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT); fctx_try(fctx, true, false); break; + case ISC_R_CANCELED: + break; + default: FCTXTRACE3("query canceled in " "resquery_connected() " "due to unexpected result; responding", eresult); - fctx_cancelquery(query, NULL, NULL, false, false); + fctx_cancelquery(query, NULL, false, false); fctx_done(fctx, eresult, __LINE__); - } - - LOCK(&res->buckets[bucketnum].lock); - bucket_empty = fctx_decreference(fctx); - UNLOCK(&res->buckets[bucketnum].lock); - if (bucket_empty) { - empty_bucket(res); + break; } detach: - resquery_detach(&connquery); + resquery_detach(&query); /* Detach dispatch query */ } static void @@ -4513,7 +4518,6 @@ fctx_add_event(fetchctx_t *fctx, isc_task_t *task, const isc_sockaddr_t *client, dns_messageid_t id, isc_taskaction_t action, void *arg, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_fetch_t *fetch, isc_eventtype_t event_type) { - isc_task_t *tclone = NULL; dns_fetchevent_t *event = NULL; /* @@ -4521,10 +4525,9 @@ fctx_add_event(fetchctx_t *fctx, isc_task_t *task, const isc_sockaddr_t *client, * sender field. We'll make the fetch the sender when we * actually send the event. */ - isc_task_attach(task, &tclone); - event = (dns_fetchevent_t *)isc_event_allocate(fctx->res->mctx, tclone, - event_type, action, arg, - sizeof(*event)); + isc_task_attach(task, &(isc_task_t *){ NULL }); + event = (dns_fetchevent_t *)isc_event_allocate( + fctx->res->mctx, task, event_type, action, arg, sizeof(*event)); event->result = DNS_R_SERVFAIL; event->qtype = fctx->type; event->db = NULL; @@ -4579,11 +4582,11 @@ log_ns_ttl(fetchctx_t *fctx, const char *where) { } static isc_result_t -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, - unsigned int bucketnum, unsigned int depth, isc_counter_t *qc, - fetchctx_t **fctxp) { +fctx_create(dns_resolver_t *res, isc_task_t *task, 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, unsigned int bucketnum, unsigned int depth, + isc_counter_t *qc, fetchctx_t **fctxp) { fetchctx_t *fctx = NULL; isc_result_t result; isc_result_t iresult; @@ -4606,6 +4609,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type, .qmintype = type, .options = options, .res = res, + .task = task, .bucketnum = bucketnum, .dbucketnum = RES_NOBUCKET, .state = fetchstate_init, @@ -7202,17 +7206,22 @@ betterreferral(respctx_t *rctx) { * resquery_send(). Sets up a response context (respctx_t). */ static void -resquery_response(isc_task_t *task, isc_event_t *event) { - isc_result_t result = ISC_R_SUCCESS; - resquery_t *query = event->ev_arg; - dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event; - fetchctx_t *fctx; +resquery_response(isc_nmhandle_t *handle, isc_result_t eresult, + isc_region_t *region, void *arg) { + isc_result_t result; + resquery_t *query = (resquery_t *)arg; + fetchctx_t *fctx = NULL; respctx_t rctx; + UNUSED(handle); + + if (eresult == ISC_R_CANCELED) { + return; + } + REQUIRE(VALID_QUERY(query)); fctx = query->fctx; REQUIRE(VALID_FCTX(fctx)); - REQUIRE(event->ev_type == DNS_EVENT_DISPATCH); QTRACE("response"); @@ -7222,7 +7231,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) { inc_stats(fctx->res, dns_resstatscounter_responsev6); } - rctx_respinit(task, devent, query, fctx, &rctx); + rctx_respinit(query, fctx, eresult, region, &rctx); if (atomic_load_acquire(&fctx->res->exiting)) { result = ISC_R_SHUTTINGDOWN; @@ -7273,9 +7282,8 @@ resquery_response(isc_task_t *task, isc_event_t *event) { if ((rctx.retryopts & DNS_FETCHOPT_TCP) == 0) { if ((rctx.retryopts & DNS_FETCHOPT_NOEDNS0) == 0) { - dns_adb_setudpsize( - fctx->adb, query->addrinfo, - isc_buffer_usedlength(&devent->buffer)); + dns_adb_setudpsize(fctx->adb, query->addrinfo, + isc_buffer_usedlength(&rctx.buffer)); } else { dns_adb_plainresponse(fctx->adb, query->addrinfo); } @@ -7601,16 +7609,15 @@ resquery_response(isc_task_t *task, isc_event_t *event) { * resquery_response(). */ static void -rctx_respinit(isc_task_t *task, dns_dispatchevent_t *devent, resquery_t *query, - fetchctx_t *fctx, respctx_t *rctx) { - *rctx = (respctx_t){ .task = task, - .devent = devent, - .result = devent->result, +rctx_respinit(resquery_t *query, fetchctx_t *fctx, isc_result_t result, + isc_region_t *region, respctx_t *rctx) { + *rctx = (respctx_t){ .result = result, .query = query, .fctx = fctx, .broken_type = badns_response, .retryopts = query->options }; - + isc_buffer_init(&rctx->buffer, region->base, region->length); + isc_buffer_add(&rctx->buffer, region->length); TIME_NOW(&rctx->tnow); rctx->finish = &rctx->tnow; rctx->now = (isc_stdtime_t)isc_time_seconds(&rctx->tnow); @@ -7675,17 +7682,15 @@ rctx_answer_init(respctx_t *rctx) { */ static isc_result_t rctx_dispfail(respctx_t *rctx) { - dns_dispatchevent_t *devent = rctx->devent; fetchctx_t *fctx = rctx->fctx; resquery_t *query = rctx->query; - if (devent->result == ISC_R_SUCCESS) { + if (rctx->result == ISC_R_SUCCESS) { return (ISC_R_SUCCESS); } - if (devent->result == ISC_R_EOF && - (rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0) - { + if (rctx->result == ISC_R_EOF && + (rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0) { /* * The problem might be that they don't understand * EDNS0. Turn it off and try again. @@ -7704,18 +7709,18 @@ rctx_dispfail(respctx_t *rctx) { * adjust finish and no_response so that we penalize * this address in SRTT adjustment later. */ - if (devent->result == ISC_R_HOSTUNREACH || - devent->result == ISC_R_NETUNREACH || - devent->result == ISC_R_CONNREFUSED || - devent->result == ISC_R_CANCELED) + if (rctx->result == ISC_R_HOSTUNREACH || + rctx->result == ISC_R_NETUNREACH || + rctx->result == ISC_R_CONNREFUSED || + rctx->result == ISC_R_CANCELED) { - rctx->broken_server = devent->result; + rctx->broken_server = rctx->result; rctx->broken_type = badns_unreachable; rctx->finish = NULL; rctx->no_response = true; } } - FCTXTRACE3("dispatcher failure", devent->result); + FCTXTRACE3("dispatcher failure", rctx->result); rctx_done(rctx, ISC_R_SUCCESS); return (ISC_R_COMPLETE); } @@ -7768,7 +7773,7 @@ rctx_parse(respctx_t *rctx) { fetchctx_t *fctx = rctx->fctx; resquery_t *query = rctx->query; - result = dns_message_parse(query->rmessage, &rctx->devent->buffer, 0); + result = dns_message_parse(query->rmessage, &rctx->buffer, 0); if (result == ISC_R_SUCCESS) { return (ISC_R_SUCCESS); } @@ -9336,17 +9341,15 @@ rctx_resend(respctx_t *rctx, dns_adbaddrinfo_t *addrinfo) { inc_stats(fctx->res, dns_resstatscounter_retry); fctx_increference(fctx); result = fctx_query(fctx, addrinfo, rctx->retryopts); - if (result == ISC_R_SUCCESS) { - return; - } - - bucketnum = fctx->bucketnum; - fctx_done(fctx, result, __LINE__); - LOCK(&res->buckets[bucketnum].lock); - bucket_empty = fctx_decreference(fctx); - UNLOCK(&res->buckets[bucketnum].lock); - if (bucket_empty) { - empty_bucket(res); + if (result != ISC_R_SUCCESS) { + bucketnum = fctx->bucketnum; + fctx_done(fctx, result, __LINE__); + LOCK(&res->buckets[bucketnum].lock); + bucket_empty = fctx_decreference(fctx); + UNLOCK(&res->buckets[bucketnum].lock); + if (bucket_empty) { + empty_bucket(res); + } } } @@ -9368,7 +9371,7 @@ rctx_next(respctx_t *rctx) { inc_stats(rctx->fctx->res, dns_resstatscounter_nextitem); INSIST(rctx->query->dispentry != NULL); dns_message_reset(rctx->query->rmessage, DNS_MESSAGE_INTENTPARSE); - result = dns_dispatch_getnext(rctx->query->dispentry, &rctx->devent); + result = dns_dispatch_getnext(rctx->query->dispentry); if (result != ISC_R_SUCCESS) { fctx_done(rctx->fctx, result, __LINE__); } @@ -9399,7 +9402,7 @@ rctx_chaseds(respctx_t *rctx, dns_message_t *message, result = dns_resolver_createfetch( fctx->res, fctx->nsname, dns_rdatatype_ns, NULL, NULL, NULL, - NULL, 0, fctx->options, 0, NULL, rctx->task, 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) { @@ -9437,41 +9440,39 @@ rctx_done(respctx_t *rctx, isc_result_t result) { FCTXTRACE4("query canceled in rctx_done();", rctx->no_response ? "no response" : "responding", result); - /* - * Cancel the query. - */ - if (!rctx->nextitem) { - fctx_cancelquery(query, &rctx->devent, rctx->finish, - rctx->no_response, false); - } - #ifdef ENABLE_AFL if (dns_fuzzing_resolver && (rctx->next_server || rctx->resend || rctx->nextitem)) { - if (rctx->nextitem) { - fctx_cancelquery(query, &rctx->devent, rctx->finish, - rctx->no_response, false); - } + fctx_cancelquery(query, rctx->finish, rctx->no_response, false); fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); - return; - } else + goto detach; + } #endif /* ifdef ENABLE_AFL */ - if (rctx->next_server) - { + + if (rctx->nextitem) { + REQUIRE(!rctx->next_server); + REQUIRE(!rctx->resend); + + result = rctx_next(rctx); + if (result == ISC_R_SUCCESS) { + goto detach; + } + } + + /* Cancel the query */ + fctx_cancelquery(query, rctx->finish, rctx->no_response, false); + + if (rctx->next_server) { rctx_nextserver(rctx, message, addrinfo, result); } else if (rctx->resend) { rctx_resend(rctx, addrinfo); - } else if (rctx->nextitem) { - if (rctx_next(rctx) != ISC_R_SUCCESS) { - resquery_detach(&query); - } } else if (result == DNS_R_CHASEDSSERVERS) { rctx_chaseds(rctx, message, addrinfo, result); } else if (result == ISC_R_SUCCESS && !HAVE_ANSWER(fctx)) { /* - * All has gone well so far, but we are waiting for the - * DNSSEC validator to validate the answer. + * All has gone well so far, but we are waiting for the DNSSEC + * validator to validate the answer. */ FCTXTRACE("wait for validator"); fctx_cancelqueries(fctx, true, false); @@ -9482,6 +9483,7 @@ rctx_done(respctx_t *rctx, isc_result_t result) { fctx_done(fctx, result, __LINE__); } +detach: dns_message_detach(&message); } @@ -9539,7 +9541,7 @@ rctx_logpacket(respctx_t *rctx) { dns_dt_send(fctx->res->view, dtmsgtype, la, &rctx->query->addrinfo->sockaddr, ((rctx->query->options & DNS_FETCHOPT_TCP) != 0), &zr, - &rctx->query->start, NULL, &rctx->devent->buffer); + &rctx->query->start, NULL, &rctx->buffer); #endif /* HAVE_DNSTAP */ } @@ -9960,12 +9962,12 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr, } if (dispatchv4 != NULL) { - dns_dispatchset_create(view->mctx, taskmgr, dispatchv4, + dns_dispatchset_create(view->mctx, dispatchv4, &res->dispatches4, ndisp); } if (dispatchv6 != NULL) { - dns_dispatchset_create(view->mctx, taskmgr, dispatchv6, + dns_dispatchset_create(view->mctx, dispatchv6, &res->dispatches6, ndisp); } @@ -10156,8 +10158,7 @@ dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp) { void dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task, isc_event_t **eventp) { - isc_task_t *tclone; - isc_event_t *event; + isc_event_t *event = NULL; REQUIRE(VALID_RESOLVER(res)); REQUIRE(eventp != NULL); @@ -10176,9 +10177,8 @@ dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task, event->ev_sender = res; isc_task_send(task, &event); } else { - tclone = NULL; - isc_task_attach(task, &tclone); - event->ev_sender = tclone; + isc_task_attach(task, &(isc_task_t *){ NULL }); + event->ev_sender = task; ISC_LIST_APPEND(res->whenshutdown, event, ev_link); } @@ -10473,7 +10473,7 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name, } if (fctx == NULL) { - result = fctx_create(res, name, type, domain, nameservers, + result = fctx_create(res, task, name, type, domain, nameservers, client, options, bucketnum, depth, qc, &fctx); if (result != ISC_R_SUCCESS) { diff --git a/lib/dns/zone.c b/lib/dns/zone.c index d2e1b75bbf..5fbe523b22 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -590,7 +590,6 @@ struct dns_zonemgr { isc_refcount_t refs; isc_taskmgr_t *taskmgr; isc_timermgr_t *timermgr; - isc_socketmgr_t *socketmgr; isc_nm_t *netmgr; isc_taskpool_t *zonetasks; isc_taskpool_t *loadtasks; @@ -18735,8 +18734,8 @@ zonemgr_keymgmt_find(dns_zonemgr_t *zmgr, dns_zone_t *zone, isc_result_t dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, - isc_nm_t *netmgr, dns_zonemgr_t **zmgrp) { + isc_timermgr_t *timermgr, isc_nm_t *netmgr, + dns_zonemgr_t **zmgrp) { dns_zonemgr_t *zmgr; isc_result_t result; @@ -18746,7 +18745,6 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_mem_attach(mctx, &zmgr->mctx); zmgr->taskmgr = taskmgr; zmgr->timermgr = timermgr; - zmgr->socketmgr = socketmgr; zmgr->netmgr = netmgr; zmgr->zonetasks = NULL; zmgr->loadtasks = NULL; diff --git a/lib/isc/include/isc/types.h b/lib/isc/include/isc/types.h index 84f3be07e1..2890b56a3f 100644 --- a/lib/isc/include/isc/types.h +++ b/lib/isc/include/isc/types.h @@ -98,7 +98,6 @@ typedef struct isc_nm_http_endpoints isc_nm_http_endpoints_t; #endif /* HAVE_LIBNGHTTP2 */ typedef void (*isc_taskaction_t)(isc_task_t *, isc_event_t *); -typedef int (*isc_sockfdwatch_t)(isc_task_t *, isc_socket_t *, void *, int); /* The following cannot be listed alphabetically due to forward reference */ typedef isc_result_t(isc_httpdaction_t)( diff --git a/lib/ns/client.c b/lib/ns/client.c index 34d94d15e7..f06f9bda79 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -2413,6 +2413,7 @@ ns_clientmgr_create(ns_server_t *sctx, isc_taskmgr_t *taskmgr, result = isc_task_create_bound(manager->taskmgr, 20, &manager->task, manager->tid); RUNTIME_CHECK(result == ISC_R_SUCCESS); + isc_task_setname(manager->task, "clientmgr", NULL); isc_refcount_init(&manager->references, 1); manager->sctx = NULL; diff --git a/lib/ns/include/ns/interfacemgr.h b/lib/ns/include/ns/interfacemgr.h index 9dbde5f76c..ae552a9656 100644 --- a/lib/ns/include/ns/interfacemgr.h +++ b/lib/ns/include/ns/interfacemgr.h @@ -45,7 +45,6 @@ #include #include #include -#include #include #include @@ -74,7 +73,6 @@ struct ns_interface { isc_sockaddr_t addr; /*%< Address and port. */ unsigned int flags; /*%< Interface flags */ char name[32]; /*%< Null terminated. */ - isc_socket_t * tcpsocket; /*%< TCP socket. */ isc_nmsocket_t * udplistensocket; isc_nmsocket_t * tcplistensocket; isc_nmsocket_t * http_listensocket; diff --git a/lib/ns/interfacemgr.c b/lib/ns/interfacemgr.c index 2590794285..72b86dc0c9 100644 --- a/lib/ns/interfacemgr.c +++ b/lib/ns/interfacemgr.c @@ -698,10 +698,6 @@ ns_interface_destroy(ns_interface_t *ifp) { ns_interface_shutdown(ifp); - if (ifp->tcpsocket != NULL) { - isc_socket_detach(&ifp->tcpsocket); - } - isc_mutex_destroy(&ifp->lock); ns_interfacemgr_detach(&ifp->mgr);