3955. [bug] Notify messages due to changes are no longer queued

behind startup notify messages. [RT #24454]

(cherry picked from commit 319659fc23)
This commit is contained in:
Mark Andrews 2014-09-29 09:32:22 +10:00
parent 65246d9863
commit 538ff82430
5 changed files with 189 additions and 45 deletions

View file

@ -1,3 +1,6 @@
3955. [bug] Notify messages due to changes are no longer queued
behind startup notify messages. [RT #24454]
3954. [bug] Unchecked mutex init in dlz_dlopen_driver.c [RT #37112]
3953. [bug] Don't escape semi-colon in TXT fields. [RT #37159]

View file

@ -405,6 +405,10 @@ typedef struct {
#define DNS_ZONEFLG_THAW 0x08000000U
/* #define DNS_ZONEFLG_XXXXX 0x10000000U XXXMPA unused. */
#define DNS_ZONEFLG_NODELAY 0x20000000U
#define DNS_ZONEFLG_NEEDSTARTUPNOTIFY 0x80000000U /*%< need to send out notify
* due to the zone just
* being loaded for the
* first time. */
#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
#define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
@ -441,6 +445,8 @@ struct dns_zonemgr {
isc_task_t * task;
isc_ratelimiter_t * notifyrl;
isc_ratelimiter_t * refreshrl;
isc_ratelimiter_t * startupnotifyrl;
isc_ratelimiter_t * startuprefreshrl;
isc_rwlock_t rwlock;
isc_mutex_t iolock;
isc_rwlock_t urlock;
@ -453,7 +459,10 @@ struct dns_zonemgr {
/* Configuration data. */
isc_uint32_t transfersin;
isc_uint32_t transfersperns;
unsigned int notifyrate;
unsigned int startupnotifyrate;
unsigned int serialqueryrate;
unsigned int startupserialqueryrate;
/* Locked by iolock */
isc_uint32_t iolimit;
@ -479,9 +488,11 @@ struct dns_notify {
dns_name_t ns;
isc_sockaddr_t dst;
ISC_LINK(dns_notify_t) link;
isc_event_t *event;
};
#define DNS_NOTIFY_NOSOA 0x0001U
#define DNS_NOTIFY_STARTUP 0x0002U
/*%
* dns_stub holds state while performing a 'stub' transfer.
@ -688,6 +699,8 @@ static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
dns_dbnode_t *node, dns_name_t *name,
dns_diff_t *diff);
static void zone_rekey(dns_zone_t *zone);
static void setrl(isc_ratelimiter_t *rl, unsigned int *rate,
unsigned int value);
#define ENTER zone_debuglog(zone, me, 1, "enter")
@ -3737,7 +3750,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
zone_attachdb(zone, db);
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
DNS_ZONE_SETFLAG(zone,
DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
DNS_ZONEFLG_LOADED|
DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
}
result = ISC_R_SUCCESS;
@ -8283,7 +8297,8 @@ zone_maintenance(dns_zone_t *zone) {
* Slaves send notifies before backing up to disk, masters after.
*/
if (zone->type == dns_zone_slave &&
DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
isc_time_compare(&now, &zone->notifytime) >= 0)
zone_notify(zone, &now);
@ -8321,7 +8336,8 @@ zone_maintenance(dns_zone_t *zone) {
*/
switch (zone->type) {
case dns_zone_master:
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
isc_time_compare(&now, &zone->notifytime) >= 0)
zone_notify(zone, &now);
default:
@ -8870,21 +8886,50 @@ dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
}
static isc_boolean_t
notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
isc_sockaddr_t *addr)
{
dns_notify_t *notify;
dns_zonemgr_t *zmgr;
isc_result_t result;
for (notify = ISC_LIST_HEAD(zone->notifies);
notify != NULL;
notify = ISC_LIST_NEXT(notify, link)) {
if (notify->request != NULL)
continue;
if ((flags & DNS_NOTIFY_STARTUP) == 0)
notify->flags &= ~DNS_NOTIFY_STARTUP;
if (name != NULL && dns_name_dynamic(&notify->ns) &&
dns_name_equal(name, &notify->ns))
return (ISC_TRUE);
goto requeue;
if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst))
return (ISC_TRUE);
goto requeue;
}
return (ISC_FALSE);
requeue:
/*
* If we are enqueued on the startup ratelimiter and this is
* not a startup notify, re-enqueue on the normal notify
* ratelimiter.
*/
if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0) {
zmgr = notify->zone->zmgr;
result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl,
notify->event);
if (result != ISC_R_SUCCESS)
return (ISC_TRUE);
result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
notify->zone->task,
&notify->event);
if (result != ISC_R_SUCCESS) {
isc_event_free(&notify->event);
return (ISC_FALSE);
}
}
return (ISC_TRUE);
}
static isc_boolean_t
@ -8979,6 +9024,7 @@ notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
notify->zone = NULL;
notify->find = NULL;
notify->request = NULL;
notify->event = NULL;
isc_sockaddr_any(&notify->dst);
dns_name_init(&notify->ns, NULL);
ISC_LINK_INIT(notify, link);
@ -9054,22 +9100,27 @@ notify_find_address(dns_notify_t *notify) {
static isc_result_t
notify_send_queue(dns_notify_t *notify) {
notify_send_queue(dns_notify_t *notify, isc_boolean_t startup) {
isc_event_t *e;
isc_result_t result;
e = isc_event_allocate(notify->mctx, NULL,
DNS_EVENT_NOTIFYSENDTOADDR,
notify_send_toaddr,
notify, sizeof(isc_event_t));
INSIST(notify->event == NULL);
e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR,
notify_send_toaddr, notify, sizeof(isc_event_t));
if (e == NULL)
return (ISC_R_NOMEMORY);
if (startup)
notify->event = e;
e->ev_arg = notify;
e->ev_sender = NULL;
result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
result = isc_ratelimiter_enqueue(startup
? notify->zone->zmgr->startupnotifyrl
: notify->zone->zmgr->notifyrl,
notify->zone->task, &e);
if (result != ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS) {
isc_event_free(&e);
notify->event = NULL;
}
return (result);
}
@ -9092,6 +9143,8 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
LOCK_ZONE(notify->zone);
notify->event = NULL;
if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
result = ISC_R_CANCELED;
goto cleanup;
@ -9193,6 +9246,8 @@ notify_send(dns_notify_t *notify) {
isc_sockaddr_t dst;
isc_result_t result;
dns_notify_t *new = NULL;
unsigned int flags;
isc_boolean_t startup;
/*
* Zone lock held by caller.
@ -9204,20 +9259,20 @@ notify_send(dns_notify_t *notify) {
ai != NULL;
ai = ISC_LIST_NEXT(ai, publink)) {
dst = ai->sockaddr;
if (notify_isqueued(notify->zone, NULL, &dst))
if (notify_isqueued(notify->zone, notify->flags, NULL, &dst))
continue;
if (notify_isself(notify->zone, &dst))
continue;
new = NULL;
result = notify_create(notify->mctx,
(notify->flags & DNS_NOTIFY_NOSOA),
&new);
flags = notify->flags & DNS_NOTIFY_NOSOA;
result = notify_create(notify->mctx, flags, &new);
if (result != ISC_R_SUCCESS)
goto cleanup;
zone_iattach(notify->zone, &new->zone);
ISC_LIST_APPEND(new->zone->notifies, new, link);
new->dst = dst;
result = notify_send_queue(new);
startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0);
result = notify_send_queue(new, startup);
if (result != ISC_R_SUCCESS)
goto cleanup;
new = NULL;
@ -9263,11 +9318,14 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
dns_notifytype_t notifytype;
unsigned int flags = 0;
isc_boolean_t loggednotify = ISC_FALSE;
isc_boolean_t startup;
REQUIRE(DNS_ZONE_VALID(zone));
LOCK_ZONE(zone);
startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
notifytype = zone->notifytype;
DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
UNLOCK_ZONE(zone);
@ -9291,6 +9349,12 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
flags |= DNS_NOTIFY_NOSOA;
/*
* Record that this was a notify due to starting up.
*/
if (startup)
flags |= DNS_NOTIFY_STARTUP;
/*
* Get SOA RRset.
*/
@ -9334,7 +9398,7 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
LOCK_ZONE(zone);
for (i = 0; i < zone->notifycnt; i++) {
dst = zone->notify[i];
if (notify_isqueued(zone, NULL, &dst))
if (notify_isqueued(zone, flags, NULL, &dst))
continue;
result = notify_create(zone->mctx, flags, &notify);
if (result != ISC_R_SUCCESS)
@ -9342,7 +9406,7 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
zone_iattach(zone, &notify->zone);
notify->dst = dst;
ISC_LIST_APPEND(zone->notifies, notify, link);
result = notify_send_queue(notify);
result = notify_send_queue(notify, startup);
if (result != ISC_R_SUCCESS)
notify_destroy(notify, ISC_TRUE);
if (!loggednotify) {
@ -9392,7 +9456,7 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
}
LOCK_ZONE(zone);
isqueued = notify_isqueued(zone, &ns.name, NULL);
isqueued = notify_isqueued(zone, flags, &ns.name, NULL);
UNLOCK_ZONE(zone);
if (isqueued) {
result = dns_rdataset_next(&nsrdset);
@ -10793,7 +10857,8 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) {
switch (zone->type) {
case dns_zone_master:
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
next = zone->notifytime;
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
@ -11821,9 +11886,12 @@ notify_done(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
if (message != NULL && message->rcode == dns_rcode_formerr &&
(notify->flags & DNS_NOTIFY_NOSOA) == 0) {
isc_boolean_t startup;
notify->flags |= DNS_NOTIFY_NOSOA;
dns_request_destroy(&notify->request);
result = notify_send_queue(notify);
startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0);
result = notify_send_queue(notify, startup);
if (result != ISC_R_SUCCESS)
notify_destroy(notify, ISC_FALSE);
} else {
@ -12849,7 +12917,6 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
{
dns_zonemgr_t *zmgr;
isc_result_t result;
isc_interval_t interval;
zmgr = isc_mem_get(mctx, sizeof(*zmgr));
if (zmgr == NULL)
@ -12864,6 +12931,8 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
zmgr->task = NULL;
zmgr->notifyrl = NULL;
zmgr->refreshrl = NULL;
zmgr->startupnotifyrl = NULL;
zmgr->startuprefreshrl = NULL;
ISC_LIST_INIT(zmgr->zones);
ISC_LIST_INIT(zmgr->waiting_for_xfrin);
ISC_LIST_INIT(zmgr->xfrin_in_progress);
@ -12896,15 +12965,21 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
if (result != ISC_R_SUCCESS)
goto free_notifyrl;
/* default to 20 refresh queries / notifies per second. */
isc_interval_set(&interval, 0, 1000000000/2);
result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
isc_ratelimiter_setpertic(zmgr->notifyrl, 10);
result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
&zmgr->startupnotifyrl);
if (result != ISC_R_SUCCESS)
goto free_refreshrl;
result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
isc_ratelimiter_setpertic(zmgr->refreshrl, 10);
result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
&zmgr->startuprefreshrl);
if (result != ISC_R_SUCCESS)
goto free_startupnotifyrl;
/* default to 20 refresh queries / notifies per second. */
setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20);
setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20);
zmgr->iolimit = 1;
zmgr->ioactive = 0;
@ -12913,7 +12988,7 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
result = isc_mutex_init(&zmgr->iolock);
if (result != ISC_R_SUCCESS)
goto free_refreshrl;
goto free_startuprefreshrl;
zmgr->magic = ZONEMGR_MAGIC;
@ -12924,6 +12999,10 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
free_iolock:
DESTROYLOCK(&zmgr->iolock);
#endif
free_startuprefreshrl:
isc_ratelimiter_detach(&zmgr->startuprefreshrl);
free_startupnotifyrl:
isc_ratelimiter_detach(&zmgr->startupnotifyrl);
free_refreshrl:
isc_ratelimiter_detach(&zmgr->refreshrl);
free_notifyrl:
@ -13097,6 +13176,8 @@ dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
isc_ratelimiter_shutdown(zmgr->notifyrl);
isc_ratelimiter_shutdown(zmgr->refreshrl);
isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
if (zmgr->task != NULL)
isc_task_destroy(&zmgr->task);
@ -13156,6 +13237,8 @@ zonemgr_free(dns_zonemgr_t *zmgr) {
DESTROYLOCK(&zmgr->iolock);
isc_ratelimiter_detach(&zmgr->notifyrl);
isc_ratelimiter_detach(&zmgr->refreshrl);
isc_ratelimiter_detach(&zmgr->startupnotifyrl);
isc_ratelimiter_detach(&zmgr->startuprefreshrl);
isc_rwlock_destroy(&zmgr->urlock);
isc_rwlock_destroy(&zmgr->rwlock);
@ -13517,15 +13600,13 @@ dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
}
#endif
void
dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
static void
setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
isc_interval_t interval;
isc_uint32_t s, ns;
isc_uint32_t pertic;
isc_result_t result;
REQUIRE(DNS_ZONEMGR_VALID(zmgr));
if (value == 0)
value = 1;
@ -13545,15 +13626,26 @@ dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
isc_interval_set(&interval, s, ns);
result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval);
result = isc_ratelimiter_setinterval(rl, &interval);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
isc_ratelimiter_setpertic(zmgr->notifyrl, pertic);
isc_ratelimiter_setpertic(rl, pertic);
result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
isc_ratelimiter_setpertic(zmgr->refreshrl, pertic);
*rate = value;
}
zmgr->serialqueryrate = value;
void
dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
REQUIRE(DNS_ZONEMGR_VALID(zmgr));
setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value);
/* Seperately controlled in BIND 9.11.x */
setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
/* XXXMPA seperate out once we have the code to support this. */
setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value);
}
unsigned int

View file

@ -89,6 +89,16 @@ isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task,
*\li '(*eventp)->ev_sender' to be NULL.
*/
isc_result_t
isc_ratelimiter_dequeue(isc_ratelimiter_t *rl, isc_event_t *event);
/*
* Dequeue a event off the ratelimiter queue.
*
* Returns:
* \li ISC_R_NOTFOUND if the event is no longer linked to the rate limiter.
* \li ISC_R_SUCCESS
*/
void
isc_ratelimiter_shutdown(isc_ratelimiter_t *ratelimiter);
/*%<

View file

@ -79,6 +79,7 @@ isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
result = isc_mutex_init(&rl->lock);
if (result != ISC_R_SUCCESS)
goto free_mem;
result = isc_timer_create(timermgr, isc_timertype_inactive,
NULL, NULL, rl->task, ratelimiter_tick,
rl, &rl->timer);
@ -109,6 +110,10 @@ free_mem:
isc_result_t
isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval) {
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(rl != NULL);
REQUIRE(interval != NULL);
LOCK(&rl->lock);
rl->interval = *interval;
/*
@ -124,6 +129,9 @@ isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval) {
void
isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, isc_uint32_t pertic) {
REQUIRE(rl != NULL);
if (pertic == 0)
pertic = 1;
rl->pertic = pertic;
@ -136,8 +144,9 @@ isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task,
isc_result_t result = ISC_R_SUCCESS;
isc_event_t *ev;
REQUIRE(eventp != NULL && *eventp != NULL);
REQUIRE(rl != NULL);
REQUIRE(task != NULL);
REQUIRE(eventp != NULL && *eventp != NULL);
ev = *eventp;
REQUIRE(ev->ev_sender == NULL);
@ -165,6 +174,22 @@ isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task,
return (result);
}
isc_result_t
isc_ratelimiter_dequeue(isc_ratelimiter_t *rl, isc_event_t *event) {
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(rl != NULL);
REQUIRE(event != NULL);
LOCK(&rl->lock);
if (ISC_LINK_LINKED(event, ev_link))
ISC_LIST_UNLINK(rl->pending, event, ev_link);
else
result = ISC_R_NOTFOUND;
UNLOCK(&rl->lock);
return (result);
}
static void
ratelimiter_tick(isc_task_t *task, isc_event_t *event) {
isc_result_t result = ISC_R_SUCCESS;
@ -211,6 +236,9 @@ void
isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) {
isc_event_t *ev;
isc_task_t *task;
REQUIRE(rl != NULL);
LOCK(&rl->lock);
rl->state = isc_ratelimiter_shuttingdown;
(void)isc_timer_reset(rl->timer, isc_timertype_inactive,
@ -222,6 +250,7 @@ isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) {
isc_task_send(task, &ev);
}
isc_timer_detach(&rl->timer);
/*
* Send an event to our task. The delivery of this event
* indicates that no more timer events will be delivered.
@ -249,6 +278,7 @@ ratelimiter_free(isc_ratelimiter_t *rl) {
void
isc_ratelimiter_attach(isc_ratelimiter_t *source, isc_ratelimiter_t **target) {
REQUIRE(source != NULL);
REQUIRE(target != NULL && *target == NULL);
@ -262,9 +292,13 @@ isc_ratelimiter_attach(isc_ratelimiter_t *source, isc_ratelimiter_t **target) {
void
isc_ratelimiter_detach(isc_ratelimiter_t **rlp) {
isc_ratelimiter_t *rl = *rlp;
isc_ratelimiter_t *rl;
isc_boolean_t free_now = ISC_FALSE;
REQUIRE(rlp != NULL && *rlp != NULL);
rl = *rlp;
LOCK(&rl->lock);
REQUIRE(rl->refs > 0);
rl->refs--;
@ -282,6 +316,8 @@ isc_result_t
isc_ratelimiter_stall(isc_ratelimiter_t *rl) {
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(rl != NULL);
LOCK(&rl->lock);
switch (rl->state) {
case isc_ratelimiter_shuttingdown:
@ -305,6 +341,8 @@ isc_result_t
isc_ratelimiter_release(isc_ratelimiter_t *rl) {
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(rl != NULL);
LOCK(&rl->lock);
switch (rl->state) {
case isc_ratelimiter_shuttingdown:

View file

@ -444,6 +444,7 @@ isc_random_jitter
isc_random_seed
isc_ratelimiter_attach
isc_ratelimiter_create
isc_ratelimiter_dequeue
isc_ratelimiter_detach
isc_ratelimiter_enqueue
isc_ratelimiter_setinterval