mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 15:05:23 +00:00
3318. [tuning] Reduce the amount of work performed while holding a
bucket lock when finshed with a fetch context. [RT #29239]
This commit is contained in:
4
CHANGES
4
CHANGES
@@ -1,3 +1,7 @@
|
|||||||
|
3318. [tuning] Reduce the amount of work performed while holding a
|
||||||
|
bucket lock when finshed with a fetch context.
|
||||||
|
[RT #29239]
|
||||||
|
|
||||||
3317. [func] Add ECDSA support (RFC 6605). [RT #21918]
|
3317. [func] Add ECDSA support (RFC 6605). [RT #21918]
|
||||||
|
|
||||||
3316. [tuning] Improved locking performance when recursing.
|
3316. [tuning] Improved locking performance when recursing.
|
||||||
|
@@ -182,7 +182,9 @@ struct fetchctx {
|
|||||||
dns_rdatatype_t type;
|
dns_rdatatype_t type;
|
||||||
unsigned int options;
|
unsigned int options;
|
||||||
unsigned int bucketnum;
|
unsigned int bucketnum;
|
||||||
char * info;
|
char * info;
|
||||||
|
isc_mem_t * mctx;
|
||||||
|
|
||||||
/*% Locked by appropriate bucket lock. */
|
/*% Locked by appropriate bucket lock. */
|
||||||
fetchstate state;
|
fetchstate state;
|
||||||
isc_boolean_t want_shutdown;
|
isc_boolean_t want_shutdown;
|
||||||
@@ -446,7 +448,8 @@ static void resquery_response(isc_task_t *task, isc_event_t *event);
|
|||||||
static void resquery_connected(isc_task_t *task, isc_event_t *event);
|
static void resquery_connected(isc_task_t *task, isc_event_t *event);
|
||||||
static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying,
|
static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying,
|
||||||
isc_boolean_t badcache);
|
isc_boolean_t badcache);
|
||||||
static isc_boolean_t fctx_destroy(fetchctx_t *fctx);
|
static void fctx_destroy(fetchctx_t *fctx);
|
||||||
|
static isc_boolean_t fctx_unlink(fetchctx_t *fctx);
|
||||||
static isc_result_t ncache_adderesult(dns_message_t *message,
|
static isc_result_t ncache_adderesult(dns_message_t *message,
|
||||||
dns_db_t *cache, dns_dbnode_t *node,
|
dns_db_t *cache, dns_dbnode_t *node,
|
||||||
dns_rdatatype_t covers,
|
dns_rdatatype_t covers,
|
||||||
@@ -478,8 +481,7 @@ valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
|
|||||||
dns_valarg_t *valarg;
|
dns_valarg_t *valarg;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
valarg = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx,
|
valarg = isc_mem_get(fctx->mctx, sizeof(*valarg));
|
||||||
sizeof(*valarg));
|
|
||||||
if (valarg == NULL)
|
if (valarg == NULL)
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
|
|
||||||
@@ -501,8 +503,7 @@ valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
|
|||||||
}
|
}
|
||||||
ISC_LIST_APPEND(fctx->validators, validator, link);
|
ISC_LIST_APPEND(fctx->validators, validator, link);
|
||||||
} else
|
} else
|
||||||
isc_mem_put(fctx->res->buckets[fctx->bucketnum].mctx,
|
isc_mem_put(fctx->mctx, valarg, sizeof(*valarg));
|
||||||
valarg, sizeof(*valarg));
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1387,13 +1388,12 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
|||||||
|
|
||||||
dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE);
|
dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE);
|
||||||
|
|
||||||
query = isc_mem_get(res->buckets[fctx->bucketnum].mctx,
|
query = isc_mem_get(fctx->mctx, sizeof(*query));
|
||||||
sizeof(*query));
|
|
||||||
if (query == NULL) {
|
if (query == NULL) {
|
||||||
result = ISC_R_NOMEMORY;
|
result = ISC_R_NOMEMORY;
|
||||||
goto stop_idle_timer;
|
goto stop_idle_timer;
|
||||||
}
|
}
|
||||||
query->mctx = res->buckets[fctx->bucketnum].mctx;
|
query->mctx = fctx->mctx;
|
||||||
query->options = options;
|
query->options = options;
|
||||||
query->attributes = 0;
|
query->attributes = 0;
|
||||||
query->sends = 0;
|
query->sends = 0;
|
||||||
@@ -1572,8 +1572,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
|||||||
cleanup_query:
|
cleanup_query:
|
||||||
if (query->connects == 0) {
|
if (query->connects == 0) {
|
||||||
query->magic = 0;
|
query->magic = 0;
|
||||||
isc_mem_put(res->buckets[fctx->bucketnum].mctx,
|
isc_mem_put(fctx->mctx, query, sizeof(*query));
|
||||||
query, sizeof(*query));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_idle_timer:
|
stop_idle_timer:
|
||||||
@@ -1603,8 +1602,7 @@ add_bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) {
|
|||||||
if (bad_edns(fctx, address))
|
if (bad_edns(fctx, address))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx,
|
sa = isc_mem_get(fctx->mctx, sizeof(*sa));
|
||||||
sizeof(*sa));
|
|
||||||
if (sa == NULL)
|
if (sa == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1633,8 +1631,7 @@ add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
|
|||||||
if (triededns(fctx, address))
|
if (triededns(fctx, address))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx,
|
sa = isc_mem_get(fctx->mctx, sizeof(*sa));
|
||||||
sizeof(*sa));
|
|
||||||
if (sa == NULL)
|
if (sa == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1663,8 +1660,7 @@ add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
|
|||||||
if (triededns512(fctx, address))
|
if (triededns512(fctx, address))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx,
|
sa = isc_mem_get(fctx->mctx, sizeof(*sa));
|
||||||
sizeof(*sa));
|
|
||||||
if (sa == NULL)
|
if (sa == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -2173,6 +2169,7 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_boolean_t want_done = ISC_FALSE;
|
isc_boolean_t want_done = ISC_FALSE;
|
||||||
isc_boolean_t bucket_empty = ISC_FALSE;
|
isc_boolean_t bucket_empty = ISC_FALSE;
|
||||||
unsigned int bucketnum;
|
unsigned int bucketnum;
|
||||||
|
isc_boolean_t destroy = ISC_FALSE;
|
||||||
|
|
||||||
find = event->ev_sender;
|
find = event->ev_sender;
|
||||||
fctx = event->ev_arg;
|
fctx = event->ev_arg;
|
||||||
@@ -2211,8 +2208,10 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
|
|||||||
} else if (SHUTTINGDOWN(fctx) && fctx->pending == 0 &&
|
} else if (SHUTTINGDOWN(fctx) && fctx->pending == 0 &&
|
||||||
fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
|
fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
|
||||||
|
|
||||||
if (fctx->references == 0)
|
if (fctx->references == 0) {
|
||||||
bucket_empty = fctx_destroy(fctx);
|
bucket_empty = fctx_unlink(fctx);
|
||||||
|
destroy = ISC_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
UNLOCK(&res->buckets[bucketnum].lock);
|
UNLOCK(&res->buckets[bucketnum].lock);
|
||||||
|
|
||||||
@@ -2223,8 +2222,11 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
|
|||||||
fctx_try(fctx, ISC_TRUE, ISC_FALSE);
|
fctx_try(fctx, ISC_TRUE, ISC_FALSE);
|
||||||
else if (want_done)
|
else if (want_done)
|
||||||
fctx_done(fctx, ISC_R_FAILURE, __LINE__);
|
fctx_done(fctx, ISC_R_FAILURE, __LINE__);
|
||||||
else if (bucket_empty)
|
else if (destroy) {
|
||||||
empty_bucket(res);
|
fctx_destroy(fctx);
|
||||||
|
if (bucket_empty)
|
||||||
|
empty_bucket(res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2347,8 +2349,7 @@ add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason,
|
|||||||
|
|
||||||
FCTXTRACE("add_bad");
|
FCTXTRACE("add_bad");
|
||||||
|
|
||||||
sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx,
|
sa = isc_mem_get(fctx->mctx, sizeof(*sa));
|
||||||
sizeof(*sa));
|
|
||||||
if (sa == NULL)
|
if (sa == NULL)
|
||||||
return;
|
return;
|
||||||
*sa = *address;
|
*sa = *address;
|
||||||
@@ -2631,12 +2632,9 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
|
|||||||
fctx->fwdpolicy = forwarders->fwdpolicy;
|
fctx->fwdpolicy = forwarders->fwdpolicy;
|
||||||
if (fctx->fwdpolicy == dns_fwdpolicy_only &&
|
if (fctx->fwdpolicy == dns_fwdpolicy_only &&
|
||||||
isstrictsubdomain(domain, &fctx->domain)) {
|
isstrictsubdomain(domain, &fctx->domain)) {
|
||||||
isc_mem_t *mctx;
|
dns_name_free(&fctx->domain, fctx->mctx);
|
||||||
|
|
||||||
mctx = res->buckets[fctx->bucketnum].mctx;
|
|
||||||
dns_name_free(&fctx->domain, mctx);
|
|
||||||
dns_name_init(&fctx->domain, NULL);
|
dns_name_init(&fctx->domain, NULL);
|
||||||
result = dns_name_dup(domain, mctx,
|
result = dns_name_dup(domain, fctx->mctx,
|
||||||
&fctx->domain);
|
&fctx->domain);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
@@ -3075,10 +3073,9 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isc_boolean_t
|
static isc_boolean_t
|
||||||
fctx_destroy(fetchctx_t *fctx) {
|
fctx_unlink(fetchctx_t *fctx) {
|
||||||
dns_resolver_t *res;
|
dns_resolver_t *res;
|
||||||
unsigned int bucketnum;
|
unsigned int bucketnum;
|
||||||
isc_sockaddr_t *sa, *next_sa;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Caller must be holding the bucket lock.
|
* Caller must be holding the bucket lock.
|
||||||
@@ -3095,61 +3092,13 @@ fctx_destroy(fetchctx_t *fctx) {
|
|||||||
REQUIRE(fctx->references == 0);
|
REQUIRE(fctx->references == 0);
|
||||||
REQUIRE(ISC_LIST_EMPTY(fctx->validators));
|
REQUIRE(ISC_LIST_EMPTY(fctx->validators));
|
||||||
|
|
||||||
FCTXTRACE("destroy");
|
FCTXTRACE("unlink");
|
||||||
|
|
||||||
res = fctx->res;
|
res = fctx->res;
|
||||||
bucketnum = fctx->bucketnum;
|
bucketnum = fctx->bucketnum;
|
||||||
|
|
||||||
ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link);
|
ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link);
|
||||||
|
|
||||||
/*
|
|
||||||
* Free bad.
|
|
||||||
*/
|
|
||||||
for (sa = ISC_LIST_HEAD(fctx->bad);
|
|
||||||
sa != NULL;
|
|
||||||
sa = next_sa) {
|
|
||||||
next_sa = ISC_LIST_NEXT(sa, link);
|
|
||||||
ISC_LIST_UNLINK(fctx->bad, sa, link);
|
|
||||||
isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (sa = ISC_LIST_HEAD(fctx->edns);
|
|
||||||
sa != NULL;
|
|
||||||
sa = next_sa) {
|
|
||||||
next_sa = ISC_LIST_NEXT(sa, link);
|
|
||||||
ISC_LIST_UNLINK(fctx->edns, sa, link);
|
|
||||||
isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (sa = ISC_LIST_HEAD(fctx->edns512);
|
|
||||||
sa != NULL;
|
|
||||||
sa = next_sa) {
|
|
||||||
next_sa = ISC_LIST_NEXT(sa, link);
|
|
||||||
ISC_LIST_UNLINK(fctx->edns512, sa, link);
|
|
||||||
isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (sa = ISC_LIST_HEAD(fctx->bad_edns);
|
|
||||||
sa != NULL;
|
|
||||||
sa = next_sa) {
|
|
||||||
next_sa = ISC_LIST_NEXT(sa, link);
|
|
||||||
ISC_LIST_UNLINK(fctx->bad_edns, sa, link);
|
|
||||||
isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa));
|
|
||||||
}
|
|
||||||
|
|
||||||
isc_timer_detach(&fctx->timer);
|
|
||||||
dns_message_destroy(&fctx->rmessage);
|
|
||||||
dns_message_destroy(&fctx->qmessage);
|
|
||||||
if (dns_name_countlabels(&fctx->domain) > 0)
|
|
||||||
dns_name_free(&fctx->domain, res->buckets[bucketnum].mctx);
|
|
||||||
if (dns_rdataset_isassociated(&fctx->nameservers))
|
|
||||||
dns_rdataset_disassociate(&fctx->nameservers);
|
|
||||||
dns_name_free(&fctx->name, res->buckets[bucketnum].mctx);
|
|
||||||
dns_db_detach(&fctx->cache);
|
|
||||||
dns_adb_detach(&fctx->adb);
|
|
||||||
isc_mem_free(res->buckets[bucketnum].mctx, fctx->info);
|
|
||||||
isc_mem_put(res->buckets[bucketnum].mctx, fctx, sizeof(*fctx));
|
|
||||||
|
|
||||||
LOCK(&res->nlock);
|
LOCK(&res->nlock);
|
||||||
res->nfctx--;
|
res->nfctx--;
|
||||||
UNLOCK(&res->nlock);
|
UNLOCK(&res->nlock);
|
||||||
@@ -3161,6 +3110,73 @@ fctx_destroy(fetchctx_t *fctx) {
|
|||||||
return (ISC_FALSE);
|
return (ISC_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fctx_destroy(fetchctx_t *fctx) {
|
||||||
|
isc_sockaddr_t *sa, *next_sa;
|
||||||
|
|
||||||
|
REQUIRE(VALID_FCTX(fctx));
|
||||||
|
REQUIRE(fctx->state == fetchstate_done ||
|
||||||
|
fctx->state == fetchstate_init);
|
||||||
|
REQUIRE(ISC_LIST_EMPTY(fctx->events));
|
||||||
|
REQUIRE(ISC_LIST_EMPTY(fctx->queries));
|
||||||
|
REQUIRE(ISC_LIST_EMPTY(fctx->finds));
|
||||||
|
REQUIRE(ISC_LIST_EMPTY(fctx->altfinds));
|
||||||
|
REQUIRE(fctx->pending == 0);
|
||||||
|
REQUIRE(fctx->references == 0);
|
||||||
|
REQUIRE(ISC_LIST_EMPTY(fctx->validators));
|
||||||
|
REQUIRE(!ISC_LINK_LINKED(fctx, link));
|
||||||
|
|
||||||
|
FCTXTRACE("destroy");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free bad.
|
||||||
|
*/
|
||||||
|
for (sa = ISC_LIST_HEAD(fctx->bad);
|
||||||
|
sa != NULL;
|
||||||
|
sa = next_sa) {
|
||||||
|
next_sa = ISC_LIST_NEXT(sa, link);
|
||||||
|
ISC_LIST_UNLINK(fctx->bad, sa, link);
|
||||||
|
isc_mem_put(fctx->mctx, sa, sizeof(*sa));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (sa = ISC_LIST_HEAD(fctx->edns);
|
||||||
|
sa != NULL;
|
||||||
|
sa = next_sa) {
|
||||||
|
next_sa = ISC_LIST_NEXT(sa, link);
|
||||||
|
ISC_LIST_UNLINK(fctx->edns, sa, link);
|
||||||
|
isc_mem_put(fctx->mctx, sa, sizeof(*sa));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (sa = ISC_LIST_HEAD(fctx->edns512);
|
||||||
|
sa != NULL;
|
||||||
|
sa = next_sa) {
|
||||||
|
next_sa = ISC_LIST_NEXT(sa, link);
|
||||||
|
ISC_LIST_UNLINK(fctx->edns512, sa, link);
|
||||||
|
isc_mem_put(fctx->mctx, sa, sizeof(*sa));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (sa = ISC_LIST_HEAD(fctx->bad_edns);
|
||||||
|
sa != NULL;
|
||||||
|
sa = next_sa) {
|
||||||
|
next_sa = ISC_LIST_NEXT(sa, link);
|
||||||
|
ISC_LIST_UNLINK(fctx->bad_edns, sa, link);
|
||||||
|
isc_mem_put(fctx->mctx, sa, sizeof(*sa));
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_timer_detach(&fctx->timer);
|
||||||
|
dns_message_destroy(&fctx->rmessage);
|
||||||
|
dns_message_destroy(&fctx->qmessage);
|
||||||
|
if (dns_name_countlabels(&fctx->domain) > 0)
|
||||||
|
dns_name_free(&fctx->domain, fctx->mctx);
|
||||||
|
if (dns_rdataset_isassociated(&fctx->nameservers))
|
||||||
|
dns_rdataset_disassociate(&fctx->nameservers);
|
||||||
|
dns_name_free(&fctx->name, fctx->mctx);
|
||||||
|
dns_db_detach(&fctx->cache);
|
||||||
|
dns_adb_detach(&fctx->adb);
|
||||||
|
isc_mem_free(fctx->mctx, fctx->info);
|
||||||
|
isc_mem_putanddetach(&fctx->mctx, fctx, sizeof(*fctx));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fetch event handlers.
|
* Fetch event handlers.
|
||||||
*/
|
*/
|
||||||
@@ -3258,6 +3274,7 @@ fctx_doshutdown(isc_task_t *task, isc_event_t *event) {
|
|||||||
dns_resolver_t *res;
|
dns_resolver_t *res;
|
||||||
unsigned int bucketnum;
|
unsigned int bucketnum;
|
||||||
dns_validator_t *validator;
|
dns_validator_t *validator;
|
||||||
|
isc_boolean_t destroy = ISC_FALSE;
|
||||||
|
|
||||||
REQUIRE(VALID_FCTX(fctx));
|
REQUIRE(VALID_FCTX(fctx));
|
||||||
|
|
||||||
@@ -3307,13 +3324,18 @@ fctx_doshutdown(isc_task_t *task, isc_event_t *event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fctx->references == 0 && fctx->pending == 0 &&
|
if (fctx->references == 0 && fctx->pending == 0 &&
|
||||||
fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators))
|
fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
|
||||||
bucket_empty = fctx_destroy(fctx);
|
bucket_empty = fctx_unlink(fctx);
|
||||||
|
destroy = ISC_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
UNLOCK(&res->buckets[bucketnum].lock);
|
UNLOCK(&res->buckets[bucketnum].lock);
|
||||||
|
|
||||||
if (bucket_empty)
|
if (destroy) {
|
||||||
empty_bucket(res);
|
fctx_destroy(fctx);
|
||||||
|
if (bucket_empty)
|
||||||
|
empty_bucket(res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -3322,6 +3344,7 @@ fctx_start(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_boolean_t done = ISC_FALSE, bucket_empty = ISC_FALSE;
|
isc_boolean_t done = ISC_FALSE, bucket_empty = ISC_FALSE;
|
||||||
dns_resolver_t *res;
|
dns_resolver_t *res;
|
||||||
unsigned int bucketnum;
|
unsigned int bucketnum;
|
||||||
|
isc_boolean_t destroy = ISC_FALSE;
|
||||||
|
|
||||||
REQUIRE(VALID_FCTX(fctx));
|
REQUIRE(VALID_FCTX(fctx));
|
||||||
|
|
||||||
@@ -3354,7 +3377,8 @@ fctx_start(isc_task_t *task, isc_event_t *event) {
|
|||||||
/*
|
/*
|
||||||
* It's now safe to destroy this fctx.
|
* It's now safe to destroy this fctx.
|
||||||
*/
|
*/
|
||||||
bucket_empty = fctx_destroy(fctx);
|
bucket_empty = fctx_unlink(fctx);
|
||||||
|
destroy = ISC_TRUE;
|
||||||
}
|
}
|
||||||
done = ISC_TRUE;
|
done = ISC_TRUE;
|
||||||
} else {
|
} else {
|
||||||
@@ -3376,6 +3400,8 @@ fctx_start(isc_task_t *task, isc_event_t *event) {
|
|||||||
if (!done) {
|
if (!done) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
|
INSIST(!destroy);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All is well. Start working on the fetch.
|
* All is well. Start working on the fetch.
|
||||||
*/
|
*/
|
||||||
@@ -3384,8 +3410,11 @@ fctx_start(isc_task_t *task, isc_event_t *event) {
|
|||||||
fctx_done(fctx, result, __LINE__);
|
fctx_done(fctx, result, __LINE__);
|
||||||
else
|
else
|
||||||
fctx_try(fctx, ISC_FALSE, ISC_FALSE);
|
fctx_try(fctx, ISC_FALSE, ISC_FALSE);
|
||||||
} else if (bucket_empty)
|
} else if (destroy) {
|
||||||
empty_bucket(res);
|
fctx_destroy(fctx);
|
||||||
|
if (bucket_empty)
|
||||||
|
empty_bucket(res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3473,27 +3502,29 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE];
|
char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE];
|
||||||
char typebuf[DNS_RDATATYPE_FORMATSIZE];
|
char typebuf[DNS_RDATATYPE_FORMATSIZE];
|
||||||
dns_name_t suffix;
|
dns_name_t suffix;
|
||||||
|
isc_mem_t *mctx;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Caller must be holding the lock for bucket number 'bucketnum'.
|
* Caller must be holding the lock for bucket number 'bucketnum'.
|
||||||
*/
|
*/
|
||||||
REQUIRE(fctxp != NULL && *fctxp == NULL);
|
REQUIRE(fctxp != NULL && *fctxp == NULL);
|
||||||
|
|
||||||
fctx = isc_mem_get(res->buckets[bucketnum].mctx, sizeof(*fctx));
|
mctx = res->buckets[bucketnum].mctx;
|
||||||
|
fctx = isc_mem_get(mctx, sizeof(*fctx));
|
||||||
if (fctx == NULL)
|
if (fctx == NULL)
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
dns_name_format(name, buf, sizeof(buf));
|
dns_name_format(name, buf, sizeof(buf));
|
||||||
dns_rdatatype_format(type, typebuf, sizeof(typebuf));
|
dns_rdatatype_format(type, typebuf, sizeof(typebuf));
|
||||||
strcat(buf, "/"); /* checked */
|
strcat(buf, "/"); /* checked */
|
||||||
strcat(buf, typebuf); /* checked */
|
strcat(buf, typebuf); /* checked */
|
||||||
fctx->info = isc_mem_strdup(res->buckets[bucketnum].mctx, buf);
|
fctx->info = isc_mem_strdup(mctx, buf);
|
||||||
if (fctx->info == NULL) {
|
if (fctx->info == NULL) {
|
||||||
result = ISC_R_NOMEMORY;
|
result = ISC_R_NOMEMORY;
|
||||||
goto cleanup_fetch;
|
goto cleanup_fetch;
|
||||||
}
|
}
|
||||||
FCTXTRACE("create");
|
FCTXTRACE("create");
|
||||||
dns_name_init(&fctx->name, NULL);
|
dns_name_init(&fctx->name, NULL);
|
||||||
result = dns_name_dup(name, res->buckets[bucketnum].mctx, &fctx->name);
|
result = dns_name_dup(name, mctx, &fctx->name);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup_info;
|
goto cleanup_info;
|
||||||
dns_name_init(&fctx->domain, NULL);
|
dns_name_init(&fctx->domain, NULL);
|
||||||
@@ -3596,9 +3627,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
NULL);
|
NULL);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup_name;
|
goto cleanup_name;
|
||||||
result = dns_name_dup(domain,
|
result = dns_name_dup(domain, mctx, &fctx->domain);
|
||||||
res->buckets[bucketnum].mctx,
|
|
||||||
&fctx->domain);
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
dns_rdataset_disassociate(&fctx->nameservers);
|
dns_rdataset_disassociate(&fctx->nameservers);
|
||||||
goto cleanup_name;
|
goto cleanup_name;
|
||||||
@@ -3609,16 +3638,12 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
/*
|
/*
|
||||||
* We're in forward-only mode. Set the query domain.
|
* We're in forward-only mode. Set the query domain.
|
||||||
*/
|
*/
|
||||||
result = dns_name_dup(domain,
|
result = dns_name_dup(domain, mctx, &fctx->domain);
|
||||||
res->buckets[bucketnum].mctx,
|
|
||||||
&fctx->domain);
|
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup_name;
|
goto cleanup_name;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = dns_name_dup(domain,
|
result = dns_name_dup(domain, mctx, &fctx->domain);
|
||||||
res->buckets[bucketnum].mctx,
|
|
||||||
&fctx->domain);
|
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup_name;
|
goto cleanup_name;
|
||||||
dns_rdataset_clone(nameservers, &fctx->nameservers);
|
dns_rdataset_clone(nameservers, &fctx->nameservers);
|
||||||
@@ -3631,16 +3656,14 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
INSIST(dns_name_issubdomain(&fctx->name, &fctx->domain));
|
INSIST(dns_name_issubdomain(&fctx->name, &fctx->domain));
|
||||||
|
|
||||||
fctx->qmessage = NULL;
|
fctx->qmessage = NULL;
|
||||||
result = dns_message_create(res->buckets[bucketnum].mctx,
|
result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER,
|
||||||
DNS_MESSAGE_INTENTRENDER,
|
|
||||||
&fctx->qmessage);
|
&fctx->qmessage);
|
||||||
|
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup_domain;
|
goto cleanup_domain;
|
||||||
|
|
||||||
fctx->rmessage = NULL;
|
fctx->rmessage = NULL;
|
||||||
result = dns_message_create(res->buckets[bucketnum].mctx,
|
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE,
|
||||||
DNS_MESSAGE_INTENTPARSE,
|
|
||||||
&fctx->rmessage);
|
&fctx->rmessage);
|
||||||
|
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
@@ -3690,6 +3713,8 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
dns_db_attach(res->view->cachedb, &fctx->cache);
|
dns_db_attach(res->view->cachedb, &fctx->cache);
|
||||||
fctx->adb = NULL;
|
fctx->adb = NULL;
|
||||||
dns_adb_attach(res->view->adb, &fctx->adb);
|
dns_adb_attach(res->view->adb, &fctx->adb);
|
||||||
|
fctx->mctx = NULL;
|
||||||
|
isc_mem_attach(mctx, &fctx->mctx);
|
||||||
|
|
||||||
ISC_LIST_INIT(fctx->events);
|
ISC_LIST_INIT(fctx->events);
|
||||||
ISC_LINK_INIT(fctx, link);
|
ISC_LINK_INIT(fctx, link);
|
||||||
@@ -3713,18 +3738,18 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
|
|
||||||
cleanup_domain:
|
cleanup_domain:
|
||||||
if (dns_name_countlabels(&fctx->domain) > 0)
|
if (dns_name_countlabels(&fctx->domain) > 0)
|
||||||
dns_name_free(&fctx->domain, res->buckets[bucketnum].mctx);
|
dns_name_free(&fctx->domain, mctx);
|
||||||
if (dns_rdataset_isassociated(&fctx->nameservers))
|
if (dns_rdataset_isassociated(&fctx->nameservers))
|
||||||
dns_rdataset_disassociate(&fctx->nameservers);
|
dns_rdataset_disassociate(&fctx->nameservers);
|
||||||
|
|
||||||
cleanup_name:
|
cleanup_name:
|
||||||
dns_name_free(&fctx->name, res->buckets[bucketnum].mctx);
|
dns_name_free(&fctx->name, mctx);
|
||||||
|
|
||||||
cleanup_info:
|
cleanup_info:
|
||||||
isc_mem_free(res->buckets[bucketnum].mctx, fctx->info);
|
isc_mem_free(mctx, fctx->info);
|
||||||
|
|
||||||
cleanup_fetch:
|
cleanup_fetch:
|
||||||
isc_mem_put(res->buckets[bucketnum].mctx, fctx, sizeof(*fctx));
|
isc_mem_put(mctx, fctx, sizeof(*fctx));
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
@@ -3934,6 +3959,7 @@ maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) {
|
|||||||
isc_boolean_t bucket_empty = ISC_FALSE;
|
isc_boolean_t bucket_empty = ISC_FALSE;
|
||||||
dns_resolver_t *res = fctx->res;
|
dns_resolver_t *res = fctx->res;
|
||||||
dns_validator_t *validator, *next_validator;
|
dns_validator_t *validator, *next_validator;
|
||||||
|
isc_boolean_t destroy = ISC_FALSE;
|
||||||
|
|
||||||
REQUIRE(SHUTTINGDOWN(fctx));
|
REQUIRE(SHUTTINGDOWN(fctx));
|
||||||
|
|
||||||
@@ -3949,11 +3975,15 @@ maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) {
|
|||||||
dns_validator_cancel(validator);
|
dns_validator_cancel(validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators))
|
if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators)) {
|
||||||
bucket_empty = fctx_destroy(fctx);
|
bucket_empty = fctx_unlink(fctx);
|
||||||
|
destroy = ISC_TRUE;
|
||||||
|
}
|
||||||
unlock:
|
unlock:
|
||||||
if (!locked)
|
if (!locked)
|
||||||
UNLOCK(&res->buckets[bucketnum].lock);
|
UNLOCK(&res->buckets[bucketnum].lock);
|
||||||
|
if (destroy)
|
||||||
|
fctx_destroy(fctx);
|
||||||
return (bucket_empty);
|
return (bucket_empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4008,8 +4038,7 @@ validated(isc_task_t *task, isc_event_t *event) {
|
|||||||
* destroy the fctx if necessary.
|
* destroy the fctx if necessary.
|
||||||
*/
|
*/
|
||||||
dns_validator_destroy(&vevent->validator);
|
dns_validator_destroy(&vevent->validator);
|
||||||
isc_mem_put(res->buckets[fctx->bucketnum].mctx,
|
isc_mem_put(fctx->mctx, valarg, sizeof(*valarg));
|
||||||
valarg, sizeof(*valarg));
|
|
||||||
|
|
||||||
negative = ISC_TF(vevent->rdataset == NULL);
|
negative = ISC_TF(vevent->rdataset == NULL);
|
||||||
|
|
||||||
@@ -5723,14 +5752,11 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
|
|||||||
* if so we should bail out.
|
* if so we should bail out.
|
||||||
*/
|
*/
|
||||||
INSIST(dns_name_countlabels(&fctx->domain) > 0);
|
INSIST(dns_name_countlabels(&fctx->domain) > 0);
|
||||||
dns_name_free(&fctx->domain,
|
dns_name_free(&fctx->domain, fctx->mctx);
|
||||||
fctx->res->buckets[fctx->bucketnum].mctx);
|
|
||||||
if (dns_rdataset_isassociated(&fctx->nameservers))
|
if (dns_rdataset_isassociated(&fctx->nameservers))
|
||||||
dns_rdataset_disassociate(&fctx->nameservers);
|
dns_rdataset_disassociate(&fctx->nameservers);
|
||||||
dns_name_init(&fctx->domain, NULL);
|
dns_name_init(&fctx->domain, NULL);
|
||||||
result = dns_name_dup(ns_name,
|
result = dns_name_dup(ns_name, fctx->mctx, &fctx->domain);
|
||||||
fctx->res->buckets[fctx->bucketnum].mctx,
|
|
||||||
&fctx->domain);
|
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
fctx->attributes |= FCTX_ATTR_WANTCACHE;
|
fctx->attributes |= FCTX_ATTR_WANTCACHE;
|
||||||
@@ -6232,7 +6258,8 @@ fctx_decreference(fetchctx_t *fctx) {
|
|||||||
* This fctx is already shutdown; we were just
|
* This fctx is already shutdown; we were just
|
||||||
* waiting for the last reference to go away.
|
* waiting for the last reference to go away.
|
||||||
*/
|
*/
|
||||||
bucket_empty = fctx_destroy(fctx);
|
bucket_empty = fctx_unlink(fctx);
|
||||||
|
fctx_destroy(fctx);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Initiate shutdown.
|
* Initiate shutdown.
|
||||||
@@ -6287,12 +6314,9 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) {
|
|||||||
fctx->ns_ttl = fctx->nameservers.ttl;
|
fctx->ns_ttl = fctx->nameservers.ttl;
|
||||||
fctx->ns_ttl_ok = ISC_TRUE;
|
fctx->ns_ttl_ok = ISC_TRUE;
|
||||||
log_ns_ttl(fctx, "resume_dslookup");
|
log_ns_ttl(fctx, "resume_dslookup");
|
||||||
dns_name_free(&fctx->domain,
|
dns_name_free(&fctx->domain, fctx->mctx);
|
||||||
fctx->res->buckets[bucketnum].mctx);
|
|
||||||
dns_name_init(&fctx->domain, NULL);
|
dns_name_init(&fctx->domain, NULL);
|
||||||
result = dns_name_dup(&fctx->nsname,
|
result = dns_name_dup(&fctx->nsname, fctx->mctx, &fctx->domain);
|
||||||
fctx->res->buckets[bucketnum].mctx,
|
|
||||||
&fctx->domain);
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
|
fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -7174,12 +7198,9 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||||||
fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
|
fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dns_name_free(&fctx->domain,
|
dns_name_free(&fctx->domain, fctx->mctx);
|
||||||
fctx->res->buckets[fctx->bucketnum].mctx);
|
|
||||||
dns_name_init(&fctx->domain, NULL);
|
dns_name_init(&fctx->domain, NULL);
|
||||||
result = dns_name_dup(fname,
|
result = dns_name_dup(fname, fctx->mctx, &fctx->domain);
|
||||||
fctx->res->buckets[fctx->bucketnum].mctx,
|
|
||||||
&fctx->domain);
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
|
fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
|
||||||
return;
|
return;
|
||||||
@@ -7918,6 +7939,7 @@ dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name,
|
|||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
unsigned int spillat;
|
unsigned int spillat;
|
||||||
unsigned int spillatmin;
|
unsigned int spillatmin;
|
||||||
|
isc_boolean_t destroy = ISC_FALSE;
|
||||||
|
|
||||||
UNUSED(forwarders);
|
UNUSED(forwarders);
|
||||||
|
|
||||||
@@ -8015,16 +8037,20 @@ dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name,
|
|||||||
isc_task_send(res->buckets[bucketnum].task, &event);
|
isc_task_send(res->buckets[bucketnum].task, &event);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* We don't care about the result of fctx_destroy()
|
* We don't care about the result of fctx_unlink()
|
||||||
* since we know we're not exiting.
|
* since we know we're not exiting.
|
||||||
*/
|
*/
|
||||||
(void)fctx_destroy(fctx);
|
(void)fctx_unlink(fctx);
|
||||||
|
destroy = ISC_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
UNLOCK(&res->buckets[bucketnum].lock);
|
UNLOCK(&res->buckets[bucketnum].lock);
|
||||||
|
|
||||||
|
if (destroy)
|
||||||
|
fctx_destroy(fctx);
|
||||||
|
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
FTRACE("created");
|
FTRACE("created");
|
||||||
*fetchp = fetch;
|
*fetchp = fetch;
|
||||||
|
Reference in New Issue
Block a user