2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 05:57:52 +00:00

Convert dispatch to netmgr

The flow of operations in dispatch is changing and will now be similar
for both UDP and TCP queries:

1) Call dns_dispatch_addresponse() to assign a query ID and register
   that we'll be listening for a response with that ID soon. the
   parameters for this function include callback functions to inform the
   caller when the socket is connected and when the message has been
   sent, as well as a task action that will be sent when the response
   arrives. (later this could become a netmgr callback, but at this
   stage to minimize disruption to the calling code, we continue to use
   isc_task for the response event.) on successful completion of this
   function, a dispatch entry object will be instantiated.

2) Call dns_dispatch_connect() on the dispatch entry. this runs
   isc_nm_udpconnect() or isc_nm_tcpdnsconnect(), as needed, and begins
   listening for responses. the caller is informed via a callback
   function when the connection is established.

3) Call dns_dispatch_send() on the dispatch entry. this runs
   isc_nm_send() to send a request.

4) Call dns_dispatch_removeresponse() to terminate listening and close
   the connection.

Implementation comments below:

- As we will be using netmgr buffers now.  code to send the length in
  TCP queries has also been removed as that is handled by the netmgr.

- TCP dispatches can be used by multiple simultaneous queries, so
  dns_dispatch_connect() now checks whether the dispatch is already
  connected before calling isc_nm_tcpdnsconnect() again.

- Running dns_dispatch_getnext() from a non-network thread caused a
  crash due to assertions in the netmgr read functions that appear to be
  unnecessary now. the assertions have been removed.

- fctx->nqueries was formerly incremented when the connection was
  successful, but is now incremented when the query is started and
  decremented if the connection fails.

- It's no longer necessary for each dispatch to have a pool of tasks, so
  there's now a single task per dispatch.

- Dispatch code to avoid UDP ports already in use has been removed.

- dns_resolver and dns_request have been modified to use netmgr callback
  functions instead of task events. some additional changes were needed
  to handle shutdown processing correctly.

- Timeout processing is not yet fully converted to use netmgr timeouts.

- Fixed a lock order cycle reported by TSAN (view -> zone-> adb -> view)
  by by calling dns_zt functions without holding the view lock.
This commit is contained in:
Evan Hunt 2021-01-14 13:02:57 -08:00
parent 9ee60e7a17
commit 308bc46a59
28 changed files with 924 additions and 1606 deletions

View File

@ -1725,7 +1725,6 @@ main(int argc, char *argv[]) {
isc_appctx_t *actx = NULL;
isc_nm_t *netmgr = NULL;
isc_taskmgr_t *taskmgr = NULL;
isc_socketmgr_t *socketmgr = NULL;
isc_timermgr_t *timermgr = NULL;
dns_master_style_t *style = NULL;
struct sigaction sa;
@ -1744,8 +1743,8 @@ main(int argc, char *argv[]) {
isc_mem_create(&mctx);
CHECK(isc_appctx_create(mctx, &actx));
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, &timermgr,
&socketmgr);
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, &timermgr, NULL);
parse_args(argc, argv);
@ -1763,7 +1762,7 @@ main(int argc, char *argv[]) {
}
/* Create client */
result = dns_client_create(mctx, actx, taskmgr, socketmgr, timermgr, 0,
result = dns_client_create(mctx, actx, taskmgr, netmgr, timermgr, 0,
&client, srcaddr4, srcaddr6);
if (result != ISC_R_SUCCESS) {
delv_log(ISC_LOG_ERROR, "dns_client_create: %s",
@ -1846,7 +1845,9 @@ cleanup:
if (client != NULL) {
dns_client_detach(&client);
}
isc_managers_destroy(&netmgr, &taskmgr, &timermgr, &socketmgr);
isc_managers_destroy(&netmgr, &taskmgr, &timermgr, NULL);
if (actx != NULL) {
isc_appctx_destroy(&actx);
}

View File

@ -1315,8 +1315,8 @@ get_view_querysource_dispatch(const cfg_obj_t **maps, int af,
}
}
result = dns_dispatch_createudp(named_g_dispatchmgr, named_g_socketmgr,
named_g_taskmgr, &sa, attrs, &disp);
result = dns_dispatch_createudp(named_g_dispatchmgr, named_g_taskmgr,
&sa, attrs, &disp);
if (result != ISC_R_SUCCESS) {
isc_sockaddr_t any;
char buf[ISC_SOCKADDR_FORMATSIZE];
@ -4716,7 +4716,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
ndisp = 4 * ISC_MIN(named_g_udpdisp, MAX_UDP_DISPATCH);
CHECK(dns_view_createresolver(
view, named_g_taskmgr, RESOLVER_NTASKS_PERCPU * named_g_cpus,
ndisp, named_g_socketmgr, named_g_timermgr, resopts,
ndisp, named_g_netmgr, named_g_timermgr, resopts,
named_g_dispatchmgr, dispatch4, dispatch6));
if (dscp4 == -1) {
@ -9862,7 +9862,8 @@ run_server(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
CHECKFATAL(dns_dispatchmgr_create(named_g_mctx, &named_g_dispatchmgr),
CHECKFATAL(dns_dispatchmgr_create(named_g_mctx, named_g_netmgr,
&named_g_dispatchmgr),
"creating dispatch manager");
dns_dispatchmgr_setstats(named_g_dispatchmgr, server->resolverstats);
@ -10357,8 +10358,8 @@ named_add_reserved_dispatch(named_server_t *server,
dispatch->dispatchgen = server->dispatchgen;
dispatch->dispatch = NULL;
result = dns_dispatch_createudp(named_g_dispatchmgr, named_g_socketmgr,
named_g_taskmgr, &dispatch->addr, attrs,
result = dns_dispatch_createudp(named_g_dispatchmgr, named_g_taskmgr,
&dispatch->addr, attrs,
&dispatch->dispatch);
if (result != ISC_R_SUCCESS) {
goto cleanup;

View File

@ -31,6 +31,7 @@
#include <isc/log.h>
#include <isc/managers.h>
#include <isc/mem.h>
#include <isc/netmgr.h>
#include <isc/nonce.h>
#include <isc/parseint.h>
#include <isc/portset.h>
@ -38,11 +39,9 @@
#include <isc/random.h>
#include <isc/region.h>
#include <isc/sockaddr.h>
#include <isc/socket.h>
#include <isc/stdio.h>
#include <isc/string.h>
#include <isc/task.h>
#include <isc/timer.h>
#include <isc/types.h>
#include <isc/util.h>
@ -131,8 +130,6 @@ static isc_log_t *glctx = NULL;
static isc_mem_t *gmctx = NULL;
static dns_dispatchmgr_t *dispatchmgr = NULL;
static dns_requestmgr_t *requestmgr = NULL;
static isc_socketmgr_t *socketmgr = NULL;
static isc_timermgr_t *timermgr = NULL;
static dns_dispatch_t *dispatchv4 = NULL;
static dns_dispatch_t *dispatchv6 = NULL;
static dns_message_t *updatemsg = NULL;
@ -917,11 +914,12 @@ setup_system(void) {
irs_resconf_destroy(&resconf);
result = dns_dispatchmgr_create(gmctx, &dispatchmgr);
check_result(result, "dns_dispatchmgr_create");
result = isc_managers_create(gmctx, 1, 0, 0, &netmgr, &taskmgr, NULL,
NULL);
check_result(result, "isc_managers_create");
isc_managers_create(gmctx, 1, 0, 0, &netmgr, &taskmgr, &timermgr,
&socketmgr);
result = dns_dispatchmgr_create(gmctx, netmgr, &dispatchmgr);
check_result(result, "dns_dispatchmgr_create");
result = isc_task_create(taskmgr, 0, &global_task);
check_result(result, "isc_task_create");
@ -937,21 +935,20 @@ setup_system(void) {
if (have_ipv6) {
isc_sockaddr_any6(&bind_any6);
result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr,
result = dns_dispatch_createudp(dispatchmgr, taskmgr,
&bind_any6, 0, &dispatchv6);
check_result(result, "dns_dispatch_createudp (v6)");
}
if (have_ipv4) {
isc_sockaddr_any(&bind_any);
result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr,
&bind_any, 0, &dispatchv4);
result = dns_dispatch_createudp(dispatchmgr, taskmgr, &bind_any,
0, &dispatchv4);
check_result(result, "dns_dispatch_createudp (v4)");
}
result = dns_requestmgr_create(gmctx, timermgr, socketmgr, taskmgr,
dispatchmgr, dispatchv4, dispatchv6,
&requestmgr);
result = dns_requestmgr_create(gmctx, taskmgr, dispatchmgr, dispatchv4,
dispatchv6, &requestmgr);
check_result(result, "dns_requestmgr_create");
if (keystr != NULL) {
@ -3322,7 +3319,7 @@ cleanup(void) {
}
ddebug("Shutting down managers");
isc_managers_destroy(&netmgr, &taskmgr, &timermgr, &socketmgr);
isc_managers_destroy(&netmgr, &taskmgr, NULL, NULL);
ddebug("Destroying event");
isc_event_free(&global_event);

View File

@ -23,12 +23,11 @@
#include <isc/managers.h>
#include <isc/mem.h>
#include <isc/net.h>
#include <isc/netmgr.h>
#include <isc/parseint.h>
#include <isc/print.h>
#include <isc/sockaddr.h>
#include <isc/socket.h>
#include <isc/task.h>
#include <isc/timer.h>
#include <isc/util.h>
#include <dns/dispatch.h>
@ -70,7 +69,8 @@ static void
recvresponse(isc_task_t *task, isc_event_t *event) {
dns_requestevent_t *reqev = (dns_requestevent_t *)event;
isc_result_t result;
dns_message_t *query = NULL, *response = NULL;
dns_message_t *query = NULL;
dns_message_t *response = NULL;
isc_buffer_t outbuf;
char output[1024];
@ -203,8 +203,6 @@ main(int argc, char *argv[]) {
isc_nm_t *netmgr = NULL;
isc_taskmgr_t *taskmgr = NULL;
isc_task_t *task = NULL;
isc_timermgr_t *timermgr = NULL;
isc_socketmgr_t *socketmgr = NULL;
dns_dispatchmgr_t *dispatchmgr = NULL;
dns_dispatch_t *dispatchv4 = NULL;
dns_view_t *view = NULL;
@ -267,18 +265,15 @@ main(int argc, char *argv[]) {
RUNCHECK(dst_lib_init(mctx, NULL));
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, &timermgr,
&socketmgr);
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, NULL, NULL);
RUNCHECK(isc_task_create(taskmgr, 0, &task));
RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr));
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
RUNCHECK(dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr,
RUNCHECK(dns_dispatch_createudp(dispatchmgr, taskmgr,
have_src ? &srcaddr : &bind_any, 0,
&dispatchv4));
RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr,
dispatchmgr, dispatchv4, NULL,
&requestmgr));
RUNCHECK(dns_requestmgr_create(mctx, taskmgr, dispatchmgr, dispatchv4,
NULL, &requestmgr));
RUNCHECK(dns_view_create(mctx, 0, "_test", &view));
RUNCHECK(isc_app_onrun(mctx, task, sendqueries, NULL));
@ -296,7 +291,7 @@ main(int argc, char *argv[]) {
isc_task_shutdown(task);
isc_task_detach(&task);
isc_managers_destroy(&netmgr, &taskmgr, &timermgr, &socketmgr);
isc_managers_destroy(&netmgr, &taskmgr, NULL, NULL);
dst_lib_destroy();

View File

@ -27,9 +27,9 @@
#include <isc/commandline.h>
#include <isc/managers.h>
#include <isc/mem.h>
#include <isc/netmgr.h>
#include <isc/print.h>
#include <isc/sockaddr.h>
#include <isc/socket.h>
#include <isc/task.h>
#include <isc/timer.h>
#include <isc/util.h>
@ -58,13 +58,11 @@ isc_mem_t *ctxs_mctx = NULL;
isc_appctx_t *ctxs_actx = NULL;
isc_nm_t *ctxs_netmgr = NULL;
isc_taskmgr_t *ctxs_taskmgr = NULL;
isc_socketmgr_t *ctxs_socketmgr = NULL;
isc_timermgr_t *ctxs_timermgr = NULL;
static void
ctxs_destroy(void) {
isc_managers_destroy(&ctxs_netmgr, &ctxs_taskmgr, &ctxs_timermgr,
&ctxs_socketmgr);
isc_managers_destroy(&ctxs_netmgr, &ctxs_taskmgr, &ctxs_timermgr, NULL);
if (ctxs_actx != NULL) {
isc_appctx_destroy(&ctxs_actx);
@ -87,7 +85,7 @@ ctxs_init(void) {
}
isc_managers_create(ctxs_mctx, 1, 0, 0, &ctxs_netmgr, &ctxs_taskmgr,
&ctxs_timermgr, &ctxs_socketmgr);
&ctxs_timermgr, NULL);
result = isc_app_ctxstart(ctxs_actx);
if (result != ISC_R_SUCCESS) {
@ -102,7 +100,7 @@ fail:
return (result);
}
static char *algname;
static char *algname = NULL;
static isc_result_t
printdata(dns_rdataset_t *rdataset, dns_name_t *owner) {
@ -281,9 +279,9 @@ main(int argc, char *argv[]) {
isc_buffer_t b;
dns_fixedname_t qname0;
unsigned int namelen;
dns_name_t *qname, *name;
dns_name_t *qname = NULL, *name = NULL;
dns_rdatatype_t type = dns_rdatatype_a;
dns_rdataset_t *rdataset;
dns_rdataset_t *rdataset = NULL;
dns_namelist_t namelist;
unsigned int clientopt, resopt = 0;
bool is_sep = false;
@ -406,7 +404,7 @@ main(int argc, char *argv[]) {
clientopt = 0;
result = dns_client_create(ctxs_mctx, ctxs_actx, ctxs_taskmgr,
ctxs_socketmgr, ctxs_timermgr, clientopt,
ctxs_netmgr, ctxs_timermgr, clientopt,
&client, addr4, addr6);
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "dns_client_create failed: %u, %s\n", result,

View File

@ -18,13 +18,12 @@
#include <isc/log.h>
#include <isc/managers.h>
#include <isc/mem.h>
#include <isc/netmgr.h>
#include <isc/nonce.h>
#include <isc/print.h>
#include <isc/random.h>
#include <isc/sockaddr.h>
#include <isc/socket.h>
#include <isc/task.h>
#include <isc/timer.h>
#include <isc/util.h>
#include <dns/dispatch.h>
@ -86,7 +85,6 @@ recvquery(isc_task_t *task, isc_event_t *event) {
query = reqev->ev_arg;
response = NULL;
dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
result = dns_request_getresponse(reqev->request, response,
@ -190,9 +188,6 @@ main(int argc, char *argv[]) {
char *ourkeyname = NULL;
isc_nm_t *netmgr = NULL;
isc_taskmgr_t *taskmgr = NULL;
isc_timermgr_t *timermgr = NULL;
isc_socketmgr_t *socketmgr = NULL;
isc_socket_t *sock = NULL;
isc_sockaddr_t bind_any;
dns_dispatchmgr_t *dispatchmgr = NULL;
dns_dispatch_t *dispatchv4 = NULL;
@ -227,18 +222,16 @@ main(int argc, char *argv[]) {
RUNCHECK(dst_lib_init(mctx, NULL));
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, &timermgr,
&socketmgr);
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, NULL, NULL);
RUNCHECK(isc_task_create(taskmgr, 0, &task));
RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr));
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
isc_sockaddr_any(&bind_any);
RUNCHECK(dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr,
&bind_any, 0, &dispatchv4));
RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr,
dispatchmgr, dispatchv4, NULL,
&requestmgr));
RUNCHECK(dns_dispatch_createudp(dispatchmgr, taskmgr, &bind_any, 0,
&dispatchv4));
RUNCHECK(dns_requestmgr_create(mctx, taskmgr, dispatchmgr, dispatchv4,
NULL, &requestmgr));
RUNCHECK(dns_tsigkeyring_create(mctx, &ring));
RUNCHECK(dns_tkeyctx_create(mctx, &tctx));
@ -247,9 +240,6 @@ main(int argc, char *argv[]) {
dns_view_setkeyring(view, ring);
dns_tsigkeyring_detach(&ring);
RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp,
&sock));
RUNCHECK(isc_app_onrun(mctx, task, sendquery, NULL));
type = DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_KEY;
@ -268,8 +258,7 @@ main(int argc, char *argv[]) {
dns_dispatchmgr_destroy(&dispatchmgr);
isc_task_shutdown(task);
isc_task_detach(&task);
isc_socket_detach(&sock);
isc_managers_destroy(&netmgr, &taskmgr, &timermgr, &socketmgr);
isc_managers_destroy(&netmgr, &taskmgr, NULL, NULL);
dst_key_free(&ourkey);
dns_tsigkey_detach(&initialkey);

View File

@ -22,9 +22,7 @@
#include <isc/print.h>
#include <isc/random.h>
#include <isc/sockaddr.h>
#include <isc/socket.h>
#include <isc/task.h>
#include <isc/timer.h>
#include <isc/util.h>
#include <dns/dispatch.h>
@ -134,9 +132,6 @@ main(int argc, char **argv) {
char *keyname = NULL;
isc_nm_t *netmgr = NULL;
isc_taskmgr_t *taskmgr = NULL;
isc_timermgr_t *timermgr = NULL;
isc_socketmgr_t *socketmgr = NULL;
isc_socket_t *sock = NULL;
isc_sockaddr_t bind_any;
dns_dispatchmgr_t *dispatchmgr = NULL;
dns_dispatch_t *dispatchv4 = NULL;
@ -171,17 +166,15 @@ main(int argc, char **argv) {
RUNCHECK(dst_lib_init(mctx, NULL));
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, &timermgr,
&socketmgr);
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, NULL, NULL);
RUNCHECK(isc_task_create(taskmgr, 0, &task));
RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr));
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
isc_sockaddr_any(&bind_any);
RUNCHECK(dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr,
&bind_any, 0, &dispatchv4));
RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr,
dispatchmgr, dispatchv4, NULL,
&requestmgr));
RUNCHECK(dns_dispatch_createudp(dispatchmgr, taskmgr, &bind_any, 0,
&dispatchv4));
RUNCHECK(dns_requestmgr_create(mctx, taskmgr, dispatchmgr, dispatchv4,
NULL, &requestmgr));
RUNCHECK(dns_tsigkeyring_create(mctx, &ring));
RUNCHECK(dns_tkeyctx_create(mctx, &tctx));
@ -189,9 +182,6 @@ main(int argc, char **argv) {
RUNCHECK(dns_view_create(mctx, 0, "_test", &view));
dns_view_setkeyring(view, ring);
RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp,
&sock));
RUNCHECK(isc_app_onrun(mctx, task, sendquery, NULL));
type = DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_KEY;
@ -211,8 +201,7 @@ main(int argc, char **argv) {
dns_dispatchmgr_destroy(&dispatchmgr);
isc_task_shutdown(task);
isc_task_detach(&task);
isc_socket_detach(&sock);
isc_managers_destroy(&netmgr, &taskmgr, &timermgr, &socketmgr);
isc_managers_destroy(&netmgr, &taskmgr, NULL, NULL);
dns_tsigkeyring_detach(&ring);

View File

@ -24,15 +24,14 @@
#include <isc/managers.h>
#include <isc/mem.h>
#include <isc/net.h>
#include <isc/netmgr.h>
#include <isc/nonce.h>
#include <isc/parseint.h>
#include <isc/print.h>
#include <isc/random.h>
#include <isc/sockaddr.h>
#include <isc/socket.h>
#include <isc/string.h>
#include <isc/task.h>
#include <isc/timer.h>
#include <isc/util.h>
#include <dns/byaddr.h>
@ -2068,8 +2067,6 @@ main(int argc, char *argv[]) {
isc_nm_t *netmgr = NULL;
isc_taskmgr_t *taskmgr = NULL;
isc_task_t *task = NULL;
isc_timermgr_t *timermgr = NULL;
isc_socketmgr_t *socketmgr = NULL;
dns_dispatchmgr_t *dispatchmgr = NULL;
dns_dispatch_t *dispatchvx = NULL;
dns_view_t *view = NULL;
@ -2122,25 +2119,22 @@ main(int argc, char *argv[]) {
fatal("can't choose between IPv4 and IPv6");
}
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, &timermgr,
&socketmgr);
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, NULL, NULL);
RUNCHECK(isc_task_create(taskmgr, 0, &task));
RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr));
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
if (have_ipv4) {
isc_sockaddr_any(&bind_any);
} else {
isc_sockaddr_any6(&bind_any);
}
RUNCHECK(dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr,
RUNCHECK(dns_dispatch_createudp(dispatchmgr, taskmgr,
have_src ? &srcaddr : &bind_any, 0,
&dispatchvx));
RUNCHECK(dns_requestmgr_create(
mctx, timermgr, socketmgr, taskmgr, dispatchmgr,
have_ipv4 ? dispatchvx : NULL, have_ipv6 ? dispatchvx : NULL,
&requestmgr));
mctx, taskmgr, dispatchmgr, have_ipv4 ? dispatchvx : NULL,
have_ipv6 ? dispatchvx : NULL, &requestmgr));
RUNCHECK(dns_view_create(mctx, 0, "_test", &view));
@ -2186,7 +2180,7 @@ main(int argc, char *argv[]) {
isc_task_shutdown(task);
isc_task_detach(&task);
isc_managers_destroy(&netmgr, &taskmgr, &timermgr, &socketmgr);
isc_managers_destroy(&netmgr, &taskmgr, NULL, NULL);
dst_lib_destroy();

View File

@ -86,7 +86,7 @@ struct dns_client {
isc_appctx_t *actx;
isc_taskmgr_t *taskmgr;
isc_task_t *task;
isc_socketmgr_t *socketmgr;
isc_nm_t *nm;
isc_timermgr_t *timermgr;
dns_dispatchmgr_t *dispatchmgr;
dns_dispatch_t *dispatchv4;
@ -202,8 +202,8 @@ cleanup:
static isc_result_t
getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr,
isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr,
dns_dispatch_t **dispp, const isc_sockaddr_t *localaddr) {
isc_taskmgr_t *taskmgr, dns_dispatch_t **dispp,
const isc_sockaddr_t *localaddr) {
dns_dispatch_t *disp = NULL;
isc_result_t result;
isc_sockaddr_t anyaddr;
@ -213,8 +213,8 @@ getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr,
localaddr = &anyaddr;
}
result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr,
localaddr, 0, &disp);
result = dns_dispatch_createudp(dispatchmgr, taskmgr, localaddr, 0,
&disp);
if (result == ISC_R_SUCCESS) {
*dispp = disp;
}
@ -224,10 +224,9 @@ getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr,
static isc_result_t
createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_taskmgr_t *taskmgr,
unsigned int ntasks, isc_socketmgr_t *socketmgr,
isc_timermgr_t *timermgr, dns_dispatchmgr_t *dispatchmgr,
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
dns_view_t **viewp) {
unsigned int ntasks, isc_nm_t *nm, isc_timermgr_t *timermgr,
dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4,
dns_dispatch_t *dispatchv6, dns_view_t **viewp) {
isc_result_t result;
dns_view_t *view = NULL;
@ -243,8 +242,8 @@ createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_taskmgr_t *taskmgr,
return (result);
}
result = dns_view_createresolver(view, taskmgr, ntasks, 1, socketmgr,
timermgr, 0, dispatchmgr, dispatchv4,
result = dns_view_createresolver(view, taskmgr, ntasks, 1, nm, timermgr,
0, dispatchmgr, dispatchv4,
dispatchv6);
if (result != ISC_R_SUCCESS) {
dns_view_detach(&view);
@ -264,9 +263,8 @@ createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_taskmgr_t *taskmgr,
isc_result_t
dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr,
unsigned int options, dns_client_t **clientp,
const isc_sockaddr_t *localaddr4,
isc_nm_t *nm, isc_timermgr_t *timermgr, unsigned int options,
dns_client_t **clientp, const isc_sockaddr_t *localaddr4,
const isc_sockaddr_t *localaddr6) {
isc_result_t result;
dns_client_t *client = NULL;
@ -278,27 +276,24 @@ dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
REQUIRE(mctx != NULL);
REQUIRE(taskmgr != NULL);
REQUIRE(timermgr != NULL);
REQUIRE(socketmgr != NULL);
REQUIRE(nm != NULL);
REQUIRE(clientp != NULL && *clientp == NULL);
UNUSED(options);
client = isc_mem_get(mctx, sizeof(*client));
*client = (dns_client_t){
.actx = actx, .taskmgr = taskmgr, .timermgr = timermgr, .nm = nm
};
isc_mutex_init(&client->lock);
client->actx = actx;
client->taskmgr = taskmgr;
client->socketmgr = socketmgr;
client->timermgr = timermgr;
client->task = NULL;
result = isc_task_create(client->taskmgr, 0, &client->task);
if (result != ISC_R_SUCCESS) {
goto cleanup_lock;
}
result = dns_dispatchmgr_create(mctx, &dispatchmgr);
result = dns_dispatchmgr_create(mctx, nm, &dispatchmgr);
if (result != ISC_R_SUCCESS) {
goto cleanup_task;
}
@ -311,8 +306,8 @@ dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
*/
client->dispatchv4 = NULL;
if (localaddr4 != NULL || localaddr6 == NULL) {
result = getudpdispatch(AF_INET, dispatchmgr, socketmgr,
taskmgr, &dispatchv4, localaddr4);
result = getudpdispatch(AF_INET, dispatchmgr, taskmgr,
&dispatchv4, localaddr4);
if (result == ISC_R_SUCCESS) {
client->dispatchv4 = dispatchv4;
}
@ -320,8 +315,8 @@ dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
client->dispatchv6 = NULL;
if (localaddr6 != NULL || localaddr4 == NULL) {
result = getudpdispatch(AF_INET6, dispatchmgr, socketmgr,
taskmgr, &dispatchv6, localaddr6);
result = getudpdispatch(AF_INET6, dispatchmgr, taskmgr,
&dispatchv6, localaddr6);
if (result == ISC_R_SUCCESS) {
client->dispatchv6 = dispatchv6;
}
@ -337,8 +332,8 @@ dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
/* Create the default view for class IN */
result = createview(mctx, dns_rdataclass_in, taskmgr, RESOLVER_NTASKS,
socketmgr, timermgr, dispatchmgr, dispatchv4,
dispatchv6, &view);
nm, timermgr, dispatchmgr, dispatchv4, dispatchv6,
&view);
if (result != ISC_R_SUCCESS) {
goto cleanup_references;
}
@ -350,12 +345,10 @@ dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
ISC_LIST_INIT(client->resctxs);
client->mctx = NULL;
isc_mem_attach(mctx, &client->mctx);
client->find_timeout = DEF_FIND_TIMEOUT;
client->find_udpretries = DEF_FIND_UDPRETRIES;
client->attributes = 0;
client->magic = DNS_CLIENT_MAGIC;

File diff suppressed because it is too large Load Diff

View File

@ -89,9 +89,8 @@ typedef struct dns_clientresevent {
isc_result_t
dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr,
unsigned int options, dns_client_t **clientp,
const isc_sockaddr_t *localaddr4,
isc_nm_t *nm, isc_timermgr_t *timermgr, unsigned int options,
dns_client_t **clientp, const isc_sockaddr_t *localaddr4,
const isc_sockaddr_t *localaddr6);
/*%<
* Create a DNS client object with minimal internal resources, such as
@ -113,7 +112,7 @@ dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
*
*\li 'taskmgr' is a valid task manager.
*
*\li 'socketmgr' is a valid socket manager.
*\li 'nm' is a valid network manager.
*
*\li 'timermgr' is a valid timer manager.
*

View File

@ -9,6 +9,8 @@
* information regarding copyright ownership.
*/
#include <isc/netmgr.h>
#ifndef DNS_DISPATCH_H
#define DNS_DISPATCH_H 1
@ -50,6 +52,7 @@
#include <isc/buffer.h>
#include <isc/lang.h>
#include <isc/mutex.h>
#include <isc/netmgr.h>
#include <isc/socket.h>
#include <isc/types.h>
@ -76,12 +79,9 @@ ISC_LANG_BEGINDECLS
struct dns_dispatchevent {
ISC_EVENT_COMMON(dns_dispatchevent_t); /*%< standard event common */
isc_result_t result; /*%< result code */
int32_t id; /*%< message id */
isc_sockaddr_t addr; /*%< address recv'd from */
struct in6_pktinfo pktinfo; /*%< reply info for v6 */
isc_buffer_t buffer; /*%< data buffer */
uint32_t attributes; /*%< mirrored from socket.h */
isc_result_t result; /*%< result code */
isc_region_t region; /*%< data region */
isc_buffer_t buffer; /*%< data buffer */
};
/*%
@ -128,14 +128,16 @@ struct dns_dispatchset {
#define DNS_DISPATCHOPT_FIXEDID 0x00000001U
isc_result_t
dns_dispatchmgr_create(isc_mem_t *mctx, dns_dispatchmgr_t **mgrp);
dns_dispatchmgr_create(isc_mem_t *mctx, isc_nm_t *nm, dns_dispatchmgr_t **mgrp);
/*%<
* Creates a new dispatchmgr object, and sets the available ports
* to the default range (1024-65535).
*
* Requires:
*\li "mctx" be a valid memory context.
*\li 'mctx' be a valid memory context.
*
*\li 'nm' is a valid network manager.
*\li mgrp != NULL && *mgrp == NULL
*
* Returns:
@ -205,9 +207,9 @@ dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats);
*/
isc_result_t
dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr,
unsigned int attributes, dns_dispatch_t **dispp);
dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
const isc_sockaddr_t *localaddr, unsigned int attributes,
dns_dispatch_t **dispp);
/*%<
* Create a new UDP dispatch.
*
@ -223,8 +225,8 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
*/
isc_result_t
dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr,
dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
const isc_sockaddr_t *localaddr,
const isc_sockaddr_t *destaddr, unsigned int attributes,
isc_dscp_t dscp, dns_dispatch_t **dispp);
/*%<
@ -265,15 +267,13 @@ dns_dispatch_detach(dns_dispatch_t **dispp);
*/
isc_result_t
dns_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp,
isc_task_t *task, isc_taskaction_t action, void *arg);
dns_dispatch_connect(dns_dispentry_t *resp);
/*%<
* Connect the UDP socket in 'resp' or the TCP socket in 'disp' to the
* remote server, and run the specified callback.
* Connect to the remote server configured in 'resp' and run the
* connect callback that was set up via dns_dispatch_addresponse().
*
* Requires:
*\li 'resp' is NULL and 'disp' is valid, or
*\li 'disp' is NULL and 'resp' is valid.
*\li 'resp' is valid.
*/
void
@ -288,29 +288,16 @@ dns_dispatch_cancel(dns_dispatch_t *disp, dns_dispentry_t *resp, bool sending,
*\li 'disp' is NULL and 'resp' is valid.
*/
isc_result_t
dns_dispatch_send(dns_dispentry_t *resp, bool tcp, isc_task_t *task,
isc_socketevent_t *sendevent, isc_region_t *r,
const isc_sockaddr_t *address, isc_dscp_t dscp,
isc_taskaction_t action, void *arg);
void
dns_dispatch_send(dns_dispentry_t *resp, isc_region_t *r, isc_dscp_t dscp);
/*%<
* Send region 'r' using the socket in 'resp', then run the specified
* callback. 'sendevent' must point to enough memory to hold an
* isc_socketevent; it will be overwritten.
* callback.
*
* Requires:
*\li 'resp' is valid.
*/
void
dns_dispatch_starttcp(dns_dispatch_t *disp);
/*%<
* Start processing of a TCP dispatch once the socket connects.
*
* Requires:
*\li 'disp' is valid.
*/
isc_result_t
dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr,
const isc_sockaddr_t *localaddr, bool *connected,
@ -322,18 +309,29 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr,
isc_result_t
dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
const isc_sockaddr_t *dest, isc_task_t *task,
isc_taskaction_t action, void *arg, uint16_t *idp,
dns_dispentry_t **resp, isc_socketmgr_t *sockmgr);
unsigned int timeout, const isc_sockaddr_t *dest,
isc_task_t *task, isc_nm_cb_t connected,
isc_nm_cb_t sent, isc_taskaction_t action,
isc_taskaction_t timeout_action, void *arg,
dns_messageid_t *idp, dns_dispentry_t **resp);
/*%<
* Add a response entry for this dispatch.
*
* "*idp" is filled in with the assigned message ID, and *resp is filled in
* to contain the magic token used to request event flow stop.
*
* Arranges for the given task to get a callback for response packets. When
* the event is delivered, it must be returned using dns_dispatch_freeevent()
* or through dns_dispatch_removeresponse() for another to be delivered.
* The 'connected' and 'sent' callbacks are run to inform the caller when
* the connection and send functions are complete.
*
* The specified 'task' is sent the 'action' callback for response packets.
* (Later, this should be updated to a network manager callback function,
* but for now we still use isc_task for this.) When the event is delivered,
* it must be returned using dns_dispatch_freeevent() or through
* dns_dispatch_removeresponse() for another to be delivered.
*
* On timeout, 'timeout_action' will be sent to the task.
*
* All three callback functions are sent 'arg' as a parameter.
*
* Requires:
*\li "idp" be non-NULL.
@ -344,10 +342,6 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
*
*\li "resp" be non-NULL and *resp be NULL
*
*\li "sockmgr" be NULL or a valid socket manager. If 'disp' has
* the DNS_DISPATCHATTR_EXCLUSIVE attribute, this must not be NULL,
* which also means dns_dispatch_addresponse() cannot be used.
*
* Ensures:
*
*\li &lt;id, dest> is a unique tuple. That means incoming messages
@ -452,9 +446,9 @@ dns_dispatchset_get(dns_dispatchset_t *dset);
*/
isc_result_t
dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr,
isc_taskmgr_t *taskmgr, dns_dispatch_t *source,
dns_dispatchset_t **dsetp, int n);
dns_dispatchset_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
dns_dispatch_t *source, dns_dispatchset_t **dsetp,
int n);
/*%<
* Given a valid dispatch 'source', create a dispatch set containing
* 'n' UDP dispatches, with the remainder filled out by clones of the

View File

@ -53,8 +53,7 @@ typedef struct dns_requestevent {
ISC_LANG_BEGINDECLS
isc_result_t
dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr,
dns_requestmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
dns_dispatchmgr_t *dispatchmgr,
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
dns_requestmgr_t **requestmgrp);
@ -65,8 +64,6 @@ dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
*
*\li 'mctx' is a valid memory context.
*
*\li 'timermgr' is a valid timer manager.
*
*\li 'socketmgr' is a valid socket manager.
*
*\li 'taskmgr' is a valid task manager.

View File

@ -163,11 +163,10 @@ typedef enum { dns_quotatype_zone = 0, dns_quotatype_server } dns_quotatype_t;
isc_result_t
dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
unsigned int ntasks, unsigned int ndisp,
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);
unsigned int ntasks, unsigned int ndisp, isc_nm_t *nm,
isc_timermgr_t *timermgr, unsigned int options,
dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4,
dns_dispatch_t *dispatchv6, dns_resolver_t **resp);
/*%<
* Create a resolver.
@ -185,7 +184,7 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
*
*\li 'ntasks' > 0.
*
*\li 'socketmgr' is a valid socket manager.
*\li 'nm' is a valid network manager.
*
*\li 'timermgr' is a valid timer manager.
*
@ -413,9 +412,6 @@ dns_resolver_dispatchv4(dns_resolver_t *resolver);
dns_dispatch_t *
dns_resolver_dispatchv6(dns_resolver_t *resolver);
isc_socketmgr_t *
dns_resolver_socketmgr(dns_resolver_t *resolver);
isc_taskmgr_t *
dns_resolver_taskmgr(dns_resolver_t *resolver);

View File

@ -393,9 +393,9 @@ dns_view_createzonetable(dns_view_t *view);
isc_result_t
dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
unsigned int ntasks, unsigned int ndisp,
isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr,
unsigned int options, dns_dispatchmgr_t *dispatchmgr,
unsigned int ntasks, unsigned int ndisp, isc_nm_t *nm,
isc_timermgr_t *timermgr, unsigned int options,
dns_dispatchmgr_t *dispatchmgr,
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6);
/*%<
* Create a resolver and address database for the view.
@ -407,7 +407,7 @@ dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
*\li 'view' does not have a resolver already.
*
*\li The requirements of dns_resolver_create() apply to 'taskmgr',
* 'ntasks', 'socketmgr', 'timermgr', 'options', 'dispatchv4', and
* 'ntasks', 'nm', 'timermgr', 'options', 'dispatchv4', and
* 'dispatchv6'.
*
* Returns:

View File

@ -17,7 +17,6 @@
#include <isc/magic.h>
#include <isc/mem.h>
#include <isc/task.h>
#include <isc/timer.h>
#include <isc/util.h>
#include <dns/acl.h>
@ -50,8 +49,6 @@ struct dns_requestmgr {
/* locked */
int32_t eref;
int32_t iref;
isc_timermgr_t *timermgr;
isc_socketmgr_t *socketmgr;
isc_taskmgr_t *taskmgr;
dns_dispatchmgr_t *dispatchmgr;
dns_dispatch_t *dispatchv4;
@ -74,7 +71,6 @@ struct dns_request {
dns_requestevent_t *event;
dns_dispatch_t *dispatch;
dns_dispentry_t *dispentry;
isc_timer_t *timer;
dns_requestmgr_t *requestmgr;
isc_buffer_t *tsig;
dns_tsigkey_t *tsigkey;
@ -115,16 +111,16 @@ static isc_result_t
req_render(dns_message_t *message, isc_buffer_t **buffer, unsigned int options,
isc_mem_t *mctx);
static void
req_senddone(isc_task_t *task, isc_event_t *event);
static void
req_response(isc_task_t *task, isc_event_t *event);
static void
req_timeout(isc_task_t *task, isc_event_t *event);
static void
req_connected(isc_task_t *task, isc_event_t *event);
req_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *arg);
static void
req_sendevent(dns_request_t *request, isc_result_t result);
static void
req_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg);
static void
req_cancel(dns_request_t *request);
static void
req_destroy(dns_request_t *request);
@ -138,8 +134,7 @@ do_cancel(isc_task_t *task, isc_event_t *event);
***/
isc_result_t
dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr,
dns_requestmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
dns_dispatchmgr_t *dispatchmgr,
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
dns_requestmgr_t **requestmgrp) {
@ -150,8 +145,6 @@ dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create");
REQUIRE(requestmgrp != NULL && *requestmgrp == NULL);
REQUIRE(timermgr != NULL);
REQUIRE(socketmgr != NULL);
REQUIRE(taskmgr != NULL);
REQUIRE(dispatchmgr != NULL);
@ -171,8 +164,6 @@ dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
for (i = 0; i < DNS_REQUEST_NLOCKS; i++) {
isc_mutex_init(&requestmgr->locks[i]);
}
requestmgr->timermgr = timermgr;
requestmgr->socketmgr = socketmgr;
requestmgr->taskmgr = taskmgr;
requestmgr->dispatchmgr = dispatchmgr;
requestmgr->dispatchv4 = NULL;
@ -410,12 +401,9 @@ mgr_gethash(dns_requestmgr_t *requestmgr) {
return (requestmgr->hash % DNS_REQUEST_NLOCKS);
}
static inline isc_result_t
req_send(dns_request_t *request, isc_task_t *task,
const isc_sockaddr_t *address) {
isc_result_t result;
static inline void
req_send(dns_request_t *request) {
isc_region_t r;
bool tcp;
req_log(ISC_LOG_DEBUG(3), "req_send: request %p", request);
@ -423,14 +411,8 @@ req_send(dns_request_t *request, isc_task_t *task,
isc_buffer_usedregion(request->query, &r);
tcp = dns_request_usedtcp(request);
request->flags |= DNS_REQUEST_F_SENDING;
result = dns_dispatch_send(request->dispentry, tcp, task,
&request->sendevent, &r, address,
request->dscp, req_senddone, request);
INSIST(result == ISC_R_SUCCESS);
return (result);
dns_dispatch_send(request->dispentry, &r, request->dscp);
}
static isc_result_t
@ -497,9 +479,9 @@ tcp_dispatch(bool newtcp, dns_requestmgr_t *requestmgr,
}
}
result = dns_dispatch_createtcp(
requestmgr->dispatchmgr, requestmgr->socketmgr,
requestmgr->taskmgr, srcaddr, destaddr, 0, dscp, dispatchp);
result = dns_dispatch_createtcp(requestmgr->dispatchmgr,
requestmgr->taskmgr, srcaddr, destaddr,
0, dscp, dispatchp);
return (result);
}
@ -528,9 +510,9 @@ udp_dispatch(dns_requestmgr_t *requestmgr, const isc_sockaddr_t *srcaddr,
return (ISC_R_SUCCESS);
}
return (dns_dispatch_createudp(
requestmgr->dispatchmgr, requestmgr->socketmgr,
requestmgr->taskmgr, srcaddr, 0, dispatchp));
return (dns_dispatch_createudp(requestmgr->dispatchmgr,
requestmgr->taskmgr, srcaddr, 0,
dispatchp));
}
static isc_result_t
@ -548,25 +530,6 @@ get_dispatch(bool tcp, bool newtcp, dns_requestmgr_t *requestmgr,
return (result);
}
static isc_result_t
set_timer(isc_timer_t *timer, unsigned int timeout, unsigned int udpresend) {
isc_time_t expires;
isc_interval_t interval;
isc_result_t result;
isc_timertype_t timertype;
isc_interval_set(&interval, timeout, 0);
result = isc_time_nowplusinterval(&expires, &interval);
isc_interval_set(&interval, udpresend, 0);
timertype = udpresend != 0 ? isc_timertype_limited : isc_timertype_once;
if (result == ISC_R_SUCCESS) {
result = isc_timer_reset(timer, timertype, &expires, &interval,
false);
}
return (result);
}
isc_result_t
dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
const isc_sockaddr_t *srcaddr,
@ -617,19 +580,13 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
udptimeout = 1;
}
}
timeout *= 1000;
udptimeout *= 1000;
request->udpcount = udpretries;
request->dscp = dscp;
/*
* Create timer now. We will set it below once.
*/
result = isc_timer_create(requestmgr->timermgr, isc_timertype_inactive,
NULL, NULL, task, req_timeout, request,
&request->timer);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
request->event = (dns_requestevent_t *)isc_event_allocate(
mctx, task, DNS_EVENT_REQUESTDONE, action, arg,
sizeof(dns_requestevent_t));
@ -661,8 +618,9 @@ again:
}
result = dns_dispatch_addresponse(
request->dispatch, dispopt, destaddr, task, req_response,
request, &id, &request->dispentry, requestmgr->socketmgr);
request->dispatch, dispopt, tcp ? timeout : udptimeout,
destaddr, task, req_connected, req_senddone, req_response,
req_timeout, request, &id, &request->dispentry);
if (result != ISC_R_SUCCESS) {
if ((options & DNS_REQUESTOPT_FIXEDID) != 0 && !newtcp) {
newtcp = true;
@ -674,9 +632,6 @@ again:
}
isc_buffer_allocate(mctx, &request->query, r.length + (tcp ? 2 : 0));
if (tcp) {
isc_buffer_putuint16(request->query, (uint16_t)r.length);
}
result = isc_buffer_copyregion(request->query, &r);
if (result != ISC_R_SUCCESS) {
goto cleanup;
@ -684,9 +639,6 @@ again:
/* Add message ID. */
isc_buffer_usedregion(request->query, &r);
if (tcp) {
isc_region_consume(&r, 2);
}
r.base[0] = (id >> 8) & 0xff;
r.base[1] = id & 0xff;
@ -701,24 +653,15 @@ again:
ISC_LIST_APPEND(requestmgr->requests, request, link);
UNLOCK(&requestmgr->lock);
result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout);
if (result != ISC_R_SUCCESS) {
goto unlink;
}
request->destaddr = *destaddr;
if (tcp && !connected) {
result = dns_dispatch_connect(request->dispatch, NULL, task,
req_connected, request);
if (!tcp || !connected) {
result = dns_dispatch_connect(request->dispentry);
if (result != ISC_R_SUCCESS) {
goto unlink;
}
request->flags |= DNS_REQUEST_F_CONNECTING | DNS_REQUEST_F_TCP;
} else {
result = req_send(request, task, connected ? NULL : destaddr);
if (result != ISC_R_SUCCESS) {
goto unlink;
}
req_send(request);
}
req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: request %p", request);
@ -790,7 +733,6 @@ dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
return (DNS_R_BLACKHOLED);
}
request = NULL;
result = new_request(mctx, &request);
if (result != ISC_R_SUCCESS) {
return (result);
@ -802,19 +744,13 @@ dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
udptimeout = 1;
}
}
timeout *= 1000;
udptimeout *= 1000;
request->udpcount = udpretries;
request->dscp = dscp;
/*
* Create timer now. We will set it below once.
*/
result = isc_timer_create(requestmgr->timermgr, isc_timertype_inactive,
NULL, NULL, task, req_timeout, request,
&request->timer);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
request->event = (dns_requestevent_t *)isc_event_allocate(
mctx, task, DNS_EVENT_REQUESTDONE, action, arg,
sizeof(dns_requestevent_t));
@ -835,8 +771,9 @@ use_tcp:
}
result = dns_dispatch_addresponse(
request->dispatch, 0, destaddr, task, req_response, request,
&id, &request->dispentry, requestmgr->socketmgr);
request->dispatch, 0, tcp ? timeout : udptimeout, destaddr,
task, req_connected, req_senddone, req_response, req_timeout,
request, &id, &request->dispentry);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
@ -880,24 +817,15 @@ use_tcp:
ISC_LIST_APPEND(requestmgr->requests, request, link);
UNLOCK(&requestmgr->lock);
result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout);
if (result != ISC_R_SUCCESS) {
goto unlink;
}
request->destaddr = *destaddr;
if (tcp && !connected) {
result = dns_dispatch_connect(request->dispatch, NULL, task,
req_connected, request);
if (!tcp || !connected) {
result = dns_dispatch_connect(request->dispentry);
if (result != ISC_R_SUCCESS) {
goto unlink;
}
request->flags |= DNS_REQUEST_F_CONNECTING | DNS_REQUEST_F_TCP;
} else {
result = req_send(request, task, connected ? NULL : destaddr);
if (result != ISC_R_SUCCESS) {
goto unlink;
}
req_send(request);
}
req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: request %p", request);
@ -926,7 +854,6 @@ req_render(dns_message_t *message, isc_buffer_t **bufferp, unsigned int options,
isc_buffer_t *buf2 = NULL;
isc_result_t result;
isc_region_t r;
bool tcp = false;
dns_compress_t cctx;
bool cleanup_cctx = false;
@ -984,16 +911,11 @@ req_render(dns_message_t *message, isc_buffer_t **bufferp, unsigned int options,
* Copy rendered message to exact sized buffer.
*/
isc_buffer_usedregion(buf1, &r);
if ((options & DNS_REQUESTOPT_TCP) != 0) {
tcp = true;
} else if (r.length > 512) {
if ((options & DNS_REQUESTOPT_TCP) == 0 && r.length > 512) {
result = DNS_R_USETCP;
goto cleanup;
}
isc_buffer_allocate(mctx, &buf2, r.length + (tcp ? 2 : 0));
if (tcp) {
isc_buffer_putuint16(buf2, (uint16_t)r.length);
}
isc_buffer_allocate(mctx, &buf2, r.length);
result = isc_buffer_copyregion(buf2, &r);
if (result != ISC_R_SUCCESS) {
goto cleanup;
@ -1138,7 +1060,6 @@ dns_request_destroy(dns_request_t **requestp) {
INSIST(!ISC_LINK_LINKED(request, link));
INSIST(request->dispentry == NULL);
INSIST(request->dispatch == NULL);
INSIST(request->timer == NULL);
req_destroy(request);
}
@ -1147,12 +1068,11 @@ dns_request_destroy(dns_request_t **requestp) {
*** Private: request.
***/
static void
req_connected(isc_task_t *task, isc_event_t *event) {
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
isc_result_t result;
dns_request_t *request = event->ev_arg;
req_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
dns_request_t *request = (dns_request_t *)arg;
UNUSED(handle);
REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
REQUIRE(VALID_REQUEST(request));
REQUIRE(DNS_REQUEST_CONNECTING(request));
@ -1171,53 +1091,42 @@ req_connected(isc_task_t *task, isc_event_t *event) {
send_if_done(request, ISC_R_CANCELED);
}
} else {
dns_dispatch_starttcp(request->dispatch);
result = sevent->result;
if (result == ISC_R_SUCCESS) {
result = req_send(request, task, NULL);
}
if (result != ISC_R_SUCCESS) {
if (eresult == ISC_R_SUCCESS) {
req_send(request);
} else {
req_cancel(request);
send_if_done(request, ISC_R_CANCELED);
}
}
UNLOCK(&request->requestmgr->locks[request->hash]);
isc_event_free(&event);
}
static void
req_senddone(isc_task_t *task, isc_event_t *event) {
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
dns_request_t *request = event->ev_arg;
req_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
dns_request_t *request = (dns_request_t *)arg;
REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);
REQUIRE(VALID_REQUEST(request));
REQUIRE(DNS_REQUEST_SENDING(request));
req_log(ISC_LOG_DEBUG(3), "req_senddone: request %p", request);
UNUSED(handle);
UNUSED(task);
req_log(ISC_LOG_DEBUG(3), "req_senddone: request %p", request);
LOCK(&request->requestmgr->locks[request->hash]);
request->flags &= ~DNS_REQUEST_F_SENDING;
if (DNS_REQUEST_CANCELED(request)) {
/*
* Send delayed event.
*/
if (DNS_REQUEST_TIMEDOUT(request)) {
send_if_done(request, ISC_R_TIMEDOUT);
} else {
send_if_done(request, ISC_R_CANCELED);
}
} else if (sevent->result != ISC_R_SUCCESS) {
} else if (eresult != ISC_R_SUCCESS) {
req_cancel(request);
send_if_done(request, ISC_R_CANCELED);
}
UNLOCK(&request->requestmgr->locks[request->hash]);
isc_event_free(&event);
UNLOCK(&request->requestmgr->locks[request->hash]);
}
static void
@ -1266,7 +1175,6 @@ done:
static void
req_timeout(isc_task_t *task, isc_event_t *event) {
dns_request_t *request = event->ev_arg;
isc_result_t result;
REQUIRE(VALID_REQUEST(request));
@ -1274,13 +1182,9 @@ req_timeout(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
LOCK(&request->requestmgr->locks[request->hash]);
if (event->ev_type == ISC_TIMEREVENT_TICK && request->udpcount-- != 0) {
if (request->udpcount-- != 0) {
if (!DNS_REQUEST_SENDING(request)) {
result = req_send(request, task, &request->destaddr);
if (result != ISC_R_SUCCESS) {
req_cancel(request);
send_if_done(request, result);
}
req_send(request);
}
} else {
request->flags |= DNS_REQUEST_F_TIMEDOUT;
@ -1330,9 +1234,6 @@ req_destroy(dns_request_t *request) {
if (request->dispatch != NULL) {
dns_dispatch_detach(&request->dispatch);
}
if (request->timer != NULL) {
isc_timer_detach(&request->timer);
}
if (request->tsig != NULL) {
isc_buffer_free(&request->tsig);
}
@ -1359,10 +1260,6 @@ req_cancel(dns_request_t *request) {
*/
request->flags |= DNS_REQUEST_F_CANCELED;
if (request->timer != NULL) {
isc_timer_detach(&request->timer);
}
if (request->dispentry != NULL) {
dns_dispatch_cancel(NULL, request->dispentry,
DNS_REQUEST_SENDING(request),

View File

@ -496,7 +496,7 @@ struct dns_resolver {
isc_mutex_t lock;
isc_mutex_t primelock;
dns_rdataclass_t rdclass;
isc_socketmgr_t *socketmgr;
isc_nm_t *nm;
isc_timermgr_t *timermgr;
isc_taskmgr_t *taskmgr;
dns_view_t *view;
@ -604,7 +604,7 @@ resquery_send(resquery_t *query);
static void
resquery_response(isc_task_t *task, isc_event_t *event);
static void
resquery_connected(isc_task_t *task, isc_event_t *event);
resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg);
static void
fctx_try(fetchctx_t *fctx, bool retrying, bool badcache);
static isc_result_t
@ -1354,10 +1354,11 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
}
dns_adb_adjustsrtt(fctx->adb, query->addrinfo, rtt, factor);
}
if ((query->options & DNS_FETCHOPT_TCP) == 0) {
/* Inform the ADB that we're ending a UDP fetch */
dns_adb_endudpfetch(fctx->adb, query->addrinfo);
if ((query->options & DNS_FETCHOPT_TCP) == 0) {
/* Inform the ADB that we're ending a UDP fetch */
dns_adb_endudpfetch(fctx->adb, query->addrinfo);
}
}
/*
@ -1428,7 +1429,9 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
dns_dispatch_removeresponse(&query->dispentry, deventp);
}
ISC_LIST_UNLINK(fctx->queries, query, link);
if (ISC_LINK_LINKED(query, link)) {
ISC_LIST_UNLINK(fctx->queries, query, link);
}
if (query->tsig != NULL) {
isc_buffer_free(&query->tsig);
@ -1796,13 +1799,20 @@ fctx_done(fetchctx_t *fctx, isc_result_t result, int line) {
}
static void
process_sendevent(resquery_t *query, isc_event_t *event) {
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
resquery_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
resquery_t *query = (resquery_t *)arg;
bool destroy_query = false;
bool retry = false;
isc_result_t result;
fetchctx_t *fctx = NULL;
QTRACE("senddone");
UNUSED(handle);
INSIST(RESQUERY_SENDING(query));
query->sends--;
fctx = query->fctx;
if (RESQUERY_CANCELED(query)) {
@ -1810,7 +1820,7 @@ process_sendevent(resquery_t *query, isc_event_t *event) {
destroy_query = true;
}
} else {
switch (sevent->result) {
switch (eresult) {
case ISC_R_SUCCESS:
break;
@ -1819,94 +1829,44 @@ process_sendevent(resquery_t *query, isc_event_t *event) {
case ISC_R_NOPERM:
case ISC_R_ADDRNOTAVAIL:
case ISC_R_CONNREFUSED:
FCTXTRACE3("query canceled in sendevent(): "
FCTXTRACE3("query canceled in resquery_senddone(): "
"no route to host; no response",
sevent->result);
eresult);
/*
* No route to remote.
*/
add_bad(fctx, query->rmessage, query->addrinfo,
sevent->result, badns_unreachable);
add_bad(fctx, query->rmessage, query->addrinfo, eresult,
badns_unreachable);
fctx_cancelquery(&query, NULL, NULL, true, false);
retry = true;
/*
* Behave as if the idle timer has expired. For TCP
* this may not actually reflect the latest timer.
*/
FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
result = fctx_stopidletimer(fctx);
if (result != ISC_R_SUCCESS) {
fctx_done(fctx, result, __LINE__);
} else {
fctx_try(fctx, true, false);
}
break;
default:
FCTXTRACE3("query canceled in sendevent() due to "
"unexpected event result; responding",
sevent->result);
FCTXTRACE3("query canceled in resquery_senddone() "
"due to unexpected result; responding",
eresult);
fctx_cancelquery(&query, NULL, NULL, false, false);
break;
}
}
if (event->ev_type == ISC_SOCKEVENT_CONNECT) {
isc_event_free(&event);
}
if (retry) {
/*
* Behave as if the idle timer has expired. For TCP
* this may not actually reflect the latest timer.
*/
FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
result = fctx_stopidletimer(fctx);
if (result != ISC_R_SUCCESS) {
fctx_done(fctx, result, __LINE__);
} else {
fctx_try(fctx, true, false);
}
}
if (destroy_query) {
resquery_destroy(&query);
}
}
static void
resquery_udpconnected(isc_task_t *task, isc_event_t *event) {
resquery_t *query = event->ev_arg;
REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
QTRACE("udpconnected");
UNUSED(task);
INSIST(RESQUERY_CONNECTING(query));
query->connects--;
process_sendevent(query, event);
}
static void
resquery_senddone(isc_task_t *task, isc_event_t *event) {
resquery_t *query = event->ev_arg;
REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);
QTRACE("senddone");
/*
* XXXRTH
*
* Currently we don't wait for the senddone event before retrying
* a query. This means that if we get really behind, we may end
* up doing extra work!
*/
UNUSED(task);
INSIST(RESQUERY_SENDING(query));
query->sends--;
process_sendevent(query, event);
}
static inline isc_result_t
fctx_addopt(dns_message_t *message, unsigned int version, uint16_t udpsize,
dns_ednsopt_t *ednsopts, size_t count) {
@ -1972,15 +1932,14 @@ fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) {
static isc_result_t
fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
unsigned int options) {
isc_result_t result;
dns_resolver_t *res = NULL;
isc_task_t *task = NULL;
isc_result_t result;
resquery_t *query = NULL;
isc_sockaddr_t addr;
bool have_addr = false;
unsigned int srtt;
isc_dscp_t dscp = -1;
unsigned int bucketnum;
FCTXTRACE("query");
@ -2088,9 +2047,9 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
query->dscp = dscp;
}
result = dns_dispatch_createtcp(
res->dispatchmgr, res->socketmgr, res->taskmgr, &addr,
&addrinfo->sockaddr, 0, query->dscp, &query->dispatch);
result = dns_dispatch_createtcp(res->dispatchmgr, res->taskmgr,
&addr, &addrinfo->sockaddr, 0,
query->dscp, &query->dispatch);
if (result != ISC_R_SUCCESS) {
goto cleanup_query;
}
@ -2107,9 +2066,9 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
result = ISC_R_NOTIMPLEMENTED;
goto cleanup_query;
}
result = dns_dispatch_createudp(
res->dispatchmgr, res->socketmgr, res->taskmgr,
&addr, 0, &query->dispatch);
result = dns_dispatch_createudp(res->dispatchmgr,
res->taskmgr, &addr, 0,
&query->dispatch);
if (result != ISC_R_SUCCESS) {
goto cleanup_query;
}
@ -2150,49 +2109,34 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
ISC_LINK_INIT(query, link);
query->magic = QUERY_MAGIC;
if ((query->options & DNS_FETCHOPT_TCP) != 0) {
/*
* Connect to the remote server.
*/
result = dns_dispatch_connect(query->dispatch, NULL, task,
resquery_connected, query);
if (result != ISC_R_SUCCESS) {
goto cleanup_dispatch;
}
query->connects++;
QTRACE("connecting via TCP");
} else {
if ((query->options & DNS_FETCHOPT_TCP) == 0) {
if (dns_adbentry_overquota(addrinfo->entry)) {
goto cleanup_dispatch;
}
/* Inform the ADB that we're starting a UDP fetch */
dns_adb_beginudpfetch(fctx->adb, addrinfo);
result = resquery_send(query);
if (result != ISC_R_SUCCESS) {
goto cleanup_dispatch;
}
}
fctx->querysent++;
ISC_LIST_APPEND(fctx->queries, query, link);
bucketnum = fctx->bucketnum;
LOCK(&res->buckets[bucketnum].lock);
LOCK(&res->buckets[fctx->bucketnum].lock);
fctx->nqueries++;
UNLOCK(&res->buckets[bucketnum].lock);
if (isc_sockaddr_pf(&addrinfo->sockaddr) == PF_INET) {
inc_stats(res, dns_resstatscounter_queryv4);
} else {
inc_stats(res, dns_resstatscounter_queryv6);
}
if (res->view->resquerystats != NULL) {
dns_rdatatypestats_increment(res->view->resquerystats,
fctx->type);
UNLOCK(&res->buckets[fctx->bucketnum].lock);
/* Set up the dispatch and set the query ID */
/* XXX: timeout hard-coded to 10 seconds */
result = dns_dispatch_addresponse(
query->dispatch, 0, 10000, &query->addrinfo->sockaddr, task,
resquery_connected, resquery_senddone, resquery_response, NULL,
query, &query->id, &query->dispentry);
if (result != ISC_R_SUCCESS) {
goto cleanup_dispatch;
}
return (ISC_R_SUCCESS);
/* Connect the socket */
query->connects++;
fctx_increference(fctx);
result = dns_dispatch_connect(query->dispentry);
return (result);
cleanup_dispatch:
if (query->dispatch != NULL) {
@ -2349,21 +2293,19 @@ issecuredomain(dns_view_t *view, const dns_name_t *name, dns_rdatatype_t type,
static isc_result_t
resquery_send(resquery_t *query) {
fetchctx_t *fctx = NULL;
isc_result_t result;
fetchctx_t *fctx = query->fctx;
dns_resolver_t *res = fctx->res;
isc_buffer_t buffer;
dns_name_t *qname = NULL;
dns_rdataset_t *qrdataset = NULL;
isc_region_t r;
dns_resolver_t *res = NULL;
isc_task_t *task = NULL;
isc_buffer_t tcpbuffer;
isc_buffer_t *buffer = NULL;
isc_netaddr_t ipaddr;
dns_tsigkey_t *tsigkey = NULL;
dns_peer_t *peer = NULL;
bool useedns;
dns_compress_t cctx;
bool cleanup_cctx = false;
bool useedns;
bool secure_domain;
bool tcp = ((query->options & DNS_FETCHOPT_TCP) != 0);
dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
@ -2377,24 +2319,11 @@ resquery_send(resquery_t *query) {
isc_buffer_t zb;
#endif /* HAVE_DNSTAP */
fctx = query->fctx;
QTRACE("send");
res = fctx->res;
task = res->buckets[fctx->bucketnum].task;
if (tcp) {
/*
* Reserve space for the TCP message length.
*/
isc_buffer_init(&tcpbuffer, query->data, sizeof(query->data));
isc_buffer_init(&query->buffer, query->data + 2,
sizeof(query->data) - 2);
buffer = &tcpbuffer;
} else {
isc_buffer_init(&query->buffer, query->data,
sizeof(query->data));
buffer = &query->buffer;
if (atomic_load_acquire(&res->exiting)) {
FCTXTRACE("resquery_send: resolver shutting down");
return (ISC_R_SHUTTINGDOWN);
}
result = dns_message_gettempname(fctx->qmessage, &qname);
@ -2406,17 +2335,6 @@ resquery_send(resquery_t *query) {
goto cleanup_temps;
}
/*
* Get a query id from the dispatch.
*/
result = dns_dispatch_addresponse(query->dispatch, 0,
&query->addrinfo->sockaddr, task,
resquery_response, query, &query->id,
&query->dispentry, res->socketmgr);
if (result != ISC_R_SUCCESS) {
goto cleanup_temps;
}
fctx->qmessage->opcode = dns_opcode_query;
/*
@ -2479,7 +2397,8 @@ resquery_send(resquery_t *query) {
}
cleanup_cctx = true;
result = dns_message_renderbegin(fctx->qmessage, &cctx, &query->buffer);
isc_buffer_init(&buffer, query->data, sizeof(query->data));
result = dns_message_renderbegin(fctx->qmessage, &cctx, &buffer);
if (result != ISC_R_SUCCESS) {
goto cleanup_message;
}
@ -2490,7 +2409,6 @@ resquery_send(resquery_t *query) {
goto cleanup_message;
}
peer = NULL;
isc_netaddr_fromsockaddr(&ipaddr, &query->addrinfo->sockaddr);
(void)dns_peerlist_peerbyaddr(fctx->res->view->peers, &ipaddr, &peer);
@ -2757,16 +2675,6 @@ resquery_send(resquery_t *query) {
}
}
/*
* If using TCP, write the length of the message at the beginning
* of the buffer.
*/
if (tcp) {
isc_buffer_usedregion(&query->buffer, &r);
isc_buffer_putuint16(&tcpbuffer, (uint16_t)r.length);
isc_buffer_add(&tcpbuffer, r.length);
}
/*
* Log the outgoing packet.
*/
@ -2780,23 +2688,9 @@ resquery_send(resquery_t *query) {
*/
dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
if (!tcp) {
/* Connect the UDP socket */
result = dns_dispatch_connect(NULL, query->dispentry, task,
resquery_udpconnected, query);
if (result != ISC_R_SUCCESS) {
goto cleanup_message;
}
query->connects++;
}
isc_buffer_usedregion(&buffer, &r);
isc_buffer_usedregion(buffer, &r);
result = dns_dispatch_send(query->dispentry, tcp, task,
&query->sendevent, &r,
&query->addrinfo->sockaddr, query->dscp,
resquery_senddone, query);
INSIST(result == ISC_R_SUCCESS);
dns_dispatch_send(query->dispentry, &r, query->dscp);
query->sends++;
QTRACE("sent");
@ -2817,7 +2711,7 @@ resquery_send(resquery_t *query) {
}
dns_dt_send(fctx->res->view, dtmsgtype, la, &query->addrinfo->sockaddr,
tcp, &zr, &query->start, NULL, &query->buffer);
tcp, &zr, &query->start, NULL, &buffer);
#endif /* HAVE_DNSTAP */
return (ISC_R_SUCCESS);
@ -2846,40 +2740,40 @@ cleanup_temps:
}
static void
resquery_connected(isc_task_t *task, isc_event_t *event) {
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
resquery_t *query = event->ev_arg;
bool retry = false;
resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
resquery_t *query = (resquery_t *)arg;
isc_interval_t interval;
isc_result_t result;
fetchctx_t *fctx;
fetchctx_t *fctx = NULL;
dns_resolver_t *res = NULL;
unsigned int bucketnum;
bool bucket_empty;
int pf;
REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
REQUIRE(VALID_QUERY(query));
QTRACE("connected");
UNUSED(task);
/*
* XXXRTH
*
* Currently we don't wait for the connect event before retrying
* a query. This means that if we get really behind, we may end
* up doing extra work!
*/
UNUSED(handle);
query->connects--;
fctx = query->fctx;
res = fctx->res;
bucketnum = fctx->bucketnum;
if (atomic_load_acquire(&res->exiting)) {
eresult = ISC_R_SHUTTINGDOWN;
}
if (RESQUERY_CANCELED(query)) {
/*
* This query was canceled while the connect() was in
* progress.
* This query was canceled while the connect() was
* in progress.
*/
resquery_destroy(&query);
} else {
switch (sevent->result) {
switch (eresult) {
case ISC_R_SUCCESS:
/*
@ -2890,8 +2784,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
* received.
*/
isc_interval_set(&interval,
fctx->res->query_timeout / 1000 / 2,
0);
res->query_timeout / 1000 / 2, 0);
result = fctx_startidletimer(query->fctx, &interval);
if (result != ISC_R_SUCCESS) {
FCTXTRACE("query canceled: idle timer failed; "
@ -2904,7 +2797,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
}
/*
* We are connected. Update the dispatcher and
* We are connected. Update the dispatcher and
* send the query.
*/
dns_dispatch_changeattributes(
@ -2920,6 +2813,20 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
false);
fctx_done(fctx, result, __LINE__);
}
fctx->querysent++;
ISC_LIST_APPEND(fctx->queries, query, link);
pf = isc_sockaddr_pf(&query->addrinfo->sockaddr);
if (pf == PF_INET) {
inc_stats(res, dns_resstatscounter_queryv4);
} else {
inc_stats(res, dns_resstatscounter_queryv6);
}
if (res->view->resquerystats != NULL) {
dns_rdatatypestats_increment(
res->view->resquerystats, fctx->type);
}
break;
case ISC_R_NETUNREACH:
@ -2928,45 +2835,46 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
case ISC_R_NOPERM:
case ISC_R_ADDRNOTAVAIL:
case ISC_R_CONNECTIONRESET:
FCTXTRACE3("query canceled in connected(): "
FCTXTRACE3("query canceled in resquery_connected(): "
"no route to host; no response",
sevent->result);
eresult);
/*
* Do not query this server again in this fetch context
* if the server is unavailable over TCP.
*/
add_bad(fctx, query->rmessage, query->addrinfo,
sevent->result, badns_unreachable);
add_bad(fctx, query->rmessage, query->addrinfo, eresult,
badns_unreachable);
fctx_cancelquery(&query, NULL, NULL, true, false);
retry = true;
/*
* Behave as if the idle timer has expired. For
* TCP connections this may not actually reflect
* the latest timer.
*/
FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
result = fctx_stopidletimer(fctx);
if (result != ISC_R_SUCCESS) {
fctx_done(fctx, result, __LINE__);
} else {
fctx_try(fctx, true, false);
}
break;
default:
FCTXTRACE3("query canceled in connected() due to "
"unexpected event result; responding",
sevent->result);
FCTXTRACE3("query canceled in resquery_connected() "
"due to unexpected result; responding",
eresult);
dns_dispatch_detach(&query->dispatch);
fctx_cancelquery(&query, NULL, NULL, false, false);
break;
}
}
isc_event_free(&event);
if (retry) {
/*
* Behave as if the idle timer has expired. For TCP
* connections this may not actually reflect the latest timer.
*/
FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
result = fctx_stopidletimer(fctx);
if (result != ISC_R_SUCCESS) {
fctx_done(fctx, result, __LINE__);
} else {
fctx_try(fctx, true, false);
}
LOCK(&res->buckets[bucketnum].lock);
bucket_empty = fctx_decreference(fctx);
UNLOCK(&res->buckets[bucketnum].lock);
if (bucket_empty) {
empty_bucket(res);
}
}
@ -4140,7 +4048,6 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
}
fctx_increference(fctx);
result = fctx_query(fctx, addrinfo, fctx->options);
if (result != ISC_R_SUCCESS) {
fctx_done(fctx, result, __LINE__);
@ -5033,8 +4940,8 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
(res->query_timeout - 1000));
/*
* Compute an expiration time after which stale data will
* attempted to be served, if stale answers are enabled and
* target RRset is available in cache.
* be served, if stale answers are enabled and target RRset is
* available in cache.
*/
isc_interval_set(
&interval, res->view->staleanswerclienttimeout / 1000,
@ -7521,6 +7428,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
if (atomic_load_acquire(&fctx->res->exiting)) {
result = ISC_R_SHUTTINGDOWN;
FCTXTRACE("resolver shutting down");
rctx.finish = NULL;
rctx_done(&rctx, result);
return;
}
@ -9689,13 +9597,13 @@ rctx_done(respctx_t *rctx, isc_result_t result) {
/*
* Need to attach to the message until the scope
* of this function ends, since there are many places
* where te message is used and/or may be destroyed
* where the message is used and/or may be destroyed
* before this function ends.
*/
dns_message_t *message = NULL;
dns_message_attach(query->rmessage, &message);
FCTXTRACE4("query canceled in response(); ",
FCTXTRACE4("query canceled in rctx_done(); ",
rctx->no_response ? "no response" : "responding", result);
/*
@ -10128,11 +10036,10 @@ spillattimer_countdown(isc_task_t *task, isc_event_t *event) {
isc_result_t
dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
unsigned int ntasks, unsigned int ndisp,
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) {
unsigned int ntasks, unsigned int ndisp, isc_nm_t *nm,
isc_timermgr_t *timermgr, unsigned int options,
dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4,
dns_dispatch_t *dispatchv6, dns_resolver_t **resp) {
dns_resolver_t *res = NULL;
isc_result_t result = ISC_R_SUCCESS;
unsigned int i, buckets_created = 0, dbuckets_created = 0;
@ -10154,7 +10061,7 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
res = isc_mem_get(view->mctx, sizeof(*res));
*res = (dns_resolver_t){ .mctx = view->mctx,
.rdclass = view->rdclass,
.socketmgr = socketmgr,
.nm = nm,
.timermgr = timermgr,
.taskmgr = taskmgr,
.dispatchmgr = dispatchmgr,
@ -10230,13 +10137,13 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
}
if (dispatchv4 != NULL) {
dns_dispatchset_create(view->mctx, socketmgr, taskmgr,
dispatchv4, &res->dispatches4, ndisp);
dns_dispatchset_create(view->mctx, taskmgr, dispatchv4,
&res->dispatches4, ndisp);
}
if (dispatchv6 != NULL) {
dns_dispatchset_create(view->mctx, socketmgr, taskmgr,
dispatchv6, &res->dispatches6, ndisp);
dns_dispatchset_create(view->mctx, taskmgr, dispatchv6,
&res->dispatches6, ndisp);
}
isc_mutex_init(&res->lock);
@ -10951,12 +10858,6 @@ dns_resolver_dispatchv6(dns_resolver_t *resolver) {
return (dns_dispatchset_get(resolver->dispatches6));
}
isc_socketmgr_t *
dns_resolver_socketmgr(dns_resolver_t *resolver) {
REQUIRE(VALID_RESOLVER(resolver));
return (resolver->socketmgr);
}
isc_taskmgr_t *
dns_resolver_taskmgr(dns_resolver_t *resolver) {
REQUIRE(VALID_RESOLVER(resolver));

View File

@ -20,16 +20,17 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <uv.h>
#define UNIT_TESTING
#include <cmocka.h>
#include <isc/app.h>
#include <isc/buffer.h>
#include <isc/managers.h>
#include <isc/refcount.h>
#include <isc/socket.h>
#include <isc/task.h>
#include <isc/timer.h>
#include <isc/util.h>
#include <dns/dispatch.h>
@ -38,18 +39,91 @@
#include "dnstest.h"
/* Timeouts in miliseconds */
#define T_INIT 120 * 1000
#define T_IDLE 120 * 1000
#define T_KEEPALIVE 120 * 1000
#define T_ADVERTISED 120 * 1000
#define T_CONNECT 30 * 1000
dns_dispatchmgr_t *dispatchmgr = NULL;
dns_dispatchset_t *dset = NULL;
isc_nm_t *connect_nm = NULL;
static isc_sockaddr_t server_addr;
static isc_sockaddr_t connect_addr;
static int
setup_ephemeral_port(isc_sockaddr_t *addr, sa_family_t family) {
socklen_t addrlen = sizeof(*addr);
uv_os_sock_t fd;
int r;
isc_sockaddr_fromin6(addr, &in6addr_loopback, 0);
fd = socket(AF_INET6, family, 0);
if (fd < 0) {
perror("setup_ephemeral_port: socket()");
return (-1);
}
r = bind(fd, (const struct sockaddr *)&addr->type.sa,
sizeof(addr->type.sin6));
if (r != 0) {
perror("setup_ephemeral_port: bind()");
close(fd);
return (r);
}
r = getsockname(fd, (struct sockaddr *)&addr->type.sa, &addrlen);
if (r != 0) {
perror("setup_ephemeral_port: getsockname()");
close(fd);
return (r);
}
#if IPV6_RECVERR
#define setsockopt_on(socket, level, name) \
setsockopt(socket, level, name, &(int){ 1 }, sizeof(int))
r = setsockopt_on(fd, IPPROTO_IPV6, IPV6_RECVERR);
if (r != 0) {
perror("setup_ephemeral_port");
close(fd);
return (r);
}
#endif
return (fd);
}
static int
_setup(void **state) {
isc_result_t result;
uv_os_sock_t sock = -1;
UNUSED(state);
result = dns_test_begin(NULL, true);
assert_int_equal(result, ISC_R_SUCCESS);
connect_addr = (isc_sockaddr_t){ .length = 0 };
isc_sockaddr_fromin6(&connect_addr, &in6addr_loopback, 0);
server_addr = (isc_sockaddr_t){ .length = 0 };
sock = setup_ephemeral_port(&server_addr, SOCK_DGRAM);
if (sock < 0) {
return (-1);
}
close(sock);
/* Create a secondary network manager */
isc_managers_create(dt_mctx, ncpus, 0, 0, &connect_nm, NULL, NULL,
NULL);
isc_nm_settimeouts(netmgr, T_INIT, T_IDLE, T_KEEPALIVE, T_ADVERTISED);
isc_nm_settimeouts(connect_nm, T_INIT, T_IDLE, T_KEEPALIVE,
T_ADVERTISED);
return (0);
}
@ -57,6 +131,9 @@ static int
_teardown(void **state) {
UNUSED(state);
isc_managers_destroy(&connect_nm, NULL, NULL, NULL);
assert_null(connect_nm);
dns_test_end();
return (0);
@ -68,20 +145,18 @@ make_dispatchset(unsigned int ndisps) {
isc_sockaddr_t any;
dns_dispatch_t *disp = NULL;
result = dns_dispatchmgr_create(dt_mctx, &dispatchmgr);
result = dns_dispatchmgr_create(dt_mctx, netmgr, &dispatchmgr);
if (result != ISC_R_SUCCESS) {
return (result);
}
isc_sockaddr_any(&any);
result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, &any,
0, &disp);
result = dns_dispatch_createudp(dispatchmgr, taskmgr, &any, 0, &disp);
if (result != ISC_R_SUCCESS) {
return (result);
}
result = dns_dispatchset_create(dt_mctx, socketmgr, taskmgr, disp,
&dset, ndisps);
result = dns_dispatchset_create(dt_mctx, taskmgr, disp, &dset, ndisps);
dns_dispatch_detach(&disp);
return (result);
@ -155,68 +230,57 @@ dispatchset_get(void **state) {
reset();
}
struct {
isc_nmhandle_t *handle;
atomic_uint_fast32_t responses;
} testdata;
static dns_dispatch_t *dispatch = NULL;
static dns_dispentry_t *dispentry = NULL;
static atomic_bool first = ATOMIC_VAR_INIT(true);
static void
senddone(isc_task_t *task, isc_event_t *event) {
isc_socket_t *sock = event->ev_arg;
server_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) {
UNUSED(handle);
UNUSED(eresult);
UNUSED(cbarg);
UNUSED(task);
isc_socket_detach(&sock);
isc_event_free(&event);
return;
}
static void
nameserver(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
isc_region_t region;
isc_socket_t *dummy;
isc_socket_t *sock = event->ev_arg;
isc_socketevent_t *ev = (isc_socketevent_t *)event;
nameserver(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
void *cbarg) {
isc_region_t response;
static unsigned char buf1[16];
static unsigned char buf2[16];
memmove(buf1, ev->region.base, 12);
UNUSED(eresult);
UNUSED(cbarg);
memmove(buf1, region->base, 12);
memset(buf1 + 12, 0, 4);
buf1[2] |= 0x80; /* qr=1 */
memmove(buf2, ev->region.base, 12);
memmove(buf2, region->base, 12);
memset(buf2 + 12, 1, 4);
buf2[2] |= 0x80; /* qr=1 */
/*
* send message to be discarded.
*/
region.base = buf1;
region.length = sizeof(buf1);
dummy = NULL;
isc_socket_attach(sock, &dummy);
result = isc_socket_sendto(sock, &region, task, senddone, sock,
&ev->address, NULL);
if (result != ISC_R_SUCCESS) {
isc_socket_detach(&dummy);
}
response.base = buf1;
response.length = sizeof(buf1);
isc_nm_send(handle, &response, server_senddone, NULL);
/*
* send nextitem message.
*/
region.base = buf2;
region.length = sizeof(buf2);
dummy = NULL;
isc_socket_attach(sock, &dummy);
result = isc_socket_sendto(sock, &region, task, senddone, sock,
&ev->address, NULL);
if (result != ISC_R_SUCCESS) {
isc_socket_detach(&dummy);
}
isc_event_free(&event);
response.base = buf2;
response.length = sizeof(buf2);
isc_nm_send(handle, &response, server_senddone, NULL);
}
static dns_dispatch_t *dispatch = NULL;
static dns_dispentry_t *dispentry = NULL;
static atomic_bool first = ATOMIC_VAR_INIT(true);
static isc_sockaddr_t local;
static atomic_uint_fast32_t responses;
static void
response(isc_task_t *task, isc_event_t *event) {
dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event;
@ -224,78 +288,81 @@ response(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
atomic_fetch_add_relaxed(&responses, 1);
atomic_fetch_add_relaxed(&testdata.responses, 1);
if (atomic_compare_exchange_strong(&first, &exp_true, false)) {
isc_result_t result = dns_dispatch_getnext(dispentry, &devent);
assert_int_equal(result, ISC_R_SUCCESS);
} else {
dns_dispatch_removeresponse(&dispentry, &devent);
isc_nmhandle_detach(&testdata.handle);
isc_app_shutdown();
}
}
static void
startit(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
isc_socket_t *sock = NULL;
connected(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) {
isc_region_t *r = (isc_region_t *)cbarg;
isc_socket_attach(dns_dispatch_getentrysocket(dispentry), &sock);
result = isc_socket_sendto(sock, event->ev_arg, task, senddone, sock,
&local, NULL);
assert_int_equal(result, ISC_R_SUCCESS);
UNUSED(eresult);
isc_nmhandle_attach(handle, &testdata.handle);
dns_dispatch_send(dispentry, r, -1);
}
static void
client_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) {
UNUSED(handle);
UNUSED(eresult);
UNUSED(cbarg);
return;
}
static void
startit(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
dns_dispatch_connect(dispentry);
isc_event_free(&event);
}
/* test dispatch getnext */
static void
dispatch_getnext(void **state) {
isc_region_t region;
isc_result_t result;
isc_socket_t *sock = NULL;
isc_region_t region;
isc_nmsocket_t *sock = NULL;
isc_task_t *task = NULL;
uint16_t id;
struct in_addr ina;
unsigned char message[12];
unsigned char rbuf[12];
uint16_t id;
UNUSED(state);
atomic_init(&responses, 0);
testdata.handle = NULL;
atomic_init(&testdata.responses, 0);
result = isc_task_create(taskmgr, 0, &task);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_dispatchmgr_create(dt_mctx, &dispatchmgr);
result = dns_dispatchmgr_create(dt_mctx, connect_nm, &dispatchmgr);
assert_int_equal(result, ISC_R_SUCCESS);
ina.s_addr = htonl(INADDR_LOOPBACK);
isc_sockaddr_fromin(&local, &ina, 0);
result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, &local,
0, &dispatch);
result = dns_dispatch_createudp(dispatchmgr, taskmgr, &connect_addr, 0,
&dispatch);
assert_int_equal(result, ISC_R_SUCCESS);
/*
* Create a local udp nameserver on the loopback.
*/
result = isc_socket_create(socketmgr, AF_INET, isc_sockettype_udp,
&sock);
assert_int_equal(result, ISC_R_SUCCESS);
ina.s_addr = htonl(INADDR_LOOPBACK);
isc_sockaddr_fromin(&local, &ina, 0);
result = isc_socket_bind(sock, &local, 0);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_socket_getsockname(sock, &local);
result = isc_nm_listenudp(netmgr, &server_addr, nameserver, NULL, 0,
&sock);
assert_int_equal(result, ISC_R_SUCCESS);
region.base = rbuf;
region.length = sizeof(rbuf);
result = isc_socket_recv(sock, &region, 1, task, nameserver, sock);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_dispatch_addresponse(dispatch, 0, &local, task, response,
NULL, &id, &dispentry, socketmgr);
result = dns_dispatch_addresponse(
dispatch, 0, 10000, &server_addr, task, connected,
client_senddone, response, NULL, &region, &id, &dispentry);
assert_int_equal(result, ISC_R_SUCCESS);
memset(message, 0, sizeof(message));
@ -304,19 +371,22 @@ dispatch_getnext(void **state) {
region.base = message;
region.length = sizeof(message);
result = isc_app_onrun(dt_mctx, task, startit, &region);
result = isc_app_onrun(dt_mctx, task, startit, NULL);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_app_run();
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(atomic_load_acquire(&responses), 2);
assert_int_equal(atomic_load_acquire(&testdata.responses), 2);
isc_nm_stoplistening(sock);
isc_nmsocket_close(&sock);
assert_null(sock);
/*
* Shutdown nameserver.
*/
isc_socket_cancel(sock, task, ISC_SOCKCANCEL_RECV);
isc_socket_detach(&sock);
isc_task_detach(&task);
/*

View File

@ -34,6 +34,7 @@
#include <isc/lex.h>
#include <isc/managers.h>
#include <isc/mem.h>
#include <isc/netmgr.h>
#include <isc/os.h>
#include <isc/print.h>
#include <isc/socket.h>
@ -96,10 +97,12 @@ cleanup_managers(void) {
isc_task_shutdown(maintask);
isc_task_destroy(&maintask);
}
isc_managers_destroy(netmgr == NULL ? NULL : &netmgr,
taskmgr == NULL ? NULL : &taskmgr,
timermgr == NULL ? NULL : &timermgr,
socketmgr == NULL ? NULL : &socketmgr);
if (app_running) {
isc_app_finish();
}

View File

@ -46,6 +46,7 @@ extern isc_taskmgr_t *taskmgr;
extern isc_task_t *maintask;
extern isc_timermgr_t *timermgr;
extern isc_socketmgr_t *socketmgr;
extern isc_nm_t *netmgr;
extern dns_zonemgr_t *zonemgr;
extern bool app_running;
extern int ncpus;

View File

@ -50,15 +50,15 @@ _setup(void **state) {
result = dns_test_begin(NULL, true);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_dispatchmgr_create(dt_mctx, &dispatchmgr);
result = dns_dispatchmgr_create(dt_mctx, netmgr, &dispatchmgr);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_test_makeview("view", &view);
assert_int_equal(result, ISC_R_SUCCESS);
isc_sockaddr_any(&local);
result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, &local,
0, &dispatch);
result = dns_dispatch_createudp(dispatchmgr, taskmgr, &local, 0,
&dispatch);
assert_int_equal(result, ISC_R_SUCCESS);
return (0);
@ -80,8 +80,8 @@ static void
mkres(dns_resolver_t **resolverp) {
isc_result_t result;
result = dns_resolver_create(view, taskmgr, 1, 1, socketmgr, timermgr,
0, dispatchmgr, dispatch, NULL, resolverp);
result = dns_resolver_create(view, taskmgr, 1, 1, netmgr, timermgr, 0,
dispatchmgr, dispatch, NULL, resolverp);
assert_int_equal(result, ISC_R_SUCCESS);
}

View File

@ -634,6 +634,7 @@ view_flushanddetach(dns_view_t **viewp, bool flush) {
dns_zone_t *mkzone = NULL, *rdzone = NULL;
isc_refcount_destroy(&view->references);
if (!RESSHUTDOWN(view)) {
dns_resolver_shutdown(view->resolver);
}
@ -643,14 +644,14 @@ view_flushanddetach(dns_view_t **viewp, bool flush) {
if (!REQSHUTDOWN(view)) {
dns_requestmgr_shutdown(view->requestmgr);
}
LOCK(&view->lock);
if (view->zonetable != NULL) {
if (view->flush) {
dns_zt_flushanddetach(&view->zonetable);
} else {
dns_zt_detach(&view->zonetable);
}
if (view->zonetable != NULL && view->flush) {
dns_zt_flushanddetach(&view->zonetable);
} else if (view->zonetable != NULL) {
dns_zt_detach(&view->zonetable);
}
LOCK(&view->lock);
if (view->managed_keys != NULL) {
mkzone = view->managed_keys;
view->managed_keys = NULL;
@ -796,9 +797,9 @@ dns_view_createzonetable(dns_view_t *view) {
isc_result_t
dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
unsigned int ntasks, unsigned int ndisp,
isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr,
unsigned int options, dns_dispatchmgr_t *dispatchmgr,
unsigned int ntasks, unsigned int ndisp, isc_nm_t *nm,
isc_timermgr_t *timermgr, unsigned int options,
dns_dispatchmgr_t *dispatchmgr,
dns_dispatch_t *dispatchv4,
dns_dispatch_t *dispatchv6) {
isc_result_t result;
@ -815,8 +816,8 @@ dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
}
isc_task_setname(view->task, "view", view);
result = dns_resolver_create(view, taskmgr, ntasks, ndisp, socketmgr,
timermgr, options, dispatchmgr, dispatchv4,
result = dns_resolver_create(view, taskmgr, ntasks, ndisp, nm, timermgr,
options, dispatchmgr, dispatchv4,
dispatchv6, &view->resolver);
if (result != ISC_R_SUCCESS) {
isc_task_detach(&view->task);
@ -841,11 +842,10 @@ dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
atomic_fetch_and(&view->attributes, ~DNS_VIEWATTR_ADBSHUTDOWN);
isc_refcount_increment(&view->weakrefs);
result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
dns_resolver_taskmgr(view->resolver),
dns_resolver_dispatchmgr(view->resolver),
dispatchv4, dispatchv6,
&view->requestmgr);
result = dns_requestmgr_create(
view->mctx, dns_resolver_taskmgr(view->resolver),
dns_resolver_dispatchmgr(view->resolver), dispatchv4,
dispatchv6, &view->requestmgr);
if (result != ISC_R_SUCCESS) {
dns_adb_shutdown(view->adb);
dns_resolver_shutdown(view->resolver);
@ -2502,12 +2502,12 @@ dns_view_setviewcommit(dns_view_t *view) {
if (view->managed_keys != NULL) {
dns_zone_attach(view->managed_keys, &managed_keys);
}
if (view->zonetable != NULL) {
dns_zt_setviewcommit(view->zonetable);
}
UNLOCK(&view->lock);
if (view->zonetable != NULL) {
dns_zt_setviewcommit(view->zonetable);
}
if (redirect != NULL) {
dns_zone_setviewcommit(redirect);
dns_zone_detach(&redirect);

View File

@ -483,6 +483,7 @@ dns_zt_setviewcommit(dns_zt_t *zt) {
REQUIRE(VALID_ZT(zt));
RWLOCK(&zt->rwlock, isc_rwlocktype_read);
dns_rbtnodechain_init(&chain);
result = dns_rbtnodechain_first(&chain, zt->table, NULL, NULL);
@ -496,6 +497,7 @@ dns_zt_setviewcommit(dns_zt_t *zt) {
}
dns_rbtnodechain_invalidate(&chain);
RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
}
void

View File

@ -450,6 +450,16 @@ isc_nm_setstats(isc_nm_t *mgr, isc_stats_t *stats);
* full range of socket-related stats counter numbers.
*/
isc_result_t
isc_nm_checkaddr(const isc_sockaddr_t *addr, isc_socktype_t type);
/*%<
* Check whether the specified address is available on the local system
* by opening a socket and immediately closing it.
*
* Requires:
*\li 'addr' is not NULL.
*/
void
isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
isc_nm_cb_t cb, void *cbarg, unsigned int timeout,

View File

@ -91,7 +91,7 @@ isc_managers_destroy(isc_nm_t **netmgrp, isc_taskmgr_t **taskmgrp,
/*
* If we have a taskmgr to clean up, then we must also have a netmgr.
*/
REQUIRE(taskmgrp != NULL || netmgrp == NULL);
REQUIRE(taskmgrp == NULL || netmgrp != NULL);
/*
* The sequence of operations here is important:

View File

@ -2593,7 +2593,7 @@ isc_socket_close(isc_socket_t *sock) {
int fd;
isc_socketmgr_t *manager;
isc__socketthread_t *thread;
fflush(stdout);
REQUIRE(VALID_SOCKET(sock));
LOCK(&sock->lock);

View File

@ -482,7 +482,7 @@ ns_interface_listentcp(ns_interface_t *ifp) {
#if 0
#ifndef ISC_ALLOW_MAPPED
isc_socket_ipv6only(ifp->tcpsocket,true);
isc_socket_ipv6only(ifp->tcpsocket, true);
#endif /* ifndef ISC_ALLOW_MAPPED */
if (ifp->dscp != -1) {

View File

@ -233,7 +233,7 @@ create_managers(void) {
CHECK(ns_server_create(mctx, matchview, &sctx));
CHECK(dns_dispatchmgr_create(mctx, &dispatchmgr));
CHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
CHECK(ns_interfacemgr_create(mctx, sctx, taskmgr, timermgr, socketmgr,
netmgr, dispatchmgr, maintask, NULL, ncpus,