mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 04:30:00 -04:00
[v9_9] backport performance changes from 9.10
3316. [tuning] Improved locking performance when recursing.
[RT #28836]
3315. [tuning] Use multiple dispatch objects for sending upstream
queries; this can improve performance on busy
multiprocessor systems by reducing lock contention.
[RT #28605]
This commit is contained in:
parent
76e34eb2fd
commit
7cec7ec1d2
20 changed files with 688 additions and 133 deletions
8
CHANGES
8
CHANGES
|
|
@ -97,6 +97,14 @@
|
|||
add NS RRsets to the additional section or not.
|
||||
[RT #30479]
|
||||
|
||||
3316. [tuning] Improved locking performance when recursing.
|
||||
[RT #28836]
|
||||
|
||||
3315. [tuning] Use multiple dispatch objects for sending upstream
|
||||
queries; this can improve performance on busy
|
||||
multiprocessor systems by reducing lock contention.
|
||||
[RT #28605]
|
||||
|
||||
--- 9.9.2 released ---
|
||||
|
||||
3373. [bug] win32: open raw files in binary mode. [RT #30944]
|
||||
|
|
|
|||
|
|
@ -1701,7 +1701,7 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
|
|||
ns_cache_t *nsc;
|
||||
isc_boolean_t zero_no_soattl;
|
||||
dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL;
|
||||
unsigned int query_timeout;
|
||||
unsigned int query_timeout, ndisp;
|
||||
struct cfg_context *nzctx;
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
|
@ -2228,7 +2228,9 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
|
|||
result = ISC_R_UNEXPECTED;
|
||||
goto cleanup;
|
||||
}
|
||||
CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31,
|
||||
|
||||
ndisp = 4 * ISC_MIN(ns_g_udpdisp, MAX_UDP_DISPATCH);
|
||||
CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31, ndisp,
|
||||
ns_g_socketmgr, ns_g_timermgr,
|
||||
resopts, ns_g_dispatchmgr,
|
||||
dispatch4, dispatch6));
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ create_view(void) {
|
|||
== ISC_R_SUCCESS);
|
||||
INSIST(disp6 != NULL);
|
||||
|
||||
RUNTIME_CHECK(dns_view_createresolver(view, taskmgr, 10,
|
||||
RUNTIME_CHECK(dns_view_createresolver(view, taskmgr, 10, 1,
|
||||
socketmgr,
|
||||
timermgr, 0,
|
||||
dispatchmgr,
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ main(int argc, char *argv[]) {
|
|||
INSIST(disp6 != NULL);
|
||||
}
|
||||
|
||||
RUNTIME_CHECK(dns_view_createresolver(view, taskmgr, 10,
|
||||
RUNTIME_CHECK(dns_view_createresolver(view, taskmgr, 10, 1,
|
||||
socketmgr,
|
||||
timermgr, 0,
|
||||
dispatchmgr,
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ main(int argc, char *argv[]) {
|
|||
INSIST(disp6 != NULL);
|
||||
}
|
||||
|
||||
RUNTIME_CHECK(dns_view_createresolver(view, taskmgr, 10,
|
||||
RUNTIME_CHECK(dns_view_createresolver(view, taskmgr, 10, 1,
|
||||
socketmgr,
|
||||
timermgr, 0,
|
||||
dispatchmgr,
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ make_resolver(dns_resolver_t **resolverp) {
|
|||
isc_result_t result;
|
||||
|
||||
result = dns_resolver_create(view,
|
||||
task_manager, 1,
|
||||
task_manager, 1, 1,
|
||||
socket_manager,
|
||||
timer_manager,
|
||||
0, /* unsigned int options, */
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ dns_client_createview(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|||
return (result);
|
||||
}
|
||||
|
||||
result = dns_view_createresolver(view, taskmgr, ntasks, socketmgr,
|
||||
result = dns_view_createresolver(view, taskmgr, ntasks, 1, socketmgr,
|
||||
timermgr, 0, dispatchmgr,
|
||||
dispatchv4, dispatchv6);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <isc/portset.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/random.h>
|
||||
#include <isc/socket.h>
|
||||
#include <isc/stats.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/task.h>
|
||||
|
|
@ -101,12 +102,16 @@ struct dns_dispatchmgr {
|
|||
unsigned int maxbuffers; /*%< max buffers */
|
||||
|
||||
/* Locked internally. */
|
||||
isc_mutex_t pool_lock;
|
||||
isc_mempool_t *epool; /*%< memory pool for events */
|
||||
isc_mempool_t *rpool; /*%< memory pool for replies */
|
||||
isc_mutex_t depool_lock;
|
||||
isc_mempool_t *depool; /*%< pool for dispatch events */
|
||||
isc_mutex_t rpool_lock;
|
||||
isc_mempool_t *rpool; /*%< pool for replies */
|
||||
isc_mutex_t dpool_lock;
|
||||
isc_mempool_t *dpool; /*%< dispatch allocations */
|
||||
isc_mempool_t *bpool; /*%< memory pool for buffers */
|
||||
isc_mempool_t *spool; /*%< memory pool for dispsocs */
|
||||
isc_mutex_t bpool_lock;
|
||||
isc_mempool_t *bpool; /*%< pool for buffers */
|
||||
isc_mutex_t spool_lock;
|
||||
isc_mempool_t *spool; /*%< pool for dispsocks */
|
||||
|
||||
/*%
|
||||
* Locked by qid->lock if qid exists; otherwise, can be used without
|
||||
|
|
@ -226,6 +231,9 @@ struct dns_dispatch {
|
|||
unsigned int maxrequests; /*%< max requests */
|
||||
isc_event_t *ctlevent;
|
||||
|
||||
isc_mutex_t sepool_lock;
|
||||
isc_mempool_t *sepool; /*%< pool for socket events */
|
||||
|
||||
/*% Locked by mgr->lock. */
|
||||
ISC_LINK(dns_dispatch_t) link;
|
||||
|
||||
|
|
@ -301,8 +309,8 @@ static isc_uint32_t dns_hash(dns_qid_t *, isc_sockaddr_t *, dns_messageid_t,
|
|||
in_port_t);
|
||||
static void free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len);
|
||||
static void *allocate_udp_buffer(dns_dispatch_t *disp);
|
||||
static inline void free_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev);
|
||||
static inline dns_dispatchevent_t *allocate_event(dns_dispatch_t *disp);
|
||||
static inline void free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev);
|
||||
static inline dns_dispatchevent_t *allocate_devent(dns_dispatch_t *disp);
|
||||
static void do_cancel(dns_dispatch_t *disp);
|
||||
static dns_dispentry_t *linear_first(dns_qid_t *disp);
|
||||
static dns_dispentry_t *linear_next(dns_qid_t *disp,
|
||||
|
|
@ -723,6 +731,11 @@ destroy_disp(isc_task_t *task, isc_event_t *event) {
|
|||
"shutting down; detaching from sock %p, task %p",
|
||||
disp->socket, disp->task[0]); /* XXXX */
|
||||
|
||||
if (disp->sepool != NULL) {
|
||||
isc_mempool_destroy(&disp->sepool);
|
||||
isc_mutex_destroy(&disp->sepool_lock);
|
||||
}
|
||||
|
||||
if (disp->socket != NULL)
|
||||
isc_socket_detach(&disp->socket);
|
||||
while ((dispsocket = ISC_LIST_HEAD(disp->inactivesockets)) != NULL) {
|
||||
|
|
@ -787,6 +800,7 @@ new_portentry(dns_dispatch_t *disp, in_port_t port) {
|
|||
static void
|
||||
deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
|
||||
dispportentry_t *portentry = *portentryp;
|
||||
isc_boolean_t unlink = ISC_FALSE;
|
||||
dns_qid_t *qid;
|
||||
|
||||
REQUIRE(disp->port_table != NULL);
|
||||
|
|
@ -795,7 +809,10 @@ deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
|
|||
qid = DNS_QID(disp);
|
||||
LOCK(&qid->lock);
|
||||
portentry->refs--;
|
||||
if (portentry->refs == 0) {
|
||||
unlink = ISC_TF(portentry->refs == 0);
|
||||
UNLOCK(&qid->lock);
|
||||
|
||||
if (unlink) {
|
||||
ISC_LIST_UNLINK(disp->port_table[portentry->port %
|
||||
DNS_DISPATCH_PORTTABLESIZE],
|
||||
portentry, link);
|
||||
|
|
@ -803,7 +820,6 @@ deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
|
|||
}
|
||||
|
||||
*portentryp = NULL;
|
||||
UNLOCK(&qid->lock);
|
||||
}
|
||||
|
||||
/*%
|
||||
|
|
@ -833,12 +849,12 @@ socket_search(dns_qid_t *qid, isc_sockaddr_t *dest, in_port_t port,
|
|||
|
||||
/*%
|
||||
* Make a new socket for a single dispatch with a random port number.
|
||||
* The caller must hold the disp->lock and qid->lock.
|
||||
* The caller must hold the disp->lock
|
||||
*/
|
||||
static isc_result_t
|
||||
get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest,
|
||||
isc_socketmgr_t *sockmgr, dns_qid_t *qid,
|
||||
dispsocket_t **dispsockp, in_port_t *portp)
|
||||
isc_socketmgr_t *sockmgr, dispsocket_t **dispsockp,
|
||||
in_port_t *portp)
|
||||
{
|
||||
int i;
|
||||
isc_uint32_t r;
|
||||
|
|
@ -853,6 +869,7 @@ get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest,
|
|||
in_port_t *ports;
|
||||
unsigned int bindoptions;
|
||||
dispportentry_t *portentry = NULL;
|
||||
dns_qid_t *qid;
|
||||
|
||||
if (isc_sockaddr_pf(&disp->local) == AF_INET) {
|
||||
nports = disp->mgr->nv4ports;
|
||||
|
|
@ -893,16 +910,23 @@ get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest,
|
|||
* very likely to fail in bind(2) or connect(2).
|
||||
*/
|
||||
localaddr = disp->local;
|
||||
qid = DNS_QID(disp);
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
port = ports[dispatch_uniformrandom(DISP_ARC4CTX(disp),
|
||||
nports)];
|
||||
isc_sockaddr_setport(&localaddr, port);
|
||||
|
||||
LOCK(&qid->lock);
|
||||
bucket = dns_hash(qid, dest, 0, port);
|
||||
if (socket_search(qid, dest, port, bucket) != NULL)
|
||||
if (socket_search(qid, dest, port, bucket) != NULL) {
|
||||
UNLOCK(&qid->lock);
|
||||
continue;
|
||||
}
|
||||
UNLOCK(&qid->lock);
|
||||
bindoptions = 0;
|
||||
portentry = port_search(disp, port);
|
||||
|
||||
if (portentry != NULL)
|
||||
bindoptions |= ISC_SOCKET_REUSEADDRESS;
|
||||
result = open_socket(sockmgr, &localaddr, bindoptions, &sock,
|
||||
|
|
@ -932,7 +956,9 @@ get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest,
|
|||
dispsock->host = *dest;
|
||||
dispsock->portentry = portentry;
|
||||
dispsock->bucket = bucket;
|
||||
LOCK(&qid->lock);
|
||||
ISC_LIST_APPEND(qid->sock_table[bucket], dispsock, blink);
|
||||
UNLOCK(&qid->lock);
|
||||
*dispsockp = dispsock;
|
||||
*portp = port;
|
||||
} else {
|
||||
|
|
@ -1067,6 +1093,7 @@ entry_search(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id,
|
|||
|
||||
static void
|
||||
free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
|
||||
isc_mempool_t *bpool;
|
||||
INSIST(buf != NULL && len != 0);
|
||||
|
||||
|
||||
|
|
@ -1081,8 +1108,9 @@ free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
|
|||
INSIST(disp->mgr->buffers > 0);
|
||||
INSIST(len == disp->mgr->buffersize);
|
||||
disp->mgr->buffers--;
|
||||
isc_mempool_put(disp->mgr->bpool, buf);
|
||||
bpool = disp->mgr->bpool;
|
||||
UNLOCK(&disp->mgr->buffer_lock);
|
||||
isc_mempool_put(bpool, buf);
|
||||
break;
|
||||
default:
|
||||
INSIST(0);
|
||||
|
|
@ -1092,20 +1120,60 @@ free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
|
|||
|
||||
static void *
|
||||
allocate_udp_buffer(dns_dispatch_t *disp) {
|
||||
isc_mempool_t *bpool;
|
||||
void *temp;
|
||||
|
||||
LOCK(&disp->mgr->buffer_lock);
|
||||
temp = isc_mempool_get(disp->mgr->bpool);
|
||||
|
||||
if (temp != NULL)
|
||||
disp->mgr->buffers++;
|
||||
bpool = disp->mgr->bpool;
|
||||
disp->mgr->buffers++;
|
||||
UNLOCK(&disp->mgr->buffer_lock);
|
||||
|
||||
temp = isc_mempool_get(bpool);
|
||||
|
||||
if (temp == NULL) {
|
||||
LOCK(&disp->mgr->buffer_lock);
|
||||
disp->mgr->buffers--;
|
||||
UNLOCK(&disp->mgr->buffer_lock);
|
||||
}
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
static inline void
|
||||
free_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev) {
|
||||
free_sevent(isc_event_t *ev) {
|
||||
isc_mempool_t *pool = ev->ev_destroy_arg;
|
||||
isc_socketevent_t *sev = (isc_socketevent_t *) ev;
|
||||
isc_mempool_put(pool, sev);
|
||||
}
|
||||
|
||||
static inline isc_socketevent_t *
|
||||
allocate_sevent(dns_dispatch_t *disp, isc_socket_t *socket,
|
||||
isc_eventtype_t type, isc_taskaction_t action, const void *arg)
|
||||
{
|
||||
isc_socketevent_t *ev;
|
||||
void *deconst_arg;
|
||||
|
||||
ev = isc_mempool_get(disp->sepool);
|
||||
if (ev == NULL)
|
||||
return (NULL);
|
||||
DE_CONST(arg, deconst_arg);
|
||||
ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, type,
|
||||
action, deconst_arg, socket,
|
||||
free_sevent, disp->sepool);
|
||||
ev->result = ISC_R_UNSET;
|
||||
ISC_LINK_INIT(ev, ev_link);
|
||||
ISC_LIST_INIT(ev->bufferlist);
|
||||
ev->region.base = NULL;
|
||||
ev->n = 0;
|
||||
ev->offset = 0;
|
||||
ev->attributes = 0;
|
||||
|
||||
return (ev);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev) {
|
||||
if (disp->failsafe_ev == ev) {
|
||||
INSIST(disp->shutdown_out == 1);
|
||||
disp->shutdown_out = 0;
|
||||
|
|
@ -1113,14 +1181,14 @@ free_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev) {
|
|||
return;
|
||||
}
|
||||
|
||||
isc_mempool_put(disp->mgr->epool, ev);
|
||||
isc_mempool_put(disp->mgr->depool, ev);
|
||||
}
|
||||
|
||||
static inline dns_dispatchevent_t *
|
||||
allocate_event(dns_dispatch_t *disp) {
|
||||
allocate_devent(dns_dispatch_t *disp) {
|
||||
dns_dispatchevent_t *ev;
|
||||
|
||||
ev = isc_mempool_get(disp->mgr->epool);
|
||||
ev = isc_mempool_get(disp->mgr->depool);
|
||||
if (ev == NULL)
|
||||
return (NULL);
|
||||
ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, 0,
|
||||
|
|
@ -1385,7 +1453,7 @@ udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) {
|
|||
|
||||
sendresponse:
|
||||
queue_response = resp->item_out;
|
||||
rev = allocate_event(resp->disp);
|
||||
rev = allocate_devent(resp->disp);
|
||||
if (rev == NULL) {
|
||||
free_buffer(disp, ev->region.base, ev->region.length);
|
||||
goto unlock;
|
||||
|
|
@ -1583,7 +1651,7 @@ tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
|
|||
if (resp == NULL)
|
||||
goto unlock;
|
||||
queue_response = resp->item_out;
|
||||
rev = allocate_event(disp);
|
||||
rev = allocate_devent(disp);
|
||||
if (rev == NULL)
|
||||
goto unlock;
|
||||
|
||||
|
|
@ -1664,16 +1732,33 @@ startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) {
|
|||
if (region.base == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
if (dispsock != NULL) {
|
||||
res = isc_socket_recv(socket, ®ion, 1,
|
||||
dispsock->task, udp_exrecv,
|
||||
dispsock);
|
||||
isc_task_t *dt = dispsock->task;
|
||||
isc_socketevent_t *sev =
|
||||
allocate_sevent(disp, socket,
|
||||
ISC_SOCKEVENT_RECVDONE,
|
||||
udp_exrecv, dispsock);
|
||||
if (sev == NULL) {
|
||||
free_buffer(disp, region.base, region.length);
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
|
||||
res = isc_socket_recv2(socket, ®ion, 1, dt, sev, 0);
|
||||
if (res != ISC_R_SUCCESS) {
|
||||
free_buffer(disp, region.base, region.length);
|
||||
return (res);
|
||||
}
|
||||
} else {
|
||||
res = isc_socket_recv(socket, ®ion, 1,
|
||||
disp->task[0], udp_shrecv, disp);
|
||||
isc_task_t *dt = disp->task[0];
|
||||
isc_socketevent_t *sev =
|
||||
allocate_sevent(disp, socket,
|
||||
ISC_SOCKEVENT_RECVDONE,
|
||||
udp_shrecv, disp);
|
||||
if (sev == NULL) {
|
||||
free_buffer(disp, region.base, region.length);
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
|
||||
res = isc_socket_recv2(socket, ®ion, 1, dt, sev, 0);
|
||||
if (res != ISC_R_SUCCESS) {
|
||||
free_buffer(disp, region.base, region.length);
|
||||
disp->shutdown_why = res;
|
||||
|
|
@ -1713,16 +1798,16 @@ static isc_boolean_t
|
|||
destroy_mgr_ok(dns_dispatchmgr_t *mgr) {
|
||||
mgr_log(mgr, LVL(90),
|
||||
"destroy_mgr_ok: shuttingdown=%d, listnonempty=%d, "
|
||||
"epool=%d, rpool=%d, dpool=%d",
|
||||
"depool=%d, rpool=%d, dpool=%d",
|
||||
MGR_IS_SHUTTINGDOWN(mgr), !ISC_LIST_EMPTY(mgr->list),
|
||||
isc_mempool_getallocated(mgr->epool),
|
||||
isc_mempool_getallocated(mgr->depool),
|
||||
isc_mempool_getallocated(mgr->rpool),
|
||||
isc_mempool_getallocated(mgr->dpool));
|
||||
if (!MGR_IS_SHUTTINGDOWN(mgr))
|
||||
return (ISC_FALSE);
|
||||
if (!ISC_LIST_EMPTY(mgr->list))
|
||||
return (ISC_FALSE);
|
||||
if (isc_mempool_getallocated(mgr->epool) != 0)
|
||||
if (isc_mempool_getallocated(mgr->depool) != 0)
|
||||
return (ISC_FALSE);
|
||||
if (isc_mempool_getallocated(mgr->rpool) != 0)
|
||||
return (ISC_FALSE);
|
||||
|
|
@ -1752,7 +1837,7 @@ destroy_mgr(dns_dispatchmgr_t **mgrp) {
|
|||
|
||||
DESTROYLOCK(&mgr->arc4_lock);
|
||||
|
||||
isc_mempool_destroy(&mgr->epool);
|
||||
isc_mempool_destroy(&mgr->depool);
|
||||
isc_mempool_destroy(&mgr->rpool);
|
||||
isc_mempool_destroy(&mgr->dpool);
|
||||
if (mgr->bpool != NULL)
|
||||
|
|
@ -1760,7 +1845,11 @@ destroy_mgr(dns_dispatchmgr_t **mgrp) {
|
|||
if (mgr->spool != NULL)
|
||||
isc_mempool_destroy(&mgr->spool);
|
||||
|
||||
DESTROYLOCK(&mgr->pool_lock);
|
||||
DESTROYLOCK(&mgr->spool_lock);
|
||||
DESTROYLOCK(&mgr->bpool_lock);
|
||||
DESTROYLOCK(&mgr->dpool_lock);
|
||||
DESTROYLOCK(&mgr->rpool_lock);
|
||||
DESTROYLOCK(&mgr->depool_lock);
|
||||
|
||||
#ifdef BIND9
|
||||
if (mgr->entropy != NULL)
|
||||
|
|
@ -1900,22 +1989,38 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
|
|||
if (result != ISC_R_SUCCESS)
|
||||
goto kill_arc4_lock;
|
||||
|
||||
result = isc_mutex_init(&mgr->pool_lock);
|
||||
result = isc_mutex_init(&mgr->depool_lock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto kill_buffer_lock;
|
||||
|
||||
mgr->epool = NULL;
|
||||
result = isc_mutex_init(&mgr->rpool_lock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto kill_depool_lock;
|
||||
|
||||
result = isc_mutex_init(&mgr->dpool_lock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto kill_rpool_lock;
|
||||
|
||||
result = isc_mutex_init(&mgr->bpool_lock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto kill_dpool_lock;
|
||||
|
||||
result = isc_mutex_init(&mgr->spool_lock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto kill_bpool_lock;
|
||||
|
||||
mgr->depool = NULL;
|
||||
if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatchevent_t),
|
||||
&mgr->epool) != ISC_R_SUCCESS) {
|
||||
&mgr->depool) != ISC_R_SUCCESS) {
|
||||
result = ISC_R_NOMEMORY;
|
||||
goto kill_pool_lock;
|
||||
goto kill_spool_lock;
|
||||
}
|
||||
|
||||
mgr->rpool = NULL;
|
||||
if (isc_mempool_create(mgr->mctx, sizeof(dns_dispentry_t),
|
||||
&mgr->rpool) != ISC_R_SUCCESS) {
|
||||
result = ISC_R_NOMEMORY;
|
||||
goto kill_epool;
|
||||
goto kill_depool;
|
||||
}
|
||||
|
||||
mgr->dpool = NULL;
|
||||
|
|
@ -1925,17 +2030,23 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
|
|||
goto kill_rpool;
|
||||
}
|
||||
|
||||
isc_mempool_setname(mgr->epool, "dispmgr_epool");
|
||||
isc_mempool_setfreemax(mgr->epool, 1024);
|
||||
isc_mempool_associatelock(mgr->epool, &mgr->pool_lock);
|
||||
isc_mempool_setname(mgr->depool, "dispmgr_depool");
|
||||
isc_mempool_setmaxalloc(mgr->depool, 32768);
|
||||
isc_mempool_setfreemax(mgr->depool, 32768);
|
||||
isc_mempool_associatelock(mgr->depool, &mgr->depool_lock);
|
||||
isc_mempool_setfillcount(mgr->depool, 256);
|
||||
|
||||
isc_mempool_setname(mgr->rpool, "dispmgr_rpool");
|
||||
isc_mempool_setfreemax(mgr->rpool, 1024);
|
||||
isc_mempool_associatelock(mgr->rpool, &mgr->pool_lock);
|
||||
isc_mempool_setmaxalloc(mgr->rpool, 32768);
|
||||
isc_mempool_setfreemax(mgr->rpool, 32768);
|
||||
isc_mempool_associatelock(mgr->rpool, &mgr->rpool_lock);
|
||||
isc_mempool_setfillcount(mgr->rpool, 256);
|
||||
|
||||
isc_mempool_setname(mgr->dpool, "dispmgr_dpool");
|
||||
isc_mempool_setfreemax(mgr->dpool, 1024);
|
||||
isc_mempool_associatelock(mgr->dpool, &mgr->pool_lock);
|
||||
isc_mempool_setmaxalloc(mgr->dpool, 32768);
|
||||
isc_mempool_setfreemax(mgr->dpool, 32768);
|
||||
isc_mempool_associatelock(mgr->dpool, &mgr->dpool_lock);
|
||||
isc_mempool_setfillcount(mgr->dpool, 256);
|
||||
|
||||
mgr->buffers = 0;
|
||||
mgr->buffersize = 0;
|
||||
|
|
@ -1984,10 +2095,18 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
|
|||
isc_mempool_destroy(&mgr->dpool);
|
||||
kill_rpool:
|
||||
isc_mempool_destroy(&mgr->rpool);
|
||||
kill_epool:
|
||||
isc_mempool_destroy(&mgr->epool);
|
||||
kill_pool_lock:
|
||||
DESTROYLOCK(&mgr->pool_lock);
|
||||
kill_depool:
|
||||
isc_mempool_destroy(&mgr->depool);
|
||||
kill_spool_lock:
|
||||
DESTROYLOCK(&mgr->spool_lock);
|
||||
kill_bpool_lock:
|
||||
DESTROYLOCK(&mgr->bpool_lock);
|
||||
kill_dpool_lock:
|
||||
DESTROYLOCK(&mgr->dpool_lock);
|
||||
kill_rpool_lock:
|
||||
DESTROYLOCK(&mgr->rpool_lock);
|
||||
kill_depool_lock:
|
||||
DESTROYLOCK(&mgr->depool_lock);
|
||||
kill_buffer_lock:
|
||||
DESTROYLOCK(&mgr->buffer_lock);
|
||||
kill_arc4_lock:
|
||||
|
|
@ -2141,6 +2260,7 @@ dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr,
|
|||
*/
|
||||
if (maxbuffers > mgr->maxbuffers) {
|
||||
isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
|
||||
isc_mempool_setfreemax(mgr->bpool, maxbuffers);
|
||||
mgr->maxbuffers = maxbuffers;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -2151,12 +2271,16 @@ dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr,
|
|||
}
|
||||
isc_mempool_setname(mgr->bpool, "dispmgr_bpool");
|
||||
isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
|
||||
isc_mempool_associatelock(mgr->bpool, &mgr->pool_lock);
|
||||
isc_mempool_setfreemax(mgr->bpool, maxbuffers);
|
||||
isc_mempool_associatelock(mgr->bpool, &mgr->bpool_lock);
|
||||
isc_mempool_setfillcount(mgr->bpool, 256);
|
||||
}
|
||||
|
||||
/* Create or adjust socket pool */
|
||||
if (mgr->spool != NULL) {
|
||||
isc_mempool_setmaxalloc(mgr->spool, DNS_DISPATCH_POOLSOCKS * 2);
|
||||
if (maxrequests < DNS_DISPATCH_POOLSOCKS * 2)
|
||||
isc_mempool_setmaxalloc(mgr->spool, DNS_DISPATCH_POOLSOCKS * 2);
|
||||
isc_mempool_setfreemax(mgr->spool, DNS_DISPATCH_POOLSOCKS * 2);
|
||||
UNLOCK(&mgr->buffer_lock);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
|
@ -2168,7 +2292,9 @@ dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr,
|
|||
}
|
||||
isc_mempool_setname(mgr->spool, "dispmgr_spool");
|
||||
isc_mempool_setmaxalloc(mgr->spool, maxrequests);
|
||||
isc_mempool_associatelock(mgr->spool, &mgr->pool_lock);
|
||||
isc_mempool_setfreemax(mgr->spool, maxrequests);
|
||||
isc_mempool_associatelock(mgr->spool, &mgr->spool_lock);
|
||||
isc_mempool_setfillcount(mgr->spool, 256);
|
||||
|
||||
result = qid_allocate(mgr, buckets, increment, &mgr->qid, ISC_TRUE);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
|
|
@ -2494,7 +2620,7 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,
|
|||
if (result != ISC_R_SUCCESS)
|
||||
goto deallocate;
|
||||
|
||||
disp->failsafe_ev = allocate_event(disp);
|
||||
disp->failsafe_ev = allocate_devent(disp);
|
||||
if (disp->failsafe_ev == NULL) {
|
||||
result = ISC_R_NOMEMORY;
|
||||
goto kill_lock;
|
||||
|
|
@ -2545,7 +2671,7 @@ dispatch_free(dns_dispatch_t **dispp)
|
|||
INSIST(ISC_LIST_EMPTY(disp->activesockets));
|
||||
INSIST(ISC_LIST_EMPTY(disp->inactivesockets));
|
||||
|
||||
isc_mempool_put(mgr->epool, disp->failsafe_ev);
|
||||
isc_mempool_put(mgr->depool, disp->failsafe_ev);
|
||||
disp->failsafe_ev = NULL;
|
||||
|
||||
if (disp->qid != NULL)
|
||||
|
|
@ -2609,6 +2735,8 @@ 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, 0, &disp->task[0]);
|
||||
|
|
@ -2972,6 +3100,24 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
|||
goto kill_task;
|
||||
}
|
||||
|
||||
disp->sepool = NULL;
|
||||
if (isc_mempool_create(mgr->mctx, sizeof(isc_socketevent_t),
|
||||
&disp->sepool) != ISC_R_SUCCESS)
|
||||
{
|
||||
result = ISC_R_NOMEMORY;
|
||||
goto kill_ctlevent;
|
||||
}
|
||||
|
||||
result = isc_mutex_init(&disp->sepool_lock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto kill_sepool;
|
||||
|
||||
isc_mempool_setname(disp->sepool, "disp_sepool");
|
||||
isc_mempool_setmaxalloc(disp->sepool, 32768);
|
||||
isc_mempool_setfreemax(disp->sepool, 32768);
|
||||
isc_mempool_associatelock(disp->sepool, &disp->sepool_lock);
|
||||
isc_mempool_setfillcount(disp->sepool, 16);
|
||||
|
||||
attributes &= ~DNS_DISPATCHATTR_TCP;
|
||||
attributes |= DNS_DISPATCHATTR_UDP;
|
||||
disp->attributes = attributes;
|
||||
|
|
@ -2993,6 +3139,10 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
|||
/*
|
||||
* Error returns.
|
||||
*/
|
||||
kill_sepool:
|
||||
isc_mempool_destroy(&disp->sepool);
|
||||
kill_ctlevent:
|
||||
isc_event_free(&disp->ctlevent);
|
||||
kill_task:
|
||||
for (i = 0; i < disp->ntasks; i++)
|
||||
isc_task_detach(&disp->task[i]);
|
||||
|
|
@ -3109,7 +3259,7 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
|
|||
oldestsocket = ISC_LIST_HEAD(disp->activesockets);
|
||||
oldestresp = oldestsocket->resp;
|
||||
if (oldestresp != NULL && !oldestresp->item_out) {
|
||||
rev = allocate_event(oldestresp->disp);
|
||||
rev = allocate_devent(oldestresp->disp);
|
||||
if (rev != NULL) {
|
||||
rev->buffer.base = NULL;
|
||||
rev->result = ISC_R_CANCELED;
|
||||
|
|
@ -3136,16 +3286,14 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
|
|||
}
|
||||
|
||||
qid = DNS_QID(disp);
|
||||
LOCK(&qid->lock);
|
||||
|
||||
if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
|
||||
/*
|
||||
* Get a separate UDP socket with a random port number.
|
||||
*/
|
||||
result = get_dispsocket(disp, dest, sockmgr, qid, &dispsocket,
|
||||
result = get_dispsocket(disp, dest, sockmgr, &dispsocket,
|
||||
&localport);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
UNLOCK(&qid->lock);
|
||||
UNLOCK(&disp->lock);
|
||||
inc_stats(disp->mgr, dns_resstatscounter_dispsockfail);
|
||||
return (result);
|
||||
|
|
@ -3157,6 +3305,7 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
|
|||
/*
|
||||
* Try somewhat hard to find an unique ID.
|
||||
*/
|
||||
LOCK(&qid->lock);
|
||||
id = (dns_messageid_t)dispatch_random(DISP_ARC4CTX(disp));
|
||||
bucket = dns_hash(qid, dest, id, localport);
|
||||
ok = ISC_FALSE;
|
||||
|
|
@ -3169,16 +3318,15 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
|
|||
id &= 0x0000ffff;
|
||||
bucket = dns_hash(qid, dest, id, localport);
|
||||
}
|
||||
UNLOCK(&qid->lock);
|
||||
|
||||
if (!ok) {
|
||||
UNLOCK(&qid->lock);
|
||||
UNLOCK(&disp->lock);
|
||||
return (ISC_R_NOMORE);
|
||||
}
|
||||
|
||||
res = isc_mempool_get(disp->mgr->rpool);
|
||||
if (res == NULL) {
|
||||
UNLOCK(&qid->lock);
|
||||
UNLOCK(&disp->lock);
|
||||
if (dispsocket != NULL)
|
||||
destroy_dispsocket(disp, &dispsocket);
|
||||
|
|
@ -3203,6 +3351,8 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
|
|||
ISC_LIST_INIT(res->items);
|
||||
ISC_LINK_INIT(res, link);
|
||||
res->magic = RESPONSE_MAGIC;
|
||||
|
||||
LOCK(&qid->lock);
|
||||
ISC_LIST_APPEND(qid->qid_table[bucket], res, link);
|
||||
UNLOCK(&qid->lock);
|
||||
|
||||
|
|
@ -3350,7 +3500,7 @@ dns_dispatch_removeresponse(dns_dispentry_t **resp,
|
|||
res->item_out = ISC_FALSE;
|
||||
if (ev->buffer.base != NULL)
|
||||
free_buffer(disp, ev->buffer.base, ev->buffer.length);
|
||||
free_event(disp, ev);
|
||||
free_devent(disp, ev);
|
||||
}
|
||||
|
||||
request_log(disp, res, LVL(90), "detaching from task %p", res->task);
|
||||
|
|
@ -3370,7 +3520,7 @@ dns_dispatch_removeresponse(dns_dispentry_t **resp,
|
|||
ISC_LIST_UNLINK(res->items, ev, ev_link);
|
||||
if (ev->buffer.base != NULL)
|
||||
free_buffer(disp, ev->buffer.base, ev->buffer.length);
|
||||
free_event(disp, ev);
|
||||
free_devent(disp, ev);
|
||||
ev = ISC_LIST_HEAD(res->items);
|
||||
}
|
||||
res->magic = 0;
|
||||
|
|
@ -3567,6 +3717,128 @@ dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event) {
|
|||
isc_task_send(disp->task[0], ISC_EVENT_PTR(&newsevent));
|
||||
}
|
||||
|
||||
dns_dispatch_t *
|
||||
dns_dispatchset_get(dns_dispatchset_t *dset) {
|
||||
dns_dispatch_t *disp;
|
||||
|
||||
/* check that dispatch set is configured */
|
||||
if (dset == NULL || dset->ndisp == 0)
|
||||
return (NULL);
|
||||
|
||||
LOCK(&dset->lock);
|
||||
disp = dset->dispatches[dset->cur];
|
||||
dset->cur++;
|
||||
if (dset->cur == dset->ndisp)
|
||||
dset->cur = 0;
|
||||
UNLOCK(&dset->lock);
|
||||
|
||||
return (disp);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr,
|
||||
isc_taskmgr_t *taskmgr, dns_dispatch_t *source,
|
||||
dns_dispatchset_t **dsetp, int n)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_dispatchset_t *dset;
|
||||
dns_dispatchmgr_t *mgr;
|
||||
int i, j;
|
||||
|
||||
REQUIRE(VALID_DISPATCH(source));
|
||||
REQUIRE((source->attributes & DNS_DISPATCHATTR_UDP) != 0);
|
||||
REQUIRE(dsetp != NULL && *dsetp == NULL);
|
||||
|
||||
mgr = source->mgr;
|
||||
|
||||
dset = isc_mem_get(mctx, sizeof(dns_dispatchset_t));
|
||||
if (dset == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
memset(dset, 0, sizeof(*dset));
|
||||
|
||||
result = isc_mutex_init(&dset->lock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto fail_alloc;
|
||||
|
||||
dset->dispatches = isc_mem_get(mctx, sizeof(dns_dispatch_t *) * n);
|
||||
if (dset == NULL) {
|
||||
result = ISC_R_NOMEMORY;
|
||||
goto fail_lock;
|
||||
}
|
||||
|
||||
isc_mem_attach(mctx, &dset->mctx);
|
||||
dset->ndisp = n;
|
||||
dset->cur = 0;
|
||||
|
||||
dset->dispatches[0] = NULL;
|
||||
dns_dispatch_attach(source, &dset->dispatches[0]);
|
||||
|
||||
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);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
UNLOCK(&mgr->lock);
|
||||
*dsetp = dset;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
fail:
|
||||
UNLOCK(&mgr->lock);
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
dns_dispatch_detach(&(dset->dispatches[j]));
|
||||
isc_mem_put(mctx, dset->dispatches, sizeof(dns_dispatch_t *) * n);
|
||||
if (dset->mctx == mctx)
|
||||
isc_mem_detach(&dset->mctx);
|
||||
|
||||
fail_lock:
|
||||
DESTROYLOCK(&dset->lock);
|
||||
|
||||
fail_alloc:
|
||||
isc_mem_put(mctx, dset, sizeof(dns_dispatchset_t));
|
||||
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;
|
||||
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;
|
||||
int i;
|
||||
|
||||
REQUIRE(dsetp != NULL && *dsetp != NULL);
|
||||
|
||||
dset = *dsetp;
|
||||
for (i = 0; i < dset->ndisp; i++)
|
||||
dns_dispatch_detach(&(dset->dispatches[i]));
|
||||
isc_mem_put(dset->mctx, dset->dispatches,
|
||||
sizeof(dns_dispatch_t *) * dset->ndisp);
|
||||
DESTROYLOCK(&dset->lock);
|
||||
isc_mem_putanddetach(&dset->mctx, dset, sizeof(dns_dispatchset_t));
|
||||
|
||||
*dsetp = NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
dns_dispatchmgr_dump(dns_dispatchmgr_t *mgr) {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/lang.h>
|
||||
#include <isc/mutex.h>
|
||||
#include <isc/socket.h>
|
||||
#include <isc/types.h>
|
||||
|
||||
|
|
@ -88,6 +89,18 @@ struct dns_dispatchevent {
|
|||
isc_uint32_t attributes; /*%< mirrored from socket.h */
|
||||
};
|
||||
|
||||
/*%
|
||||
* This is a set of one or more dispatches which can be retrieved
|
||||
* round-robin fashion.
|
||||
*/
|
||||
struct dns_dispatchset {
|
||||
isc_mem_t *mctx;
|
||||
dns_dispatch_t **dispatches;
|
||||
int ndisp;
|
||||
int cur;
|
||||
isc_mutex_t lock;
|
||||
};
|
||||
|
||||
/*@{*/
|
||||
/*%
|
||||
* Attributes for added dispatchers.
|
||||
|
|
@ -505,6 +518,46 @@ dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event);
|
|||
* event != NULL
|
||||
*/
|
||||
|
||||
dns_dispatch_t *
|
||||
dns_dispatchset_get(dns_dispatchset_t *dset);
|
||||
/*%<
|
||||
* Retrieve the next dispatch from dispatch set 'dset', and increment
|
||||
* the round-robin counter.
|
||||
*
|
||||
* Requires:
|
||||
*\li dset != NULL
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr,
|
||||
isc_taskmgr_t *taskmgr, dns_dispatch_t *source,
|
||||
dns_dispatchset_t **dsetp, int n);
|
||||
/*%<
|
||||
* Given a valid dispatch 'source', create a dispatch set containing
|
||||
* 'n' UDP dispatches, with the remainder filled out by clones of the
|
||||
* source.
|
||||
*
|
||||
* Requires:
|
||||
*\li source is a valid UDP dispatcher
|
||||
*\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);
|
||||
/*%<
|
||||
* Dereference all the dispatches in '*dsetp', free the dispatchset
|
||||
* memory, and set *dsetp to NULL.
|
||||
*
|
||||
* Requires:
|
||||
*\li dset is valid
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_DISPATCH_H */
|
||||
|
|
|
|||
|
|
@ -126,7 +126,8 @@ typedef struct dns_fetchevent {
|
|||
|
||||
isc_result_t
|
||||
dns_resolver_create(dns_view_t *view,
|
||||
isc_taskmgr_t *taskmgr, unsigned int ntasks,
|
||||
isc_taskmgr_t *taskmgr,
|
||||
unsigned int ntasks, unsigned int ndisp,
|
||||
isc_socketmgr_t *socketmgr,
|
||||
isc_timermgr_t *timermgr,
|
||||
unsigned int options,
|
||||
|
|
@ -155,9 +156,11 @@ dns_resolver_create(dns_view_t *view,
|
|||
*
|
||||
*\li 'timermgr' is a valid timer manager.
|
||||
*
|
||||
*\li 'dispatchv4' is a valid dispatcher with an IPv4 UDP socket, or is NULL.
|
||||
*\li 'dispatchv4' is a dispatch with an IPv4 UDP socket, or is NULL.
|
||||
* If not NULL, 'ndisp' clones of it will be created by the resolver.
|
||||
*
|
||||
*\li 'dispatchv6' is a valid dispatcher with an IPv6 UDP socket, or is NULL.
|
||||
*\li 'dispatchv6' is a dispatch with an IPv6 UDP socket, or is NULL.
|
||||
* If not NULL, 'ndisp' clones of it will be created by the resolver.
|
||||
*
|
||||
*\li resp != NULL && *resp == NULL.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ typedef struct dns_decompress dns_decompress_t;
|
|||
typedef struct dns_dispatch dns_dispatch_t;
|
||||
typedef struct dns_dispatchevent dns_dispatchevent_t;
|
||||
typedef struct dns_dispatchlist dns_dispatchlist_t;
|
||||
typedef struct dns_dispatchset dns_dispatchset_t;
|
||||
typedef struct dns_dispatchmgr dns_dispatchmgr_t;
|
||||
typedef struct dns_dispentry dns_dispentry_t;
|
||||
typedef struct dns_dns64 dns_dns64_t;
|
||||
|
|
|
|||
|
|
@ -313,7 +313,8 @@ dns_view_weakdetach(dns_view_t **targetp);
|
|||
|
||||
isc_result_t
|
||||
dns_view_createresolver(dns_view_t *view,
|
||||
isc_taskmgr_t *taskmgr, unsigned int ntasks,
|
||||
isc_taskmgr_t *taskmgr,
|
||||
unsigned int ntasks, unsigned int ndisp,
|
||||
isc_socketmgr_t *socketmgr,
|
||||
isc_timermgr_t *timermgr,
|
||||
unsigned int options,
|
||||
|
|
|
|||
|
|
@ -25,8 +25,9 @@
|
|||
#include <isc/print.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/random.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/socket.h>
|
||||
#include <isc/stats.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/timer.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
|
|
@ -156,6 +157,7 @@ typedef struct query {
|
|||
isc_buffer_t buffer;
|
||||
isc_buffer_t *tsig;
|
||||
dns_tsigkey_t *tsigkey;
|
||||
isc_socketevent_t sendevent;
|
||||
unsigned int options;
|
||||
unsigned int attributes;
|
||||
unsigned int sends;
|
||||
|
|
@ -389,11 +391,10 @@ struct dns_resolver {
|
|||
isc_boolean_t frozen;
|
||||
unsigned int options;
|
||||
dns_dispatchmgr_t * dispatchmgr;
|
||||
dns_dispatch_t * dispatchv4;
|
||||
dns_dispatchset_t * dispatches4;
|
||||
isc_boolean_t exclusivev4;
|
||||
dns_dispatch_t * dispatchv6;
|
||||
dns_dispatchset_t * dispatches6;
|
||||
isc_boolean_t exclusivev6;
|
||||
unsigned int ndisps;
|
||||
unsigned int nbuckets;
|
||||
fctxbucket_t * buckets;
|
||||
isc_uint32_t lame_ttl;
|
||||
|
|
@ -420,7 +421,6 @@ struct dns_resolver {
|
|||
unsigned int activebuckets;
|
||||
isc_boolean_t priming;
|
||||
unsigned int spillat; /* clients-per-query */
|
||||
unsigned int nextdisp;
|
||||
|
||||
/* Bad cache. */
|
||||
dns_badcache_t ** badcache;
|
||||
|
|
@ -1210,7 +1210,8 @@ process_sendevent(resquery_t *query, isc_event_t *event) {
|
|||
}
|
||||
}
|
||||
|
||||
isc_event_free(&event);
|
||||
if (event->ev_type == ISC_SOCKEVENT_CONNECT)
|
||||
isc_event_free(&event);
|
||||
|
||||
if (retry) {
|
||||
/*
|
||||
|
|
@ -1457,14 +1458,14 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
|||
if (!have_addr) {
|
||||
switch (pf) {
|
||||
case PF_INET:
|
||||
result =
|
||||
dns_dispatch_getlocaladdress(res->dispatchv4,
|
||||
&addr);
|
||||
result = dns_dispatch_getlocaladdress(
|
||||
res->dispatches4->dispatches[0],
|
||||
&addr);
|
||||
break;
|
||||
case PF_INET6:
|
||||
result =
|
||||
dns_dispatch_getlocaladdress(res->dispatchv6,
|
||||
&addr);
|
||||
result = dns_dispatch_getlocaladdress(
|
||||
res->dispatches6->dispatches[0],
|
||||
&addr);
|
||||
break;
|
||||
default:
|
||||
result = ISC_R_NOTIMPLEMENTED;
|
||||
|
|
@ -1520,13 +1521,15 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
|||
} else {
|
||||
switch (isc_sockaddr_pf(&addrinfo->sockaddr)) {
|
||||
case PF_INET:
|
||||
dns_dispatch_attach(res->dispatchv4,
|
||||
&query->dispatch);
|
||||
dns_dispatch_attach(
|
||||
dns_resolver_dispatchv4(res),
|
||||
&query->dispatch);
|
||||
query->exclusivesocket = res->exclusivev4;
|
||||
break;
|
||||
case PF_INET6:
|
||||
dns_dispatch_attach(res->dispatchv6,
|
||||
&query->dispatch);
|
||||
dns_dispatch_attach(
|
||||
dns_resolver_dispatchv6(res),
|
||||
&query->dispatch);
|
||||
query->exclusivesocket = res->exclusivev6;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -2010,8 +2013,11 @@ resquery_send(resquery_t *query) {
|
|||
* XXXRTH Make sure we don't send to ourselves! We should probably
|
||||
* prune out these addresses when we get them from the ADB.
|
||||
*/
|
||||
result = isc_socket_sendto(socket, &r, task, resquery_senddone,
|
||||
query, address, NULL);
|
||||
ISC_EVENT_INIT(&query->sendevent, sizeof(query->sendevent), 0, NULL,
|
||||
ISC_SOCKEVENT_SENDDONE, resquery_senddone, query,
|
||||
NULL, NULL, NULL);
|
||||
result = isc_socket_sendto2(socket, &r, task, address, NULL,
|
||||
&query->sendevent, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (connecting) {
|
||||
/*
|
||||
|
|
@ -2545,9 +2551,9 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,
|
|||
*/
|
||||
if (need_alternate != NULL &&
|
||||
!*need_alternate && unshared &&
|
||||
((res->dispatchv4 == NULL &&
|
||||
((res->dispatches4 == NULL &&
|
||||
find->result_v6 != DNS_R_NXDOMAIN) ||
|
||||
(res->dispatchv6 == NULL &&
|
||||
(res->dispatches6 == NULL &&
|
||||
find->result_v4 != DNS_R_NXDOMAIN)))
|
||||
*need_alternate = ISC_TRUE;
|
||||
} else {
|
||||
|
|
@ -2562,9 +2568,9 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,
|
|||
* an alternative server.
|
||||
*/
|
||||
if (need_alternate != NULL && !*need_alternate &&
|
||||
((res->dispatchv4 == NULL &&
|
||||
((res->dispatches4 == NULL &&
|
||||
find->result_v6 == DNS_R_NXRRSET) ||
|
||||
(res->dispatchv6 == NULL &&
|
||||
(res->dispatches6 == NULL &&
|
||||
find->result_v4 == DNS_R_NXRRSET)))
|
||||
*need_alternate = ISC_TRUE;
|
||||
dns_adb_destroyfind(&find);
|
||||
|
|
@ -2662,9 +2668,9 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
|
|||
|
||||
while (sa != NULL) {
|
||||
if ((isc_sockaddr_pf(sa) == AF_INET &&
|
||||
fctx->res->dispatchv4 == NULL) ||
|
||||
fctx->res->dispatches4 == NULL) ||
|
||||
(isc_sockaddr_pf(sa) == AF_INET6 &&
|
||||
fctx->res->dispatchv6 == NULL)) {
|
||||
fctx->res->dispatches6 == NULL)) {
|
||||
sa = ISC_LIST_NEXT(sa, link);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -2712,9 +2718,9 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
|
|||
*/
|
||||
stdoptions |= DNS_ADBFIND_AVOIDFETCHES;
|
||||
}
|
||||
if (res->dispatchv4 != NULL)
|
||||
if (res->dispatches4 != NULL)
|
||||
stdoptions |= DNS_ADBFIND_INET;
|
||||
if (res->dispatchv6 != NULL)
|
||||
if (res->dispatches6 != NULL)
|
||||
stdoptions |= DNS_ADBFIND_INET6;
|
||||
isc_stdtime_get(&now);
|
||||
|
||||
|
|
@ -2747,7 +2753,7 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
|
|||
if (need_alternate) {
|
||||
int family;
|
||||
alternate_t *a;
|
||||
family = (res->dispatchv6 != NULL) ? AF_INET6 : AF_INET;
|
||||
family = (res->dispatches6 != NULL) ? AF_INET6 : AF_INET;
|
||||
for (a = ISC_LIST_HEAD(fctx->res->alternates);
|
||||
a != NULL;
|
||||
a = ISC_LIST_NEXT(a, link)) {
|
||||
|
|
@ -7363,10 +7369,10 @@ destroy(dns_resolver_t *res) {
|
|||
}
|
||||
isc_mem_put(res->mctx, res->buckets,
|
||||
res->nbuckets * sizeof(fctxbucket_t));
|
||||
if (res->dispatchv4 != NULL)
|
||||
dns_dispatch_detach(&res->dispatchv4);
|
||||
if (res->dispatchv6 != NULL)
|
||||
dns_dispatch_detach(&res->dispatchv6);
|
||||
if (res->dispatches4 != NULL)
|
||||
dns_dispatchset_destroy(&res->dispatches4);
|
||||
if (res->dispatches6 != NULL)
|
||||
dns_dispatchset_destroy(&res->dispatches6);
|
||||
while ((a = ISC_LIST_HEAD(res->alternates)) != NULL) {
|
||||
ISC_LIST_UNLINK(res->alternates, a, link);
|
||||
if (!a->isaddress)
|
||||
|
|
@ -7456,7 +7462,8 @@ spillattimer_countdown(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
isc_result_t
|
||||
dns_resolver_create(dns_view_t *view,
|
||||
isc_taskmgr_t *taskmgr, unsigned int ntasks,
|
||||
isc_taskmgr_t *taskmgr,
|
||||
unsigned int ntasks, unsigned int ndisp,
|
||||
isc_socketmgr_t *socketmgr,
|
||||
isc_timermgr_t *timermgr,
|
||||
unsigned int options,
|
||||
|
|
@ -7478,6 +7485,7 @@ dns_resolver_create(dns_view_t *view,
|
|||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
REQUIRE(ntasks > 0);
|
||||
REQUIRE(ndisp > 0);
|
||||
REQUIRE(resp != NULL && *resp == NULL);
|
||||
REQUIRE(dispatchmgr != NULL);
|
||||
REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL);
|
||||
|
|
@ -7508,8 +7516,6 @@ dns_resolver_create(dns_view_t *view,
|
|||
res->spillattimer = NULL;
|
||||
res->zero_no_soa_ttl = ISC_FALSE;
|
||||
res->query_timeout = DEFAULT_QUERY_TIMEOUT;
|
||||
res->ndisps = 0;
|
||||
res->nextdisp = 0; /* meaningless at this point, but init it */
|
||||
res->nbuckets = ntasks;
|
||||
res->activebuckets = ntasks;
|
||||
res->buckets = isc_mem_get(view->mctx,
|
||||
|
|
@ -7552,17 +7558,19 @@ dns_resolver_create(dns_view_t *view,
|
|||
buckets_created++;
|
||||
}
|
||||
|
||||
res->dispatchv4 = NULL;
|
||||
res->dispatches4 = NULL;
|
||||
if (dispatchv4 != NULL) {
|
||||
dns_dispatch_attach(dispatchv4, &res->dispatchv4);
|
||||
dns_dispatchset_create(view->mctx, socketmgr, taskmgr,
|
||||
dispatchv4, &res->dispatches4, ndisp);
|
||||
dispattr = dns_dispatch_getattributes(dispatchv4);
|
||||
res->exclusivev4 =
|
||||
ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0);
|
||||
}
|
||||
|
||||
res->dispatchv6 = NULL;
|
||||
res->dispatches6 = NULL;
|
||||
if (dispatchv6 != NULL) {
|
||||
dns_dispatch_attach(dispatchv6, &res->dispatchv6);
|
||||
dns_dispatchset_create(view->mctx, socketmgr, taskmgr,
|
||||
dispatchv6, &res->dispatches6, ndisp);
|
||||
dispattr = dns_dispatch_getattributes(dispatchv6);
|
||||
res->exclusivev6 =
|
||||
ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0);
|
||||
|
|
@ -7638,10 +7646,10 @@ dns_resolver_create(dns_view_t *view,
|
|||
DESTROYLOCK(&res->lock);
|
||||
|
||||
cleanup_dispatches:
|
||||
if (res->dispatchv6 != NULL)
|
||||
dns_dispatch_detach(&res->dispatchv6);
|
||||
if (res->dispatchv4 != NULL)
|
||||
dns_dispatch_detach(&res->dispatchv4);
|
||||
if (res->dispatches6 != NULL)
|
||||
dns_dispatchset_destroy(&res->dispatches6);
|
||||
if (res->dispatches4 != NULL)
|
||||
dns_dispatchset_destroy(&res->dispatches4);
|
||||
|
||||
cleanup_buckets:
|
||||
for (i = 0; i < buckets_created; i++) {
|
||||
|
|
@ -7830,7 +7838,6 @@ void
|
|||
dns_resolver_shutdown(dns_resolver_t *res) {
|
||||
unsigned int i;
|
||||
fetchctx_t *fctx;
|
||||
isc_socket_t *sock;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(VALID_RESOLVER(res));
|
||||
|
|
@ -7849,15 +7856,13 @@ dns_resolver_shutdown(dns_resolver_t *res) {
|
|||
fctx != NULL;
|
||||
fctx = ISC_LIST_NEXT(fctx, link))
|
||||
fctx_shutdown(fctx);
|
||||
if (res->dispatchv4 != NULL && !res->exclusivev4) {
|
||||
sock = dns_dispatch_getsocket(res->dispatchv4);
|
||||
isc_socket_cancel(sock, res->buckets[i].task,
|
||||
ISC_SOCKCANCEL_ALL);
|
||||
if (res->dispatches4 != NULL && !res->exclusivev4) {
|
||||
dns_dispatchset_cancelall(res->dispatches4,
|
||||
res->buckets[i].task);
|
||||
}
|
||||
if (res->dispatchv6 != NULL && !res->exclusivev6) {
|
||||
sock = dns_dispatch_getsocket(res->dispatchv6);
|
||||
isc_socket_cancel(sock, res->buckets[i].task,
|
||||
ISC_SOCKCANCEL_ALL);
|
||||
if (res->dispatches6 != NULL && !res->exclusivev6) {
|
||||
dns_dispatchset_cancelall(res->dispatches6,
|
||||
res->buckets[i].task);
|
||||
}
|
||||
res->buckets[i].exiting = ISC_TRUE;
|
||||
if (ISC_LIST_EMPTY(res->buckets[i].fctxs)) {
|
||||
|
|
@ -8240,13 +8245,13 @@ dns_resolver_dispatchmgr(dns_resolver_t *resolver) {
|
|||
dns_dispatch_t *
|
||||
dns_resolver_dispatchv4(dns_resolver_t *resolver) {
|
||||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
return (resolver->dispatchv4);
|
||||
return (dns_dispatchset_get(resolver->dispatches4));
|
||||
}
|
||||
|
||||
dns_dispatch_t *
|
||||
dns_resolver_dispatchv6(dns_resolver_t *resolver) {
|
||||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
return (resolver->dispatchv6);
|
||||
return (dns_dispatchset_get(resolver->dispatches6));
|
||||
}
|
||||
|
||||
isc_socketmgr_t *
|
||||
|
|
|
|||
|
|
@ -39,13 +39,15 @@ LIBS = @LIBS@ @ATFLIBS@
|
|||
OBJS = dnstest.@O@
|
||||
SRCS = dnstest.c master_test.c dbiterator_test.c time_test.c \
|
||||
private_test.c update_test.c zonemgr_test.c zt_test.c \
|
||||
dbdiff_test.c nsec3_test.c rdataset_test.c rdata_test.c
|
||||
dbdiff_test.c dispatch_test.c nsec3_test.c \
|
||||
rdataset_test.c rdata_test.c
|
||||
|
||||
SUBDIRS =
|
||||
TARGETS = master_test@EXEEXT@ dbiterator_test@EXEEXT@ time_test@EXEEXT@ \
|
||||
private_test@EXEEXT@ update_test@EXEEXT@ zonemgr_test@EXEEXT@ \
|
||||
zt_test@EXEEXT@ dbversion_test@EXEEXT@ dbdiff_test@EXEEXT@ \
|
||||
nsec3_test@EXEEXT@ rdataset_test@EXEEXT@ rdata_test@EXEEXT@
|
||||
dispatch_test@EXEEXT@ nsec3_test@EXEEXT@ \
|
||||
rdataset_test@EXEEXT@ rdata_test@EXEEXT@
|
||||
|
||||
@BIND9_MAKE_RULES@
|
||||
|
||||
|
|
@ -114,6 +116,16 @@ rdata_test@EXEEXT@: rdata_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
|
|||
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
|
||||
rdata_test.@O@ ${DNSLIBS} ${ISCLIBS} ${LIBS}
|
||||
|
||||
dispatch_test@EXEEXT@: dispatch_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
|
||||
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
|
||||
dispatch_test.@O@ dnstest.@O@ ${DNSLIBS} \
|
||||
${ISCLIBS} ${LIBS}
|
||||
|
||||
dispatch_test@EXEEXT@: dispatch_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
|
||||
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
|
||||
dispatch_test.@O@ dnstest.@O@ ${DNSLIBS} \
|
||||
${ISCLIBS} ${LIBS}
|
||||
|
||||
unit::
|
||||
sh ${top_srcdir}/unit/unittest.sh
|
||||
|
||||
|
|
|
|||
160
lib/dns/tests/dispatch_test.c
Normal file
160
lib/dns/tests/dispatch_test.c
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/socket.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/timer.h>
|
||||
|
||||
#include <dns/dispatch.h>
|
||||
#include <dns/name.h>
|
||||
#include <dns/view.h>
|
||||
|
||||
#include "dnstest.h"
|
||||
|
||||
dns_dispatchmgr_t *dispatchmgr = NULL;
|
||||
dns_dispatchset_t *dset = NULL;
|
||||
|
||||
static isc_result_t
|
||||
make_dispatchset(unsigned int ndisps) {
|
||||
isc_result_t result;
|
||||
isc_sockaddr_t any;
|
||||
unsigned int attrs;
|
||||
dns_dispatch_t *disp = NULL;
|
||||
|
||||
result = dns_dispatchmgr_create(mctx, NULL, &dispatchmgr);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
isc_sockaddr_any(&any);
|
||||
attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP;
|
||||
result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr,
|
||||
&any, 512, 6, 1024, 17, 19, attrs,
|
||||
attrs, &disp);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
result = dns_dispatchset_create(mctx, socketmgr, taskmgr, disp,
|
||||
&dset, ndisps);
|
||||
dns_dispatch_detach(&disp);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
teardown() {
|
||||
if (dset != NULL)
|
||||
dns_dispatchset_destroy(&dset);
|
||||
if (dispatchmgr != NULL)
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Individual unit tests
|
||||
*/
|
||||
ATF_TC(dispatchset_create);
|
||||
ATF_TC_HEAD(dispatchset_create, tc) {
|
||||
atf_tc_set_md_var(tc, "descr", "create dispatch set");
|
||||
}
|
||||
ATF_TC_BODY(dispatchset_create, tc) {
|
||||
isc_result_t result;
|
||||
|
||||
UNUSED(tc);
|
||||
|
||||
result = dns_test_begin(NULL, ISC_TRUE);
|
||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
result = make_dispatchset(1);
|
||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||
teardown();
|
||||
|
||||
result = make_dispatchset(10);
|
||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||
teardown();
|
||||
|
||||
dns_test_end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
ATF_TC(dispatchset_get);
|
||||
ATF_TC_HEAD(dispatchset_get, tc) {
|
||||
atf_tc_set_md_var(tc, "descr", "test dispatch set round-robin");
|
||||
}
|
||||
ATF_TC_BODY(dispatchset_get, tc) {
|
||||
isc_result_t result;
|
||||
dns_dispatch_t *d1, *d2, *d3, *d4, *d5;
|
||||
|
||||
UNUSED(tc);
|
||||
|
||||
result = dns_test_begin(NULL, ISC_TRUE);
|
||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
result = make_dispatchset(1);
|
||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
d1 = dns_dispatchset_get(dset);
|
||||
d2 = dns_dispatchset_get(dset);
|
||||
d3 = dns_dispatchset_get(dset);
|
||||
d4 = dns_dispatchset_get(dset);
|
||||
d5 = dns_dispatchset_get(dset);
|
||||
|
||||
ATF_CHECK_EQ(d1, d2);
|
||||
ATF_CHECK_EQ(d2, d3);
|
||||
ATF_CHECK_EQ(d3, d4);
|
||||
ATF_CHECK_EQ(d4, d5);
|
||||
|
||||
teardown();
|
||||
|
||||
result = make_dispatchset(4);
|
||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
d1 = dns_dispatchset_get(dset);
|
||||
d2 = dns_dispatchset_get(dset);
|
||||
d3 = dns_dispatchset_get(dset);
|
||||
d4 = dns_dispatchset_get(dset);
|
||||
d5 = dns_dispatchset_get(dset);
|
||||
|
||||
ATF_CHECK_EQ(d1, d5);
|
||||
ATF_CHECK(d1 != d2);
|
||||
ATF_CHECK(d2 != d3);
|
||||
ATF_CHECK(d3 != d4);
|
||||
ATF_CHECK(d4 != d5);
|
||||
|
||||
teardown();
|
||||
dns_test_end();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Main
|
||||
*/
|
||||
ATF_TP_ADD_TCS(tp) {
|
||||
ATF_TP_ADD_TC(tp, dispatchset_create);
|
||||
ATF_TP_ADD_TC(tp, dispatchset_get);
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
#include <dns/adb.h>
|
||||
#include <dns/cache.h>
|
||||
#include <dns/db.h>
|
||||
#include <dns/dispatch.h>
|
||||
#include <dns/dlz.h>
|
||||
#ifdef BIND9
|
||||
#include <dns/dns64.h>
|
||||
|
|
@ -670,7 +671,8 @@ req_shutdown(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
isc_result_t
|
||||
dns_view_createresolver(dns_view_t *view,
|
||||
isc_taskmgr_t *taskmgr, unsigned int ntasks,
|
||||
isc_taskmgr_t *taskmgr,
|
||||
unsigned int ntasks, unsigned int ndisp,
|
||||
isc_socketmgr_t *socketmgr,
|
||||
isc_timermgr_t *timermgr,
|
||||
unsigned int options,
|
||||
|
|
@ -691,7 +693,7 @@ dns_view_createresolver(dns_view_t *view,
|
|||
return (result);
|
||||
isc_task_setname(view->task, "view", view);
|
||||
|
||||
result = dns_resolver_create(view, taskmgr, ntasks, socketmgr,
|
||||
result = dns_resolver_create(view, taskmgr, ntasks, ndisp, socketmgr,
|
||||
timermgr, options, dispatchmgr,
|
||||
dispatchv4, dispatchv6,
|
||||
&view->resolver);
|
||||
|
|
@ -723,8 +725,7 @@ dns_view_createresolver(dns_view_t *view,
|
|||
result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
|
||||
dns_resolver_taskmgr(view->resolver),
|
||||
dns_resolver_dispatchmgr(view->resolver),
|
||||
dns_resolver_dispatchv4(view->resolver),
|
||||
dns_resolver_dispatchv6(view->resolver),
|
||||
dispatchv4, dispatchv6,
|
||||
&view->requestmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_adb_shutdown(view->adb);
|
||||
|
|
|
|||
|
|
@ -191,6 +191,10 @@ dns_dispatchmgr_setavailports
|
|||
dns_dispatchmgr_setblackhole
|
||||
dns_dispatchmgr_setblackportlist
|
||||
dns_dispatchmgr_setstats
|
||||
dns_dispatchset_cancelall
|
||||
dns_dispatchset_create
|
||||
dns_dispatchset_destroy
|
||||
dns_dispatchset_get
|
||||
dns_dlz_writeablezone
|
||||
dns_dlzallowzonexfr
|
||||
dns_dlzconfigure
|
||||
|
|
|
|||
|
|
@ -283,12 +283,20 @@ typedef struct isc_socketmethods {
|
|||
isc_task_t *task, isc_taskaction_t action,
|
||||
const void *arg, isc_sockaddr_t *address,
|
||||
struct in6_pktinfo *pktinfo);
|
||||
isc_result_t (*sendto2)(isc_socket_t *sock, isc_region_t *region,
|
||||
isc_task_t *task, isc_sockaddr_t *address,
|
||||
struct in6_pktinfo *pktinfo,
|
||||
isc_socketevent_t *event,
|
||||
unsigned int flags);
|
||||
isc_result_t (*connect)(isc_socket_t *sock, isc_sockaddr_t *addr,
|
||||
isc_task_t *task, isc_taskaction_t action,
|
||||
const void *arg);
|
||||
isc_result_t (*recv)(isc_socket_t *sock, isc_region_t *region,
|
||||
unsigned int minimum, isc_task_t *task,
|
||||
isc_taskaction_t action, const void *arg);
|
||||
isc_result_t (*recv2)(isc_socket_t *sock, isc_region_t *region,
|
||||
unsigned int minimum, isc_task_t *task,
|
||||
isc_socketevent_t *event, unsigned int flags);
|
||||
void (*cancel)(isc_socket_t *sock, isc_task_t *task,
|
||||
unsigned int how);
|
||||
isc_result_t (*getsockname)(isc_socket_t *sock,
|
||||
|
|
|
|||
|
|
@ -140,6 +140,18 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_task_t *task,
|
|||
pktinfo));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
|
||||
isc_task_t *task, isc_sockaddr_t *address,
|
||||
struct in6_pktinfo *pktinfo, isc_socketevent_t *event,
|
||||
unsigned int flags)
|
||||
{
|
||||
REQUIRE(ISCAPI_SOCKET_VALID(sock));
|
||||
|
||||
return (sock->methods->sendto2(sock, region, task, address,
|
||||
pktinfo, event, flags));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task,
|
||||
isc_taskaction_t action, const void *arg)
|
||||
|
|
@ -158,6 +170,17 @@ isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum,
|
|||
return (sock->methods->recv(sock, region, minimum, task, action, arg));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
|
||||
unsigned int minimum, isc_task_t *task,
|
||||
isc_socketevent_t *event, unsigned int flags)
|
||||
{
|
||||
REQUIRE(ISCAPI_SOCKET_VALID(sock));
|
||||
|
||||
return (sock->methods->recv2(sock, region, minimum, task,
|
||||
event, flags));
|
||||
}
|
||||
|
||||
void
|
||||
isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
|
||||
REQUIRE(ISCAPI_SOCKET_VALID(sock));
|
||||
|
|
|
|||
|
|
@ -572,8 +572,10 @@ static struct {
|
|||
isc__socket_detach,
|
||||
isc__socket_bind,
|
||||
isc__socket_sendto,
|
||||
isc__socket_sendto2,
|
||||
isc__socket_connect,
|
||||
isc__socket_recv,
|
||||
isc__socket_recv2,
|
||||
isc__socket_cancel,
|
||||
isc__socket_getsockname,
|
||||
isc__socket_gettype,
|
||||
|
|
|
|||
Loading…
Reference in a new issue