From: Mark Andrews Date: Sun, 28 Sep 2014 23:32:22 +0000 (+1000) Subject: 3955. [bug] Notify messages due to changes are no longer queued X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=538ff824300d87137978ccde830770ac8370492a;p=thirdparty%2Fbind9.git 3955. [bug] Notify messages due to changes are no longer queued behind startup notify messages. [RT #24454] (cherry picked from commit 319659fc230ea1215afc08e880fb93a35830ee13) --- diff --git a/CHANGES b/CHANGES index 58d9a553909..36f35807a67 100644 --- a/CHANGES +++ b/CHANGES @@ -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] diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 45b366c2423..bfb2813e459 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -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(¬ify->ns) && dns_name_equal(name, ¬ify->ns)) - return (ISC_TRUE); + goto requeue; if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->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, + ¬ify->event); + if (result != ISC_R_SUCCESS) { + isc_event_free(¬ify->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(¬ify->dst); dns_name_init(¬ify->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, ¬ify); if (result != ISC_R_SUCCESS) @@ -9342,7 +9406,7 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) { zone_iattach(zone, ¬ify->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(¬ify->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; +} + +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); - zmgr->serialqueryrate = value; + /* XXXMPA seperate out once we have the code to support this. */ + setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value); } unsigned int diff --git a/lib/isc/include/isc/ratelimiter.h b/lib/isc/include/isc/ratelimiter.h index 00a7209758b..670a1274b85 100644 --- a/lib/isc/include/isc/ratelimiter.h +++ b/lib/isc/include/isc/ratelimiter.h @@ -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); /*%< diff --git a/lib/isc/ratelimiter.c b/lib/isc/ratelimiter.c index fc66e9f61ef..0273b813700 100644 --- a/lib/isc/ratelimiter.c +++ b/lib/isc/ratelimiter.c @@ -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: diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 8ea9fd82efb..73110815518 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -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