xref: /src/contrib/libevent/ratelim-internal.h (revision c6879c6c14eedbd060ba588a3129a6c60ebbe783)
1cbc620a4SEd Maste /*
2cbc620a4SEd Maste  * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
3cbc620a4SEd Maste  *
4cbc620a4SEd Maste  * Redistribution and use in source and binary forms, with or without
5cbc620a4SEd Maste  * modification, are permitted provided that the following conditions
6cbc620a4SEd Maste  * are met:
7cbc620a4SEd Maste  * 1. Redistributions of source code must retain the above copyright
8cbc620a4SEd Maste  *    notice, this list of conditions and the following disclaimer.
9cbc620a4SEd Maste  * 2. Redistributions in binary form must reproduce the above copyright
10cbc620a4SEd Maste  *    notice, this list of conditions and the following disclaimer in the
11cbc620a4SEd Maste  *    documentation and/or other materials provided with the distribution.
12cbc620a4SEd Maste  * 3. The name of the author may not be used to endorse or promote products
13cbc620a4SEd Maste  *    derived from this software without specific prior written permission.
14cbc620a4SEd Maste  *
15cbc620a4SEd Maste  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16cbc620a4SEd Maste  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17cbc620a4SEd Maste  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18cbc620a4SEd Maste  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19cbc620a4SEd Maste  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20cbc620a4SEd Maste  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21cbc620a4SEd Maste  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22cbc620a4SEd Maste  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23cbc620a4SEd Maste  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24cbc620a4SEd Maste  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25cbc620a4SEd Maste  */
26cbc620a4SEd Maste #ifndef RATELIM_INTERNAL_H_INCLUDED_
27cbc620a4SEd Maste #define RATELIM_INTERNAL_H_INCLUDED_
28cbc620a4SEd Maste 
29cbc620a4SEd Maste #ifdef __cplusplus
30cbc620a4SEd Maste extern "C" {
31cbc620a4SEd Maste #endif
32cbc620a4SEd Maste 
33cbc620a4SEd Maste #include "event2/util.h"
34cbc620a4SEd Maste 
35cbc620a4SEd Maste /** A token bucket is an internal structure that tracks how many bytes we are
36cbc620a4SEd Maste  * currently willing to read or write on a given bufferevent or group of
37cbc620a4SEd Maste  * bufferevents */
38cbc620a4SEd Maste struct ev_token_bucket {
39cbc620a4SEd Maste 	/** How many bytes are we willing to read or write right now? These
40cbc620a4SEd Maste 	 * values are signed so that we can do "defecit spending" */
41cbc620a4SEd Maste 	ev_ssize_t read_limit, write_limit;
42cbc620a4SEd Maste 	/** When was this bucket last updated?  Measured in abstract 'ticks'
43cbc620a4SEd Maste 	 * relative to the token bucket configuration. */
44cbc620a4SEd Maste 	ev_uint32_t last_updated;
45cbc620a4SEd Maste };
46cbc620a4SEd Maste 
47cbc620a4SEd Maste /** Configuration info for a token bucket or set of token buckets. */
48cbc620a4SEd Maste struct ev_token_bucket_cfg {
49cbc620a4SEd Maste 	/** How many bytes are we willing to read on average per tick? */
50cbc620a4SEd Maste 	size_t read_rate;
51cbc620a4SEd Maste 	/** How many bytes are we willing to read at most in any one tick? */
52cbc620a4SEd Maste 	size_t read_maximum;
53cbc620a4SEd Maste 	/** How many bytes are we willing to write on average per tick? */
54cbc620a4SEd Maste 	size_t write_rate;
55cbc620a4SEd Maste 	/** How many bytes are we willing to write at most in any one tick? */
56cbc620a4SEd Maste 	size_t write_maximum;
57cbc620a4SEd Maste 
58cbc620a4SEd Maste 	/* How long is a tick?  Note that fractions of a millisecond are
59cbc620a4SEd Maste 	 * ignored. */
60cbc620a4SEd Maste 	struct timeval tick_timeout;
61cbc620a4SEd Maste 
62cbc620a4SEd Maste 	/* How long is a tick, in milliseconds?  Derived from tick_timeout. */
63cbc620a4SEd Maste 	unsigned msec_per_tick;
64cbc620a4SEd Maste };
65cbc620a4SEd Maste 
66cbc620a4SEd Maste /** The current tick is 'current_tick': add bytes to 'bucket' as specified in
67cbc620a4SEd Maste  * 'cfg'. */
68cbc620a4SEd Maste int ev_token_bucket_update_(struct ev_token_bucket *bucket,
69cbc620a4SEd Maste     const struct ev_token_bucket_cfg *cfg,
70cbc620a4SEd Maste     ev_uint32_t current_tick);
71cbc620a4SEd Maste 
72cbc620a4SEd Maste /** In which tick does 'tv' fall according to 'cfg'?  Note that ticks can
73cbc620a4SEd Maste  * overflow easily; your code needs to handle this. */
74cbc620a4SEd Maste ev_uint32_t ev_token_bucket_get_tick_(const struct timeval *tv,
75cbc620a4SEd Maste     const struct ev_token_bucket_cfg *cfg);
76cbc620a4SEd Maste 
77cbc620a4SEd Maste /** Adjust 'bucket' to respect 'cfg', and note that it was last updated in
78cbc620a4SEd Maste  * 'current_tick'.  If 'reinitialize' is true, we are changing the
79cbc620a4SEd Maste  * configuration of 'bucket'; otherwise, we are setting it up for the first
80cbc620a4SEd Maste  * time.
81cbc620a4SEd Maste  */
82cbc620a4SEd Maste int ev_token_bucket_init_(struct ev_token_bucket *bucket,
83cbc620a4SEd Maste     const struct ev_token_bucket_cfg *cfg,
84cbc620a4SEd Maste     ev_uint32_t current_tick,
85cbc620a4SEd Maste     int reinitialize);
86cbc620a4SEd Maste 
87cbc620a4SEd Maste int bufferevent_remove_from_rate_limit_group_internal_(struct bufferevent *bev,
88cbc620a4SEd Maste     int unsuspend);
89cbc620a4SEd Maste 
90cbc620a4SEd Maste /** Decrease the read limit of 'b' by 'n' bytes */
91cbc620a4SEd Maste #define ev_token_bucket_decrement_read(b,n)	\
92cbc620a4SEd Maste 	do {					\
93cbc620a4SEd Maste 		(b)->read_limit -= (n);		\
94cbc620a4SEd Maste 	} while (0)
95cbc620a4SEd Maste /** Decrease the write limit of 'b' by 'n' bytes */
96cbc620a4SEd Maste #define ev_token_bucket_decrement_write(b,n)	\
97cbc620a4SEd Maste 	do {					\
98cbc620a4SEd Maste 		(b)->write_limit -= (n);	\
99cbc620a4SEd Maste 	} while (0)
100cbc620a4SEd Maste 
101cbc620a4SEd Maste #ifdef __cplusplus
102cbc620a4SEd Maste }
103cbc620a4SEd Maste #endif
104cbc620a4SEd Maste 
105cbc620a4SEd Maste #endif
106