xref: /netbsd-src/external/mpl/bind/dist/lib/isc/include/isc/quota.h (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /*	$NetBSD: quota.h,v 1.10 2024/02/21 22:52:31 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/quota.h
23  *
24  * \brief The isc_quota_t object is a simple helper object for implementing
25  * quotas on things like the number of simultaneous connections to
26  * a server.  It keeps track of the amount of quota in use, and
27  * encapsulates the locking necessary to allow multiple tasks to
28  * share a quota.
29  */
30 
31 /***
32  *** Imports.
33  ***/
34 
35 #include <isc/atomic.h>
36 #include <isc/lang.h>
37 #include <isc/magic.h>
38 #include <isc/mutex.h>
39 #include <isc/types.h>
40 
41 /*****
42 ***** Types.
43 *****/
44 
45 ISC_LANG_BEGINDECLS
46 
47 /*% isc_quota_cb - quota callback structure */
48 typedef struct isc_quota_cb isc_quota_cb_t;
49 typedef void (*isc_quota_cb_func_t)(isc_quota_t *quota, void *data);
50 struct isc_quota_cb {
51 	int		    magic;
52 	isc_quota_cb_func_t cb_func;
53 	void		   *data;
54 	ISC_LINK(isc_quota_cb_t) link;
55 };
56 
57 /*% isc_quota structure */
58 struct isc_quota {
59 	int		     magic;
60 	atomic_uint_fast32_t max;
61 	atomic_uint_fast32_t used;
62 	atomic_uint_fast32_t soft;
63 	atomic_uint_fast32_t waiting;
64 	isc_mutex_t	     cblock;
65 	ISC_LIST(isc_quota_cb_t) cbs;
66 	ISC_LINK(isc_quota_t) link;
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