naming
[oweals/gnunet.git] / src / dht / gnunet-service-dht_routing.c
index 1d43cfd3dc8fd4774638989e965b13ab7c3270c3..607c756c61a9508a7a8a8bb107ec1741e0a86201 100644 (file)
  * @brief GNUnet DHT tracking of requests for routing replies
  * @author Christian Grothoff
  */
-
+#include "platform.h"
+#include "gnunet-service-dht_neighbours.h"
 #include "gnunet-service-dht_routing.h"
+#include "gnunet-service-dht.h"
 
 
 /**
@@ -81,6 +83,11 @@ struct RecentRequest
    */
   uint32_t reply_bf_mutator;
 
+  /**
+   * Request options.
+   */
+  enum GNUNET_DHT_RouteOption options;
+
 };
 
 
@@ -118,7 +125,7 @@ struct ProcessContext
   /**
    * Expiration time of the result.
    */
-  GNUNET_TIME_Absolute expiration_time;
+  struct GNUNET_TIME_Absolute expiration_time;
 
   /**
    * Number of entries in 'put_path'.
@@ -160,13 +167,45 @@ process (void *cls,
   struct ProcessContext *pc = cls;
   struct RecentRequest *rr = value;
   enum GNUNET_BLOCK_EvaluationResult eval;
+  unsigned int gpl;
+  unsigned int ppl;
+  GNUNET_HashCode hc;
+  const GNUNET_HashCode *eval_key;
 
   if ( (rr->type != GNUNET_BLOCK_TYPE_ANY) &&
        (rr->type != pc->type) )
     return GNUNET_OK; /* type missmatch */
-  eval = GNUNET_BLOCK_evaluate (block_context,
+
+  if (0 != (rr->options & GNUNET_DHT_RO_RECORD_ROUTE))
+  {
+    gpl = pc->get_path_length;
+    ppl = pc->put_path_length;
+  }
+  else
+  {
+    gpl = 0;
+    ppl = 0;
+  }
+  if ( (0 != (rr->options & GNUNET_DHT_RO_FIND_PEER)) &&
+       (pc->type == GNUNET_BLOCK_TYPE_DHT_HELLO) )
+  {
+    /* key may not match HELLO, which is OK since
+       the search is approximate.  Still, the evaluation
+       would fail since the match is not exact.  So 
+       we fake it by changing the key to the actual PID ... */
+    GNUNET_BLOCK_get_key (GDS_block_context,
+                         GNUNET_BLOCK_TYPE_DHT_HELLO,
+                         pc->data, pc->data_size,
+                         &hc);
+    eval_key = &hc;
+  }
+  else
+  {
+    eval_key = key;
+  }
+  eval = GNUNET_BLOCK_evaluate (GDS_block_context,
                                pc->type,
-                               key,
+                               eval_key,
                                &rr->reply_bf,
                                rr->reply_bf_mutator,
                                rr->xquery,
@@ -177,27 +216,38 @@ process (void *cls,
   {
   case GNUNET_BLOCK_EVALUATION_OK_MORE:
   case GNUNET_BLOCK_EVALUATION_OK_LAST:
-    GDS_NEIGHBOURS_handle_reply (&rr->target,
+    GNUNET_STATISTICS_update (GDS_stats,
+                             gettext_noop ("# Good REPLIES matched against routing table"), 1,
+                             GNUNET_NO);
+    GDS_NEIGHBOURS_handle_reply (&rr->peer,
                                 pc->type,
                                 pc->expiration_time,
                                 key,
-                                pc->put_path_length,
+                                ppl,
                                 pc->put_path,
-                                pc->get_path_length,
+                                gpl,
                                 pc->get_path,
                                 pc->data,
                                 pc->data_size);
     break;
   case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
+    GNUNET_STATISTICS_update (GDS_stats,
+                             gettext_noop ("# Duplicate REPLIES matched against routing table"), 1,
+                             GNUNET_NO);
     return GNUNET_OK;
   case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
-    GNUNET_break_op (0);
+    GNUNET_STATISTICS_update (GDS_stats,
+                             gettext_noop ("# Invalid REPLIES matched against routing table"), 1,
+                             GNUNET_NO);
     return GNUNET_SYSERR;
   case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
-  case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
+  case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
     GNUNET_break (0);
     return GNUNET_OK;
   case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
+    GNUNET_STATISTICS_update (GDS_stats,
+                             gettext_noop ("# Unsupported REPLIES matched against routing table"), 1,
+                             GNUNET_NO);
     return GNUNET_SYSERR;
   default:
     GNUNET_break (0);
@@ -226,7 +276,7 @@ process (void *cls,
  */
 void
 GDS_ROUTING_process (enum GNUNET_BLOCK_Type type,
-                    GNUNET_TIME_Absolute expiration_time,
+                    struct GNUNET_TIME_Absolute expiration_time,
                     const GNUNET_HashCode *key,
                     unsigned int put_path_length,
                     const struct GNUNET_PeerIdentity *put_path,
@@ -245,10 +295,10 @@ GDS_ROUTING_process (enum GNUNET_BLOCK_Type type,
   pc.get_path = get_path;
   pc.data = data;
   pc.data_size = data_size;
-  GNUNET_CONTAINER_multihashmap_iterate (recent_map,
-                                        key,
-                                        &process,
-                                        &pc);
+  GNUNET_CONTAINER_multihashmap_get_multiple (recent_map,
+                                             key,
+                                             &process,
+                                             &pc);
 }
 
 
@@ -257,6 +307,7 @@ GDS_ROUTING_process (enum GNUNET_BLOCK_Type type,
  *
  * @param sender peer that originated the request
  * @param type type of the block
+ * @param options options for processing
  * @param key key for the content
  * @param xquery extended query
  * @param xquery_size number of bytes in xquery
@@ -264,8 +315,9 @@ GDS_ROUTING_process (enum GNUNET_BLOCK_Type type,
  * @param reply_bf_mutator mutator for reply_bf
 */
 void
-GDS_ROUTING_add (const GNUNET_PeerIdentity *sender,
+GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender,
                 enum GNUNET_BLOCK_Type type,
+                enum GNUNET_DHT_RouteOption options,
                 const GNUNET_HashCode *key,
                 const void *xquery,
                 size_t xquery_size,
@@ -276,13 +328,19 @@ GDS_ROUTING_add (const GNUNET_PeerIdentity *sender,
 
   while (GNUNET_CONTAINER_heap_get_size (recent_heap) >= DHT_MAX_RECENT)
   {
+    GNUNET_STATISTICS_update (GDS_stats,
+                             gettext_noop ("# Entries removed from routing table"), 1,
+                             GNUNET_NO);
     recent_req = GNUNET_CONTAINER_heap_peek (recent_heap);
     GNUNET_assert (recent_req != NULL);
     GNUNET_CONTAINER_heap_remove_node (recent_req->heap_node);
-    GNUNET_CONTAINER_bloomfilter_free (recent_req->bloom);
+    GNUNET_CONTAINER_bloomfilter_free (recent_req->reply_bf);
     GNUNET_free (recent_req);
   }
 
+  GNUNET_STATISTICS_update (GDS_stats,
+                           gettext_noop ("# Entries added to routing table"), 1,
+                           GNUNET_NO);
   recent_req = GNUNET_malloc (sizeof (struct RecentRequest) + xquery_size);
   recent_req->peer = *sender;
   recent_req->key = *key;
@@ -292,6 +350,7 @@ GDS_ROUTING_add (const GNUNET_PeerIdentity *sender,
   recent_req->reply_bf =
     GNUNET_CONTAINER_bloomfilter_copy (reply_bf);
   recent_req->type = type;
+  recent_req->options = options;
   recent_req->xquery = &recent_req[1];
   recent_req->xquery_size = xquery_size;
   recent_req->reply_bf_mutator = reply_bf_mutator;
@@ -313,7 +372,7 @@ GDS_ROUTING_init ()
   recent_heap =
     GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
   recent_map =
-      GNUNET_CONTAINER_multihashmap_create (MAX_BUCKETS / 8);
+      GNUNET_CONTAINER_multihashmap_create (DHT_MAX_RECENT * 4 / 3);
 }
 
 
@@ -327,13 +386,16 @@ GDS_ROUTING_done ()
 
   while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0)
   {
+    GNUNET_STATISTICS_update (GDS_stats,
+                             gettext_noop ("# Entries removed from routing table"), 1,
+                             GNUNET_NO);
     recent_req = GNUNET_CONTAINER_heap_peek (recent_heap);
     GNUNET_assert (recent_req != NULL);
     GNUNET_CONTAINER_heap_remove_node (recent_req->heap_node);
-    GNUNET_CONTAINER_bloomfilter_free (recent_req->bloom);
+    GNUNET_CONTAINER_bloomfilter_free (recent_req->reply_bf);
     GNUNET_free (recent_req);
   }
-  GNUNET_assert (0 == GNUNET_CONTAINER_heap_size (recent_heap));
+  GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (recent_heap));
   GNUNET_CONTAINER_heap_destroy (recent_heap);
   recent_heap = NULL;
   GNUNET_CONTAINER_multihashmap_destroy (recent_map);