fixing crash: excess task has to be stopped when neighbour is freed
[oweals/gnunet.git] / src / util / bandwidth.c
index 95ff4bfffa559a3f7b035050d53a62a028e4f784..2a1a4011b8a23f44de2098f0e3b7feca99c9012a 100644 (file)
@@ -1,10 +1,10 @@
 /*
      This file is part of GNUnet.
 /*
      This file is part of GNUnet.
-     (C) 2010 Christian Grothoff (and other contributing authors)
+     (C) 2010, 2013 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
 
 /**
  * @file util/bandwidth.c
 
 /**
  * @file util/bandwidth.c
- * @brief functions related to bandwidth (unit) 
+ * @brief functions related to bandwidth (unit)
  * @author Christian Grothoff
  */
 #include "platform.h"
  * @author Christian Grothoff
  */
 #include "platform.h"
-#include "gnunet_bandwidth_lib.h"
-#include "gnunet_server_lib.h"
+#include "gnunet_util_lib.h"
 
 
-#define DEBUG_BANDWIDTH GNUNET_NO
+
+#define LOG(kind,...) GNUNET_log_from (kind, "util-bandwidth", __VA_ARGS__)
 
 /**
  * Create a new bandwidth value.
 
 /**
  * Create a new bandwidth value.
@@ -40,10 +40,9 @@ GNUNET_BANDWIDTH_value_init (uint32_t bytes_per_second)
 {
   struct GNUNET_BANDWIDTH_Value32NBO ret;
 
 {
   struct GNUNET_BANDWIDTH_Value32NBO ret;
 
-#if DEBUG_BANDWIDTH
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initializing bandwidth of %u Bps\n",
-              (unsigned int) bytes_per_second);
-#endif
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Initializing bandwidth of %u Bps\n",
+       (unsigned int) bytes_per_second);
   ret.value__ = htonl (bytes_per_second);
   return ret;
 }
   ret.value__ = htonl (bytes_per_second);
   return ret;
 }
@@ -75,27 +74,23 @@ GNUNET_BANDWIDTH_value_min (struct GNUNET_BANDWIDTH_Value32NBO b1,
  * @return number of bytes available at bps until deadline
  */
 uint64_t
  * @return number of bytes available at bps until deadline
  */
 uint64_t
-GNUNET_BANDWIDTH_value_get_available_until (struct GNUNET_BANDWIDTH_Value32NBO
-                                            bps,
-                                            struct GNUNET_TIME_Relative
-                                            deadline)
+GNUNET_BANDWIDTH_value_get_available_until (struct GNUNET_BANDWIDTH_Value32NBO bps,
+                                            struct GNUNET_TIME_Relative deadline)
 {
   uint64_t b;
 
   b = ntohl (bps.value__);
 {
   uint64_t b;
 
   b = ntohl (bps.value__);
-#if DEBUG_BANDWIDTH
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Bandwidth has %llu bytes available until deadline in %llums\n",
-              (unsigned long long) ((b * deadline.rel_value + 500LL) / 1000LL),
-              deadline.rel_value);
-#endif
-  return (b * deadline.rel_value + 500LL) / 1000LL;
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Bandwidth has %llu bytes available until deadline in %s\n",
+       (unsigned long long) ((b * deadline.rel_value_us + 500000LL) / 1000000LL),
+       GNUNET_STRINGS_relative_time_to_string (deadline, GNUNET_YES));
+  return (b * deadline.rel_value_us + 500000LL) / 1000000LL;
 }
 
 
 /**
  * At the given bandwidth, calculate how long it would take for
 }
 
 
 /**
  * At the given bandwidth, calculate how long it would take for
- * 'size' bytes to be transmitted.
+ * @a size bytes to be transmitted.
  *
  * @param bps bandwidth
  * @param size number of bytes we want to have available
  *
  * @param bps bandwidth
  * @param size number of bytes we want to have available
@@ -109,56 +104,183 @@ GNUNET_BANDWIDTH_value_get_delay_for (struct GNUNET_BANDWIDTH_Value32NBO bps,
   struct GNUNET_TIME_Relative ret;
 
   b = ntohl (bps.value__);
   struct GNUNET_TIME_Relative ret;
 
   b = ntohl (bps.value__);
-  if (b == 0)
+  if (0 == b)
   {
   {
-#if DEBUG_BANDWIDTH
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Bandwidth suggests delay of infinity (zero bandwidth)\n");
-#endif
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Bandwidth suggests delay of infinity (zero bandwidth)\n");
     return GNUNET_TIME_UNIT_FOREVER_REL;
   }
     return GNUNET_TIME_UNIT_FOREVER_REL;
   }
-  ret.rel_value = size * 1000LL / b;
-#if DEBUG_BANDWIDTH
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Bandwidth suggests delay of %llu ms for %llu bytes of traffic\n",
-              (unsigned long long) ret.rel_value, (unsigned long long) size);
-#endif
+  ret.rel_value_us = size * 1000LL * 1000LL / b;
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Bandwidth suggests delay of %s for %llu bytes of traffic\n",
+       GNUNET_STRINGS_relative_time_to_string (ret, GNUNET_YES),
+       (unsigned long long) size);
   return ret;
 }
 
 
   return ret;
 }
 
 
+/**
+ * Task run whenever we hit the bandwidth limit for a tracker.
+ *
+ * @param cls the `struct GNUNET_BANDWIDTH_Tracker`
+ * @param tc scheduler context
+ */
+static void
+excess_trigger (void *cls,
+                const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_BANDWIDTH_Tracker *av = cls;
+
+  av->excess_task = GNUNET_SCHEDULER_NO_TASK;
+
+  if (NULL != av->excess_cb)
+    av->excess_cb (av->excess_cb_cls);
+}
+
+
+/**
+ * Recalculate when we might need to call the excess callback.
+ */
+static void
+update_excess (struct GNUNET_BANDWIDTH_Tracker *av)
+{
+  struct GNUNET_TIME_Relative delay;
+  struct GNUNET_TIME_Absolute now;
+  uint64_t delta_time;
+  uint64_t delta_avail;
+  int64_t left_bytes;
+  uint64_t max_carry;
+  int64_t current_consumption;
+
+  if (NULL == av->excess_cb)
+    return; /* nothing to do */
+  now = GNUNET_TIME_absolute_get ();
+  delta_time = now.abs_value_us - av->last_update__.abs_value_us;
+  delta_avail =
+      (delta_time * ((unsigned long long) av->available_bytes_per_s__) +
+       500000LL) / 1000000LL;
+  current_consumption = av->consumption_since_last_update__ - delta_avail;
+  /* negative current_consumption means that we have savings */
+  max_carry = av->available_bytes_per_s__ * av->max_carry_s__;
+  if (max_carry < GNUNET_SERVER_MAX_MESSAGE_SIZE)
+    max_carry = GNUNET_SERVER_MAX_MESSAGE_SIZE;
+  left_bytes = max_carry + current_consumption;
+  /* left_bytes now contains the number of bytes needed until
+     we have more savings than allowed */
+  if (left_bytes < 0)
+  {
+    /* having excess already */
+    delay = GNUNET_TIME_UNIT_ZERO;
+  }
+  else
+  {
+    delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
+                                           left_bytes);
+    delay = GNUNET_TIME_relative_divide (delay,
+                                         av->available_bytes_per_s__);
+  }
+  if (GNUNET_SCHEDULER_NO_TASK != av->excess_task)
+    GNUNET_SCHEDULER_cancel (av->excess_task);
+  av->excess_task = GNUNET_SCHEDULER_add_delayed (delay,
+                                                  &excess_trigger,
+                                                  av);
+}
+
+
 /**
  * Initialize bandwidth tracker.  Note that in addition to the
  * 'max_carry_s' limit, we also always allow at least
 /**
  * Initialize bandwidth tracker.  Note that in addition to the
  * 'max_carry_s' limit, we also always allow at least
- * GNUNET_SERVER_MAX_MESSAGE_SIZE to accumulate.  So if the
+ * #GNUNET_SERVER_MAX_MESSAGE_SIZE to accumulate.  So if the
  * bytes-per-second limit is so small that within 'max_carry_s' not
  * bytes-per-second limit is so small that within 'max_carry_s' not
- * even GNUNET_SERVER_MAX_MESSAGE_SIZE is allowed to accumulate, it is
- * ignored and replaced by GNUNET_SERVER_MAX_MESSAGE_SIZE (which is in
+ * even #GNUNET_SERVER_MAX_MESSAGE_SIZE is allowed to accumulate, it is
+ * ignored and replaced by #GNUNET_SERVER_MAX_MESSAGE_SIZE (which is in
  * bytes).
  *
  * @param av tracker to initialize
  * bytes).
  *
  * @param av tracker to initialize
+ * @param update_cb callback to notify a client about the tracker being updated
+ * @param update_cb_cls cls for the callback
  * @param bytes_per_second_limit initial limit to assume
  * @param max_carry_s maximum number of seconds unused bandwidth
  *        may accumulate before it expires
  * @param bytes_per_second_limit initial limit to assume
  * @param max_carry_s maximum number of seconds unused bandwidth
  *        may accumulate before it expires
+ * @param excess_cb callback to notify if we have excess bandwidth
+ * @param excess_cb_cls closure for @a excess_cb
  */
 void
  */
 void
-GNUNET_BANDWIDTH_tracker_init (struct GNUNET_BANDWIDTH_Tracker *av,
-                               struct GNUNET_BANDWIDTH_Value32NBO
-                               bytes_per_second_limit, uint32_t max_carry_s)
+GNUNET_BANDWIDTH_tracker_init2 (struct GNUNET_BANDWIDTH_Tracker *av,
+                                GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb,
+                                void *update_cb_cls,
+                                struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit,
+                                uint32_t max_carry_s,
+                                GNUNET_BANDWIDTH_ExcessNotificationCallback excess_cb,
+                                void *excess_cb_cls)
 {
 {
+  av->update_cb = update_cb;
+  av->update_cb_cls = update_cb_cls;
   av->consumption_since_last_update__ = 0;
   av->last_update__ = GNUNET_TIME_absolute_get ();
   av->available_bytes_per_s__ = ntohl (bytes_per_second_limit.value__);
   av->max_carry_s__ = max_carry_s;
   av->consumption_since_last_update__ = 0;
   av->last_update__ = GNUNET_TIME_absolute_get ();
   av->available_bytes_per_s__ = ntohl (bytes_per_second_limit.value__);
   av->max_carry_s__ = max_carry_s;
-#if DEBUG_BANDWIDTH
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Tracker %p initialized with %u Bps and max carry %u\n", av,
-              (unsigned int) av->available_bytes_per_s__,
-              (unsigned int) max_carry_s);
-#endif
+  av->excess_cb = excess_cb;
+  av->excess_cb_cls = excess_cb_cls;
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Tracker %p initialized with %u Bps and max carry %u\n",
+       av,
+       (unsigned int) av->available_bytes_per_s__,
+       (unsigned int) max_carry_s);
+  update_excess (av);
+}
+
+
+/**
+ * Initialize bandwidth tracker.  Note that in addition to the
+ * 'max_carry_s' limit, we also always allow at least
+ * GNUNET_SERVER_MAX_MESSAGE_SIZE to accumulate.  So if the
+ * bytes-per-second limit is so small that within 'max_carry_s' not
+ * even GNUNET_SERVER_MAX_MESSAGE_SIZE is allowed to accumulate, it is
+ * ignored and replaced by GNUNET_SERVER_MAX_MESSAGE_SIZE (which is in
+ * bytes).
+ *
+ * @param av tracker to initialize
+ * @param update_cb callback to notify a client about the tracker being updated
+ * @param update_cb_cls cls for the callback
+ * @param bytes_per_second_limit initial limit to assume
+ * @param max_carry_s maximum number of seconds unused bandwidth
+ *        may accumulate before it expires
+ */
+void
+GNUNET_BANDWIDTH_tracker_init (struct GNUNET_BANDWIDTH_Tracker *av,
+                               GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb,
+                               void *update_cb_cls,
+                               struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit,
+                               uint32_t max_carry_s)
+{
+  GNUNET_BANDWIDTH_tracker_init2 (av, update_cb,
+                                  update_cb_cls,
+                                  bytes_per_second_limit,
+                                  max_carry_s,
+                                  NULL, NULL);
+}
+
+
+/**
+ * Stop notifying about tracker updates and excess notifications
+ *
+ * @param av the respective trackers
+ */
+void
+GNUNET_BANDWIDTH_tracker_notification_stop (struct GNUNET_BANDWIDTH_Tracker *av)
+{
+  if (GNUNET_SCHEDULER_NO_TASK != av->excess_task)
+    GNUNET_SCHEDULER_cancel (av->excess_task);
+  av->excess_task = GNUNET_SCHEDULER_NO_TASK;
+  av->excess_cb = NULL;
+  av->excess_cb_cls = NULL;
+  av->update_cb = NULL;
+  av->update_cb_cls = NULL;
 }
 
 
 }
 
 
+
 /**
  * Update the tracker, looking at the current time and
  * bandwidth consumption data.
 /**
  * Update the tracker, looking at the current time and
  * bandwidth consumption data.
@@ -169,16 +291,17 @@ static void
 update_tracker (struct GNUNET_BANDWIDTH_Tracker *av)
 {
   struct GNUNET_TIME_Absolute now;
 update_tracker (struct GNUNET_BANDWIDTH_Tracker *av)
 {
   struct GNUNET_TIME_Absolute now;
+  struct GNUNET_TIME_Relative delta;
   uint64_t delta_time;
   uint64_t delta_avail;
   uint64_t left_bytes;
   uint64_t max_carry;
 
   now = GNUNET_TIME_absolute_get ();
   uint64_t delta_time;
   uint64_t delta_avail;
   uint64_t left_bytes;
   uint64_t max_carry;
 
   now = GNUNET_TIME_absolute_get ();
-  delta_time = now.abs_value - av->last_update__.abs_value;
+  delta_time = now.abs_value_us - av->last_update__.abs_value_us;
   delta_avail =
       (delta_time * ((unsigned long long) av->available_bytes_per_s__) +
   delta_avail =
       (delta_time * ((unsigned long long) av->available_bytes_per_s__) +
-       500LL) / 1000LL;
+       500000LL) / 1000000LL;
   av->consumption_since_last_update__ -= delta_avail;
   av->last_update__ = now;
   if (av->consumption_since_last_update__ < 0)
   av->consumption_since_last_update__ -= delta_avail;
   av->last_update__ = now;
   if (av->consumption_since_last_update__ < 0)
@@ -192,13 +315,11 @@ update_tracker (struct GNUNET_BANDWIDTH_Tracker *av)
     else
       av->consumption_since_last_update__ = -max_carry;
   }
     else
       av->consumption_since_last_update__ = -max_carry;
   }
-#if DEBUG_BANDWIDTH
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Tracker %p  updated, have %u Bps, last update was %llu ms ago\n",
-              av, (unsigned int) av->available_bytes_per_s__,
-              (unsigned long long) delta_time);
-#endif
-
+  delta.rel_value_us = delta_time;
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Tracker %p updated, have %u Bps, last update was %s ago\n", av,
+       (unsigned int) av->available_bytes_per_s__,
+       GNUNET_STRINGS_relative_time_to_string (delta, GNUNET_YES));
 }
 
 
 }
 
 
@@ -206,12 +327,12 @@ update_tracker (struct GNUNET_BANDWIDTH_Tracker *av)
  * Notify the tracker that a certain number of bytes of bandwidth have
  * been consumed.  Note that it is legal to consume bytes even if not
  * enough bandwidth is available (in that case,
  * Notify the tracker that a certain number of bytes of bandwidth have
  * been consumed.  Note that it is legal to consume bytes even if not
  * enough bandwidth is available (in that case,
- * GNUNET_BANDWIDTH_tracker_get_delay may return non-zero delay values
+ * #GNUNET_BANDWIDTH_tracker_get_delay may return non-zero delay values
  * even for a size of zero for a while).
  *
  * @param av tracker to update
  * @param size number of bytes consumed
  * even for a size of zero for a while).
  *
  * @param av tracker to update
  * @param size number of bytes consumed
- * @return GNUNET_YES if this consumption is above the limit
+ * @return #GNUNET_YES if this consumption is above the limit
  */
 int
 GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av,
  */
 int
 GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av,
@@ -219,10 +340,10 @@ GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av,
 {
   int64_t nc;
 
 {
   int64_t nc;
 
-#if DEBUG_BANDWIDTH
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Tracker %p consumes %d bytes\n", av,
-              (int) size);
-#endif
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Tracker %p consumes %d bytes\n",
+       av,
+       (int) size);
   if (size > 0)
   {
     nc = av->consumption_since_last_update__ + size;
   if (size > 0)
   {
     nc = av->consumption_since_last_update__ + size;
@@ -233,19 +354,19 @@ GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av,
     }
     av->consumption_since_last_update__ = nc;
     update_tracker (av);
     }
     av->consumption_since_last_update__ = nc;
     update_tracker (av);
+    update_excess (av);
     if (av->consumption_since_last_update__ > 0)
     {
     if (av->consumption_since_last_update__ > 0)
     {
-#if DEBUG_BANDWIDTH
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "Tracker %p consumption %llu bytes above limit\n", av,
-                  (unsigned long long) av->consumption_since_last_update__);
-#endif
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+           "Tracker %p consumption %llu bytes above limit\n", av,
+           (unsigned long long) av->consumption_since_last_update__);
       return GNUNET_YES;
     }
   }
   else
   {
     av->consumption_since_last_update__ += size;
       return GNUNET_YES;
     }
   }
   else
   {
     av->consumption_since_last_update__ += size;
+    update_excess (av);
   }
   return GNUNET_NO;
 }
   }
   return GNUNET_NO;
 }
@@ -267,31 +388,28 @@ GNUNET_BANDWIDTH_tracker_get_delay (struct GNUNET_BANDWIDTH_Tracker *av,
   struct GNUNET_TIME_Relative ret;
   int64_t bytes_needed;
 
   struct GNUNET_TIME_Relative ret;
   int64_t bytes_needed;
 
-  if (av->available_bytes_per_s__ == 0)
+  if (0 == av->available_bytes_per_s__)
   {
   {
-#if DEBUG_BANDWIDTH
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Tracker %p delay is infinity\n", av);
-#endif
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+        "Tracker %p delay is infinity\n", av);
     return GNUNET_TIME_UNIT_FOREVER_REL;
   }
   update_tracker (av);
   bytes_needed = size + av->consumption_since_last_update__;
   if (bytes_needed <= 0)
   {
     return GNUNET_TIME_UNIT_FOREVER_REL;
   }
   update_tracker (av);
   bytes_needed = size + av->consumption_since_last_update__;
   if (bytes_needed <= 0)
   {
-#if DEBUG_BANDWIDTH
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Tracker %p delay for %u bytes is zero\n", av,
-                (unsigned int) size);
-#endif
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+        "Tracker %p delay for %u bytes is zero\n", av,
+         (unsigned int) size);
     return GNUNET_TIME_UNIT_ZERO;
   }
     return GNUNET_TIME_UNIT_ZERO;
   }
-  ret.rel_value =
-      1000LL * bytes_needed / (unsigned long long) av->available_bytes_per_s__;
-#if DEBUG_BANDWIDTH
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Tracker %p delay for %u bytes is %llu ms\n", av,
-              (unsigned int) size, (unsigned long long) ret.rel_value);
-#endif
+  ret.rel_value_us =
+      (1000LL * 1000LL * bytes_needed) /
+      (unsigned long long) av->available_bytes_per_s__;
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Tracker %p delay for %u bytes is %s\n",
+       av, (unsigned int) size,
+       GNUNET_STRINGS_relative_time_to_string (ret, GNUNET_YES));
   return ret;
 }
 
   return ret;
 }
 
@@ -304,7 +422,7 @@ GNUNET_BANDWIDTH_tracker_get_delay (struct GNUNET_BANDWIDTH_Tracker *av,
  * @return number of bytes available for consumption right now
  */
 int64_t
  * @return number of bytes available for consumption right now
  */
 int64_t
-GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker * av)
+GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker *av)
 {
   struct GNUNET_BANDWIDTH_Value32NBO bps;
   uint64_t avail;
 {
   struct GNUNET_BANDWIDTH_Value32NBO bps;
   uint64_t avail;
@@ -317,11 +435,9 @@ GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker * av)
                                                   GNUNET_TIME_absolute_get_duration
                                                   (av->last_update__));
   used = av->consumption_since_last_update__;
                                                   GNUNET_TIME_absolute_get_duration
                                                   (av->last_update__));
   used = av->consumption_since_last_update__;
-#if DEBUG_BANDWIDTH
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Tracker %p  available bandwidth is %lld bytes\n", av,
-              (long long) (int64_t) (avail - used));
-#endif
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Tracker %p available bandwidth is %lld bytes\n", av,
+       (long long) (int64_t) (avail - used));
   return (int64_t) (avail - used);
 }
 
   return (int64_t) (avail - used);
 }
 
@@ -334,23 +450,23 @@ GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker * av)
  */
 void
 GNUNET_BANDWIDTH_tracker_update_quota (struct GNUNET_BANDWIDTH_Tracker *av,
  */
 void
 GNUNET_BANDWIDTH_tracker_update_quota (struct GNUNET_BANDWIDTH_Tracker *av,
-                                       struct GNUNET_BANDWIDTH_Value32NBO
-                                       bytes_per_second_limit)
+                                       struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit)
 {
   uint32_t old_limit;
   uint32_t new_limit;
 
   new_limit = ntohl (bytes_per_second_limit.value__);
 {
   uint32_t old_limit;
   uint32_t new_limit;
 
   new_limit = ntohl (bytes_per_second_limit.value__);
-#if DEBUG_BANDWIDTH
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Tracker %p bandwidth changed to %u Bps\n", av,
-              (unsigned int) new_limit);
-#endif
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Tracker %p bandwidth changed to %u Bps\n", av,
+       (unsigned int) new_limit);
   update_tracker (av);
   old_limit = av->available_bytes_per_s__;
   av->available_bytes_per_s__ = new_limit;
   update_tracker (av);
   old_limit = av->available_bytes_per_s__;
   av->available_bytes_per_s__ = new_limit;
+  if (NULL != av->update_cb)
+    av->update_cb (av->update_cb_cls);
   if (old_limit > new_limit)
     update_tracker (av);        /* maximum excess might be less now */
   if (old_limit > new_limit)
     update_tracker (av);        /* maximum excess might be less now */
+  update_excess (av);
 }
 
 
 }