gnunet-android

GNUnet for Android
Log | Files | Refs | README

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 */