2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-02 07:35:26 +00:00

Merge the mlg-20000518 branch onto the mainline. Change summary:

dns_dispatch_create() no longer exists.  dns_dispatch_createtcp()
	and dns_dispatch_getudp() are the replacements.  _createtcp() takes
	a bound, connected TCP socket, while _getudp() will search for
	a sharable UDP socket, and if found, attach to it and return a
	pointer to it.  If one is not found, it will create a udp socket,
	bind it to a supplied local address, and create a new dispatcher
	around it.

	dns_dispatch_remove{request,response}() no longer take the dispatch
	as an argument.

	query-source can now be set per view.

	The dispatch manager holds onto three memory pools, one for
	allocating dispatchers from, one for events, and one for
	requests/replies.  The free list on these pools is hard-coded,
	but set to 1024.  This keeps us from having to dig into the
	isc_mem_t the pools draw from as often.

	dns_resolver_create() and dns_view_createresolver() require that
	valid dispatchers be passed in; dispatchers are no longer created
	for the caller.
This commit is contained in:
Michael Graff
2000-05-19 21:46:46 +00:00
parent 244b9e154b
commit 46993e1d9d
14 changed files with 924 additions and 700 deletions

View File

@@ -183,9 +183,7 @@ client_deactivate(ns_client_t *client) {
deventp = &client->dispevent; deventp = &client->dispevent;
else else
deventp = NULL; deventp = NULL;
dns_dispatch_removerequest(client->dispatch, dns_dispatch_removerequest(&client->dispentry, deventp);
&client->dispentry,
deventp);
} }
if (client->dispatch != NULL) if (client->dispatch != NULL)
dns_dispatch_detach(&client->dispatch); dns_dispatch_detach(&client->dispatch);

View File

@@ -56,10 +56,6 @@ struct ns_server {
ns_interfacemgr_t * interfacemgr; ns_interfacemgr_t * interfacemgr;
dns_db_t * in_roothints; dns_db_t * in_roothints;
dns_tkey_ctx_t * tkeyctx; dns_tkey_ctx_t * tkeyctx;
isc_sockaddr_t querysrc_addressv4;
dns_dispatch_t * querysrc_dispatchv4;
isc_sockaddr_t querysrc_addressv6;
dns_dispatch_t * querysrc_dispatchv6;
isc_timer_t * interface_timer; isc_timer_t * interface_timer;
isc_mutex_t reload_event_lock; isc_mutex_t reload_event_lock;

View File

@@ -197,7 +197,6 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
} }
isc_task_setname(ifp->task, "ifp", ifp); isc_task_setname(ifp->task, "ifp", ifp);
ifp->udpsocket = NULL;
ifp->udpdispatch = NULL; ifp->udpdispatch = NULL;
ifp->tcpsocket = NULL; ifp->tcpsocket = NULL;
@@ -232,38 +231,21 @@ static isc_result_t
ns_interface_listenudp(ns_interface_t *ifp) { ns_interface_listenudp(ns_interface_t *ifp) {
isc_result_t result; isc_result_t result;
unsigned int attrs; unsigned int attrs;
unsigned int attrmask;
/*
* Open a UDP socket.
*/
result = isc_socket_create(ifp->mgr->socketmgr,
isc_sockaddr_pf(&ifp->addr),
isc_sockettype_udp,
&ifp->udpsocket);
if (result != ISC_R_SUCCESS) {
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
"creating UDP socket: %s",
isc_result_totext(result));
goto udp_socket_failure;
}
result = isc_socket_bind(ifp->udpsocket, &ifp->addr);
if (result != ISC_R_SUCCESS) {
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
"binding UDP socket: %s",
isc_result_totext(result));
goto udp_bind_failure;
}
attrs = 0; attrs = 0;
attrs |= DNS_DISPATCHATTR_UDP; attrs |= DNS_DISPATCHATTR_UDP;
if (isc_sockaddr_pf(&ifp->addr) == AF_INET) if (isc_sockaddr_pf(&ifp->addr) == AF_INET)
attrs |= DNS_DISPATCHATTR_IPV4; attrs |= DNS_DISPATCHATTR_IPV4;
else else
attrs |= DNS_DISPATCHATTR_IPV6; attrs |= DNS_DISPATCHATTR_IPV6;
attrs |= DNS_DISPATCHATTR_MAKEQUERY; attrmask = 0;
attrs |= DNS_DISPATCHATTR_ACCEPTREQUEST; attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP;
result = dns_dispatch_create(ifp->mgr->dispatchmgr, ifp->udpsocket, attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6;
ifp->task, 4096, 1000, 32768, 8219, result = dns_dispatch_getudp(ifp->mgr->dispatchmgr, ns_g_socketmgr,
8237, NULL, attrs, &ifp->udpdispatch); ns_g_taskmgr, &ifp->addr,
4096, 1000, 32768, 8219, 8237,
attrs, attrmask, &ifp->udpdispatch);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__, UNEXPECTED_ERROR(__FILE__, __LINE__,
"UDP dns_dispatch_create(): %s", "UDP dns_dispatch_create(): %s",
@@ -284,9 +266,6 @@ ns_interface_listenudp(ns_interface_t *ifp) {
addtodispatch_failure: addtodispatch_failure:
dns_dispatch_detach(&ifp->udpdispatch); dns_dispatch_detach(&ifp->udpdispatch);
udp_dispatch_failure: udp_dispatch_failure:
udp_bind_failure:
isc_socket_detach(&ifp->udpsocket);
udp_socket_failure:
return (result); return (result);
} }
@@ -383,10 +362,6 @@ ns_interface_destroy(ns_interface_t *ifp) {
if (ifp->udpdispatch != NULL) if (ifp->udpdispatch != NULL)
dns_dispatch_detach(&ifp->udpdispatch); dns_dispatch_detach(&ifp->udpdispatch);
if (ifp->udpsocket != NULL) {
isc_socket_cancel(ifp->udpsocket, NULL, ISC_SOCKCANCEL_ALL);
isc_socket_detach(&ifp->udpsocket);
}
if (ifp->tcpsocket != NULL) { if (ifp->tcpsocket != NULL) {
isc_socket_cancel(ifp->tcpsocket, NULL, ISC_SOCKCANCEL_ALL); isc_socket_cancel(ifp->tcpsocket, NULL, ISC_SOCKCANCEL_ALL);
isc_socket_detach(&ifp->tcpsocket); isc_socket_detach(&ifp->tcpsocket);

View File

@@ -260,14 +260,6 @@ create_managers(void) {
return (ISC_R_UNEXPECTED); 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); return (ISC_R_SUCCESS);
} }
@@ -284,7 +276,6 @@ destroy_managers(void) {
isc_taskmgr_destroy(&ns_g_taskmgr); isc_taskmgr_destroy(&ns_g_taskmgr);
isc_timermgr_destroy(&ns_g_timermgr); isc_timermgr_destroy(&ns_g_timermgr);
isc_socketmgr_destroy(&ns_g_socketmgr); isc_socketmgr_destroy(&ns_g_socketmgr);
dns_dispatchmgr_destroy(&ns_g_dispatchmgr);
} }
static void static void

View File

@@ -262,6 +262,96 @@ configure_view_dnsseckeys(dns_c_ctx_t *cctx,
} }
/*
* Get a dispatch appropriate for the resolver of a given view.
*/
static isc_result_t
get_view_querysource_dispatch(dns_c_ctx_t *cctx, dns_c_view_t *cview,
int af, dns_dispatch_t **dispatchp)
{
isc_result_t result;
dns_dispatch_t *disp;
isc_sockaddr_t sa;
unsigned int attrs, attrmask;
/*
* Make compiler happy.
*/
result = ISC_R_FAILURE;
switch (af) {
case AF_INET:
result = ISC_R_NOTFOUND;
if (cview != NULL)
result = dns_c_view_getquerysource(cview, &sa);
if (result != ISC_R_SUCCESS)
result = dns_c_ctx_getquerysource(cctx, &sa);
if (result != ISC_R_SUCCESS)
isc_sockaddr_any(&sa);
break;
case AF_INET6:
result = ISC_R_NOTFOUND;
if (cview != NULL)
result = dns_c_view_getquerysourcev6(cview, &sa);
if (result != ISC_R_SUCCESS)
result = dns_c_ctx_getquerysourcev6(cctx, &sa);
if (result != ISC_R_SUCCESS)
isc_sockaddr_any6(&sa);
break;
default:
INSIST(0);
}
INSIST(isc_sockaddr_pf(&sa) == af);
/*
* If we don't support this address family, we're done!
*/
switch (af) {
case AF_INET:
result = isc_net_probeipv4();
break;
case AF_INET6:
result = isc_net_probeipv6();
break;
default:
INSIST(0);
}
if (result != ISC_R_SUCCESS)
return (ISC_R_SUCCESS);
/*
* Try to find a dispatcher that we can share.
*/
attrs = 0;
attrs |= DNS_DISPATCHATTR_UDP;
switch (af) {
case AF_INET:
attrs |= DNS_DISPATCHATTR_IPV4;
break;
case AF_INET6:
attrs |= DNS_DISPATCHATTR_IPV6;
break;
}
attrmask = 0;
attrmask |= DNS_DISPATCHATTR_UDP;
attrmask |= DNS_DISPATCHATTR_TCP;
attrmask |= DNS_DISPATCHATTR_IPV4;
attrmask |= DNS_DISPATCHATTR_IPV6;
disp = NULL;
result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr,
ns_g_taskmgr, &sa, 4096,
1000, 32768, 16411, 16433,
attrs, attrmask, &disp);
if (result != ISC_R_SUCCESS)
return (result);
*dispatchp = disp;
return (ISC_R_SUCCESS);
}
/* /*
* Configure 'view' according to 'cview', taking defaults from 'cctx' * Configure 'view' according to 'cview', taking defaults from 'cctx'
* where values are missing in cctx. * where values are missing in cctx.
@@ -271,8 +361,7 @@ configure_view_dnsseckeys(dns_c_ctx_t *cctx,
*/ */
static isc_result_t static isc_result_t
configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview, configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview,
isc_mem_t *mctx, dns_aclconfctx_t *actx, isc_mem_t *mctx, dns_aclconfctx_t *actx)
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6)
{ {
dns_cache_t *cache = NULL; dns_cache_t *cache = NULL;
isc_result_t result; isc_result_t result;
@@ -286,6 +375,8 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview,
dns_view_t *pview = NULL; /* Production view */ dns_view_t *pview = NULL; /* Production view */
unsigned int i; unsigned int i;
isc_mem_t *cmctx; isc_mem_t *cmctx;
dns_dispatch_t *dispatch4 = NULL;
dns_dispatch_t *dispatch6 = NULL;
REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(DNS_VIEW_VALID(view));
@@ -354,10 +445,18 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview,
* *
* XXXRTH Hardwired number of tasks. * XXXRTH Hardwired number of tasks.
*/ */
CHECK(get_view_querysource_dispatch(cctx, cview, AF_INET,
&dispatch4));
CHECK(get_view_querysource_dispatch(cctx, cview, AF_INET6,
&dispatch6));
CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31, CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31,
ns_g_socketmgr, ns_g_timermgr, ns_g_socketmgr, ns_g_timermgr,
0, ns_g_dispatchmgr, 0, ns_g_dispatchmgr,
dispatchv4, dispatchv6)); dispatch4, dispatch6));
if (dispatch4 != NULL)
dns_dispatch_detach(&dispatch4);
if (dispatch6 != NULL)
dns_dispatch_detach(&dispatch6);
/* /*
* Set resolver forwarding policy. * Set resolver forwarding policy.
@@ -868,159 +967,6 @@ configure_server_quota(dns_c_ctx_t *cctx,
quota->max = val; quota->max = val;
} }
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;
dns_dispatch_t **server_dispatchp;
isc_sockaddr_t *server_dispatchaddr;
/*
* Make compiler happy.
*/
result = ISC_R_FAILURE;
any = NULL;
server_dispatchp = NULL;
server_dispatchaddr = NULL;
ina.s_addr = htonl(INADDR_ANY);
isc_sockaddr_fromin(&any4, &ina, 0);
isc_sockaddr_fromin6(&any6, &in6addr_any, 0);
*dispatchp = NULL;
switch (af) {
case AF_INET:
any = &any4;
result = dns_c_ctx_getquerysource(cctx, &sa);
break;
case AF_INET6:
any = &any6;
result = dns_c_ctx_getquerysourcev6(cctx, &sa);
break;
default:
INSIST(0);
}
if (result != ISC_R_SUCCESS)
sa = *any;
INSIST(isc_sockaddr_pf(&sa) == af);
/*
* If we don't support this address family, we're done!
*/
switch (af) {
case AF_INET:
result = isc_net_probeipv4();
break;
case AF_INET6:
result = isc_net_probeipv6();
break;
default:
INSIST(0);
}
if (result != ISC_R_SUCCESS)
return (ISC_R_SUCCESS);
if (isc_sockaddr_equal(&sa, any)) {
/*
* The query source is fully wild. No special dispatcher
* work needs to be done.
*/
return (ISC_R_SUCCESS);
}
/*
* If the interface manager has a dispatcher for this address,
* use it.
*/
switch (af) {
case AF_INET:
server_dispatchp = &server->querysrc_dispatchv4;
server_dispatchaddr = &server->querysrc_addressv4;
break;
case AF_INET6:
server_dispatchp = &server->querysrc_dispatchv6;
server_dispatchaddr = &server->querysrc_addressv6;
break;
default:
INSIST(0);
}
if (ns_interfacemgr_findudpdispatcher(server->interfacemgr, &sa,
dispatchp) !=
ISC_R_SUCCESS) {
/*
* The interface manager doesn't have a matching dispatcher.
*/
if (*server_dispatchp != NULL) {
/*
* We've already got a custom dispatcher. If it is
* compatible with the new configuration, use it.
*/
if (isc_sockaddr_equal(server_dispatchaddr,
&sa)) {
dns_dispatch_attach(*server_dispatchp,
dispatchp);
return (ISC_R_SUCCESS);
}
/*
* The existing custom dispatcher is not compatible.
* We don't need it anymore.
*/
dns_dispatch_detach(server_dispatchp);
}
/*
* Create a custom dispatcher.
*/
INSIST(*server_dispatchp == NULL);
*server_dispatchaddr = sa;
socket = NULL;
result = isc_socket_create(ns_g_socketmgr, af,
isc_sockettype_udp,
&socket);
if (result != ISC_R_SUCCESS)
return (result);
result = isc_socket_bind(socket, &sa);
if (result != ISC_R_SUCCESS) {
isc_socket_detach(&socket);
return (result);
}
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,
attrs, server_dispatchp);
/*
* Regardless of whether dns_dispatch_create() succeeded or
* failed, we don't need to keep the reference to the socket.
*/
isc_socket_detach(&socket);
if (result != ISC_R_SUCCESS)
return (result);
dns_dispatch_attach(*server_dispatchp, dispatchp);
} else {
/*
* We're sharing a UDP dispatcher with the interface manager
* now. Any prior custom dispatcher can be discarded.
*/
if (*server_dispatchp != NULL)
dns_dispatch_detach(server_dispatchp);
}
return (ISC_R_SUCCESS);
}
/* /*
* This function is called as soon as the 'options' statement has been * This function is called as soon as the 'options' statement has been
* parsed. * parsed.
@@ -1190,11 +1136,6 @@ load_configuration(const char *filename, ns_server_t *server,
NULL, &interval, ISC_FALSE); NULL, &interval, ISC_FALSE);
} }
CHECK(configure_server_querysource(cctx, server,
AF_INET, &dispatchv4));
CHECK(configure_server_querysource(cctx, server,
AF_INET6, &dispatchv6));
/* /*
* Configure and freeze all explicit views. Explicit * Configure and freeze all explicit views. Explicit
* views that have zones were already created at parsing * views that have zones were already created at parsing
@@ -1211,8 +1152,7 @@ load_configuration(const char *filename, ns_server_t *server,
&lctx.viewlist, &view)); &lctx.viewlist, &view));
INSIST(view != NULL); INSIST(view != NULL);
CHECK(configure_view(view, cctx, cview, ns_g_mctx, CHECK(configure_view(view, cctx, cview, ns_g_mctx,
&aclconfctx, &aclconfctx));
dispatchv4, dispatchv6));
dns_view_freeze(view); dns_view_freeze(view);
dns_view_detach(&view); dns_view_detach(&view);
} }
@@ -1232,8 +1172,7 @@ load_configuration(const char *filename, ns_server_t *server,
*/ */
CHECK(find_or_create_view(NULL, &lctx.viewlist, &view)); CHECK(find_or_create_view(NULL, &lctx.viewlist, &view));
CHECK(configure_view(view, cctx, NULL, CHECK(configure_view(view, cctx, NULL,
ns_g_mctx, &aclconfctx, ns_g_mctx, &aclconfctx));
dispatchv4, dispatchv6));
dns_view_freeze(view); dns_view_freeze(view);
dns_view_detach(&view); dns_view_detach(&view);
} else { } else {
@@ -1400,6 +1339,9 @@ run_server(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event); isc_event_free(&event);
CHECKFATAL(dns_dispatchmgr_create(ns_g_mctx, &ns_g_dispatchmgr),
"creating dispatch manager");
CHECKFATAL(ns_clientmgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr, CHECKFATAL(ns_clientmgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr,
&server->clientmgr), &server->clientmgr),
"creating client manager"); "creating client manager");
@@ -1446,19 +1388,17 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
dns_view_detach(&view); dns_view_detach(&view);
} }
if (server->querysrc_dispatchv4 != NULL)
dns_dispatch_detach(&server->querysrc_dispatchv4);
if (server->querysrc_dispatchv6 != NULL)
dns_dispatch_detach(&server->querysrc_dispatchv6);
ns_clientmgr_destroy(&server->clientmgr); ns_clientmgr_destroy(&server->clientmgr);
isc_timer_detach(&server->interface_timer); isc_timer_detach(&server->interface_timer);
ns_interfacemgr_shutdown(server->interfacemgr); ns_interfacemgr_shutdown(server->interfacemgr);
ns_interfacemgr_detach(&server->interfacemgr); ns_interfacemgr_detach(&server->interfacemgr);
dns_dispatchmgr_destroy(&ns_g_dispatchmgr);
dns_zonemgr_shutdown(server->zonemgr); dns_zonemgr_shutdown(server->zonemgr);
dns_zonemgr_detach(&server->zonemgr); dns_zonemgr_detach(&server->zonemgr);
isc_task_detach(&server->task); isc_task_detach(&server->task);
isc_event_free(&event); isc_event_free(&event);
@@ -1518,8 +1458,6 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
server->tkeyctx = NULL; server->tkeyctx = NULL;
CHECKFATAL(dns_tkeyctx_create(ns_g_mctx, &server->tkeyctx), CHECKFATAL(dns_tkeyctx_create(ns_g_mctx, &server->tkeyctx),
"creating TKEY context"); "creating TKEY context");
server->querysrc_dispatchv4 = NULL;
server->querysrc_dispatchv6 = NULL;
/* /*
* Setup the server task, which is responsible for coordinating * Setup the server task, which is responsible for coordinating
@@ -1550,8 +1488,6 @@ ns_server_destroy(ns_server_t **serverp) {
ns_server_t *server = *serverp; ns_server_t *server = *serverp;
REQUIRE(NS_SERVER_VALID(server)); REQUIRE(NS_SERVER_VALID(server));
REQUIRE(server->querysrc_dispatchv4 == NULL);
REQUIRE(server->querysrc_dispatchv6 == NULL);
if (server->tkeyctx != NULL) if (server->tkeyctx != NULL)
dns_tkeyctx_destroy(&server->tkeyctx); dns_tkeyctx_destroy(&server->tkeyctx);

View File

@@ -21,34 +21,37 @@
#include <unistd.h> #include <unistd.h>
#include <isc/app.h> #include <isc/app.h>
#include <isc/log.h>
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/string.h> #include <isc/string.h>
#include <isc/task.h> #include <isc/task.h>
#include <isc/util.h> #include <isc/util.h>
#include <dns/dispatch.h> #include <dns/dispatch.h>
#include <dns/log.h>
#include <dns/rdatalist.h> #include <dns/rdatalist.h>
#include <dns/rdataset.h> #include <dns/rdataset.h>
#include <dns/result.h> #include <dns/result.h>
#include "printmsg.h" #include "printmsg.h"
#define NCLIENTS 16
typedef struct { typedef struct {
unsigned int client_number;
int count; int count;
dns_dispentry_t *resp;
isc_buffer_t render; isc_buffer_t render;
unsigned char render_buffer[1024]; unsigned char render_buffer[1024];
dns_rdataset_t rdataset;
dns_rdatalist_t rdatalist;
dns_dispentry_t *resp;
} clictx_t; } clictx_t;
isc_mem_t *mctx; isc_mem_t *mctx;
isc_taskmgr_t *manager; isc_taskmgr_t *taskmgr;
isc_socketmgr_t *socketmgr; isc_socketmgr_t *socketmgr;
dns_dispatchmgr_t *dispatchmgr; dns_dispatchmgr_t *dispatchmgr;
dns_dispatch_t *disp; dns_dispatch_t *disp;
isc_task_t *t0, *t1, *t2; isc_task_t *t0;
clictx_t clients[16]; /* Lots of things might want to use this. */ clictx_t clients[NCLIENTS]; /* Lots of things might want to use this. */
unsigned int client_count = 0; unsigned int client_count = 0;
isc_mutex_t client_lock; isc_mutex_t client_lock;
@@ -102,7 +105,7 @@ send_done(isc_task_t *task, isc_event_t *ev_in) {
isc_event_free(&ev_in); isc_event_free(&ev_in);
printf("--- removing response (FAILURE)\n"); printf("--- removing response (FAILURE)\n");
dns_dispatch_removeresponse(disp, &cli->resp, NULL); dns_dispatch_removeresponse(&cli->resp, NULL);
isc_app_shutdown(); isc_app_shutdown();
} }
@@ -117,6 +120,8 @@ start_response(clictx_t *cli, char *query, isc_task_t *task) {
isc_buffer_t target; isc_buffer_t target;
isc_buffer_t source; isc_buffer_t source;
isc_region_t region; isc_region_t region;
dns_rdataset_t *rdataset;
dns_rdatalist_t *rdatalist;
isc_buffer_init(&source, query, strlen(query)); isc_buffer_init(&source, query, strlen(query));
isc_buffer_add(&source, strlen(query)); isc_buffer_add(&source, strlen(query));
@@ -148,16 +153,28 @@ start_response(clictx_t *cli, char *query, isc_task_t *task) {
dns_message_addname(msg, name, DNS_SECTION_QUESTION); dns_message_addname(msg, name, DNS_SECTION_QUESTION);
cli->rdatalist.rdclass = dns_rdataclass_in; rdataset = NULL;
cli->rdatalist.type = dns_rdatatype_a; result = dns_message_gettemprdataset(msg, &rdataset);
cli->rdatalist.ttl = 0; CHECKRESULT(result, "dns_message_gettemprdataset()");
ISC_LIST_INIT(cli->rdatalist.rdata);
dns_rdataset_init(&cli->rdataset); rdatalist = NULL;
result = dns_rdatalist_tordataset(&cli->rdatalist, &cli->rdataset); result = dns_message_gettemprdatalist(msg, &rdatalist);
CHECKRESULT(result, "dns_message_gettemprdatalist()");
dns_rdatalist_init(rdatalist);
rdatalist->rdclass = dns_rdataclass_in;
rdatalist->type = dns_rdatatype_a;
rdatalist->ttl = 0;
ISC_LIST_INIT(rdatalist->rdata);
dns_rdataset_init(rdataset);
result = dns_rdatalist_tordataset(rdatalist, rdataset);
CHECKRESULT(result, "dns_rdatalist_tordataset()"); CHECKRESULT(result, "dns_rdatalist_tordataset()");
rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
ISC_LIST_APPEND(name->list, &cli->rdataset, link); ISC_LIST_APPEND(name->list, rdataset, link);
rdataset = NULL;
rdatalist = NULL;
result = printmessage(msg); result = printmessage(msg);
CHECKRESULT(result, "printmessage()"); CHECKRESULT(result, "printmessage()");
@@ -167,8 +184,6 @@ start_response(clictx_t *cli, char *query, isc_task_t *task) {
result = dns_message_renderbegin(msg, &cli->render); result = dns_message_renderbegin(msg, &cli->render);
CHECKRESULT(result, "dns_message_renderbegin()"); CHECKRESULT(result, "dns_message_renderbegin()");
cli->rdataset.attributes |= DNS_RDATASETATTR_QUESTION;
result = dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0); result = dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0);
CHECKRESULT(result, "dns_message_rendersection(QUESTION)"); CHECKRESULT(result, "dns_message_rendersection(QUESTION)");
@@ -226,7 +241,7 @@ got_response(isc_task_t *task, isc_event_t *ev_in) {
printf("--- shutting down dispatcher\n"); printf("--- shutting down dispatcher\n");
dns_dispatch_cancel(disp); dns_dispatch_cancel(disp);
printf("--- removing response\n"); printf("--- removing response\n");
dns_dispatch_removeresponse(disp, &resp, &ev); dns_dispatch_removeresponse(&resp, &ev);
RUNTIME_CHECK(isc_mutex_lock(&client_lock) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_mutex_lock(&client_lock) == ISC_R_SUCCESS);
INSIST(client_count > 0); INSIST(client_count > 0);
client_count--; client_count--;
@@ -252,7 +267,7 @@ got_response(isc_task_t *task, isc_event_t *ev_in) {
printf("--- shutting down dispatcher\n"); printf("--- shutting down dispatcher\n");
dns_dispatch_cancel(disp); dns_dispatch_cancel(disp);
printf("--- removing response\n"); printf("--- removing response\n");
dns_dispatch_removeresponse(disp, &resp, &ev); dns_dispatch_removeresponse(&resp, &ev);
RUNTIME_CHECK(isc_mutex_lock(&client_lock) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_mutex_lock(&client_lock) == ISC_R_SUCCESS);
INSIST(client_count > 0); INSIST(client_count > 0);
client_count--; client_count--;
@@ -269,6 +284,8 @@ got_request(isc_task_t *task, isc_event_t *ev_in) {
dns_message_t *msg; dns_message_t *msg;
isc_result_t result; isc_result_t result;
unsigned int cnt; unsigned int cnt;
unsigned char text[8192];
isc_buffer_t textbuf;
printf("App: Got request. Result: %s\n", printf("App: Got request. Result: %s\n",
isc_result_totext(ev->result)); isc_result_totext(ev->result));
@@ -277,7 +294,7 @@ got_request(isc_task_t *task, isc_event_t *ev_in) {
RUNTIME_CHECK(isc_mutex_lock(&client_lock) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_mutex_lock(&client_lock) == ISC_R_SUCCESS);
printf("Got error, terminating CLIENT %p resp %p\n", printf("Got error, terminating CLIENT %p resp %p\n",
cli, cli->resp); cli, cli->resp);
dns_dispatch_removerequest(disp, &cli->resp, &ev); dns_dispatch_removerequest(&cli->resp, &ev);
INSIST(client_count > 0); INSIST(client_count > 0);
client_count--; client_count--;
cnt = client_count; cnt = client_count;
@@ -297,14 +314,20 @@ got_request(isc_task_t *task, isc_event_t *ev_in) {
result = dns_message_parse(msg, &ev->buffer, ISC_FALSE); result = dns_message_parse(msg, &ev->buffer, ISC_FALSE);
CHECKRESULT(result, "dns_message_parse() failed"); CHECKRESULT(result, "dns_message_parse() failed");
result = printmessage(msg); isc_buffer_init(&textbuf, text, sizeof text);
CHECKRESULT(result, "printmessage() failed"); result = dns_message_totext(msg, ISC_TRUE, ISC_TRUE,
ISC_FALSE, ISC_FALSE, &textbuf);
CHECKRESULT(result, "dns_message_totext() failed");
dns_message_destroy(&msg); dns_message_destroy(&msg);
sleep (1); fprintf(stderr, "msg:\n%*s\n",
isc_buffer_usedlength(&textbuf),
isc_buffer_base(&textbuf));
cli->count++; cli->count++;
printf("App: Client %p ready, count == %d.\n", cli, cli->count); printf("App: Client %p(%u) ready, count == %d.\n",
cli, cli->client_number, cli->count);
switch (cli->count) { switch (cli->count) {
case 4: case 4:
printf("--- starting DNS lookup\n"); printf("--- starting DNS lookup\n");
@@ -316,7 +339,7 @@ got_request(isc_task_t *task, isc_event_t *ev_in) {
case 2: case 2:
printf("--- removing request\n"); printf("--- removing request\n");
dns_dispatch_removerequest(disp, &cli->resp, &ev); dns_dispatch_removerequest(&cli->resp, &ev);
printf("--- adding request\n"); printf("--- adding request\n");
RUNTIME_CHECK(dns_dispatch_addrequest(disp, task, got_request, RUNTIME_CHECK(dns_dispatch_addrequest(disp, task, got_request,
cli, &cli->resp) cli, &cli->resp)
@@ -331,12 +354,16 @@ got_request(isc_task_t *task, isc_event_t *ev_in) {
int int
main(int argc, char *argv[]) { main(int argc, char *argv[]) {
isc_socket_t *s0; isc_sockaddr_t sa;
isc_sockaddr_t sockaddr;
unsigned int i; unsigned int i;
unsigned int attrs;
isc_log_t *log;
isc_logconfig_t *lcfg;
isc_logdestination_t destination;
isc_result_t result;
(void)argc; UNUSED(argc);
(void)argv; UNUSED(argv);
RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS); RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS);
@@ -348,89 +375,121 @@ main(int argc, char *argv[]) {
dns_result_register(); dns_result_register();
log = NULL;
lcfg = NULL;
RUNTIME_CHECK(isc_log_create(mctx, &log, &lcfg) == ISC_R_SUCCESS);
isc_log_setcontext(log);
dns_log_init(log);
dns_log_setcontext(log);
destination.file.stream = stderr;
destination.file.name = NULL;
destination.file.versions = ISC_LOG_ROLLNEVER;
destination.file.maximum_size = 0;
result = isc_log_createchannel(lcfg, "_default",
ISC_LOG_TOFILEDESC,
ISC_LOG_DYNAMIC,
&destination, ISC_LOG_PRINTTIME);
INSIST(result == ISC_R_SUCCESS);
result = isc_log_usechannel(lcfg, "_default", NULL, NULL);
INSIST(result == ISC_R_SUCCESS);
/* /*
* The task manager is independent (other than memory context). * The task manager is independent (other than memory context).
*/ */
manager = NULL; taskmgr = NULL;
RUNTIME_CHECK(isc_taskmgr_create(mctx, 5, 0, &manager) == RUNTIME_CHECK(isc_taskmgr_create(mctx, 5, 0, &taskmgr) ==
ISC_R_SUCCESS); ISC_R_SUCCESS);
isc_log_setdebuglevel(log, 99);
t0 = NULL; t0 = NULL;
RUNTIME_CHECK(isc_task_create(manager, 0, &t0) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_create(taskmgr, 0, &t0) == ISC_R_SUCCESS);
t1 = NULL;
RUNTIME_CHECK(isc_task_create(manager, 0, &t1) == ISC_R_SUCCESS);
t2 = NULL;
RUNTIME_CHECK(isc_task_create(manager, 0, &t2) == ISC_R_SUCCESS);
socketmgr = NULL; socketmgr = NULL;
RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS);
/*
* Open up a random socket. Who cares where.
*/
s0 = NULL;
memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.type.sin.sin_family = AF_INET;
sockaddr.type.sin.sin_port = htons(5555);
sockaddr.length = sizeof (struct sockaddr_in);
RUNTIME_CHECK(isc_socket_create(socketmgr, PF_INET,
isc_sockettype_udp, &s0) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(isc_socket_bind(s0, &sockaddr) == ISC_R_SUCCESS);
dispatchmgr = NULL; dispatchmgr = NULL;
RUNTIME_CHECK(dns_dispatchmgr_create(mctx, &dispatchmgr) RUNTIME_CHECK(dns_dispatchmgr_create(mctx, &dispatchmgr)
== ISC_R_SUCCESS); == ISC_R_SUCCESS);
isc_sockaddr_any(&sa);
isc_sockaddr_setport(&sa, 5356);
/* /*
* Create a dispatch context. * Get or create a dispatch context.
*/ */
attrs = 0;
attrs |= DNS_DISPATCHATTR_IPV4;
attrs |= DNS_DISPATCHATTR_UDP;
disp = NULL; disp = NULL;
RUNTIME_CHECK(dns_dispatch_create(dispatchmgr, s0, t0, 512, 6, 1024, RUNTIME_CHECK(dns_dispatch_getudp(dispatchmgr, socketmgr,
17, 19, NULL, 0, &disp) taskmgr, &sa, 512, 6, 1024,
17, 19, attrs, attrs, &disp)
== ISC_R_SUCCESS); == ISC_R_SUCCESS);
INSIST(disp != NULL);
RUNTIME_CHECK(isc_mutex_init(&client_lock) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_mutex_init(&client_lock) == ISC_R_SUCCESS);
RUNTIME_CHECK(isc_mutex_lock(&client_lock) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_mutex_lock(&client_lock) == ISC_R_SUCCESS);
memset(clients, 0, sizeof (clients));
for (i = 0 ; i < NCLIENTS ; i++)
clients[i].client_number = i;
for (i = 0 ; i < 2 ; i++) { for (i = 0 ; i < 2 ; i++) {
clients[i].count = 0; clients[i].count = 0;
clients[i].resp = NULL; clients[i].resp = NULL;
RUNTIME_CHECK(dns_dispatch_addrequest(disp, t1, got_request, RUNTIME_CHECK(dns_dispatch_addrequest(disp, t0, got_request,
&clients[i], &clients[i],
&clients[i].resp) &clients[i].resp)
== ISC_R_SUCCESS); == ISC_R_SUCCESS);
INSIST(clients[i].resp != NULL);
fprintf(stderr, "Started client %i via addrequest\n", i);
client_count++; client_count++;
} }
RUNTIME_CHECK(isc_mutex_unlock(&client_lock) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_mutex_unlock(&client_lock) == ISC_R_SUCCESS);
isc_mem_stats(mctx, stderr);
isc_app_run(); isc_app_run();
fprintf(stderr, "canceling dispatcher\n"); fprintf(stderr, "canceling dispatcher\n");
isc_mem_stats(mctx, stderr);
sleep(2);
dns_dispatch_cancel(disp); dns_dispatch_cancel(disp);
fprintf(stderr, "detaching from socket\n"); INSIST(disp != NULL);
isc_socket_detach(&s0);
fprintf(stderr, "detaching from dispatcher\n"); fprintf(stderr, "detaching from dispatcher\n");
isc_mem_stats(mctx, stderr);
sleep(2);
dns_dispatch_detach(&disp); dns_dispatch_detach(&disp);
fprintf(stderr, "destroying dispatch manager\n");
isc_mem_stats(mctx, stderr);
sleep(2);
dns_dispatchmgr_destroy(&dispatchmgr);
fprintf(stderr, "Destroying socket manager\n"); fprintf(stderr, "Destroying socket manager\n");
isc_mem_stats(mctx, stderr);
sleep(2);
isc_socketmgr_destroy(&socketmgr); isc_socketmgr_destroy(&socketmgr);
isc_task_shutdown(t0); isc_task_shutdown(t0);
isc_task_detach(&t0); isc_task_detach(&t0);
isc_task_shutdown(t1);
isc_task_detach(&t1);
isc_task_shutdown(t2);
isc_task_detach(&t2);
fprintf(stderr, "Destroying task manager\n"); fprintf(stderr, "Destroying task manager\n");
isc_taskmgr_destroy(&manager);
isc_mem_stats(mctx, stderr); isc_mem_stats(mctx, stderr);
isc_mem_destroy(&mctx); sleep(2);
isc_taskmgr_destroy(&taskmgr);
isc_app_finish(); isc_app_finish();
isc_log_destroy(&log);
sleep(2);
isc_mem_stats(mctx, stderr);
fflush(stderr);
isc_mem_detach(&mctx);
return (0); return (0);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -85,21 +85,6 @@ struct dns_dispatchevent {
isc_uint32_t attributes; /* mirrored from socket.h */ isc_uint32_t attributes; /* mirrored from socket.h */
}; };
/*
* Functions to:
*
* Return if a packet is a query or a response,
* Hash IDs,
* Generate a new random ID,
* Compare entries (IDs) for equality,
*/
struct dns_dispatchmethods {
isc_uint32_t (*randomid)(dns_dispatch_t *);
isc_uint32_t (*hash)(dns_dispatch_t *, isc_sockaddr_t *,
isc_uint32_t);
};
typedef struct dns_dispatchmethods dns_dispatchmethods_t;
/* /*
* Attributes for added dispatchers. * Attributes for added dispatchers.
* *
@@ -124,11 +109,6 @@ typedef struct dns_dispatchmethods dns_dispatchmethods_t;
* _MAKEQUERY * _MAKEQUERY
* The dispatcher can be used to issue queries to other servers, and * The dispatcher can be used to issue queries to other servers, and
* accept replies from them. * accept replies from them.
*
* _CONNECTED
* The socket the dispatcher uses is a connected socket, and can
* only send to a specific host. This will disallow wildcarded
* remote addresses.
*/ */
#define DNS_DISPATCHATTR_PRIVATE 0x00000001U #define DNS_DISPATCHATTR_PRIVATE 0x00000001U
#define DNS_DISPATCHATTR_TCP 0x00000002U #define DNS_DISPATCHATTR_TCP 0x00000002U
@@ -197,16 +177,24 @@ dns_dispatchmgr_find(dns_dispatchmgr_t *mgr,
isc_result_t isc_result_t
dns_dispatch_create(dns_dispatchmgr_t *mgr, isc_socket_t *sock, dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
isc_task_t *task, unsigned int maxbuffersize, isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
unsigned int buffersize,
unsigned int maxbuffers, unsigned int maxrequests, unsigned int maxbuffers, unsigned int maxrequests,
unsigned int buckets, unsigned int increment, unsigned int buckets, unsigned int increment,
dns_dispatchmethods_t *methods, unsigned int attributes, unsigned int attributes, unsigned int mask,
dns_dispatch_t **dispp); dns_dispatch_t **dispp);
isc_result_t
dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
isc_taskmgr_t *taskmgr, unsigned int buffersize,
unsigned int maxbuffers, unsigned int maxrequests,
unsigned int buckets, unsigned int increment,
unsigned int attributes, dns_dispatch_t **dispp);
/* /*
* Create a new dns_dispatch and attach it to the provided isc_socket_t. * Create a new dns_dispatch and attach it to the provided isc_socket_t.
* *
* For all dispatches, "maxbuffersize" is the maximum packet size we will * For all dispatches, "buffersize" is the maximum packet size we will
* accept. * accept.
* *
* "maxbuffers" and "maxrequests" control the number of buffers in the * "maxbuffers" and "maxrequests" control the number of buffers in the
@@ -218,10 +206,6 @@ dns_dispatch_create(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
* "increment" is used in a collision avoidance function, and needs to be * "increment" is used in a collision avoidance function, and needs to be
* a prime > buckets, and not 2. * a prime > buckets, and not 2.
* *
* "methods" be NULL for normal DNS wire format, or all elements in that
* structure be filled in with function pointers to control dispatch
* behavior.
*
* Requires: * Requires:
* *
* mgr is a valid dispatch manager. * mgr is a valid dispatch manager.
@@ -313,7 +297,7 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
void void
dns_dispatch_removeresponse(dns_dispatch_t *disp, dns_dispentry_t **resp, dns_dispatch_removeresponse(dns_dispentry_t **resp,
dns_dispatchevent_t **sockevent); dns_dispatchevent_t **sockevent);
/* /*
* Stops the flow of responses for the provided id and destination. * Stops the flow of responses for the provided id and destination.
@@ -353,7 +337,7 @@ dns_dispatch_addrequest(dns_dispatch_t *disp,
void void
dns_dispatch_removerequest(dns_dispatch_t *disp, dns_dispentry_t **resp, dns_dispatch_removerequest(dns_dispentry_t **resp,
dns_dispatchevent_t **sockevent); dns_dispatchevent_t **sockevent);
/* /*
* Stops the flow of requests for the provided id and destination. * Stops the flow of requests for the provided id and destination.

View File

@@ -56,7 +56,7 @@ ISC_LANG_BEGINDECLS
isc_result_t isc_result_t
dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr, dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
isc_socketmgr_t *socketmgr, isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr,
dns_dispatchmgr_t *dispatchmgr, dns_dispatchmgr_t *dispatchmgr,
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6, dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
dns_requestmgr_t **requestmgrp); dns_requestmgr_t **requestmgrp);
@@ -71,6 +71,8 @@ dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
* *
* 'socketmgr' is a valid socket manager. * 'socketmgr' is a valid socket manager.
* *
* 'taskmgr' is a valid task manager.
*
* 'dispatchv4' is a valid dispatcher with an IPv4 UDP socket, or is NULL. * 'dispatchv4' is a valid dispatcher with an IPv4 UDP socket, or is NULL.
* *
* 'dispatchv6' is a valid dispatcher with an IPv6 UDP socket, or is NULL. * 'dispatchv6' is a valid dispatcher with an IPv6 UDP socket, or is NULL.

View File

@@ -351,6 +351,9 @@ dns_resolver_dispatchv6(dns_resolver_t *resolver);
isc_socketmgr_t * isc_socketmgr_t *
dns_resolver_socketmgr(dns_resolver_t *resolver); dns_resolver_socketmgr(dns_resolver_t *resolver);
isc_taskmgr_t *
dns_resolver_taskmgr(dns_resolver_t *resolver);
ISC_LANG_ENDDECLS ISC_LANG_ENDDECLS
#endif /* DNS_RESOLVER_H */ #endif /* DNS_RESOLVER_H */

View File

@@ -51,6 +51,7 @@ struct dns_requestmgr {
isc_int32_t iref; isc_int32_t iref;
isc_timermgr_t *timermgr; isc_timermgr_t *timermgr;
isc_socketmgr_t *socketmgr; isc_socketmgr_t *socketmgr;
isc_taskmgr_t *taskmgr;
dns_dispatchmgr_t *dispatchmgr; dns_dispatchmgr_t *dispatchmgr;
dns_dispatch_t *dispatchv4; dns_dispatch_t *dispatchv4;
dns_dispatch_t *dispatchv6; dns_dispatch_t *dispatchv6;
@@ -111,6 +112,7 @@ isc_result_t
dns_requestmgr_create(isc_mem_t *mctx, dns_requestmgr_create(isc_mem_t *mctx,
isc_timermgr_t *timermgr, isc_timermgr_t *timermgr,
isc_socketmgr_t *socketmgr, isc_socketmgr_t *socketmgr,
isc_taskmgr_t *taskmgr,
dns_dispatchmgr_t *dispatchmgr, dns_dispatchmgr_t *dispatchmgr,
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv4,
dns_dispatch_t *dispatchv6, dns_dispatch_t *dispatchv6,
@@ -126,6 +128,7 @@ dns_requestmgr_create(isc_mem_t *mctx,
REQUIRE(requestmgrp != NULL && *requestmgrp == NULL); REQUIRE(requestmgrp != NULL && *requestmgrp == NULL);
REQUIRE(timermgr != NULL); REQUIRE(timermgr != NULL);
REQUIRE(socketmgr != NULL); REQUIRE(socketmgr != NULL);
REQUIRE(taskmgr != NULL);
REQUIRE(dispatchmgr != NULL); REQUIRE(dispatchmgr != NULL);
if (dispatchv4 != NULL) { if (dispatchv4 != NULL) {
socket = dns_dispatch_getsocket(dispatchv4); socket = dns_dispatch_getsocket(dispatchv4);
@@ -157,6 +160,7 @@ dns_requestmgr_create(isc_mem_t *mctx,
} }
requestmgr->timermgr = timermgr; requestmgr->timermgr = timermgr;
requestmgr->socketmgr = socketmgr; requestmgr->socketmgr = socketmgr;
requestmgr->taskmgr = taskmgr;
requestmgr->dispatchmgr = dispatchmgr; requestmgr->dispatchmgr = dispatchmgr;
requestmgr->dispatchv4 = NULL; requestmgr->dispatchv4 = NULL;
if (dispatchv4 != NULL) if (dispatchv4 != NULL)
@@ -492,10 +496,10 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
else else
attrs |= DNS_DISPATCHATTR_IPV6; attrs |= DNS_DISPATCHATTR_IPV6;
attrs |= DNS_DISPATCHATTR_MAKEQUERY; attrs |= DNS_DISPATCHATTR_MAKEQUERY;
result = dns_dispatch_create(requestmgr->dispatchmgr, result = dns_dispatch_createtcp(requestmgr->dispatchmgr,
socket, task, socket, requestmgr->taskmgr,
4096, 2, 1, 1, 3, NULL, attrs, 4096, 2, 1, 1, 3, attrs,
&request->dispatch); &request->dispatch);
isc_socket_detach(&socket); isc_socket_detach(&socket);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
goto cleanup; goto cleanup;
@@ -530,8 +534,7 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
* Try again using TCP. * Try again using TCP.
*/ */
dns_message_renderreset(message); dns_message_renderreset(message);
dns_dispatch_removeresponse(request->dispatch, dns_dispatch_removeresponse(&request->dispentry, NULL);
&request->dispentry, NULL);
dns_dispatch_detach(&request->dispatch); dns_dispatch_detach(&request->dispatch);
socket = NULL; socket = NULL;
isc_buffer_free(&request->query); isc_buffer_free(&request->query);
@@ -589,8 +592,7 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
if (request->requestmgr != NULL) if (request->requestmgr != NULL)
requestmgr_detach(&request->requestmgr); requestmgr_detach(&request->requestmgr);
if (request->dispentry != NULL) if (request->dispentry != NULL)
dns_dispatch_removeresponse(request->dispatch, dns_dispatch_removeresponse(&request->dispentry, NULL);
&request->dispentry, NULL);
if (request->dispatch != NULL) if (request->dispatch != NULL)
dns_dispatch_detach(&request->dispatch); dns_dispatch_detach(&request->dispatch);
if (request->event != NULL) if (request->event != NULL)
@@ -819,8 +821,7 @@ req_response(isc_task_t *task, isc_event_t *event) {
/* /*
* Cleanup. * Cleanup.
*/ */
dns_dispatch_removeresponse(request->dispatch, &request->dispentry, dns_dispatch_removeresponse(&request->dispentry, &devent);
&devent);
req_cancel(request); req_cancel(request);
/* /*
* Send completion event. * Send completion event.
@@ -878,8 +879,7 @@ req_destroy(dns_request_t *request) {
if (request->event != NULL) if (request->event != NULL)
isc_event_free((isc_event_t **)&request->event); isc_event_free((isc_event_t **)&request->event);
if (request->dispentry != NULL) if (request->dispentry != NULL)
dns_dispatch_removeresponse(request->dispatch, dns_dispatch_removeresponse(&request->dispentry, NULL);
&request->dispentry, NULL);
if (request->dispatch != NULL) if (request->dispatch != NULL)
dns_dispatch_detach(&request->dispatch); dns_dispatch_detach(&request->dispatch);
if (request->timer != NULL) if (request->timer != NULL)
@@ -906,8 +906,7 @@ req_cancel(dns_request_t *request) {
if (request->timer != NULL) if (request->timer != NULL)
isc_timer_detach(&request->timer); isc_timer_detach(&request->timer);
if (request->dispentry != NULL) if (request->dispentry != NULL)
dns_dispatch_removeresponse(request->dispatch, dns_dispatch_removeresponse(&request->dispentry, NULL);
&request->dispentry, NULL);
if (DNS_REQUEST_CONNECTING(request)) { if (DNS_REQUEST_CONNECTING(request)) {
socket = dns_dispatch_getsocket(request->dispatch); socket = dns_dispatch_getsocket(request->dispatch);
isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_CONNECT); isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_CONNECT);

View File

@@ -209,13 +209,12 @@ struct dns_resolver {
dns_rdataclass_t rdclass; dns_rdataclass_t rdclass;
isc_socketmgr_t * socketmgr; isc_socketmgr_t * socketmgr;
isc_timermgr_t * timermgr; isc_timermgr_t * timermgr;
isc_taskmgr_t * taskmgr;
dns_view_t * view; dns_view_t * view;
isc_boolean_t frozen; isc_boolean_t frozen;
isc_sockaddrlist_t forwarders; isc_sockaddrlist_t forwarders;
dns_fwdpolicy_t fwdpolicy; dns_fwdpolicy_t fwdpolicy;
unsigned int options; unsigned int options;
isc_socket_t * udpsocketv4;
isc_socket_t * udpsocketv6;
dns_dispatchmgr_t * dispatchmgr; dns_dispatchmgr_t * dispatchmgr;
dns_dispatch_t * dispatchv4; dns_dispatch_t * dispatchv4;
dns_dispatch_t * dispatchv6; dns_dispatch_t * dispatchv6;
@@ -377,8 +376,7 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
} }
if (query->dispentry != NULL) if (query->dispentry != NULL)
dns_dispatch_removeresponse(query->dispatch, &query->dispentry, dns_dispatch_removeresponse(&query->dispentry, deventp);
deventp);
ISC_LIST_UNLINK(fctx->queries, query, link); ISC_LIST_UNLINK(fctx->queries, query, link);
if (query->tsig != NULL) { if (query->tsig != NULL) {
dns_rdata_freestruct(query->tsig); dns_rdata_freestruct(query->tsig);
@@ -637,7 +635,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
query = isc_mem_get(res->mctx, sizeof *query); query = isc_mem_get(res->mctx, sizeof *query);
if (query == NULL) { if (query == NULL) {
result = ISC_R_NOMEMORY; result = ISC_R_NOMEMORY;
goto stop_idle_timer; goto stop_idle_timer;
} }
query->options = options; query->options = options;
@@ -967,9 +965,7 @@ resquery_send(resquery_t *query) {
/* /*
* Stop the dispatcher from listening. * Stop the dispatcher from listening.
*/ */
dns_dispatch_removeresponse(query->dispatch, dns_dispatch_removeresponse(&query->dispentry, NULL);
&query->dispentry,
NULL);
cleanup_temps: cleanup_temps:
if (qname != NULL) if (qname != NULL)
@@ -1028,14 +1024,17 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
attrs |= DNS_DISPATCHATTR_IPV6; attrs |= DNS_DISPATCHATTR_IPV6;
attrs |= DNS_DISPATCHATTR_MAKEQUERY; attrs |= DNS_DISPATCHATTR_MAKEQUERY;
result = dns_dispatch_create(query->dispatchmgr, result = dns_dispatch_createtcp(query->dispatchmgr,
query->tcpsocket, task, query->tcpsocket,
4096, 2, 1, 1, 3, NULL, attrs, query->fctx->res->taskmgr,
&query->dispatch); 4096, 2, 1, 1, 3,
attrs,
&query->dispatch);
/* /*
* Regardless of whether dns_dispatch_create() succeeded or * Regardless of whether dns_dispatch_create()
* not, we don't need our reference to the socket anymore. * succeeded or not, we don't need our reference
* to the socket anymore.
*/ */
isc_socket_detach(&query->tcpsocket); isc_socket_detach(&query->tcpsocket);
@@ -3904,12 +3903,8 @@ destroy(dns_resolver_t *res) {
res->nbuckets * sizeof (fctxbucket_t)); res->nbuckets * sizeof (fctxbucket_t));
if (res->dispatchv4 != NULL) if (res->dispatchv4 != NULL)
dns_dispatch_detach(&res->dispatchv4); dns_dispatch_detach(&res->dispatchv4);
if (res->udpsocketv4 != NULL)
isc_socket_detach(&res->udpsocketv4);
if (res->dispatchv6 != NULL) if (res->dispatchv6 != NULL)
dns_dispatch_detach(&res->dispatchv6); dns_dispatch_detach(&res->dispatchv6);
if (res->udpsocketv6 != NULL)
isc_socket_detach(&res->udpsocketv6);
free_forwarders(res); free_forwarders(res);
res->magic = 0; res->magic = 0;
isc_mem_put(res->mctx, res, sizeof *res); isc_mem_put(res->mctx, res, sizeof *res);
@@ -3964,7 +3959,6 @@ dns_resolver_create(dns_view_t *view,
isc_result_t result = ISC_R_SUCCESS; isc_result_t result = ISC_R_SUCCESS;
unsigned int i, buckets_created = 0; unsigned int i, buckets_created = 0;
char name[16]; char name[16];
unsigned int attrs;
/* /*
* Create a resolver. * Create a resolver.
@@ -3974,6 +3968,7 @@ dns_resolver_create(dns_view_t *view,
REQUIRE(ntasks > 0); REQUIRE(ntasks > 0);
REQUIRE(resp != NULL && *resp == NULL); REQUIRE(resp != NULL && *resp == NULL);
REQUIRE(dispatchmgr != NULL); REQUIRE(dispatchmgr != NULL);
REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL);
res = isc_mem_get(view->mctx, sizeof *res); res = isc_mem_get(view->mctx, sizeof *res);
if (res == NULL) if (res == NULL)
@@ -3983,6 +3978,7 @@ dns_resolver_create(dns_view_t *view,
res->rdclass = view->rdclass; res->rdclass = view->rdclass;
res->socketmgr = socketmgr; res->socketmgr = socketmgr;
res->timermgr = timermgr; res->timermgr = timermgr;
res->taskmgr = taskmgr;
res->dispatchmgr = dispatchmgr; res->dispatchmgr = dispatchmgr;
res->view = view; res->view = view;
res->options = options; res->options = options;
@@ -4012,80 +4008,12 @@ dns_resolver_create(dns_view_t *view,
buckets_created++; buckets_created++;
} }
/*
* IPv4 Dispatcher.
*/
res->dispatchv4 = NULL; res->dispatchv4 = NULL;
res->udpsocketv4 = NULL; if (dispatchv4 != NULL)
if (dispatchv4 != NULL) {
dns_dispatch_attach(dispatchv4, &res->dispatchv4); 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.
*/
result = isc_socket_create(socketmgr, AF_INET,
isc_sockettype_udp,
&res->udpsocketv4);
if (result != ISC_R_SUCCESS)
goto cleanup_buckets;
isc_sockaddr_any(&saddr);
#if 1 /* 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,
attrs, &res->dispatchv4);
if (result != ISC_R_SUCCESS)
goto cleanup_udpsocketv4;
}
/*
* IPv6 Dispatcher.
*/
res->dispatchv6 = NULL; res->dispatchv6 = NULL;
res->udpsocketv6 = NULL; if (dispatchv6 != NULL)
if (dispatchv6 != NULL) {
dns_dispatch_attach(dispatchv6, &res->dispatchv6); 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.
*/
result = isc_socket_create(socketmgr, AF_INET6,
isc_sockettype_udp,
&res->udpsocketv6);
if (result != ISC_R_SUCCESS)
goto cleanup_dispatchv4;
isc_sockaddr_any6(&saddr);
#if 1 /* 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,
attrs, &res->dispatchv6);
if (result != ISC_R_SUCCESS)
goto cleanup_udpsocketv6;
}
/* /*
* Forwarding. * Forwarding.
@@ -4102,7 +4030,7 @@ dns_resolver_create(dns_view_t *view,
result = isc_mutex_init(&res->lock); result = isc_mutex_init(&res->lock);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
goto cleanup_dispatchv6; goto cleanup_dispatches;
res->magic = RES_MAGIC; res->magic = RES_MAGIC;
@@ -4110,22 +4038,12 @@ dns_resolver_create(dns_view_t *view,
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
cleanup_dispatchv6: cleanup_dispatches:
if (res->dispatchv6 != NULL) if (res->dispatchv6 != NULL)
dns_dispatch_detach(&res->dispatchv6); dns_dispatch_detach(&res->dispatchv6);
cleanup_udpsocketv6:
if (res->udpsocketv6 != NULL)
isc_socket_detach(&res->udpsocketv6);
cleanup_dispatchv4:
if (res->dispatchv4 != NULL) if (res->dispatchv4 != NULL)
dns_dispatch_detach(&res->dispatchv4); dns_dispatch_detach(&res->dispatchv4);
cleanup_udpsocketv4:
if (res->udpsocketv4 != NULL)
isc_socket_detach(&res->udpsocketv4);
cleanup_buckets: cleanup_buckets:
for (i = 0; i < buckets_created; i++) { for (i = 0; i < buckets_created; i++) {
(void)isc_mutex_destroy(&res->buckets[i].lock); (void)isc_mutex_destroy(&res->buckets[i].lock);
@@ -4359,6 +4277,7 @@ void
dns_resolver_shutdown(dns_resolver_t *res) { dns_resolver_shutdown(dns_resolver_t *res) {
unsigned int i; unsigned int i;
fetchctx_t *fctx; fetchctx_t *fctx;
isc_socket_t *sock;
REQUIRE(VALID_RESOLVER(res)); REQUIRE(VALID_RESOLVER(res));
@@ -4376,14 +4295,16 @@ dns_resolver_shutdown(dns_resolver_t *res) {
fctx != NULL; fctx != NULL;
fctx = ISC_LIST_NEXT(fctx, link)) fctx = ISC_LIST_NEXT(fctx, link))
fctx_shutdown(fctx); fctx_shutdown(fctx);
if (res->udpsocketv4 != NULL) if (res->dispatchv4 != NULL) {
isc_socket_cancel(res->udpsocketv4, sock = dns_dispatch_getsocket(res->dispatchv4);
res->buckets[i].task, isc_socket_cancel(sock, res->buckets[i].task,
ISC_SOCKCANCEL_ALL); ISC_SOCKCANCEL_ALL);
if (res->udpsocketv6 != NULL) }
isc_socket_cancel(res->udpsocketv6, if (res->dispatchv6 != NULL) {
res->buckets[i].task, sock = dns_dispatch_getsocket(res->dispatchv6);
isc_socket_cancel(sock, res->buckets[i].task,
ISC_SOCKCANCEL_ALL); ISC_SOCKCANCEL_ALL);
}
res->buckets[i].exiting = ISC_TRUE; res->buckets[i].exiting = ISC_TRUE;
if (ISC_LIST_EMPTY(res->buckets[i].fctxs)) { if (ISC_LIST_EMPTY(res->buckets[i].fctxs)) {
INSIST(res->activebuckets > 0); INSIST(res->activebuckets > 0);
@@ -4691,3 +4612,9 @@ dns_resolver_socketmgr(dns_resolver_t *resolver) {
REQUIRE(VALID_RESOLVER(resolver)); REQUIRE(VALID_RESOLVER(resolver));
return (resolver->socketmgr); return (resolver->socketmgr);
} }
isc_taskmgr_t *
dns_resolver_taskmgr(dns_resolver_t *resolver) {
REQUIRE(VALID_RESOLVER(resolver));
return (resolver->taskmgr);
}

View File

@@ -450,6 +450,7 @@ dns_view_createresolver(dns_view_t *view,
view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN; view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN;
result = dns_requestmgr_create(view->mctx, timermgr, socketmgr, result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
dns_resolver_taskmgr(view->resolver),
dns_resolver_dispatchmgr(view->resolver), dns_resolver_dispatchmgr(view->resolver),
dns_resolver_dispatchv4(view->resolver), dns_resolver_dispatchv4(view->resolver),
dns_resolver_dispatchv6(view->resolver), dns_resolver_dispatchv6(view->resolver),

View File

@@ -381,7 +381,7 @@ process_cmsg(isc_socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
cmsgp = CMSG_FIRSTHDR(msg); cmsgp = CMSG_FIRSTHDR(msg);
while (cmsgp != NULL) { while (cmsgp != NULL) {
socket_log(sock, NULL, TRACE, "Processing cmsg %p", cmsgp); socket_log(sock, NULL, TRACE, "processing cmsg %p", cmsgp);
#ifdef ISC_PLATFORM_HAVEIPV6 #ifdef ISC_PLATFORM_HAVEIPV6
if (cmsgp->cmsg_level == IPPROTO_IPV6 if (cmsgp->cmsg_level == IPPROTO_IPV6
@@ -2531,6 +2531,7 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) {
} }
} }
socket_log(sock, sockaddr, TRACE, "bound");
sock->bound = 1; sock->bound = 1;
UNLOCK(&sock->lock); UNLOCK(&sock->lock);