]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Remove support for shared UDP dispatch sockets
authorEvan Hunt <each@isc.org>
Wed, 16 Dec 2020 09:32:06 +0000 (01:32 -0800)
committerOndřej Surý <ondrej@sury.org>
Sat, 2 Oct 2021 08:21:43 +0000 (10:21 +0200)
Currently the netmgr doesn't support unconnected, shared UDP sockets, so
there's no reason to retain that functionality in the dispatcher prior
to porting to the netmgr.

In this commit, the DNS_DISPATCHATTR_EXCLUSIVE attribute has been
removed as it is now non-optional; UDP dispatches are alwasy exclusive.
Code implementing non-exclusive UDP dispatches has been removed.
dns_dispatch_getentrysocket() now always returns the dispsocket for UDP
dispatches and the dispatch socket for TCP dispatches.

There is no longer any need to search for existing dispatches from
dns_dispatch_getudp(), so the 'mask' option has been removed, and the
function renamed to the more descriptive dns_dispatch_createudp().

13 files changed:
bin/named/server.c
bin/nsupdate/nsupdate.c
bin/tests/system/pipelined/pipequeries.c
bin/tests/system/tkey/keycreate.c
bin/tests/system/tkey/keydelete.c
bin/tools/mdig.c
lib/dns/client.c
lib/dns/dispatch.c
lib/dns/include/dns/dispatch.h
lib/dns/request.c
lib/dns/resolver.c
lib/dns/tests/dispatch_test.c
lib/dns/tests/resolver_test.c

index 857609dd5a5fc4f0decab4aa76411a0d576becc2..57930b5040025b16038b1c77b2d8cab524489e08 100644 (file)
 #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;
        }
index bc39de6725dffe8cd7438db7ff8ad16899f7688b..ce2a48c4d094dc8c205666269ac8e3bb58a1e275 100644 (file)
@@ -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,
index f9371e7c0d45d92af5ad698917e6753a12cfb10b..e8aa99dbd16ccdee815cdf26e2f1c4cfd3a2a6b5 100644 (file)
@@ -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();
index 14fb88857bbe75a9a903063f70730b390bb51170..1b9d50089314bd7f6b0de52a11bd075f2d86d3f5 100644 (file)
@@ -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,
index 605be6ecc064cb75024045d2cdad25d4ffceba96..eabb3f0c7e9bcffee7abea04f0275f42c1624c47 100644 (file)
@@ -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,
index c07e64b03287ddd424474fb1773c11ce84f7b0d9..d379285ed76178e4155e042e851591d85bfb76ed 100644 (file)
@@ -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,
index ce2c7e325c5c31c9eb4fe2c0c0b9c27128cf0642..3547d3cc8121c7d0ea4636dc3bbc0a51eb046e47 100644 (file)
@@ -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;
        }
index 1bbff39504059e30735109e701959073a24fae60..5a3bbad8994f5bbe2b1d02d4723a61269af691f4 100644 (file)
@@ -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");
-               inc_stats(mgr, dns_resstatscounter_mismatch);
-               free_buffer(disp, ev->region.base, ev->region.length);
-               goto unlock;
-       }
-
-       if (resp == NULL) {
+       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;
+               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, &region, 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, &region, 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, &region, 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;
+       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]);
+       }
 
-               /*
-                * 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;
-                       }
-               }
+       if (isc_log_wouldlog(dns_lctx, 90)) {
+               char addrbuf[ISC_SOCKADDR_FORMATSIZE];
 
-               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]);
-               }
+               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;
index ddedac07b54f8b0f381089837254c4ba1de6dec3..e4fc0cc72753d0b095d11a1e2bf50f9ec33fdf1d 100644 (file)
@@ -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);
 /*%<
index 953023a22e02122e31628c6d23a830ae36f4a5bf..a4ca668e18936efd8ae1c3160dc092bda7e9e57b 100644 (file)
@@ -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);
index a47edf9ab2491cc291ae7a3b79a3b54e46025bba..66bebaaa6f34bc72ddb26fd0ad54fcc6f8c813cb 100644 (file)
@@ -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);
index 5bc81a2cd5636fdaa7e35c25d1727ef511f92a89..fb79fcf40b0c0ebadbe868477cd58f85fa58c0ce 100644 (file)
@@ -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));
index b144e09f846424b713de82a7aa77f4c7728dd783..5b4b7e8b81746c3f2f13e90f7d3f5630a7133dcf 100644 (file)
@@ -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);