mirror of
https://github.com/isc-projects/bind9.git
synced 2026-02-23 18:04:10 -05:00
Remove support for shared UDP dispatch sockets
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().
This commit is contained in:
parent
300392ae2f
commit
5dcf55da03
13 changed files with 235 additions and 645 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
/*%<
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue