summaryrefslogtreecommitdiff
path: root/usr.sbin/bind/lib/isc/ratelimiter.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bind/lib/isc/ratelimiter.c')
-rw-r--r--usr.sbin/bind/lib/isc/ratelimiter.c84
1 files changed, 67 insertions, 17 deletions
diff --git a/usr.sbin/bind/lib/isc/ratelimiter.c b/usr.sbin/bind/lib/isc/ratelimiter.c
index 5794e5a095c..3b7de219563 100644
--- a/usr.sbin/bind/lib/isc/ratelimiter.c
+++ b/usr.sbin/bind/lib/isc/ratelimiter.c
@@ -1,21 +1,21 @@
/*
- * Copyright (C) 1999-2001 Internet Software Consortium.
+ * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: ratelimiter.c,v 1.18 2001/01/09 21:56:23 bwelling Exp $ */
+/* $ISC: ratelimiter.c,v 1.18.14.4 2004/03/08 09:04:50 marka Exp $ */
#include <config.h>
@@ -27,9 +27,10 @@
#include <isc/util.h>
typedef enum {
- isc_ratelimiter_ratelimited,
- isc_ratelimiter_worklimited,
- isc_ratelimiter_shuttingdown
+ isc_ratelimiter_stalled = 0,
+ isc_ratelimiter_ratelimited = 1,
+ isc_ratelimiter_idle = 2,
+ isc_ratelimiter_shuttingdown = 3
} isc_ratelimiter_state_t;
struct isc_ratelimiter {
@@ -70,7 +71,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->state = isc_ratelimiter_worklimited;
+ rl->state = isc_ratelimiter_idle;
ISC_LIST_INIT(rl->pending);
result = isc_mutex_init(&rl->lock);
@@ -139,12 +140,13 @@ isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task,
REQUIRE(ev->ev_sender == NULL);
LOCK(&rl->lock);
- if (rl->state == isc_ratelimiter_ratelimited) {
+ if (rl->state == isc_ratelimiter_ratelimited ||
+ rl->state == isc_ratelimiter_stalled) {
isc_event_t *ev = *eventp;
ev->ev_sender = task;
ISC_LIST_APPEND(rl->pending, ev, ev_link);
*eventp = NULL;
- } else if (rl->state == isc_ratelimiter_worklimited) {
+ } else if (rl->state == isc_ratelimiter_idle) {
result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL,
&rl->interval, ISC_FALSE);
if (result == ISC_R_SUCCESS) {
@@ -191,7 +193,7 @@ ratelimiter_tick(isc_task_t *task, isc_event_t *event) {
isc_timertype_inactive,
NULL, NULL, ISC_FALSE);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
- rl->state = isc_ratelimiter_worklimited;
+ rl->state = isc_ratelimiter_idle;
pertic = 0; /* Force the loop to exit. */
}
UNLOCK(&rl->lock);
@@ -274,3 +276,51 @@ isc_ratelimiter_detach(isc_ratelimiter_t **rlp) {
*rlp = NULL;
}
+isc_result_t
+isc_ratelimiter_stall(isc_ratelimiter_t *rl) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ LOCK(&rl->lock);
+ switch (rl->state) {
+ case isc_ratelimiter_shuttingdown:
+ result = ISC_R_SHUTTINGDOWN;
+ break;
+ case isc_ratelimiter_ratelimited:
+ result = isc_timer_reset(rl->timer, isc_timertype_inactive,
+ NULL, NULL, ISC_FALSE);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ case isc_ratelimiter_idle:
+ case isc_ratelimiter_stalled:
+ rl->state = isc_ratelimiter_stalled;
+ break;
+ }
+ UNLOCK(&rl->lock);
+ return (result);
+}
+
+isc_result_t
+isc_ratelimiter_release(isc_ratelimiter_t *rl) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ LOCK(&rl->lock);
+ switch (rl->state) {
+ case isc_ratelimiter_shuttingdown:
+ result = ISC_R_SHUTTINGDOWN;
+ break;
+ case isc_ratelimiter_stalled:
+ if (!ISC_LIST_EMPTY(rl->pending)) {
+ result = isc_timer_reset(rl->timer,
+ isc_timertype_ticker, NULL,
+ &rl->interval, ISC_FALSE);
+ if (result == ISC_R_SUCCESS)
+ rl->state = isc_ratelimiter_ratelimited;
+ } else
+ rl->state = isc_ratelimiter_idle;
+ break;
+ case isc_ratelimiter_ratelimited:
+ case isc_ratelimiter_idle:
+ break;
+ }
+ UNLOCK(&rl->lock);
+ return (result);
+}