mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
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:
parent
65246d9863
commit
538ff82430
5 changed files with 189 additions and 45 deletions
3
CHANGES
3
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]
|
||||
|
|
|
|||
178
lib/dns/zone.c
178
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
/*%<
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue