Merge branch 'master' of ssh://gnunet.org/gnunet
[oweals/gnunet.git] / src / dht / gnunet-service-dht_clients.c
index 0e344b566c868ebaea38c40132fe0012403bb0ee..0f521a4015aa0e0b04311ccb00a05a92da550d65 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2009, 2010, 2011, 2016 GNUnet e.V.
+     Copyright (C) 2009, 2010, 2011, 2016, 2017 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -213,6 +213,25 @@ struct ClientHandle
 
 };
 
+/**
+ * Our handle to the BLOCK library.
+ */
+struct GNUNET_BLOCK_Context *GDS_block_context;
+
+/**
+ * Handle for the statistics service.
+ */
+struct GNUNET_STATISTICS_Handle *GDS_stats;
+
+/**
+ * Handle for the service.
+ */
+struct GNUNET_SERVICE_Handle *GDS_service;
+
+/**
+ * The configuration the DHT service is running with
+ */
+const struct GNUNET_CONFIGURATION_Handle *GDS_cfg;
 
 /**
  * List of active monitoring requests.
@@ -343,21 +362,25 @@ client_disconnect_cb (void *cls,
 static void
 transmit_request (struct ClientQueryRecord *cqr)
 {
-  int32_t reply_bf_mutator;
-  struct GNUNET_CONTAINER_BloomFilter *reply_bf;
+  struct GNUNET_BLOCK_Group *bg;
   struct GNUNET_CONTAINER_BloomFilter *peer_bf;
 
   GNUNET_STATISTICS_update (GDS_stats,
                             gettext_noop ("# GET requests from clients injected"),
                             1,
                             GNUNET_NO);
-  reply_bf_mutator =
-      (int32_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
-                                          UINT32_MAX);
-  reply_bf
-    = GNUNET_BLOCK_construct_bloomfilter (reply_bf_mutator,
-                                          cqr->seen_replies,
-                                          cqr->seen_replies_count);
+  bg = GNUNET_BLOCK_group_create (GDS_block_context,
+                                  cqr->type,
+                                  GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
+                                                            UINT32_MAX),
+                                  NULL,
+                                  0,
+                                  "seen-set-size",
+                                  cqr->seen_replies_count,
+                                  NULL);
+  GNUNET_BLOCK_group_set_seen (bg,
+                               cqr->seen_replies,
+                               cqr->seen_replies_count);
   peer_bf
     = GNUNET_CONTAINER_bloomfilter_init (NULL,
                                          DHT_BLOOM_SIZE,
@@ -374,10 +397,9 @@ transmit_request (struct ClientQueryRecord *cqr)
                              &cqr->key,
                              cqr->xquery,
                              cqr->xquery_size,
-                             reply_bf,
-                             reply_bf_mutator,
+                             bg,
                              peer_bf);
-  GNUNET_CONTAINER_bloomfilter_free (reply_bf);
+  GNUNET_BLOCK_group_destroy (bg);
   GNUNET_CONTAINER_bloomfilter_free (peer_bf);
 
   /* exponential back-off for retries.
@@ -407,19 +429,20 @@ transmit_next_request_task (void *cls)
     delay = GNUNET_TIME_absolute_get_remaining (cqr->retry_time);
     if (delay.rel_value_us > 0)
     {
-      cqr->hnode =
-          GNUNET_CONTAINER_heap_insert (retry_heap,
+      cqr->hnode
+        = GNUNET_CONTAINER_heap_insert (retry_heap,
                                         cqr,
                                         cqr->retry_time.abs_value_us);
-      retry_task =
-          GNUNET_SCHEDULER_add_delayed (delay,
-                                        &transmit_next_request_task,
-                                        NULL);
+      retry_task
+        = GNUNET_SCHEDULER_add_at (cqr->retry_time,
+                                   &transmit_next_request_task,
+                                   NULL);
       return;
     }
     transmit_request (cqr);
     cqr->hnode
-      = GNUNET_CONTAINER_heap_insert (retry_heap, cqr,
+      = GNUNET_CONTAINER_heap_insert (retry_heap,
+                                      cqr,
                                       cqr->retry_time.abs_value_us);
   }
 }
@@ -496,7 +519,7 @@ handle_dht_local_put (void *cls,
                              ntohl (dht_msg->options),
                              ntohl (dht_msg->desired_replication_level),
                              GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
-                             0 /* hop count */ ,
+                             0 /* hop count */,
                              peer_bf,
                              &dht_msg->key,
                              0,
@@ -540,6 +563,43 @@ check_dht_local_get (void *cls,
 }
 
 
+/**
+ * Handle a result from local datacache for a GET operation.
+ *
+ * @param cls the `struct ClientHandle` of the client doing the query
+ * @param type type of the block
+ * @param expiration_time when does the content expire
+ * @param key key for the content
+ * @param put_path_length number of entries in @a put_path
+ * @param put_path peers the original PUT traversed (if tracked)
+ * @param get_path_length number of entries in @a get_path
+ * @param get_path peers this reply has traversed so far (if tracked)
+ * @param data payload of the reply
+ * @param data_size number of bytes in @a data
+ */
+static void
+handle_local_result (void *cls,
+                     enum GNUNET_BLOCK_Type type,
+                     struct GNUNET_TIME_Absolute expiration_time,
+                     const struct GNUNET_HashCode *key,
+                     unsigned int put_path_length,
+                     const struct GNUNET_PeerIdentity *put_path,
+                     unsigned int get_path_length,
+                     const struct GNUNET_PeerIdentity *get_path,
+                     const void *data,
+                     size_t data_size)
+{
+  // FIXME: this needs some clean up: inline the function,
+  // possibly avoid even looking up the client!
+  GDS_CLIENTS_handle_reply (expiration_time,
+                            key,
+                            0, NULL,
+                            put_path_length, put_path,
+                            type,
+                            data_size, data);
+}
+
+
 /**
  * Handler for DHT GET messages from the client.
  *
@@ -611,7 +671,8 @@ handle_dht_local_get (void *cls,
                            cqr->xquery,
                            xquery_size,
                             NULL,
-                           0);
+                            &handle_local_result,
+                            ch);
   GNUNET_SERVICE_client_continue (ch->client);
 }
 
@@ -993,10 +1054,9 @@ forward_reply (void *cls,
   eval
     = GNUNET_BLOCK_evaluate (GDS_block_context,
                              record->type,
+                             NULL,
                              GNUNET_BLOCK_EO_NONE,
                              key,
-                             NULL,
-                             0,
                              record->xquery,
                              record->xquery_size,
                              frc->data,
@@ -1413,11 +1473,12 @@ GDS_CLIENTS_stop ()
 /**
  * Define "main" method using service macro.
  *
+ * @param name name of the service, i.e. "dht" or "xdht"
  * @param run name of the initializaton method for the service
  */
-#define GDS_DHT_SERVICE_INIT(run)   \
+#define GDS_DHT_SERVICE_INIT(name,run)          \
  GNUNET_SERVICE_MAIN \
-  ("dht", \
+  (name, \
   GNUNET_SERVICE_OPTION_NONE, \
   run, \
   &client_connect_cb, \