diff --git a/CHANGES b/CHANGES index bafd2e405e..c177a44dd5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4438. [func] Use LIFO rather than FIFO when processing startup + notify and refresh queries. [RT #42825] + 4437. [func] Minimal-responses now has two additional modes no-auth and no-auth-recursive which suppress adding the NS records to the authority section diff --git a/lib/dns/zone.c b/lib/dns/zone.c index a12a1eb599..d59e719eef 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15567,6 +15567,8 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20); setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20); setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20); + isc_ratelimiter_setpushpop(zmgr->startupnotifyrl, ISC_TRUE); + isc_ratelimiter_setpushpop(zmgr->startuprefreshrl, ISC_TRUE); zmgr->iolimit = 1; zmgr->ioactive = 0; diff --git a/lib/isc/include/isc/ratelimiter.h b/lib/isc/include/isc/ratelimiter.h index c44a367fb8..9cc4111142 100644 --- a/lib/isc/include/isc/ratelimiter.h +++ b/lib/isc/include/isc/ratelimiter.h @@ -58,6 +58,13 @@ isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, isc_uint32_t perint); * If 'perint' is zero it is treated as 1. */ +void +isc_ratelimiter_setpushpop(isc_ratelimiter_t *rl, isc_boolean_t pushpop); +/*%< + * Set / clear the ratelimiter to from push pop mode rather + * first in - first out mode (default). + */ + isc_result_t isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task, isc_event_t **eventp); diff --git a/lib/isc/ratelimiter.c b/lib/isc/ratelimiter.c index 8327f484c0..f78b93018f 100644 --- a/lib/isc/ratelimiter.c +++ b/lib/isc/ratelimiter.c @@ -34,6 +34,7 @@ struct isc_ratelimiter { isc_timer_t * timer; isc_interval_t interval; isc_uint32_t pertic; + isc_boolean_t pushpop; isc_ratelimiter_state_t state; isc_event_t shutdownevent; ISC_LIST(isc_event_t) pending; @@ -64,6 +65,7 @@ isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr, isc_interval_set(&rl->interval, 0, 0); rl->timer = NULL; rl->pertic = 1; + rl->pushpop = ISC_FALSE; rl->state = isc_ratelimiter_idle; ISC_LIST_INIT(rl->pending); @@ -128,6 +130,14 @@ isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, isc_uint32_t pertic) { rl->pertic = pertic; } +void +isc_ratelimiter_setpushpop(isc_ratelimiter_t *rl, isc_boolean_t pushpop) { + + REQUIRE(rl != NULL); + + rl->pushpop = pushpop; +} + isc_result_t isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task, isc_event_t **eventp) @@ -146,7 +156,10 @@ isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task, rl->state == isc_ratelimiter_stalled) { ev->ev_sender = task; *eventp = NULL; - ISC_LIST_APPEND(rl->pending, ev, ev_link); + if (rl->pushpop) + ISC_LIST_PREPEND(rl->pending, ev, ev_link); + else + ISC_LIST_APPEND(rl->pending, ev, ev_link); } else if (rl->state == isc_ratelimiter_idle) { result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL, &rl->interval, ISC_FALSE);