diff --git a/bin/named/server.c b/bin/named/server.c index 857609dd5a..57930b5040 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -161,11 +161,9 @@ #ifdef TUNE_LARGE #define RESOLVER_NTASKS_PERCPU 32 #define UDPBUFFERS 32768 -#define EXCLBUFFERS 32768 #else #define RESOLVER_NTASKS_PERCPU 8 -#define UDPBUFFERS 1000 -#define EXCLBUFFERS 4096 +#define UDPBUFFERS 4096 #endif /* TUNE_LARGE */ /* RFC7828 defines timeout as 16-bit value specified in units of 100 @@ -1260,7 +1258,7 @@ get_view_querysource_dispatch(const cfg_obj_t **maps, int af, dns_dispatch_t **dispatchp, isc_dscp_t *dscpp, bool is_firstview) { isc_result_t result = ISC_R_FAILURE; - dns_dispatch_t *disp; + dns_dispatch_t *disp = NULL; isc_sockaddr_t sa; unsigned int attrs; const cfg_obj_t *obj = NULL; @@ -1310,8 +1308,7 @@ get_view_querysource_dispatch(const cfg_obj_t **maps, int af, /* * Try to find a dispatcher that we can share. */ - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; + attrs = DNS_DISPATCHATTR_UDP; switch (af) { case AF_INET: attrs |= DNS_DISPATCHATTR_IPV4; @@ -1320,10 +1317,7 @@ get_view_querysource_dispatch(const cfg_obj_t **maps, int af, attrs |= DNS_DISPATCHATTR_IPV6; break; } - if (isc_sockaddr_getport(&sa) == 0) { - attrs |= DNS_DISPATCHATTR_EXCLUSIVE; - maxdispatchbuffers = EXCLBUFFERS; - } else { + if (isc_sockaddr_getport(&sa) != 0) { INSIST(obj != NULL); if (is_firstview) { cfg_obj_log(obj, named_g_lctx, ISC_LOG_INFO, @@ -1333,10 +1327,9 @@ get_view_querysource_dispatch(const cfg_obj_t **maps, int af, } } - disp = NULL; - result = dns_dispatch_getudp(named_g_dispatchmgr, named_g_socketmgr, - named_g_taskmgr, &sa, maxdispatchbuffers, - 32768, 16411, 16433, attrs, &disp); + result = dns_dispatch_createudp( + named_g_dispatchmgr, named_g_socketmgr, named_g_taskmgr, &sa, + maxdispatchbuffers, 32768, 16411, 16433, attrs, &disp); if (result != ISC_R_SUCCESS) { isc_sockaddr_t any; char buf[ISC_SOCKADDR_FORMATSIZE]; @@ -10377,8 +10370,7 @@ named_add_reserved_dispatch(named_server_t *server, dispatch->dispatchgen = server->dispatchgen; dispatch->dispatch = NULL; - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; + attrs = DNS_DISPATCHATTR_UDP; switch (isc_sockaddr_pf(addr)) { case AF_INET: attrs |= DNS_DISPATCHATTR_IPV4; @@ -10391,10 +10383,10 @@ named_add_reserved_dispatch(named_server_t *server, goto cleanup; } - result = dns_dispatch_getudp(named_g_dispatchmgr, named_g_socketmgr, - named_g_taskmgr, &dispatch->addr, - UDPBUFFERS, 32768, 16411, 16433, attrs, - &dispatch->dispatch); + result = dns_dispatch_createudp(named_g_dispatchmgr, named_g_socketmgr, + named_g_taskmgr, &dispatch->addr, + UDPBUFFERS, 32768, 16411, 16433, attrs, + &dispatch->dispatch); if (result != ISC_R_SUCCESS) { goto cleanup; } diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index bc39de6725..ce2a48c4d0 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -937,25 +937,23 @@ setup_system(void) { set_source_ports(dispatchmgr); if (have_ipv6) { - attrs = DNS_DISPATCHATTR_UDP; - attrs |= DNS_DISPATCHATTR_MAKEQUERY; - attrs |= DNS_DISPATCHATTR_IPV6; + attrs = (DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY | + DNS_DISPATCHATTR_IPV6); isc_sockaddr_any6(&bind_any6); - result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, - &bind_any6, 4, 2, 3, 5, attrs, - &dispatchv6); - check_result(result, "dns_dispatch_getudp (v6)"); + result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, + &bind_any6, 4, 2, 3, 5, attrs, + &dispatchv6); + check_result(result, "dns_dispatch_createudp (v6)"); } if (have_ipv4) { - attrs = DNS_DISPATCHATTR_UDP; - attrs |= DNS_DISPATCHATTR_MAKEQUERY; - attrs |= DNS_DISPATCHATTR_IPV4; + attrs = (DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY | + DNS_DISPATCHATTR_IPV4); isc_sockaddr_any(&bind_any); - result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, - &bind_any, 4, 2, 3, 5, attrs, - &dispatchv4); - check_result(result, "dns_dispatch_getudp (v4)"); + result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, + &bind_any, 4, 2, 3, 5, attrs, + &dispatchv4); + check_result(result, "dns_dispatch_createudp (v4)"); } result = dns_requestmgr_create(gmctx, timermgr, socketmgr, taskmgr, diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c index f9371e7c0d..e8aa99dbd1 100644 --- a/bin/tests/system/pipelined/pipequeries.c +++ b/bin/tests/system/pipelined/pipequeries.c @@ -59,8 +59,8 @@ #define PORT 5300 #define TIMEOUT 30 -static isc_mem_t *mctx; -static dns_requestmgr_t *requestmgr; +static isc_mem_t *mctx = NULL; +static dns_requestmgr_t *requestmgr = NULL; static bool have_src = false; static isc_sockaddr_t srcaddr; static isc_sockaddr_t dstaddr; @@ -126,10 +126,10 @@ recvresponse(isc_task_t *task, isc_event_t *event) { static isc_result_t sendquery(isc_task_t *task) { - dns_request_t *request; - dns_message_t *message; - dns_name_t *qname; - dns_rdataset_t *qrdataset; + dns_request_t *request = NULL; + dns_message_t *message = NULL; + dns_name_t *qname = NULL; + dns_rdataset_t *qrdataset = NULL; isc_result_t result; dns_fixedname_t queryname; isc_buffer_t buf; @@ -150,7 +150,6 @@ sendquery(isc_task_t *task) { dns_rootname, 0, NULL); CHECK("dns_name_fromtext", result); - message = NULL; dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message); message->opcode = dns_opcode_query; @@ -158,11 +157,9 @@ sendquery(isc_task_t *task) { message->rdclass = dns_rdataclass_in; message->id = (unsigned short)(random() & 0xFFFF); - qname = NULL; result = dns_message_gettempname(message, &qname); CHECK("dns_message_gettempname", result); - qrdataset = NULL; result = dns_message_gettemprdataset(message, &qrdataset); CHECK("dns_message_gettemprdataset", result); @@ -172,7 +169,6 @@ sendquery(isc_task_t *task) { ISC_LIST_APPEND(qname->list, qrdataset, link); dns_message_addname(message, qname, DNS_SECTION_QUESTION); - request = NULL; result = dns_request_createvia(requestmgr, message, have_src ? &srcaddr : NULL, &dstaddr, -1, DNS_REQUESTOPT_TCP, NULL, TIMEOUT, 0, 0, @@ -203,8 +199,8 @@ main(int argc, char *argv[]) { isc_sockaddr_t bind_any; struct in_addr inaddr; isc_result_t result; - isc_log_t *lctx; - isc_logconfig_t *lcfg; + isc_log_t *lctx = NULL; + isc_logconfig_t *lcfg = NULL; isc_nm_t *netmgr = NULL; isc_taskmgr_t *taskmgr = NULL; isc_task_t *task = NULL; @@ -212,8 +208,8 @@ main(int argc, char *argv[]) { isc_socketmgr_t *socketmgr = NULL; dns_dispatchmgr_t *dispatchmgr = NULL; unsigned int attrs; - dns_dispatch_t *dispatchv4; - dns_view_t *view; + dns_dispatch_t *dispatchv4 = NULL; + dns_view_t *view = NULL; uint16_t port = PORT; int c; @@ -267,11 +263,8 @@ main(int argc, char *argv[]) { } isc_sockaddr_fromin(&dstaddr, &inaddr, port); - mctx = NULL; isc_mem_create(&mctx); - lctx = NULL; - lcfg = NULL; isc_log_create(mctx, &lctx, &lcfg); RUNCHECK(dst_lib_init(mctx, NULL)); @@ -284,18 +277,15 @@ main(int argc, char *argv[]) { attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY | DNS_DISPATCHATTR_IPV4; - dispatchv4 = NULL; - RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, - have_src ? &srcaddr : &bind_any, 4, 2, 3, - 5, attrs, &dispatchv4)); - requestmgr = NULL; + + RUNCHECK(dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, + have_src ? &srcaddr : &bind_any, 4, 2, + 3, 5, attrs, &dispatchv4)); RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr, dispatchmgr, dispatchv4, NULL, &requestmgr)); - view = NULL; RUNCHECK(dns_view_create(mctx, 0, "_test", &view)); - RUNCHECK(isc_app_onrun(mctx, task, sendqueries, NULL)); (void)isc_app_run(); diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c index 14fb88857b..1b9d500893 100644 --- a/bin/tests/system/tkey/keycreate.c +++ b/bin/tests/system/tkey/keycreate.c @@ -243,9 +243,9 @@ main(int argc, char *argv[]) { isc_sockaddr_any(&bind_any); attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY | DNS_DISPATCHATTR_IPV4; - dispatchv4 = NULL; - RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &bind_any, - 4, 2, 3, 5, attrs, &dispatchv4)); + RUNCHECK(dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, + &bind_any, 4, 2, 3, 5, attrs, + &dispatchv4)); requestmgr = NULL; RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr, dispatchmgr, dispatchv4, NULL, diff --git a/bin/tests/system/tkey/keydelete.c b/bin/tests/system/tkey/keydelete.c index 605be6ecc0..eabb3f0c7e 100644 --- a/bin/tests/system/tkey/keydelete.c +++ b/bin/tests/system/tkey/keydelete.c @@ -186,9 +186,9 @@ main(int argc, char **argv) { isc_sockaddr_any(&bind_any); attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY | DNS_DISPATCHATTR_IPV4; - dispatchv4 = NULL; - RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &bind_any, - 4, 2, 3, 5, attrs, &dispatchv4)); + RUNCHECK(dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, + &bind_any, 4, 2, 3, 5, attrs, + &dispatchv4)); requestmgr = NULL; RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr, dispatchmgr, dispatchv4, NULL, diff --git a/bin/tools/mdig.c b/bin/tools/mdig.c index c07e64b032..d379285ed7 100644 --- a/bin/tools/mdig.c +++ b/bin/tools/mdig.c @@ -2071,11 +2071,10 @@ main(int argc, char *argv[]) { isc_timermgr_t *timermgr = NULL; isc_socketmgr_t *socketmgr = NULL; dns_dispatchmgr_t *dispatchmgr = NULL; - unsigned int attrs; dns_dispatch_t *dispatchvx = NULL; dns_view_t *view = NULL; + unsigned int attrs, i; int ns; - unsigned int i; RUNCHECK(isc_app_start()); @@ -2094,7 +2093,6 @@ main(int argc, char *argv[]) { preparse_args(argc, argv); isc_mem_create(&mctx); - isc_log_create(mctx, &lctx, &lcfg); RUNCHECK(dst_lib_init(mctx, NULL)); @@ -2128,7 +2126,6 @@ main(int argc, char *argv[]) { &socketmgr); RUNCHECK(isc_task_create(taskmgr, 0, &task)); - RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr)); attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY; @@ -2139,10 +2136,10 @@ main(int argc, char *argv[]) { isc_sockaddr_any6(&bind_any); attrs |= DNS_DISPATCHATTR_IPV6; } - dispatchvx = NULL; - RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, - have_src ? &srcaddr : &bind_any, 100, 100, - 17, 19, attrs, &dispatchvx)); + RUNCHECK(dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, + have_src ? &srcaddr : &bind_any, 100, + 100, 17, 19, attrs, &dispatchvx)); + RUNCHECK(dns_requestmgr_create( mctx, timermgr, socketmgr, taskmgr, dispatchmgr, have_ipv4 ? dispatchvx : NULL, have_ipv6 ? dispatchvx : NULL, diff --git a/lib/dns/client.c b/lib/dns/client.c index ce2c7e325c..3547d3cc81 100644 --- a/lib/dns/client.c +++ b/lib/dns/client.c @@ -206,13 +206,12 @@ getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr, bool is_shared, dns_dispatch_t **dispp, const isc_sockaddr_t *localaddr) { unsigned int attrs; - dns_dispatch_t *disp; + dns_dispatch_t *disp = NULL; unsigned maxbuffers, maxrequests, buckets, increment; isc_result_t result; isc_sockaddr_t anyaddr; - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; + attrs = DNS_DISPATCHATTR_UDP; switch (family) { case AF_INET: attrs |= DNS_DISPATCHATTR_IPV4; @@ -235,10 +234,9 @@ getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr, buckets = is_shared ? 16411 : 3; increment = is_shared ? 16433 : 5; - disp = NULL; - result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, localaddr, - maxbuffers, maxrequests, buckets, - increment, attrs, &disp); + result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, + localaddr, maxbuffers, maxrequests, + buckets, increment, attrs, &disp); if (result == ISC_R_SUCCESS) { *dispp = disp; } diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index 1bbff39504..5a3bbad899 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -275,11 +275,7 @@ destroy_dispsocket(dns_dispatch_t *, dispsocket_t **); static void deactivate_dispsocket(dns_dispatch_t *, dispsocket_t *); static void -udp_exrecv(isc_task_t *, isc_event_t *); -static void -udp_shrecv(isc_task_t *, isc_event_t *); -static void -udp_recv(isc_event_t *, dns_dispatch_t *, dispsocket_t *); +udp_recv(isc_task_t *, isc_event_t *); static void tcp_recv(isc_task_t *, isc_event_t *); static isc_result_t @@ -303,14 +299,10 @@ linear_next(dns_qid_t *disp, dns_dispentry_t *resp); static void dispatch_free(dns_dispatch_t **dispp); static isc_result_t -get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp, - isc_socketmgr_t *sockmgr, const isc_sockaddr_t *localaddr, - isc_socket_t **sockp, isc_socket_t *dup_socket); -static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr, unsigned int maxrequests, unsigned int attributes, - dns_dispatch_t **dispp, isc_socket_t *dup_socket); + dns_dispatch_t **dispp); static bool destroy_mgr_ok(dns_dispatchmgr_t *mgr); static void @@ -324,9 +316,6 @@ static isc_result_t open_socket(isc_socketmgr_t *mgr, const isc_sockaddr_t *local, unsigned int options, isc_socket_t **sockp, isc_socket_t *dup_socket); -static bool -portavailable(dns_dispatchmgr_t *mgr, isc_socket_t *sock, - isc_sockaddr_t *sockaddrp); #define LVL(x) ISC_LOG_DEBUG(x) @@ -534,9 +523,8 @@ destroy_disp(isc_task_t *task, isc_event_t *event) { LOCK(&mgr->lock); ISC_LIST_UNLINK(mgr->list, disp, link); - dispatch_log(disp, LVL(90), - "shutting down; detaching from sock %p, task %p", - disp->socket, disp->task[0]); /* XXXX */ + dispatch_log(disp, LVL(90), "shutting down; detaching from sock %p", + disp->socket); if (disp->sepool != NULL) { isc_mem_destroy(&disp->sepool); @@ -747,29 +735,25 @@ get_dispsocket(dns_dispatch_t *disp, const isc_sockaddr_t *dest, } } - if (result == ISC_R_SUCCESS) { - dispsock->socket = sock; - dispsock->host = *dest; - dispsock->bucket = bucket; - LOCK(&qid->lock); - dispsock->portentry = portentry; - ISC_LIST_APPEND(qid->sock_table[bucket], dispsock, blink); - UNLOCK(&qid->lock); - *dispsockp = dispsock; - *portp = port; - } else { - /* - * We could keep it in the inactive list, but since this should - * be an exceptional case and might be resource shortage, we'd - * rather destroy it. - */ + if (result != ISC_R_SUCCESS) { if (sock != NULL) { isc_socket_detach(&sock); } destroy_dispsocket(disp, &dispsock); + return (result); } - return (result); + dispsock->socket = sock; + dispsock->host = *dest; + dispsock->bucket = bucket; + LOCK(&qid->lock); + dispsock->portentry = portentry; + ISC_LIST_APPEND(qid->sock_table[bucket], dispsock, blink); + UNLOCK(&qid->lock); + *dispsockp = dispsock; + *portp = port; + + return (ISC_R_SUCCESS); } /*% @@ -973,26 +957,6 @@ allocate_devent(dns_dispatch_t *disp) { return (ev); } -static void -udp_exrecv(isc_task_t *task, isc_event_t *ev) { - dispsocket_t *dispsock = ev->ev_arg; - - UNUSED(task); - - REQUIRE(VALID_DISPSOCK(dispsock)); - udp_recv(ev, dispsock->disp, dispsock); -} - -static void -udp_shrecv(isc_task_t *task, isc_event_t *ev) { - dns_dispatch_t *disp = ev->ev_arg; - - UNUSED(task); - - REQUIRE(VALID_DISPATCH(disp)); - udp_recv(ev, disp, NULL); -} - /* * General flow: * @@ -1008,28 +972,36 @@ udp_shrecv(isc_task_t *task, isc_event_t *ev) { * restart. */ static void -udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) { +udp_recv(isc_task_t *task, isc_event_t *ev_in) { isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; + dispsocket_t *dispsock = NULL; + dns_dispatch_t *disp = NULL; dns_messageid_t id; isc_result_t dres; isc_buffer_t source; unsigned int flags; dns_dispentry_t *resp = NULL; dns_dispatchevent_t *rev = NULL; - unsigned int bucket; bool killit; bool queue_response; dns_dispatchmgr_t *mgr = NULL; - dns_qid_t *qid = NULL; isc_netaddr_t netaddr; int match; int result; - bool qidlocked = false; + + UNUSED(task); + + REQUIRE(ev->ev_type == ISC_SOCKEVENT_RECVDONE); + + dispsock = ev_in->ev_arg; + + REQUIRE(VALID_DISPSOCK(dispsock)); + + disp = dispsock->disp; LOCK(&disp->lock); mgr = disp->mgr; - qid = mgr->qid; LOCK(&disp->mgr->buffer_lock); dispatch_log(disp, LVL(90), @@ -1037,24 +1009,12 @@ udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) { disp->requests, disp->mgr->buffers, disp->recv_pending); UNLOCK(&disp->mgr->buffer_lock); - if (dispsock == NULL && ev->ev_type == ISC_SOCKEVENT_RECVDONE) { - /* - * Unless the receive event was imported from a listening - * interface, in which case the event type is - * DNS_EVENT_IMPORTRECVDONE, receive operation must be pending. - */ - INSIST(disp->recv_pending != 0); - disp->recv_pending = 0; - } - - if (dispsock != NULL && - (ev->result == ISC_R_CANCELED || dispsock->resp == NULL)) - { + if (ev->result == ISC_R_CANCELED || dispsock->resp == NULL) { /* * dispsock->resp can be NULL if this transaction was canceled * just after receiving a response. Since this socket is * exclusively used and there should be at most one receive - * event the canceled event should have been no effect. So + * event the canceled event should have no effect. So * we can (and should) deactivate the socket right now. */ deactivate_dispsocket(disp, dispsock); @@ -1079,40 +1039,26 @@ udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) { return; } - if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { - if (dispsock == NULL) { - free_buffer(disp, ev->region.base, ev->region.length); - - isc_event_free(&ev_in); - UNLOCK(&disp->lock); - return; - } - - resp = dispsock->resp; - id = resp->id; - if (ev->result != ISC_R_SUCCESS) { - /* - * This is most likely a network error on a - * connected socket. It makes no sense to - * check the address or parse the packet, but it - * will help to return the error to the caller. - */ - goto sendresponse; - } - } else if (ev->result != ISC_R_SUCCESS) { + if (dispsock == NULL) { free_buffer(disp, ev->region.base, ev->region.length); - - if (ev->result != ISC_R_CANCELED) { - dispatch_log(disp, ISC_LOG_ERROR, - "odd socket result in udp_recv(): %s", - isc_result_totext(ev->result)); - } - isc_event_free(&ev_in); UNLOCK(&disp->lock); return; } + resp = dispsock->resp; + id = resp->id; + + if (ev->result != ISC_R_SUCCESS) { + /* + * This is most likely a network error on a + * connected socket. It makes no sense to + * check the address or parse the packet, but it + * will help to return the error to the caller. + */ + goto sendresponse; + } + /* * If this is from a blackholed address, drop it. */ @@ -1160,33 +1106,13 @@ udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) { } /* - * Search for the corresponding response. If we are using an exclusive - * socket, we've already identified it and we can skip the search; but - * the ID and the address must match the expected ones. + * The QID and the address must match the expected ones. */ - if (resp == NULL) { - bucket = dns_hash(qid, &ev->address, id, disp->localport); - LOCK(&qid->lock); - qidlocked = true; - resp = entry_search(qid, &ev->address, id, disp->localport, - bucket); - dispatch_log(disp, LVL(90), - "search for response in bucket %d: %s", bucket, - (resp == NULL ? "not found" : "found")); - - } else if (resp->id != id || - !isc_sockaddr_equal(&ev->address, &resp->host)) { - dispatch_log(disp, LVL(90), - "response to an exclusive socket doesn't match"); + if (resp->id != id || !isc_sockaddr_equal(&ev->address, &resp->host)) { + dispatch_log(disp, LVL(90), "response doesn't match"); inc_stats(mgr, dns_resstatscounter_mismatch); free_buffer(disp, ev->region.base, ev->region.length); - goto unlock; - } - - if (resp == NULL) { - inc_stats(mgr, dns_resstatscounter_mismatch); - free_buffer(disp, ev->region.base, ev->region.length); - goto unlock; + goto restart; } /* @@ -1206,7 +1132,7 @@ udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) { isc_sockaddr_getport(&resp->disp->local)) { free_buffer(disp, ev->region.base, ev->region.length); - goto unlock; + goto restart; } /* @@ -1223,7 +1149,7 @@ udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) { isc_sockaddr_pf(&disp->local) != PF_INET6) { free_buffer(disp, ev->region.base, ev->region.length); - goto unlock; + goto restart; } isc_sockaddr_anyofpf(&a1, isc_sockaddr_pf(&resp->disp->local)); isc_sockaddr_anyofpf(&a2, isc_sockaddr_pf(&disp->local)); @@ -1232,7 +1158,7 @@ udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) { !isc_sockaddr_eqaddr(&a2, &disp->local)) { free_buffer(disp, ev->region.base, ev->region.length); - goto unlock; + goto restart; } } @@ -1264,23 +1190,13 @@ sendresponse: resp->item_out = true; isc_task_send(resp->task, ISC_EVENT_PTR(&rev)); } -unlock: - if (qidlocked) { - UNLOCK(&qid->lock); - } /* * Restart recv() to get the next packet. */ restart: result = startrecv(disp, dispsock); - if (result != ISC_R_SUCCESS && dispsock != NULL) { - /* - * XXX: wired. There seems to be no recovery process other than - * deactivate this socket anyway (since we cannot start - * receiving, we won't be able to receive a cancel event - * from the user). - */ + if (result != ISC_R_SUCCESS) { deactivate_dispsocket(disp, dispsock); } isc_event_free(&ev_in); @@ -1478,26 +1394,21 @@ startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) { isc_result_t res; isc_region_t region; isc_socket_t *sock = NULL; + isc_socketevent_t *sev = NULL; if (disp->shutting_down == 1) { return (ISC_R_SUCCESS); } - if (disp->recv_pending != 0 && dispsock == NULL) { - return (ISC_R_SUCCESS); - } - - if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 && - dispsock == NULL) { - return (ISC_R_SUCCESS); - } - - if (dispsock != NULL) { - sock = dispsock->socket; - } else { + if (dispsock == NULL) { + if (disp->socktype == isc_sockettype_udp || + disp->recv_pending != 0) { + return (ISC_R_SUCCESS); + } sock = disp->socket; + } else { + sock = dispsock->socket; } - INSIST(sock != NULL); switch (disp->socktype) { /* @@ -1509,33 +1420,13 @@ startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) { if (region.base == NULL) { return (ISC_R_NOMEMORY); } - if (dispsock != NULL) { - isc_task_t *dt = dispsock->task; - isc_socketevent_t *sev = allocate_sevent( - disp, sock, ISC_SOCKEVENT_RECVDONE, udp_exrecv, - dispsock); - - res = isc_socket_recv2(sock, ®ion, 1, dt, sev, 0); - if (res != ISC_R_SUCCESS) { - free_buffer(disp, region.base, region.length); - return (res); - } - } else { - isc_task_t *dt = disp->task[0]; - isc_socketevent_t *sev = allocate_sevent( - disp, sock, ISC_SOCKEVENT_RECVDONE, udp_shrecv, - disp); - - res = isc_socket_recv2(sock, ®ion, 1, dt, sev, 0); - if (res != ISC_R_SUCCESS) { - free_buffer(disp, region.base, region.length); - disp->shutdown_why = res; - disp->shutting_down = 1; - do_cancel(disp); - return (ISC_R_SUCCESS); /* recover by cancel */ - } - INSIST(disp->recv_pending == 0); - disp->recv_pending = 1; + sev = allocate_sevent(disp, sock, ISC_SOCKEVENT_RECVDONE, + udp_recv, dispsock); + res = isc_socket_recv2(sock, ®ion, 1, dispsock->task, sev, + 0); + if (res != ISC_R_SUCCESS) { + free_buffer(disp, region.base, region.length); + return (res); } break; @@ -1876,62 +1767,6 @@ dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats) { isc_stats_attach(stats, &mgr->stats); } -static int -port_cmp(const void *key, const void *ent) { - in_port_t p1 = *(const in_port_t *)key; - in_port_t p2 = *(const in_port_t *)ent; - - if (p1 < p2) { - return (-1); - } else if (p1 == p2) { - return (0); - } else { - return (1); - } -} - -static bool -portavailable(dns_dispatchmgr_t *mgr, isc_socket_t *sock, - isc_sockaddr_t *sockaddrp) { - isc_sockaddr_t sockaddr; - isc_result_t result; - in_port_t *ports, port; - unsigned int nports; - bool available = false; - - REQUIRE(sock != NULL || sockaddrp != NULL); - - PORTBUFLOCK(mgr); - if (sock != NULL) { - sockaddrp = &sockaddr; - result = isc_socket_getsockname(sock, sockaddrp); - if (result != ISC_R_SUCCESS) { - goto unlock; - } - } - - if (isc_sockaddr_pf(sockaddrp) == AF_INET) { - ports = mgr->v4ports; - nports = mgr->nv4ports; - } else { - ports = mgr->v6ports; - nports = mgr->nv6ports; - } - if (ports == NULL) { - goto unlock; - } - - port = isc_sockaddr_getport(sockaddrp); - if (bsearch(&port, ports, nports, sizeof(in_port_t), port_cmp) != NULL) - { - available = true; - } - -unlock: - PORTBUFUNLOCK(mgr); - return (available); -} - static isc_result_t qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets, unsigned int increment, dns_qid_t **qidp, bool needsocktable) { @@ -2120,8 +1955,6 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, disp->socket = NULL; isc_socket_attach(sock, &disp->socket); - disp->sepool = NULL; - disp->ntasks = 1; disp->task[0] = NULL; result = isc_task_create(taskmgr, 50, &disp->task[0]); @@ -2140,6 +1973,12 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, disp->attributes = attributes; + if (destaddr == NULL) { + (void)isc_socket_getpeername(sock, &disp->peer); + } else { + disp->peer = *destaddr; + } + if (localaddr == NULL) { if (destaddr != NULL) { switch (isc_sockaddr_pf(destaddr)) { @@ -2150,15 +1989,13 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, isc_sockaddr_any6(&disp->local); break; } + } else { + (void)isc_socket_getsockname(sock, &disp->local); } } else { disp->local = *localaddr; } - if (destaddr != NULL) { - disp->peer = *destaddr; - } - /* * Append it to the dispatcher list. */ @@ -2205,7 +2042,7 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr, /* First pass */ attributes = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_CONNECTED; mask = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_PRIVATE | - DNS_DISPATCHATTR_EXCLUSIVE | DNS_DISPATCHATTR_CONNECTED; + DNS_DISPATCHATTR_CONNECTED; LOCK(&mgr->lock); disp = ISC_LIST_HEAD(mgr->list); @@ -2269,11 +2106,11 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr, } isc_result_t -dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, - isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, - unsigned int attributes, dns_dispatch_t **dispp) { +dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, + isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr, + unsigned int maxbuffers, unsigned int maxrequests, + unsigned int buckets, unsigned int increment, + unsigned int attributes, dns_dispatch_t **dispp) { isc_result_t result; dns_dispatch_t *disp = NULL; @@ -2294,149 +2131,26 @@ dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, } LOCK(&mgr->lock); - - if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { - REQUIRE(isc_sockaddr_getport(localaddr) == 0); - } - - /* - * We need an exclusive-socket dispatch, or else we didn't - * find a suitable shared one and need to create it. - */ result = dispatch_createudp(mgr, sockmgr, taskmgr, localaddr, - maxrequests, attributes, &disp, NULL); - if (result != ISC_R_SUCCESS) { - UNLOCK(&mgr->lock); - return (result); + maxrequests, attributes, &disp); + + if (result == ISC_R_SUCCESS) { + *dispp = disp; } UNLOCK(&mgr->lock); - *dispp = disp; - return (ISC_R_SUCCESS); } -/* - * mgr should be locked. - */ - -#ifndef DNS_DISPATCH_HELD -#define DNS_DISPATCH_HELD 20U -#endif /* ifndef DNS_DISPATCH_HELD */ - -static isc_result_t -get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp, - isc_socketmgr_t *sockmgr, const isc_sockaddr_t *localaddr, - isc_socket_t **sockp, isc_socket_t *dup_socket) { - unsigned int i, j; - isc_socket_t *held[DNS_DISPATCH_HELD]; - isc_sockaddr_t localaddr_bound; - isc_socket_t *sock = NULL; - isc_result_t result = ISC_R_SUCCESS; - unsigned int nports; - in_port_t *ports = NULL; - - REQUIRE(sockp != NULL && *sockp == NULL); - - if (isc_sockaddr_getport(localaddr) != 0) { - /* Allow to reuse address for non-random ports. */ - result = open_socket(sockmgr, localaddr, - ISC_SOCKET_REUSEADDRESS, &sock, - dup_socket); - if (result == ISC_R_SUCCESS) { - *sockp = sock; - } - - return (result); - } - - /* - * If no port is specified, we first try to pick up a random - * port by ourselves. - */ - if (isc_sockaddr_pf(localaddr) == AF_INET) { - nports = mgr->nv4ports; - ports = mgr->v4ports; - } else { - nports = mgr->nv6ports; - ports = mgr->v6ports; - } - if (nports == 0) { - return (ISC_R_ADDRNOTAVAIL); - } - - localaddr_bound = *localaddr; - - for (i = 0; i < 1024; i++) { - in_port_t prt; - - prt = ports[isc_random_uniform(nports)]; - isc_sockaddr_setport(&localaddr_bound, prt); - result = open_socket(sockmgr, &localaddr_bound, 0, &sock, NULL); - /* - * If the port chosen is already in use or the OS has - * reserved it, try again. - */ - if (result == ISC_R_NOPERM || result == ISC_R_ADDRINUSE) { - continue; - } - disp->localport = prt; - *sockp = sock; - return (result); - } - - /* - * If this fails 1024 times, we then ask the kernel for - * help choosing one. - */ - memset(held, 0, sizeof(held)); - i = 0; - - for (j = 0; j < 0xffffU; j++) { - result = open_socket(sockmgr, localaddr, 0, &sock, NULL); - if (result != ISC_R_SUCCESS) { - goto end; - } else if (portavailable(mgr, sock, NULL)) { - break; - } - if (held[i] != NULL) { - isc_socket_detach(&held[i]); - } - held[i++] = sock; - sock = NULL; - if (i == DNS_DISPATCH_HELD) { - i = 0; - } - } - - if (j == 0xffffU) { - mgr_log(mgr, ISC_LOG_ERROR, - "avoid-v%s-udp-ports: unable to allocate " - "an available port", - isc_sockaddr_pf(localaddr) == AF_INET ? "4" : "6"); - result = ISC_R_FAILURE; - goto end; - } - *sockp = sock; - -end: - for (i = 0; i < DNS_DISPATCH_HELD; i++) { - if (held[i] != NULL) { - isc_socket_detach(&held[i]); - } - } - - return (result); -} - static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr, unsigned int maxrequests, unsigned int attributes, - dns_dispatch_t **dispp, isc_socket_t *dup_socket) { + dns_dispatch_t **dispp) { isc_result_t result; dns_dispatch_t *disp = NULL; isc_socket_t *sock = NULL; + isc_sockaddr_t sa_any; int i = 0; /* @@ -2450,59 +2164,44 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, disp->socktype = isc_sockettype_udp; - if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0) { - result = get_udpsocket(mgr, disp, sockmgr, localaddr, &sock, - dup_socket); + /* + * For dispatches with a specified source address, we open a + * socket to make sure that address is available on the system, + * but we don't keep it open; sockets used for sending requests + * will be created later on demand. + */ + isc_sockaddr_anyofpf(&sa_any, isc_sockaddr_pf(localaddr)); + if (!isc_sockaddr_eqaddr(&sa_any, localaddr)) { + result = open_socket(sockmgr, localaddr, 0, &sock, NULL); + if (sock != NULL) { + isc_socket_detach(&sock); + } if (result != ISC_R_SUCCESS) { goto deallocate_dispatch; } - - if (isc_log_wouldlog(dns_lctx, 90)) { - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - - isc_sockaddr_format(localaddr, addrbuf, - ISC_SOCKADDR_FORMATSIZE); - mgr_log(mgr, LVL(90), - "dispatch_createudp: created shared " - "UDP dispatch for %s with socket fd %d", - addrbuf, isc_socket_getfd(sock)); - } - } else { - isc_sockaddr_t sa_any; - - /* - * For dispatches using exclusive sockets with a specific - * source address, we only check if the specified address is - * available on the system. Query sockets will be created later - * on demand. - */ - isc_sockaddr_anyofpf(&sa_any, isc_sockaddr_pf(localaddr)); - if (!isc_sockaddr_eqaddr(&sa_any, localaddr)) { - result = open_socket(sockmgr, localaddr, 0, &sock, - NULL); - if (sock != NULL) { - isc_socket_detach(&sock); - } - if (result != ISC_R_SUCCESS) { - goto deallocate_dispatch; - } - } - - disp->port_table = isc_mem_get( - mgr->mctx, sizeof(disp->port_table[0]) * - DNS_DISPATCH_PORTTABLESIZE); - for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++) { - ISC_LIST_INIT(disp->port_table[i]); - } } + + disp->port_table = isc_mem_get(mgr->mctx, + sizeof(disp->port_table[0]) * + DNS_DISPATCH_PORTTABLESIZE); + for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++) { + ISC_LIST_INIT(disp->port_table[i]); + } + + if (isc_log_wouldlog(dns_lctx, 90)) { + char addrbuf[ISC_SOCKADDR_FORMATSIZE]; + + isc_sockaddr_format(localaddr, addrbuf, + ISC_SOCKADDR_FORMATSIZE); + mgr_log(mgr, LVL(90), + "dispatch_createudp: created UDP dispatch for %s", + addrbuf); + } + disp->socket = sock; disp->local = *localaddr; + disp->ntasks = MAX_INTERNAL_TASKS; - if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { - disp->ntasks = MAX_INTERNAL_TASKS; - } else { - disp->ntasks = 1; - } for (i = 0; i < disp->ntasks; i++) { disp->task[i] = NULL; result = isc_task_create(taskmgr, 0, &disp->task[i]); @@ -2565,13 +2264,6 @@ dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp) { *dispp = disp; } -/* - * It is important to lock the manager while we are deleting the dispatch, - * since dns_dispatch_getudp will call dispatch_find, which returns to - * the caller a dispatch but does not attach to it until later. _getudp - * locks the manager, however, so locking it here will keep us from attaching - * to a dispatcher that is in the process of going away. - */ void dns_dispatch_detach(dns_dispatch_t **dispp) { dns_dispatch_t *disp = NULL; @@ -2629,9 +2321,7 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, REQUIRE(dest != NULL); REQUIRE(resp != NULL && *resp == NULL); REQUIRE(idp != NULL); - if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { - REQUIRE(sockmgr != NULL); - } + REQUIRE(disp->socktype == isc_sockettype_tcp || sockmgr != NULL); LOCK(&disp->lock); @@ -2645,7 +2335,7 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, return (ISC_R_QUOTA); } - if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 && + if (disp->socktype == isc_sockettype_udp && disp->nsockets > DNS_DISPATCH_SOCKSQUOTA) { dispsocket_t *oldestsocket = NULL; @@ -2681,7 +2371,7 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, qid = DNS_QID(disp); - if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { + if (disp->socktype == isc_sockettype_udp) { /* * Get a separate UDP socket with a random port number. */ @@ -2692,8 +2382,6 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, inc_stats(disp->mgr, dns_resstatscounter_dispsockfail); return (result); } - } else { - localport = disp->localport; } /* @@ -2793,13 +2481,11 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, UNLOCK(&disp->lock); + INSIST(disp->socktype == isc_sockettype_tcp || res->dispsocket != NULL); + *idp = id; *resp = res; - if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { - INSIST(res->dispsocket != NULL); - } - return (ISC_R_SUCCESS); } @@ -3046,7 +2732,9 @@ isc_socket_t * dns_dispatch_getentrysocket(dns_dispentry_t *resp) { REQUIRE(VALID_RESPONSE(resp)); - if (resp->dispsocket != NULL) { + if (resp->disp->socktype == isc_sockettype_tcp) { + return (resp->disp->socket); + } else if (resp->dispsocket != NULL) { return (resp->dispsocket->socket); } else { return (NULL); @@ -3080,8 +2768,6 @@ void dns_dispatch_changeattributes(dns_dispatch_t *disp, unsigned int attributes, unsigned int mask) { REQUIRE(VALID_DISPATCH(disp)); - /* Exclusive attribute can only be set on creation */ - REQUIRE((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0); LOCK(&disp->lock); @@ -3140,10 +2826,10 @@ dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr, LOCK(&mgr->lock); for (i = 1; i < n; i++) { dset->dispatches[i] = NULL; - result = dispatch_createudp( - mgr, sockmgr, taskmgr, &source->local, - source->maxrequests, source->attributes, - &dset->dispatches[i], source->socket); + result = dispatch_createudp(mgr, sockmgr, taskmgr, + &source->local, source->maxrequests, + source->attributes, + &dset->dispatches[i]); if (result != ISC_R_SUCCESS) { goto fail; } @@ -3170,19 +2856,6 @@ fail: return (result); } -void -dns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task) { - int i; - - REQUIRE(dset != NULL); - - for (i = 0; i < dset->ndisp; i++) { - isc_socket_t *sock = NULL; - sock = dns_dispatch_getsocket(dset->dispatches[i]); - isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL); - } -} - void dns_dispatchset_destroy(dns_dispatchset_t **dsetp) { dns_dispatchset_t *dset = NULL; diff --git a/lib/dns/include/dns/dispatch.h b/lib/dns/include/dns/dispatch.h index ddedac07b5..e4fc0cc727 100644 --- a/lib/dns/include/dns/dispatch.h +++ b/lib/dns/include/dns/dispatch.h @@ -118,9 +118,6 @@ struct dns_dispatchset { * _MAKEQUERY * The dispatcher can be used to issue queries to other servers, and * accept replies from them. - * - * _EXCLUSIVE - * A separate socket will be used on-demand for each transaction. */ #define DNS_DISPATCHATTR_PRIVATE 0x00000001U #define DNS_DISPATCHATTR_TCP 0x00000002U @@ -129,7 +126,6 @@ struct dns_dispatchset { #define DNS_DISPATCHATTR_IPV6 0x00000010U #define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U #define DNS_DISPATCHATTR_CONNECTED 0x00000080U -#define DNS_DISPATCHATTR_EXCLUSIVE 0x00000200U /*@}*/ /* @@ -214,14 +210,13 @@ dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats); */ isc_result_t -dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, - isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, - unsigned int attributes, dns_dispatch_t **dispp); +dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, + isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr, + unsigned int maxbuffers, unsigned int maxrequests, + unsigned int buckets, unsigned int increment, + unsigned int attributes, dns_dispatch_t **dispp); /*%< - * Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find, - * otherwise create a new UDP dispatch. + * Create a new UDP dispatch. * * Requires: *\li All pointer parameters be valid for their respective types. @@ -394,7 +389,7 @@ dns_dispatch_getentrysocket(dns_dispentry_t *resp); isc_socket_t * dns_dispatch_getsocket(dns_dispatch_t *disp); /*%< - * Return the socket associated with this dispatcher. + * Return the socket associated with dispatcher or dispatch entry. * * Requires: *\li disp is valid. @@ -477,12 +472,6 @@ dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr, *\li dsetp != NULL, *dsetp == NULL */ -void -dns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task); -/*%< - * Cancel socket operations for the dispatches in 'dset'. - */ - void dns_dispatchset_destroy(dns_dispatchset_t **dsetp); /*%< diff --git a/lib/dns/request.c b/lib/dns/request.c index 953023a22e..a4ca668e18 100644 --- a/lib/dns/request.c +++ b/lib/dns/request.c @@ -415,13 +415,14 @@ static inline isc_result_t req_send(dns_request_t *request, isc_task_t *task, const isc_sockaddr_t *address) { isc_region_t r; - isc_socket_t *sock; - isc_socketevent_t *sendevent; + isc_socket_t *sock = NULL; + isc_socketevent_t *sendevent = NULL; isc_result_t result; req_log(ISC_LOG_DEBUG(3), "req_send: request %p", request); REQUIRE(VALID_REQUEST(request)); + sock = req_getsocket(request); isc_buffer_usedregion(request->query, &r); /* @@ -596,8 +597,7 @@ find_udp_dispatch(dns_requestmgr_t *requestmgr, const isc_sockaddr_t *srcaddr, dns_dispatch_attach(disp, dispatchp); return (ISC_R_SUCCESS); } - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; + attrs = DNS_DISPATCHATTR_UDP; switch (isc_sockaddr_pf(srcaddr)) { case PF_INET: attrs |= DNS_DISPATCHATTR_IPV4; @@ -610,10 +610,11 @@ find_udp_dispatch(dns_requestmgr_t *requestmgr, const isc_sockaddr_t *srcaddr, default: return (ISC_R_NOTIMPLEMENTED); } - return (dns_dispatch_getudp(requestmgr->dispatchmgr, - requestmgr->socketmgr, requestmgr->taskmgr, - srcaddr, 32768, 32768, 16411, 16433, attrs, - dispatchp)); + + return (dns_dispatch_createudp(requestmgr->dispatchmgr, + requestmgr->socketmgr, + requestmgr->taskmgr, srcaddr, 32768, + 32768, 16411, 16433, attrs, dispatchp)); } static isc_result_t @@ -1242,18 +1243,7 @@ dns_request_destroy(dns_request_t **requestp) { static isc_socket_t * req_getsocket(dns_request_t *request) { - unsigned int dispattr; - isc_socket_t *sock; - - dispattr = dns_dispatch_getattributes(request->dispatch); - if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { - INSIST(request->dispentry != NULL); - sock = dns_dispatch_getentrysocket(request->dispentry); - } else { - sock = dns_dispatch_getsocket(request->dispatch); - } - - return (sock); + return (dns_dispatch_getentrysocket(request->dispentry)); } static void @@ -1460,8 +1450,7 @@ req_destroy(dns_request_t *request) { */ static void req_cancel(dns_request_t *request) { - isc_socket_t *sock; - unsigned int dispattr; + isc_socket_t *sock = NULL; REQUIRE(VALID_REQUEST(request)); @@ -1475,16 +1464,10 @@ req_cancel(dns_request_t *request) { if (request->timer != NULL) { isc_timer_detach(&request->timer); } - dispattr = dns_dispatch_getattributes(request->dispatch); - sock = NULL; + if (DNS_REQUEST_CONNECTING(request) || DNS_REQUEST_SENDING(request)) { - if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { - if (request->dispentry != NULL) { - sock = dns_dispatch_getentrysocket( - request->dispentry); - } - } else { - sock = dns_dispatch_getsocket(request->dispatch); + if (request->dispentry != NULL) { + sock = dns_dispatch_getentrysocket(request->dispentry); } if (DNS_REQUEST_CONNECTING(request) && sock != NULL) { isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_CONNECT); diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index a47edf9ab2..66bebaaa6f 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -227,7 +227,6 @@ typedef struct query { isc_mem_t *mctx; dns_dispatchmgr_t *dispatchmgr; dns_dispatch_t *dispatch; - bool exclusivesocket; dns_adbaddrinfo_t *addrinfo; isc_socket_t *tcpsocket; isc_time_t start; @@ -507,11 +506,9 @@ struct dns_resolver { unsigned int options; dns_dispatchmgr_t *dispatchmgr; dns_dispatchset_t *dispatches4; - bool exclusivev4; dns_dispatchset_t *dispatches6; isc_dscp_t querydscp4; isc_dscp_t querydscp6; - bool exclusivev6; unsigned int nbuckets; fctxbucket_t *buckets; zonebucket_t *dbuckets; @@ -1434,7 +1431,6 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp, isc_socket_cancel(query->tcpsocket, NULL, ISC_SOCKCANCEL_CONNECT); } else if (query->dispentry != NULL) { - INSIST(query->exclusivesocket); sock = dns_dispatch_getentrysocket(query->dispentry); if (sock != NULL) { isc_socket_cancel(sock, NULL, @@ -1446,7 +1442,7 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp, /* * Cancel the pending send. */ - if (query->exclusivesocket && query->dispentry != NULL) { + if (query->dispentry != NULL) { sock = dns_dispatch_getentrysocket(query->dispentry); } else { sock = dns_dispatch_getsocket(query->dispatch); @@ -2074,7 +2070,6 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, * a dispatch for it here. Otherwise we use the resolver's * shared dispatch. */ - query->dispatchmgr = res->dispatchmgr; if (res->view->peers != NULL) { dns_peer_t *peer = NULL; isc_netaddr_t dstip; @@ -2160,7 +2155,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, result = ISC_R_NOTIMPLEMENTED; goto cleanup_query; } - result = dns_dispatch_getudp( + result = dns_dispatch_createudp( res->dispatchmgr, res->socketmgr, res->taskmgr, &addr, 20000, 32768, 16411, 16433, attrs, &query->dispatch); @@ -2173,14 +2168,12 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_dispatch_attach( dns_resolver_dispatchv4(res), &query->dispatch); - query->exclusivesocket = res->exclusivev4; dscp = dns_resolver_getquerydscp4(fctx->res); break; case PF_INET6: dns_dispatch_attach( dns_resolver_dispatchv6(res), &query->dispatch); - query->exclusivesocket = res->exclusivev6; dscp = dns_resolver_getquerydscp6(fctx->res); break; default: @@ -2364,11 +2357,7 @@ addr2buf(void *buf, const size_t bufsize, const isc_sockaddr_t *sockaddr) { static inline isc_socket_t * query2sock(const resquery_t *query) { - if (query->exclusivesocket) { - return (dns_dispatch_getentrysocket(query->dispentry)); - } else { - return (dns_dispatch_getsocket(query->dispatch)); - } + return (dns_dispatch_getentrysocket(query->dispentry)); } static inline size_t @@ -2864,15 +2853,12 @@ resquery_send(resquery_t *query) { */ if (!tcp) { address = &query->addrinfo->sockaddr; - if (query->exclusivesocket) { - result = isc_socket_connect(sock, address, task, - resquery_udpconnected, - query); - if (result != ISC_R_SUCCESS) { - goto cleanup_message; - } - query->connects++; + result = isc_socket_connect(sock, address, task, + resquery_udpconnected, query); + if (result != ISC_R_SUCCESS) { + goto cleanup_message; } + query->connects++; } isc_buffer_usedregion(buffer, &r); @@ -3011,17 +2997,16 @@ resquery_connected(isc_task_t *task, isc_event_t *event) { * We are connected. Create a dispatcher and * send the query. */ - attrs = 0; - attrs |= DNS_DISPATCHATTR_TCP; - attrs |= DNS_DISPATCHATTR_PRIVATE; - attrs |= DNS_DISPATCHATTR_CONNECTED; + attrs = DNS_DISPATCHATTR_TCP | + DNS_DISPATCHATTR_PRIVATE | + DNS_DISPATCHATTR_CONNECTED | + DNS_DISPATCHATTR_MAKEQUERY; if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == AF_INET) { attrs |= DNS_DISPATCHATTR_IPV4; } else { attrs |= DNS_DISPATCHATTR_IPV6; } - attrs |= DNS_DISPATCHATTR_MAKEQUERY; result = dns_dispatch_createtcp( query->dispatchmgr, query->tcpsocket, @@ -8129,17 +8114,15 @@ rctx_dispfail(respctx_t *rctx) { rctx->next_server = true; /* - * If this is a network error on an exclusive query - * socket, mark the server as bad so that we won't try - * it for this fetch again. Also adjust finish and - * no_response so that we penalize this address in SRTT - * adjustment later. + * If this is a network error, mark the server as bad so + * that we won't try it for this fetch again. Also adjust + * finish and no_response so that we penalize this address + * in SRTT adjustment later. */ - if (query->exclusivesocket && - (devent->result == ISC_R_HOSTUNREACH || - devent->result == ISC_R_NETUNREACH || - devent->result == ISC_R_CONNREFUSED || - devent->result == ISC_R_CANCELED)) + if (devent->result == ISC_R_HOSTUNREACH || + devent->result == ISC_R_NETUNREACH || + devent->result == ISC_R_CONNREFUSED || + devent->result == ISC_R_CANCELED) { rctx->broken_server = devent->result; rctx->broken_type = badns_unreachable; @@ -10275,7 +10258,6 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr, unsigned int i, buckets_created = 0, dbuckets_created = 0; isc_task_t *task = NULL; char name[16]; - unsigned dispattr; /* * Create a resolver. @@ -10370,15 +10352,11 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr, if (dispatchv4 != NULL) { dns_dispatchset_create(view->mctx, socketmgr, taskmgr, dispatchv4, &res->dispatches4, ndisp); - dispattr = dns_dispatch_getattributes(dispatchv4); - res->exclusivev4 = (dispattr & DNS_DISPATCHATTR_EXCLUSIVE); } if (dispatchv6 != NULL) { dns_dispatchset_create(view->mctx, socketmgr, taskmgr, dispatchv6, &res->dispatches6, ndisp); - dispattr = dns_dispatch_getattributes(dispatchv6); - res->exclusivev6 = (dispattr & DNS_DISPATCHATTR_EXCLUSIVE); } isc_mutex_init(&res->lock); @@ -10617,14 +10595,6 @@ dns_resolver_shutdown(dns_resolver_t *res) { { fctx_shutdown(fctx); } - if (res->dispatches4 != NULL && !res->exclusivev4) { - dns_dispatchset_cancelall(res->dispatches4, - res->buckets[i].task); - } - if (res->dispatches6 != NULL && !res->exclusivev6) { - dns_dispatchset_cancelall(res->dispatches6, - res->buckets[i].task); - } atomic_store(&res->buckets[i].exiting, true); if (ISC_LIST_EMPTY(res->buckets[i].fctxs)) { INSIST(res->activebuckets > 0); diff --git a/lib/dns/tests/dispatch_test.c b/lib/dns/tests/dispatch_test.c index 5bc81a2cd5..fb79fcf40b 100644 --- a/lib/dns/tests/dispatch_test.c +++ b/lib/dns/tests/dispatch_test.c @@ -76,8 +76,8 @@ make_dispatchset(unsigned int ndisps) { isc_sockaddr_any(&any); attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP; - result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &any, 6, - 1024, 17, 19, attrs, &disp); + result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, &any, + 6, 1024, 17, 19, attrs, &disp); if (result != ISC_R_SUCCESS) { return (result); } @@ -241,7 +241,7 @@ startit(isc_task_t *task, isc_event_t *event) { isc_result_t result; isc_socket_t *sock = NULL; - isc_socket_attach(dns_dispatch_getsocket(dispatch), &sock); + isc_socket_attach(dns_dispatch_getentrysocket(dispentry), &sock); result = isc_socket_sendto(sock, event->ev_arg, task, senddone, sock, &local, NULL); assert_int_equal(result, ISC_R_SUCCESS); @@ -274,8 +274,8 @@ dispatch_getnext(void **state) { ina.s_addr = htonl(INADDR_LOOPBACK); isc_sockaddr_fromin(&local, &ina, 0); attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP; - result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &local, 6, - 1024, 17, 19, attrs, &dispatch); + result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, &local, + 6, 1024, 17, 19, attrs, &dispatch); assert_int_equal(result, ISC_R_SUCCESS); /* @@ -299,7 +299,7 @@ dispatch_getnext(void **state) { assert_int_equal(result, ISC_R_SUCCESS); result = dns_dispatch_addresponse(dispatch, 0, &local, task, response, - NULL, &id, &dispentry, NULL); + NULL, &id, &dispentry, socketmgr); assert_int_equal(result, ISC_R_SUCCESS); memset(message, 0, sizeof(message)); diff --git a/lib/dns/tests/resolver_test.c b/lib/dns/tests/resolver_test.c index b144e09f84..5b4b7e8b81 100644 --- a/lib/dns/tests/resolver_test.c +++ b/lib/dns/tests/resolver_test.c @@ -57,8 +57,8 @@ _setup(void **state) { assert_int_equal(result, ISC_R_SUCCESS); isc_sockaddr_any(&local); - result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &local, - 100, 100, 100, 500, 0, &dispatch); + result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, &local, + 100, 100, 100, 500, 0, &dispatch); assert_int_equal(result, ISC_R_SUCCESS); return (0);