mirror of
https://github.com/isc-projects/bind9.git
synced 2026-02-25 19:04:57 -05:00
Keep track of allow client detach
The stale-answer-client-timeout feature introduced a dependancy on
when a client may be detached from the handle. The dboption
DNS_DBFIND_STALEONLY was reused to track this attribute. This overloads
the meaning of this database option, and actually introduced a bug
because the option was checked in other places. In particular, in
'ns_query_done()' there is a check for 'RECURSING(qctx->client) &&
(!QUERY_STALEONLY(&qctx->client->query) || ...' and the condition is
satisfied because recursion has not completed yet and
DNS_DBFIND_STALEONLY is already cleared by that time (in
query_lookup()), because we found a useful answer and we should detach
the client from the handle after sending the response.
Add a new boolean to the client structure to keep track of client
detach from handle is allowed or not. It is only disallowed if we are
in a staleonly lookup and we didn't found a useful answer.
(cherry picked from commit fee164243f)
This commit is contained in:
parent
bcae8ec0ef
commit
fcf8fb4f39
2 changed files with 15 additions and 11 deletions
|
|
@ -178,6 +178,7 @@ struct ns_client {
|
|||
ns_clientmgr_t * manager;
|
||||
ns_clientstate_t state;
|
||||
int nupdates;
|
||||
bool nodetach;
|
||||
bool shuttingdown;
|
||||
unsigned int attributes;
|
||||
isc_task_t * task;
|
||||
|
|
|
|||
|
|
@ -560,7 +560,7 @@ query_send(ns_client_t *client) {
|
|||
inc_stats(client, counter);
|
||||
ns_client_send(client);
|
||||
|
||||
if (!QUERY_STALEONLY(&client->query)) {
|
||||
if (!client->nodetach) {
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
}
|
||||
}
|
||||
|
|
@ -590,7 +590,7 @@ query_error(ns_client_t *client, isc_result_t result, int line) {
|
|||
|
||||
ns_client_error(client, result);
|
||||
|
||||
if (!QUERY_STALEONLY(&client->query)) {
|
||||
if (!client->nodetach) {
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
}
|
||||
}
|
||||
|
|
@ -606,7 +606,7 @@ query_next(ns_client_t *client, isc_result_t result) {
|
|||
}
|
||||
ns_client_drop(client, result);
|
||||
|
||||
if (!QUERY_STALEONLY(&client->query)) {
|
||||
if (!client->nodetach) {
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
}
|
||||
}
|
||||
|
|
@ -5177,7 +5177,7 @@ qctx_freedata(query_ctx_t *qctx) {
|
|||
dns_db_detach(&qctx->zdb);
|
||||
}
|
||||
|
||||
if (qctx->event != NULL && !QUERY_STALEONLY(&qctx->client->query)) {
|
||||
if (qctx->event != NULL && !qctx->client->nodetach) {
|
||||
free_devent(qctx->client, ISC_EVENT_PTR(&qctx->event),
|
||||
&qctx->event);
|
||||
}
|
||||
|
|
@ -5720,6 +5720,7 @@ query_lookup(query_ctx_t *qctx) {
|
|||
* active RRset is not available.
|
||||
*/
|
||||
qctx->client->query.dboptions |= DNS_DBFIND_STALEONLY;
|
||||
qctx->client->nodetach = true;
|
||||
}
|
||||
|
||||
dboptions = qctx->client->query.dboptions;
|
||||
|
|
@ -5881,6 +5882,7 @@ query_lookup(query_ctx_t *qctx) {
|
|||
&qctx->db);
|
||||
qctx->client->query.dboptions &=
|
||||
~DNS_DBFIND_STALEONLY;
|
||||
qctx->client->nodetach = false;
|
||||
qctx->options &= ~DNS_GETDB_STALEFIRST;
|
||||
if (qctx->client->query.fetch != NULL) {
|
||||
dns_resolver_destroyfetch(
|
||||
|
|
@ -5927,7 +5929,7 @@ query_lookup(query_ctx_t *qctx) {
|
|||
* actually not a 'stale-only' lookup. Clear the flag to
|
||||
* allow the client to be detach the handle.
|
||||
*/
|
||||
qctx->client->query.dboptions &= ~DNS_DBFIND_STALEONLY;
|
||||
qctx->client->nodetach = false;
|
||||
}
|
||||
|
||||
result = query_gotanswer(qctx, result);
|
||||
|
|
@ -5962,6 +5964,7 @@ query_lookup_staleonly(ns_client_t *client) {
|
|||
dns_db_attach(client->view->cachedb, &qctx.db);
|
||||
client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK;
|
||||
client->query.dboptions |= DNS_DBFIND_STALEONLY;
|
||||
client->nodetach = true;
|
||||
(void)query_lookup(&qctx);
|
||||
if (qctx.node != NULL) {
|
||||
dns_db_detachnode(qctx.db, &qctx.node);
|
||||
|
|
@ -6003,10 +6006,11 @@ fetch_callback(isc_task_t *task, isc_event_t *event) {
|
|||
query_lookup_staleonly(client);
|
||||
isc_event_free(ISC_EVENT_PTR(&event));
|
||||
return;
|
||||
} else {
|
||||
client->query.dboptions &= ~DNS_DBFIND_STALEONLY;
|
||||
}
|
||||
|
||||
client->query.dboptions &= ~DNS_DBFIND_STALEONLY;
|
||||
client->nodetach = false;
|
||||
|
||||
LOCK(&client->query.fetchlock);
|
||||
if (client->query.fetch != NULL) {
|
||||
/*
|
||||
|
|
@ -11244,7 +11248,7 @@ isc_result_t
|
|||
ns_query_done(query_ctx_t *qctx) {
|
||||
isc_result_t result;
|
||||
const dns_namelist_t *secs = qctx->client->message->sections;
|
||||
bool query_stale_only;
|
||||
bool nodetach;
|
||||
|
||||
CCTRACE(ISC_LOG_DEBUG(3), "ns_query_done");
|
||||
|
||||
|
|
@ -11356,10 +11360,9 @@ ns_query_done(query_ctx_t *qctx) {
|
|||
* Client may have been detached after query_send(), so
|
||||
* we test and store the flag state here, for safety.
|
||||
*/
|
||||
query_stale_only = QUERY_STALEONLY(&qctx->client->query);
|
||||
nodetach = qctx->client->nodetach;
|
||||
query_send(qctx->client);
|
||||
|
||||
if (!query_stale_only) {
|
||||
if (!nodetach) {
|
||||
qctx->detach_client = true;
|
||||
}
|
||||
return (qctx->result);
|
||||
|
|
|
|||
Loading…
Reference in a new issue