xref: /netbsd-src/external/mpl/bind/dist/lib/isc/include/isc/quota.h (revision 73d56d5b0be8704e4f0a7e8221a2c7309572c9a1)
1 /*	$NetBSD: quota.h,v 1.7 2020/08/03 17:23:42 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * See the COPYRIGHT file distributed with this work for additional
11  * information regarding copyright ownership.
12  */
13 
14 #ifndef ISC_QUOTA_H
15 #define ISC_QUOTA_H 1
16 
17 /*****
18 ***** Module Info
19 *****/
20 
21 /*! \file isc/quota.h
22  *
23  * \brief The isc_quota_t object is a simple helper object for implementing
24  * quotas on things like the number of simultaneous connections to
25  * a server.  It keeps track of the amount of quota in use, and
26  * encapsulates the locking necessary to allow multiple tasks to
27  * share a quota.
28  */
29 
30 /***
31  *** Imports.
32  ***/
33 
34 #include <isc/atomic.h>
35 #include <isc/lang.h>
36 #include <isc/mutex.h>
37 #include <isc/types.h>
38 
39 /*****
40 ***** Types.
41 *****/
42 
43 ISC_LANG_BEGINDECLS
44 
45 /*% isc_quota_cb - quota callback structure */
46 typedef struct isc_quota_cb isc_quota_cb_t;
47 typedef void (*isc_quota_cb_func_t)(isc_quota_t *quota, void *data);
48 struct isc_quota_cb {
49 	isc_quota_cb_func_t cb_func;
50 	void *		    data;
51 	ISC_LINK(isc_quota_cb_t) link;
52 };
53 
54 /*% isc_quota structure */
55 struct isc_quota {
56 	atomic_uint_fast32_t max;
57 	atomic_uint_fast32_t used;
58 	atomic_uint_fast32_t soft;
59 	atomic_uint_fast32_t waiting;
60 	isc_mutex_t	     cblock;
61 	ISC_LIST(isc_quota_cb_t) cbs;
62 };
63 
64 void
65 isc_quota_init(isc_quota_t *quota, unsigned int max);
66 /*%<
67  * Initialize a quota object.
68  */
69 
70 void
71 isc_quota_destroy(isc_quota_t *quota);
72 /*%<
73  * Destroy a quota object.
74  */
75 
76 void
77 isc_quota_soft(isc_quota_t *quota, unsigned int soft);
78 /*%<
79  * Set a soft quota.
80  */
81 
82 void
83 isc_quota_max(isc_quota_t *quota, unsigned int max);
84 /*%<
85  * Re-set a maximum quota.
86  */
87 
88 unsigned int
89 isc_quota_getmax(isc_quota_t *quota);
90 /*%<
91  * Get the maximum quota.
92  */
93 
94 unsigned int
95 isc_quota_getsoft(isc_quota_t *quota);
96 /*%<
97  * Get the soft quota.
98  */
99 
100 unsigned int
101 isc_quota_getused(isc_quota_t *quota);
102 /*%<
103  * Get the current usage of quota.
104  */
105 
106 isc_result_t
107 isc_quota_attach(isc_quota_t *quota, isc_quota_t **p);
108 /*%<
109  *
110  * Attempt to reserve one unit of 'quota', and also attaches '*p' to the quota
111  * if successful (ISC_R_SUCCESS or ISC_R_SOFTQUOTA).
112  *
113  * Returns:
114  * \li	#ISC_R_SUCCESS		Success
115  * \li	#ISC_R_SOFTQUOTA	Success soft quota reached
116  * \li	#ISC_R_QUOTA		Quota is full
117  */
118 
119 isc_result_t
120 isc_quota_attach_cb(isc_quota_t *quota, isc_quota_t **p, isc_quota_cb_t *cb);
121 /*%<
122  *
123  * Like isc_quota_attach(), but if there's no quota left then cb->cb_func will
124  * be called when we are attached to quota.
125  *
126  * Note: It's the caller's responsibility to make sure that we don't end up
127  * with a huge number of callbacks waiting, making it easy to create a
128  * resource exhaustion attack. For example, in the case of TCP listening,
129  * we simply don't accept new connections when the quota is exceeded, so
130  * the number of callbacks waiting in the queue will be limited by the
131  * listen() backlog.
132  *
133  * Returns:
134  * \li	#ISC_R_SUCCESS		Success
135  * \li	#ISC_R_SOFTQUOTA	Success soft quota reached
136  * \li	#ISC_R_QUOTA		Quota is full
137  */
138 
139 void
140 isc_quota_cb_init(isc_quota_cb_t *cb, isc_quota_cb_func_t cb_func, void *data);
141 /*%<
142  * Initialize isc_quota_cb_t - setup the list, set the callback and data.
143  */
144 
145 void
146 isc_quota_detach(isc_quota_t **p);
147 /*%<
148  * Release one unit of quota, and also detaches '*p' from the quota.
149  */
150 
151 ISC_LANG_ENDDECLS
152 
153 #endif /* ISC_QUOTA_H */
154