mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Refactor dispatch, resolver and request
Since every dispsock was associated with a dispentry anyway (though not always vice versa), the members of dispsock have been combined into dispentry, which is now reference-counted. dispentry objects are now attached before connecting and detached afterward to prevent races between the connect callback and dns_dispatch_removeresponse(). Dispatch and dispatchmgr objects are now reference counted as well, and the shutdown process has been simplified. reference counting of resquery and request objects has also been cleaned up significantly. dns_dispatch_cancel() now flags a dispentry as having been canceled, so that if the connect callback runs after cancellation, it will not initiate a read. The isblackholed() function has been simplified.
This commit is contained in:
parent
08ce69a0ea
commit
7dc54fa6f2
16 changed files with 1360 additions and 1406 deletions
|
|
@ -10003,7 +10003,7 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
ns_interfacemgr_detach(&server->interfacemgr);
|
||||
|
||||
dns_dispatchmgr_destroy(&named_g_dispatchmgr);
|
||||
dns_dispatchmgr_detach(&named_g_dispatchmgr);
|
||||
|
||||
dns_zonemgr_shutdown(server->zonemgr);
|
||||
|
||||
|
|
|
|||
|
|
@ -735,7 +735,7 @@ doshutdown(void) {
|
|||
}
|
||||
|
||||
ddebug("Shutting down dispatch manager");
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
dns_dispatchmgr_detach(&dispatchmgr);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ main(int argc, char *argv[]) {
|
|||
dns_requestmgr_detach(&requestmgr);
|
||||
|
||||
dns_dispatch_detach(&dispatchv4);
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
dns_dispatchmgr_detach(&dispatchmgr);
|
||||
|
||||
isc_task_shutdown(task);
|
||||
isc_task_detach(&task);
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ main(int argc, char *argv[]) {
|
|||
dns_requestmgr_shutdown(requestmgr);
|
||||
dns_requestmgr_detach(&requestmgr);
|
||||
dns_dispatch_detach(&dispatchv4);
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
dns_dispatchmgr_detach(&dispatchmgr);
|
||||
isc_task_shutdown(task);
|
||||
isc_task_detach(&task);
|
||||
isc_managers_destroy(&netmgr, &taskmgr, NULL, NULL);
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ main(int argc, char **argv) {
|
|||
dns_requestmgr_shutdown(requestmgr);
|
||||
dns_requestmgr_detach(&requestmgr);
|
||||
dns_dispatch_detach(&dispatchv4);
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
dns_dispatchmgr_detach(&dispatchmgr);
|
||||
isc_task_shutdown(task);
|
||||
isc_task_detach(&task);
|
||||
isc_managers_destroy(&netmgr, &taskmgr, NULL, NULL);
|
||||
|
|
|
|||
|
|
@ -2175,7 +2175,7 @@ main(int argc, char *argv[]) {
|
|||
dns_requestmgr_detach(&requestmgr);
|
||||
|
||||
dns_dispatch_detach(&dispatchvx);
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
dns_dispatchmgr_detach(&dispatchmgr);
|
||||
|
||||
isc_task_shutdown(task);
|
||||
isc_task_detach(&task);
|
||||
|
|
|
|||
|
|
@ -268,7 +268,6 @@ dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
|
|||
const isc_sockaddr_t *localaddr6) {
|
||||
isc_result_t result;
|
||||
dns_client_t *client = NULL;
|
||||
dns_dispatchmgr_t *dispatchmgr = NULL;
|
||||
dns_dispatch_t *dispatchv4 = NULL;
|
||||
dns_dispatch_t *dispatchv6 = NULL;
|
||||
dns_view_t *view = NULL;
|
||||
|
|
@ -293,12 +292,11 @@ dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
|
|||
goto cleanup_lock;
|
||||
}
|
||||
|
||||
result = dns_dispatchmgr_create(mctx, nm, &dispatchmgr);
|
||||
result = dns_dispatchmgr_create(mctx, nm, &client->dispatchmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_task;
|
||||
}
|
||||
client->dispatchmgr = dispatchmgr;
|
||||
(void)setsourceports(mctx, dispatchmgr);
|
||||
(void)setsourceports(mctx, client->dispatchmgr);
|
||||
|
||||
/*
|
||||
* If only one address family is specified, use it.
|
||||
|
|
@ -306,7 +304,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, dispatchmgr, taskmgr,
|
||||
result = getudpdispatch(AF_INET, client->dispatchmgr, taskmgr,
|
||||
&dispatchv4, localaddr4);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
client->dispatchv4 = dispatchv4;
|
||||
|
|
@ -315,7 +313,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, dispatchmgr, taskmgr,
|
||||
result = getudpdispatch(AF_INET6, client->dispatchmgr, taskmgr,
|
||||
&dispatchv6, localaddr6);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
client->dispatchv6 = dispatchv6;
|
||||
|
|
@ -332,8 +330,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,
|
||||
nm, timermgr, dispatchmgr, dispatchv4, dispatchv6,
|
||||
&view);
|
||||
nm, timermgr, client->dispatchmgr, dispatchv4,
|
||||
dispatchv6, &view);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_references;
|
||||
}
|
||||
|
|
@ -366,7 +364,7 @@ cleanup_dispatchmgr:
|
|||
if (dispatchv6 != NULL) {
|
||||
dns_dispatch_detach(&dispatchv6);
|
||||
}
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
dns_dispatchmgr_detach(&client->dispatchmgr);
|
||||
cleanup_task:
|
||||
isc_task_detach(&client->task);
|
||||
cleanup_lock:
|
||||
|
|
@ -394,7 +392,7 @@ destroyclient(dns_client_t *client) {
|
|||
dns_dispatch_detach(&client->dispatchv6);
|
||||
}
|
||||
|
||||
dns_dispatchmgr_destroy(&client->dispatchmgr);
|
||||
dns_dispatchmgr_detach(&client->dispatchmgr);
|
||||
|
||||
isc_task_detach(&client->task);
|
||||
|
||||
|
|
|
|||
1335
lib/dns/dispatch.c
1335
lib/dns/dispatch.c
File diff suppressed because it is too large
Load diff
|
|
@ -79,9 +79,10 @@ ISC_LANG_BEGINDECLS
|
|||
|
||||
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 */
|
||||
isc_result_t result; /*%< result code */
|
||||
isc_region_t region; /*%< data region */
|
||||
isc_buffer_t buffer; /*%< data buffer */
|
||||
dns_dispatch_t *dispatch;
|
||||
};
|
||||
|
||||
/*%
|
||||
|
|
@ -146,8 +147,19 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_nm_t *nm, dns_dispatchmgr_t **mgrp);
|
|||
*\li anything else -- failure
|
||||
*/
|
||||
|
||||
#define dns_dispatchmgr_attach(mgr, mgrp) \
|
||||
dns__dispatchmgr_attach(mgr, mgrp, __func__, __FILE__, __LINE__)
|
||||
|
||||
void
|
||||
dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp);
|
||||
dns__dispatchmgr_attach(dns_dispatchmgr_t *mgr, dns_dispatchmgr_t **mgrp,
|
||||
const char *func, const char *file, unsigned int line);
|
||||
|
||||
#define dns_dispatchmgr_detach(mgrp) \
|
||||
dns__dispatchmgr_detach(mgrp, __func__, __FILE__, __LINE__)
|
||||
|
||||
void
|
||||
dns__dispatchmgr_detach(dns_dispatchmgr_t **mgrp, const char *func,
|
||||
const char *file, unsigned int line);
|
||||
/*%<
|
||||
* Destroys the dispatchmgr when it becomes empty. This could be
|
||||
* immediately.
|
||||
|
|
@ -246,8 +258,12 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_taskmgr_t *taskmgr,
|
|||
*\li Anything else -- failure.
|
||||
*/
|
||||
|
||||
#define dns_dispatch_attach(d, dp) \
|
||||
dns__dispatch_attach(d, dp, __func__, __FILE__, __LINE__)
|
||||
|
||||
void
|
||||
dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp);
|
||||
dns__dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp,
|
||||
const char *func, const char *file, unsigned int line);
|
||||
/*%<
|
||||
* Attach to a dispatch handle.
|
||||
*
|
||||
|
|
@ -257,8 +273,12 @@ dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp);
|
|||
*\li dispp != NULL && *dispp == NULL
|
||||
*/
|
||||
|
||||
#define dns_dispatch_detach(dp) \
|
||||
dns__dispatch_detach(dp, __func__, __FILE__, __LINE__)
|
||||
|
||||
void
|
||||
dns_dispatch_detach(dns_dispatch_t **dispp);
|
||||
dns__dispatch_detach(dns_dispatch_t **dispp, const char *func, const char *file,
|
||||
unsigned int line);
|
||||
/*%<
|
||||
* Detaches from the dispatch.
|
||||
*
|
||||
|
|
@ -277,15 +297,13 @@ dns_dispatch_connect(dns_dispentry_t *resp);
|
|||
*/
|
||||
|
||||
void
|
||||
dns_dispatch_cancel(dns_dispatch_t *disp, dns_dispentry_t *resp, bool sending,
|
||||
bool connecting);
|
||||
dns_dispatch_cancel(dns_dispentry_t *resp);
|
||||
/*%<
|
||||
* Cancel pending sends (if 'sending' is true) and connects (if
|
||||
* 'connecting' is true) in 'resp' or 'disp'.
|
||||
* Cancel pending connects in 'resp', by setting a flag so that
|
||||
* a read is not started when the connect handler runs.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'resp' is NULL and 'disp' is valid, or
|
||||
*\li 'disp' is NULL and 'resp' is valid.
|
||||
*\li 'resp' is valid.
|
||||
*/
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -124,8 +124,12 @@ dns_requestmgr_shutdown(dns_requestmgr_t *requestmgr);
|
|||
*\li 'requestmgr' is a valid requestmgr.
|
||||
*/
|
||||
|
||||
#define dns_requestmgr_attach(source, targetp) \
|
||||
dns__requestmgr_attach(source, targetp, __FILE__, __LINE__, __func__)
|
||||
|
||||
void
|
||||
dns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp);
|
||||
dns__requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp,
|
||||
const char *file, unsigned int line, const char *func);
|
||||
/*%<
|
||||
* Attach to the request manager. dns_requestmgr_shutdown() must not
|
||||
* have been called on 'source' prior to calling dns_requestmgr_attach().
|
||||
|
|
@ -137,8 +141,12 @@ dns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp);
|
|||
*\li 'targetp' to be non NULL and '*targetp' to be NULL.
|
||||
*/
|
||||
|
||||
#define dns_requestmgr_detach(requestmgrp) \
|
||||
dns__requestmgr_detach(requestmgrp, __FILE__, __LINE__, __func__)
|
||||
|
||||
void
|
||||
dns_requestmgr_detach(dns_requestmgr_t **requestmgrp);
|
||||
dns__requestmgr_detach(dns_requestmgr_t **requestmgrp, const char *file,
|
||||
unsigned int line, const char *func);
|
||||
/*%<
|
||||
* Detach from the given requestmgr. If this is the final detach
|
||||
* requestmgr will be destroyed. dns_requestmgr_shutdown() must
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
#include <dns/result.h>
|
||||
#include <dns/tsig.h>
|
||||
|
||||
#define REQ_TRACE
|
||||
|
||||
#define REQUESTMGR_MAGIC ISC_MAGIC('R', 'q', 'u', 'M')
|
||||
#define VALID_REQUESTMGR(mgr) ISC_MAGIC_VALID(mgr, REQUESTMGR_MAGIC)
|
||||
|
||||
|
|
@ -44,17 +46,17 @@ typedef ISC_LIST(dns_request_t) dns_requestlist_t;
|
|||
|
||||
struct dns_requestmgr {
|
||||
unsigned int magic;
|
||||
isc_refcount_t references;
|
||||
|
||||
isc_mutex_t lock;
|
||||
isc_mem_t *mctx;
|
||||
|
||||
/* locked */
|
||||
int32_t eref;
|
||||
int32_t iref;
|
||||
isc_taskmgr_t *taskmgr;
|
||||
dns_dispatchmgr_t *dispatchmgr;
|
||||
dns_dispatch_t *dispatchv4;
|
||||
dns_dispatch_t *dispatchv6;
|
||||
bool exiting;
|
||||
atomic_bool exiting;
|
||||
isc_eventlist_t whenshutdown;
|
||||
unsigned int hash;
|
||||
isc_mutex_t locks[DNS_REQUEST_NLOCKS];
|
||||
|
|
@ -63,6 +65,8 @@ struct dns_requestmgr {
|
|||
|
||||
struct dns_request {
|
||||
unsigned int magic;
|
||||
isc_refcount_t references;
|
||||
|
||||
unsigned int hash;
|
||||
isc_mem_t *mctx;
|
||||
int32_t flags;
|
||||
|
|
@ -97,8 +101,6 @@ struct dns_request {
|
|||
|
||||
static void
|
||||
mgr_destroy(dns_requestmgr_t *requestmgr);
|
||||
static void
|
||||
mgr_shutdown(dns_requestmgr_t *requestmgr);
|
||||
static unsigned int
|
||||
mgr_gethash(dns_requestmgr_t *requestmgr);
|
||||
static void
|
||||
|
|
@ -118,12 +120,23 @@ req_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg);
|
|||
static void
|
||||
req_timeout(isc_nmhandle_t *handle, isc_result_t eresult, void *arg);
|
||||
static void
|
||||
__req_attach(dns_request_t *source, dns_request_t **targetp, const char *file,
|
||||
unsigned int line, const char *func);
|
||||
static void
|
||||
__req_detach(dns_request_t **requestp, const char *file, unsigned int line,
|
||||
const char *func);
|
||||
static void
|
||||
req_destroy(dns_request_t *request);
|
||||
static void
|
||||
req_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
|
||||
void
|
||||
request_cancel(dns_request_t *request);
|
||||
|
||||
#define req_attach(source, targetp) \
|
||||
__req_attach(source, targetp, __FILE__, __LINE__, __func__)
|
||||
#define req_detach(requestp) \
|
||||
__req_detach(requestp, __FILE__, __LINE__, __func__)
|
||||
|
||||
/***
|
||||
*** Public
|
||||
***/
|
||||
|
|
@ -171,11 +184,10 @@ dns_requestmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
|||
}
|
||||
requestmgr->mctx = NULL;
|
||||
isc_mem_attach(mctx, &requestmgr->mctx);
|
||||
requestmgr->eref = 1; /* implicit attach */
|
||||
requestmgr->iref = 0;
|
||||
isc_refcount_init(&requestmgr->references, 1);
|
||||
ISC_LIST_INIT(requestmgr->whenshutdown);
|
||||
ISC_LIST_INIT(requestmgr->requests);
|
||||
requestmgr->exiting = false;
|
||||
atomic_init(&requestmgr->exiting, false);
|
||||
requestmgr->hash = 0;
|
||||
requestmgr->magic = REQUESTMGR_MAGIC;
|
||||
|
||||
|
|
@ -201,7 +213,7 @@ dns_requestmgr_whenshutdown(dns_requestmgr_t *requestmgr, isc_task_t *task,
|
|||
|
||||
LOCK(&requestmgr->lock);
|
||||
|
||||
if (requestmgr->exiting) {
|
||||
if (atomic_load_acquire(&requestmgr->exiting)) {
|
||||
/*
|
||||
* We're already shutdown. Send the event.
|
||||
*/
|
||||
|
|
@ -218,126 +230,95 @@ dns_requestmgr_whenshutdown(dns_requestmgr_t *requestmgr, isc_task_t *task,
|
|||
|
||||
void
|
||||
dns_requestmgr_shutdown(dns_requestmgr_t *requestmgr) {
|
||||
dns_request_t *request;
|
||||
|
||||
REQUIRE(VALID_REQUESTMGR(requestmgr));
|
||||
|
||||
req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_shutdown: %p", requestmgr);
|
||||
|
||||
LOCK(&requestmgr->lock);
|
||||
mgr_shutdown(requestmgr);
|
||||
UNLOCK(&requestmgr->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
mgr_shutdown(dns_requestmgr_t *requestmgr) {
|
||||
dns_request_t *request;
|
||||
|
||||
if (!requestmgr->exiting) {
|
||||
requestmgr->exiting = true;
|
||||
for (request = ISC_LIST_HEAD(requestmgr->requests);
|
||||
request != NULL; request = ISC_LIST_NEXT(request, link))
|
||||
{
|
||||
dns_request_cancel(request);
|
||||
}
|
||||
if (requestmgr->iref == 0) {
|
||||
INSIST(ISC_LIST_EMPTY(requestmgr->requests));
|
||||
send_shutdown_events(requestmgr);
|
||||
}
|
||||
if (!atomic_compare_exchange_strong(&requestmgr->exiting,
|
||||
&(bool){ false }, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) {
|
||||
/*
|
||||
* Locked by caller.
|
||||
*/
|
||||
|
||||
REQUIRE(VALID_REQUESTMGR(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
REQUIRE(!source->exiting);
|
||||
|
||||
source->iref++;
|
||||
*targetp = source;
|
||||
|
||||
req_log(ISC_LOG_DEBUG(3), "requestmgr_attach: %p: eref %d iref %d",
|
||||
source, source->eref, source->iref);
|
||||
}
|
||||
|
||||
static void
|
||||
requestmgr_detach(dns_requestmgr_t **requestmgrp) {
|
||||
dns_requestmgr_t *requestmgr;
|
||||
bool need_destroy = false;
|
||||
|
||||
REQUIRE(requestmgrp != NULL);
|
||||
requestmgr = *requestmgrp;
|
||||
*requestmgrp = NULL;
|
||||
REQUIRE(VALID_REQUESTMGR(requestmgr));
|
||||
|
||||
LOCK(&requestmgr->lock);
|
||||
INSIST(requestmgr->iref > 0);
|
||||
requestmgr->iref--;
|
||||
for (request = ISC_LIST_HEAD(requestmgr->requests); request != NULL;
|
||||
request = ISC_LIST_NEXT(request, link))
|
||||
{
|
||||
dns_request_cancel(request);
|
||||
}
|
||||
|
||||
req_log(ISC_LOG_DEBUG(3), "requestmgr_detach: %p: eref %d iref %d",
|
||||
requestmgr, requestmgr->eref, requestmgr->iref);
|
||||
|
||||
if (requestmgr->iref == 0 && requestmgr->exiting) {
|
||||
INSIST(ISC_LIST_HEAD(requestmgr->requests) == NULL);
|
||||
if (ISC_LIST_EMPTY(requestmgr->requests)) {
|
||||
send_shutdown_events(requestmgr);
|
||||
if (requestmgr->eref == 0) {
|
||||
need_destroy = true;
|
||||
}
|
||||
}
|
||||
UNLOCK(&requestmgr->lock);
|
||||
|
||||
if (need_destroy) {
|
||||
mgr_destroy(requestmgr);
|
||||
}
|
||||
UNLOCK(&requestmgr->lock);
|
||||
}
|
||||
|
||||
void
|
||||
dns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) {
|
||||
dns__requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp,
|
||||
const char *file, unsigned int line, const char *func) {
|
||||
uint_fast32_t ref;
|
||||
|
||||
REQUIRE(VALID_REQUESTMGR(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
REQUIRE(!source->exiting);
|
||||
|
||||
LOCK(&source->lock);
|
||||
source->eref++;
|
||||
REQUIRE(!atomic_load_acquire(&source->exiting));
|
||||
|
||||
ref = isc_refcount_increment(&source->references);
|
||||
|
||||
#ifdef REQ_TRACE
|
||||
fprintf(stderr, "%s:%s:%u:%s(%p, %p) = %" PRIuFAST32 "\n", func, file,
|
||||
line, __func__, source, targetp, ref + 1);
|
||||
#else
|
||||
UNUSED(func);
|
||||
UNUSED(file);
|
||||
UNUSED(line);
|
||||
UNUSED(ref);
|
||||
#endif /* REQ_TRACE */
|
||||
|
||||
req_log(ISC_LOG_DEBUG(3),
|
||||
"dns_requestmgr_attach: %p: references = %" PRIuFAST32, source,
|
||||
ref + 1);
|
||||
|
||||
*targetp = source;
|
||||
UNLOCK(&source->lock);
|
||||
|
||||
req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_attach: %p: eref %d iref %d",
|
||||
source, source->eref, source->iref);
|
||||
}
|
||||
|
||||
void
|
||||
dns_requestmgr_detach(dns_requestmgr_t **requestmgrp) {
|
||||
dns_requestmgr_t *requestmgr;
|
||||
bool need_destroy = false;
|
||||
dns__requestmgr_detach(dns_requestmgr_t **requestmgrp, const char *file,
|
||||
unsigned int line, const char *func) {
|
||||
dns_requestmgr_t *requestmgr = NULL;
|
||||
uint_fast32_t ref;
|
||||
|
||||
REQUIRE(requestmgrp != NULL && VALID_REQUESTMGR(*requestmgrp));
|
||||
|
||||
REQUIRE(requestmgrp != NULL);
|
||||
requestmgr = *requestmgrp;
|
||||
*requestmgrp = NULL;
|
||||
REQUIRE(VALID_REQUESTMGR(requestmgr));
|
||||
|
||||
LOCK(&requestmgr->lock);
|
||||
INSIST(requestmgr->eref > 0);
|
||||
requestmgr->eref--;
|
||||
ref = isc_refcount_decrement(&requestmgr->references);
|
||||
|
||||
req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_detach: %p: eref %d iref %d",
|
||||
requestmgr, requestmgr->eref, requestmgr->iref);
|
||||
#ifdef REQ_TRACE
|
||||
fprintf(stderr, "%s:%s:%u:%s(%p, %p) = %" PRIuFAST32 "\n", func, file,
|
||||
line, __func__, requestmgr, requestmgrp, ref - 1);
|
||||
#else
|
||||
UNUSED(func);
|
||||
UNUSED(file);
|
||||
UNUSED(line);
|
||||
UNUSED(ref);
|
||||
#endif /* REQ_TRACE */
|
||||
|
||||
if (requestmgr->eref == 0 && requestmgr->iref == 0) {
|
||||
INSIST(requestmgr->exiting &&
|
||||
ISC_LIST_HEAD(requestmgr->requests) == NULL);
|
||||
need_destroy = true;
|
||||
}
|
||||
UNLOCK(&requestmgr->lock);
|
||||
req_log(ISC_LOG_DEBUG(3),
|
||||
"dns_requestmgr_detach: %p: references = %" PRIuFAST32,
|
||||
requestmgr, ref - 1);
|
||||
|
||||
if (need_destroy) {
|
||||
if (ref == 1) {
|
||||
INSIST(ISC_LIST_EMPTY(requestmgr->requests));
|
||||
mgr_destroy(requestmgr);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME */
|
||||
static void
|
||||
send_shutdown_events(dns_requestmgr_t *requestmgr) {
|
||||
isc_event_t *event, *next_event;
|
||||
|
|
@ -365,8 +346,7 @@ mgr_destroy(dns_requestmgr_t *requestmgr) {
|
|||
|
||||
req_log(ISC_LOG_DEBUG(3), "mgr_destroy");
|
||||
|
||||
REQUIRE(requestmgr->eref == 0);
|
||||
REQUIRE(requestmgr->iref == 0);
|
||||
isc_refcount_destroy(&requestmgr->references);
|
||||
|
||||
isc_mutex_destroy(&requestmgr->lock);
|
||||
for (i = 0; i < DNS_REQUEST_NLOCKS; i++) {
|
||||
|
|
@ -409,12 +389,13 @@ req_send(dns_request_t *request) {
|
|||
|
||||
static isc_result_t
|
||||
new_request(isc_mem_t *mctx, dns_request_t **requestp) {
|
||||
dns_request_t *request;
|
||||
dns_request_t *request = NULL;
|
||||
|
||||
request = isc_mem_get(mctx, sizeof(*request));
|
||||
*request = (dns_request_t){ .dscp = -1 };
|
||||
ISC_LINK_INIT(request, link);
|
||||
|
||||
isc_refcount_init(&request->references, 1);
|
||||
isc_mem_attach(mctx, &request->mctx);
|
||||
|
||||
request->magic = REQUEST_MAGIC;
|
||||
|
|
@ -426,25 +407,25 @@ static bool
|
|||
isblackholed(dns_dispatchmgr_t *dispatchmgr, const isc_sockaddr_t *destaddr) {
|
||||
dns_acl_t *blackhole;
|
||||
isc_netaddr_t netaddr;
|
||||
int match;
|
||||
bool drop = false;
|
||||
char netaddrstr[ISC_NETADDR_FORMATSIZE];
|
||||
int match;
|
||||
isc_result_t result;
|
||||
|
||||
blackhole = dns_dispatchmgr_getblackhole(dispatchmgr);
|
||||
if (blackhole != NULL) {
|
||||
isc_netaddr_fromsockaddr(&netaddr, destaddr);
|
||||
if (dns_acl_match(&netaddr, NULL, blackhole, NULL, &match,
|
||||
NULL) == ISC_R_SUCCESS &&
|
||||
match > 0)
|
||||
{
|
||||
drop = true;
|
||||
}
|
||||
if (blackhole == NULL) {
|
||||
return (false);
|
||||
}
|
||||
if (drop) {
|
||||
isc_netaddr_format(&netaddr, netaddrstr, sizeof(netaddrstr));
|
||||
req_log(ISC_LOG_DEBUG(10), "blackholed address %s", netaddrstr);
|
||||
|
||||
isc_netaddr_fromsockaddr(&netaddr, destaddr);
|
||||
result = dns_acl_match(&netaddr, NULL, blackhole, NULL, &match, NULL);
|
||||
if (result != ISC_R_SUCCESS || match == 0) {
|
||||
return (false);
|
||||
}
|
||||
return (drop);
|
||||
|
||||
isc_netaddr_format(&netaddr, netaddrstr, sizeof(netaddrstr));
|
||||
req_log(ISC_LOG_DEBUG(10), "blackholed address %s", netaddrstr);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
|
|
@ -553,6 +534,10 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
|
|||
|
||||
req_log(ISC_LOG_DEBUG(3), "dns_request_createraw");
|
||||
|
||||
if (atomic_load_acquire(&requestmgr->exiting)) {
|
||||
return (ISC_R_SHUTTINGDOWN);
|
||||
}
|
||||
|
||||
if (isblackholed(requestmgr->dispatchmgr, destaddr)) {
|
||||
return (DNS_R_BLACKHOLED);
|
||||
}
|
||||
|
|
@ -593,6 +578,12 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
|
|||
request->timeout = udptimeout * 1000;
|
||||
}
|
||||
|
||||
isc_buffer_allocate(mctx, &request->query, r.length + (tcp ? 2 : 0));
|
||||
result = isc_buffer_copyregion(request->query, &r);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
again:
|
||||
result = get_dispatch(tcp, newtcp, requestmgr, srcaddr, destaddr, dscp,
|
||||
&connected, &request->dispatch);
|
||||
|
|
@ -605,6 +596,9 @@ again:
|
|||
dispopt |= DNS_DISPATCHOPT_FIXEDID;
|
||||
}
|
||||
|
||||
dns_request_t *tmp = NULL;
|
||||
req_attach(request, &tmp);
|
||||
|
||||
result = dns_dispatch_addresponse(
|
||||
request->dispatch, dispopt, request->timeout, destaddr, task,
|
||||
req_connected, req_senddone, req_response, req_timeout, request,
|
||||
|
|
@ -619,24 +613,13 @@ again:
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
isc_buffer_allocate(mctx, &request->query, r.length + (tcp ? 2 : 0));
|
||||
result = isc_buffer_copyregion(request->query, &r);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Add message ID. */
|
||||
isc_buffer_usedregion(request->query, &r);
|
||||
r.base[0] = (id >> 8) & 0xff;
|
||||
r.base[1] = id & 0xff;
|
||||
|
||||
LOCK(&requestmgr->lock);
|
||||
if (requestmgr->exiting) {
|
||||
UNLOCK(&requestmgr->lock);
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto cleanup;
|
||||
}
|
||||
requestmgr_attach(requestmgr, &request->requestmgr);
|
||||
dns_requestmgr_attach(requestmgr, &request->requestmgr);
|
||||
request->hash = mgr_gethash(requestmgr);
|
||||
ISC_LIST_APPEND(requestmgr->requests, request, link);
|
||||
UNLOCK(&requestmgr->lock);
|
||||
|
|
@ -665,7 +648,7 @@ cleanup:
|
|||
if (tclone != NULL) {
|
||||
isc_task_detach(&tclone);
|
||||
}
|
||||
req_destroy(request);
|
||||
req_detach(&request);
|
||||
req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: failed %s",
|
||||
dns_result_totext(result));
|
||||
return (result);
|
||||
|
|
@ -697,7 +680,6 @@ dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
|
|||
isc_mem_t *mctx;
|
||||
dns_messageid_t id;
|
||||
bool tcp = false;
|
||||
bool settsigkey = true;
|
||||
bool connected = false;
|
||||
|
||||
REQUIRE(VALID_REQUESTMGR(requestmgr));
|
||||
|
|
@ -712,6 +694,10 @@ dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
|
|||
|
||||
req_log(ISC_LOG_DEBUG(3), "dns_request_createvia");
|
||||
|
||||
if (atomic_load_acquire(&requestmgr->exiting)) {
|
||||
return (ISC_R_SHUTTINGDOWN);
|
||||
}
|
||||
|
||||
if (srcaddr != NULL &&
|
||||
isc_sockaddr_pf(srcaddr) != isc_sockaddr_pf(destaddr)) {
|
||||
return (ISC_R_FAMILYMISMATCH);
|
||||
|
|
@ -740,7 +726,11 @@ dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
|
|||
dns_tsigkey_attach(key, &request->tsigkey);
|
||||
}
|
||||
|
||||
use_tcp:
|
||||
result = dns_message_settsigkey(message, request->tsigkey);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((options & DNS_REQUESTOPT_TCP) != 0) {
|
||||
tcp = true;
|
||||
request->timeout = timeout * 1000;
|
||||
|
|
@ -754,12 +744,16 @@ use_tcp:
|
|||
request->timeout = udptimeout * 1000;
|
||||
}
|
||||
|
||||
use_tcp:
|
||||
result = get_dispatch(tcp, false, requestmgr, srcaddr, destaddr, dscp,
|
||||
&connected, &request->dispatch);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dns_request_t *tmp = NULL;
|
||||
req_attach(request, &tmp);
|
||||
|
||||
result = dns_dispatch_addresponse(
|
||||
request->dispatch, 0, request->timeout, destaddr, task,
|
||||
req_connected, req_senddone, req_response, req_timeout, request,
|
||||
|
|
@ -769,14 +763,8 @@ use_tcp:
|
|||
}
|
||||
|
||||
message->id = id;
|
||||
if (settsigkey) {
|
||||
result = dns_message_settsigkey(message, request->tsigkey);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
result = req_render(message, &request->query, options, mctx);
|
||||
if (result == DNS_R_USETCP && (options & DNS_REQUESTOPT_TCP) == 0) {
|
||||
if (result == DNS_R_USETCP && !tcp) {
|
||||
/*
|
||||
* Try again using TCP.
|
||||
*/
|
||||
|
|
@ -784,7 +772,7 @@ use_tcp:
|
|||
dns_dispatch_removeresponse(&request->dispentry, NULL);
|
||||
dns_dispatch_detach(&request->dispatch);
|
||||
options |= DNS_REQUESTOPT_TCP;
|
||||
settsigkey = false;
|
||||
tcp = true;
|
||||
goto use_tcp;
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
@ -797,12 +785,7 @@ use_tcp:
|
|||
}
|
||||
|
||||
LOCK(&requestmgr->lock);
|
||||
if (requestmgr->exiting) {
|
||||
UNLOCK(&requestmgr->lock);
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto cleanup;
|
||||
}
|
||||
requestmgr_attach(requestmgr, &request->requestmgr);
|
||||
dns_requestmgr_attach(requestmgr, &request->requestmgr);
|
||||
request->hash = mgr_gethash(requestmgr);
|
||||
ISC_LIST_APPEND(requestmgr->requests, request, link);
|
||||
UNLOCK(&requestmgr->lock);
|
||||
|
|
@ -831,7 +814,7 @@ cleanup:
|
|||
if (tclone != NULL) {
|
||||
isc_task_detach(&tclone);
|
||||
}
|
||||
req_destroy(request);
|
||||
req_detach(&request);
|
||||
req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: failed %s",
|
||||
dns_result_totext(result));
|
||||
return (result);
|
||||
|
|
@ -956,9 +939,7 @@ request_cancel(dns_request_t *request) {
|
|||
request->flags &= ~DNS_REQUEST_F_CONNECTING;
|
||||
|
||||
if (request->dispentry != NULL) {
|
||||
dns_dispatch_cancel(NULL, request->dispentry,
|
||||
DNS_REQUEST_SENDING(request),
|
||||
DNS_REQUEST_CONNECTING(request));
|
||||
dns_dispatch_cancel(request->dispentry);
|
||||
dns_dispatch_removeresponse(&request->dispentry, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -1047,7 +1028,7 @@ dns_request_destroy(dns_request_t **requestp) {
|
|||
INSIST(request->dispentry == NULL);
|
||||
INSIST(request->dispatch == NULL);
|
||||
|
||||
req_destroy(request);
|
||||
req_detach(&request);
|
||||
}
|
||||
|
||||
/***
|
||||
|
|
@ -1059,15 +1040,17 @@ req_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
|
|||
|
||||
UNUSED(handle);
|
||||
|
||||
req_log(ISC_LOG_DEBUG(3), "req_connected: request %p: %s", request,
|
||||
isc_result_totext(eresult));
|
||||
|
||||
if (eresult == ISC_R_CANCELED) {
|
||||
req_detach(&request);
|
||||
return;
|
||||
}
|
||||
|
||||
REQUIRE(VALID_REQUEST(request));
|
||||
REQUIRE(DNS_REQUEST_CONNECTING(request));
|
||||
|
||||
req_log(ISC_LOG_DEBUG(3), "req_connected: request %p", request);
|
||||
|
||||
LOCK(&request->requestmgr->locks[request->hash]);
|
||||
request->flags &= ~DNS_REQUEST_F_CONNECTING;
|
||||
|
||||
|
|
@ -1084,6 +1067,8 @@ req_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
|
|||
send_if_done(request, ISC_R_CANCELED);
|
||||
}
|
||||
UNLOCK(&request->requestmgr->locks[request->hash]);
|
||||
|
||||
req_detach(&request);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1195,12 +1180,76 @@ req_sendevent(dns_request_t *request, isc_result_t result) {
|
|||
isc_task_sendanddetach(&task, (isc_event_t **)&request->event);
|
||||
}
|
||||
|
||||
static void
|
||||
__req_attach(dns_request_t *source, dns_request_t **targetp, const char *file,
|
||||
unsigned int line, const char *func) {
|
||||
uint_fast32_t ref;
|
||||
|
||||
REQUIRE(VALID_REQUEST(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
ref = isc_refcount_increment(&source->references);
|
||||
|
||||
#ifdef REQ_TRACE
|
||||
fprintf(stderr, "%s:%s:%u:%s(%p, %p) = %" PRIuFAST32 "\n", func, file,
|
||||
line, __func__, source, targetp, ref + 1);
|
||||
#else
|
||||
UNUSED(func);
|
||||
UNUSED(file);
|
||||
UNUSED(line);
|
||||
UNUSED(ref);
|
||||
#endif /* REQ_TRACE */
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
|
||||
static void
|
||||
__req_detach(dns_request_t **requestp, const char *file, unsigned int line,
|
||||
const char *func) {
|
||||
dns_request_t *request = NULL;
|
||||
uint_fast32_t ref;
|
||||
|
||||
REQUIRE(requestp != NULL && VALID_REQUEST(*requestp));
|
||||
|
||||
request = *requestp;
|
||||
*requestp = NULL;
|
||||
|
||||
ref = isc_refcount_decrement(&request->references);
|
||||
|
||||
#ifdef REQ_TRACE
|
||||
fprintf(stderr, "%s:%s:%u:%s(%p, %p) = %" PRIuFAST32 "\n", func, file,
|
||||
line, __func__, request, requestp, ref - 1);
|
||||
#else
|
||||
UNUSED(func);
|
||||
UNUSED(file);
|
||||
UNUSED(line);
|
||||
UNUSED(ref);
|
||||
#endif /* REQ_TRACE */
|
||||
|
||||
if (request->requestmgr != NULL &&
|
||||
atomic_load_acquire(&request->requestmgr->exiting))
|
||||
{
|
||||
/* We are shutting down and this was last request */
|
||||
LOCK(&request->requestmgr->lock);
|
||||
if (ISC_LIST_EMPTY(request->requestmgr->requests)) {
|
||||
send_shutdown_events(request->requestmgr);
|
||||
}
|
||||
UNLOCK(&request->requestmgr->lock);
|
||||
}
|
||||
|
||||
if (ref == 1) {
|
||||
req_destroy(request);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
req_destroy(dns_request_t *request) {
|
||||
REQUIRE(VALID_REQUEST(request));
|
||||
|
||||
req_log(ISC_LOG_DEBUG(3), "req_destroy: request %p", request);
|
||||
|
||||
isc_refcount_destroy(&request->references);
|
||||
|
||||
request->magic = 0;
|
||||
if (request->query != NULL) {
|
||||
isc_buffer_free(&request->query);
|
||||
|
|
@ -1224,7 +1273,7 @@ req_destroy(dns_request_t *request) {
|
|||
dns_tsigkey_detach(&request->tsigkey);
|
||||
}
|
||||
if (request->requestmgr != NULL) {
|
||||
requestmgr_detach(&request->requestmgr);
|
||||
dns_requestmgr_detach(&request->requestmgr);
|
||||
}
|
||||
isc_mem_putanddetach(&request->mctx, request, sizeof(*request));
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -168,7 +168,7 @@ reset(void) {
|
|||
dns_dispatchset_destroy(&dset);
|
||||
}
|
||||
if (dispatchmgr != NULL) {
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
dns_dispatchmgr_detach(&dispatchmgr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -393,7 +393,7 @@ dispatch_getnext(void **state) {
|
|||
* Shutdown the dispatch.
|
||||
*/
|
||||
dns_dispatch_detach(&dispatch);
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
dns_dispatchmgr_detach(&dispatchmgr);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ _teardown(void **state) {
|
|||
|
||||
dns_dispatch_detach(&dispatch);
|
||||
dns_view_detach(&view);
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
dns_dispatchmgr_detach(&dispatchmgr);
|
||||
dns_test_end();
|
||||
|
||||
return (0);
|
||||
|
|
|
|||
|
|
@ -14011,8 +14011,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
|
|||
result = dns_request_getresponse(revent->request, msg, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_zone_log(zone, ISC_LOG_INFO,
|
||||
"refresh: failure trying master "
|
||||
"%s (source %s): %s",
|
||||
"refresh: unable to get response, master "
|
||||
"%s, source %s: %s",
|
||||
master, source, dns_result_totext(result));
|
||||
goto next_master;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ shutdown_managers(isc_task_t *task, isc_event_t *event) {
|
|||
}
|
||||
|
||||
if (dispatchmgr != NULL) {
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
dns_dispatchmgr_detach(&dispatchmgr);
|
||||
}
|
||||
|
||||
atomic_store(&shutdown_done, true);
|
||||
|
|
|
|||
Loading…
Reference in a new issue