implement dns_dispatchmgr_t, replacing dns_dispatchlist_t. Use it throughout the library/server.
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <dns/cache.h>
|
||||
#include <dns/db.h>
|
||||
#include <dns/dispatch.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/resolver.h>
|
||||
#include <dns/result.h>
|
||||
@@ -53,6 +54,7 @@ dns_view_t *view;
|
||||
isc_taskmgr_t *taskmgr;
|
||||
isc_socketmgr_t *sockmgr;
|
||||
isc_timermgr_t *timermgr;
|
||||
dns_dispatchmgr_t *dispatchmgr;
|
||||
|
||||
isc_sockaddrlist_t forwarders;
|
||||
|
||||
@@ -88,7 +90,7 @@ create_view(isc_mem_t *mctx) {
|
||||
* XXXMLG hardwired number of tasks.
|
||||
*/
|
||||
result = dns_view_createresolver(view, taskmgr, 16, sockmgr,
|
||||
timermgr, 0, NULL, NULL);
|
||||
timermgr, dispatchmgr, 0, NULL, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto out;
|
||||
|
||||
@@ -271,6 +273,13 @@ main(int argc, char **argv) {
|
||||
result = isc_timermgr_create(mem, &timermgr);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Create a dispatch manager.
|
||||
*/
|
||||
dispatchmgr = NULL;
|
||||
result = dns_dispatchmgr_create(mem, &dispatchmgr);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Read resolv.conf to get our forwarders.
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
EXTERN isc_mem_t * ns_g_mctx INIT(NULL);
|
||||
EXTERN unsigned int ns_g_cpus INIT(1);
|
||||
EXTERN isc_taskmgr_t * ns_g_taskmgr INIT(NULL);
|
||||
EXTERN dns_dispatchmgr_t * ns_g_dispatchmgr INIT(NULL);
|
||||
/*
|
||||
* XXXRTH We're going to want multiple timer managers eventually. One
|
||||
* for really short timers, another for client timers, and one
|
||||
|
||||
@@ -87,8 +87,9 @@ struct ns_interface {
|
||||
|
||||
isc_result_t
|
||||
ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
||||
isc_socketmgr_t *socketmgr, ns_clientmgr_t *clientmgr,
|
||||
ns_interfacemgr_t **mgrp);
|
||||
isc_socketmgr_t *socketmgr,
|
||||
dns_dispatchmgr_t *dispatchmgr,
|
||||
ns_clientmgr_t *clientmgr, ns_interfacemgr_t **mgrp);
|
||||
|
||||
void
|
||||
ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target);
|
||||
|
||||
@@ -42,6 +42,7 @@ struct ns_interfacemgr {
|
||||
isc_mem_t * mctx; /* Memory context. */
|
||||
isc_taskmgr_t * taskmgr; /* Task manager. */
|
||||
isc_socketmgr_t * socketmgr; /* Socket manager. */
|
||||
dns_dispatchmgr_t * dispatchmgr;
|
||||
ns_clientmgr_t * clientmgr; /* Client manager. */
|
||||
unsigned int generation; /* Current generation no. */
|
||||
ns_listenlist_t * listenon;
|
||||
@@ -71,8 +72,9 @@ sockaddr_format(isc_sockaddr_t *sa, char *array, unsigned int size) {
|
||||
|
||||
isc_result_t
|
||||
ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
||||
isc_socketmgr_t *socketmgr, ns_clientmgr_t *clientmgr,
|
||||
ns_interfacemgr_t **mgrp)
|
||||
isc_socketmgr_t *socketmgr,
|
||||
dns_dispatchmgr_t *dispatchmgr,
|
||||
ns_clientmgr_t *clientmgr, ns_interfacemgr_t **mgrp)
|
||||
{
|
||||
isc_result_t result;
|
||||
ns_interfacemgr_t *mgr;
|
||||
@@ -92,6 +94,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
||||
mgr->mctx = mctx;
|
||||
mgr->taskmgr = taskmgr;
|
||||
mgr->socketmgr = socketmgr;
|
||||
mgr->dispatchmgr = dispatchmgr;
|
||||
mgr->clientmgr = clientmgr;
|
||||
mgr->generation = 1;
|
||||
mgr->listenon = NULL;
|
||||
@@ -245,6 +248,7 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
|
||||
static isc_result_t
|
||||
ns_interface_listenudp(ns_interface_t *ifp) {
|
||||
isc_result_t result;
|
||||
unsigned int attrs;
|
||||
|
||||
/*
|
||||
* Open a UDP socket.
|
||||
@@ -266,9 +270,17 @@ ns_interface_listenudp(ns_interface_t *ifp) {
|
||||
isc_result_totext(result));
|
||||
goto udp_bind_failure;
|
||||
}
|
||||
result = dns_dispatch_create(ifp->mgr->mctx, ifp->udpsocket, ifp->task,
|
||||
4096, 1000, 32768, 8219, 8237, NULL,
|
||||
&ifp->udpdispatch);
|
||||
attrs = 0;
|
||||
attrs |= DNS_DISPATCHATTR_UDP;
|
||||
if (isc_sockaddr_pf(&ifp->addr) == AF_INET)
|
||||
attrs |= DNS_DISPATCHATTR_IPV4;
|
||||
else
|
||||
attrs |= DNS_DISPATCHATTR_IPV6;
|
||||
attrs |= DNS_DISPATCHATTR_MAKEQUERY;
|
||||
attrs |= DNS_DISPATCHATTR_ACCEPTREQUEST;
|
||||
result = dns_dispatch_create(ifp->mgr->dispatchmgr, ifp->udpsocket,
|
||||
ifp->task, 4096, 1000, 32768, 8219,
|
||||
8237, NULL, attrs, &ifp->udpdispatch);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"UDP dns_dispatch_create(): %s",
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <isc/timer.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/dispatch.h>
|
||||
|
||||
#include <dst/result.h>
|
||||
|
||||
/*
|
||||
@@ -258,6 +260,14 @@ create_managers() {
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
|
||||
result = dns_dispatchmgr_create(ns_g_mctx, &ns_g_dispatchmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"dns_dispatchmgr_create() failed: %s",
|
||||
isc_result_totext(result));
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -274,6 +284,7 @@ destroy_managers(void) {
|
||||
isc_taskmgr_destroy(&ns_g_taskmgr);
|
||||
isc_timermgr_destroy(&ns_g_timermgr);
|
||||
isc_socketmgr_destroy(&ns_g_socketmgr);
|
||||
dns_dispatchmgr_destroy(&ns_g_dispatchmgr);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -356,7 +356,8 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview,
|
||||
*/
|
||||
CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31,
|
||||
ns_g_socketmgr, ns_g_timermgr,
|
||||
0, dispatchv4, dispatchv6));
|
||||
0, ns_g_dispatchmgr,
|
||||
dispatchv4, dispatchv6));
|
||||
|
||||
/*
|
||||
* Set resolver forwarding policy.
|
||||
@@ -866,6 +867,7 @@ static isc_result_t
|
||||
configure_server_querysource(dns_c_ctx_t *cctx, ns_server_t *server, int af,
|
||||
dns_dispatch_t **dispatchp) {
|
||||
isc_result_t result;
|
||||
unsigned int attrs;
|
||||
struct in_addr ina;
|
||||
isc_sockaddr_t sa, any4, any6, *any;
|
||||
isc_socket_t *socket;
|
||||
@@ -982,10 +984,18 @@ configure_server_querysource(dns_c_ctx_t *cctx, ns_server_t *server, int af,
|
||||
isc_socket_detach(&socket);
|
||||
return (result);
|
||||
}
|
||||
result = dns_dispatch_create(ns_g_mctx, socket,
|
||||
attrs = 0;
|
||||
attrs = DNS_DISPATCHATTR_UDP;
|
||||
attrs |= DNS_DISPATCHATTR_PRIVATE;
|
||||
if (af == AF_INET)
|
||||
attrs |= DNS_DISPATCHATTR_IPV4;
|
||||
else
|
||||
attrs |= DNS_DISPATCHATTR_IPV6;
|
||||
attrs |= DNS_DISPATCHATTR_MAKEQUERY;
|
||||
result = dns_dispatch_create(ns_g_dispatchmgr, socket,
|
||||
server->task, 4096,
|
||||
1000, 32768, 16411, 16433, NULL,
|
||||
server_dispatchp);
|
||||
attrs, server_dispatchp);
|
||||
/*
|
||||
* Regardless of whether dns_dispatch_create() succeeded or
|
||||
* failed, we don't need to keep the reference to the socket.
|
||||
@@ -1390,7 +1400,8 @@ run_server(isc_task_t *task, isc_event_t *event) {
|
||||
"creating client manager");
|
||||
|
||||
CHECKFATAL(ns_interfacemgr_create(ns_g_mctx, ns_g_taskmgr,
|
||||
ns_g_socketmgr, server->clientmgr,
|
||||
ns_g_socketmgr, ns_g_dispatchmgr,
|
||||
server->clientmgr,
|
||||
&server->interfacemgr),
|
||||
"creating interface manager");
|
||||
|
||||
|
||||
@@ -119,7 +119,6 @@ DNSSAFEOBJS = sec/dnssafe/ahchdig.@O@ sec/dnssafe/ahchencr.@O@ \
|
||||
OBJS = a6.@O@ acl.@O@ aclconf.@O@ adb.@O@ byaddr.@O@ \
|
||||
cache.@O@ callbacks.@O@ compress.@O@ \
|
||||
db.@O@ dbiterator.@O@ dbtable.@O@ dispatch.@O@ dnssec.@O@ \
|
||||
dispatchlist.@O@ \
|
||||
journal.@O@ keytable.@O@ lib.@O@ log.@O@ \
|
||||
master.@O@ masterdump.@O@ message.@O@ \
|
||||
name.@O@ ncache.@O@ nxt.@O@ peer.@O@ \
|
||||
@@ -135,7 +134,6 @@ OBJS = a6.@O@ acl.@O@ aclconf.@O@ adb.@O@ byaddr.@O@ \
|
||||
SRCS = a6.c acl.c aclconf.c adb.c byaddr.c \
|
||||
cache.c callbacks.c compress.c \
|
||||
db.c dbiterator.c dbtable.c dispatch.c dnssec.c \
|
||||
dispatchlist.c \
|
||||
journal.c keytable.c lib.c log.c \
|
||||
master.c masterdump.c message.c \
|
||||
name.c ncache.c nxt.c peer.c \
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <isc/lfsr.h>
|
||||
#include <isc/list.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/mutex.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/util.h>
|
||||
@@ -30,6 +32,23 @@
|
||||
#include <dns/log.h>
|
||||
#include <dns/message.h>
|
||||
#include <dns/tcpmsg.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
struct dns_dispatchmgr {
|
||||
/* Unlocked. */
|
||||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
|
||||
/* Locked by "lock". */
|
||||
isc_mutex_t lock;
|
||||
unsigned int state;
|
||||
ISC_LIST(dns_dispatch_t) list;
|
||||
};
|
||||
|
||||
#define MGR_SHUTTINGDOWN 0x00000001U
|
||||
#define MGR_IS_SHUTTINGDOWN(l) (((l)->state & MGR_SHUTTINGDOWN) != 0)
|
||||
|
||||
#define IS_PRIVATE(d) (((d)->attributes & DNS_DISPATCHATTR_PRIVATE) != 0)
|
||||
|
||||
struct dns_dispentry {
|
||||
unsigned int magic;
|
||||
@@ -51,14 +70,18 @@ typedef ISC_LIST(dns_dispentry_t) dns_displist_t;
|
||||
struct dns_dispatch {
|
||||
/* Unlocked. */
|
||||
unsigned int magic; /* magic */
|
||||
isc_mem_t *mctx; /* memory context */
|
||||
dns_dispatchmgr_t *mgr; /* dispatch manager */
|
||||
isc_task_t *task; /* internal task */
|
||||
isc_socket_t *socket; /* isc socket attached to */
|
||||
unsigned int buffersize; /* size of each buffer */
|
||||
unsigned int maxrequests; /* max requests */
|
||||
unsigned int maxbuffers; /* max buffers */
|
||||
|
||||
/* Locked. */
|
||||
/* Locked by mgr->lock. */
|
||||
unsigned int attributes;
|
||||
ISC_LINK(dns_dispatch_t) link;
|
||||
|
||||
/* Locked by "lock". */
|
||||
isc_mutex_t lock; /* locks all below */
|
||||
unsigned int refcount; /* number of users */
|
||||
isc_mempool_t *epool; /* memory pool for events */
|
||||
@@ -83,21 +106,24 @@ struct dns_dispatch {
|
||||
dns_displist_t *qid_table; /* the table itself */
|
||||
};
|
||||
|
||||
#define REQUEST_MAGIC 0x53912051 /* "random" value */
|
||||
#define VALID_REQUEST(e) ((e) != NULL && (e)->magic == REQUEST_MAGIC)
|
||||
#define REQUEST_MAGIC ISC_MAGIC('D', 'r', 'q', 's')
|
||||
#define VALID_REQUEST(e) ISC_MAGIC_VALID((e), REQUEST_MAGIC)
|
||||
|
||||
#define RESPONSE_MAGIC 0x15021935 /* "random" value */
|
||||
#define VALID_RESPONSE(e) ((e) != NULL && (e)->magic == RESPONSE_MAGIC)
|
||||
#define RESPONSE_MAGIC ISC_MAGIC('D', 'r', 's', 'p')
|
||||
#define VALID_RESPONSE(e) ISC_MAGIC_VALID((e), RESPONSE_MAGIC)
|
||||
|
||||
#define DISPATCH_MAGIC 0x69385829 /* "random" value */
|
||||
#define VALID_DISPATCH(e) ((e) != NULL && (e)->magic == DISPATCH_MAGIC)
|
||||
#define DISPATCH_MAGIC ISC_MAGIC('D', 'i', 's', 'p')
|
||||
#define VALID_DISPATCH(e) ISC_MAGIC_VALID((e), DISPATCH_MAGIC)
|
||||
|
||||
#define DNS_DISPATCHMGR_MAGIC ISC_MAGIC('D', 'M', 'g', 'r')
|
||||
#define VALID_DISPATCHMGR(e) ISC_MAGIC_VALID((e), DNS_DISPATCHMGR_MAGIC)
|
||||
|
||||
/*
|
||||
* statics.
|
||||
*/
|
||||
static dns_dispentry_t *bucket_search(dns_dispatch_t *, isc_sockaddr_t *,
|
||||
dns_messageid_t, unsigned int);
|
||||
static void destroy(dns_dispatch_t *);
|
||||
static void destroy_disp(dns_dispatch_t *);
|
||||
static void udp_recv(isc_task_t *, isc_event_t *);
|
||||
static void tcp_recv(isc_task_t *, isc_event_t *);
|
||||
static inline void startrecv(dns_dispatch_t *);
|
||||
@@ -124,7 +150,8 @@ static dns_dispentry_t *linear_next(dns_dispatch_t *disp,
|
||||
* The resulting string is guaranteed to be null-terminated.
|
||||
*/
|
||||
static void
|
||||
sockaddr_format(isc_sockaddr_t *sa, char *array, unsigned int size) {
|
||||
sockaddr_format(isc_sockaddr_t *sa, char *array, unsigned int size)
|
||||
{
|
||||
isc_result_t result;
|
||||
isc_buffer_t buf;
|
||||
|
||||
@@ -182,7 +209,8 @@ request_log(dns_dispatch_t *disp, dns_dispentry_t *resp,
|
||||
}
|
||||
|
||||
static void
|
||||
reseed_lfsr(isc_lfsr_t *lfsr, void *arg) {
|
||||
reseed_lfsr(isc_lfsr_t *lfsr, void *arg)
|
||||
{
|
||||
UNUSED(arg);
|
||||
|
||||
lfsr->count = (random() & 0x1f) + 32; /* From 32 to 63 states */
|
||||
@@ -194,7 +222,8 @@ reseed_lfsr(isc_lfsr_t *lfsr, void *arg) {
|
||||
* Return an unpredictable message ID.
|
||||
*/
|
||||
static isc_uint32_t
|
||||
dns_randomid(dns_dispatch_t *disp) {
|
||||
dns_randomid(dns_dispatch_t *disp)
|
||||
{
|
||||
isc_uint32_t id;
|
||||
|
||||
id = isc_lfsr_generate32(&disp->qid_lfsr1, &disp->qid_lfsr2);
|
||||
@@ -206,7 +235,8 @@ dns_randomid(dns_dispatch_t *disp) {
|
||||
* Return a hash of the destination and message id.
|
||||
*/
|
||||
static isc_uint32_t
|
||||
dns_hash(dns_dispatch_t *disp, isc_sockaddr_t *dest, isc_uint32_t id) {
|
||||
dns_hash(dns_dispatch_t *disp, isc_sockaddr_t *dest, isc_uint32_t id)
|
||||
{
|
||||
unsigned int ret;
|
||||
|
||||
ret = isc_sockaddr_hash(dest, ISC_TRUE);
|
||||
@@ -224,7 +254,8 @@ static dns_dispatchmethods_t dns_wire_methods = {
|
||||
};
|
||||
|
||||
static dns_dispentry_t *
|
||||
linear_first(dns_dispatch_t *disp) {
|
||||
linear_first(dns_dispatch_t *disp)
|
||||
{
|
||||
dns_dispentry_t *ret;
|
||||
unsigned int bucket;
|
||||
|
||||
@@ -241,7 +272,8 @@ linear_first(dns_dispatch_t *disp) {
|
||||
}
|
||||
|
||||
static dns_dispentry_t *
|
||||
linear_next(dns_dispatch_t *disp, dns_dispentry_t *resp) {
|
||||
linear_next(dns_dispatch_t *disp, dns_dispentry_t *resp)
|
||||
{
|
||||
dns_dispentry_t *ret;
|
||||
unsigned int bucket;
|
||||
|
||||
@@ -261,11 +293,21 @@ linear_next(dns_dispatch_t *disp, dns_dispentry_t *resp) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when refcount reaches 0 (and safe to destroy)
|
||||
* Called when refcount reaches 0 (and safe to destroy).
|
||||
*
|
||||
* The dispatch lock must NOT be locked, and the manager lock MUST be
|
||||
* locked.
|
||||
*/
|
||||
static void
|
||||
destroy(dns_dispatch_t *disp) {
|
||||
destroy_disp(dns_dispatch_t *disp)
|
||||
{
|
||||
dns_dispatchevent_t *ev;
|
||||
dns_dispatchmgr_t *mgr;
|
||||
|
||||
mgr = disp->mgr;
|
||||
disp->mgr = NULL;
|
||||
|
||||
ISC_LIST_UNLINK(mgr->list, disp, link);
|
||||
|
||||
disp->magic = 0;
|
||||
|
||||
@@ -299,10 +341,10 @@ destroy(dns_dispatch_t *disp) {
|
||||
isc_mempool_destroy(&disp->rpool);
|
||||
isc_mempool_destroy(&disp->bpool);
|
||||
isc_mempool_destroy(&disp->epool);
|
||||
isc_mem_put(disp->mctx, disp->qid_table,
|
||||
isc_mem_put(mgr->mctx, disp->qid_table,
|
||||
disp->qid_nbuckets * sizeof(dns_displist_t));
|
||||
|
||||
isc_mem_put(disp->mctx, disp, sizeof(dns_dispatch_t));
|
||||
isc_mem_put(mgr->mctx, disp, sizeof(dns_dispatch_t));
|
||||
}
|
||||
|
||||
|
||||
@@ -326,7 +368,8 @@ bucket_search(dns_dispatch_t *disp, isc_sockaddr_t *dest, dns_messageid_t id,
|
||||
}
|
||||
|
||||
static void
|
||||
free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
|
||||
free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len)
|
||||
{
|
||||
isc_sockettype_t socktype;
|
||||
|
||||
INSIST(buf != NULL && len != 0);
|
||||
@@ -337,13 +380,13 @@ free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
|
||||
|
||||
switch (socktype) {
|
||||
case isc_sockettype_tcp:
|
||||
isc_mem_put(disp->mctx, buf, len);
|
||||
isc_mem_put(disp->mgr->mctx, buf, len);
|
||||
break;
|
||||
case isc_sockettype_udp:
|
||||
if (len == disp->buffersize)
|
||||
isc_mempool_put(disp->bpool, buf);
|
||||
else
|
||||
isc_mem_put(disp->mctx, buf, len);
|
||||
isc_mem_put(disp->mgr->mctx, buf, len);
|
||||
break;
|
||||
default:
|
||||
INSIST(0);
|
||||
@@ -352,7 +395,8 @@ free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
|
||||
}
|
||||
|
||||
static void *
|
||||
allocate_buffer(dns_dispatch_t *disp, unsigned int len) {
|
||||
allocate_buffer(dns_dispatch_t *disp, unsigned int len)
|
||||
{
|
||||
void *temp;
|
||||
|
||||
INSIST(len > 0);
|
||||
@@ -360,7 +404,7 @@ allocate_buffer(dns_dispatch_t *disp, unsigned int len) {
|
||||
if (len == disp->buffersize)
|
||||
temp = isc_mempool_get(disp->bpool);
|
||||
else
|
||||
temp = isc_mem_get(disp->mctx, len);
|
||||
temp = isc_mem_get(disp->mgr->mctx, len);
|
||||
|
||||
if (temp != NULL)
|
||||
disp->buffers++;
|
||||
@@ -369,7 +413,8 @@ allocate_buffer(dns_dispatch_t *disp, unsigned int len) {
|
||||
}
|
||||
|
||||
static inline void
|
||||
free_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev) {
|
||||
free_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev)
|
||||
{
|
||||
if (disp->failsafe_ev == ev) {
|
||||
INSIST(disp->shutdown_out == 1);
|
||||
disp->shutdown_out = 0;
|
||||
@@ -381,7 +426,8 @@ free_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev) {
|
||||
}
|
||||
|
||||
static inline dns_dispatchevent_t *
|
||||
allocate_event(dns_dispatch_t *disp) {
|
||||
allocate_event(dns_dispatch_t *disp)
|
||||
{
|
||||
dns_dispatchevent_t *ev;
|
||||
|
||||
ev = isc_mempool_get(disp->epool);
|
||||
@@ -413,7 +459,8 @@ allocate_event(dns_dispatch_t *disp) {
|
||||
* restart.
|
||||
*/
|
||||
static void
|
||||
udp_recv(isc_task_t *task, isc_event_t *ev_in) {
|
||||
udp_recv(isc_task_t *task, isc_event_t *ev_in)
|
||||
{
|
||||
isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
|
||||
dns_dispatch_t *disp = ev_in->ev_arg;
|
||||
dns_messageid_t id;
|
||||
@@ -451,7 +498,7 @@ udp_recv(isc_task_t *task, isc_event_t *ev_in) {
|
||||
UNLOCK(&disp->lock);
|
||||
|
||||
if (killit)
|
||||
destroy(disp);
|
||||
destroy_disp(disp);
|
||||
|
||||
isc_event_free(&ev_in);
|
||||
return;
|
||||
@@ -596,7 +643,8 @@ udp_recv(isc_task_t *task, isc_event_t *ev_in) {
|
||||
* restart.
|
||||
*/
|
||||
static void
|
||||
tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
|
||||
tcp_recv(isc_task_t *task, isc_event_t *ev_in)
|
||||
{
|
||||
dns_dispatch_t *disp = ev_in->ev_arg;
|
||||
dns_tcpmsg_t *tcpmsg = &disp->tcpmsg;
|
||||
dns_messageid_t id;
|
||||
@@ -652,13 +700,13 @@ tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
|
||||
|
||||
/*
|
||||
* The event is statically allocated in the tcpmsg
|
||||
* structure, and destroy() frees the tcpmsg, so we must
|
||||
* free the event *before* calling destroy().
|
||||
* structure, and destroy_disp() frees the tcpmsg, so we must
|
||||
* free the event *before* calling destroy_disp().
|
||||
*/
|
||||
isc_event_free(&ev_in);
|
||||
|
||||
if (killit)
|
||||
destroy(disp);
|
||||
destroy_disp(disp);
|
||||
|
||||
return;
|
||||
|
||||
@@ -767,7 +815,8 @@ tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
|
||||
* disp must be locked.
|
||||
*/
|
||||
static void
|
||||
startrecv(dns_dispatch_t *disp) {
|
||||
startrecv(dns_dispatch_t *disp)
|
||||
{
|
||||
isc_sockettype_t socktype;
|
||||
isc_result_t res;
|
||||
isc_region_t region;
|
||||
@@ -825,16 +874,142 @@ startrecv(dns_dispatch_t *disp) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mgr must be locked when calling this function.
|
||||
*/
|
||||
static isc_boolean_t
|
||||
destroy_mgr_ok(dns_dispatchmgr_t *mgr)
|
||||
{
|
||||
if (!MGR_IS_SHUTTINGDOWN(mgr))
|
||||
return (ISC_FALSE);
|
||||
if (!ISC_LIST_EMPTY(mgr->list))
|
||||
return (ISC_FALSE);
|
||||
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mgr must be unlocked when calling this function.
|
||||
*/
|
||||
static void
|
||||
destroy_mgr(dns_dispatchmgr_t **mgrp)
|
||||
{
|
||||
isc_mem_t *mctx;
|
||||
dns_dispatchmgr_t *mgr;
|
||||
|
||||
mgr = *mgrp;
|
||||
*mgrp = NULL;
|
||||
|
||||
mctx = mgr->mctx;
|
||||
|
||||
mgr->magic = 0;
|
||||
mgr->mctx = 0;
|
||||
isc_mutex_destroy(&mgr->lock);
|
||||
mgr->state = 0;
|
||||
|
||||
isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t));
|
||||
isc_mem_detach(&mctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Publics.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
unsigned int maxbuffersize,
|
||||
dns_dispatchmgr_create(isc_mem_t *mctx, dns_dispatchmgr_t **mgrp)
|
||||
{
|
||||
dns_dispatchmgr_t *mgr;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(mctx != NULL);
|
||||
REQUIRE(mgrp != NULL && *mgrp == NULL);
|
||||
|
||||
mgr = isc_mem_get(mctx, sizeof(dns_dispatchmgr_t));
|
||||
if (mgr == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
result = isc_mutex_init(&mgr->lock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t));
|
||||
return (result);
|
||||
}
|
||||
|
||||
mgr->magic = DNS_DISPATCHMGR_MAGIC;
|
||||
mgr->state = 0;
|
||||
mgr->mctx = NULL;
|
||||
isc_mem_attach(mctx, &mgr->mctx);
|
||||
ISC_LIST_INIT(mgr->list);
|
||||
|
||||
*mgrp = mgr;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp)
|
||||
{
|
||||
dns_dispatchmgr_t *mgr;
|
||||
isc_boolean_t killit;
|
||||
|
||||
REQUIRE(mgrp != NULL);
|
||||
REQUIRE(VALID_DISPATCHMGR(*mgrp));
|
||||
|
||||
mgr = *mgrp;
|
||||
*mgrp = NULL;
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
mgr->state |= MGR_SHUTTINGDOWN;
|
||||
killit = destroy_mgr_ok(mgr);
|
||||
UNLOCK(&mgr->lock);
|
||||
|
||||
if (killit)
|
||||
destroy_mgr(&mgr);
|
||||
}
|
||||
|
||||
|
||||
#define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask)))
|
||||
|
||||
isc_result_t
|
||||
dns_dispatchmgr_find(dns_dispatchmgr_t *mgr, unsigned int attributes,
|
||||
unsigned int mask, dns_dispatch_t **dispp)
|
||||
{
|
||||
dns_dispatch_t *disp;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(VALID_DISPATCHMGR(mgr));
|
||||
REQUIRE(dispp != NULL && *dispp == NULL);
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
disp = ISC_LIST_HEAD(mgr->list);
|
||||
while (disp != NULL) {
|
||||
if (!IS_PRIVATE(disp)
|
||||
&& ATTRMATCH(disp->attributes, attributes, mask))
|
||||
break;
|
||||
disp = ISC_LIST_NEXT(disp, link);
|
||||
}
|
||||
|
||||
if (disp == NULL) {
|
||||
result = ISC_R_NOTFOUND;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dns_dispatch_attach(disp, dispp);
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
out:
|
||||
UNLOCK(&mgr->lock);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
isc_result_t
|
||||
dns_dispatch_create(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
|
||||
isc_task_t *task, unsigned int maxbuffersize,
|
||||
unsigned int maxbuffers, unsigned int maxrequests,
|
||||
unsigned int buckets, unsigned int increment,
|
||||
dns_dispatchmethods_t *methods,
|
||||
dns_dispatchmethods_t *methods, unsigned int attributes,
|
||||
dns_dispatch_t **dispp)
|
||||
{
|
||||
dns_dispatch_t *disp;
|
||||
@@ -842,7 +1017,7 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
isc_sockettype_t socktype;
|
||||
unsigned int i;
|
||||
|
||||
REQUIRE(mctx != NULL);
|
||||
REQUIRE(VALID_DISPATCHMGR(mgr));
|
||||
REQUIRE(sock != NULL);
|
||||
REQUIRE(task != NULL);
|
||||
REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */
|
||||
@@ -857,15 +1032,16 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
|
||||
res = ISC_R_SUCCESS;
|
||||
|
||||
disp = isc_mem_get(mctx, sizeof(dns_dispatch_t));
|
||||
disp = isc_mem_get(mgr->mctx, sizeof(dns_dispatch_t));
|
||||
if (disp == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
disp->magic = 0;
|
||||
disp->mctx = mctx;
|
||||
disp->buffersize = maxbuffersize;
|
||||
disp->maxrequests = maxrequests;
|
||||
disp->maxbuffers = maxbuffers;
|
||||
disp->attributes = attributes;
|
||||
ISC_LINK_INIT(disp, link);
|
||||
disp->refcount = 1;
|
||||
disp->recvs = 0;
|
||||
if (socktype == isc_sockettype_udp) {
|
||||
@@ -886,7 +1062,7 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
else
|
||||
disp->methods = *methods;
|
||||
|
||||
disp->qid_table = isc_mem_get(disp->mctx,
|
||||
disp->qid_table = isc_mem_get(mgr->mctx,
|
||||
buckets * sizeof(dns_displist_t));
|
||||
if (disp->qid_table == NULL) {
|
||||
res = ISC_R_NOMEMORY;
|
||||
@@ -906,7 +1082,7 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
}
|
||||
|
||||
disp->epool = NULL;
|
||||
if (isc_mempool_create(mctx, sizeof(dns_dispatchevent_t),
|
||||
if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatchevent_t),
|
||||
&disp->epool) != ISC_R_SUCCESS) {
|
||||
res = ISC_R_NOMEMORY;
|
||||
goto out3;
|
||||
@@ -914,7 +1090,7 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
isc_mempool_setname(disp->epool, "disp_epool");
|
||||
|
||||
disp->bpool = NULL;
|
||||
if (isc_mempool_create(mctx, maxbuffersize,
|
||||
if (isc_mempool_create(mgr->mctx, maxbuffersize,
|
||||
&disp->bpool) != ISC_R_SUCCESS) {
|
||||
res = ISC_R_NOMEMORY;
|
||||
goto out4;
|
||||
@@ -923,7 +1099,7 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
isc_mempool_setname(disp->bpool, "disp_bpool");
|
||||
|
||||
disp->rpool = NULL;
|
||||
if (isc_mempool_create(mctx, sizeof(dns_dispentry_t),
|
||||
if (isc_mempool_create(mgr->mctx, sizeof(dns_dispentry_t),
|
||||
&disp->rpool) != ISC_R_SUCCESS) {
|
||||
res = ISC_R_NOMEMORY;
|
||||
goto out5;
|
||||
@@ -968,6 +1144,7 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
0, reseed_lfsr, disp);
|
||||
|
||||
disp->magic = DISPATCH_MAGIC;
|
||||
disp->mgr = mgr;
|
||||
|
||||
disp->task = NULL;
|
||||
isc_task_attach(task, &disp->task);
|
||||
@@ -976,7 +1153,14 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
isc_socket_attach(sock, &disp->socket);
|
||||
dispatch_log(disp, LVL(90), "attaching to socket %p", disp->socket);
|
||||
|
||||
dns_tcpmsg_init(disp->mctx, disp->socket, &disp->tcpmsg);
|
||||
dns_tcpmsg_init(mgr->mctx, disp->socket, &disp->tcpmsg);
|
||||
|
||||
/*
|
||||
* Append it to the dispatcher list.
|
||||
*/
|
||||
LOCK(&mgr->lock);
|
||||
ISC_LIST_APPEND(mgr->list, disp, link);
|
||||
UNLOCK(&mgr->lock);
|
||||
|
||||
*dispp = disp;
|
||||
|
||||
@@ -994,34 +1178,43 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
out3:
|
||||
isc_mutex_destroy(&disp->lock);
|
||||
out2:
|
||||
isc_mem_put(mctx, disp->mctx, disp->qid_nbuckets * sizeof(void *));
|
||||
isc_mem_put(mgr->mctx, disp->mgr->mctx,
|
||||
disp->qid_nbuckets * sizeof(void *));
|
||||
out1:
|
||||
isc_mem_put(mctx, disp, sizeof(dns_dispatch_t));
|
||||
isc_mem_put(mgr->mctx, disp, sizeof(dns_dispatch_t));
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
void
|
||||
dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp) {
|
||||
dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp)
|
||||
{
|
||||
REQUIRE(VALID_DISPATCH(disp));
|
||||
REQUIRE(dispp != NULL && *dispp == NULL);
|
||||
|
||||
LOCK(&disp->lock);
|
||||
disp->refcount++;
|
||||
UNLOCK(&disp->lock);
|
||||
|
||||
*dispp = disp;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dns_dispatch_detach(dns_dispatch_t **dispp) {
|
||||
dns_dispatch_detach(dns_dispatch_t **dispp)
|
||||
{
|
||||
dns_dispatch_t *disp;
|
||||
isc_boolean_t killit;
|
||||
dns_dispatchmgr_t *mgr;
|
||||
|
||||
REQUIRE(dispp != NULL && VALID_DISPATCH(*dispp));
|
||||
|
||||
disp = *dispp;
|
||||
*dispp = NULL;
|
||||
|
||||
mgr = disp->mgr;
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
LOCK(&disp->lock);
|
||||
|
||||
INSIST(disp->refcount > 0);
|
||||
@@ -1040,7 +1233,14 @@ dns_dispatch_detach(dns_dispatch_t **dispp) {
|
||||
UNLOCK(&disp->lock);
|
||||
|
||||
if (killit)
|
||||
destroy(disp);
|
||||
destroy_disp(disp);
|
||||
|
||||
killit = destroy_mgr_ok(mgr);
|
||||
|
||||
UNLOCK(&mgr->lock);
|
||||
|
||||
if (killit)
|
||||
destroy_mgr(&mgr);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
@@ -1219,7 +1419,7 @@ dns_dispatch_removeresponse(dns_dispatch_t *disp, dns_dispentry_t **resp,
|
||||
UNLOCK(&disp->lock);
|
||||
|
||||
if (killit)
|
||||
destroy(disp);
|
||||
destroy_disp(disp);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
@@ -1360,7 +1560,7 @@ dns_dispatch_removerequest(dns_dispatch_t *disp, dns_dispentry_t **resp,
|
||||
UNLOCK(&disp->lock);
|
||||
|
||||
if (killit)
|
||||
destroy(disp);
|
||||
destroy_disp(disp);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1405,7 +1605,8 @@ dns_dispatch_freeevent(dns_dispatch_t *disp, dns_dispentry_t *resp,
|
||||
}
|
||||
|
||||
static void
|
||||
do_next_response(dns_dispatch_t *disp, dns_dispentry_t *resp) {
|
||||
do_next_response(dns_dispatch_t *disp, dns_dispentry_t *resp)
|
||||
{
|
||||
dns_dispatchevent_t *ev;
|
||||
|
||||
INSIST(resp->item_out == ISC_FALSE);
|
||||
@@ -1430,7 +1631,8 @@ do_next_response(dns_dispatch_t *disp, dns_dispentry_t *resp) {
|
||||
}
|
||||
|
||||
static void
|
||||
do_next_request(dns_dispatch_t *disp, dns_dispentry_t *resp) {
|
||||
do_next_request(dns_dispatch_t *disp, dns_dispentry_t *resp)
|
||||
{
|
||||
dns_dispatchevent_t *ev;
|
||||
|
||||
INSIST(resp->item_out == ISC_FALSE);
|
||||
@@ -1454,7 +1656,8 @@ do_next_request(dns_dispatch_t *disp, dns_dispentry_t *resp) {
|
||||
}
|
||||
|
||||
static void
|
||||
do_cancel(dns_dispatch_t *disp, dns_dispentry_t *resp) {
|
||||
do_cancel(dns_dispatch_t *disp, dns_dispentry_t *resp)
|
||||
{
|
||||
dns_dispatchevent_t *ev;
|
||||
|
||||
if (disp->shutdown_out == 1)
|
||||
@@ -1516,14 +1719,16 @@ do_cancel(dns_dispatch_t *disp, dns_dispentry_t *resp) {
|
||||
}
|
||||
|
||||
isc_socket_t *
|
||||
dns_dispatch_getsocket(dns_dispatch_t *disp) {
|
||||
dns_dispatch_getsocket(dns_dispatch_t *disp)
|
||||
{
|
||||
REQUIRE(VALID_DISPATCH(disp));
|
||||
|
||||
return (disp->socket);
|
||||
}
|
||||
|
||||
void
|
||||
dns_dispatch_cancel(dns_dispatch_t *disp) {
|
||||
dns_dispatch_cancel(dns_dispatch_t *disp)
|
||||
{
|
||||
REQUIRE(VALID_DISPATCH(disp));
|
||||
|
||||
LOCK(&disp->lock);
|
||||
@@ -1541,3 +1746,15 @@ dns_dispatch_cancel(dns_dispatch_t *disp) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
dns_dispatch_changeattributes(dns_dispatch_t *disp,
|
||||
unsigned int attributes, unsigned int mask)
|
||||
{
|
||||
LOCK(&disp->mgr->lock);
|
||||
LOCK(&disp->lock);
|
||||
disp->attributes &= ~mask;
|
||||
disp->attributes |= (attributes & mask);
|
||||
UNLOCK(&disp->lock);
|
||||
UNLOCK(&disp->mgr->lock);
|
||||
}
|
||||
|
||||
@@ -1,263 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2000 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <isc/mem.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/dispatch.h>
|
||||
#include <dns/dispatchlist.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
/*
|
||||
* This module implements a dispatch list. The items on the list are
|
||||
* dispatch objects. These dispatchers have attributes such as shared,
|
||||
* TCP, UDP, IPv4, IPv6, etc. When searching for a usable shared
|
||||
* dispatcher these flags are respected.
|
||||
*/
|
||||
|
||||
typedef struct dns__dle dns__dle_t;
|
||||
|
||||
struct dns__dle {
|
||||
dns_dispatch_t *disp;
|
||||
unsigned int attributes;
|
||||
ISC_LINK(dns__dle_t) link;
|
||||
};
|
||||
|
||||
struct dns_dispatchlist {
|
||||
/* Unlocked. */
|
||||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
|
||||
/* Locked. */
|
||||
isc_mutex_t lock;
|
||||
unsigned int state;
|
||||
ISC_LIST(dns__dle_t) list;
|
||||
};
|
||||
|
||||
#define SHUTTINGDOWN 0x00000001U
|
||||
#define IS_SHUTTINGDOWN(l) (((l)->state & SHUTTINGDOWN) != 0)
|
||||
|
||||
#define IS_PRIVATE(dle) (((dle)->attributes & DNS_DISPATCHLISTATTR_PRIVATE) \
|
||||
!= 0)
|
||||
|
||||
#define DNS_DISPATCHLIST_MAGIC ISC_MAGIC('D', 'l', 's', 't')
|
||||
#define DNS_DISPATCHLIST_VALID(a) \
|
||||
ISC_MAGIC_VALID(a, DNS_DISPATCHLIST_MAGIC)
|
||||
|
||||
|
||||
isc_result_t
|
||||
dns_dispatchlist_create(isc_mem_t *mctx, dns_dispatchlist_t **listp)
|
||||
{
|
||||
dns_dispatchlist_t *list;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(mctx != NULL);
|
||||
REQUIRE(listp != NULL && *listp == NULL);
|
||||
|
||||
list = isc_mem_get(mctx, sizeof(dns_dispatchlist_t));
|
||||
if (list == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
result = isc_mutex_init(&list->lock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_mem_put(mctx, list, sizeof(dns_dispatchlist_t));
|
||||
return (result);
|
||||
}
|
||||
|
||||
list->magic = DNS_DISPATCHLIST_MAGIC;
|
||||
list->state = 0;
|
||||
list->mctx = NULL;
|
||||
isc_mem_attach(mctx, &list->mctx);
|
||||
ISC_LIST_INIT(list->list);
|
||||
|
||||
*listp = list;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* List must be locked when calling this function.
|
||||
*/
|
||||
static isc_boolean_t
|
||||
destroy_ok(dns_dispatchlist_t *list)
|
||||
{
|
||||
if ((list->state & SHUTTINGDOWN) == 0)
|
||||
return (ISC_FALSE);
|
||||
if (!ISC_LIST_EMPTY(list->list))
|
||||
return (ISC_FALSE);
|
||||
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* List must be unlocked when calling this function.
|
||||
*/
|
||||
static void
|
||||
destroy(dns_dispatchlist_t **listp)
|
||||
{
|
||||
isc_mem_t *mctx;
|
||||
dns_dispatchlist_t *list;
|
||||
|
||||
list = *listp;
|
||||
*listp = NULL;
|
||||
|
||||
mctx = list->mctx;
|
||||
|
||||
list->magic = 0;
|
||||
list->mctx = 0;
|
||||
isc_mutex_destroy(&list->lock);
|
||||
list->state = 0;
|
||||
|
||||
isc_mem_put(mctx, list, sizeof(dns_dispatchlist_t));
|
||||
isc_mem_detach(&mctx);
|
||||
}
|
||||
|
||||
void
|
||||
dns_dispatchlist_destroy(dns_dispatchlist_t **listp)
|
||||
{
|
||||
dns_dispatchlist_t *list;
|
||||
isc_boolean_t killit;
|
||||
|
||||
REQUIRE(listp != NULL);
|
||||
REQUIRE(DNS_DISPATCHLIST_VALID(*listp));
|
||||
RUNTIME_CHECK(destroy_ok(*listp));
|
||||
|
||||
list = *listp;
|
||||
*listp = NULL;
|
||||
|
||||
LOCK(&list->lock);
|
||||
list->state |= SHUTTINGDOWN;
|
||||
killit = destroy_ok(list);
|
||||
UNLOCK(&list->lock);
|
||||
|
||||
if (killit)
|
||||
destroy(&list);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_dispatchlist_add(dns_dispatchlist_t *list, dns_dispatch_t *disp,
|
||||
unsigned int attributes)
|
||||
{
|
||||
dns__dle_t *dle;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(DNS_DISPATCHLIST_VALID(list));
|
||||
REQUIRE(disp != NULL);
|
||||
|
||||
LOCK(&list->lock);
|
||||
if (IS_SHUTTINGDOWN(list)) {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dle = isc_mem_get(list->mctx, sizeof(dns__dle_t));
|
||||
if (dle == NULL) {
|
||||
result = ISC_R_NOMEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dle->disp = NULL;
|
||||
dns_dispatch_attach(disp, &dle->disp);
|
||||
dle->attributes = attributes;
|
||||
ISC_LINK_INIT(dle, link);
|
||||
ISC_LIST_APPEND(list->list, dle, link);
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
out:
|
||||
UNLOCK(&list->lock);
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_dispatchlist_delete(dns_dispatchlist_t *list, dns_dispatch_t *disp)
|
||||
{
|
||||
dns__dle_t *dle;
|
||||
isc_result_t result;
|
||||
isc_boolean_t killit;
|
||||
|
||||
REQUIRE(DNS_DISPATCHLIST_VALID(list));
|
||||
REQUIRE(disp != NULL);
|
||||
|
||||
LOCK(&list->lock);
|
||||
dle = ISC_LIST_HEAD(list->list);
|
||||
while (dle != NULL) {
|
||||
if (dle->disp == disp)
|
||||
break;
|
||||
dle = ISC_LIST_NEXT(dle, link);
|
||||
}
|
||||
|
||||
if (dle == NULL) {
|
||||
result = ISC_R_NOTFOUND;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ISC_LIST_UNLINK(list->list, dle, link);
|
||||
dns_dispatch_detach(&dle->disp);
|
||||
|
||||
isc_mem_put(list->mctx, dle, sizeof(dns__dle_t));
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
out:
|
||||
killit = destroy_ok(list);
|
||||
UNLOCK(&list->lock);
|
||||
|
||||
if (killit)
|
||||
destroy(&list);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
#define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask)))
|
||||
|
||||
isc_result_t
|
||||
dns_dispatchlist_find(dns_dispatchlist_t *list, unsigned int attributes,
|
||||
unsigned int mask, dns_dispatch_t **dispp)
|
||||
{
|
||||
dns__dle_t *dle;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(DNS_DISPATCHLIST_VALID(list));
|
||||
REQUIRE(dispp != NULL && *dispp == NULL);
|
||||
|
||||
LOCK(&list->lock);
|
||||
dle = ISC_LIST_HEAD(list->list);
|
||||
while (dle != NULL) {
|
||||
if (!IS_PRIVATE(dle)
|
||||
&& ATTRMATCH(dle->attributes, attributes, mask))
|
||||
break;
|
||||
dle = ISC_LIST_NEXT(dle, link);
|
||||
}
|
||||
|
||||
if (dle == NULL) {
|
||||
result = ISC_R_NOTFOUND;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dns_dispatch_attach(dle->disp, dispp);
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
out:
|
||||
UNLOCK(&list->lock);
|
||||
|
||||
return (result);
|
||||
}
|
||||
@@ -105,8 +105,8 @@ struct dns_c_ctx {
|
||||
* statement. If a field is NULL then it has never been set.
|
||||
*/
|
||||
struct dns_c_options {
|
||||
isc_mem_t *mem;
|
||||
isc_uint32_t magic;
|
||||
isc_mem_t *mem;
|
||||
|
||||
char *directory;
|
||||
char *version;
|
||||
|
||||
@@ -58,8 +58,6 @@
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
#define DNS_DISPATCHEVENT_RECV (ISC_EVENTCLASS_DNS + 1) /* XXXMLG */
|
||||
|
||||
/*
|
||||
* This event is sent to a task when a response (or request) comes in.
|
||||
* No part of this structure should ever be modified by the caller,
|
||||
@@ -102,12 +100,101 @@ struct dns_dispatchmethods {
|
||||
};
|
||||
typedef struct dns_dispatchmethods dns_dispatchmethods_t;
|
||||
|
||||
/*
|
||||
* Attributes for added dispatchers.
|
||||
*
|
||||
* Values with the mask 0xffff0000 are application defined.
|
||||
* Values with the mask 0x0000ffff are library defined.
|
||||
*
|
||||
* Insane values (like setting both TCP and UDP) are not caught. Don't
|
||||
* do that.
|
||||
*
|
||||
* _PRIVATE
|
||||
* The dispatcher cannot be shared.
|
||||
*
|
||||
* _TCP, _UDP
|
||||
* The dispatcher is a TCP or UDP socket.
|
||||
*
|
||||
* _IPV4, _IPV6
|
||||
* The dispatcher uses an ipv4 or ipv6 socket.
|
||||
*
|
||||
* _REQUEST
|
||||
* The dispatcher can be used to accept requests.
|
||||
*
|
||||
* _RESPONSE
|
||||
* The dispatcher can be used to issue queries to other servers, and
|
||||
* accept replies from them.
|
||||
*/
|
||||
#define DNS_DISPATCHATTR_PRIVATE 0x00000001U
|
||||
#define DNS_DISPATCHATTR_TCP 0x00000002U
|
||||
#define DNS_DISPATCHATTR_UDP 0x00000004U
|
||||
#define DNS_DISPATCHATTR_IPV4 0x00000008U
|
||||
#define DNS_DISPATCHATTR_IPV6 0x00000010U
|
||||
#define DNS_DISPATCHATTR_ACCEPTREQUEST 0x00000020U
|
||||
#define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
isc_result_t
|
||||
dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
unsigned int maxbuffersize,
|
||||
dns_dispatchmgr_create(isc_mem_t *mctx, dns_dispatchmgr_t **mgrp);
|
||||
/*
|
||||
* Creates a new dispatchmgr object.
|
||||
*
|
||||
* Requires:
|
||||
* "mctx" be a valid memory context.
|
||||
*
|
||||
* mgrp != NULL && *mgrp == NULL
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS -- all ok
|
||||
*
|
||||
* anything else -- failure
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp);
|
||||
/*
|
||||
* Destroys the dispatchmgr when it becomes empty. This could be
|
||||
* immediately.
|
||||
*
|
||||
* Requires:
|
||||
* mgrp != NULL && *mgrp is a valid dispatchmgr.
|
||||
*/
|
||||
|
||||
|
||||
isc_result_t
|
||||
dns_dispatchmgr_find(dns_dispatchmgr_t *mgr, unsigned int attributes,
|
||||
unsigned int mask, dns_dispatch_t **dispp);
|
||||
/*
|
||||
* Search for a dispatcher that has the attributes specified by
|
||||
* (attributes & mask)
|
||||
*
|
||||
* Requires:
|
||||
* "mgr" be a valid dispatchmgr.
|
||||
*
|
||||
* dispp != NULL && *dispp == NULL.
|
||||
*
|
||||
* Ensures:
|
||||
* The dispatcher returned into *dispp is attached on behalf of the
|
||||
* caller. It is required that the caller detach from it when it is
|
||||
* no longer needed.
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS -- found.
|
||||
*
|
||||
* ISC_R_NOTFOUND -- no dispatcher matching the requirements found.
|
||||
*
|
||||
* anything else -- failure.
|
||||
*/
|
||||
|
||||
|
||||
isc_result_t
|
||||
dns_dispatch_create(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
|
||||
isc_task_t *task, unsigned int maxbuffersize,
|
||||
unsigned int maxbuffers, unsigned int maxrequests,
|
||||
unsigned int buckets, unsigned int increment,
|
||||
dns_dispatchmethods_t *methods,
|
||||
dns_dispatchmethods_t *methods, unsigned int attributes,
|
||||
dns_dispatch_t **dispp);
|
||||
/*
|
||||
* Create a new dns_dispatch and attach it to the provided isc_socket_t.
|
||||
@@ -130,7 +217,7 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* mctx is a valid memory context.
|
||||
* mgr is a valid dispatch manager.
|
||||
*
|
||||
* sock is a valid.
|
||||
*
|
||||
@@ -148,6 +235,7 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
* increment > buckets (and prime)
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp);
|
||||
/*
|
||||
@@ -163,6 +251,7 @@ dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp);
|
||||
* < mumble >
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
dns_dispatch_detach(dns_dispatch_t **dispp);
|
||||
/*
|
||||
@@ -178,6 +267,7 @@ dns_dispatch_detach(dns_dispatch_t **dispp);
|
||||
* < mumble >
|
||||
*/
|
||||
|
||||
|
||||
isc_result_t
|
||||
dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
@@ -214,6 +304,7 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
|
||||
* for this destination.
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
dns_dispatch_removeresponse(dns_dispatch_t *disp, dns_dispentry_t **resp,
|
||||
dns_dispatchevent_t **sockevent);
|
||||
@@ -233,6 +324,7 @@ dns_dispatch_removeresponse(dns_dispatch_t *disp, dns_dispentry_t **resp,
|
||||
* < mumble >
|
||||
*/
|
||||
|
||||
|
||||
isc_result_t
|
||||
dns_dispatch_addrequest(dns_dispatch_t *disp,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
@@ -252,6 +344,7 @@ dns_dispatch_addrequest(dns_dispatch_t *disp,
|
||||
* < mumble >
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
dns_dispatch_removerequest(dns_dispatch_t *disp, dns_dispentry_t **resp,
|
||||
dns_dispatchevent_t **sockevent);
|
||||
@@ -270,6 +363,7 @@ dns_dispatch_removerequest(dns_dispatch_t *disp, dns_dispentry_t **resp,
|
||||
* < mumble >
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
dns_dispatch_freeevent(dns_dispatch_t *disp, dns_dispentry_t *resp,
|
||||
dns_dispatchevent_t **sockevent);
|
||||
@@ -288,16 +382,53 @@ dns_dispatch_freeevent(dns_dispatch_t *disp, dns_dispentry_t *resp,
|
||||
* < mumble >
|
||||
*/
|
||||
|
||||
|
||||
isc_socket_t *
|
||||
dns_dispatch_getsocket(dns_dispatch_t *disp);
|
||||
/*
|
||||
* Return the socket associated with this dispatcher
|
||||
* Return the socket associated with this dispatcher.
|
||||
*
|
||||
* Requires:
|
||||
* < mumble >
|
||||
*
|
||||
* Ensures:
|
||||
* < mumble >
|
||||
*
|
||||
* Returns:
|
||||
* < mumble >
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
dns_dispatch_cancel(dns_dispatch_t *disp);
|
||||
/*
|
||||
* cancel outstanding clients
|
||||
*
|
||||
* Requires:
|
||||
* < mumble >
|
||||
*
|
||||
* Ensures:
|
||||
* < mumble >
|
||||
*
|
||||
* Returns:
|
||||
* < mumble >
|
||||
*/
|
||||
|
||||
void
|
||||
dns_dispatch_changeattributes(dns_dispatch_t *disp,
|
||||
unsigned int attributes, unsigned int mask);
|
||||
/*
|
||||
* Set the bits described by "mask" to the corresponding values in
|
||||
* "attributes".
|
||||
*
|
||||
* Requires:
|
||||
* < mumble >
|
||||
*
|
||||
* Ensures:
|
||||
* < mumble >
|
||||
*
|
||||
* Returns:
|
||||
* < mumble >
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2000 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
#ifndef DNS_DISPATCHLIST_H
|
||||
#define DNS_DISPATCHLIST_H 1
|
||||
|
||||
/*****
|
||||
***** Module Info
|
||||
*****/
|
||||
|
||||
/*
|
||||
* DNS Dispatch List Management
|
||||
*
|
||||
* Maintains a list of dispatchers to help various parts of the DNS
|
||||
* library and applications keep track and share dispatchers.
|
||||
*
|
||||
* MP:
|
||||
*
|
||||
* All locking is performed internally to each list.
|
||||
*
|
||||
* dns_dispatchlist_find() will return dispatches which are
|
||||
* attached.
|
||||
*
|
||||
* Reliability:
|
||||
*
|
||||
* Resources:
|
||||
*
|
||||
* Security:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* Standards:
|
||||
*
|
||||
* None.
|
||||
*/
|
||||
|
||||
/***
|
||||
*** Imports
|
||||
***/
|
||||
|
||||
#include <isc/lang.h>
|
||||
|
||||
#include <dns/types.h>
|
||||
|
||||
/*
|
||||
* Attributes for added dispatchers.
|
||||
*
|
||||
* Values with the mask 0xffff0000 are application defined.
|
||||
* Values with the mask 0x0000ffff are library defined.
|
||||
*
|
||||
* Insane values (like setting both TCP and UDP) are not caught. Don't
|
||||
* do that.
|
||||
*/
|
||||
#define DNS_DISPATCHLISTATTR_PRIVATE 0x00000001U
|
||||
#define DNS_DISPATCHLISTATTR_TCP 0x00000002U
|
||||
#define DNS_DISPATCHLISTATTR_UDP 0x00000004U
|
||||
#define DNS_DISPATCHLISTATTR_IPV4 0x00000008U
|
||||
#define DNS_DISPATCHLISTATTR_IPV6 0x00000010U
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
isc_result_t
|
||||
dns_dispatchlist_create(isc_mem_t *mctx, dns_dispatchlist_t **listp);
|
||||
/*
|
||||
* Creates a new dispatchlist object.
|
||||
*
|
||||
* Requires:
|
||||
* "mctx" be a valid memory context.
|
||||
*
|
||||
* listp != NULL && *listp == NULL
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS -- all ok
|
||||
*
|
||||
* anything else -- failure
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
dns_dispatchlist_destroy(dns_dispatchlist_t **listp);
|
||||
/*
|
||||
* Destroys the dispatchlist when it becomes empty. This could be
|
||||
* immediately.
|
||||
*
|
||||
* Requires:
|
||||
* listp != NULL && *listp is a valid dispatchlist.
|
||||
*/
|
||||
|
||||
|
||||
isc_result_t
|
||||
dns_dispatchlist_add(dns_dispatchlist_t *list, dns_dispatch_t *disp,
|
||||
unsigned int attributes);
|
||||
/*
|
||||
* Add a new dispatch object to the dispatch list with the attributes
|
||||
* supplied.
|
||||
*
|
||||
* Requires:
|
||||
* "list" be a valid dispatchlist.
|
||||
*
|
||||
* "disp" be a valid dispatcher that is not already present on "list"
|
||||
*
|
||||
* Ensures:
|
||||
* On successful return, the dispatcher is attached, preventing it
|
||||
* from being deleted while on the dispatchlist.
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS -- added.
|
||||
*
|
||||
* anything else -- failure.
|
||||
*/
|
||||
|
||||
|
||||
isc_result_t
|
||||
dns_dispatchlist_delete(dns_dispatchlist_t *list, dns_dispatch_t *disp);
|
||||
/*
|
||||
* Deletes the dispatcher from the list.
|
||||
*
|
||||
* Requires:
|
||||
* "list" be a valid dispatchlist.
|
||||
*
|
||||
* "disp" be a valid dispatcher.
|
||||
*
|
||||
* Ensures:
|
||||
* On successful return, the dispatcher is detached once, allowing it
|
||||
* to be deleted.
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS -- deleted.
|
||||
*
|
||||
* ISC_R_NOTFOUND -- dispatcher is not on the list.
|
||||
*
|
||||
* anything else -- failure.
|
||||
*/
|
||||
|
||||
|
||||
isc_result_t
|
||||
dns_dispatchlist_find(dns_dispatchlist_t *list, unsigned int attributes,
|
||||
unsigned int mask, dns_dispatch_t **dispp);
|
||||
/*
|
||||
* Search for a dispatcher that has the attributes specified by
|
||||
* (attributes & mask)
|
||||
*
|
||||
* Requires:
|
||||
* "list" be a valid dispatchlist.
|
||||
*
|
||||
* dispp != NULL && *dispp == NULL.
|
||||
*
|
||||
* Ensures:
|
||||
* The dispatcher returned into *dispp is attached on behalf of the
|
||||
* caller. It is required that the caller detach from it when it is
|
||||
* no longer needed.
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS -- found.
|
||||
*
|
||||
* ISC_R_NOTFOUND -- no dispatcher matching the requirements found.
|
||||
*
|
||||
* anything else -- failure.
|
||||
*/
|
||||
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_DISPATCHLIST_H */
|
||||
@@ -57,6 +57,7 @@ ISC_LANG_BEGINDECLS
|
||||
isc_result_t
|
||||
dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
|
||||
isc_socketmgr_t *socketmgr,
|
||||
dns_dispatchmgr_t *dispatchmgr,
|
||||
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
|
||||
dns_requestmgr_t **requestmgrp);
|
||||
/*
|
||||
|
||||
@@ -94,6 +94,7 @@ dns_resolver_create(dns_view_t *view,
|
||||
isc_socketmgr_t *socketmgr,
|
||||
isc_timermgr_t *timermgr,
|
||||
unsigned int options,
|
||||
dns_dispatchmgr_t *dispatchmgr,
|
||||
dns_dispatch_t *dispatchv4,
|
||||
dns_dispatch_t *dispatchv6,
|
||||
dns_resolver_t **resp);
|
||||
@@ -338,6 +339,9 @@ dns_resolver_destroyfetch(dns_fetch_t **fetchp);
|
||||
* *fetchp == NULL.
|
||||
*/
|
||||
|
||||
dns_dispatchmgr_t *
|
||||
dns_resolver_dispatchmgr(dns_resolver_t *resolver);
|
||||
|
||||
dns_dispatch_t *
|
||||
dns_resolver_dispatchv4(dns_resolver_t *resolver);
|
||||
|
||||
|
||||
@@ -52,6 +52,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_dispatchmgr dns_dispatchmgr_t;
|
||||
typedef struct dns_dispentry dns_dispentry_t;
|
||||
typedef struct dns_fetch dns_fetch_t;
|
||||
typedef struct dns_fixedname dns_fixedname_t;
|
||||
|
||||
@@ -191,6 +191,7 @@ dns_view_createresolver(dns_view_t *view,
|
||||
isc_socketmgr_t *socketmgr,
|
||||
isc_timermgr_t *timermgr,
|
||||
unsigned int options,
|
||||
dns_dispatchmgr_t *dispatchmgr,
|
||||
dns_dispatch_t *dispatchv4,
|
||||
dns_dispatch_t *dispatchv6);
|
||||
/*
|
||||
|
||||
@@ -42,37 +42,38 @@ typedef ISC_LIST(dns_request_t) dns_requestlist_t;
|
||||
#define DNS_REQUEST_NLOCKS 7
|
||||
|
||||
struct dns_requestmgr {
|
||||
isc_int32_t magic;
|
||||
isc_mutex_t lock;
|
||||
isc_mem_t *mctx;
|
||||
isc_int32_t magic;
|
||||
isc_mutex_t lock;
|
||||
isc_mem_t *mctx;
|
||||
|
||||
/* locked */
|
||||
isc_int32_t eref;
|
||||
isc_int32_t iref;
|
||||
isc_timermgr_t *timermgr;
|
||||
isc_socketmgr_t *socketmgr;
|
||||
dns_dispatch_t *dispatchv4;
|
||||
dns_dispatch_t *dispatchv6;
|
||||
isc_boolean_t exiting;
|
||||
isc_eventlist_t whenshutdown;
|
||||
unsigned int hash;
|
||||
isc_mutex_t locks[DNS_REQUEST_NLOCKS];
|
||||
dns_requestlist_t requests;
|
||||
isc_int32_t eref;
|
||||
isc_int32_t iref;
|
||||
isc_timermgr_t *timermgr;
|
||||
isc_socketmgr_t *socketmgr;
|
||||
dns_dispatchmgr_t *dispatchmgr;
|
||||
dns_dispatch_t *dispatchv4;
|
||||
dns_dispatch_t *dispatchv6;
|
||||
isc_boolean_t exiting;
|
||||
isc_eventlist_t whenshutdown;
|
||||
unsigned int hash;
|
||||
isc_mutex_t locks[DNS_REQUEST_NLOCKS];
|
||||
dns_requestlist_t requests;
|
||||
};
|
||||
|
||||
struct dns_request {
|
||||
isc_int32_t magic;
|
||||
unsigned int hash;
|
||||
isc_mem_t *mctx;
|
||||
isc_int32_t flags;
|
||||
ISC_LINK(dns_request_t) link;
|
||||
isc_buffer_t *query;
|
||||
isc_buffer_t *answer;
|
||||
dns_requestevent_t *event;
|
||||
dns_dispatch_t *dispatch;
|
||||
dns_dispentry_t *dispentry;
|
||||
isc_timer_t *timer;
|
||||
dns_requestmgr_t *requestmgr;
|
||||
isc_int32_t magic;
|
||||
unsigned int hash;
|
||||
isc_mem_t *mctx;
|
||||
isc_int32_t flags;
|
||||
ISC_LINK(dns_request_t) link;
|
||||
isc_buffer_t *query;
|
||||
isc_buffer_t *answer;
|
||||
dns_requestevent_t *event;
|
||||
dns_dispatch_t *dispatch;
|
||||
dns_dispentry_t *dispentry;
|
||||
isc_timer_t *timer;
|
||||
dns_requestmgr_t *requestmgr;
|
||||
};
|
||||
|
||||
#define DNS_REQUEST_F_CONNECTING 0x0001
|
||||
@@ -110,6 +111,7 @@ isc_result_t
|
||||
dns_requestmgr_create(isc_mem_t *mctx,
|
||||
isc_timermgr_t *timermgr,
|
||||
isc_socketmgr_t *socketmgr,
|
||||
dns_dispatchmgr_t *dispatchmgr,
|
||||
dns_dispatch_t *dispatchv4,
|
||||
dns_dispatch_t *dispatchv6,
|
||||
dns_requestmgr_t **requestmgrp)
|
||||
@@ -124,6 +126,7 @@ dns_requestmgr_create(isc_mem_t *mctx,
|
||||
REQUIRE(requestmgrp != NULL && *requestmgrp == NULL);
|
||||
REQUIRE(timermgr != NULL);
|
||||
REQUIRE(socketmgr != NULL);
|
||||
REQUIRE(dispatchmgr != NULL);
|
||||
if (dispatchv4 != NULL) {
|
||||
socket = dns_dispatch_getsocket(dispatchv4);
|
||||
REQUIRE(isc_socket_gettype(socket) == isc_sockettype_udp);
|
||||
@@ -154,6 +157,7 @@ dns_requestmgr_create(isc_mem_t *mctx,
|
||||
}
|
||||
requestmgr->timermgr = timermgr;
|
||||
requestmgr->socketmgr = socketmgr;
|
||||
requestmgr->dispatchmgr = dispatchmgr;
|
||||
requestmgr->dispatchv4 = NULL;
|
||||
if (dispatchv4 != NULL)
|
||||
dns_dispatch_attach(dispatchv4, &requestmgr->dispatchv4);
|
||||
@@ -419,6 +423,7 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
|
||||
isc_interval_t interval;
|
||||
dns_messageid_t id;
|
||||
isc_time_t expires;
|
||||
unsigned int attrs;
|
||||
|
||||
REQUIRE(VALID_REQUESTMGR(requestmgr));
|
||||
REQUIRE(message != NULL);
|
||||
@@ -479,8 +484,17 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
|
||||
isc_sockettype_tcp, &socket);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
result = dns_dispatch_create(mctx, socket, task,
|
||||
4096, 2, 1, 1, 3, NULL,
|
||||
attrs = 0;
|
||||
attrs |= DNS_DISPATCHATTR_TCP;
|
||||
attrs |= DNS_DISPATCHATTR_PRIVATE;
|
||||
if (isc_sockaddr_pf(address) == AF_INET)
|
||||
attrs |= DNS_DISPATCHATTR_IPV4;
|
||||
else
|
||||
attrs |= DNS_DISPATCHATTR_IPV6;
|
||||
attrs |= DNS_DISPATCHATTR_MAKEQUERY;
|
||||
result = dns_dispatch_create(requestmgr->dispatchmgr,
|
||||
socket, task,
|
||||
4096, 2, 1, 1, 3, NULL, attrs,
|
||||
&request->dispatch);
|
||||
isc_socket_detach(&socket);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
|
||||
@@ -214,6 +214,7 @@ struct dns_resolver {
|
||||
unsigned int options;
|
||||
isc_socket_t * udpsocketv4;
|
||||
isc_socket_t * udpsocketv6;
|
||||
dns_dispatchmgr_t * dispatchmgr;
|
||||
dns_dispatch_t * dispatchv4;
|
||||
dns_dispatch_t * dispatchv6;
|
||||
unsigned int nbuckets;
|
||||
@@ -615,6 +616,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
||||
isc_result_t result;
|
||||
resquery_t *query;
|
||||
isc_socket_t *socket;
|
||||
unsigned int attrs;
|
||||
|
||||
FCTXTRACE("query");
|
||||
|
||||
@@ -659,8 +661,16 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
||||
&socket);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_query;
|
||||
result = dns_dispatch_create(res->mctx, socket, task,
|
||||
4096, 2, 1, 1, 3, NULL,
|
||||
attrs = 0;
|
||||
attrs |= DNS_DISPATCHATTR_TCP;
|
||||
attrs |= DNS_DISPATCHATTR_PRIVATE;
|
||||
if (isc_sockaddr_pf(addrinfo->sockaddr) == AF_INET)
|
||||
attrs |= DNS_DISPATCHATTR_IPV4;
|
||||
else
|
||||
attrs |= DNS_DISPATCHATTR_IPV6;
|
||||
attrs |= DNS_DISPATCHATTR_MAKEQUERY;
|
||||
result = dns_dispatch_create(res->dispatchmgr, socket, task,
|
||||
4096, 2, 1, 1, 3, NULL, attrs,
|
||||
&query->dispatch);
|
||||
/*
|
||||
* Regardless of whether dns_dispatch_create() succeeded or
|
||||
@@ -3911,6 +3921,7 @@ dns_resolver_create(dns_view_t *view,
|
||||
isc_socketmgr_t *socketmgr,
|
||||
isc_timermgr_t *timermgr,
|
||||
unsigned int options,
|
||||
dns_dispatchmgr_t *dispatchmgr,
|
||||
dns_dispatch_t *dispatchv4,
|
||||
dns_dispatch_t *dispatchv6,
|
||||
dns_resolver_t **resp)
|
||||
@@ -3919,6 +3930,7 @@ dns_resolver_create(dns_view_t *view,
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
unsigned int i, buckets_created = 0;
|
||||
char name[16];
|
||||
unsigned int attrs;
|
||||
|
||||
/*
|
||||
* Create a resolver.
|
||||
@@ -3927,6 +3939,7 @@ dns_resolver_create(dns_view_t *view,
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
REQUIRE(ntasks > 0);
|
||||
REQUIRE(resp != NULL && *resp == NULL);
|
||||
REQUIRE(dispatchmgr != NULL);
|
||||
|
||||
res = isc_mem_get(view->mctx, sizeof *res);
|
||||
if (res == NULL)
|
||||
@@ -3936,6 +3949,7 @@ dns_resolver_create(dns_view_t *view,
|
||||
res->rdclass = view->rdclass;
|
||||
res->socketmgr = socketmgr;
|
||||
res->timermgr = timermgr;
|
||||
res->dispatchmgr = dispatchmgr;
|
||||
res->view = view;
|
||||
res->options = options;
|
||||
|
||||
@@ -3972,6 +3986,8 @@ dns_resolver_create(dns_view_t *view,
|
||||
if (dispatchv4 != NULL) {
|
||||
dns_dispatch_attach(dispatchv4, &res->dispatchv4);
|
||||
} else if (isc_net_probeipv4() == ISC_R_SUCCESS) {
|
||||
isc_sockaddr_t saddr;
|
||||
|
||||
/*
|
||||
* Create an IPv4 UDP socket and a dispatcher for it.
|
||||
*/
|
||||
@@ -3980,10 +3996,22 @@ dns_resolver_create(dns_view_t *view,
|
||||
&res->udpsocketv4);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_buckets;
|
||||
result = dns_dispatch_create(res->mctx, res->udpsocketv4,
|
||||
isc_sockaddr_any(&saddr);
|
||||
#if 0 /* XXXMLG */
|
||||
result = isc_socket_bind(res->udpsocketv4, &saddr);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_udpsocketv4;
|
||||
#endif
|
||||
attrs = 0;
|
||||
attrs |= DNS_DISPATCHATTR_UDP;
|
||||
attrs |= DNS_DISPATCHATTR_PRIVATE;
|
||||
attrs |= DNS_DISPATCHATTR_IPV4;
|
||||
attrs |= DNS_DISPATCHATTR_MAKEQUERY;
|
||||
result = dns_dispatch_create(res->dispatchmgr,
|
||||
res->udpsocketv4,
|
||||
res->buckets[0].task, 4096,
|
||||
1000, 32768, 16411, 16433, NULL,
|
||||
&res->dispatchv4);
|
||||
attrs, &res->dispatchv4);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_udpsocketv4;
|
||||
}
|
||||
@@ -3996,6 +4024,7 @@ dns_resolver_create(dns_view_t *view,
|
||||
if (dispatchv6 != NULL) {
|
||||
dns_dispatch_attach(dispatchv6, &res->dispatchv6);
|
||||
} else if (isc_net_probeipv6() == ISC_R_SUCCESS) {
|
||||
isc_sockaddr_t saddr;
|
||||
/*
|
||||
* Create an IPv6 UDP socket and a dispatcher for it.
|
||||
*/
|
||||
@@ -4004,10 +4033,22 @@ dns_resolver_create(dns_view_t *view,
|
||||
&res->udpsocketv6);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_dispatchv4;
|
||||
result = dns_dispatch_create(res->mctx, res->udpsocketv6,
|
||||
isc_sockaddr_any6(&saddr);
|
||||
#if 0 /* XXXMLG */
|
||||
result = isc_socket_bind(res->udpsocketv6, &saddr);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_udpsocketv6;
|
||||
#endif
|
||||
attrs = 0;
|
||||
attrs |= DNS_DISPATCHATTR_UDP;
|
||||
attrs |= DNS_DISPATCHATTR_PRIVATE;
|
||||
attrs |= DNS_DISPATCHATTR_IPV6;
|
||||
attrs |= DNS_DISPATCHATTR_MAKEQUERY;
|
||||
result = dns_dispatch_create(res->dispatchmgr,
|
||||
res->udpsocketv6,
|
||||
res->buckets[0].task, 4096,
|
||||
1000, 32768, 16411, 16433, NULL,
|
||||
&res->dispatchv6);
|
||||
attrs, &res->dispatchv6);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_udpsocketv6;
|
||||
}
|
||||
@@ -4593,6 +4634,12 @@ dns_resolver_destroyfetch(dns_fetch_t **fetchp) {
|
||||
empty_bucket(res);
|
||||
}
|
||||
|
||||
dns_dispatchmgr_t *
|
||||
dns_resolver_dispatchmgr(dns_resolver_t *resolver) {
|
||||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
return (resolver->dispatchmgr);
|
||||
}
|
||||
|
||||
dns_dispatch_t *
|
||||
dns_resolver_dispatchv4(dns_resolver_t *resolver) {
|
||||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
|
||||
@@ -376,6 +376,7 @@ dns_view_createresolver(dns_view_t *view,
|
||||
isc_socketmgr_t *socketmgr,
|
||||
isc_timermgr_t *timermgr,
|
||||
unsigned int options,
|
||||
dns_dispatchmgr_t *dispatchmgr,
|
||||
dns_dispatch_t *dispatchv4,
|
||||
dns_dispatch_t *dispatchv6)
|
||||
{
|
||||
@@ -396,7 +397,8 @@ dns_view_createresolver(dns_view_t *view,
|
||||
isc_task_setname(view->task, "view", view);
|
||||
|
||||
result = dns_resolver_create(view, taskmgr, ntasks, socketmgr,
|
||||
timermgr, options, dispatchv4, dispatchv6,
|
||||
timermgr, options, dispatchmgr,
|
||||
dispatchv4, dispatchv6,
|
||||
&view->resolver);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_task_detach(&view->task);
|
||||
@@ -417,6 +419,7 @@ dns_view_createresolver(dns_view_t *view,
|
||||
view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN;
|
||||
|
||||
result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
|
||||
dns_resolver_dispatchmgr(view->resolver),
|
||||
dns_resolver_dispatchv4(view->resolver),
|
||||
dns_resolver_dispatchv6(view->resolver),
|
||||
&view->requestmgr);
|
||||
|
||||
Reference in New Issue
Block a user