dispatch: Refactor to eliminate dns_dispatchevent

- Responses received by the dispatch are no longer sent to the caller
  via a task event, but via a netmgr-style recv callback.  the 'action'
  parameter to dns_dispatch_addresponse() is now called 'response' and
  is called directly from udp_recv() or tcp_recv() when a valid response
  has been received.

- All references to isc_task and isc_taskmgr have been removed from
  dispatch functions.

- All references to dns_dispatchevent_t have been removed and the type
  has been deleted.

- Added a task to the resolver response context, to be used for fctx
  events.

- When the caller cancels an operation, the response handler will be
  called with ISC_R_CANCELED; it can abort immediately since the caller
  will presumably have taken care of cleanup already.

- Cleaned up attach/detach in resquery and request.
This commit is contained in:
Evan Hunt 2021-07-26 20:23:18 -07:00
parent 81a22cbf5f
commit 8b532d2e64
18 changed files with 288 additions and 629 deletions

View file

@ -1315,8 +1315,7 @@ get_view_querysource_dispatch(const cfg_obj_t **maps, int af,
}
}
result = dns_dispatch_createudp(named_g_dispatchmgr, named_g_taskmgr,
&sa, attrs, &disp);
result = dns_dispatch_createudp(named_g_dispatchmgr, &sa, attrs, &disp);
if (result != ISC_R_SUCCESS) {
isc_sockaddr_t any;
char buf[ISC_SOCKADDR_FORMATSIZE];
@ -10145,8 +10144,8 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
server->heartbeat_interval = 0;
CHECKFATAL(dns_zonemgr_create(named_g_mctx, named_g_taskmgr,
named_g_timermgr, named_g_socketmgr,
named_g_netmgr, &server->zonemgr),
named_g_timermgr, named_g_netmgr,
&server->zonemgr),
"dns_zonemgr_create");
CHECKFATAL(dns_zonemgr_setsize(server->zonemgr, 1000), "dns_zonemgr_"
"setsize");
@ -10358,9 +10357,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_taskmgr,
&dispatch->addr, attrs,
&dispatch->dispatch);
result = dns_dispatch_createudp(named_g_dispatchmgr, &dispatch->addr,
attrs, &dispatch->dispatch);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}

View file

@ -935,15 +935,15 @@ setup_system(void) {
if (have_ipv6) {
isc_sockaddr_any6(&bind_any6);
result = dns_dispatch_createudp(dispatchmgr, taskmgr,
&bind_any6, 0, &dispatchv6);
result = dns_dispatch_createudp(dispatchmgr, &bind_any6, 0,
&dispatchv6);
check_result(result, "dns_dispatch_createudp (v6)");
}
if (have_ipv4) {
isc_sockaddr_any(&bind_any);
result = dns_dispatch_createudp(dispatchmgr, taskmgr, &bind_any,
0, &dispatchv4);
result = dns_dispatch_createudp(dispatchmgr, &bind_any, 0,
&dispatchv4);
check_result(result, "dns_dispatch_createudp (v4)");
}

View file

@ -269,9 +269,8 @@ main(int argc, char *argv[]) {
RUNCHECK(isc_task_create(taskmgr, 0, &task));
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
RUNCHECK(dns_dispatch_createudp(dispatchmgr, taskmgr,
have_src ? &srcaddr : &bind_any, 0,
&dispatchv4));
RUNCHECK(dns_dispatch_createudp(
dispatchmgr, have_src ? &srcaddr : &bind_any, 0, &dispatchv4));
RUNCHECK(dns_requestmgr_create(mctx, taskmgr, dispatchmgr, dispatchv4,
NULL, &requestmgr));

View file

@ -228,8 +228,8 @@ main(int argc, char *argv[]) {
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
isc_sockaddr_any(&bind_any);
RUNCHECK(dns_dispatch_createudp(dispatchmgr, taskmgr, &bind_any, 0,
&dispatchv4));
RUNCHECK(
dns_dispatch_createudp(dispatchmgr, &bind_any, 0, &dispatchv4));
RUNCHECK(dns_requestmgr_create(mctx, taskmgr, dispatchmgr, dispatchv4,
NULL, &requestmgr));

View file

@ -171,8 +171,8 @@ main(int argc, char **argv) {
RUNCHECK(isc_task_create(taskmgr, 0, &task));
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
isc_sockaddr_any(&bind_any);
RUNCHECK(dns_dispatch_createudp(dispatchmgr, taskmgr, &bind_any, 0,
&dispatchv4));
RUNCHECK(
dns_dispatch_createudp(dispatchmgr, &bind_any, 0, &dispatchv4));
RUNCHECK(dns_requestmgr_create(mctx, taskmgr, dispatchmgr, dispatchv4,
NULL, &requestmgr));

View file

@ -2128,9 +2128,8 @@ main(int argc, char *argv[]) {
} else {
isc_sockaddr_any6(&bind_any);
}
RUNCHECK(dns_dispatch_createudp(dispatchmgr, taskmgr,
have_src ? &srcaddr : &bind_any, 0,
&dispatchvx));
RUNCHECK(dns_dispatch_createudp(
dispatchmgr, have_src ? &srcaddr : &bind_any, 0, &dispatchvx));
RUNCHECK(dns_requestmgr_create(
mctx, taskmgr, dispatchmgr, have_ipv4 ? dispatchvx : NULL,

View file

@ -202,8 +202,7 @@ cleanup:
static isc_result_t
getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr,
isc_taskmgr_t *taskmgr, dns_dispatch_t **dispp,
const isc_sockaddr_t *localaddr) {
dns_dispatch_t **dispp, const isc_sockaddr_t *localaddr) {
dns_dispatch_t *disp = NULL;
isc_result_t result;
isc_sockaddr_t anyaddr;
@ -213,8 +212,7 @@ getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr,
localaddr = &anyaddr;
}
result = dns_dispatch_createudp(dispatchmgr, taskmgr, localaddr, 0,
&disp);
result = dns_dispatch_createudp(dispatchmgr, localaddr, 0, &disp);
if (result == ISC_R_SUCCESS) {
*dispp = disp;
}
@ -304,7 +302,7 @@ 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, client->dispatchmgr, taskmgr,
result = getudpdispatch(AF_INET, client->dispatchmgr,
&dispatchv4, localaddr4);
if (result == ISC_R_SUCCESS) {
client->dispatchv4 = dispatchv4;
@ -313,7 +311,7 @@ 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, client->dispatchmgr, taskmgr,
result = getudpdispatch(AF_INET6, client->dispatchmgr,
&dispatchv6, localaddr6);
if (result == ISC_R_SUCCESS) {
client->dispatchv6 = dispatchv6;

View file

@ -25,13 +25,11 @@
#include <isc/random.h>
#include <isc/stats.h>
#include <isc/string.h>
#include <isc/task.h>
#include <isc/time.h>
#include <isc/util.h>
#include <dns/acl.h>
#include <dns/dispatch.h>
#include <dns/events.h>
#include <dns/log.h>
#include <dns/message.h>
#include <dns/stats.h>
@ -79,7 +77,6 @@ struct dns_dispentry {
unsigned int magic;
isc_refcount_t references;
dns_dispatch_t *disp;
isc_task_t *task;
isc_nmhandle_t *handle; /*%< netmgr handle for UDP connection */
unsigned int bucket;
unsigned int timeout;
@ -89,11 +86,10 @@ struct dns_dispentry {
dns_messageid_t id;
isc_nm_cb_t connected;
isc_nm_cb_t sent;
isc_nm_recv_cb_t response;
isc_nm_cb_t timedout;
isc_taskaction_t action;
void *arg;
bool canceled;
ISC_LIST(dns_dispatchevent_t) items;
ISC_LINK(dns_dispentry_t) link;
ISC_LINK(dns_dispentry_t) alink;
};
@ -109,7 +105,6 @@ struct dns_dispatch {
/* Unlocked. */
unsigned int magic; /*%< magic */
dns_dispatchmgr_t *mgr; /*%< dispatch manager */
isc_task_t *task;
isc_nmhandle_t *handle; /*%< netmgr handle for TCP connection */
isc_sockaddr_t local; /*%< local address */
in_port_t localport; /*%< local UDP port */
@ -123,8 +118,7 @@ struct dns_dispatch {
isc_socktype_t socktype;
unsigned int attributes;
isc_refcount_t references;
dns_dispatchevent_t failsafe_ev; /*%< failsafe cancel event */
unsigned int shutdown_out : 1, recv_pending : 1;
unsigned int shutdown_out : 1;
ISC_LIST(dns_dispentry_t) active;
unsigned int nsockets;
@ -159,14 +153,6 @@ struct dns_dispatch {
#define DNS_DISPATCH_SOCKSQUOTA 3072
#endif /* ifndef DNS_DISPATCH_SOCKSQUOTA */
/*%
* Number of buffers available for all dispatches in the buffer
* memory pool.
*/
#ifndef DNS_DISPATCH_MAXBUFFERS
#define DNS_DISPATCH_MAXBUFFERS 37268
#endif /* ifndef DNS_DISPATCH_MAXBUFFERS */
/*%
* Quota to control the number of concurrent requests that can be handled
* by each TCP dispatch. (UDP dispatches do not currently support socket
@ -206,16 +192,11 @@ tcp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
void *arg);
static uint32_t
dns_hash(dns_qid_t *, const isc_sockaddr_t *, dns_messageid_t, in_port_t);
static inline void
free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev);
static inline dns_dispatchevent_t *
allocate_devent(dns_dispatch_t *disp);
static void
dispatch_free(dns_dispatch_t **dispp);
static isc_result_t
dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
const isc_sockaddr_t *localaddr, unsigned int attributes,
dns_dispatch_t **dispp);
dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
unsigned int attributes, dns_dispatch_t **dispp);
static void
qid_allocate(dns_dispatchmgr_t *mgr, dns_qid_t **qidp);
static void
@ -285,39 +266,6 @@ dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...) {
msgbuf);
}
static void
request_log(dns_dispatch_t *disp, dns_dispentry_t *resp, int level,
const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5);
static void
request_log(dns_dispatch_t *disp, dns_dispentry_t *resp, int level,
const char *fmt, ...) {
char msgbuf[2048];
va_list ap;
if (!isc_log_wouldlog(dns_lctx, level)) {
return;
}
va_start(ap, fmt);
vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
va_end(ap);
if (VALID_RESPONSE(resp)) {
char peerbuf[256];
isc_sockaddr_format(&resp->peer, peerbuf, sizeof(peerbuf));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH,
DNS_LOGMODULE_DISPATCH, level,
"dispatch %p response %p %s: %s", disp, resp,
peerbuf, msgbuf);
} else {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH,
DNS_LOGMODULE_DISPATCH, level,
"dispatch %p req/resp %p: %s", disp, resp,
msgbuf);
}
}
/*
* Return a hash of the destination and message id.
*/
@ -381,10 +329,12 @@ deactivate_dispentry(dns_dispatch_t *disp, dns_dispentry_t *resp) {
if (ISC_LINK_LINKED(resp, alink)) {
ISC_LIST_UNLINK(disp->active, resp, alink);
}
if (resp->handle != NULL) {
isc_nm_cancelread(resp->handle);
isc_nmhandle_detach(&resp->handle);
}
disp->nsockets--;
}
@ -414,79 +364,6 @@ entry_search(dns_qid_t *qid, const isc_sockaddr_t *dest, dns_messageid_t id,
return (NULL);
}
static void
free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
REQUIRE(buf != NULL && len != 0);
switch (disp->socktype) {
case isc_socktype_tcp:
INSIST(disp->tcpbuffers > 0);
disp->tcpbuffers--;
isc_mem_put(disp->mgr->mctx, buf, len);
break;
case isc_socktype_udp:
LOCK(&disp->mgr->buffer_lock);
INSIST(disp->mgr->buffers > 0);
INSIST(len == DNS_DISPATCH_UDPBUFSIZE);
disp->mgr->buffers--;
UNLOCK(&disp->mgr->buffer_lock);
isc_mem_put(disp->mgr->mctx, buf, len);
break;
default:
INSIST(0);
ISC_UNREACHABLE();
}
}
static void *
allocate_udp_buffer(dns_dispatch_t *disp) {
LOCK(&disp->mgr->buffer_lock);
if (disp->mgr->buffers >= DNS_DISPATCH_MAXBUFFERS) {
UNLOCK(&disp->mgr->buffer_lock);
return (NULL);
}
disp->mgr->buffers++;
UNLOCK(&disp->mgr->buffer_lock);
return (isc_mem_get(disp->mgr->mctx, DNS_DISPATCH_UDPBUFSIZE));
}
static inline void
free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev) {
/* failsafe_ev is not allocated */
if (&(disp->failsafe_ev) == ev) {
INSIST(disp->shutdown_out == 1);
disp->shutdown_out = 0;
return;
}
if (ev->region.base != NULL) {
free_buffer(disp, ev->region.base, ev->region.length);
ev->region.base = NULL;
ev->region.length = 0;
}
isc_mem_put(disp->mgr->mctx, ev, sizeof(*ev));
dns_dispatch_detach(&disp);
}
static inline dns_dispatchevent_t *
allocate_devent(dns_dispatch_t *disp) {
dns_dispatchevent_t *ev = NULL;
ev = isc_mem_get(disp->mgr->mctx, sizeof(*ev));
*ev = (dns_dispatchevent_t){ 0 };
dns_dispatch_attach(disp, &ev->dispatch);
ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, 0, NULL, NULL, NULL, NULL,
NULL);
return (ev);
}
static void
dispentry_attach(dns_dispentry_t *resp, dns_dispentry_t **respp) {
REQUIRE(VALID_RESPONSE(resp));
@ -509,7 +386,6 @@ dispentry_destroy(dns_dispentry_t *resp) {
isc_refcount_destroy(&resp->references);
isc_task_detach(&resp->task);
isc_mem_put(disp->mgr->mctx, resp, sizeof(*resp));
dns_dispatch_detach(&disp);
@ -554,14 +430,14 @@ udp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
isc_result_t dres;
isc_buffer_t source;
unsigned int flags;
dns_dispatchevent_t *rev = NULL;
isc_sockaddr_t peer;
isc_netaddr_t netaddr;
int match;
isc_taskaction_t action = NULL;
isc_nm_recv_cb_t response = NULL;
bool nomore = true;
REQUIRE(VALID_RESPONSE(resp));
REQUIRE(VALID_DISPATCH(resp->disp));
disp = resp->disp;
@ -569,8 +445,8 @@ udp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
if (isc_log_wouldlog(dns_lctx, LVL(90))) {
LOCK(&disp->mgr->buffer_lock);
dispatch_log(disp, LVL(90), "got packet: requests %d, recvs %d",
disp->requests, disp->recv_pending);
dispatch_log(disp, LVL(90), "got packet: requests %d",
disp->requests);
UNLOCK(&disp->mgr->buffer_lock);
}
@ -578,7 +454,7 @@ udp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
/*
* This dispatcher is shutting down.
*/
goto unlock;
goto sendevent;
}
if (!ISC_LINK_LINKED(resp, alink)) {
@ -661,43 +537,24 @@ udp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
}
sendevent:
rev = allocate_devent(disp);
/*
* At this point, rev contains the event we want to fill in, and
* resp contains the information on the place to send it to.
* Send the event off.
*/
rev->result = eresult;
if (region != NULL) {
rev->region.base = allocate_udp_buffer(disp);
rev->region.length = DNS_DISPATCH_UDPBUFSIZE;
memmove(rev->region.base, region->base, region->length);
isc_buffer_init(&rev->buffer, rev->region.base,
rev->region.length);
isc_buffer_add(&rev->buffer, rev->region.length);
}
ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH,
resp->action, resp->arg, resp, NULL, NULL);
request_log(disp, resp, LVL(90),
"[a] Sent event %p buffer %p len %d to task %p", rev,
rev->buffer.base, rev->buffer.length, resp->task);
action = resp->action;
response = resp->response;
unlock:
UNLOCK(&disp->lock);
if (action != NULL) {
action(resp->task, (isc_event_t *)rev);
if (response != NULL) {
response(handle, eresult, region, resp->arg);
}
if (nomore) {
dispentry_detach(&resp);
}
return;
}
/*
@ -718,32 +575,30 @@ unlock:
static void
tcp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
void *arg) {
dns_dispatch_t *disp = (dns_dispatch_t *)arg;
dns_dispentry_t *resp0 = (dns_dispentry_t *)arg;
dns_dispentry_t *resp = NULL;
dns_dispatch_t *disp = NULL;
dns_messageid_t id;
isc_result_t dres;
unsigned int flags;
dns_dispentry_t *resp = NULL;
dns_dispatchevent_t *rev = NULL;
unsigned int bucket;
dns_qid_t *qid = NULL;
int level;
char buf[ISC_SOCKADDR_FORMATSIZE];
isc_buffer_t source;
isc_sockaddr_t peer;
isc_taskaction_t action = NULL;
REQUIRE(VALID_DISPATCH(disp));
REQUIRE(VALID_RESPONSE(resp0));
REQUIRE(VALID_DISPATCH(resp0->disp));
disp = resp0->disp;
qid = disp->mgr->qid;
LOCK(&disp->lock);
dispatch_log(disp, LVL(90),
"got TCP packet: requests %d, buffers %d, recvs %d",
disp->requests, disp->tcpbuffers, disp->recv_pending);
INSIST(disp->recv_pending != 0);
disp->recv_pending = 0;
dispatch_log(disp, LVL(90), "got TCP packet: requests %d, buffers %d",
disp->requests, disp->tcpbuffers);
peer = isc_nmhandle_peeraddr(handle);
@ -761,13 +616,14 @@ tcp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
/*
* Time out the first active response for which
* no event has already been sent.
* FIXME: The code doesn't match the description
*/
for (resp = ISC_LIST_HEAD(disp->active); resp != NULL;
resp = ISC_LIST_NEXT(resp, alink))
{
ISC_LIST_UNLINK(disp->active, resp, alink);
ISC_LIST_APPEND(disp->active, resp, alink);
goto sendevent;
break;
}
break;
@ -832,48 +688,22 @@ tcp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
dispatch_log(disp, LVL(90), "search for response in bucket %d: %s",
bucket, (resp == NULL ? "not found" : "found"));
UNLOCK(&qid->lock);
if (resp == NULL) {
goto next;
goto unlock;
}
sendevent:
rev = allocate_devent(disp);
/*
* At this point, rev contains the event we want to fill in, and
* resp contains the information on the place to send it to.
* Send the event off.
*/
rev->result = eresult;
if (region != NULL) {
disp->tcpbuffers++;
rev->region.base = isc_mem_get(disp->mgr->mctx, region->length);
rev->region.length = region->length;
memmove(rev->region.base, region->base, region->length);
isc_buffer_init(&rev->buffer, rev->region.base,
rev->region.length);
isc_buffer_add(&rev->buffer, rev->region.length);
}
ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH,
resp->action, resp->arg, resp, NULL, NULL);
request_log(disp, resp, LVL(90),
"[b] Sent event %p buffer %p len %d to task %p", rev,
rev->buffer.base, rev->buffer.length, resp->task);
action = resp->action;
next:
startrecv(disp, NULL);
startrecv(disp, resp0);
unlock:
isc_nmhandle_detach(&handle);
UNLOCK(&disp->lock);
dns_dispatch_detach(&disp);
dispentry_detach(&resp0);
if (action != NULL) {
action(resp->task, (isc_event_t *)rev);
if (resp != NULL) {
resp->response(handle, eresult, region, resp->arg);
}
}
@ -1168,10 +998,6 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type, int pf,
isc_mutex_init(&disp->lock);
/* failsafe_ev is not allocated */
ISC_EVENT_INIT(&disp->failsafe_ev, sizeof(disp->failsafe_ev), 0, NULL,
0, NULL, NULL, NULL, NULL, NULL);
disp->magic = DISPATCH_MAGIC;
*dispp = disp;
@ -1195,7 +1021,6 @@ dispatch_free(dns_dispatch_t **dispp) {
REQUIRE(VALID_DISPATCHMGR(mgr));
INSIST(disp->requests == 0);
INSIST(disp->recv_pending == 0);
INSIST(ISC_LIST_EMPTY(disp->active));
isc_mutex_destroy(&disp->lock);
@ -1204,11 +1029,9 @@ dispatch_free(dns_dispatch_t **dispp) {
}
isc_result_t
dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
const isc_sockaddr_t *localaddr,
dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
const isc_sockaddr_t *destaddr, unsigned int attributes,
isc_dscp_t dscp, dns_dispatch_t **dispp) {
isc_result_t result;
dns_dispatch_t *disp = NULL;
int pf;
@ -1231,13 +1054,6 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
isc_sockaddr_setport(&disp->local, 0);
}
result = isc_task_create(taskmgr, 50, &disp->task);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
isc_task_setname(disp->task, "tcpdispatch", disp);
/*
* Append it to the dispatcher list.
*/
@ -1248,18 +1064,10 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
mgr_log(mgr, LVL(90),
"dns_dispatch_createtcp: created TCP dispatch %p",
disp);
dispatch_log(disp, LVL(90), "created task %p", disp->task);
}
*dispp = disp;
return (ISC_R_SUCCESS);
cleanup:
dispatch_free(&disp);
UNLOCK(&mgr->lock);
return (result);
}
#define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask)))
@ -1333,19 +1141,17 @@ again:
}
isc_result_t
dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
const isc_sockaddr_t *localaddr, unsigned int attributes,
dns_dispatch_t **dispp) {
dns_dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
unsigned int attributes, dns_dispatch_t **dispp) {
isc_result_t result;
dns_dispatch_t *disp = NULL;
REQUIRE(VALID_DISPATCHMGR(mgr));
REQUIRE(localaddr != NULL);
REQUIRE(taskmgr != NULL);
REQUIRE(dispp != NULL && *dispp == NULL);
LOCK(&mgr->lock);
result = dispatch_createudp(mgr, taskmgr, localaddr, attributes, &disp);
result = dispatch_createudp(mgr, localaddr, attributes, &disp);
if (result == ISC_R_SUCCESS) {
*dispp = disp;
}
@ -1355,9 +1161,8 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
}
static isc_result_t
dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
const isc_sockaddr_t *localaddr, unsigned int attributes,
dns_dispatch_t **dispp) {
dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
unsigned int attributes, dns_dispatch_t **dispp) {
isc_result_t result = ISC_R_SUCCESS;
dns_dispatch_t *disp = NULL;
isc_sockaddr_t sa_any;
@ -1388,10 +1193,6 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
}
disp->local = *localaddr;
result = isc_task_create(taskmgr, 0, &disp->task);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
/*
* Append it to the dispatcher list.
@ -1399,7 +1200,6 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
ISC_LIST_APPEND(mgr->list, disp, link);
mgr_log(mgr, LVL(90), "created UDP dispatcher %p", disp);
dispatch_log(disp, LVL(90), "created task %p", disp->task);
*dispp = disp;
@ -1429,8 +1229,6 @@ dns_dispatch_destroy(dns_dispatch_t *disp) {
isc_nmhandle_detach(&disp->handle);
}
isc_task_detach(&disp->task);
dispatch_free(&disp);
/* Because dispatch uses mgr->mctx, we must detach after freeing
@ -1463,7 +1261,6 @@ dns_dispatch_detach(dns_dispatch_t **dispp) {
dispatch_log(disp, LVL(90), "detach: refcount %" PRIuFAST32, ref - 1);
if (ref == 1) {
LOCK(&disp->lock);
REQUIRE(disp->recv_pending == 0);
REQUIRE(ISC_LIST_EMPTY(disp->active));
UNLOCK(&disp->lock);
@ -1474,9 +1271,9 @@ dns_dispatch_detach(dns_dispatch_t **dispp) {
isc_result_t
dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
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_nm_cb_t timedout, void *arg, dns_messageid_t *idp,
isc_nm_cb_t connected, isc_nm_cb_t sent,
isc_nm_recv_cb_t response, isc_nm_cb_t timedout,
void *arg, dns_messageid_t *idp,
dns_dispentry_t **resp) {
dns_dispentry_t *res = NULL;
dns_qid_t *qid = NULL;
@ -1485,12 +1282,9 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
unsigned int bucket;
bool ok = false;
int i = 0;
isc_taskaction_t oldest_action = NULL;
isc_task_t *oldest_task = NULL;
isc_event_t *oldest_ev = NULL;
isc_nm_recv_cb_t oldest_response = NULL;
REQUIRE(VALID_DISPATCH(disp));
REQUIRE(task != NULL);
REQUIRE(dest != NULL);
REQUIRE(resp != NULL && *resp == NULL);
REQUIRE(idp != NULL);
@ -1510,7 +1304,6 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
disp->nsockets > DNS_DISPATCH_SOCKSQUOTA)
{
dns_dispentry_t *oldest = NULL;
dns_dispatchevent_t *rev = NULL;
/*
* Kill oldest outstanding query if the number of sockets
@ -1518,17 +1311,7 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
*/
oldest = ISC_LIST_HEAD(disp->active);
if (oldest != NULL) {
rev = allocate_devent(oldest->disp);
rev->buffer.base = NULL;
rev->result = ISC_R_CANCELED;
ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL,
DNS_EVENT_DISPATCH, oldest->action,
oldest->arg, oldest, NULL, NULL);
oldest_action = oldest->action;
oldest_task = oldest->task;
oldest_ev = (isc_event_t *)rev;
oldest_response = oldest->response;
inc_stats(disp->mgr, dns_resstatscounter_dispabort);
}
}
@ -1541,12 +1324,11 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
.connected = connected,
.sent = sent,
.timedout = timedout,
.action = action,
.response = response,
.arg = arg };
isc_refcount_init(&res->references, 1);
ISC_LIST_INIT(res->items);
ISC_LINK_INIT(res, link);
ISC_LINK_INIT(res, alink);
@ -1593,8 +1375,6 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
dns_dispatch_attach(disp, &res->disp);
isc_task_attach(task, &res->task);
res->id = id;
res->bucket = bucket;
res->magic = RESPONSE_MAGIC;
@ -1605,8 +1385,6 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
ISC_LIST_APPEND(qid->qid_table[bucket], res, link);
UNLOCK(&qid->lock);
request_log(disp, res, LVL(90), "attached to task %p", res->task);
inc_stats(disp->mgr, (disp->socktype == isc_socktype_udp)
? dns_resstatscounter_disprequdp
: dns_resstatscounter_dispreqtcp);
@ -1615,8 +1393,8 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
UNLOCK(&disp->lock);
if (oldest_action != NULL) {
oldest_action(oldest_task, oldest_ev);
if (oldest_response != NULL) {
oldest_response(res->handle, ISC_R_CANCELED, NULL, res->arg);
}
*idp = id;
@ -1626,54 +1404,28 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
}
isc_result_t
dns_dispatch_getnext(dns_dispentry_t *resp, dns_dispatchevent_t **sockevent) {
dns_dispatch_getnext(dns_dispentry_t *resp) {
dns_dispatch_t *disp = NULL;
dns_dispatchevent_t *ev = NULL;
isc_taskaction_t action = NULL;
REQUIRE(VALID_RESPONSE(resp));
REQUIRE(sockevent != NULL && *sockevent != NULL);
disp = resp->disp;
REQUIRE(VALID_DISPATCH(disp));
ev = *sockevent;
*sockevent = NULL;
LOCK(&disp->lock);
free_devent(disp, ev);
ev = ISC_LIST_HEAD(resp->items);
if (ev != NULL) {
ISC_LIST_UNLINK(resp->items, ev, ev_link);
ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, DNS_EVENT_DISPATCH,
resp->action, resp->arg, resp, NULL, NULL);
request_log(disp, resp, LVL(90),
"[c] Sent event %p buffer %p len %d to task %p", ev,
ev->buffer.base, ev->buffer.length, resp->task);
action = resp->action;
}
startrecv(disp, resp);
UNLOCK(&disp->lock);
if (action != NULL) {
action(resp->task, (isc_event_t *)ev);
}
return (ISC_R_SUCCESS);
}
void
dns_dispatch_removeresponse(dns_dispentry_t **respp,
dns_dispatchevent_t **sockevent) {
dns_dispatch_removeresponse(dns_dispentry_t **respp) {
dns_dispatchmgr_t *mgr = NULL;
dns_dispatch_t *disp = NULL;
dns_dispentry_t *resp = NULL;
dns_dispatchevent_t *ev = NULL;
dns_qid_t *qid = NULL;
REQUIRE(respp != NULL);
@ -1692,14 +1444,6 @@ dns_dispatch_removeresponse(dns_dispentry_t **respp,
qid = mgr->qid;
if (sockevent != NULL) {
REQUIRE(*sockevent != NULL);
ev = *sockevent;
*sockevent = NULL;
} else {
ev = NULL;
}
LOCK(&disp->lock);
INSIST(disp->requests > 0);
disp->requests--;
@ -1715,20 +1459,6 @@ dns_dispatch_removeresponse(dns_dispentry_t **respp,
UNLOCK(&qid->lock);
UNLOCK(&disp->lock);
if (ev != NULL) {
free_devent(disp, ev);
}
/*
* Free any buffered responses as well
*/
ev = ISC_LIST_HEAD(resp->items);
while (ev != NULL) {
ISC_LIST_UNLINK(resp->items, ev, ev_link);
free_devent(disp, ev);
ev = ISC_LIST_HEAD(resp->items);
}
dispentry_detach(respp);
}
@ -1737,32 +1467,28 @@ dns_dispatch_removeresponse(dns_dispentry_t **respp,
*/
static void
startrecv(dns_dispatch_t *disp, dns_dispentry_t *resp) {
isc_nmhandle_t *handle = NULL;
dns_dispentry_t *tmp_resp = NULL;
dns_dispatch_t *tmp_disp = NULL;
switch (disp->socktype) {
case isc_socktype_udp:
REQUIRE(resp != NULL);
REQUIRE(resp->handle != NULL);
REQUIRE(resp != NULL && resp->handle != NULL);
dispentry_attach(resp, &tmp_resp);
/* resp->handle is detached in _removeresponse() */
dispentry_attach(resp, &(dns_dispentry_t *){ NULL });
isc_nm_read(resp->handle, udp_recv, resp);
break;
case isc_socktype_tcp:
if (resp != NULL) {
REQUIRE(resp->handle == NULL);
REQUIRE(resp != NULL && resp->handle == NULL);
REQUIRE(disp->handle != NULL);
if (isc_nmhandle_timer_running(disp->handle)) {
isc_nmhandle_settimeout(disp->handle, resp->timeout);
break;
}
isc_nmhandle_attach(disp->handle, &handle);
dns_dispatch_attach(disp, &tmp_disp);
isc_nm_read(handle, tcp_recv, disp);
INSIST(disp->recv_pending == 0);
disp->recv_pending = 1;
isc_nmhandle_attach(disp->handle, &(isc_nmhandle_t *){ NULL });
dispentry_attach(resp, &(dns_dispentry_t *){ NULL });
isc_nm_read(disp->handle, tcp_recv, resp);
break;
default:
INSIST(0);
ISC_UNREACHABLE();
@ -1779,13 +1505,6 @@ disp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
goto detach;
}
if (MGR_IS_SHUTTINGDOWN(disp->mgr)) {
eresult = ISC_R_SHUTTINGDOWN;
}
/*
* Start listening on success
*/
if (eresult == ISC_R_SUCCESS) {
switch (disp->socktype) {
case isc_socktype_udp:
@ -1793,13 +1512,12 @@ disp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
startrecv(disp, resp);
break;
case isc_socktype_tcp:
if (disp->handle == NULL) {
LOCK(&disp->lock);
isc_nmhandle_attach(handle, &disp->handle);
disp->attributes |= DNS_DISPATCHATTR_CONNECTED;
UNLOCK(&disp->lock);
startrecv(disp, resp);
}
REQUIRE(disp->handle == NULL);
LOCK(&disp->lock);
isc_nmhandle_attach(handle, &disp->handle);
disp->attributes |= DNS_DISPATCHATTR_CONNECTED;
UNLOCK(&disp->lock);
startrecv(disp, resp);
break;
default:
INSIST(0);
@ -1807,6 +1525,10 @@ disp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
}
}
if (MGR_IS_SHUTTINGDOWN(disp->mgr)) {
eresult = ISC_R_SHUTTINGDOWN;
}
if (resp->connected != NULL) {
resp->connected(handle, eresult, resp->arg);
}
@ -1829,11 +1551,6 @@ dns_dispatch_connect(dns_dispentry_t *resp) {
switch (disp->socktype) {
case isc_socktype_tcp:
INSIST(disp->handle == NULL);
if (disp->handle != NULL) {
/* We are already connected */
break;
}
isc_nm_tcpdnsconnect(disp->mgr->nm, &disp->local, &disp->peer,
disp_connected, resp, resp->timeout, 0);
break;
@ -1866,7 +1583,6 @@ send_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
void
dns_dispatch_send(dns_dispentry_t *resp, isc_region_t *r, isc_dscp_t dscp) {
isc_nmhandle_t *handle = NULL;
dns_dispentry_t *tmp = NULL;
REQUIRE(VALID_RESPONSE(resp));
@ -1888,7 +1604,7 @@ dns_dispatch_send(dns_dispentry_t *resp, isc_region_t *r, isc_dscp_t dscp) {
}
#endif
dispentry_attach(resp, &tmp); /* detached in send_done() */
dispentry_attach(resp, &(dns_dispentry_t *){ NULL });
isc_nm_send(handle, r, send_done, resp);
}
@ -1996,9 +1712,8 @@ dns_dispatchset_get(dns_dispatchset_t *dset) {
}
isc_result_t
dns_dispatchset_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
dns_dispatch_t *source, dns_dispatchset_t **dsetp,
int n) {
dns_dispatchset_create(isc_mem_t *mctx, dns_dispatch_t *source,
dns_dispatchset_t **dsetp, int n) {
isc_result_t result;
dns_dispatchset_t *dset = NULL;
dns_dispatchmgr_t *mgr = NULL;
@ -2025,7 +1740,7 @@ dns_dispatchset_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
LOCK(&mgr->lock);
for (i = 1; i < n; i++) {
dset->dispatches[i] = NULL;
result = dispatch_createudp(mgr, taskmgr, &source->local,
result = dispatch_createudp(mgr, &source->local,
source->attributes,
&dset->dispatches[i]);
if (result != ISC_R_SUCCESS) {

View file

@ -60,31 +60,6 @@
ISC_LANG_BEGINDECLS
/*%
* This event is sent to a task when a response comes in.
* No part of this structure should ever be modified by the caller,
* other than parts of the buffer. The holy parts of the buffer are
* the base and size of the buffer. All other parts of the buffer may
* be used. On event delivery the used region contains the packet.
*
* "id" is the received message id,
*
* "addr" is the host that sent it to us,
*
* "buffer" holds state on the received data.
*
* The "free" routine for this event will clean up itself as well as
* any buffer space allocated from common pools.
*/
struct dns_dispatchevent {
ISC_EVENT_COMMON(dns_dispatchevent_t); /*%< standard event common */
isc_result_t result; /*%< result code */
isc_region_t region; /*%< data region */
isc_buffer_t buffer; /*%< data buffer */
dns_dispatch_t *dispatch;
};
/*%
* This is a set of one or more dispatches which can be retrieved
* round-robin fashion.
@ -219,9 +194,8 @@ dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats);
*/
isc_result_t
dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
const isc_sockaddr_t *localaddr, unsigned int attributes,
dns_dispatch_t **dispp);
dns_dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
unsigned int attributes, dns_dispatch_t **dispp);
/*%<
* Create a new UDP dispatch.
*
@ -237,8 +211,7 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
*/
isc_result_t
dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
const isc_sockaddr_t *localaddr,
dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
const isc_sockaddr_t *destaddr, unsigned int attributes,
isc_dscp_t dscp, dns_dispatch_t **dispp);
/*%<
@ -250,8 +223,6 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
*
*\li sock is a valid.
*
*\li task is a valid task that can be used internally to this dispatcher.
*
* Returns:
*\li ISC_R_SUCCESS -- success.
*
@ -320,33 +291,28 @@ 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,
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_nm_cb_t timedout, void *arg, dns_messageid_t *idp,
isc_nm_cb_t connected, isc_nm_cb_t sent,
isc_nm_recv_cb_t response, isc_nm_cb_t timedout,
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.
* with the dispatch entry object.
*
* The 'connected' and 'sent' callbacks are run to inform the caller when
* the connect and send functions are complete. The 'timedout' callback
* is run to inform the caller that a read has timed out; it may optionally
* reset the read timer.
* reset the read timer. The 'response' callback is run for recv results
* (response packets, timeouts, or cancellations).
*
* 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.
*
* All three callback functions are sent 'arg' as a parameter.
* All the callback functions are sent 'arg' as a parameter.
*
* Requires:
*\li "idp" be non-NULL.
*
*\li "task" "action" and "arg" be set as appropriate.
*\li "response" and "arg" be set as appropriate.
*
*\li "dest" be non-NULL and valid.
*
@ -366,19 +332,13 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
*/
void
dns_dispatch_removeresponse(dns_dispentry_t ** resp,
dns_dispatchevent_t **sockevent);
dns_dispatch_removeresponse(dns_dispentry_t **resp);
/*%<
* Stops the flow of responses for the provided id and destination.
* If "sockevent" is non-NULL, the dispatch event and associated buffer is
* also returned to the system.
*
* Requires:
*\li "resp" != NULL and "*resp" contain a value previously allocated
* by dns_dispatch_addresponse();
*
*\li May only be called from within the task given as the 'task'
* argument to dns_dispatch_addresponse() when allocating '*resp'.
*/
isc_result_t
@ -456,9 +416,8 @@ dns_dispatchset_get(dns_dispatchset_t *dset);
*/
isc_result_t
dns_dispatchset_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
dns_dispatch_t *source, dns_dispatchset_t **dsetp,
int n);
dns_dispatchset_create(isc_mem_t *mctx, 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
@ -480,14 +439,12 @@ dns_dispatchset_destroy(dns_dispatchset_t **dsetp);
*/
isc_result_t
dns_dispatch_getnext(dns_dispentry_t *resp, dns_dispatchevent_t **sockevent);
dns_dispatch_getnext(dns_dispentry_t *resp);
/*%<
* Free the sockevent and trigger the sending of the next item off the
* dispatch queue if present.
* Trigger the sending of the next item off the dispatch queue if present.
*
* Requires:
*\li resp is valid
*\li *sockevent to be valid
*/
ISC_LANG_ENDDECLS

View file

@ -65,7 +65,6 @@ typedef struct dns_dyndbctx dns_dyndbctx_t;
typedef struct dns_sdlzimplementation dns_sdlzimplementation_t;
typedef struct dns_decompress dns_decompress_t;
typedef struct dns_dispatch dns_dispatch_t;
typedef struct dns_dispatchevent dns_dispatchevent_t;
typedef struct dns_dispatchlist dns_dispatchlist_t;
typedef struct dns_dispatchset dns_dispatchset_t;
typedef struct dns_dispatchmgr dns_dispatchmgr_t;

View file

@ -1780,8 +1780,8 @@ dns_zone_getdnsseckeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
isc_result_t
dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
isc_nm_t *netmgr, dns_zonemgr_t **zmgrp);
isc_timermgr_t *timermgr, isc_nm_t *netmgr,
dns_zonemgr_t **zmgrp);
/*%<
* Create a zone manager. Note: the zone manager will not be able to
* manage any zones until dns_zonemgr_setsize() has been run.

View file

@ -108,7 +108,8 @@ static isc_result_t
req_render(dns_message_t *message, isc_buffer_t **buffer, unsigned int options,
isc_mem_t *mctx);
static void
req_response(isc_task_t *task, isc_event_t *event);
req_response(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region,
void *arg);
static void
req_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *arg);
static void
@ -418,9 +419,8 @@ tcp_dispatch(bool newtcp, dns_requestmgr_t *requestmgr,
}
}
result = dns_dispatch_createtcp(requestmgr->dispatchmgr,
requestmgr->taskmgr, srcaddr, destaddr,
0, dscp, dispatchp);
result = dns_dispatch_createtcp(requestmgr->dispatchmgr, srcaddr,
destaddr, 0, dscp, dispatchp);
return (result);
}
@ -449,8 +449,7 @@ udp_dispatch(dns_requestmgr_t *requestmgr, const isc_sockaddr_t *srcaddr,
return (ISC_R_SUCCESS);
}
return (dns_dispatch_createudp(requestmgr->dispatchmgr,
requestmgr->taskmgr, srcaddr, 0,
return (dns_dispatch_createudp(requestmgr->dispatchmgr, srcaddr, 0,
dispatchp));
}
@ -479,8 +478,9 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
dns_request_t **requestp) {
dns_request_t *request = NULL;
isc_task_t *tclone = NULL;
dns_request_t *rclone = NULL;
isc_result_t result;
isc_mem_t *mctx;
isc_mem_t *mctx = NULL;
dns_messageid_t id;
bool tcp = false;
bool newtcp = false;
@ -511,7 +511,6 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
return (DNS_R_BLACKHOLED);
}
request = NULL;
result = new_request(mctx, &request);
if (result != ISC_R_SUCCESS) {
return (result);
@ -565,17 +564,16 @@ again:
dispopt |= DNS_DISPATCHOPT_FIXEDID;
}
dns_request_t *tmp = NULL;
req_attach(request, &tmp);
req_attach(request, &rclone);
result = dns_dispatch_addresponse(
request->dispatch, dispopt, request->timeout, destaddr, task,
request->dispatch, dispopt, request->timeout, destaddr,
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;
connected = false;
req_detach(&rclone);
dns_dispatch_detach(&request->dispatch);
goto again;
}
@ -602,6 +600,7 @@ again:
request->flags |= DNS_REQUEST_F_CONNECTING | DNS_REQUEST_F_TCP;
} else {
req_send(request);
req_detach(&rclone);
}
req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: request %p", request);
@ -645,8 +644,9 @@ dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
dns_request_t **requestp) {
dns_request_t *request = NULL;
isc_task_t *tclone = NULL;
dns_request_t *rclone = NULL;
isc_result_t result;
isc_mem_t *mctx;
isc_mem_t *mctx = NULL;
dns_messageid_t id;
bool tcp = false;
bool connected = false;
@ -720,13 +720,11 @@ use_tcp:
goto cleanup;
}
dns_request_t *tmp = NULL;
req_attach(request, &tmp);
req_attach(request, &rclone);
result = dns_dispatch_addresponse(
request->dispatch, 0, request->timeout, destaddr, task,
req_connected, req_senddone, req_response, req_timeout, request,
&id, &request->dispentry);
request->dispatch, 0, request->timeout, destaddr, req_connected,
req_senddone, req_response, req_timeout, request, &id,
&request->dispentry);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
@ -737,8 +735,9 @@ use_tcp:
/*
* Try again using TCP.
*/
req_detach(&rclone);
dns_message_renderreset(message);
dns_dispatch_removeresponse(&request->dispentry, NULL);
dns_dispatch_removeresponse(&request->dispentry);
dns_dispatch_detach(&request->dispatch);
options |= DNS_REQUESTOPT_TCP;
tcp = true;
@ -768,6 +767,7 @@ use_tcp:
request->flags |= DNS_REQUEST_F_CONNECTING | DNS_REQUEST_F_TCP;
} else {
req_send(request);
req_detach(&rclone);
}
req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: request %p", request);
@ -783,6 +783,9 @@ cleanup:
if (tclone != NULL) {
isc_task_detach(&tclone);
}
if (rclone != NULL) {
req_detach(&rclone);
}
req_detach(&request);
req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: failed %s",
dns_result_totext(result));
@ -909,7 +912,7 @@ request_cancel(dns_request_t *request) {
if (request->dispentry != NULL) {
dns_dispatch_cancel(request->dispentry);
dns_dispatch_removeresponse(&request->dispentry, NULL);
dns_dispatch_removeresponse(&request->dispentry);
}
dns_dispatch_detach(&request->dispatch);
@ -1024,7 +1027,7 @@ req_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
request->flags &= ~DNS_REQUEST_F_CONNECTING;
if (eresult == ISC_R_TIMEDOUT) {
dns_dispatch_removeresponse(&request->dispentry, NULL);
dns_dispatch_removeresponse(&request->dispentry);
dns_dispatch_detach(&request->dispatch);
send_if_done(request, eresult);
} else if (DNS_REQUEST_CANCELED(request)) {
@ -1089,32 +1092,31 @@ req_timeout(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
}
static void
req_response(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
dns_request_t *request = event->ev_arg;
dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event;
isc_region_t r;
req_response(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region,
void *arg) {
dns_request_t *request = (dns_request_t *)arg;
UNUSED(handle);
if (result == ISC_R_CANCELED) {
return;
}
REQUIRE(VALID_REQUEST(request));
REQUIRE(event->ev_type == DNS_EVENT_DISPATCH);
UNUSED(task);
req_log(ISC_LOG_DEBUG(3), "req_response: request %p: %s", request,
dns_result_totext(devent->result));
dns_result_totext(result));
LOCK(&request->requestmgr->locks[request->hash]);
result = devent->result;
if (result != ISC_R_SUCCESS) {
goto done;
}
/*
* Copy buffer to request.
* Copy region to request.
*/
isc_buffer_usedregion(&devent->buffer, &r);
isc_buffer_allocate(request->mctx, &request->answer, r.length);
result = isc_buffer_copyregion(request->answer, &r);
isc_buffer_allocate(request->mctx, &request->answer, region->length);
result = isc_buffer_copyregion(request->answer, region);
if (result != ISC_R_SUCCESS) {
isc_buffer_free(&request->answer);
}
@ -1122,7 +1124,7 @@ done:
/*
* Cleanup.
*/
dns_dispatch_removeresponse(&request->dispentry, &devent);
dns_dispatch_removeresponse(&request->dispentry);
request_cancel(request);
/*
@ -1206,7 +1208,7 @@ req_destroy(dns_request_t *request) {
isc_event_free((isc_event_t **)&request->event);
}
if (request->dispentry != NULL) {
dns_dispatch_removeresponse(&request->dispentry, NULL);
dns_dispatch_removeresponse(&request->dispentry);
}
if (request->dispatch != NULL) {
dns_dispatch_detach(&request->dispatch);

View file

@ -287,6 +287,7 @@ struct fetchctx {
char *info;
isc_mem_t *mctx;
isc_stdtime_t now;
isc_task_t *task;
/* Atomic */
isc_refcount_t references;
@ -608,7 +609,8 @@ empty_bucket(dns_resolver_t *res);
static isc_result_t
resquery_send(resquery_t *query);
static void
resquery_response(isc_task_t *task, isc_event_t *event);
resquery_response(isc_nmhandle_t *handle, isc_result_t eresult,
isc_region_t *region, void *arg);
static void
resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg);
static void
@ -709,11 +711,10 @@ resume_qmin(isc_task_t *task, isc_event_t *event);
*/
typedef struct respctx {
isc_task_t *task;
dns_dispatchevent_t *devent;
resquery_t *query;
fetchctx_t *fctx;
isc_result_t result;
isc_buffer_t buffer;
unsigned int retryopts; /* updated options to pass to
* fctx_query() when resending */
@ -775,8 +776,8 @@ typedef struct respctx {
} respctx_t;
static void
rctx_respinit(isc_task_t *task, dns_dispatchevent_t *devent, resquery_t *query,
fetchctx_t *fctx, respctx_t *rctx);
rctx_respinit(resquery_t *query, fetchctx_t *fctx, isc_result_t result,
isc_region_t *region, respctx_t *rctx);
static void
rctx_answer_init(respctx_t *rctx);
@ -1138,6 +1139,10 @@ resquery_destroy(resquery_t *query) {
dns_tsigkey_detach(&query->tsigkey);
}
if (query->dispentry != NULL) {
dns_dispatch_removeresponse(&query->dispentry);
}
if (query->dispatch != NULL) {
dns_dispatch_detach(&query->dispatch);
}
@ -1211,8 +1216,8 @@ update_edns_stats(resquery_t *query) {
}
static void
fctx_cancelquery(resquery_t *query, dns_dispatchevent_t **deventp,
isc_time_t *finish, bool no_response, bool age_untried) {
fctx_cancelquery(resquery_t *query, isc_time_t *finish, bool no_response,
bool age_untried) {
fetchctx_t *fctx = NULL;
unsigned int rtt, rttms;
unsigned int factor;
@ -1394,7 +1399,7 @@ fctx_cancelquery(resquery_t *query, dns_dispatchevent_t **deventp,
*/
if (query->dispentry != NULL) {
dns_dispatch_cancel(query->dispentry);
dns_dispatch_removeresponse(&query->dispentry, deventp);
dns_dispatch_removeresponse(&query->dispentry);
}
if (ISC_LINK_LINKED(query, link)) {
@ -1407,14 +1412,14 @@ fctx_cancelquery(resquery_t *query, dns_dispatchevent_t **deventp,
static void
fctx_cancelqueries(fetchctx_t *fctx, bool no_response, bool age_untried) {
resquery_t *query, *next_query;
resquery_t *query = NULL, *next_query = NULL;
FCTXTRACE("cancelqueries");
for (query = ISC_LIST_HEAD(fctx->queries); query != NULL;
query = next_query) {
next_query = ISC_LIST_NEXT(query, link);
fctx_cancelquery(query, NULL, NULL, no_response, age_untried);
fctx_cancelquery(query, NULL, no_response, age_untried);
}
}
@ -1764,8 +1769,7 @@ resquery_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
switch (eresult) {
case ISC_R_SUCCESS:
/* Don't detach from resquery */
return;
goto detach;
case ISC_R_HOSTUNREACH:
case ISC_R_NETUNREACH:
@ -1781,22 +1785,24 @@ resquery_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
*/
add_bad(fctx, query->rmessage, query->addrinfo, eresult,
badns_unreachable);
fctx_cancelquery(query, NULL, NULL, true, false);
fctx_cancelquery(query, NULL, true, false);
FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
fctx_try(fctx, true, false);
break;
case ISC_R_CANCELED:
break;
default:
FCTXTRACE3("query canceled in resquery_senddone() "
"due to unexpected result; responding",
eresult);
fctx_cancelquery(query, NULL, NULL, false, false);
fctx_cancelquery(query, NULL, false, false);
fctx_done(fctx, eresult, __LINE__);
break;
}
detach:
resquery_detach(&query);
resquery_detach(&query); /* Detach dispatch query */
}
static inline isc_result_t
@ -1954,7 +1960,6 @@ 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;
resquery_t *query = NULL;
isc_sockaddr_t addr;
bool have_addr = false;
@ -1964,7 +1969,6 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
FCTXTRACE("query");
res = fctx->res;
task = res->buckets[fctx->bucketnum].task;
srtt = addrinfo->srtt;
@ -2069,8 +2073,8 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
query->dscp = dscp;
}
result = dns_dispatch_createtcp(res->dispatchmgr, res->taskmgr,
&addr, &addrinfo->sockaddr, 0,
result = dns_dispatch_createtcp(res->dispatchmgr, &addr,
&addrinfo->sockaddr, 0,
query->dscp, &query->dispatch);
if (result != ISC_R_SUCCESS) {
goto cleanup_query;
@ -2090,9 +2094,8 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
result = ISC_R_NOTIMPLEMENTED;
goto cleanup_query;
}
result = dns_dispatch_createudp(res->dispatchmgr,
res->taskmgr, &addr, 0,
&query->dispatch);
result = dns_dispatch_createudp(res->dispatchmgr, &addr,
0, &query->dispatch);
if (result != ISC_R_SUCCESS) {
goto cleanup_query;
}
@ -2147,13 +2150,10 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
fctx->nqueries++;
UNLOCK(&res->buckets[fctx->bucketnum].lock);
resquery_t *tmp = NULL;
resquery_attach(query, &tmp);
/* Set up the dispatch and set the query ID */
result = dns_dispatch_addresponse(
query->dispatch, 0, isc_interval_ms(&fctx->interval),
&query->addrinfo->sockaddr, task, resquery_connected,
&query->addrinfo->sockaddr, resquery_connected,
resquery_senddone, resquery_response, resquery_timeout, query,
&query->id, &query->dispentry);
if (result != ISC_R_SUCCESS) {
@ -2161,9 +2161,11 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
}
/* Connect the socket */
fctx_increference(fctx);
resquery_attach(query, &(resquery_t *){ NULL }); /* dispatch query */
result = dns_dispatch_connect(query->dispentry);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
return (result);
cleanup_dispatch:
@ -2720,6 +2722,7 @@ resquery_send(resquery_t *query) {
isc_buffer_usedregion(&buffer, &r);
resquery_attach(query, &(resquery_t *){ NULL });
dns_dispatch_send(query->dispentry, &r, query->dscp);
QTRACE("sent");
@ -2755,7 +2758,7 @@ cleanup_message:
/*
* Stop the dispatcher from listening.
*/
dns_dispatch_removeresponse(&query->dispentry, NULL);
dns_dispatch_removeresponse(&query->dispentry);
cleanup_temps:
if (qname != NULL) {
@ -2771,12 +2774,9 @@ cleanup_temps:
static void
resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
resquery_t *query = (resquery_t *)arg;
resquery_t *connquery = query;
isc_result_t result;
fetchctx_t *fctx = NULL;
dns_resolver_t *res = NULL;
unsigned int bucketnum;
bool bucket_empty;
int pf;
REQUIRE(VALID_QUERY(query));
@ -2788,16 +2788,23 @@ resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
fctx = query->fctx;
res = fctx->res;
bucketnum = fctx->bucketnum;
if (atomic_load_acquire(&res->exiting)) {
eresult = ISC_R_SHUTTINGDOWN;
}
if (RESQUERY_CANCELED(query)) {
goto detach;
}
if (atomic_load_acquire(&fctx->res->exiting)) {
if (eresult == ISC_R_SUCCESS) {
/*
* The reading from the socket has already started at
* this point, so we need to properly cancel the reading
* and then detach the final resquery_t
*/
resquery_attach(query, &(resquery_t *){ NULL });
dns_dispatch_cancel(query->dispentry);
}
eresult = ISC_R_SHUTTINGDOWN;
}
switch (eresult) {
case ISC_R_SUCCESS:
/*
@ -2814,8 +2821,9 @@ resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
"resquery_send() failed; "
"responding");
fctx_cancelquery(query, NULL, NULL, false, false);
fctx_cancelquery(query, NULL, false, false);
fctx_done(fctx, result, __LINE__);
break;
}
fctx->querysent++;
@ -2831,7 +2839,7 @@ resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
dns_rdatatypestats_increment(res->view->resquerystats,
fctx->type);
}
break;
goto detach;
case ISC_R_NETUNREACH:
case ISC_R_HOSTUNREACH:
@ -2852,31 +2860,28 @@ resquery_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
*/
add_bad(fctx, query->rmessage, query->addrinfo, eresult,
badns_unreachable);
fctx_cancelquery(query, NULL, NULL, true, false);
fctx_cancelquery(query, NULL, true, false);
FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
fctx_try(fctx, true, false);
break;
case ISC_R_CANCELED:
break;
default:
FCTXTRACE3("query canceled in "
"resquery_connected() "
"due to unexpected result; responding",
eresult);
fctx_cancelquery(query, NULL, NULL, false, false);
fctx_cancelquery(query, NULL, false, false);
fctx_done(fctx, eresult, __LINE__);
}
LOCK(&res->buckets[bucketnum].lock);
bucket_empty = fctx_decreference(fctx);
UNLOCK(&res->buckets[bucketnum].lock);
if (bucket_empty) {
empty_bucket(res);
break;
}
detach:
resquery_detach(&connquery);
resquery_detach(&query); /* Detach dispatch query */
}
static void
@ -4513,7 +4518,6 @@ fctx_add_event(fetchctx_t *fctx, isc_task_t *task, const isc_sockaddr_t *client,
dns_messageid_t id, isc_taskaction_t action, void *arg,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
dns_fetch_t *fetch, isc_eventtype_t event_type) {
isc_task_t *tclone = NULL;
dns_fetchevent_t *event = NULL;
/*
@ -4521,10 +4525,9 @@ fctx_add_event(fetchctx_t *fctx, isc_task_t *task, const isc_sockaddr_t *client,
* sender field. We'll make the fetch the sender when we
* actually send the event.
*/
isc_task_attach(task, &tclone);
event = (dns_fetchevent_t *)isc_event_allocate(fctx->res->mctx, tclone,
event_type, action, arg,
sizeof(*event));
isc_task_attach(task, &(isc_task_t *){ NULL });
event = (dns_fetchevent_t *)isc_event_allocate(
fctx->res->mctx, task, event_type, action, arg, sizeof(*event));
event->result = DNS_R_SERVFAIL;
event->qtype = fctx->type;
event->db = NULL;
@ -4579,11 +4582,11 @@ log_ns_ttl(fetchctx_t *fctx, const char *where) {
}
static isc_result_t
fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
const dns_name_t *domain, dns_rdataset_t *nameservers,
const isc_sockaddr_t *client, unsigned int options,
unsigned int bucketnum, unsigned int depth, isc_counter_t *qc,
fetchctx_t **fctxp) {
fctx_create(dns_resolver_t *res, isc_task_t *task, const dns_name_t *name,
dns_rdatatype_t type, const dns_name_t *domain,
dns_rdataset_t *nameservers, const isc_sockaddr_t *client,
unsigned int options, unsigned int bucketnum, unsigned int depth,
isc_counter_t *qc, fetchctx_t **fctxp) {
fetchctx_t *fctx = NULL;
isc_result_t result;
isc_result_t iresult;
@ -4606,6 +4609,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
.qmintype = type,
.options = options,
.res = res,
.task = task,
.bucketnum = bucketnum,
.dbucketnum = RES_NOBUCKET,
.state = fetchstate_init,
@ -7202,17 +7206,22 @@ betterreferral(respctx_t *rctx) {
* resquery_send(). Sets up a response context (respctx_t).
*/
static void
resquery_response(isc_task_t *task, isc_event_t *event) {
isc_result_t result = ISC_R_SUCCESS;
resquery_t *query = event->ev_arg;
dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event;
fetchctx_t *fctx;
resquery_response(isc_nmhandle_t *handle, isc_result_t eresult,
isc_region_t *region, void *arg) {
isc_result_t result;
resquery_t *query = (resquery_t *)arg;
fetchctx_t *fctx = NULL;
respctx_t rctx;
UNUSED(handle);
if (eresult == ISC_R_CANCELED) {
return;
}
REQUIRE(VALID_QUERY(query));
fctx = query->fctx;
REQUIRE(VALID_FCTX(fctx));
REQUIRE(event->ev_type == DNS_EVENT_DISPATCH);
QTRACE("response");
@ -7222,7 +7231,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
inc_stats(fctx->res, dns_resstatscounter_responsev6);
}
rctx_respinit(task, devent, query, fctx, &rctx);
rctx_respinit(query, fctx, eresult, region, &rctx);
if (atomic_load_acquire(&fctx->res->exiting)) {
result = ISC_R_SHUTTINGDOWN;
@ -7273,9 +7282,8 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
if ((rctx.retryopts & DNS_FETCHOPT_TCP) == 0) {
if ((rctx.retryopts & DNS_FETCHOPT_NOEDNS0) == 0) {
dns_adb_setudpsize(
fctx->adb, query->addrinfo,
isc_buffer_usedlength(&devent->buffer));
dns_adb_setudpsize(fctx->adb, query->addrinfo,
isc_buffer_usedlength(&rctx.buffer));
} else {
dns_adb_plainresponse(fctx->adb, query->addrinfo);
}
@ -7601,16 +7609,15 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
* resquery_response().
*/
static void
rctx_respinit(isc_task_t *task, dns_dispatchevent_t *devent, resquery_t *query,
fetchctx_t *fctx, respctx_t *rctx) {
*rctx = (respctx_t){ .task = task,
.devent = devent,
.result = devent->result,
rctx_respinit(resquery_t *query, fetchctx_t *fctx, isc_result_t result,
isc_region_t *region, respctx_t *rctx) {
*rctx = (respctx_t){ .result = result,
.query = query,
.fctx = fctx,
.broken_type = badns_response,
.retryopts = query->options };
isc_buffer_init(&rctx->buffer, region->base, region->length);
isc_buffer_add(&rctx->buffer, region->length);
TIME_NOW(&rctx->tnow);
rctx->finish = &rctx->tnow;
rctx->now = (isc_stdtime_t)isc_time_seconds(&rctx->tnow);
@ -7675,17 +7682,15 @@ rctx_answer_init(respctx_t *rctx) {
*/
static isc_result_t
rctx_dispfail(respctx_t *rctx) {
dns_dispatchevent_t *devent = rctx->devent;
fetchctx_t *fctx = rctx->fctx;
resquery_t *query = rctx->query;
if (devent->result == ISC_R_SUCCESS) {
if (rctx->result == ISC_R_SUCCESS) {
return (ISC_R_SUCCESS);
}
if (devent->result == ISC_R_EOF &&
(rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0)
{
if (rctx->result == ISC_R_EOF &&
(rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0) {
/*
* The problem might be that they don't understand
* EDNS0. Turn it off and try again.
@ -7704,18 +7709,18 @@ rctx_dispfail(respctx_t *rctx) {
* adjust finish and no_response so that we penalize
* this address in SRTT adjustment later.
*/
if (devent->result == ISC_R_HOSTUNREACH ||
devent->result == ISC_R_NETUNREACH ||
devent->result == ISC_R_CONNREFUSED ||
devent->result == ISC_R_CANCELED)
if (rctx->result == ISC_R_HOSTUNREACH ||
rctx->result == ISC_R_NETUNREACH ||
rctx->result == ISC_R_CONNREFUSED ||
rctx->result == ISC_R_CANCELED)
{
rctx->broken_server = devent->result;
rctx->broken_server = rctx->result;
rctx->broken_type = badns_unreachable;
rctx->finish = NULL;
rctx->no_response = true;
}
}
FCTXTRACE3("dispatcher failure", devent->result);
FCTXTRACE3("dispatcher failure", rctx->result);
rctx_done(rctx, ISC_R_SUCCESS);
return (ISC_R_COMPLETE);
}
@ -7768,7 +7773,7 @@ rctx_parse(respctx_t *rctx) {
fetchctx_t *fctx = rctx->fctx;
resquery_t *query = rctx->query;
result = dns_message_parse(query->rmessage, &rctx->devent->buffer, 0);
result = dns_message_parse(query->rmessage, &rctx->buffer, 0);
if (result == ISC_R_SUCCESS) {
return (ISC_R_SUCCESS);
}
@ -9336,17 +9341,15 @@ rctx_resend(respctx_t *rctx, dns_adbaddrinfo_t *addrinfo) {
inc_stats(fctx->res, dns_resstatscounter_retry);
fctx_increference(fctx);
result = fctx_query(fctx, addrinfo, rctx->retryopts);
if (result == ISC_R_SUCCESS) {
return;
}
bucketnum = fctx->bucketnum;
fctx_done(fctx, result, __LINE__);
LOCK(&res->buckets[bucketnum].lock);
bucket_empty = fctx_decreference(fctx);
UNLOCK(&res->buckets[bucketnum].lock);
if (bucket_empty) {
empty_bucket(res);
if (result != ISC_R_SUCCESS) {
bucketnum = fctx->bucketnum;
fctx_done(fctx, result, __LINE__);
LOCK(&res->buckets[bucketnum].lock);
bucket_empty = fctx_decreference(fctx);
UNLOCK(&res->buckets[bucketnum].lock);
if (bucket_empty) {
empty_bucket(res);
}
}
}
@ -9368,7 +9371,7 @@ rctx_next(respctx_t *rctx) {
inc_stats(rctx->fctx->res, dns_resstatscounter_nextitem);
INSIST(rctx->query->dispentry != NULL);
dns_message_reset(rctx->query->rmessage, DNS_MESSAGE_INTENTPARSE);
result = dns_dispatch_getnext(rctx->query->dispentry, &rctx->devent);
result = dns_dispatch_getnext(rctx->query->dispentry);
if (result != ISC_R_SUCCESS) {
fctx_done(rctx->fctx, result, __LINE__);
}
@ -9399,7 +9402,7 @@ rctx_chaseds(respctx_t *rctx, dns_message_t *message,
result = dns_resolver_createfetch(
fctx->res, fctx->nsname, dns_rdatatype_ns, NULL, NULL, NULL,
NULL, 0, fctx->options, 0, NULL, rctx->task, resume_dslookup,
NULL, 0, fctx->options, 0, NULL, fctx->task, resume_dslookup,
fctx, &fctx->nsrrset, NULL, &fctx->nsfetch);
if (result != ISC_R_SUCCESS) {
if (result == DNS_R_DUPLICATE) {
@ -9437,41 +9440,39 @@ rctx_done(respctx_t *rctx, isc_result_t result) {
FCTXTRACE4("query canceled in rctx_done();",
rctx->no_response ? "no response" : "responding", result);
/*
* Cancel the query.
*/
if (!rctx->nextitem) {
fctx_cancelquery(query, &rctx->devent, rctx->finish,
rctx->no_response, false);
}
#ifdef ENABLE_AFL
if (dns_fuzzing_resolver &&
(rctx->next_server || rctx->resend || rctx->nextitem))
{
if (rctx->nextitem) {
fctx_cancelquery(query, &rctx->devent, rctx->finish,
rctx->no_response, false);
}
fctx_cancelquery(query, rctx->finish, rctx->no_response, false);
fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
return;
} else
goto detach;
}
#endif /* ifdef ENABLE_AFL */
if (rctx->next_server)
{
if (rctx->nextitem) {
REQUIRE(!rctx->next_server);
REQUIRE(!rctx->resend);
result = rctx_next(rctx);
if (result == ISC_R_SUCCESS) {
goto detach;
}
}
/* Cancel the query */
fctx_cancelquery(query, rctx->finish, rctx->no_response, false);
if (rctx->next_server) {
rctx_nextserver(rctx, message, addrinfo, result);
} else if (rctx->resend) {
rctx_resend(rctx, addrinfo);
} else if (rctx->nextitem) {
if (rctx_next(rctx) != ISC_R_SUCCESS) {
resquery_detach(&query);
}
} else if (result == DNS_R_CHASEDSSERVERS) {
rctx_chaseds(rctx, message, addrinfo, result);
} else if (result == ISC_R_SUCCESS && !HAVE_ANSWER(fctx)) {
/*
* All has gone well so far, but we are waiting for the
* DNSSEC validator to validate the answer.
* All has gone well so far, but we are waiting for the DNSSEC
* validator to validate the answer.
*/
FCTXTRACE("wait for validator");
fctx_cancelqueries(fctx, true, false);
@ -9482,6 +9483,7 @@ rctx_done(respctx_t *rctx, isc_result_t result) {
fctx_done(fctx, result, __LINE__);
}
detach:
dns_message_detach(&message);
}
@ -9539,7 +9541,7 @@ rctx_logpacket(respctx_t *rctx) {
dns_dt_send(fctx->res->view, dtmsgtype, la,
&rctx->query->addrinfo->sockaddr,
((rctx->query->options & DNS_FETCHOPT_TCP) != 0), &zr,
&rctx->query->start, NULL, &rctx->devent->buffer);
&rctx->query->start, NULL, &rctx->buffer);
#endif /* HAVE_DNSTAP */
}
@ -9960,12 +9962,12 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
}
if (dispatchv4 != NULL) {
dns_dispatchset_create(view->mctx, taskmgr, dispatchv4,
dns_dispatchset_create(view->mctx, dispatchv4,
&res->dispatches4, ndisp);
}
if (dispatchv6 != NULL) {
dns_dispatchset_create(view->mctx, taskmgr, dispatchv6,
dns_dispatchset_create(view->mctx, dispatchv6,
&res->dispatches6, ndisp);
}
@ -10156,8 +10158,7 @@ dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp) {
void
dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task,
isc_event_t **eventp) {
isc_task_t *tclone;
isc_event_t *event;
isc_event_t *event = NULL;
REQUIRE(VALID_RESOLVER(res));
REQUIRE(eventp != NULL);
@ -10176,9 +10177,8 @@ dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task,
event->ev_sender = res;
isc_task_send(task, &event);
} else {
tclone = NULL;
isc_task_attach(task, &tclone);
event->ev_sender = tclone;
isc_task_attach(task, &(isc_task_t *){ NULL });
event->ev_sender = task;
ISC_LIST_APPEND(res->whenshutdown, event, ev_link);
}
@ -10473,7 +10473,7 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
}
if (fctx == NULL) {
result = fctx_create(res, name, type, domain, nameservers,
result = fctx_create(res, task, name, type, domain, nameservers,
client, options, bucketnum, depth, qc,
&fctx);
if (result != ISC_R_SUCCESS) {

View file

@ -590,7 +590,6 @@ struct dns_zonemgr {
isc_refcount_t refs;
isc_taskmgr_t *taskmgr;
isc_timermgr_t *timermgr;
isc_socketmgr_t *socketmgr;
isc_nm_t *netmgr;
isc_taskpool_t *zonetasks;
isc_taskpool_t *loadtasks;
@ -18735,8 +18734,8 @@ zonemgr_keymgmt_find(dns_zonemgr_t *zmgr, dns_zone_t *zone,
isc_result_t
dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
isc_nm_t *netmgr, dns_zonemgr_t **zmgrp) {
isc_timermgr_t *timermgr, isc_nm_t *netmgr,
dns_zonemgr_t **zmgrp) {
dns_zonemgr_t *zmgr;
isc_result_t result;
@ -18746,7 +18745,6 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
isc_mem_attach(mctx, &zmgr->mctx);
zmgr->taskmgr = taskmgr;
zmgr->timermgr = timermgr;
zmgr->socketmgr = socketmgr;
zmgr->netmgr = netmgr;
zmgr->zonetasks = NULL;
zmgr->loadtasks = NULL;

View file

@ -98,7 +98,6 @@ typedef struct isc_nm_http_endpoints isc_nm_http_endpoints_t;
#endif /* HAVE_LIBNGHTTP2 */
typedef void (*isc_taskaction_t)(isc_task_t *, isc_event_t *);
typedef int (*isc_sockfdwatch_t)(isc_task_t *, isc_socket_t *, void *, int);
/* The following cannot be listed alphabetically due to forward reference */
typedef isc_result_t(isc_httpdaction_t)(

View file

@ -2413,6 +2413,7 @@ ns_clientmgr_create(ns_server_t *sctx, isc_taskmgr_t *taskmgr,
result = isc_task_create_bound(manager->taskmgr, 20, &manager->task,
manager->tid);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
isc_task_setname(manager->task, "clientmgr", NULL);
isc_refcount_init(&manager->references, 1);
manager->sctx = NULL;

View file

@ -45,7 +45,6 @@
#include <isc/mem.h>
#include <isc/netmgr.h>
#include <isc/refcount.h>
#include <isc/socket.h>
#include <dns/geoip.h>
#include <dns/result.h>
@ -74,7 +73,6 @@ struct ns_interface {
isc_sockaddr_t addr; /*%< Address and port. */
unsigned int flags; /*%< Interface flags */
char name[32]; /*%< Null terminated. */
isc_socket_t * tcpsocket; /*%< TCP socket. */
isc_nmsocket_t * udplistensocket;
isc_nmsocket_t * tcplistensocket;
isc_nmsocket_t * http_listensocket;

View file

@ -698,10 +698,6 @@ ns_interface_destroy(ns_interface_t *ifp) {
ns_interface_shutdown(ifp);
if (ifp->tcpsocket != NULL) {
isc_socket_detach(&ifp->tcpsocket);
}
isc_mutex_destroy(&ifp->lock);
ns_interfacemgr_detach(&ifp->mgr);