xref: /netbsd-src/external/mpl/bind/dist/lib/isc/include/isc/quota.h (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: quota.h,v 1.11 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/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/job.h>
37 #include <isc/lang.h>
38 #include <isc/magic.h>
39 #include <isc/mutex.h>
40 #include <isc/os.h>
41 #include <isc/refcount.h>
42 #include <isc/types.h>
43 #include <isc/urcu.h>
44 
45 /*****
46 ***** Types.
47 *****/
48 
49 /* Add -DISC_QUOTA_TRACE=1 to CFLAGS for detailed reference tracing */
50 
51 ISC_LANG_BEGINDECLS
52 
53 /*%
54  * isc_quota structure
55  *
56  * NOTE: We are using struct cds_wfcq_head which has an internal
57  * mutex, because we are using enqueue and dequeue, and dequeues need
58  * synchronization between multiple threads (see urcu/wfcqueue.h for
59  * detailed description).
60  */
61 STATIC_ASSERT(ISC_OS_CACHELINE_SIZE >= sizeof(struct __cds_wfcq_head),
62 	      "ISC_OS_CACHELINE_SIZE smaller than "
63 	      "sizeof(struct __cds_wfcq_head)");
64 struct isc_quota {
65 	int		     magic;
66 	atomic_uint_fast32_t max;
67 	atomic_uint_fast32_t used;
68 	atomic_uint_fast32_t soft;
69 	struct {
70 		struct cds_wfcq_head head;
71 		uint8_t		     __padding[ISC_OS_CACHELINE_SIZE -
72 				       sizeof(struct __cds_wfcq_head)];
73 		struct cds_wfcq_tail tail;
74 	} jobs;
75 	ISC_LINK(isc_quota_t) link;
76 };
77 
78 void
79 isc_quota_init(isc_quota_t *quota, unsigned int max);
80 /*%<
81  * Initialize a quota object.
82  */
83 
84 void
85 isc_quota_destroy(isc_quota_t *quota);
86 /*%<
87  * Destroy a quota object.
88  */
89 
90 void
91 isc_quota_soft(isc_quota_t *quota, unsigned int soft);
92 /*%<
93  * Set a soft quota.
94  */
95 
96 void
97 isc_quota_max(isc_quota_t *quota, unsigned int max);
98 /*%<
99  * Re-set a maximum quota.
100  */
101 
102 unsigned int
103 isc_quota_getmax(isc_quota_t *quota);
104 /*%<
105  * Get the maximum quota.
106  */
107 
108 unsigned int
109 isc_quota_getsoft(isc_quota_t *quota);
110 /*%<
111  * Get the soft quota.
112  */
113 
114 unsigned int
115 isc_quota_getused(isc_quota_t *quota);
116 /*%<
117  * Get the current usage of quota.
118  */
119 
120 #define isc_quota_acquire(quota) isc_quota_acquire_cb(quota, NULL, NULL, NULL)
121 isc_result_t
122 isc_quota_acquire_cb(isc_quota_t *quota, isc_job_t *job, isc_job_cb cb,
123 		     void *cbarg);
124 /*%<
125  *
126  * Attempt to reserve one unit of 'quota', if there's no quota left then
127  * cb->cb(cb->cbarg) will be called when there's quota again.
128  *
129  * Note: It's the caller's responsibility to make sure that we don't end up
130  * with a huge number of callbacks waiting, making it easy to create a
131  * resource exhaustion attack. For example, in the case of TCP listening,
132  * we simply don't accept new connections when the quota is exceeded, so
133  * the number of callbacks waiting in the queue will be limited by the
134  * listen() backlog.
135  *
136  * Returns:
137  * \li	#ISC_R_SUCCESS		Success
138  * \li	#ISC_R_SOFTQUOTA	Success soft quota reached
139  * \li	#ISC_R_QUOTA		Quota is full
140  */
141 
142 void
143 isc_quota_release(isc_quota_t *quota);
144 /*%<
145  * Release one unit of quota.
146  */
147 
148 ISC_LANG_ENDDECLS
149