]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3955. [bug] Notify messages due to changes are no longer queued
authorMark Andrews <marka@isc.org>
Sun, 28 Sep 2014 23:32:22 +0000 (09:32 +1000)
committerMark Andrews <marka@isc.org>
Sun, 28 Sep 2014 23:52:54 +0000 (09:52 +1000)
                        behind startup notify messages. [RT #24454]

(cherry picked from commit 319659fc230ea1215afc08e880fb93a35830ee13)

CHANGES
lib/dns/zone.c
lib/isc/include/isc/ratelimiter.h
lib/isc/ratelimiter.c
lib/isc/win32/libisc.def.in

diff --git a/CHANGES b/CHANGES
index 58d9a553909f28d0364cd1cda93c34e91abd2d03..36f35807a67140176f7965e2e7637a2edf4167f1 100644 (file)
--- 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]
index 45b366c242325c6ed8fd9114bcb729d64e369530..bfb2813e4599d9ef098d50b8caff3c0fb6beaf7f 100644 (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;
+}
+
+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
index 00a7209758bbc70bd34c78a5338865f5b38cddbf..670a1274b85e960e79d6c3bd528a2b632b5dab81 100644 (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);
 /*%<
index fc66e9f61efb4ffad90901bc0c084beadd6dd9ee..0273b8137006bee3d9a0279889ac54c756ef49e3 100644 (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:
index 8ea9fd82efbede5581e694c18dc8c69314415c95..73110815518908013efa29da99df5d2d110d1379 100644 (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