From 9ce0ac5dcf9955d9e969005de1a4819275bb7061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 1 Feb 2023 09:52:19 +0100 Subject: [PATCH] EXP: When max-clients-per-query is reached, drop the first event When max-client-per-query value is reached, drop the first event, not the last one. --- lib/dns/resolver.c | 93 +++++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 39 deletions(-) diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 4761e6bf92..c7029ae27e 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -1711,10 +1711,51 @@ fcount_decr(fetchctx_t *fctx) { } } +static void +fctx_sendevent(fetchctx_t *fctx, dns_fetchevent_t *event, isc_result_t result) { + isc_task_t *task; + + ISC_LIST_UNLINK(fctx->events, event, ev_link); + if (event->ev_type == DNS_EVENT_TRYSTALE) { + /* + * Not applicable to TRY STALE events, this function is + * called when the fetch has either completed or timed + * out due to resolver-query-timeout being reached. + */ + isc_task_detach((isc_task_t **)&event->ev_sender); + isc_event_free((isc_event_t **)&event); + return; + } + task = event->ev_sender; + event->ev_sender = fctx; + event->vresult = fctx->vresult; + if (!HAVE_ANSWER(fctx)) { + event->result = result; + } + + INSIST(event->result != ISC_R_SUCCESS || + dns_rdataset_isassociated(event->rdataset) || + fctx->type == dns_rdatatype_any || + fctx->type == dns_rdatatype_rrsig || + fctx->type == dns_rdatatype_sig); + + /* + * Negative results must be indicated in event->result. + */ + if (dns_rdataset_isassociated(event->rdataset) && + NEGATIVE(event->rdataset)) + { + INSIST(event->result == DNS_R_NCACHENXDOMAIN || + event->result == DNS_R_NCACHENXRRSET); + } + + FCTXTRACE("event"); + isc_task_sendanddetach(&task, ISC_EVENT_PTR(&event)); +} + static void fctx_sendevents(fetchctx_t *fctx, isc_result_t result) { dns_fetchevent_t *event, *next_event; - isc_task_t *task; isc_time_t now; /* @@ -1737,42 +1778,8 @@ fctx_sendevents(fetchctx_t *fctx, isc_result_t result) { event = next_event) { next_event = ISC_LIST_NEXT(event, ev_link); - ISC_LIST_UNLINK(fctx->events, event, ev_link); - if (event->ev_type == DNS_EVENT_TRYSTALE) { - /* - * Not applicable to TRY STALE events, this function is - * called when the fetch has either completed or timed - * out due to resolver-query-timeout being reached. - */ - isc_task_detach((isc_task_t **)&event->ev_sender); - isc_event_free((isc_event_t **)&event); - continue; - } - task = event->ev_sender; - event->ev_sender = fctx; - event->vresult = fctx->vresult; - if (!HAVE_ANSWER(fctx)) { - event->result = result; - } - INSIST(event->result != ISC_R_SUCCESS || - dns_rdataset_isassociated(event->rdataset) || - fctx->type == dns_rdatatype_any || - fctx->type == dns_rdatatype_rrsig || - fctx->type == dns_rdatatype_sig); - - /* - * Negative results must be indicated in event->result. - */ - if (dns_rdataset_isassociated(event->rdataset) && - NEGATIVE(event->rdataset)) - { - INSIST(event->result == DNS_R_NCACHENXDOMAIN || - event->result == DNS_R_NCACHENXRRSET); - } - - FCTXTRACE("event"); - isc_task_sendanddetach(&task, ISC_EVENT_PTR(&event)); + fctx_sendevent(fctx, event, result); } UNLOCK(&fctx->lock); } @@ -10579,10 +10586,18 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name, uint_fast32_t spillat = atomic_load_relaxed(&res->spillat); if (spillat != 0 && count >= spillat) { - INSIST(fctx != NULL); + dns_fetchevent_t *event = ISC_LIST_HEAD(fctx->events); + while (event != NULL && event->sigrdataset != NULL) { + event = ISC_LIST_NEXT(event, ev_link); + } + + if (event != NULL) { + fctx_sendevent(fctx, event, DNS_R_DROP); + } else { + result = DNS_R_DROP; + goto unlock; + } fctx->spilled = true; - result = DNS_R_DROP; - goto unlock; } } else { result = fctx_create(res, name, type, domain, nameservers,