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