gnunet_bandwidth_lib.h (9989B)
1 /* 2 This file is part of GNUnet. 3 Copyright (C) 2010 GNUnet e.V. 4 5 GNUnet is free software: you can redistribute it and/or modify it 6 under the terms of the GNU Affero General Public License as published 7 by the Free Software Foundation, either version 3 of the License, 8 or (at your option) any later version. 9 10 GNUnet is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Affero General Public License for more details. 14 15 You should have received a copy of the GNU Affero General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 SPDX-License-Identifier: AGPL3.0-or-later 19 */ 20 21 /** 22 * @addtogroup libgnunetutil 23 * Multi-function utilities library for GNUnet programs 24 * @{ 25 * 26 * @author Christian Grothoff 27 * 28 * @file 29 * Functions related to bandwidth (unit) 30 * 31 * @defgroup bandwidth Bandwidth library 32 * Functions related to bandwidth (unit) 33 * @{ 34 */ 35 36 #if !defined (__GNUNET_UTIL_LIB_H_INSIDE__) 37 #error "Only <gnunet_util_lib.h> can be included directly." 38 #endif 39 40 #ifndef GNUNET_BANDWIDTH_LIB_H 41 #define GNUNET_BANDWIDTH_LIB_H 42 43 #ifdef __cplusplus 44 extern "C" { 45 #if 0 /* keep Emacsens' auto-indent happy */ 46 } 47 #endif 48 #endif 49 50 51 #include "gnunet_time_lib.h" 52 53 GNUNET_NETWORK_STRUCT_BEGIN 54 55 /** 56 * 32-bit bandwidth used for network exchange by GNUnet, in bytes per second. 57 */ 58 struct GNUNET_BANDWIDTH_Value32NBO 59 { 60 /** 61 * The actual value (bytes per second). 62 */ 63 uint32_t value__ GNUNET_PACKED; 64 }; 65 66 GNUNET_NETWORK_STRUCT_END 67 68 69 /** 70 * Callback to be called by the bandwidth tracker if the tracker 71 * was updated and the client should update it's delay values 72 * 73 * @param cls a closure to pass 74 */ 75 typedef void (*GNUNET_BANDWIDTH_TrackerUpdateCallback) (void *cls); 76 77 78 /** 79 * Callback to be called by the bandwidth tracker if the tracker 80 * was updated and the client should update it's delay values 81 * 82 * @param cls a closure to pass 83 */ 84 typedef void (*GNUNET_BANDWIDTH_ExcessNotificationCallback) (void *cls); 85 86 87 /** 88 * Struct to track available bandwidth. Combines a time stamp with a 89 * number of bytes transmitted, a quota and a maximum amount that 90 * carries over. Not opaque so that it can be inlined into data 91 * structures (reducing malloc-ing); however, values should not be 92 * accessed directly by clients (hence the '__'). 93 */ 94 struct GNUNET_BANDWIDTH_Tracker 95 { 96 /** 97 * Closure for @e update_cb. 98 */ 99 void *update_cb_cls; 100 101 /** 102 * Function we call if the tracker's bandwidth is increased and a 103 * previously returned timeout might now expire earlier. 104 */ 105 GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb; 106 107 /** 108 * Closure for @e excess_cb. 109 */ 110 void *excess_cb_cls; 111 112 /** 113 * Function we call if the tracker is about to throw 114 * away bandwidth due to excess (max carry exceeded). 115 */ 116 GNUNET_BANDWIDTH_ExcessNotificationCallback excess_cb; 117 118 /** 119 * Number of bytes consumed since we last updated the tracker. 120 */ 121 int64_t consumption_since_last_update__; 122 123 /** 124 * Task scheduled to call the @e excess_cb once we have 125 * reached the maximum bandwidth the tracker can hold. 126 */ 127 struct GNUNET_SCHEDULER_Task *excess_task; 128 129 /** 130 * Time when we last updated the tracker. 131 */ 132 struct GNUNET_TIME_Absolute last_update__; 133 134 /** 135 * Bandwidth limit to enforce in bytes per second. 136 */ 137 uint32_t available_bytes_per_s__; 138 139 /** 140 * Maximum number of seconds over which bandwidth may "accumulate". 141 * Note that additionally, we also always allow at least 142 * #GNUNET_MAX_MESSAGE_SIZE to accumulate. 143 */ 144 uint32_t max_carry_s__; 145 }; 146 147 148 /** 149 * Convenience definition to use for 0-bandwidth. 150 */ 151 #define GNUNET_BANDWIDTH_ZERO GNUNET_BANDWIDTH_value_init (0) 152 153 154 /** 155 * Create a new bandwidth value. 156 * 157 * @param bytes_per_second value to create 158 * @return the new bandwidth value 159 */ 160 struct GNUNET_BANDWIDTH_Value32NBO 161 GNUNET_BANDWIDTH_value_init (uint32_t bytes_per_second); 162 163 164 /** 165 * Maximum possible bandwidth value. 166 */ 167 #define GNUNET_BANDWIDTH_VALUE_MAX GNUNET_BANDWIDTH_value_init (UINT32_MAX) 168 169 170 /** 171 * At the given bandwidth, calculate how much traffic will be 172 * available until the given deadline. 173 * 174 * @param bps bandwidth 175 * @param deadline when is the deadline 176 * @return number of bytes available at bps until deadline 177 */ 178 uint64_t 179 GNUNET_BANDWIDTH_value_get_available_until ( 180 struct GNUNET_BANDWIDTH_Value32NBO bps, 181 struct GNUNET_TIME_Relative deadline); 182 183 184 /** 185 * At the given bandwidth, calculate how long it would take for 186 * 'size' bytes to be transmitted. 187 * 188 * @param bps bandwidth 189 * @param size number of bytes we want to have available 190 * @return how long it would take 191 */ 192 struct GNUNET_TIME_Relative 193 GNUNET_BANDWIDTH_value_get_delay_for (struct GNUNET_BANDWIDTH_Value32NBO bps, 194 uint64_t size); 195 196 197 /** 198 * Compute the MIN of two bandwidth values. 199 * 200 * @param b1 first value 201 * @param b2 second value 202 * @return the min of b1 and b2 203 */ 204 struct GNUNET_BANDWIDTH_Value32NBO 205 GNUNET_BANDWIDTH_value_min (struct GNUNET_BANDWIDTH_Value32NBO b1, 206 struct GNUNET_BANDWIDTH_Value32NBO b2); 207 208 209 /** 210 * Compute the MAX of two bandwidth values. 211 * 212 * @param b1 first value 213 * @param b2 second value 214 * @return the min of b1 and b2 215 */ 216 struct GNUNET_BANDWIDTH_Value32NBO 217 GNUNET_BANDWIDTH_value_max (struct GNUNET_BANDWIDTH_Value32NBO b1, 218 struct GNUNET_BANDWIDTH_Value32NBO b2); 219 220 221 /** 222 * Compute the SUM of two bandwidth values. 223 * 224 * @param b1 first value 225 * @param b2 second value 226 * @return the sum of b1 and b2 227 */ 228 struct GNUNET_BANDWIDTH_Value32NBO 229 GNUNET_BANDWIDTH_value_sum (struct GNUNET_BANDWIDTH_Value32NBO b1, 230 struct GNUNET_BANDWIDTH_Value32NBO b2); 231 232 233 /** 234 * Initialize bandwidth tracker. Note that in addition to the 235 * 'max_carry_s' limit, we also always allow at least 236 * #GNUNET_MAX_MESSAGE_SIZE to accumulate. So if the 237 * bytes-per-second limit is so small that within 'max_carry_s' not 238 * even #GNUNET_MAX_MESSAGE_SIZE is allowed to accumulate, it is 239 * ignored and replaced by #GNUNET_MAX_MESSAGE_SIZE (which is in 240 * bytes). 241 * 242 * @param av tracker to initialize 243 * @param update_cb callback to notify a client about the tracker being updated 244 * @param update_cb_cls cls for the @a update_cb callback 245 * @param bytes_per_second_limit initial limit to assume 246 * @param max_carry_s maximum number of seconds unused bandwidth 247 * may accumulate before it expires 248 */ 249 void 250 GNUNET_BANDWIDTH_tracker_init ( 251 struct GNUNET_BANDWIDTH_Tracker *av, 252 GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb, 253 void *update_cb_cls, 254 struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit, 255 uint32_t max_carry_s); 256 257 258 /** 259 * Initialize bandwidth tracker. Note that in addition to the 260 * 'max_carry_s' limit, we also always allow at least 261 * #GNUNET_MAX_MESSAGE_SIZE to accumulate. So if the 262 * bytes-per-second limit is so small that within 'max_carry_s' not 263 * even #GNUNET_MAX_MESSAGE_SIZE is allowed to accumulate, it is 264 * ignored and replaced by #GNUNET_MAX_MESSAGE_SIZE (which is in 265 * bytes). 266 * 267 * @param av tracker to initialize 268 * @param update_cb callback to notify a client about the tracker being updated 269 * @param update_cb_cls cls for the @a update_cb callback 270 * @param bytes_per_second_limit initial limit to assume 271 * @param max_carry_s maximum number of seconds unused bandwidth 272 * may accumulate before it expires 273 * @param excess_cb callback to notify if we have excess bandwidth 274 * @param excess_cb_cls closure for @a excess_cb 275 */ 276 void 277 GNUNET_BANDWIDTH_tracker_init2 ( 278 struct GNUNET_BANDWIDTH_Tracker *av, 279 GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb, 280 void *update_cb_cls, 281 struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit, 282 uint32_t max_carry_s, 283 GNUNET_BANDWIDTH_ExcessNotificationCallback excess_cb, 284 void *excess_cb_cls); 285 286 287 /** 288 * Stop notifying about tracker updates and excess notifications 289 * 290 * @param av the respective trackers 291 */ 292 void 293 GNUNET_BANDWIDTH_tracker_notification_stop ( 294 struct GNUNET_BANDWIDTH_Tracker *av); 295 296 297 /** 298 * Notify the tracker that a certain number of bytes of bandwidth have 299 * been consumed. Note that it is legal to consume bytes even if not 300 * enough bandwidth is available (in that case, 301 * #GNUNET_BANDWIDTH_tracker_get_delay() may return non-zero delay values 302 * even for a size of zero for a while). 303 * 304 * @param av tracker to update 305 * @param size number of bytes consumed 306 * @return #GNUNET_YES if this consumption is above the limit 307 */ 308 int 309 GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av, 310 ssize_t size); 311 312 313 /** 314 * Compute how long we should wait until consuming @a size 315 * bytes of bandwidth in order to stay within the given 316 * quota. 317 * 318 * @param av tracker to query 319 * @param size number of bytes we would like to consume 320 * @return time to wait for consumption to be OK 321 */ 322 struct GNUNET_TIME_Relative 323 GNUNET_BANDWIDTH_tracker_get_delay (struct GNUNET_BANDWIDTH_Tracker *av, 324 size_t size); 325 326 327 /** 328 * Compute how many bytes are available for consumption right now. 329 * quota. 330 * 331 * @param av tracker to query 332 * @return number of bytes available for consumption right now 333 */ 334 int64_t 335 GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker *av); 336 337 338 /** 339 * Update quota of bandwidth tracker. 340 * 341 * @param av tracker to initialize 342 * @param bytes_per_second_limit new limit to assume 343 */ 344 void 345 GNUNET_BANDWIDTH_tracker_update_quota ( 346 struct GNUNET_BANDWIDTH_Tracker *av, 347 struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit); 348 349 350 #if 0 /* keep Emacsens' auto-indent happy */ 351 { 352 #endif 353 #ifdef __cplusplus 354 } 355 #endif 356 357 /* ifndef GNUNET_BANDWIDTH_LIB_H */ 358 #endif 359 360 /** @} */ /* end of group */ 361 362 /** @} */ /* end of group addition */ 363 364 /* end of gnunet_bandwidth_lib.h */