-fixes
[oweals/gnunet.git] / src / fs / gnunet-service-fs_cp.c
index 05e5bedefa6e84d22e397010dce3c0286b1e023e..e84993bd38b07c402da69e3866c339e3ea2dd2f9 100644 (file)
 #include "gnunet-service-fs_pr.h"
 #include "gnunet-service-fs_push.h"
 
+
+/**
+ * Ratio for moving average delay calculation.  The previous
+ * average goes in with a factor of (n-1) into the calculation.
+ * Must be > 0.
+ */
+#define RUNAVG_DELAY_N 16
+
 /**
  * How often do we flush trust values to disk?
  */
@@ -241,14 +249,14 @@ struct GSF_ConnectedPeer
   struct GSF_PeerTransmitHandle *migration_pth;
 
   /**
-   * Context of our GNUNET_ATS_peer_change_preference call (or NULL).
+   * Context of our GNUNET_ATS_reserve_bandwidth call (or NULL).
    */
-  struct GNUNET_ATS_InformationRequestContext *irc;
+  struct GNUNET_ATS_ReservationContext *rc;
 
   /**
    * Task scheduled if we need to retry bandwidth reservation later.
    */
-  GNUNET_SCHEDULER_TaskIdentifier irc_delay_task;
+  GNUNET_SCHEDULER_TaskIdentifier rc_delay_task;
 
   /**
    * Active requests from this neighbour, map of query to 'struct PeerRequest'.
@@ -305,7 +313,7 @@ static char *trustDirectory;
 /**
  * Handle to ATS service.
  */
-static struct GNUNET_ATS_Handle *ats;
+static struct GNUNET_ATS_PerformanceHandle *ats;
 
 /**
  * Get the filename under which we would store the GNUNET_HELLO_Message
@@ -328,25 +336,19 @@ get_trust_filename (const struct GNUNET_PeerIdentity *id)
  * Find latency information in 'atsi'.
  *
  * @param atsi performance data
+ * @param atsi_count number of records in 'atsi'
  * @return connection latency
  */
 static struct GNUNET_TIME_Relative
-get_latency (const struct GNUNET_TRANSPORT_ATS_Information *atsi)
+get_latency (const struct GNUNET_ATS_Information *atsi, unsigned int atsi_count)
 {
-  if (atsi == NULL)
-    return GNUNET_TIME_UNIT_SECONDS;
-  while ((ntohl (atsi->type) != GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR) &&
-         (ntohl (atsi->type) != GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY))
-    atsi++;
-  if (ntohl (atsi->type) == GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR)
-  {
-    /* We sometime have no latency data, i.e. if the address came from 
-       peerinfo and we never had a chance to play transport-level 
-       PING/PONG yet. Assume 1s in that case. */
-    return GNUNET_TIME_UNIT_SECONDS;
-  }
-  return GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
-                                        ntohl (atsi->value));
+  unsigned int i;
+
+  for (i = 0; i < atsi_count; i++)
+    if (ntohl (atsi->type) == GNUNET_ATS_QUALITY_NET_DELAY)
+      return GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
+                                            ntohl (atsi->value));
+  return GNUNET_TIME_UNIT_SECONDS;
 }
 
 
@@ -355,14 +357,15 @@ get_latency (const struct GNUNET_TRANSPORT_ATS_Information *atsi)
  *
  * @param cp peer record to update
  * @param atsi transport performance data
+ * @param atsi_count number of records in 'atsi'
  */
 static void
 update_atsi (struct GSF_ConnectedPeer *cp,
-             const struct GNUNET_TRANSPORT_ATS_Information *atsi)
+             const struct GNUNET_ATS_Information *atsi, unsigned int atsi_count)
 {
   struct GNUNET_TIME_Relative latency;
 
-  latency = get_latency (atsi);
+  latency = get_latency (atsi, atsi_count);
   GNUNET_LOAD_value_set_decline (cp->ppd.transmission_delay, latency);
   /* LATER: merge atsi into cp's performance data (if we ever care...) */
 }
@@ -405,7 +408,7 @@ peer_transmit_ready_cb (void *cls, size_t size, void *buf);
  */
 static void
 ats_reserve_callback (void *cls, const struct GNUNET_PeerIdentity *peer,
-                       int32_t amount, struct GNUNET_TIME_Relative res_delay);
+                      int32_t amount, struct GNUNET_TIME_Relative res_delay);
 
 
 /**
@@ -419,13 +422,21 @@ schedule_transmission (struct GSF_PeerTransmitHandle *pth)
 {
   struct GSF_ConnectedPeer *cp;
   struct GNUNET_PeerIdentity target;
-  uint64_t ip;
 
   if ((NULL != pth->cth) || (0 != pth->cth_in_progress))
     return;                     /* already done */
   cp = pth->cp;
   GNUNET_assert (0 != cp->ppd.pid);
   GNUNET_PEER_resolve (cp->ppd.pid, &target);
+
+  if (0 != cp->inc_preference)
+  {
+    GNUNET_ATS_change_preference (ats, &target, GNUNET_ATS_PREFERENCE_BANDWIDTH,
+                                  (double) cp->inc_preference,
+                                  GNUNET_ATS_PREFERENCE_END);
+    cp->inc_preference = 0;
+  }
+
   if ((GNUNET_YES == pth->is_query) && (GNUNET_YES != pth->was_reserved))
   {
     /* query, need reservation */
@@ -434,12 +445,9 @@ schedule_transmission (struct GSF_PeerTransmitHandle *pth)
     cp->did_reserve = GNUNET_NO;
     /* reservation already done! */
     pth->was_reserved = GNUNET_YES;
-    ip = cp->inc_preference;
-    cp->inc_preference = 0;
-    cp->irc =
-        GNUNET_ATS_peer_change_preference (ats, &target,
-                                          DBLOCK_SIZE, ip,
-                                          &ats_reserve_callback, cp);
+    cp->rc =
+        GNUNET_ATS_reserve_bandwidth (ats, &target, DBLOCK_SIZE,
+                                      &ats_reserve_callback, cp);
   }
   GNUNET_assert (pth->cth == NULL);
   pth->cth_in_progress++;
@@ -515,17 +523,13 @@ static void
 retry_reservation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct GSF_ConnectedPeer *cp = cls;
-  uint64_t ip;
   struct GNUNET_PeerIdentity target;
 
   GNUNET_PEER_resolve (cp->ppd.pid, &target);
-  cp->irc_delay_task = GNUNET_SCHEDULER_NO_TASK;
-  ip = cp->inc_preference;
-  cp->inc_preference = 0;
-  cp->irc =
-      GNUNET_ATS_peer_change_preference (ats, &target,
-                                        DBLOCK_SIZE, ip,
-                                        &ats_reserve_callback, cp);
+  cp->rc_delay_task = GNUNET_SCHEDULER_NO_TASK;
+  cp->rc =
+      GNUNET_ATS_reserve_bandwidth (ats, &target, DBLOCK_SIZE,
+                                    &ats_reserve_callback, cp);
 }
 
 
@@ -541,15 +545,18 @@ retry_reservation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  */
 static void
 ats_reserve_callback (void *cls, const struct GNUNET_PeerIdentity *peer,
-                       int32_t amount, struct GNUNET_TIME_Relative res_delay)
+                      int32_t amount, struct GNUNET_TIME_Relative res_delay)
 {
   struct GSF_ConnectedPeer *cp = cls;
   struct GSF_PeerTransmitHandle *pth;
 
-  cp->irc = NULL;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Reserved %d bytes / need to wait %llu ms for reservation\n",
+              (int) amount, (unsigned long long) res_delay.rel_value);
+  cp->rc = NULL;
   if (0 == amount)
   {
-    cp->irc_delay_task =
+    cp->rc_delay_task =
         GNUNET_SCHEDULER_add_delayed (res_delay, &retry_reservation, cp);
     return;
   }
@@ -575,23 +582,26 @@ ats_reserve_callback (void *cls, const struct GNUNET_PeerIdentity *peer,
  *
  * @param peer identity of peer that connected
  * @param atsi performance data for the connection
+ * @param atsi_count number of records in 'atsi'
  * @return handle to connected peer entry
  */
 struct GSF_ConnectedPeer *
 GSF_peer_connect_handler_ (const struct GNUNET_PeerIdentity *peer,
-                           const struct GNUNET_TRANSPORT_ATS_Information *atsi)
+                           const struct GNUNET_ATS_Information *atsi,
+                           unsigned int atsi_count)
 {
   struct GSF_ConnectedPeer *cp;
   char *fn;
   uint32_t trust;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to peer %s\n",
+              GNUNET_i2s (peer));
   cp = GNUNET_malloc (sizeof (struct GSF_ConnectedPeer));
   cp->ppd.pid = GNUNET_PEER_intern (peer);
   cp->ppd.transmission_delay = GNUNET_LOAD_value_init (GNUNET_TIME_UNIT_ZERO);
-  cp->irc =
-      GNUNET_ATS_peer_change_preference (ats, peer,
-                                        DBLOCK_SIZE, 0,
-                                        &ats_reserve_callback, cp);
+  cp->rc =
+      GNUNET_ATS_reserve_bandwidth (ats, peer, DBLOCK_SIZE,
+                                    &ats_reserve_callback, cp);
   fn = get_trust_filename (peer);
   if ((GNUNET_DISK_file_test (fn) == GNUNET_YES) &&
       (sizeof (trust) == GNUNET_DISK_fn_read (fn, &trust, sizeof (trust))))
@@ -602,7 +612,10 @@ GSF_peer_connect_handler_ (const struct GNUNET_PeerIdentity *peer,
                 GNUNET_CONTAINER_multihashmap_put (cp_map, &peer->hashPubKey,
                                                    cp,
                                                    GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
-  update_atsi (cp, atsi);
+  GNUNET_STATISTICS_set (GSF_stats, gettext_noop ("# peers connected"),
+                         GNUNET_CONTAINER_multihashmap_size (cp_map),
+                         GNUNET_NO);
+  update_atsi (cp, atsi, atsi_count);
   GSF_push_start_ (cp);
   return cp;
 }
@@ -657,6 +670,7 @@ GSF_peer_get_ (const struct GNUNET_PeerIdentity *peer)
  *        for loopback messages where we are both sender and receiver)
  * @param message the actual message
  * @param atsi performance information
+ * @param atsi_count number of records in 'atsi'
  * @return GNUNET_OK to keep the connection open,
  *         GNUNET_SYSERR to close it (signal serious error)
  */
@@ -664,20 +678,23 @@ int
 GSF_handle_p2p_migration_stop_ (void *cls,
                                 const struct GNUNET_PeerIdentity *other,
                                 const struct GNUNET_MessageHeader *message,
-                                const struct GNUNET_TRANSPORT_ATS_Information
-                                *atsi)
+                                const struct GNUNET_ATS_Information *atsi,
+                                unsigned int atsi_count)
 {
   struct GSF_ConnectedPeer *cp;
   const struct MigrationStopMessage *msm;
   struct GNUNET_TIME_Relative bt;
 
   msm = (const struct MigrationStopMessage *) message;
-  cp = GNUNET_CONTAINER_multihashmap_get (cp_map, &other->hashPubKey);
+  cp = GSF_peer_get_ (other);
   if (cp == NULL)
   {
     GNUNET_break (0);
     return GNUNET_OK;
   }
+  GNUNET_STATISTICS_update (GSF_stats,
+                            gettext_noop ("# migration stop messages received"),
+                            1, GNUNET_NO);
   bt = GNUNET_TIME_relative_ntoh (msm->duration);
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               _("Migration of content to peer `%s' blocked for %llu ms\n"),
@@ -689,7 +706,7 @@ GSF_handle_p2p_migration_stop_ (void *cls,
     cp->mig_revive_task =
         GNUNET_SCHEDULER_add_delayed (bt, &revive_migration, cp);
   }
-  update_atsi (cp, atsi);
+  update_atsi (cp, atsi, atsi_count);
   return GNUNET_OK;
 }
 
@@ -729,6 +746,32 @@ copy_reply (void *cls, size_t buf_size, void *buf)
 }
 
 
+/**
+ * Free resources associated with the given peer request.
+ *
+ * @param peerreq request to free
+ * @param query associated key for the request
+ */
+static void
+free_pending_request (struct PeerRequest *peerreq,
+                     const GNUNET_HashCode *query)
+{
+  struct GSF_ConnectedPeer *cp = peerreq->cp;
+
+  if (peerreq->kill_task != GNUNET_SCHEDULER_NO_TASK)
+  {
+    GNUNET_SCHEDULER_cancel (peerreq->kill_task);
+    peerreq->kill_task = GNUNET_SCHEDULER_NO_TASK;
+  }
+  GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# P2P searches active"),
+                            -1, GNUNET_NO);
+  GNUNET_break (GNUNET_YES ==
+                GNUNET_CONTAINER_multihashmap_remove (cp->request_map,
+                                                      query, peerreq));
+  GNUNET_free (peerreq);
+}
+
+
 /**
  * Cancel all requests associated with the peer.
  *
@@ -742,22 +785,11 @@ cancel_pending_request (void *cls, const GNUNET_HashCode * query, void *value)
 {
   struct PeerRequest *peerreq = value;
   struct GSF_PendingRequest *pr = peerreq->pr;
-  struct GSF_ConnectedPeer *cp = peerreq->cp;
   struct GSF_PendingRequestData *prd;
 
-  if (peerreq->kill_task != GNUNET_SCHEDULER_NO_TASK)
-  {
-    GNUNET_SCHEDULER_cancel (peerreq->kill_task);
-    peerreq->kill_task = GNUNET_SCHEDULER_NO_TASK;
-  }
-  GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# P2P searches active"),
-                            -1, GNUNET_NO);
   prd = GSF_pending_request_get_data_ (pr);
-  GNUNET_break (GNUNET_YES ==
-                GNUNET_CONTAINER_multihashmap_remove (cp->request_map,
-                                                      &prd->query, peerreq));
   GSF_pending_request_cancel_ (pr, GNUNET_NO);
-  GNUNET_free (peerreq);
+  free_pending_request (peerreq, &prd->query);
   return GNUNET_OK;
 }
 
@@ -816,11 +848,11 @@ get_randomized_delay ()
 {
   struct GNUNET_TIME_Relative ret;
 
-  /* FIXME: replace 5000 with something relating to current observed P2P message latency */
   ret =
       GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
                                      GNUNET_CRYPTO_random_u32
-                                     (GNUNET_CRYPTO_QUALITY_WEAK, 5000));
+                                     (GNUNET_CRYPTO_QUALITY_WEAK,
+                                      2 * GSF_avg_latency.rel_value + 1));
   GNUNET_STATISTICS_update (GSF_stats,
                             gettext_noop
                             ("# artificial delays introduced (ms)"),
@@ -843,6 +875,7 @@ get_randomized_delay ()
  * @param pr handle to the original pending request
  * @param reply_anonymity_level anonymity level for the reply, UINT32_MAX for "unknown"
  * @param expiration when does 'data' expire?
+ * @param last_transmission when did we last transmit a request for this block
  * @param type type of the block
  * @param data response data, NULL on request expiration
  * @param data_len number of bytes in data
@@ -851,6 +884,7 @@ static void
 handle_p2p_reply (void *cls, enum GNUNET_BLOCK_EvaluationResult eval,
                   struct GSF_PendingRequest *pr, uint32_t reply_anonymity_level,
                   struct GNUNET_TIME_Absolute expiration,
+                  struct GNUNET_TIME_Absolute last_transmission,
                   enum GNUNET_BLOCK_Type type, const void *data,
                   size_t data_len)
 {
@@ -866,25 +900,21 @@ handle_p2p_reply (void *cls, enum GNUNET_BLOCK_EvaluationResult eval,
   prd = GSF_pending_request_get_data_ (pr);
   if (NULL == data)
   {
-    GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# P2P searches active"),
-                              -1, GNUNET_NO);
-    GNUNET_break (GNUNET_YES ==
-                  GNUNET_CONTAINER_multihashmap_remove (cp->request_map,
-                                                        &prd->query, peerreq));
-    GNUNET_free (peerreq);
+    free_pending_request (peerreq, &prd->query);
     return;
   }
   GNUNET_break (type != GNUNET_BLOCK_TYPE_ANY);
   if ((prd->type != type) && (prd->type != GNUNET_BLOCK_TYPE_ANY))
   {
-    GNUNET_break (0);
+    GNUNET_STATISTICS_update (GSF_stats,
+                             gettext_noop
+                             ("# replies dropped due to type mismatch"),
+                                1, GNUNET_NO);
     return;
   }
-#if DEBUG_FS
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Transmitting result for query `%s' to peer\n",
               GNUNET_h2s (&prd->query));
-#endif
   GNUNET_STATISTICS_update (GSF_stats,
                             gettext_noop ("# replies received for other peers"),
                             1, GNUNET_NO);
@@ -1146,7 +1176,7 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other,
   GSF_cover_query_count++;
   bm = ntohl (gm->hash_bitmap);
   bits = 0;
-  cps = GNUNET_CONTAINER_multihashmap_get (cp_map, &other->hashPubKey);
+  cps = GSF_peer_get_ (other);
   if (NULL == cps)
   {
     /* peer must have just disconnected */
@@ -1157,12 +1187,11 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other,
     return NULL;
   }
   if (0 != (bm & GET_MESSAGE_BIT_RETURN_TO))
-    cp = GNUNET_CONTAINER_multihashmap_get (cp_map, &opt[bits++]);
+    cp = GSF_peer_get_ ((const struct GNUNET_PeerIdentity *) &opt[bits++]);
   else
     cp = cps;
   if (cp == NULL)
   {
-#if DEBUG_FS
     if (0 != (bm & GET_MESSAGE_BIT_RETURN_TO))
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Failed to find RETURN-TO peer `%4s' in connection set. Dropping query.\n",
@@ -1173,7 +1202,6 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other,
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Failed to find peer `%4s' in connection set. Dropping query.\n",
                   GNUNET_i2s (other));
-#endif
     GNUNET_STATISTICS_update (GSF_stats,
                               gettext_noop
                               ("# requests dropped due to missing reverse route"),
@@ -1186,19 +1214,15 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other,
   priority = bound_priority (ntohl (gm->priority), cps);
   if (priority < 0)
   {
-#if DEBUG_FS
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Dropping query from `%s', this peer is too busy.\n",
                 GNUNET_i2s (other));
-#endif
     return NULL;
   }
-#if DEBUG_FS
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Received request for `%s' of type %u from peer `%4s' with flags %u\n",
               GNUNET_h2s (&gm->query), (unsigned int) type, GNUNET_i2s (other),
               (unsigned int) bm);
-#endif
   namespace = (0 != (bm & GET_MESSAGE_BIT_SKS_NAMESPACE)) ? &opt[bits++] : NULL;
   if ((type == GNUNET_BLOCK_TYPE_FS_SBLOCK) && (namespace == NULL))
   {
@@ -1214,7 +1238,7 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other,
       (0 !=
        (bm & GET_MESSAGE_BIT_TRANSMIT_TO)) ? ((const struct GNUNET_PeerIdentity
                                                *) &opt[bits++]) : NULL;
-  options = 0;
+  options = GSF_PRO_DEFAULTS;
   spid = 0;
   if ((GNUNET_LOAD_get_load (cp->ppd.transmission_delay) > 3 * (1 + priority))
       || (GNUNET_LOAD_get_average (cp->ppd.transmission_delay) >
@@ -1235,11 +1259,9 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other,
                                                     TTL_DECREMENT);
   if ((ttl < 0) && (((int32_t) (ttl - ttl_decrement)) > 0))
   {
-#if DEBUG_FS
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Dropping query from `%s' due to TTL underflow (%d - %u).\n",
                 GNUNET_i2s (other), ttl, ttl_decrement);
-#endif
     GNUNET_STATISTICS_update (GSF_stats,
                               gettext_noop
                               ("# requests dropped due TTL underflow"), 1,
@@ -1263,11 +1285,9 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other,
       {
         /* existing request has higher TTL, drop new one! */
         prd->priority += priority;
-#if DEBUG_FS
         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                     "Have existing request with higher TTL, dropping new request.\n",
                     GNUNET_i2s (other));
-#endif
         GNUNET_STATISTICS_update (GSF_stats,
                                   gettext_noop
                                   ("# requests dropped due to higher-TTL request"),
@@ -1275,21 +1295,9 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other,
         return NULL;
       }
       /* existing request has lower TTL, drop old one! */
-      GNUNET_STATISTICS_update (GSF_stats,
-                                gettext_noop ("# P2P searches active"), -1,
-                                GNUNET_NO);
       priority += prd->priority;
       GSF_pending_request_cancel_ (pr, GNUNET_YES);
-      GNUNET_assert (GNUNET_YES ==
-                     GNUNET_CONTAINER_multihashmap_remove (cp->request_map,
-                                                           &gm->query,
-                                                           peerreq));
-      if (peerreq->kill_task != GNUNET_SCHEDULER_NO_TASK)
-      {
-        GNUNET_SCHEDULER_cancel (peerreq->kill_task);
-        peerreq->kill_task = GNUNET_SCHEDULER_NO_TASK;
-      }
-      GNUNET_free (peerreq);
+      free_pending_request (peerreq, &gm->query);
     }
   }
 
@@ -1301,7 +1309,7 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other,
                                      0) ? (const char *) &opt[bits] : NULL,
                                     bfsize, ntohl (gm->filter_mutator),
                                     1 /* anonymity */ ,
-                                    (uint32_t) priority, ttl, spid, NULL, 0,    /* replies_seen */
+                                    (uint32_t) priority, ttl, spid, GNUNET_PEER_intern (other), NULL, 0,        /* replies_seen */
                                     &handle_p2p_reply, peerreq);
   GNUNET_assert (NULL != pr);
   peerreq->pr = pr;
@@ -1332,10 +1340,8 @@ peer_transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   struct GSF_PeerTransmitHandle *pth = cls;
   struct GSF_ConnectedPeer *cp;
 
-#if DEBUG_FS
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Timeout trying to transmit to other peer\n");
-#endif
   pth->timeout_task = GNUNET_SCHEDULER_NO_TASK;
   cp = pth->cp;
   GNUNET_CONTAINER_DLL_remove (cp->pth_head, cp->pth_tail, pth);
@@ -1502,32 +1508,6 @@ GSF_peer_update_responder_peer_ (struct GSF_ConnectedPeer *cp,
 }
 
 
-/**
- * Method called whenever a given peer has a status change.
- *
- * @param cls closure
- * @param peer peer identity this notification is about
- * @param bandwidth_in available amount of inbound bandwidth
- * @param bandwidth_out available amount of outbound bandwidth
- * @param timeout absolute time when this peer will time out
- *        unless we see some further activity from it
- * @param atsi status information
- */
-void
-GSF_peer_status_handler_ (void *cls, const struct GNUNET_PeerIdentity *peer,
-                          struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
-                          struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
-                          struct GNUNET_TIME_Absolute timeout,
-                          const struct GNUNET_TRANSPORT_ATS_Information *atsi)
-{
-  struct GSF_ConnectedPeer *cp;
-
-  cp = GNUNET_CONTAINER_multihashmap_get (cp_map, &peer->hashPubKey);
-  GNUNET_assert (NULL != cp);
-  update_atsi (cp, atsi);
-}
-
-
 /**
  * A peer disconnected from us.  Tear down the connected peer
  * record.
@@ -1542,27 +1522,30 @@ GSF_peer_disconnect_handler_ (void *cls, const struct GNUNET_PeerIdentity *peer)
   struct GSF_PeerTransmitHandle *pth;
   struct GSF_DelayedHandle *dh;
 
-  cp = GNUNET_CONTAINER_multihashmap_get (cp_map, &peer->hashPubKey);
+  cp = GSF_peer_get_ (peer);
   if (NULL == cp)
     return;                     /* must have been disconnect from core with
                                  * 'peer' == my_id, ignore */
   GNUNET_assert (GNUNET_YES ==
                  GNUNET_CONTAINER_multihashmap_remove (cp_map,
                                                        &peer->hashPubKey, cp));
+  GNUNET_STATISTICS_set (GSF_stats, gettext_noop ("# peers connected"),
+                         GNUNET_CONTAINER_multihashmap_size (cp_map),
+                         GNUNET_NO);
   if (NULL != cp->migration_pth)
   {
     GSF_peer_transmit_cancel_ (cp->migration_pth);
     cp->migration_pth = NULL;
   }
-  if (NULL != cp->irc)
+  if (NULL != cp->rc)
   {
-    GNUNET_ATS_peer_change_preference_cancel (cp->irc);
-    cp->irc = NULL;
+    GNUNET_ATS_reserve_bandwidth_cancel (cp->rc);
+    cp->rc = NULL;
   }
-  if (GNUNET_SCHEDULER_NO_TASK != cp->irc_delay_task)
+  if (GNUNET_SCHEDULER_NO_TASK != cp->rc_delay_task)
   {
-    GNUNET_SCHEDULER_cancel (cp->irc_delay_task);
-    cp->irc_delay_task = GNUNET_SCHEDULER_NO_TASK;
+    GNUNET_SCHEDULER_cancel (cp->rc_delay_task);
+    cp->rc_delay_task = GNUNET_SCHEDULER_NO_TASK;
   }
   GNUNET_CONTAINER_multihashmap_iterate (cp->request_map,
                                          &cancel_pending_request, cp);
@@ -1700,6 +1683,9 @@ create_migration_stop_message (void *cls, size_t size, void *buf)
       GNUNET_TIME_relative_hton (GNUNET_TIME_absolute_get_remaining
                                  (cp->last_migration_block));
   memcpy (buf, &msm, sizeof (struct MigrationStopMessage));
+  GNUNET_STATISTICS_update (GSF_stats,
+                            gettext_noop ("# migration stop messages sent"),
+                            1, GNUNET_NO);
   return sizeof (struct MigrationStopMessage);
 }
 
@@ -1713,25 +1699,20 @@ create_migration_stop_message (void *cls, size_t size, void *buf)
  */
 void
 GSF_block_peer_migration_ (struct GSF_ConnectedPeer *cp,
-                           struct GNUNET_TIME_Relative block_time)
+                           struct GNUNET_TIME_Absolute block_time)
 {
-  if (GNUNET_TIME_absolute_get_remaining (cp->last_migration_block).rel_value >
-      block_time.rel_value)
+  if (cp->last_migration_block.abs_value > block_time.abs_value)
   {
-#if DEBUG_FS && 0
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Migration already blocked for another %llu ms\n",
                 (unsigned long long)
                 GNUNET_TIME_absolute_get_remaining
                 (cp->last_migration_block).rel_value);
-#endif
     return;                     /* already blocked */
   }
-#if DEBUG_FS && 0
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking to stop migration for %llu ms\n",
-              (unsigned long long) block_time.rel_value);
-#endif
-  cp->last_migration_block = GNUNET_TIME_relative_to_absolute (block_time);
+              (unsigned long long) GNUNET_TIME_absolute_get_remaining (block_time).rel_value);
+  cp->last_migration_block = block_time;
   if (cp->migration_pth != NULL)
     GSF_peer_transmit_cancel_ (cp->migration_pth);
   cp->migration_pth =
@@ -1819,7 +1800,9 @@ cron_flush_trust (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
     return;
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
     return;
-  GNUNET_SCHEDULER_add_delayed (TRUST_FLUSH_FREQ, &cron_flush_trust, NULL);
+  GNUNET_SCHEDULER_add_delayed_with_priority (TRUST_FLUSH_FREQ,
+                                             GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                             &cron_flush_trust, NULL);
 }
 
 
@@ -1830,7 +1813,7 @@ void
 GSF_connected_peer_init_ ()
 {
   cp_map = GNUNET_CONTAINER_multihashmap_create (128);
-  ats = GNUNET_ATS_init (GSF_cfg, NULL, NULL);
+  ats = GNUNET_ATS_performance_init (GSF_cfg, NULL, NULL);
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_CONFIGURATION_get_value_filename (GSF_cfg, "fs",
                                                           "TRUST",
@@ -1869,7 +1852,7 @@ GSF_connected_peer_done_ ()
   cp_map = NULL;
   GNUNET_free (trustDirectory);
   trustDirectory = NULL;
-  GNUNET_ATS_shutdown (ats);
+  GNUNET_ATS_performance_done (ats);
   ats = NULL;
 }