Home | History | Annotate | Line # | Download | only in isc
      1 /*	$NetBSD: ratelimiter.h,v 1.8 2025/01/26 16:25:42 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 #pragma once
     17 
     18 /*****
     19 ***** Module Info
     20 *****/
     21 
     22 /*! \file isc/ratelimiter.h
     23  * \brief A rate limiter is a mechanism for dispatching events at a limited
     24  * rate.  This is intended to be used when sending zone maintenance
     25  * SOA queries, NOTIFY messages, etc.
     26  */
     27 
     28 /***
     29  *** Imports.
     30  ***/
     31 
     32 #include <inttypes.h>
     33 #include <stdbool.h>
     34 
     35 #include <isc/lang.h>
     36 #include <isc/loop.h>
     37 #include <isc/time.h>
     38 #include <isc/types.h>
     39 
     40 struct isc_rlevent {
     41 	isc_loop_t	  *loop;
     42 	isc_ratelimiter_t *rl;
     43 	bool		   canceled;
     44 	isc_job_cb	   cb;
     45 	void		  *arg;
     46 	ISC_LINK(isc_rlevent_t) link;
     47 };
     48 
     49 ISC_LANG_BEGINDECLS
     50 
     51 /*****
     52 ***** Functions.
     53 *****/
     54 
     55 void
     56 isc_ratelimiter_create(isc_loop_t *loop, isc_ratelimiter_t **rlp);
     57 /*%<
     58  * Create a rate limiter.  The execution interval is initially undefined.
     59  */
     60 
     61 void
     62 isc_ratelimiter_setinterval(isc_ratelimiter_t *restrict rl,
     63 			    const isc_interval_t *const interval);
     64 /*!<
     65  * Set the minimum interval between event executions.
     66  * The interval value is copied, so the caller need not preserve it.
     67  *
     68  * Requires:
     69  *	'*interval' is a nonzero interval.
     70  */
     71 
     72 void
     73 isc_ratelimiter_setpertic(isc_ratelimiter_t *restrict rl,
     74 			  const uint32_t perint);
     75 /*%<
     76  * Set the number of events processed per interval timer tick.
     77  * If 'perint' is zero it is treated as 1.
     78  */
     79 
     80 void
     81 isc_ratelimiter_setpushpop(isc_ratelimiter_t *restrict rl, const bool pushpop);
     82 /*%<
     83  * Set / clear the ratelimiter to from push pop mode rather
     84  * first in - first out mode (default).
     85  */
     86 
     87 isc_result_t
     88 isc_ratelimiter_enqueue(isc_ratelimiter_t *restrict rl,
     89 			isc_loop_t *restrict loop, isc_job_cb cb, void *arg,
     90 			isc_rlevent_t **rlep);
     91 /*%<
     92  * Queue an event for rate-limited execution.
     93  *
     94  * This is similar to doing an isc_async_run() to the 'loop', except
     95  * that the execution may be delayed to achieve the desired rate of
     96  * execution.
     97  *
     98  * '*rlep' will be set to point to an allocated ratelimiter event,
     99  * which can be freed by the caller using isc_rlevent_free() when the
    100  * event fires, or by dequeueing.
    101  *
    102  * Requires:
    103  *\li	'rl' is a valid ratelimiter.
    104  *\li	'loop ' is non NULL.
    105  *\li	'rlep' is non NULL and '*rlep' is NULL.
    106  */
    107 
    108 isc_result_t
    109 isc_ratelimiter_dequeue(isc_ratelimiter_t *restrict rl,
    110 			isc_rlevent_t **rleventp);
    111 /*
    112  * Dequeue a event off the ratelimiter queue. If the event has not already
    113  * been posted, it will be freed and '*rleventp' will be set to NULL.
    114  *
    115  * Returns:
    116  * \li	ISC_R_NOTFOUND if the event is no longer linked to the rate limiter.
    117  * \li	ISC_R_SUCCESS
    118  */
    119 
    120 void
    121 isc_ratelimiter_shutdown(isc_ratelimiter_t *restrict rl);
    122 /*%<
    123  * Shut down a rate limiter.
    124  *
    125  * Ensures:
    126  *\li	All pending events are dispatched immediately with
    127  *	rle->canceled set to true.
    128  *
    129  *\li	Further attempts to enqueue events will fail with
    130  *	#ISC_R_SHUTTINGDOWN.
    131  */
    132 
    133 void
    134 isc_rlevent_free(isc_rlevent_t **rlep);
    135 /*%<
    136  * Free the rate limiter event '*rlep'.
    137  */
    138 
    139 ISC_REFCOUNT_DECL(isc_ratelimiter);
    140 /*%<
    141  * The rate limiter reference counting.
    142  */
    143 
    144 ISC_LANG_ENDDECLS
    145