mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
the client and query data structures were not cleaned up
correctly if the server got a SIGINT with a recursive query in progress
This commit is contained in:
parent
24a2d84aed
commit
2cb0da946e
@ -126,7 +126,6 @@ maybe_free(ns_client_t *client) {
|
||||
/* We have received our last event. */
|
||||
ns_query_free(client);
|
||||
isc_mempool_destroy(&client->sendbufs);
|
||||
dns_message_destroy(&client->message);
|
||||
isc_timer_detach(&client->timer);
|
||||
|
||||
if (client->dispentry != NULL) {
|
||||
@ -139,6 +138,14 @@ maybe_free(ns_client_t *client) {
|
||||
&client->dispentry,
|
||||
deventp);
|
||||
}
|
||||
if (client->view != NULL)
|
||||
dns_view_detach(&client->view);
|
||||
if (client->opt != NULL) {
|
||||
INSIST(dns_rdataset_isassociated(client->opt));
|
||||
dns_rdataset_disassociate(client->opt);
|
||||
dns_message_puttemprdataset(client->message, &client->opt);
|
||||
}
|
||||
dns_message_destroy(&client->message);
|
||||
if (client->tcpmsg_valid)
|
||||
dns_tcpmsg_invalidate(&client->tcpmsg);
|
||||
if (client->dispatch != NULL)
|
||||
@ -488,6 +495,10 @@ client_addopt(ns_client_t *client) {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle an incoming request event from the dispatch (UDP case)
|
||||
* or tcpmsg (TCP case).
|
||||
*/
|
||||
static void
|
||||
client_request(isc_task_t *task, isc_event_t *event) {
|
||||
ns_client_t *client;
|
||||
@ -898,13 +909,16 @@ ns_client_wait(ns_client_t *client) {
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
ns_client_shuttingdown(ns_client_t *client) {
|
||||
return (client->shuttingdown);
|
||||
}
|
||||
|
||||
void
|
||||
ns_client_unwait(ns_client_t *client) {
|
||||
isc_boolean_t shuttingdown = client->shuttingdown;
|
||||
client->nwaiting--;
|
||||
INSIST(client->nwaiting >= 0);
|
||||
if (shuttingdown)
|
||||
if (client->shuttingdown)
|
||||
maybe_free(client);
|
||||
return (shuttingdown);
|
||||
}
|
||||
|
||||
/***
|
||||
|
@ -98,10 +98,16 @@ ns_client_destroy(ns_client_t *client);
|
||||
isc_result_t
|
||||
ns_client_newnamebuf(ns_client_t *client);
|
||||
|
||||
isc_boolean_t
|
||||
ns_client_shuttingdown(ns_client_t *client);
|
||||
/*
|
||||
* Return ISC_TRUE iff the client is currently shutting down.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_client_wait(ns_client_t *client);
|
||||
|
||||
isc_boolean_t
|
||||
void
|
||||
ns_client_unwait(ns_client_t *client);
|
||||
|
||||
isc_result_t
|
||||
|
@ -1627,8 +1627,7 @@ static void
|
||||
query_resume(isc_task_t *task, isc_event_t *event) {
|
||||
dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
|
||||
ns_client_t *client;
|
||||
isc_boolean_t want_find, client_shuttingdown;
|
||||
isc_stdtime_t now;
|
||||
isc_boolean_t fetch_cancelled, client_shuttingdown;
|
||||
|
||||
/*
|
||||
* Resume a query after recursion.
|
||||
@ -1640,49 +1639,48 @@ query_resume(isc_task_t *task, isc_event_t *event) {
|
||||
REQUIRE(task == client->task);
|
||||
REQUIRE(RECURSING(client));
|
||||
|
||||
if (devent->fetch == client->query.fetch) {
|
||||
if (devent->fetch != NULL) {
|
||||
/*
|
||||
* This is the fetch we've been waiting for.
|
||||
*/
|
||||
INSIST(devent->fetch == client->query.fetch);
|
||||
client->query.fetch = NULL;
|
||||
want_find = ISC_TRUE;
|
||||
fetch_cancelled = ISC_FALSE;
|
||||
/*
|
||||
* Update client->now, if we can.
|
||||
* Update client->now.
|
||||
*/
|
||||
isc_stdtime_get(&now);
|
||||
isc_stdtime_get(&client->now);
|
||||
} else {
|
||||
/*
|
||||
* This is a fetch completion event for a cancelled fetch.
|
||||
* Clean up and don't resume the find.
|
||||
*/
|
||||
fetch_cancelled = ISC_TRUE;
|
||||
}
|
||||
INSIST(client->query.fetch == NULL);
|
||||
|
||||
client->query.attributes &= ~NS_QUERYATTR_RECURSING;
|
||||
dns_resolver_destroyfetch(client->view->resolver, &devent->fetch);
|
||||
|
||||
/*
|
||||
* If this client is shutting down, or this transaction
|
||||
* has timed out, do not resume the find.
|
||||
*/
|
||||
client_shuttingdown = ns_client_shuttingdown(client);
|
||||
if (fetch_cancelled || client_shuttingdown) {
|
||||
if (devent->node != NULL)
|
||||
dns_db_detachnode(devent->db, &devent->node);
|
||||
if (devent->db != NULL)
|
||||
dns_db_detach(&devent->db);
|
||||
query_putrdataset(client, &devent->rdataset);
|
||||
query_putrdataset(client, &devent->sigrdataset);
|
||||
want_find = ISC_FALSE;
|
||||
}
|
||||
|
||||
client->query.attributes &= ~NS_QUERYATTR_RECURSING;
|
||||
dns_resolver_destroyfetch(client->view->resolver, &devent->fetch);
|
||||
|
||||
/*
|
||||
* XXXRTH If this client is shutting down, or this transaction
|
||||
* has timed out, do not resume the find.
|
||||
*
|
||||
* We should probably have a "unwait" function that
|
||||
* decrements waiting and tells us whether we should continue,
|
||||
* do nothing, or reset the client (resetting would cause the
|
||||
* client to continue with shutdown if it was in shutdown
|
||||
* mode).
|
||||
*/
|
||||
client_shuttingdown = ns_client_unwait(client);
|
||||
if (client_shuttingdown)
|
||||
return;
|
||||
|
||||
if (want_find)
|
||||
isc_event_free(&event);
|
||||
/* This may destroy the client. */
|
||||
ns_client_unwait(client);
|
||||
} else {
|
||||
ns_client_unwait(client);
|
||||
query_find(client, devent);
|
||||
}
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
|
Loading…
x
Reference in New Issue
Block a user