print stat
[oweals/gnunet.git] / src / dht / gnunet-service-dht_neighbours.c
index e31c17f48556bf662f2a6cc3586af9fc2ab96ee8..e1491a263d96742cabd9335ba7398969ec78c22e 100644 (file)
@@ -56,7 +56,7 @@
 /**
  * What is the maximum number of peers in a given bucket.
  */
-#define DEFAULT_BUCKET_SIZE 4
+#define DEFAULT_BUCKET_SIZE 8
 
 /**
  * Desired replication level for FIND PEER requests
@@ -412,6 +412,7 @@ static struct GNUNET_PeerIdentity my_identity;
 static struct GNUNET_CORE_Handle *coreAPI;
 
 
+
 /**
  * Find the optimal bucket for this key.
  *
@@ -502,7 +503,10 @@ update_core_preference (void *cls,
   if (bucket == GNUNET_SYSERR)
     preference = 0;
   else
+  {
+    GNUNET_assert (k_buckets[bucket].peers_size != 0);
     preference = (1LL << matching) / k_buckets[bucket].peers_size;
+  }
   if (preference == 0)
     {
       peer->preference_task
@@ -555,6 +559,10 @@ add_known_to_bloom (void *cls, const GNUNET_HashCode * key, void *value)
   GNUNET_HashCode mh;
 
   GNUNET_BLOCK_mingle_hash (key, ctx->bf_mutator, &mh);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Adding known peer (%s) to bloomfilter for FIND PEER with mutation %u\n",
+             GNUNET_h2s (key),
+             ctx->bf_mutator);
   GNUNET_CONTAINER_bloomfilter_add (ctx->bloom, &mh);
   return GNUNET_YES;
 }
@@ -639,6 +647,10 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer,
   /* Check for connect to self message */
   if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
     return;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Connected %s to %s\n",
+             GNUNET_i2s (&my_identity),
+             GNUNET_h2s (&peer->hashPubKey));
   if (GNUNET_YES ==
       GNUNET_CONTAINER_multihashmap_contains (all_known_peers,
                                               &peer->hashPubKey))
@@ -646,9 +658,6 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer,
     GNUNET_break (0);
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-             "Peer `%s' connected!\n",
-             GNUNET_i2s (peer));
   GNUNET_STATISTICS_update (GDS_stats,
                            gettext_noop ("# Peers connected"), 1,
                            GNUNET_NO);
@@ -696,10 +705,15 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
   struct PeerInfo *to_remove;
   int current_bucket;
   struct P2PPendingMessage *pos;
+  unsigned int discarded;
 
   /* Check for disconnect from self message */
   if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
     return;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Disconnected %s from %s\n",
+             GNUNET_i2s (&my_identity),
+             GNUNET_h2s (&peer->hashPubKey));
   to_remove =
       GNUNET_CONTAINER_multihashmap_get (all_known_peers, &peer->hashPubKey);
   if (NULL == to_remove)
@@ -707,9 +721,6 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
       GNUNET_break (0);
       return;
     }
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-             "Peer `%s' disconnected!\n",
-             GNUNET_i2s (peer));
   GNUNET_STATISTICS_update (GDS_stats,
                            gettext_noop ("# Peers connected"), -1,
                            GNUNET_NO);
@@ -742,13 +753,19 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
     GNUNET_CORE_notify_transmit_ready_cancel (to_remove->th);
     to_remove->th = NULL;
   }
+  discarded = 0;
   while (NULL != (pos = to_remove->head))
   {
     GNUNET_CONTAINER_DLL_remove (to_remove->head,
                                 to_remove->tail,
                                 pos);
+    discarded++;
     GNUNET_free (pos);
   }
+  GNUNET_STATISTICS_update (GDS_stats,
+                           gettext_noop ("# Queued messages discarded (peer disconnected)"), discarded,
+                           GNUNET_NO);
+  GNUNET_free (to_remove);
 }
 
 
@@ -771,16 +788,29 @@ core_transmit_notify (void *cls, size_t size, void *buf)
   size_t msize;
 
   peer->th = NULL;
-  if (buf == NULL)
+  while ( (NULL != (pending = peer->head)) &&
+         (GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value == 0) )
   {
-    /* client disconnected */
-    return 0;
+    peer->pending_count--;
+    GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
+    GNUNET_free (pending);
   }
-  if (peer->head == NULL)
+  if (pending == NULL)
   {
     /* no messages pending */
     return 0;
   }
+  if (buf == NULL)
+  {
+    peer->th 
+      = GNUNET_CORE_notify_transmit_ready (coreAPI, GNUNET_YES,
+                                          pending->importance,
+                                          GNUNET_TIME_absolute_get_remaining (pending->timeout),
+                                          &peer->id, ntohs (pending->msg->size),
+                                          &core_transmit_notify, peer);
+    GNUNET_break (NULL != peer->th);
+    return 0;
+  }
   off = 0;
   while ( (NULL != (pending = peer->head)) &&
          (size - off >= (msize = ntohs (pending->msg->size))) )
@@ -795,14 +825,15 @@ core_transmit_notify (void *cls, size_t size, void *buf)
     GNUNET_free (pending);
   }
   if (peer->head != NULL)
-    {
-      peer->th 
-       = GNUNET_CORE_notify_transmit_ready (coreAPI, GNUNET_YES,
-                                            pending->importance,
-                                            GNUNET_TIME_absolute_get_remaining (pending->timeout),
-                                            &peer->id, msize,
-                                            &core_transmit_notify, peer);
-    }
+  {
+    peer->th 
+      = GNUNET_CORE_notify_transmit_ready (coreAPI, GNUNET_YES,
+                                          pending->importance,
+                                          GNUNET_TIME_absolute_get_remaining (pending->timeout),
+                                          &peer->id, msize,
+                                          &core_transmit_notify, peer);
+    GNUNET_break (NULL != peer->th);
+  }
   return off;
 }
 
@@ -832,6 +863,7 @@ process_peer_queue (struct PeerInfo *peer)
                                         &peer->id,
                                         ntohs (pending->msg->size),
                                         &core_transmit_notify, peer);
+  GNUNET_break (NULL != peer->th);
 }
 
 
@@ -851,12 +883,12 @@ get_forward_count (uint32_t hop_count,
   uint32_t forward_count;
   float target_value;
 
-  if (hop_count > GDS_NSE_get () * 4.0)
+  if (hop_count > GDS_NSE_get () * 6.0)
   {
     /* forcefully terminate */
     return 0;
   }
-  if (hop_count > GDS_NSE_get () * 2.0)
+  if (hop_count > GDS_NSE_get () * 4.0)
   {
     /* Once we have reached our ideal number of hops, only forward to 1 peer */
     return 1;
@@ -1021,15 +1053,16 @@ select_peer (const GNUNET_HashCode *key,
     /* greedy selection (closest peer that is not in bloomfilter) */
     smallest_distance = UINT_MAX;
     chosen = NULL;
-    for (bc = closest_bucket; bc < MAX_BUCKETS; bc++)
+    for (bc = 0; bc < closest_bucket; bc++)
     {
       pos = k_buckets[bc].head;
       count = 0;
       while ((pos != NULL) && (count < bucket_size))
       {
-        if (GNUNET_NO ==
-            GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
-        {
+        if ( (bloom == NULL) ||
+            (GNUNET_NO ==
+             GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) )
+       {
           dist = get_distance (key, &pos->id.hashPubKey);
           if (dist < smallest_distance)
           {
@@ -1038,7 +1071,11 @@ select_peer (const GNUNET_HashCode *key,
           }
         }
         else
-        {
+       {
+         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                     "Excluded peer `%s' due to BF match in greedy routing for %s\n",
+                     GNUNET_i2s (&pos->id),
+                     GNUNET_h2s (key));
          GNUNET_STATISTICS_update (GDS_stats,
                                    gettext_noop ("# Peers excluded from routing due to Bloomfilter"), 1,
                                    GNUNET_NO);
@@ -1069,6 +1106,10 @@ select_peer (const GNUNET_HashCode *key,
        GNUNET_STATISTICS_update (GDS_stats,
                                  gettext_noop ("# Peers excluded from routing due to Bloomfilter"), 1,
                                  GNUNET_NO);
+       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                   "Excluded peer `%s' due to BF match in random routing for %s\n",
+                   GNUNET_i2s (&pos->id),
+                   GNUNET_h2s (key));
         pos = pos->next;
         continue;               /* Ignore bloomfiltered peers */
       }
@@ -1141,17 +1182,23 @@ get_target_peers (const GNUNET_HashCode *key,
     return 0;
   }
   rtargets = GNUNET_malloc (sizeof (struct PeerInfo*) * ret);
-  off = 0;
-  while (ret-- > 0)
+  for (off = 0; off < ret; off++)
   {
     nxt = select_peer (key, bloom, hop_count);
     if (nxt == NULL)
       break;      
-    rtargets[off++] = nxt;
+    rtargets[off] = nxt;
     GNUNET_break (GNUNET_NO ==
                  GNUNET_CONTAINER_bloomfilter_test (bloom, &nxt->id.hashPubKey));
-    GNUNET_CONTAINER_bloomfilter_add (bloom, &nxt->id.hashPubKey);
+    GNUNET_CONTAINER_bloomfilter_add (bloom, &rtargets[off]->id.hashPubKey);
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Selected %u/%u peers at hop %u for %s (target was %u)\n",
+             off,
+             GNUNET_CONTAINER_multihashmap_size (all_known_peers),
+             (unsigned int) hop_count,
+             GNUNET_h2s (key),
+             ret);
   if (0 == off)
   {
     GNUNET_free (rtargets);
@@ -1205,6 +1252,10 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
   struct GNUNET_PeerIdentity *pp;
   
   GNUNET_assert (NULL != bf);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Adding myself (%s) to PUT bloomfilter for %s\n",
+             GNUNET_i2s (&my_identity),
+             GNUNET_h2s (key));
   GNUNET_CONTAINER_bloomfilter_add (bf, &my_identity.hashPubKey);
   GNUNET_STATISTICS_update (GDS_stats,
                            gettext_noop ("# PUT requests routed"), 1,
@@ -1213,12 +1264,12 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
                                   desired_replication_level,
                                   &targets);
   if (0 == target_count)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                 "Not forwarding PUT for `%s' after %u hops (NSE: %f)!\n",
+    { 
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Routing PUT for %s terminates after %u hops at %s\n",
                  GNUNET_h2s (key),
-                 hop_count,
-                 GDS_NSE_get());
+                 (unsigned int) hop_count,
+                 GNUNET_i2s (&my_identity));
       return;
     }
   msize = put_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size + sizeof (struct PeerPutMessage);
@@ -1233,11 +1284,16 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
     return;
   }
   GNUNET_STATISTICS_update (GDS_stats,
-                           gettext_noop ("# Peers selected as targets for PUT requests"), target_count,
+                           gettext_noop ("# PUT messages queued for transmission"), target_count,
                            GNUNET_NO);
   for (i=0;i<target_count;i++)
   {
     target = targets[i];
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+               "Routing PUT for %s after %u hops to %s\n",
+               GNUNET_h2s (key),
+               (unsigned int) hop_count,
+               GNUNET_i2s (&target->id));
     pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
     pending->importance = 0; /* FIXME */
     pending->timeout = expiration_time;   
@@ -1310,19 +1366,24 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
   size_t reply_bf_size;
 
   GNUNET_assert (NULL != peer_bf);  
-  GNUNET_CONTAINER_bloomfilter_add (peer_bf, &my_identity.hashPubKey);
   GNUNET_STATISTICS_update (GDS_stats,
                            gettext_noop ("# GET requests routed"), 1,
                            GNUNET_NO);
   target_count = get_target_peers (key, peer_bf, hop_count,
                                   desired_replication_level,
                                   &targets);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Adding myself (%s) to GET bloomfilter for %s\n",
+             GNUNET_i2s (&my_identity),
+             GNUNET_h2s (key));
+  GNUNET_CONTAINER_bloomfilter_add (peer_bf, &my_identity.hashPubKey);
   if (0 == target_count)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                 "Not forwarding GET for `%s' after %u hops!\n",
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Routing GET for %s terminates after %u hops at %s\n",
                  GNUNET_h2s (key),
-                 hop_count);
+                 (unsigned int) hop_count,
+                 GNUNET_i2s (&my_identity));
       return;
     }
   reply_bf_size = GNUNET_CONTAINER_bloomfilter_get_size (reply_bf);
@@ -1333,12 +1394,17 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
     return;
   }
   GNUNET_STATISTICS_update (GDS_stats,
-                           gettext_noop ("# Peers selected as targets for GET requests"), target_count,
+                           gettext_noop ("# GET messages queued for transmission"), target_count,
                            GNUNET_NO);
   /* forward request */
   for (i=0;i<target_count;i++)
   {
     target = targets[i];
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+               "Routing GET for %s after %u hops to %s\n",
+               GNUNET_h2s (key),
+               (unsigned int) hop_count,
+               GNUNET_i2s (&target->id));
     pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
     pending->importance = 0; /* FIXME */
     pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
@@ -1424,13 +1490,10 @@ GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target,
   if (NULL == pi)
   {
     /* peer disconnected in the meantime, drop reply */
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-               "Not forwarding REPLY for `%s' due to predecessor disconnect\n",
-               GNUNET_h2s (key));
     return;
   }
   GNUNET_STATISTICS_update (GDS_stats,
-                           gettext_noop ("# REPLIES routed"), 1,
+                           gettext_noop ("# RESULT messages queued for transmission"), 1,
                            GNUNET_NO);
   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
   pending->importance = 0; /* FIXME */
@@ -1545,6 +1608,10 @@ handle_dht_p2p_put (void *cls,
     /* cannot verify, good luck */
     break;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "PUT for %s at %s\n",
+             GNUNET_h2s (&put->key),
+             GNUNET_i2s (&my_identity));
   bf = GNUNET_CONTAINER_bloomfilter_init (put->bloomfilter,
                                          DHT_BLOOM_SIZE,
                                          GNUNET_CONSTANTS_BLOOMFILTER_K);
@@ -1586,7 +1653,7 @@ handle_dht_p2p_put (void *cls,
                               options,
                               ntohl (put->desired_replication_level),
                               GNUNET_TIME_absolute_ntoh (put->expiration_time),
-                              ntohl (put->hop_count) + 1 /* who adds +1? */,
+                              ntohl (put->hop_count),
                               bf,
                               &put->key,
                               putlen, pp,
@@ -1667,6 +1734,7 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender,
   {
     GNUNET_assert (peer != NULL);
     peer = peer->next;
+    choice--;
   }
   choice = bucket->peers_size;
   do
@@ -1774,12 +1842,16 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
                   &get->key,
                   xquery, xquery_size,
                   reply_bf, get->bf_mutator);
-
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "GET for %s at %s after %u hops\n",
+             GNUNET_h2s (&get->key),
+             GNUNET_i2s (&my_identity),
+             (unsigned int) ntohl (get->hop_count));
   /* local lookup (this may update the reply_bf) */
   if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
        (am_closest_peer (&get->key,
                         peer_bf) ) )
-  {
+    {
     if ( (0 != (options & GNUNET_DHT_RO_FIND_PEER)))
     {
       GNUNET_STATISTICS_update (GDS_stats,
@@ -1811,7 +1883,7 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
     GDS_NEIGHBOURS_handle_get (type,
                               options,
                               ntohl (get->desired_replication_level),
-                              ntohl (get->hop_count) + 1, /* CHECK: where (else) do we do +1? */
+                              ntohl (get->hop_count),
                               &get->key,
                               xquery, xquery_size,
                               reply_bf,