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