mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
Cancel all fetch events in dns_resolver_cancelfetch()
Although 'dns_fetch_t' fetch can have two associated events, one for each of 'DNS_EVENT_FETCHDONE' and 'DNS_EVENT_TRYSTALE' types, the dns_resolver_cancelfetch() function is designed in a way that it expects only one existing event, which it must cancel, and when it happens so that 'stale-answer-client-timeout' is enabled and there are two events, only one of them is canceled, and it results in an assertion in dns_resolver_destroyfetch(), when it finds a dangling event. Change the logic of dns_resolver_cancelfetch() function so that it cancels both the events (if they exist), and in the right order. (cherry picked from commit ec2098ca35039e4f81fd0aa7c525eb960b8f47bf)
This commit is contained in:
parent
72db6402f3
commit
a4fc5e5158
@ -10976,6 +10976,8 @@ dns_resolver_cancelfetch(dns_fetch_t *fetch) {
|
|||||||
fetchctx_t *fctx = NULL;
|
fetchctx_t *fctx = NULL;
|
||||||
dns_resolver_t *res = NULL;
|
dns_resolver_t *res = NULL;
|
||||||
dns_fetchevent_t *event = NULL;
|
dns_fetchevent_t *event = NULL;
|
||||||
|
dns_fetchevent_t *event_trystale = NULL;
|
||||||
|
dns_fetchevent_t *event_fetchdone = NULL;
|
||||||
|
|
||||||
REQUIRE(DNS_FETCH_VALID(fetch));
|
REQUIRE(DNS_FETCH_VALID(fetch));
|
||||||
fctx = fetch->private;
|
fctx = fetch->private;
|
||||||
@ -10987,9 +10989,9 @@ dns_resolver_cancelfetch(dns_fetch_t *fetch) {
|
|||||||
LOCK(&res->buckets[fctx->bucketnum].lock);
|
LOCK(&res->buckets[fctx->bucketnum].lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the completion event for this fetch (as opposed
|
* Find the events for this fetch (as opposed
|
||||||
* to those for other fetches that have joined the same
|
* to those for other fetches that have joined the same
|
||||||
* fctx) and send it with result = ISC_R_CANCELED.
|
* fctx) and send them with result = ISC_R_CANCELED.
|
||||||
*/
|
*/
|
||||||
if (fctx->state != fetchstate_done) {
|
if (fctx->state != fetchstate_done) {
|
||||||
dns_fetchevent_t *next_event = NULL;
|
dns_fetchevent_t *next_event = NULL;
|
||||||
@ -10999,15 +11001,42 @@ dns_resolver_cancelfetch(dns_fetch_t *fetch) {
|
|||||||
next_event = ISC_LIST_NEXT(event, ev_link);
|
next_event = ISC_LIST_NEXT(event, ev_link);
|
||||||
if (event->fetch == fetch) {
|
if (event->fetch == fetch) {
|
||||||
ISC_LIST_UNLINK(fctx->events, event, ev_link);
|
ISC_LIST_UNLINK(fctx->events, event, ev_link);
|
||||||
break;
|
switch (event->ev_type) {
|
||||||
|
case DNS_EVENT_TRYSTALE:
|
||||||
|
INSIST(event_trystale == NULL);
|
||||||
|
event_trystale = event;
|
||||||
|
break;
|
||||||
|
case DNS_EVENT_FETCHDONE:
|
||||||
|
INSIST(event_fetchdone == NULL);
|
||||||
|
event_fetchdone = event;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
if (event_trystale != NULL &&
|
||||||
|
event_fetchdone != NULL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (event != NULL) {
|
/*
|
||||||
isc_task_t *etask = event->ev_sender;
|
* The "trystale" event must be sent before the "fetchdone" event,
|
||||||
event->ev_sender = fctx;
|
* because the latter clears the "recursing" query attribute, which is
|
||||||
event->result = ISC_R_CANCELED;
|
* required by both events (handled by the same callback function).
|
||||||
isc_task_sendanddetach(&etask, ISC_EVENT_PTR(&event));
|
*/
|
||||||
|
if (event_trystale != NULL) {
|
||||||
|
isc_task_t *etask = event_trystale->ev_sender;
|
||||||
|
event_trystale->ev_sender = fctx;
|
||||||
|
event_trystale->result = ISC_R_CANCELED;
|
||||||
|
isc_task_sendanddetach(&etask, ISC_EVENT_PTR(&event_trystale));
|
||||||
|
}
|
||||||
|
if (event_fetchdone != NULL) {
|
||||||
|
isc_task_t *etask = event_fetchdone->ev_sender;
|
||||||
|
event_fetchdone->ev_sender = fctx;
|
||||||
|
event_fetchdone->result = ISC_R_CANCELED;
|
||||||
|
isc_task_sendanddetach(&etask, ISC_EVENT_PTR(&event_fetchdone));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -6236,7 +6236,9 @@ fetch_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
CTRACE(ISC_LOG_DEBUG(3), "fetch_callback");
|
CTRACE(ISC_LOG_DEBUG(3), "fetch_callback");
|
||||||
|
|
||||||
if (event->ev_type == DNS_EVENT_TRYSTALE) {
|
if (event->ev_type == DNS_EVENT_TRYSTALE) {
|
||||||
query_lookup_stale(client);
|
if (devent->result != ISC_R_CANCELED) {
|
||||||
|
query_lookup_stale(client);
|
||||||
|
}
|
||||||
isc_event_free(ISC_EVENT_PTR(&event));
|
isc_event_free(ISC_EVENT_PTR(&event));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user