#include <isc/netmgr.h>
#include <isc/result.h>
#include <isc/task.h>
+#include <isc/thread.h>
#include <isc/util.h>
#include <dns/acl.h>
isc_buffer_usedregion(request->query, &r);
request->flags |= DNS_REQUEST_F_SENDING;
+
+ /* detached in req_senddone() */
+ req_attach(request, &(dns_request_t *){ NULL });
dns_dispatch_send(request->dispentry, &r, request->dscp);
}
isc_task_t *task, isc_taskaction_t action, void *arg,
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 = NULL;
dns_messageid_t id;
return (DNS_R_BLACKHOLED);
}
+ /* detached in dns_request_destroy() */
result = new_request(mctx, &request);
if (result != ISC_R_SUCCESS) {
return (result);
request->event = (dns_requestevent_t *)isc_event_allocate(
mctx, task, DNS_EVENT_REQUESTDONE, action, arg,
sizeof(dns_requestevent_t));
- isc_task_attach(task, &tclone);
+ isc_task_attach(task, &(isc_task_t *){ NULL });
request->event->ev_sender = task;
request->event->request = request;
request->event->result = ISC_R_FAILURE;
goto cleanup;
}
+ /* detached in req_connected() */
+ req_attach(request, &(dns_request_t *){ NULL });
+
again:
+
result = get_dispatch(tcp, newtcp, requestmgr, srcaddr, destaddr, dscp,
&connected, &request->dispatch);
if (result != ISC_R_SUCCESS) {
dispopt |= DNS_DISPATCHOPT_FIXEDID;
}
- req_attach(request, &rclone);
result = dns_dispatch_add(request->dispatch, dispopt, request->timeout,
destaddr, req_connected, req_senddone,
req_response, request, &id,
if ((options & DNS_REQUESTOPT_FIXEDID) != 0 && !newtcp) {
newtcp = true;
connected = false;
- req_detach(&rclone);
dns_dispatch_detach(&request->dispatch);
goto again;
}
- goto cleanup;
+
+ goto detach;
}
/* Add message ID. */
request->destaddr = *destaddr;
if (tcp && connected) {
req_send(request);
- req_detach(&rclone);
+
+ /* no need to call req_connected(), detach here */
+ req_detach(&(dns_request_t *){ request });
} else {
request->flags |= DNS_REQUEST_F_CONNECTING;
if (tcp) {
ISC_LIST_UNLINK(requestmgr->requests, request, link);
UNLOCK(&requestmgr->lock);
+detach:
+ /* connect failed, detach here */
+ req_detach(&(dns_request_t *){ request });
+
cleanup:
- if (tclone != NULL) {
- isc_task_detach(&tclone);
- }
- if (rclone != NULL) {
- req_detach(&rclone);
- }
+ isc_task_detach(&(isc_task_t *){ task });
+ /* final detach to shut down request */
req_detach(&request);
req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: failed %s",
isc_result_totext(result));
isc_taskaction_t action, void *arg,
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 = NULL;
dns_messageid_t id;
return (DNS_R_BLACKHOLED);
}
+ /* detached in dns_request_destroy() */
result = new_request(mctx, &request);
if (result != ISC_R_SUCCESS) {
return (result);
request->event = (dns_requestevent_t *)isc_event_allocate(
mctx, task, DNS_EVENT_REQUESTDONE, action, arg,
sizeof(dns_requestevent_t));
- isc_task_attach(task, &tclone);
+ isc_task_attach(task, &(isc_task_t *){ NULL });
request->event->ev_sender = task;
request->event->request = request;
request->event->result = ISC_R_FAILURE;
+
if (key != NULL) {
dns_tsigkey_attach(key, &request->tsigkey);
}
request->timeout = udptimeout * 1000;
}
-use_tcp:
+ /* detached in req_connected() */
+ req_attach(request, &(dns_request_t *){ NULL });
+
+again:
result = get_dispatch(tcp, false, requestmgr, srcaddr, destaddr, dscp,
&connected, &request->dispatch);
if (result != ISC_R_SUCCESS) {
- goto cleanup;
+ goto detach;
}
- req_attach(request, &rclone);
result = dns_dispatch_add(
request->dispatch, 0, request->timeout, destaddr, req_connected,
req_senddone, req_response, request, &id, &request->dispentry);
if (result != ISC_R_SUCCESS) {
- goto cleanup;
+ goto detach;
}
message->id = id;
/*
* Try again using TCP.
*/
- req_detach(&rclone);
dns_message_renderreset(message);
dns_dispatch_done(&request->dispentry);
dns_dispatch_detach(&request->dispatch);
options |= DNS_REQUESTOPT_TCP;
tcp = true;
- goto use_tcp;
+ goto again;
}
if (result != ISC_R_SUCCESS) {
- goto cleanup;
+ goto detach;
}
result = dns_message_getquerytsig(message, mctx, &request->tsig);
if (result != ISC_R_SUCCESS) {
- goto cleanup;
+ goto detach;
}
LOCK(&requestmgr->lock);
request->destaddr = *destaddr;
if (tcp && connected) {
req_send(request);
- req_detach(&rclone);
+
+ /* no need to call req_connected(), detach here */
+ req_detach(&(dns_request_t *){ request });
} else {
request->flags |= DNS_REQUEST_F_CONNECTING;
if (tcp) {
ISC_LIST_UNLINK(requestmgr->requests, request, link);
UNLOCK(&requestmgr->lock);
+detach:
+ /* connect failed, detach here */
+ req_detach(&(dns_request_t *){ request });
+
cleanup:
- if (tclone != NULL) {
- isc_task_detach(&tclone);
- }
- if (rclone != NULL) {
- req_detach(&rclone);
- }
+ isc_task_detach(&(isc_task_t *){ task });
+ /* final detach to shut down request */
req_detach(&request);
req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: failed %s",
isc_result_totext(result));
INSIST(request->dispentry == NULL);
INSIST(request->dispatch == NULL);
+ /* final detach to shut down request */
req_detach(&request);
}
}
UNLOCK(&request->requestmgr->locks[request->hash]);
- req_detach(&request);
+ /* attached in dns_request_createvia/_createraw() */
+ req_detach(&(dns_request_t *){ request });
}
static void
}
UNLOCK(&request->requestmgr->locks[request->hash]);
+
+ /* attached in req_send() */
+ req_detach(&request);
}
static void
task = request->event->ev_sender;
request->event->ev_sender = request;
request->event->result = result;
+
isc_task_sendanddetach(&task, (isc_event_t **)&request->event);
}