gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] branch master updated: -non-trivial refactoring/cleanup of the


From: gnunet
Subject: [gnunet] branch master updated: -non-trivial refactoring/cleanup of the DHT code
Date: Sun, 02 Jan 2022 20:24:06 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new e3ff01705 -non-trivial refactoring/cleanup of the DHT code
e3ff01705 is described below

commit e3ff017054eb35dedd95ae4fe66c82b88e3bbdc3
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Jan 2 20:24:02 2022 +0100

    -non-trivial refactoring/cleanup of the DHT code
---
 src/dht/gnunet-service-dht.h            |  68 +---
 src/dht/gnunet-service-dht_clients.c    | 340 +++++-----------
 src/dht/gnunet-service-dht_datacache.c  | 200 +++------
 src/dht/gnunet-service-dht_datacache.h  | 124 +++---
 src/dht/gnunet-service-dht_hello.c      |  18 +-
 src/dht/gnunet-service-dht_neighbours.c | 695 +++++++++++++-------------------
 src/dht/gnunet-service-dht_neighbours.h |  47 +--
 src/dht/gnunet-service-dht_nse.c        |  30 +-
 src/dht/gnunet-service-dht_routing.c    | 200 ++++-----
 src/dht/gnunet-service-dht_routing.h    |  24 +-
 src/include/gnunet_datacache_plugin.h   |  60 ++-
 11 files changed, 653 insertions(+), 1153 deletions(-)

diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h
index 2854131c5..d520cc905 100644
--- a/src/dht/gnunet-service-dht.h
+++ b/src/dht/gnunet-service-dht.h
@@ -26,10 +26,10 @@
 #ifndef GNUNET_SERVICE_DHT_H
 #define GNUNET_SERVICE_DHT_H
 
-#include "gnunet_util_lib.h"
+#include "gnunet-service-dht_datacache.h"
 #include "gnunet_statistics_service.h"
 #include "gnunet_transport_service.h"
-#include "gnunet_block_lib.h"
+
 
 #define DEBUG_DHT GNUNET_EXTRA_LOGGING
 
@@ -64,28 +64,16 @@ extern struct GNUNET_MessageHeader *GDS_my_hello;
  * matches any of our pending queries, forward it to the respective
  * client(s).
  *
- * @param expiration when will the reply expire
- * @param key the key of the query that triggered the reply
- * @param query_hash the query hash of the response
- * @param get_path_length number of peers in @a get_path
- * @param get_path path the reply took on get
- * @param put_path_length number of peers in @a put_path
- * @param put_path path the reply took on put
- * @param type type of the reply
- * @param data_size number of bytes in @a data
- * @param data application payload data
+ * @param bd block details
+ * @param query_hash hash of the original query, might not match key in @a bd
+ * @param get_path_length number of entries in @a get_path
+ * @param get_path path the reply has taken
  */
 void
-GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration,
-                          const struct GNUNET_HashCode *key,
+GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd,
                           const struct GNUNET_HashCode *query_hash,
                           unsigned int get_path_length,
-                          const struct GNUNET_PeerIdentity *get_path,
-                          unsigned int put_path_length,
-                          const struct GNUNET_PeerIdentity *put_path,
-                          enum GNUNET_BLOCK_Type type,
-                          size_t data_size,
-                          const void *data);
+                          const struct GNUNET_PeerIdentity *get_path);
 
 
 /**
@@ -114,26 +102,14 @@ GDS_CLIENTS_process_get (uint32_t options,
  * Check if some client is monitoring GET RESP messages and notify
  * them in that case.
  *
- * @param type The type of data in the result.
+ * @param bd block details
  * @param get_path Peers on GET path (or NULL if not recorded).
  * @param get_path_length number of entries in @a get_path.
- * @param put_path peers on the PUT path (or NULL if not recorded).
- * @param put_path_length number of entries in @a get_path.
- * @param exp Expiration time of the data.
- * @param key Key of the @a data.
- * @param data Pointer to the result data.
- * @param size Number of bytes in @a data.
  */
 void
-GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type,
+GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd,
                               const struct GNUNET_PeerIdentity *get_path,
-                              unsigned int get_path_length,
-                              const struct GNUNET_PeerIdentity *put_path,
-                              unsigned int put_path_length,
-                              struct GNUNET_TIME_Absolute exp,
-                              const struct GNUNET_HashCode *key,
-                              const void *data,
-                              size_t size);
+                              unsigned int get_path_length);
 
 
 /**
@@ -141,27 +117,15 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type,
  * them in that case. The @a path should include our own
  * peer ID (if recorded).
  *
- * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
- * @param type The type of data in the request.
+ * @param options routing options to apply
+ * @param bd details about the block
  * @param hop_count Hop count so far.
- * @param path_length number of entries in path (or 0 if not recorded).
- * @param path peers on the PUT path (or NULL if not recorded).
  * @param desired_replication_level Desired replication level.
- * @param exp Expiration time of the data.
- * @param key Key under which data is to be stored.
- * @param data Pointer to the data carried.
- * @param size Number of bytes in data.
  */
 void
-GDS_CLIENTS_process_put (uint32_t options,
-                         enum GNUNET_BLOCK_Type type,
+GDS_CLIENTS_process_put (enum GNUNET_DHT_RouteOption options,
+                         const struct GDS_DATACACHE_BlockData *bd,
                          uint32_t hop_count,
-                         uint32_t desired_replication_level,
-                         unsigned int path_length,
-                         const struct GNUNET_PeerIdentity *path,
-                         struct GNUNET_TIME_Absolute exp,
-                         const struct GNUNET_HashCode *key,
-                         const void *data,
-                         size_t size);
+                         uint32_t desired_replication_level);
 
 #endif
diff --git a/src/dht/gnunet-service-dht_clients.c 
b/src/dht/gnunet-service-dht_clients.c
index aa41f519c..b520cda41 100644
--- a/src/dht/gnunet-service-dht_clients.c
+++ b/src/dht/gnunet-service-dht_clients.c
@@ -425,6 +425,7 @@ transmit_next_request_task (void *cls)
 {
   struct ClientQueryRecord *cqr;
 
+  (void) cls;
   retry_task = NULL;
   while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap)))
   {
@@ -486,19 +487,23 @@ handle_dht_local_put (void *cls,
 {
   struct ClientHandle *ch = cls;
   uint16_t size = ntohs (dht_msg->header.size);
-  uint32_t type = ntohl (dht_msg->type);
-  struct GNUNET_TIME_Absolute expiration
-    = GNUNET_TIME_absolute_ntoh (dht_msg->expiration);
   enum GNUNET_DHT_RouteOption options
     = (enum GNUNET_DHT_RouteOption) ntohl (dht_msg->options);
   uint32_t replication_level
     = ntohl (dht_msg->desired_replication_level);
+  struct GDS_DATACACHE_BlockData bd = {
+    .key = dht_msg->key,
+    .expiration_time = GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
+    .data = &dht_msg[1],
+    .data_size = size - sizeof (*dht_msg),
+    .type = ntohl (dht_msg->type)
+  };
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Handling local PUT of %lu-bytes for query %s of type %u\n",
        (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)),
        GNUNET_h2s (&dht_msg->key),
-       (unsigned int) type);
+       (unsigned int) bd.type);
   GNUNET_STATISTICS_update (GDS_stats,
                             "# PUT requests received from clients",
                             1,
@@ -507,14 +512,10 @@ handle_dht_local_put (void *cls,
                "CLIENT-PUT %s\n",
                GNUNET_h2s_full (&dht_msg->key));
   /* give to local clients */
-  GDS_CLIENTS_handle_reply (expiration,
-                            &dht_msg->key,
-                            &dht_msg->key,
-                            0, NULL, /* get path */
-                            0, NULL, /* put path */
-                            type,
-                            size - sizeof(struct GNUNET_DHT_ClientPutMessage),
-                            &dht_msg[1]);
+  GDS_CLIENTS_handle_reply (&bd,
+                            &bd.key,
+                            0, NULL /* get path */);
+
   {
     struct GNUNET_CONTAINER_BloomFilter *peer_bf;
 
@@ -526,26 +527,14 @@ handle_dht_local_put (void *cls,
     if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
          (GDS_am_closest_peer (&dht_msg->key,
                                peer_bf)))
-      GDS_DATACACHE_handle_put (
-        expiration,
-        &dht_msg->key,
-        0, NULL,                         /* put path */
-        type,
-        size - sizeof(struct GNUNET_DHT_ClientPutMessage),
-        &dht_msg[1]);
+      GDS_DATACACHE_handle_put (&bd);
     /* route to other peers */
     if (GNUNET_OK !=
-        GDS_NEIGHBOURS_handle_put (
-          type,
-          options,
-          replication_level,
-          expiration,
-          0 /* hop count */,
-          peer_bf,
-          &dht_msg->key,
-          0, NULL,                          /* put path */
-          &dht_msg[1],
-          size - sizeof(struct GNUNET_DHT_ClientPutMessage)))
+        GDS_NEIGHBOURS_handle_put (&bd,
+                                   options,
+                                   replication_level,
+                                   0 /* hop count */,
+                                   peer_bf))
     {
       GNUNET_STATISTICS_update (GDS_stats,
                                 "# Local PUT requests not routed",
@@ -556,15 +545,9 @@ handle_dht_local_put (void *cls,
   }
   GDS_CLIENTS_process_put (
     options,
-    type,
-    0,                        /* hop count */
-    replication_level,
-    1,                        /* path length */
-    GDS_NEIGHBOURS_get_id (),
-    expiration,
-    &dht_msg->key,
-    &dht_msg[1],
-    size - sizeof(struct GNUNET_DHT_ClientPutMessage));
+    &bd,
+    0,  /* hop count */
+    replication_level);
   GNUNET_SERVICE_client_continue (ch->client);
 }
 
@@ -573,37 +556,16 @@ handle_dht_local_put (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
+ * @param bd details about the block that was found
  */
 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)
+                     const struct GDS_DATACACHE_BlockData *bd)
 {
-  // FIXME: this may deserve some clean up: inline the function,
-  // possibly avoid even looking up the client!
-  GDS_CLIENTS_handle_reply (expiration_time,
-                            key,
-                            key,
-                            0, NULL,
-                            put_path_length, put_path,
-                            type,
-                            data_size, data);
+  /* FIXME: use 'cls' instead of looking up the client? */
+  GDS_CLIENTS_handle_reply (bd,
+                            &bd->key,
+                            0, NULL /* get_path */);
 }
 
 
@@ -713,6 +675,9 @@ struct FindByUniqueIdContext
    */
   struct ClientQueryRecord *cqr;
 
+  /**
+   * Unique ID to look for.
+   */
   uint64_t unique_id;
 };
 
@@ -968,49 +933,20 @@ handle_dht_local_monitor_stop (
 struct ForwardReplyContext
 {
   /**
-   * Expiration time of the reply.
+   * Block details.
    */
-  struct GNUNET_TIME_Absolute expiration;
+  const struct GDS_DATACACHE_BlockData *bd;
 
   /**
    * GET path taken.
    */
   const struct GNUNET_PeerIdentity *get_path;
 
-  /**
-   * PUT path taken.
-   */
-  const struct GNUNET_PeerIdentity *put_path;
-
-  /**
-   * Hash under which the payload is stored.
-   */
-  const struct GNUNET_HashCode *query_hash;
-
-  /**
-   * Embedded payload.
-   */
-  const void *data;
-
-  /**
-   * Number of bytes in data.
-   */
-  size_t data_size;
-
   /**
    * Number of entries in @e get_path.
    */
   unsigned int get_path_length;
 
-  /**
-   * Number of entries in @e put_path.
-   */
-  unsigned int put_path_length;
-
-  /**
-   * Type of the data.
-   */
-  enum GNUNET_BLOCK_Type type;
 };
 
 
@@ -1019,15 +955,15 @@ struct ForwardReplyContext
  * each of the matching clients.  With some tricky recycling
  * of the buffer.
  *
- * @param cls the 'struct ForwardReplyContext'
- * @param key current key
+ * @param cls the `struct ForwardReplyContext`
+ * @param query_hash hash of the query for which this may be a reply
  * @param value value in the hash map, a ClientQueryRecord
  * @return #GNUNET_YES (we should continue to iterate),
  *         if the result is mal-formed, #GNUNET_NO
  */
 static enum GNUNET_GenericReturnValue
 forward_reply (void *cls,
-               const struct GNUNET_HashCode *key,
+               const struct GNUNET_HashCode *query_hash,
                void *value)
 {
   struct ForwardReplyContext *frc = cls;
@@ -1041,13 +977,13 @@ forward_reply (void *cls,
 
   LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG,
                "CLIENT-RESULT %s\n",
-               GNUNET_h2s_full (frc->query_hash));
-  if ((record->type != GNUNET_BLOCK_TYPE_ANY) &&
-      (record->type != frc->type))
+               GNUNET_h2s_full (&frc->bd->key));
+  if ( (record->type != GNUNET_BLOCK_TYPE_ANY) &&
+       (record->type != frc->bd->type) )
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Record type mismatch, not passing request for key %s to local 
client\n",
-         GNUNET_h2s (key));
+         GNUNET_h2s (&frc->bd->key));
     GNUNET_STATISTICS_update (GDS_stats,
                               "# Key match, type mismatches in REPLY to 
CLIENT",
                               1,
@@ -1055,8 +991,8 @@ forward_reply (void *cls,
     return GNUNET_YES;          /* type mismatch */
   }
   if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_PEER)) &&
-       (0 != GNUNET_memcmp (key,
-                            frc->query_hash)) )
+       (0 != GNUNET_memcmp (&frc->bd->key,
+                            query_hash)) )
   {
     GNUNET_STATISTICS_update (GDS_stats,
                               "# Inexact key match, but exact match required",
@@ -1064,37 +1000,36 @@ forward_reply (void *cls,
                               GNUNET_NO);
     return GNUNET_YES;          /* type mismatch */
   }
-  GNUNET_CRYPTO_hash (frc->data,
-                      frc->data_size,
+  GNUNET_CRYPTO_hash (frc->bd->data,
+                      frc->bd->data_size,
                       &ch);
   for (unsigned int i = 0; i < record->seen_replies_count; i++)
-    if (0 == memcmp (&record->seen_replies[i],
-                     &ch,
-                     sizeof(struct GNUNET_HashCode)))
+    if (0 ==
+        GNUNET_memcmp (&record->seen_replies[i],
+                       &ch))
     {
       LOG (GNUNET_ERROR_TYPE_DEBUG,
            "Duplicate reply, not passing request for key %s to local client\n",
-           GNUNET_h2s (key));
+           GNUNET_h2s (&frc->bd->key));
       GNUNET_STATISTICS_update (GDS_stats,
-                                gettext_noop
-                                (
-                                  "# Duplicate REPLIES to CLIENT request 
dropped"),
-                                1, GNUNET_NO);
+                                "# Duplicate REPLIES to CLIENT request 
dropped",
+                                1,
+                                GNUNET_NO);
       return GNUNET_YES;        /* duplicate */
     }
   eval
     = GNUNET_BLOCK_check_reply (GDS_block_context,
                                 record->type,
                                 NULL,
-                                key,
+                                &frc->bd->key,
                                 record->xquery,
                                 record->xquery_size,
-                                frc->data,
-                                frc->data_size);
+                                frc->bd->data,
+                                frc->bd->data_size);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Evaluation result is %d for key %s for local client's query\n",
        (int) eval,
-       GNUNET_h2s (key));
+       GNUNET_h2s (&frc->bd->key));
   switch (eval)
   {
   case GNUNET_BLOCK_REPLY_OK_LAST:
@@ -1125,29 +1060,29 @@ forward_reply (void *cls,
                             1,
                             GNUNET_NO);
   env = GNUNET_MQ_msg_extra (reply,
-                             frc->data_size
-                             + (frc->get_path_length + frc->put_path_length)
+                             frc->bd->data_size
+                             + (frc->get_path_length + 
frc->bd->put_path_length)
                              * sizeof(struct GNUNET_PeerIdentity),
                              GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT);
-  reply->type = htonl (frc->type);
+  reply->type = htonl (frc->bd->type);
   reply->get_path_length = htonl (frc->get_path_length);
-  reply->put_path_length = htonl (frc->put_path_length);
+  reply->put_path_length = htonl (frc->bd->put_path_length);
   reply->unique_id = record->unique_id;
-  reply->expiration = GNUNET_TIME_absolute_hton (frc->expiration);
-  reply->key = *key;
+  reply->expiration = GNUNET_TIME_absolute_hton (frc->bd->expiration_time);
+  reply->key = frc->bd->key;
   paths = (struct GNUNET_PeerIdentity *) &reply[1];
   GNUNET_memcpy (paths,
-                 frc->put_path,
-                 sizeof(struct GNUNET_PeerIdentity) * frc->put_path_length);
-  GNUNET_memcpy (&paths[frc->put_path_length],
+                 frc->bd->put_path,
+                 sizeof(struct GNUNET_PeerIdentity) * 
frc->bd->put_path_length);
+  GNUNET_memcpy (&paths[frc->bd->put_path_length],
                  frc->get_path,
                  sizeof(struct GNUNET_PeerIdentity) * frc->get_path_length);
-  GNUNET_memcpy (&paths[frc->get_path_length + frc->put_path_length],
-                 frc->data,
-                 frc->data_size);
+  GNUNET_memcpy (&paths[frc->get_path_length + frc->bd->put_path_length],
+                 frc->bd->data,
+                 frc->bd->data_size);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Sending reply to query %s for client %p\n",
-       GNUNET_h2s (key),
+       GNUNET_h2s (query_hash),
        record->ch->client);
   GNUNET_MQ_send (record->ch->mq,
                   env);
@@ -1157,66 +1092,38 @@ forward_reply (void *cls,
 }
 
 
-/**
- * Handle a reply we've received from another peer.  If the reply
- * matches any of our pending queries, forward it to the respective
- * client(s).
- *
- * @param expiration when will the reply expire
- * @param key the key of the query that triggered the reply
- * @param query_hash the query hash of the response
- * @param get_path_length number of peers in @a get_path
- * @param get_path path the reply took on get
- * @param put_path_length number of peers in @a put_path
- * @param put_path path the reply took on put
- * @param type type of the reply
- * @param data_size number of bytes in @a data
- * @param data application payload data
- */
 void
-GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration,
-                          const struct GNUNET_HashCode *key,
+GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd,
                           const struct GNUNET_HashCode *query_hash,
                           unsigned int get_path_length,
-                          const struct GNUNET_PeerIdentity *get_path,
-                          unsigned int put_path_length,
-                          const struct GNUNET_PeerIdentity *put_path,
-                          enum GNUNET_BLOCK_Type type,
-                          size_t data_size,
-                          const void *data)
+                          const struct GNUNET_PeerIdentity *get_path)
 {
   struct ForwardReplyContext frc;
-  size_t msize;
+  size_t msize = sizeof (struct GNUNET_DHT_ClientResultMessage)
+                 + bd->data_size
+                 + (get_path_length + bd->put_path_length)
+                 * sizeof(struct GNUNET_PeerIdentity);
 
-  msize = sizeof(struct GNUNET_DHT_ClientResultMessage) + data_size
-          + (get_path_length + put_path_length)
-          * sizeof(struct GNUNET_PeerIdentity);
   if (msize >= GNUNET_MAX_MESSAGE_SIZE)
   {
     GNUNET_break (0);
     return;
   }
-  frc.expiration = expiration;
-  frc.query_hash = query_hash;
+  frc.bd = bd;
   frc.get_path = get_path;
-  frc.put_path = put_path;
-  frc.data = data;
-  frc.data_size = data_size;
   frc.get_path_length = get_path_length;
-  frc.put_path_length = put_path_length;
-  frc.type = type;
   LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Forwarding reply for key %s to client\n",
-       GNUNET_h2s (key));
+       "Forwarding reply for query hash %s to client\n",
+       GNUNET_h2s (query_hash));
   if (0 ==
       GNUNET_CONTAINER_multihashmap_get_multiple (forward_map,
-                                                  key,
+                                                  query_hash,
                                                   &forward_reply,
                                                   &frc))
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "No matching client for reply for key %s\n",
-         GNUNET_h2s (key));
+         "No matching client for reply for query %s\n",
+         GNUNET_h2s (query_hash));
     GNUNET_STATISTICS_update (GDS_stats,
                               "# REPLIES ignored for CLIENTS (no match)",
                               1,
@@ -1298,15 +1205,9 @@ GDS_CLIENTS_process_get (uint32_t options,
 
 
 void
-GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type,
+GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd,
                               const struct GNUNET_PeerIdentity *get_path,
-                              unsigned int get_path_length,
-                              const struct GNUNET_PeerIdentity *put_path,
-                              unsigned int put_path_length,
-                              struct GNUNET_TIME_Absolute exp,
-                              const struct GNUNET_HashCode *key,
-                              const void *data,
-                              size_t size)
+                              unsigned int get_path_length)
 {
   struct ClientHandle **cl = NULL;
   unsigned int cl_size = 0;
@@ -1316,9 +1217,9 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type,
        m = m->next)
   {
     if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) ||
-           (m->type == type) ) &&
+           (m->type == bd->type) ) &&
          ( (GNUNET_is_zero (&m->key)) ||
-           (0 == GNUNET_memcmp (key,
+           (0 == GNUNET_memcmp (&bd->key,
                                 &m->key)) ) )
     {
       struct GNUNET_MQ_Envelope *env;
@@ -1336,27 +1237,27 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type 
type,
       GNUNET_array_append (cl,
                            cl_size,
                            m->ch);
-      msize = size;
-      msize += (get_path_length + put_path_length)
+      msize = bd->data_size;
+      msize += (get_path_length + bd->put_path_length)
                * sizeof(struct GNUNET_PeerIdentity);
       env = GNUNET_MQ_msg_extra (mmsg,
                                  msize,
                                  GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP);
-      mmsg->type = htonl (type);
-      mmsg->put_path_length = htonl (put_path_length);
+      mmsg->type = htonl (bd->type);
+      mmsg->put_path_length = htonl (bd->put_path_length);
       mmsg->get_path_length = htonl (get_path_length);
-      mmsg->expiration_time = GNUNET_TIME_absolute_hton (exp);
-      mmsg->key = *key;
+      mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
+      mmsg->key = bd->key;
       path = (struct GNUNET_PeerIdentity *) &mmsg[1];
       GNUNET_memcpy (path,
-                     put_path,
-                     put_path_length * sizeof(struct GNUNET_PeerIdentity));
+                     bd->put_path,
+                     bd->put_path_length * sizeof(struct GNUNET_PeerIdentity));
       GNUNET_memcpy (path,
                      get_path,
                      get_path_length * sizeof(struct GNUNET_PeerIdentity));
       GNUNET_memcpy (&path[get_path_length],
-                     data,
-                     size);
+                     bd->data,
+                     bd->data_size);
       GNUNET_MQ_send (m->ch->mq,
                       env);
     }
@@ -1365,32 +1266,11 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type 
type,
 }
 
 
-/**
- * Check if some client is monitoring PUT messages and notify
- * them in that case.  The @a path should include our own peer ID.
- *
- * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
- * @param type The type of data in the request.
- * @param hop_count Hop count so far.
- * @param path_length number of entries in path (or 0 if not recorded).
- * @param path peers on the PUT path (or NULL if not recorded).
- * @param desired_replication_level Desired replication level.
- * @param exp Expiration time of the data.
- * @param key Key under which data is to be stored.
- * @param data Pointer to the data carried.
- * @param size Number of bytes in data.
- */
 void
-GDS_CLIENTS_process_put (uint32_t options,
-                         enum GNUNET_BLOCK_Type type,
+GDS_CLIENTS_process_put (enum GNUNET_DHT_RouteOption options,
+                         const struct GDS_DATACACHE_BlockData *bd,
                          uint32_t hop_count,
-                         uint32_t desired_replication_level,
-                         unsigned int path_length,
-                         const struct GNUNET_PeerIdentity *path,
-                         struct GNUNET_TIME_Absolute exp,
-                         const struct GNUNET_HashCode *key,
-                         const void *data,
-                         size_t size)
+                         uint32_t desired_replication_level)
 {
   struct ClientHandle **cl = NULL;
   unsigned int cl_size = 0;
@@ -1400,10 +1280,10 @@ GDS_CLIENTS_process_put (uint32_t options,
        m = m->next)
   {
     if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) ||
-           (m->type == type) ) &&
+           (m->type == bd->type) ) &&
          ( (GNUNET_is_zero (&m->key)) ||
            (0 ==
-            GNUNET_memcmp (key,
+            GNUNET_memcmp (&bd->key,
                            &m->key)) ) )
     {
       struct GNUNET_MQ_Envelope *env;
@@ -1421,25 +1301,25 @@ GDS_CLIENTS_process_put (uint32_t options,
       GNUNET_array_append (cl,
                            cl_size,
                            m->ch);
-      msize = size;
-      msize += path_length * sizeof(struct GNUNET_PeerIdentity);
+      msize = bd->data_size;
+      msize += bd->put_path_length * sizeof(struct GNUNET_PeerIdentity);
       env = GNUNET_MQ_msg_extra (mmsg,
                                  msize,
                                  GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT);
       mmsg->options = htonl (options);
-      mmsg->type = htonl (type);
+      mmsg->type = htonl (bd->type);
       mmsg->hop_count = htonl (hop_count);
       mmsg->desired_replication_level = htonl (desired_replication_level);
-      mmsg->put_path_length = htonl (path_length);
-      mmsg->key = *key;
-      mmsg->expiration_time = GNUNET_TIME_absolute_hton (exp);
+      mmsg->put_path_length = htonl (bd->put_path_length);
+      mmsg->key = bd->key;
+      mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
       msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
       GNUNET_memcpy (msg_path,
-                     path,
-                     path_length * sizeof(struct GNUNET_PeerIdentity));
-      GNUNET_memcpy (&msg_path[path_length],
-                     data,
-                     size);
+                     bd->put_path,
+                     bd->put_path_length * sizeof(struct GNUNET_PeerIdentity));
+      GNUNET_memcpy (&msg_path[bd->put_path_length],
+                     bd->data,
+                     bd->data_size);
       GNUNET_MQ_send (m->ch->mq,
                       env);
     }
diff --git a/src/dht/gnunet-service-dht_datacache.c 
b/src/dht/gnunet-service-dht_datacache.c
index d80889635..a60f49a51 100644
--- a/src/dht/gnunet-service-dht_datacache.c
+++ b/src/dht/gnunet-service-dht_datacache.c
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2009, 2010, 2011, 2015, 2017 GNUnet e.V.
+     Copyright (C) 2009, 2010, 2011, 2015, 2017, 2022 GNUnet e.V.
 
      GNUnet is free software: you can redistribute it and/or modify it
      under the terms of the GNU Affero General Public License as published
@@ -38,35 +38,18 @@
  */
 #define NUM_CLOSEST 42
 
+
 /**
  * Handle to the datacache service (for inserting/retrieving data)
  */
 static struct GNUNET_DATACACHE_Handle *datacache;
 
 
-/**
- * Handle a datum we've received from another peer.  Cache if
- * possible.
- *
- * @param expiration when will the reply expire
- * @param key the query this reply is for
- * @param put_path_length number of peers in @a put_path
- * @param put_path path the reply took on put
- * @param type type of the reply
- * @param data_size number of bytes in @a data
- * @param data application payload data
- */
 void
-GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
-                          const struct GNUNET_HashCode *key,
-                          unsigned int put_path_length,
-                          const struct GNUNET_PeerIdentity *put_path,
-                          enum GNUNET_BLOCK_Type type,
-                          size_t data_size,
-                          const void *data)
+GDS_DATACACHE_handle_put (const struct GDS_DATACACHE_BlockData *bd)
 {
   struct GNUNET_HashCode xor;
-  int r;
+  enum GNUNET_GenericReturnValue r;
 
   if (NULL == datacache)
   {
@@ -74,7 +57,7 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute 
expiration,
                 "PUT request received, but have no datacache!\n");
     return;
   }
-  if (data_size >= GNUNET_MAX_MESSAGE_SIZE)
+  if (bd->data_size >= GNUNET_MAX_MESSAGE_SIZE)
   {
     GNUNET_break (0);
     return;
@@ -84,24 +67,24 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute 
expiration,
                             "# ITEMS stored in datacache",
                             1,
                             GNUNET_NO);
-  GNUNET_CRYPTO_hash_xor (key,
+  GNUNET_CRYPTO_hash_xor (&bd->key,
                           &my_identity_hash,
                           &xor);
   r = GNUNET_DATACACHE_put (datacache,
-                            key,
+                            &bd->key,
                             GNUNET_CRYPTO_hash_count_leading_zeros (&xor),
-                            data_size,
-                            data,
-                            type,
-                            expiration,
-                            put_path_length,
-                            put_path);
+                            bd->data_size,
+                            bd->data,
+                            bd->type,
+                            bd->expiration_time,
+                            bd->put_path_length,
+                            bd->put_path);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "DATACACHE PUT for key %s [%lu] completed (%d) after %u hops\n",
-       GNUNET_h2s (key),
-       (unsigned long) data_size,
+       GNUNET_h2s (&bd->key),
+       (unsigned long) bd->data_size,
        r,
-       put_path_length);
+       bd->put_path_length);
 }
 
 
@@ -171,30 +154,34 @@ datacache_get_iterator (void *cls,
                         unsigned int put_path_length,
                         const struct GNUNET_PeerIdentity *put_path)
 {
-  static char non_null;
   struct GetRequestContext *ctx = cls;
   enum GNUNET_BLOCK_ReplyEvaluationResult eval;
-
-  if (0 == GNUNET_TIME_absolute_get_remaining (exp).rel_value_us)
+  struct GDS_DATACACHE_BlockData bd = {
+    .key = *key,
+    .expiration_time = exp,
+    .put_path = put_path,
+    .data = data,
+    .data_size = data_size,
+    .put_path_length = put_path_length,
+    .type = type
+  };
+
+  if (GNUNET_TIME_absolute_is_past (exp))
   {
     GNUNET_break (0);  /* why does datacache return expired values? */
     return GNUNET_OK;   /* skip expired record */
   }
-  if ((NULL == data) &&
-      (0 == data_size))
-    data = &non_null; /* point anywhere, but not to NULL */
-
   eval
     = GNUNET_BLOCK_check_reply (GDS_block_context,
-                                type,
+                                bd.type,
                                 ctx->bg,
-                                key,
+                                &bd.key,
                                 ctx->xquery,
                                 ctx->xquery_size,
-                                data,
-                                data_size);
+                                bd.data,
+                                bd.data_size);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Found reply for query %s in datacache, evaluation result is %d\n",
+       "Evaluated reply for query %s in datacache, result is %d\n",
        GNUNET_h2s (key),
        (int) eval);
   ctx->eval = eval;
@@ -209,12 +196,7 @@ datacache_get_iterator (void *cls,
                               1,
                               GNUNET_NO);
     ctx->gc (ctx->gc_cls,
-             type,
-             exp,
-             key,
-             put_path_length, put_path,
-             0, NULL,
-             data, data_size);
+             &bd);
     break;
   case GNUNET_BLOCK_REPLY_OK_DUPLICATE:
     GNUNET_STATISTICS_update (GDS_stats,
@@ -240,18 +222,6 @@ datacache_get_iterator (void *cls,
 }
 
 
-/**
- * Handle a GET request we've received from another peer.
- *
- * @param key the query
- * @param type requested data type
- * @param xquery extended query
- * @param xquery_size number of bytes in @a xquery
- * @param bg block group to use for reply evaluation
- * @param gc function to call on the results
- * @param gc_cls closure for @a gc
- * @return evaluation result for the local replies
- */
 enum GNUNET_BLOCK_EvaluationResult
 GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key,
                           enum GNUNET_BLOCK_Type type,
@@ -291,62 +261,6 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode 
*key,
 }
 
 
-/**
- * Function called with a random element from the datacache.
- * Stores the key in the closure.
- *
- * @param cls a `struct GNUNET_HashCode *`, where to store the @a key
- * @param key key for the content
- * @param data_size number of bytes in @a data
- * @param data content stored
- * @param type type of the content
- * @param exp when will the content expire?
- * @param path_info_len number of entries in @a path_info
- * @param path_info a path through the network
- * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort
- */
-static int
-datacache_random_iterator (void *cls,
-                           const struct GNUNET_HashCode *key,
-                           size_t data_size,
-                           const char *data,
-                           enum GNUNET_BLOCK_Type type,
-                           struct GNUNET_TIME_Absolute exp,
-                           unsigned int path_info_len,
-                           const struct GNUNET_PeerIdentity *path_info)
-{
-  struct GNUNET_HashCode *dest = cls;
-
-  *dest = *key;
-  return GNUNET_OK; /* should actually not matter which we return */
-}
-
-
-/**
- * Obtain a random key from the datacache.
- * Used by Whanau for load-balancing.
- *
- * @param[out] key where to store the key of a random element,
- *             randomized by PRNG if datacache is empty
- * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty
- */
-int
-GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key)
-{
-  if (0 ==
-      GNUNET_DATACACHE_get_random (datacache,
-                                   &datacache_random_iterator,
-                                   key))
-  {
-    /* randomize key in this case */
-    GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE,
-                                      key);
-    return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
-}
-
-
 /**
  * Closure for #datacache_get_successors_iterator().
  */
@@ -355,12 +269,13 @@ struct SuccContext
   /**
    * Function to call on the result
    */
-  GDS_DATACACHE_SuccessorCallback cb;
+  GDS_DATACACHE_GetCallback cb;
 
   /**
    * Closure for @e cb.
    */
   void *cb_cls;
+
 };
 
 
@@ -378,7 +293,7 @@ struct SuccContext
  * @return #GNUNET_OK to continue iteration, anything else
  * to stop iteration.
  */
-static int
+static enum GNUNET_GenericReturnValue
 datacache_get_successors_iterator (void *cls,
                                    const struct GNUNET_HashCode *key,
                                    size_t size,
@@ -389,40 +304,36 @@ datacache_get_successors_iterator (void *cls,
                                    const struct GNUNET_PeerIdentity *put_path)
 {
   const struct SuccContext *sc = cls;
+  struct GDS_DATACACHE_BlockData bd = {
+    .key = *key,
+    .expiration_time = exp,
+    .put_path = put_path,
+    .data = data,
+    .data_size = size,
+    .put_path_length = put_path_length,
+    .type = type
+  };
 
   /* NOTE: The datacache currently does not store the RO from
      the original 'put', so we don't know the 'correct' option
      at this point anymore.  Thus, we conservatively assume
      that recording is desired (for now). */
   sc->cb (sc->cb_cls,
-          GNUNET_DHT_RO_RECORD_ROUTE,
-          key,
-          type,
-          put_path_length, put_path,
-          exp,
-          data,
-          size);
+          &bd);
   return GNUNET_OK;
 }
 
 
-/**
- * Handle a request for data close to a key that we have received from
- * another peer.
- *
- * @param key the location at which the peer is looking for data that is close
- * @param cb function to call with the result
- * @param cb_cls closure for @a cb
- */
 void
 GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key,
-                              GDS_DATACACHE_SuccessorCallback cb,
+                              GDS_DATACACHE_GetCallback cb,
                               void *cb_cls)
 {
-  struct SuccContext sc;
+  struct SuccContext sc = {
+    .cb = cb,
+    .cb_cls = cb_cls
+  };
 
-  sc.cb = cb;
-  sc.cb_cls = cb_cls;
   (void) GNUNET_DATACACHE_get_closest (datacache,
                                        key,
                                        NUM_CLOSEST,
@@ -431,19 +342,14 @@ GDS_DATACACHE_get_successors (const struct 
GNUNET_HashCode *key,
 }
 
 
-/**
- * Initialize datacache subsystem.
- */
 void
 GDS_DATACACHE_init ()
 {
-  datacache = GNUNET_DATACACHE_create (GDS_cfg, "dhtcache");
+  datacache = GNUNET_DATACACHE_create (GDS_cfg,
+                                       "dhtcache");
 }
 
 
-/**
- * Shutdown datacache subsystem.
- */
 void
 GDS_DATACACHE_done ()
 {
diff --git a/src/dht/gnunet-service-dht_datacache.h 
b/src/dht/gnunet-service-dht_datacache.h
index 5be59c90e..249bb8ee3 100644
--- a/src/dht/gnunet-service-dht_datacache.h
+++ b/src/dht/gnunet-service-dht_datacache.h
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2009, 2010, 2011 GNUnet e.V.
+     Copyright (C) 2009, 2010, 2011, 2022 GNUnet e.V.
 
      GNUnet is free software: you can redistribute it and/or modify it
      under the terms of the GNU Affero General Public License as published
@@ -31,53 +31,68 @@
 #include "gnunet_block_lib.h"
 #include "gnunet_dht_service.h"
 
+
+/**
+ * Information about a block stored in the datacache.
+ */
+struct GDS_DATACACHE_BlockData
+{
+  /**
+   * Key of the block.
+   */
+  struct GNUNET_HashCode key;
+
+  /**
+   * When does the block expire?
+   */
+  struct GNUNET_TIME_Absolute expiration_time;
+
+  /**
+   * PUT path taken by the block, array of peer identities.
+   */
+  const struct GNUNET_PeerIdentity *put_path;
+
+  /**
+   * Actual block data.
+   */
+  const void *data;
+
+  /**
+   * Number of bytes in @a data.
+   */
+  size_t data_size;
+
+  /**
+   * Length of the @e put_path array.
+   */
+  unsigned int put_path_length;
+
+  /**
+   * Type of the block.
+   */
+  enum GNUNET_BLOCK_Type type;
+};
+
+
 /**
  * Handle a datum we've received from another peer.  Cache if
  * possible.
  *
- * @param expiration when will the reply expire
- * @param key the query this reply is for
- * @param put_path_length number of peers in 'put_path'
- * @param put_path path the reply took on put
- * @param type type of the reply
- * @param data_size number of bytes in 'data'
- * @param data application payload data
+ * @param bd block data to cache
  */
 void
-GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
-                          const struct GNUNET_HashCode *key,
-                          unsigned int put_path_length,
-                          const struct GNUNET_PeerIdentity *put_path,
-                          enum GNUNET_BLOCK_Type type,
-                          size_t data_size,
-                          const void *data);
+GDS_DATACACHE_handle_put (const struct GDS_DATACACHE_BlockData *bd);
 
 
 /**
  * Handle a result for a GET operation.
  *
  * @param cls closure
- * @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
+ * @param bd block details
  */
 typedef void
 (*GDS_DATACACHE_GetCallback)(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);
+                             const struct GDS_DATACACHE_BlockData *bd);
 
 
 /**
@@ -102,43 +117,6 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode 
*key,
                           void *gc_cls);
 
 
-/**
- * Obtain a random key from the datacache.
- * Used by Whanau for load-balancing.
- *
- * @param[out] key where to store the key of a random element,
- *             randomized by PRNG if datacache is empty
- * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty
- */
-int
-GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key);
-
-
-/**
- * Send the get result to requesting client.
- *
- * @param cls closure
- * @param options routing options (from GET request)
- * @param key key of the requested data.
- * @param type block type
- * @param put_path_length number of peers in @a put_path
- * @param put_path path taken to put the data at its stored location.
- * @param expiration when will this result expire?
- * @param data payload to store
- * @param data_size size of the @a data
- */
-typedef void
-(*GDS_DATACACHE_SuccessorCallback)(void *cls,
-                                   enum GNUNET_DHT_RouteOption options,
-                                   const struct GNUNET_HashCode *key,
-                                   enum GNUNET_BLOCK_Type type,
-                                   unsigned int put_path_length,
-                                   const struct GNUNET_PeerIdentity *put_path,
-                                   struct GNUNET_TIME_Absolute expiration,
-                                   const void *data,
-                                   size_t data_size);
-
-
 /**
  * Handle a request for data close to a key that we have received from
  * another peer.
@@ -148,9 +126,9 @@ typedef void
  * @param cb_cls closure for @a cb
  */
 void
-GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key,
-                              GDS_DATACACHE_SuccessorCallback cb,
-                              void *cb_cls);
+GDS_DATACACHE_get_closest (const struct GNUNET_HashCode *key,
+                           GDS_DATACACHE_GetCallback cb,
+                           void *cb_cls);
 
 
 /**
diff --git a/src/dht/gnunet-service-dht_hello.c 
b/src/dht/gnunet-service-dht_hello.c
index 906391334..949456575 100644
--- a/src/dht/gnunet-service-dht_hello.c
+++ b/src/dht/gnunet-service-dht_hello.c
@@ -54,7 +54,8 @@ GDS_HELLO_get (const struct GNUNET_PeerIdentity *peer)
 {
   if (NULL == peer_to_hello)
     return NULL;
-  return GNUNET_CONTAINER_multipeermap_get (peer_to_hello, peer);
+  return GNUNET_CONTAINER_multipeermap_get (peer_to_hello,
+                                            peer);
 }
 
 
@@ -83,15 +84,20 @@ process_hello (void *cls,
   if (0 == GNUNET_TIME_absolute_get_remaining (ex).rel_value_us)
     return;
   GNUNET_STATISTICS_update (GDS_stats,
-                            gettext_noop ("# HELLOs obtained from peerinfo"), 
1,
+                            "# HELLOs obtained from peerinfo",
+                            1,
                             GNUNET_NO);
-  hm = GNUNET_CONTAINER_multipeermap_get (peer_to_hello, peer);
+  hm = GNUNET_CONTAINER_multipeermap_get (peer_to_hello,
+                                          peer);
   GNUNET_free (hm);
   hm = GNUNET_malloc (GNUNET_HELLO_size (hello));
-  GNUNET_memcpy (hm, hello, GNUNET_HELLO_size (hello));
+  GNUNET_memcpy (hm,
+                 hello,
+                 GNUNET_HELLO_size (hello));
   GNUNET_assert (GNUNET_SYSERR !=
                  GNUNET_CONTAINER_multipeermap_put (peer_to_hello,
-                                                    peer, hm,
+                                                    peer,
+                                                    hm,
                                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE));
 }
 
@@ -114,7 +120,7 @@ GDS_HELLO_init ()
 /**
  * Free memory occopied by the HELLO.
  */
-static int
+static enum GNUNET_GenericReturnValue
 free_hello (void *cls,
             const struct GNUNET_PeerIdentity *key,
             void *hello)
diff --git a/src/dht/gnunet-service-dht_neighbours.c 
b/src/dht/gnunet-service-dht_neighbours.c
index ae3f34dce..0fc42d2ef 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -1163,38 +1163,12 @@ get_target_peers (const struct GNUNET_HashCode *key,
 }
 
 
-/**
- * Perform a PUT operation.   Forwards the given request to other
- * peers.   Does not store the data locally.  Does not give the
- * data to local clients.  May do nothing if this is the only
- * peer in the network (or if we are the closest peer in the
- * network).
- *
- * @param type type of the block
- * @param options routing options
- * @param desired_replication_level desired replication count
- * @param expiration_time when does the content expire
- * @param hop_count how many hops has this message traversed so far
- * @param bf Bloom filter of peers this PUT has already traversed
- * @param key key for the content
- * @param put_path_length number of entries in @a put_path
- * @param put_path peers this request has traversed so far (if tracked)
- * @param data payload to store
- * @param data_size number of bytes in @a data
- * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not
- */
 enum GNUNET_GenericReturnValue
-GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
+GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd,
                            enum GNUNET_DHT_RouteOption options,
                            uint32_t desired_replication_level,
-                           struct GNUNET_TIME_Absolute expiration_time,
                            uint32_t hop_count,
-                           struct GNUNET_CONTAINER_BloomFilter *bf,
-                           const struct GNUNET_HashCode *key,
-                           unsigned int put_path_length,
-                           struct GNUNET_PeerIdentity *put_path,
-                           const void *data,
-                           size_t data_size)
+                           struct GNUNET_CONTAINER_BloomFilter *bf)
 {
   unsigned int target_count;
   unsigned int i;
@@ -1205,20 +1179,21 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
   struct PeerPutMessage *ppm;
   struct GNUNET_PeerIdentity *pp;
   unsigned int skip_count;
+  unsigned int put_path_length = bd->put_path_length;
 
   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_h2s (&bd->key));
   GNUNET_CONTAINER_bloomfilter_add (bf,
                                     &my_identity_hash);
   GNUNET_STATISTICS_update (GDS_stats,
-                            gettext_noop ("# PUT requests routed"),
+                            "# PUT requests routed",
                             1,
                             GNUNET_NO);
   target_count
-    = get_target_peers (key,
+    = get_target_peers (&bd->key,
                         bf,
                         hop_count,
                         desired_replication_level,
@@ -1227,17 +1202,18 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Routing PUT for %s terminates after %u hops at %s\n",
-                GNUNET_h2s (key),
+                GNUNET_h2s (&bd->key),
                 (unsigned int) hop_count,
                 GNUNET_i2s (&my_identity));
     return GNUNET_NO;
   }
-  msize = put_path_length * sizeof(struct GNUNET_PeerIdentity) + data_size;
+  msize = bd->put_path_length * sizeof(struct GNUNET_PeerIdentity)
+          + bd->data_size;
   if (msize + sizeof(struct PeerPutMessage)
       >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
   {
     put_path_length = 0;
-    msize = data_size;
+    msize = bd->data_size;
   }
   if (msize + sizeof(struct PeerPutMessage)
       >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
@@ -1267,18 +1243,18 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
     }
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Routing PUT for %s after %u hops to %s\n",
-                GNUNET_h2s (key),
+                GNUNET_h2s (&bd->key),
                 (unsigned int) hop_count,
                 GNUNET_i2s (target->id));
     env = GNUNET_MQ_msg_extra (ppm,
                                msize,
                                GNUNET_MESSAGE_TYPE_DHT_P2P_PUT);
     ppm->options = htonl (options);
-    ppm->type = htonl (type);
+    ppm->type = htonl (bd->type);
     ppm->hop_count = htonl (hop_count + 1);
     ppm->desired_replication_level = htonl (desired_replication_level);
     ppm->put_path_length = htonl (put_path_length);
-    ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
+    ppm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
     GNUNET_break (GNUNET_YES ==
                   GNUNET_CONTAINER_bloomfilter_test (bf,
                                                      &target->phash));
@@ -1286,14 +1262,14 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
                    GNUNET_CONTAINER_bloomfilter_get_raw_data (bf,
                                                               ppm->bloomfilter,
                                                               DHT_BLOOM_SIZE));
-    ppm->key = *key;
+    ppm->key = bd->key;
     pp = (struct GNUNET_PeerIdentity *) &ppm[1];
     GNUNET_memcpy (pp,
-                   put_path,
+                   bd->put_path,
                    sizeof(struct GNUNET_PeerIdentity) * put_path_length);
     GNUNET_memcpy (&pp[put_path_length],
-                   data,
-                   data_size);
+                   bd->data,
+                   bd->data_size);
     GNUNET_MQ_send (target->mq,
                     env);
   }
@@ -1302,23 +1278,6 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
 }
 
 
-/**
- * Perform a GET operation.  Forwards the given request to other
- * peers.  Does not lookup the key locally.  May do nothing if this is
- * the only peer in the network (or if we are the closest peer in the
- * network).
- *
- * @param type type of the block
- * @param options routing options
- * @param desired_replication_level desired replication count
- * @param hop_count how many hops did this request traverse so far?
- * @param key key for the content
- * @param xquery extended query
- * @param xquery_size number of bytes in @a xquery
- * @param bg group to use for filtering replies
- * @param peer_bf filter for peers not to select (again)
- * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not
- */
 enum GNUNET_GenericReturnValue
 GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
                            enum GNUNET_DHT_RouteOption options,
@@ -1444,48 +1403,27 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
 }
 
 
-/**
- * Handle a reply (route to origin).  Only forwards the reply back to
- * the given peer.  Does not do local caching or forwarding to local
- * clients.
- *
- * @param target neighbour that should receive the block (if still connected)
- * @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
- */
 void
 GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target,
-                             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,
+                             const struct GDS_DATACACHE_BlockData *bd,
+                             const struct GNUNET_HashCode *query_hash,
                              unsigned int get_path_length,
-                             const struct GNUNET_PeerIdentity *get_path,
-                             const void *data,
-                             size_t data_size)
+                             const struct GNUNET_PeerIdentity *get_path)
 {
   struct PeerInfo *pi;
   struct GNUNET_MQ_Envelope *env;
-  size_t msize;
   struct PeerResultMessage *prm;
   struct GNUNET_PeerIdentity *paths;
+  size_t msize;
 
-  msize = data_size + (get_path_length + put_path_length)
+  msize = bd->data_size + (get_path_length + bd->put_path_length)
           * sizeof(struct GNUNET_PeerIdentity);
-  if ((msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
-      (get_path_length >
-       GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ||
-      (put_path_length >
-       GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ||
-      (data_size > GNUNET_MAX_MESSAGE_SIZE))
+  if ( (msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
+       (get_path_length >
+        GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ||
+       (bd->put_path_length >
+        GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ||
+       (bd->data_size > GNUNET_MAX_MESSAGE_SIZE))
   {
     GNUNET_break (0);
     return;
@@ -1497,49 +1435,48 @@ GDS_NEIGHBOURS_handle_reply (const struct 
GNUNET_PeerIdentity *target,
     /* peer disconnected in the meantime, drop reply */
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "No matching peer for reply for key %s\n",
-                GNUNET_h2s (key));
+                GNUNET_h2s (query_hash));
     return;
   }
   if (GNUNET_MQ_get_length (pi->mq) >= MAXIMUM_PENDING_PER_PEER)
   {
     /* skip */
     GNUNET_STATISTICS_update (GDS_stats,
-                              gettext_noop (
-                                "# P2P messages dropped due to full queue"),
+                              "# P2P messages dropped due to full queue",
                               1,
                               GNUNET_NO);
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Peer queue full, ignoring reply for key %s\n",
-                GNUNET_h2s (key));
+                GNUNET_h2s (&bd->key));
     return;
   }
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Forwarding reply for key %s to peer %s\n",
-              GNUNET_h2s (key),
+              GNUNET_h2s (query_hash),
               GNUNET_i2s (target));
   GNUNET_STATISTICS_update (GDS_stats,
-                            gettext_noop
-                              ("# RESULT messages queued for transmission"), 1,
+                            "# RESULT messages queued for transmission",
+                            1,
                             GNUNET_NO);
   env = GNUNET_MQ_msg_extra (prm,
                              msize,
                              GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT);
-  prm->type = htonl (type);
-  prm->put_path_length = htonl (put_path_length);
+  prm->type = htonl (bd->type);
+  prm->put_path_length = htonl (bd->put_path_length);
   prm->get_path_length = htonl (get_path_length);
-  prm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
-  prm->key = *key;
+  prm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
+  prm->key = *query_hash;
   paths = (struct GNUNET_PeerIdentity *) &prm[1];
   GNUNET_memcpy (paths,
-                 put_path,
-                 put_path_length * sizeof(struct GNUNET_PeerIdentity));
-  GNUNET_memcpy (&paths[put_path_length],
+                 bd->put_path,
+                 bd->put_path_length * sizeof(struct GNUNET_PeerIdentity));
+  GNUNET_memcpy (&paths[bd->put_path_length],
                  get_path,
                  get_path_length * sizeof(struct GNUNET_PeerIdentity));
-  GNUNET_memcpy (&paths[put_path_length + get_path_length],
-                 data,
-                 data_size);
+  GNUNET_memcpy (&paths[bd->put_path_length + get_path_length],
+                 bd->data,
+                 bd->data_size);
   GNUNET_MQ_send (pi->mq,
                   env);
 }
@@ -1608,18 +1545,27 @@ handle_dht_p2p_put (void *cls,
                     const struct PeerPutMessage *put)
 {
   struct PeerInfo *peer = cls;
-  const struct GNUNET_PeerIdentity *put_path;
-  const void *payload;
-  uint32_t putlen;
-  uint16_t msize;
-  size_t payload_size;
-  enum GNUNET_DHT_RouteOption options;
-  struct GNUNET_CONTAINER_BloomFilter *bf;
-  int forwarded;
-  struct GNUNET_TIME_Absolute exp_time;
+  uint16_t msize = ntohs (put->header.size);
+  enum GNUNET_DHT_RouteOption options
+    = (enum GNUNET_DHT_RouteOption) ntohl (put->options);
+  struct GDS_DATACACHE_BlockData bd = {
+    .key = put->key,
+    .expiration_time = GNUNET_TIME_absolute_ntoh (put->expiration_time),
+    .type = ntohl (put->type)
+  };
+  const struct GNUNET_PeerIdentity *put_path
+    = (const struct GNUNET_PeerIdentity *) &put[1];
+  uint32_t putlen
+    = ntohl (put->put_path_length);
 
-  exp_time = GNUNET_TIME_absolute_ntoh (put->expiration_time);
-  if (GNUNET_TIME_absolute_is_past (exp_time))
+  bd.data_size = msize - (sizeof(*put)
+                          + putlen * sizeof(struct GNUNET_PeerIdentity));
+  bd.data = &put_path[putlen];
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "PUT for `%s' from %s\n",
+              GNUNET_h2s (&put->key),
+              GNUNET_i2s (peer->id));
+  if (GNUNET_TIME_absolute_is_past (bd.expiration_time))
   {
     GNUNET_STATISTICS_update (GDS_stats,
                               gettext_noop ("# Expired PUTs discarded"),
@@ -1627,26 +1573,14 @@ handle_dht_p2p_put (void *cls,
                               GNUNET_NO);
     return;
   }
-  msize = ntohs (put->header.size);
-  putlen = ntohl (put->put_path_length);
   GNUNET_STATISTICS_update (GDS_stats,
-                            gettext_noop ("# P2P PUT requests received"),
+                            "# P2P PUT requests received",
                             1,
                             GNUNET_NO);
   GNUNET_STATISTICS_update (GDS_stats,
-                            gettext_noop ("# P2P PUT bytes received"),
+                            "# P2P PUT bytes received",
                             msize,
                             GNUNET_NO);
-  put_path = (const struct GNUNET_PeerIdentity *) &put[1];
-  payload = &put_path[putlen];
-  options = ntohl (put->options);
-  payload_size = msize - (sizeof(struct PeerPutMessage)
-                          + putlen * sizeof(struct GNUNET_PeerIdentity));
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "PUT for `%s' from %s\n",
-              GNUNET_h2s (&put->key),
-              GNUNET_i2s (peer->id));
   if (GNUNET_YES == log_route_details_stderr)
   {
     char *tmp;
@@ -1681,15 +1615,15 @@ handle_dht_p2p_put (void *cls,
     enum GNUNET_GenericReturnValue ret;
 
     ret = GNUNET_BLOCK_get_key (GDS_block_context,
-                                ntohl (put->type),
-                                payload,
-                                payload_size,
+                                bd.type,
+                                bd.data,
+                                bd.data_size,
                                 &test_key);
     switch (ret)
     {
     case GNUNET_YES:
       if (0 != GNUNET_memcmp (&test_key,
-                              &put->key))
+                              &bd.key))
       {
         GNUNET_break_op (0);
         return;
@@ -1706,25 +1640,28 @@ handle_dht_p2p_put (void *cls,
 
   if (GNUNET_NO ==
       GNUNET_BLOCK_check_block (GDS_block_context,
-                                ntohl (put->type),
-                                &put->key,
-                                payload,
-                                payload_size))
+                                bd.type,
+                                &bd.key,
+                                bd.data,
+                                bd.data_size))
   {
     GNUNET_break_op (0);
     return;
   }
 
-  bf = GNUNET_CONTAINER_bloomfilter_init (put->bloomfilter,
-                                          DHT_BLOOM_SIZE,
-                                          GNUNET_CONSTANTS_BLOOMFILTER_K);
-  GNUNET_break_op (GNUNET_YES ==
-                   GNUNET_CONTAINER_bloomfilter_test (bf,
-                                                      &peer->phash));
   {
+    struct GNUNET_CONTAINER_BloomFilter *bf;
     struct GNUNET_PeerIdentity pp[putlen + 1];
 
+    bf = GNUNET_CONTAINER_bloomfilter_init (put->bloomfilter,
+                                            DHT_BLOOM_SIZE,
+                                            GNUNET_CONSTANTS_BLOOMFILTER_K);
+    GNUNET_break_op (GNUNET_YES ==
+                     GNUNET_CONTAINER_bloomfilter_test (bf,
+                                                        &peer->phash));
     /* extend 'put path' by sender */
+    bd.put_path = (const struct GNUNET_PeerIdentity *) pp;
+    bd.put_path_length = putlen + 1;
     if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE))
     {
 #if SANITY_CHECKS
@@ -1732,13 +1669,13 @@ handle_dht_p2p_put (void *cls,
       {
         for (unsigned int j = 0; j < i; j++)
         {
-          GNUNET_break (0 != memcmp (&pp[i],
-                                     &pp[j],
-                                     sizeof(struct GNUNET_PeerIdentity)));
+          GNUNET_break (0 !=
+                        GNUNET_memcmp (&pp[i],
+                                       &pp[j]));
         }
-        GNUNET_break (0 != memcmp (&pp[i],
-                                   peer->id,
-                                   sizeof(struct GNUNET_PeerIdentity)));
+        GNUNET_break (0 !=
+                      GNUNET_memcmp (&pp[i],
+                                     peer->id));
       }
 #endif
       GNUNET_memcpy (pp,
@@ -1748,57 +1685,41 @@ handle_dht_p2p_put (void *cls,
       putlen++;
     }
     else
-      putlen = 0;
+    {
+      bd.put_path_length = 0;
+    }
 
     /* give to local clients */
-    GDS_CLIENTS_handle_reply (exp_time,
-                              &put->key,
-                              &put->key,
-                              0,
-                              NULL,
-                              putlen,
-                              pp,
-                              ntohl (put->type),
-                              payload_size,
-                              payload);
+    GDS_CLIENTS_handle_reply (&bd,
+                              &bd.key,
+                              0, NULL /* get path */);
+
     /* store locally */
     if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
-        (GDS_am_closest_peer (&put->key, bf)))
-      GDS_DATACACHE_handle_put (exp_time,
-                                &put->key,
-                                putlen,
-                                pp,
-                                ntohl (put->type),
-                                payload_size,
-                                payload);
-    /* route to other peers */
-    forwarded = GDS_NEIGHBOURS_handle_put (ntohl (put->type),
-                                           options,
-                                           ntohl (
-                                             put->desired_replication_level),
-                                           exp_time,
-                                           ntohl (put->hop_count),
-                                           bf,
-                                           &put->key,
-                                           putlen,
-                                           pp,
-                                           payload,
-                                           payload_size);
-    /* notify monitoring clients */
-    GDS_CLIENTS_process_put (options
-                             | ((GNUNET_OK == forwarded)
+        (GDS_am_closest_peer (&put->key,
+                              bf)))
+      GDS_DATACACHE_handle_put (&bd);
+    {
+      enum GNUNET_GenericReturnValue forwarded;
+
+      /* route to other peers */
+      forwarded
+        = GDS_NEIGHBOURS_handle_put (&bd,
+                                     options,
+                                     ntohl (put->desired_replication_level),
+                                     ntohl (put->hop_count),
+                                     bf);
+      /* notify monitoring clients */
+      GDS_CLIENTS_process_put (options
+                               | ((GNUNET_OK == forwarded)
                                 ? GNUNET_DHT_RO_LAST_HOP
                                 : 0),
-                             ntohl (put->type),
-                             ntohl (put->hop_count),
-                             ntohl (put->desired_replication_level),
-                             putlen, pp,
-                             exp_time,
-                             &put->key,
-                             payload,
-                             payload_size);
+                               &bd,
+                               ntohl (put->hop_count),
+                               ntohl (put->desired_replication_level));
+    }
+    GNUNET_CONTAINER_bloomfilter_free (bf);
   }
-  GNUNET_CONTAINER_bloomfilter_free (bf);
 }
 
 
@@ -1812,42 +1733,40 @@ handle_dht_p2p_put (void *cls,
  */
 static void
 handle_find_peer (const struct GNUNET_PeerIdentity *sender,
-                  const struct GNUNET_HashCode *key,
+                  const struct GNUNET_HashCode *query_hash,
                   struct GNUNET_BLOCK_Group *bg)
 {
   int bucket_idx;
   struct PeerBucket *bucket;
   struct PeerInfo *peer;
   unsigned int choice;
-  const struct GNUNET_HELLO_Message *hello;
-  size_t hello_size;
+  struct GDS_DATACACHE_BlockData bd = {
+    .type = GNUNET_BLOCK_TYPE_DHT_HELLO
+  };
 
   /* first, check about our own HELLO */
   if (NULL != GDS_my_hello)
   {
-    hello_size = GNUNET_HELLO_size (
+    bd.expiration_time = GNUNET_TIME_relative_to_absolute (
+      hello_expiration),
+    bd.key = my_identity_hash,
+    bd.data = GDS_my_hello;
+    bd.data_size = GNUNET_HELLO_size (
       (const struct GNUNET_HELLO_Message *) GDS_my_hello);
-    GNUNET_break (hello_size >= sizeof(struct GNUNET_MessageHeader));
+    GNUNET_break (bd.data_size >= sizeof(struct GNUNET_MessageHeader));
     if (GNUNET_BLOCK_REPLY_OK_MORE ==
         GNUNET_BLOCK_check_reply (GDS_block_context,
                                   GNUNET_BLOCK_TYPE_DHT_HELLO,
                                   bg,
                                   &my_identity_hash,
                                   NULL, 0,
-                                  GDS_my_hello,
-                                  hello_size))
+                                  bd.data,
+                                  bd.data_size))
     {
       GDS_NEIGHBOURS_handle_reply (sender,
-                                   GNUNET_BLOCK_TYPE_DHT_HELLO,
-                                   GNUNET_TIME_relative_to_absolute (
-                                     hello_expiration),
-                                   key,
-                                   0,
-                                   NULL,
-                                   0,
-                                   NULL,
-                                   GDS_my_hello,
-                                   hello_size);
+                                   &bd,
+                                   query_hash,
+                                   0, NULL /* get path */);
     }
     else
     {
@@ -1869,11 +1788,11 @@ handle_find_peer (const struct GNUNET_PeerIdentity 
*sender,
   /* FIXME: How can this be true? Shouldnt we just do find_bucket() ? */
   if (0 ==
       GNUNET_memcmp (&my_identity_hash,
-                     key))
+                     query_hash))
     bucket_idx = closest_bucket;
   else
     bucket_idx = GNUNET_MIN ((int) closest_bucket,
-                             find_bucket (key));
+                             find_bucket (query_hash));
   if (bucket_idx < 0)
     return;
   bucket = &k_buckets[bucket_idx];
@@ -1889,84 +1808,69 @@ handle_find_peer (const struct GNUNET_PeerIdentity 
*sender,
     choice--;
   }
   choice = bucket->peers_size;
-  do
+
   {
-    peer = peer->next;
-    if (0 == choice--)
-      return;                   /* no non-masked peer available */
-    if (NULL == peer)
-      peer = bucket->head;
-    hello = GDS_HELLO_get (peer->id);
+    const struct GNUNET_HELLO_Message *hello;
+    size_t hello_size;
+
+    do
+    {
+      peer = peer->next;
+      if (0 == choice--)
+        return;                 /* no non-masked peer available */
+      if (NULL == peer)
+        peer = bucket->head;
+      hello = GDS_HELLO_get (peer->id);
+    } while ( (NULL == hello) ||
+              (GNUNET_BLOCK_REPLY_OK_MORE !=
+               GNUNET_BLOCK_check_reply (
+                 GDS_block_context,
+                 GNUNET_BLOCK_TYPE_DHT_HELLO,
+                 bg,
+                 &peer->phash,
+                 NULL, 0, /* xquery */
+                 hello,
+                 (hello_size = GNUNET_HELLO_size (hello)))));
+    bd.expiration_time = GNUNET_TIME_relative_to_absolute (
+      GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION);
+    bd.key = peer->phash;
+    bd.data = hello;
+    bd.data_size = hello_size;
+    GDS_NEIGHBOURS_handle_reply (sender,
+                                 &bd,
+                                 query_hash,
+                                 0, NULL /* get path */);
   }
-  /* FIXME: this logic is strange. extra ';', maybe, but then why a while-loop 
at all? */
-  while ((NULL == hello) ||
-         (GNUNET_BLOCK_REPLY_OK_MORE !=
-          GNUNET_BLOCK_check_reply (GDS_block_context,
-                                    GNUNET_BLOCK_TYPE_DHT_HELLO,
-                                    bg,
-                                    &peer->phash,
-                                    NULL, 0,
-                                    hello,
-                                    (hello_size = GNUNET_HELLO_size 
(hello)))));
-  GDS_NEIGHBOURS_handle_reply (sender,
-                               GNUNET_BLOCK_TYPE_DHT_HELLO,
-                               GNUNET_TIME_relative_to_absolute
-                                 (GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION),
-                               key,
-                               0,
-                               NULL,
-                               0,
-                               NULL,
-                               hello,
-                               hello_size);
 }
 
 
 /**
- * Handle a result from local datacache for a GET operation.
+ * Handle an exact result from local datacache for a GET operation.
  *
  * @param cls the `struct PeerInfo` for which this is a reply
- * @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
+ * @param bd details about the block we found locally
  */
 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)
+                     const struct GDS_DATACACHE_BlockData *bd)
 {
   struct PeerInfo *peer = cls;
+
   {
     char *pp;
 
-    pp = GNUNET_STRINGS_pp2s (put_path,
-                              put_path_length);
+    pp = GNUNET_STRINGS_pp2s (bd->put_path,
+                              bd->put_path_length);
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Found local result for %s (PP: %s)\n",
-                GNUNET_h2s (key),
+                GNUNET_h2s (&bd->key),
                 pp);
     GNUNET_free (pp);
   }
   GDS_NEIGHBOURS_handle_reply (peer->id,
-                               type,
-                               expiration_time,
-                               key,
-                               put_path_length, put_path,
-                               get_path_length, get_path,
-                               data, data_size);
+                               bd,
+                               &bd->key,
+                               0, NULL /* get path */);
 }
 
 
@@ -2159,116 +2063,81 @@ handle_dht_p2p_get (void *cls,
 }
 
 
-/**
- * Check validity of p2p result message.
- *
- * @param cls closure
- * @param message message
- * @return #GNUNET_YES if the message is well-formed
- */
-static enum GNUNET_GenericReturnValue
-check_dht_p2p_result (void *cls,
-                      const struct PeerResultMessage *prm)
-{
-  uint32_t get_path_length;
-  uint32_t put_path_length;
-  uint16_t msize;
-
-  (void) cls;
-  msize = ntohs (prm->header.size);
-  put_path_length = ntohl (prm->put_path_length);
-  get_path_length = ntohl (prm->get_path_length);
-  if ((msize <
-       sizeof(struct PeerResultMessage) + (get_path_length
-                                           + put_path_length)
-       * sizeof(struct GNUNET_PeerIdentity)) ||
-      (get_path_length >
-       GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ||
-      (put_path_length >
-       GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)))
-  {
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
-}
-
-
 /**
  * Process a reply, after the @a get_path has been updated.
  *
- * @param expiration_time when does the reply expire
- * @param key key of the original inquiry
- * @param query_hash key matching the block
+ * @param bd block details
+ * @param query_hash hash of the original query, might not match key in @a bd
  * @param get_path_length number of entries in @a get_path
  * @param get_path path the reply has taken
- * @param put_path_length number of entries in @a put_path
- * @param put_path path the PUT has taken
- * @param type type of the block
- * @param data_size number of bytes in @a data
- * @param data payload of the reply
  */
 static void
-process_reply_with_path (struct GNUNET_TIME_Absolute expiration_time,
-                         const struct GNUNET_HashCode *key,
+process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd,
                          const struct GNUNET_HashCode *query_hash,
                          unsigned int get_path_length,
-                         const struct GNUNET_PeerIdentity *get_path,
-                         unsigned int put_path_length,
-                         const struct GNUNET_PeerIdentity *put_path,
-                         enum GNUNET_BLOCK_Type type,
-                         size_t data_size,
-                         const void *data)
+                         const struct GNUNET_PeerIdentity *get_path)
 {
   /* forward to local clients */
-  GDS_CLIENTS_handle_reply (expiration_time,
-                            key,
+  GDS_CLIENTS_handle_reply (bd,
                             query_hash,
                             get_path_length,
-                            get_path,
-                            put_path_length,
-                            put_path,
-                            type,
-                            data_size,
-                            data);
-  GDS_CLIENTS_process_get_resp (type,
+                            get_path);
+  GDS_CLIENTS_process_get_resp (bd,
                                 get_path,
-                                get_path_length,
-                                put_path,
-                                put_path_length,
-                                expiration_time,
-                                query_hash,
-                                data,
-                                data_size);
+                                get_path_length);
   if (GNUNET_YES == cache_results)
   {
-    struct GNUNET_PeerIdentity xput_path[get_path_length + 1 + 
put_path_length];
+    struct GNUNET_PeerIdentity xput_path[GNUNET_NZL (get_path_length
+                                                     + bd->put_path_length)];
+    struct GDS_DATACACHE_BlockData bdx = *bd;
 
     GNUNET_memcpy (xput_path,
-                   put_path,
-                   put_path_length * sizeof(struct GNUNET_PeerIdentity));
-    GNUNET_memcpy (&xput_path[put_path_length],
+                   bd->put_path,
+                   bd->put_path_length * sizeof(struct GNUNET_PeerIdentity));
+    GNUNET_memcpy (&xput_path[bd->put_path_length],
                    get_path,
                    get_path_length * sizeof(struct GNUNET_PeerIdentity));
-
-    GDS_DATACACHE_handle_put (expiration_time,
-                              query_hash,
-                              get_path_length + put_path_length,
-                              xput_path,
-                              type,
-                              data_size,
-                              data);
+    bdx.put_path = xput_path;
+    bdx.put_path_length += get_path_length;
+    GDS_DATACACHE_handle_put (&bdx);
   }
   /* forward to other peers */
-  GDS_ROUTING_process (type,
-                       expiration_time,
-                       key,
-                       put_path_length,
-                       put_path,
+  GDS_ROUTING_process (bd,
+                       query_hash,
                        get_path_length,
-                       get_path,
-                       data,
-                       data_size);
+                       get_path);
+}
+
+
+/**
+ * Check validity of p2p result message.
+ *
+ * @param cls closure
+ * @param message message
+ * @return #GNUNET_YES if the message is well-formed
+ */
+static enum GNUNET_GenericReturnValue
+check_dht_p2p_result (void *cls,
+                      const struct PeerResultMessage *prm)
+{
+  uint32_t get_path_length = ntohl (prm->get_path_length);
+  uint32_t put_path_length = ntohl (prm->put_path_length);
+  uint16_t msize = ntohs (prm->header.size);
+
+  (void) cls;
+  if ( (msize <
+        sizeof(struct PeerResultMessage)
+        + (get_path_length + put_path_length)
+        * sizeof(struct GNUNET_PeerIdentity)) ||
+       (get_path_length >
+        GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ||
+       (put_path_length >
+        GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) )
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
 }
 
 
@@ -2283,72 +2152,66 @@ handle_dht_p2p_result (void *cls,
                        const struct PeerResultMessage *prm)
 {
   struct PeerInfo *peer = cls;
-  const struct GNUNET_PeerIdentity *put_path;
-  const struct GNUNET_PeerIdentity *get_path;
-  const void *data;
-  uint32_t get_path_length;
-  uint32_t put_path_length;
-  uint16_t msize;
-  size_t data_size;
-  enum GNUNET_BLOCK_Type type;
-  struct GNUNET_TIME_Absolute exp_time;
-  const struct GNUNET_HashCode *pquery;
-  struct GNUNET_HashCode dquery;
+  uint16_t msize = ntohs (prm->header.size);
+  uint32_t get_path_length = ntohl (prm->get_path_length);
+  struct GDS_DATACACHE_BlockData bd = {
+    .expiration_time  = GNUNET_TIME_absolute_ntoh (prm->expiration_time),
+    .put_path = (const struct GNUNET_PeerIdentity *) &prm[1],
+    .put_path_length = ntohl (prm->put_path_length),
+    .type = ntohl (prm->type)
+  };
+  const struct GNUNET_PeerIdentity *get_path
+    = &bd.put_path[bd.put_path_length];
 
   /* parse and validate message */
-  exp_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time);
-  if (0 == GNUNET_TIME_absolute_get_remaining (exp_time).rel_value_us)
+  if (GNUNET_TIME_absolute_is_past (bd.expiration_time))
   {
     GNUNET_STATISTICS_update (GDS_stats,
-                              gettext_noop ("# Expired results discarded"),
+                              "# Expired results discarded",
                               1,
                               GNUNET_NO);
     return;
   }
-  msize = ntohs (prm->header.size);
-  put_path_length = ntohl (prm->put_path_length);
-  get_path_length = ntohl (prm->get_path_length);
-  put_path = (const struct GNUNET_PeerIdentity *) &prm[1];
-  get_path = &put_path[put_path_length];
-  type = ntohl (prm->type);
-  data = (const void *) &get_path[get_path_length];
-  data_size = msize - (sizeof(struct PeerResultMessage)
-                       + (get_path_length
-                          + put_path_length)
-                       * sizeof(struct GNUNET_PeerIdentity));
+  get_path = &bd.put_path[bd.put_path_length];
+  bd.data = (const void *) &get_path[get_path_length];
+  bd.data_size = msize - (sizeof(struct PeerResultMessage)
+                          + (get_path_length + bd.put_path_length)
+                          * sizeof(struct GNUNET_PeerIdentity));
   GNUNET_STATISTICS_update (GDS_stats,
-                            gettext_noop ("# P2P RESULTS received"),
+                            "# P2P RESULTS received",
                             1,
                             GNUNET_NO);
   GNUNET_STATISTICS_update (GDS_stats,
-                            gettext_noop ("# P2P RESULT bytes received"),
+                            "# P2P RESULT bytes received",
                             msize,
                             GNUNET_NO);
   {
     enum GNUNET_GenericReturnValue ret;
+    const struct GNUNET_HashCode *pquery;
 
     ret = GNUNET_BLOCK_get_key (GDS_block_context,
-                                type,
-                                data,
-                                data_size,
-                                &dquery);
+                                bd.type,
+                                bd.data,
+                                bd.data_size,
+                                &bd.key);
     if (GNUNET_NO == ret)
     {
       GNUNET_break_op (0);
       return;
     }
-    pquery = (GNUNET_OK == ret) ? &dquery : &prm->key;
+    pquery = (GNUNET_OK == ret) ? &bd.key : &prm->key;
     if (GNUNET_OK !=
         GNUNET_BLOCK_check_block (GDS_block_context,
-                                  type,
+                                  bd.type,
                                   pquery,
-                                  data,
-                                  data_size))
+                                  bd.data,
+                                  bd.data_size))
     {
       GNUNET_break_op (0);
       return;
     }
   }
+
   if (GNUNET_YES == log_route_details_stderr)
   {
     char *tmp;
@@ -2357,8 +2220,8 @@ handle_dht_p2p_result (void *cls,
 
     gp = GNUNET_STRINGS_pp2s (get_path,
                               get_path_length);
-    pp = GNUNET_STRINGS_pp2s (put_path,
-                              put_path_length);
+    pp = GNUNET_STRINGS_pp2s (bd.put_path,
+                              bd.put_path_length);
     tmp = GNUNET_strdup (GNUNET_i2s (&my_identity));
     LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG,
                  "R5N RESULT %s: %s->%s (GP: %s, PP: %s)\n",
@@ -2371,22 +2234,22 @@ handle_dht_p2p_result (void *cls,
     GNUNET_free (pp);
     GNUNET_free (tmp);
   }
+
   /* if we got a HELLO, consider it for our own routing table */
-  if (GNUNET_BLOCK_TYPE_DHT_HELLO == type)
+  if (GNUNET_BLOCK_TYPE_DHT_HELLO == bd.type)
   {
-    const struct GNUNET_MessageHeader *h;
+    const struct GNUNET_MessageHeader *h = bd.data;
     struct GNUNET_PeerIdentity pid;
 
     /* Should be a HELLO, validate and consider using it! */
-    if (data_size < sizeof(struct GNUNET_HELLO_Message))
+    if (bd.data_size < sizeof(struct GNUNET_HELLO_Message))
     {
-      GNUNET_break_op (0);
+      GNUNET_break (0);
       return;
     }
-    h = data;
-    if (data_size != ntohs (h->size))
+    if (bd.data_size != ntohs (h->size))
     {
-      GNUNET_break_op (0);
+      GNUNET_break (0);
       return;
     }
     if (GNUNET_OK !=
@@ -2396,9 +2259,9 @@ handle_dht_p2p_result (void *cls,
       GNUNET_break_op (0);
       return;
     }
-    if ((GNUNET_YES != disable_try_connect) &&
-        (0 != GNUNET_memcmp (&my_identity,
-                             &pid)))
+    if ( (GNUNET_YES != disable_try_connect) &&
+         (0 != GNUNET_memcmp (&my_identity,
+                              &pid)) )
       try_connect (&pid,
                    h);
   }
@@ -2409,16 +2272,9 @@ handle_dht_p2p_result (void *cls,
     if (0 == GNUNET_memcmp (&get_path[i],
                             peer->id))
     {
-      process_reply_with_path (exp_time,
+      process_reply_with_path (&bd,
                                &prm->key,
-                               pquery,
-                               i,
-                               get_path,
-                               put_path_length,
-                               put_path,
-                               type,
-                               data_size,
-                               data);
+                               i, get_path);
       return;
     }
 
@@ -2430,16 +2286,9 @@ handle_dht_p2p_result (void *cls,
                    get_path,
                    get_path_length * sizeof(struct GNUNET_PeerIdentity));
     xget_path[get_path_length] = *peer->id;
-    process_reply_with_path (exp_time,
+    process_reply_with_path (&bd,
                              &prm->key,
-                             pquery,
-                             get_path_length + 1,
-                             xget_path,
-                             put_path_length,
-                             put_path,
-                             type,
-                             data_size,
-                             data);
+                             get_path_length + 1, xget_path);
   }
 }
 
diff --git a/src/dht/gnunet-service-dht_neighbours.h 
b/src/dht/gnunet-service-dht_neighbours.h
index 55cc5b135..ba7cc6055 100644
--- a/src/dht/gnunet-service-dht_neighbours.h
+++ b/src/dht/gnunet-service-dht_neighbours.h
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2009, 2010, 2011 GNUnet e.V.
+     Copyright (C) 2009, 2010, 2011, 2022 GNUnet e.V.
 
      GNUnet is free software: you can redistribute it and/or modify it
      under the terms of the GNU Affero General Public License as published
@@ -30,6 +30,7 @@
 #include "gnunet_util_lib.h"
 #include "gnunet_block_lib.h"
 #include "gnunet_dht_service.h"
+#include "gnunet-service-dht_datacache.h"
 
 /**
  * Hash of the identity of this peer.
@@ -44,30 +45,19 @@ extern struct GNUNET_HashCode my_identity_hash;
  * peer in the network (or if we are the closest peer in the
  * network).
  *
- * @param type type of the block
+ * @param bd data about the block
  * @param options routing options
  * @param desired_replication_level desired replication level
- * @param expiration_time when does the content expire
  * @param hop_count how many hops has this message traversed so far
  * @param bf Bloom filter of peers this PUT has already traversed
- * @param key key for the content
- * @param put_path_length number of entries in put_path
- * @param put_path peers this request has traversed so far (if tracked)
- * @param data payload to store
- * @param data_size number of bytes in data
  * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not
  */
-int
-GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
+enum GNUNET_GenericReturnValue
+GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd,
                            enum GNUNET_DHT_RouteOption options,
                            uint32_t desired_replication_level,
-                           struct GNUNET_TIME_Absolute expiration_time,
                            uint32_t hop_count,
-                           struct GNUNET_CONTAINER_BloomFilter *bf,
-                           const struct GNUNET_HashCode *key,
-                           unsigned int put_path_length,
-                           struct GNUNET_PeerIdentity *put_path,
-                           const void *data, size_t data_size);
+                           struct GNUNET_CONTAINER_BloomFilter *bf);
 
 
 /**
@@ -87,7 +77,7 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
  * @param peer_bf filter for peers not to select (again, updated)
  * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not
  */
-int
+enum GNUNET_GenericReturnValue
 GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
                            enum GNUNET_DHT_RouteOption options,
                            uint32_t desired_replication_level,
@@ -106,26 +96,17 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
  *
  * @param target neighbour that should receive the block (if still connected)
  * @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 put_path
- * @param put_path peers the original PUT traversed (if tracked)
+ * @param bd details about the reply
+ * @param query_hash query that was used for the request
  * @param get_path_length number of entries in put_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 data
  */
 void
 GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target,
-                             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,
+                             const struct GDS_DATACACHE_BlockData *bd,
+                             const struct GNUNET_HashCode *query_hash,
                              unsigned int get_path_length,
-                             const struct GNUNET_PeerIdentity *get_path,
-                             const void *data,
-                             size_t data_size);
+                             const struct GNUNET_PeerIdentity *get_path);
 
 
 /**
@@ -138,7 +119,7 @@ GDS_NEIGHBOURS_handle_reply (const struct 
GNUNET_PeerIdentity *target,
  * @return #GNUNET_YES if node location is closest,
  *         #GNUNET_NO otherwise.
  */
-int
+enum GNUNET_GenericReturnValue
 GDS_am_closest_peer (const struct GNUNET_HashCode *key,
                      const struct GNUNET_CONTAINER_BloomFilter *bloom);
 
@@ -148,7 +129,7 @@ GDS_am_closest_peer (const struct GNUNET_HashCode *key,
  *
  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  */
-int
+enum GNUNET_GenericReturnValue
 GDS_NEIGHBOURS_init (void);
 
 
diff --git a/src/dht/gnunet-service-dht_nse.c b/src/dht/gnunet-service-dht_nse.c
index 7f411cf71..58f18816a 100644
--- a/src/dht/gnunet-service-dht_nse.c
+++ b/src/dht/gnunet-service-dht_nse.c
@@ -52,11 +52,13 @@ static struct GNUNET_NSE_Handle *nse;
  *
  */
 static void
-update_network_size_estimate (void *cls, struct GNUNET_TIME_Absolute timestamp,
-                              double logestimate, double std_dev)
+update_network_size_estimate (void *cls,
+                              struct GNUNET_TIME_Absolute timestamp,
+                              double logestimate,
+                              double std_dev)
 {
   GNUNET_STATISTICS_update (GDS_stats,
-                            gettext_noop ("# Network size estimates received"),
+                            "# Network size estimates received",
                             1, GNUNET_NO);
   /* do not allow estimates < 0.5 */
   log_of_network_size_estimate = GNUNET_MAX (0.5, logestimate);
@@ -83,20 +85,22 @@ GDS_NSE_init ()
 {
   unsigned long long hops;
 
-  if ((GNUNET_YES ==
-       GNUNET_CONFIGURATION_have_value (GDS_cfg,
-                                        "dht",
-                                        "FORCE_NSE")) &&
-      (GNUNET_OK ==
-       GNUNET_CONFIGURATION_get_value_number (GDS_cfg,
-                                              "dht",
-                                              "FORCE_NSE",
-                                              &hops)))
+  if ( (GNUNET_YES ==
+        GNUNET_CONFIGURATION_have_value (GDS_cfg,
+                                         "dht",
+                                         "FORCE_NSE")) &&
+       (GNUNET_OK ==
+        GNUNET_CONFIGURATION_get_value_number (GDS_cfg,
+                                               "dht",
+                                               "FORCE_NSE",
+                                               &hops)) )
   {
     log_of_network_size_estimate = (double) hops;
     return;
   }
-  nse = GNUNET_NSE_connect (GDS_cfg, &update_network_size_estimate, NULL);
+  nse = GNUNET_NSE_connect (GDS_cfg,
+                            &update_network_size_estimate,
+                            NULL);
 }
 
 
diff --git a/src/dht/gnunet-service-dht_routing.c 
b/src/dht/gnunet-service-dht_routing.c
index ef3aded77..8ba0c70ad 100644
--- a/src/dht/gnunet-service-dht_routing.c
+++ b/src/dht/gnunet-service-dht_routing.c
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2011 GNUnet e.V.
+     Copyright (C) 2011, 2022 GNUnet e.V.
 
      GNUnet is free software: you can redistribute it and/or modify it
      under the terms of the GNU Affero General Public License as published
@@ -31,8 +31,9 @@
 
 /**
  * Number of requests we track at most (for routing replies).
+ * TODO: make configurable!
  */
-#define DHT_MAX_RECENT (1024 * 16)
+#define DHT_MAX_RECENT (1024 * 128)
 
 
 /**
@@ -96,49 +97,25 @@ static struct GNUNET_CONTAINER_MultiHashMap *recent_map;
 
 
 /**
- * Closure for the 'process' function.
+ * Closure for the process() function.
  */
 struct ProcessContext
 {
   /**
-   * Path of the original PUT
+   * Block data.
    */
-  const struct GNUNET_PeerIdentity *put_path;
+  const struct GDS_DATACACHE_BlockData *bd;
 
   /**
    * Path of the reply.
    */
   const struct GNUNET_PeerIdentity *get_path;
 
-  /**
-   * Payload of the reply.
-   */
-  const void *data;
-
-  /**
-   * Expiration time of the result.
-   */
-  struct GNUNET_TIME_Absolute expiration_time;
-
-  /**
-   * Number of entries in @e put_path.
-   */
-  unsigned int put_path_length;
-
   /**
    * Number of entries in @e get_path.
    */
   unsigned int get_path_length;
 
-  /**
-   * Number of bytes in @e data.
-   */
-  size_t data_size;
-
-  /**
-   * Type of the reply.
-   */
-  enum GNUNET_BLOCK_Type type;
 };
 
 
@@ -146,71 +123,56 @@ struct ProcessContext
  * Forward the result to the given peer if it matches the request.
  *
  * @param cls the `struct ProcessContext` with the result
- * @param key the query
+ * @param query_hash the hash from the original query
  * @param value the `struct RecentRequest` with the request
  * @return #GNUNET_OK (continue to iterate)
  */
 static enum GNUNET_GenericReturnValue
 process (void *cls,
-         const struct GNUNET_HashCode *key,
+         const struct GNUNET_HashCode *query_hash,
          void *value)
 {
   struct ProcessContext *pc = cls;
   struct RecentRequest *rr = value;
   enum GNUNET_BLOCK_ReplyEvaluationResult eval;
-  unsigned int gpl;
-  unsigned int ppl;
-  struct GNUNET_HashCode hc;
-  const struct GNUNET_HashCode *eval_key;
+  unsigned int get_path_length;
+  struct GDS_DATACACHE_BlockData bdx = *pc->bd;
 
-  if ((rr->type != GNUNET_BLOCK_TYPE_ANY) &&
-      (rr->type != pc->type))
+  if ( (rr->type != GNUNET_BLOCK_TYPE_ANY) &&
+       (rr->type != pc->bd->type) )
     return GNUNET_OK;           /* type mismatch */
-
   if (0 != (rr->options & GNUNET_DHT_RO_RECORD_ROUTE))
   {
-    gpl = pc->get_path_length;
-    ppl = pc->put_path_length;
+    get_path_length = pc->get_path_length;
   }
   else
   {
-    gpl = 0;
-    ppl = 0;
+    get_path_length = 0;
+    bdx.put_path_length = 0;
+    bdx.put_path = NULL;
   }
-  /* FIXME-SCHANZEN: should we modify FIND_PEER to
-     be a generic approximate search and not check
-     for the DHT_HELLO type here? */
-  if ( (0 != (rr->options & GNUNET_DHT_RO_FIND_PEER)) &&
-       (pc->type == GNUNET_BLOCK_TYPE_DHT_HELLO) )
+  if ( (0 == (rr->options & GNUNET_DHT_RO_FIND_PEER)) &&
+       (0 != GNUNET_memcmp (query_hash,
+                            &bdx.key)) )
   {
-    /* 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;
+    GNUNET_STATISTICS_update (GDS_stats,
+                              "# Inexact matches discarded in exact search",
+                              1,
+                              GNUNET_NO);
+    return GNUNET_OK; /* exact search, but inexact match */
   }
-  eval
-    = GNUNET_BLOCK_check_reply (GDS_block_context,
-                                pc->type,
-                                rr->bg,
-                                eval_key,
-                                rr->xquery,
-                                rr->xquery_size,
-                                pc->data,
-                                pc->data_size);
+  eval = GNUNET_BLOCK_check_reply (GDS_block_context,
+                                   bdx.type,
+                                   rr->bg,
+                                   &bdx.key,
+                                   rr->xquery,
+                                   rr->xquery_size,
+                                   bdx.data,
+                                   bdx.data_size);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Result for %s of type %d was evaluated as %d\n",
-              GNUNET_h2s (key),
-              pc->type,
+              GNUNET_h2s (&bdx.key),
+              bdx.type,
               eval);
   switch (eval)
   {
@@ -222,13 +184,9 @@ process (void *cls,
                               1,
                               GNUNET_NO);
     GDS_NEIGHBOURS_handle_reply (&rr->peer,
-                                 pc->type,
-                                 pc->expiration_time,
-                                 key,
-                                 ppl, pc->put_path,
-                                 gpl, pc->get_path,
-                                 pc->data,
-                                 pc->data_size);
+                                 &bdx,
+                                 query_hash,
+                                 get_path_length, pc->get_path);
     break;
   case GNUNET_BLOCK_REPLY_OK_DUPLICATE:
     GNUNET_STATISTICS_update (GDS_stats,
@@ -264,39 +222,25 @@ process (void *cls,
  * GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching
  * request recently.
  *
- * @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 bd block details
+ * @param query_hash query used in the inquiry
  * @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 data
  */
 void
-GDS_ROUTING_process (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,
+GDS_ROUTING_process (const struct GDS_DATACACHE_BlockData *bd,
+                     const struct GNUNET_HashCode *query_hash,
                      unsigned int get_path_length,
-                     const struct GNUNET_PeerIdentity *get_path,
-                     const void *data,
-                     size_t data_size)
+                     const struct GNUNET_PeerIdentity *get_path)
 {
-  struct ProcessContext pc;
-
-  pc.type = type;
-  pc.expiration_time = expiration_time;
-  pc.put_path_length = put_path_length;
-  pc.put_path = put_path;
-  pc.get_path_length = get_path_length;
-  pc.get_path = get_path;
-  pc.data = data;
-  pc.data_size = data_size;
+  struct ProcessContext pc = {
+    .bd = bd,
+    .get_path = get_path,
+    .get_path_length = get_path_length
+  };
+
   GNUNET_CONTAINER_multihashmap_get_multiple (recent_map,
-                                              key,
+                                              query_hash,
                                               &process,
                                               &pc);
 }
@@ -313,7 +257,7 @@ expire_oldest_entry (void)
   struct RecentRequest *recent_req;
 
   GNUNET_STATISTICS_update (GDS_stats,
-                            "# Entries removed from routing table",
+                            "# Old entries removed from routing table",
                             1,
                             GNUNET_NO);
   recent_req = GNUNET_CONTAINER_heap_peek (recent_heap);
@@ -334,7 +278,7 @@ expire_oldest_entry (void)
  *
  * @param cls the new `struct RecentRequest` (to discard upon successful 
combination)
  * @param key the query
- * @param value the existing 'struct RecentRequest' (to update upon successful 
combination)
+ * @param value the existing `struct RecentRequest` (to update upon successful 
combination)
  * @return #GNUNET_OK (continue to iterate),
  *         #GNUNET_SYSERR if the request was successfully combined
  */
@@ -346,13 +290,13 @@ try_combine_recent (void *cls,
   struct RecentRequest *in = cls;
   struct RecentRequest *rr = value;
 
-  if ((0 != GNUNET_memcmp (&in->peer,
-                           &rr->peer)) ||
-      (in->type != rr->type) ||
-      (in->xquery_size != rr->xquery_size) ||
-      (0 != memcmp (in->xquery,
-                    rr->xquery,
-                    in->xquery_size)))
+  if ( (0 != GNUNET_memcmp (&in->peer,
+                            &rr->peer)) ||
+       (in->type != rr->type) ||
+       (in->xquery_size != rr->xquery_size) ||
+       (0 != memcmp (in->xquery,
+                     rr->xquery,
+                     in->xquery_size) ) )
     return GNUNET_OK;
   GNUNET_break (GNUNET_SYSERR !=
                 GNUNET_BLOCK_group_merge (in->bg,
@@ -410,19 +354,21 @@ GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender,
                                                   recent_req))
   {
     GNUNET_STATISTICS_update (GDS_stats,
-                              gettext_noop
-                                ("# DHT requests combined"),
-                              1, GNUNET_NO);
+                              "# DHT requests combined",
+                              1,
+                              GNUNET_NO);
     return;
   }
   recent_req->heap_node
-    = GNUNET_CONTAINER_heap_insert (recent_heap,
-                                    recent_req,
-                                    GNUNET_TIME_absolute_get ().abs_value_us);
-  GNUNET_CONTAINER_multihashmap_put (recent_map,
-                                     key,
-                                     recent_req,
-                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+    = GNUNET_CONTAINER_heap_insert (
+        recent_heap,
+        recent_req,
+        GNUNET_TIME_absolute_get ().abs_value_us);
+  (void) GNUNET_CONTAINER_multihashmap_put (
+    recent_map,
+    key,
+    recent_req,
+    GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
 }
 
 
@@ -446,10 +392,12 @@ GDS_ROUTING_done ()
 {
   while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0)
     expire_oldest_entry ();
-  GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (recent_heap));
+  GNUNET_assert (0 ==
+                 GNUNET_CONTAINER_heap_get_size (recent_heap));
   GNUNET_CONTAINER_heap_destroy (recent_heap);
   recent_heap = NULL;
-  GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (recent_map));
+  GNUNET_assert (0 ==
+                 GNUNET_CONTAINER_multihashmap_size (recent_map));
   GNUNET_CONTAINER_multihashmap_destroy (recent_map);
   recent_map = NULL;
 }
diff --git a/src/dht/gnunet-service-dht_routing.h 
b/src/dht/gnunet-service-dht_routing.h
index 7fea01bae..1a1514cc5 100644
--- a/src/dht/gnunet-service-dht_routing.h
+++ b/src/dht/gnunet-service-dht_routing.h
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2011 GNUnet e.V.
+     Copyright (C) 2011, 2022 GNUnet e.V.
 
      GNUnet is free software: you can redistribute it and/or modify it
      under the terms of the GNU Affero General Public License as published
@@ -35,29 +35,19 @@
  * Handle a reply (route to origin).  Only forwards the reply back to
  * other peers waiting for it.  Does not do local caching or
  * forwarding to local clients.  Essentially calls
- * #GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching
+ * GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching
  * request recently.
  *
- * @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 bd block details
+ * @param query_hash query used in the inquiry
  * @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
  */
 void
-GDS_ROUTING_process (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,
+GDS_ROUTING_process (const struct GDS_DATACACHE_BlockData *bd,
+                     const struct GNUNET_HashCode *query_hash,
                      unsigned int get_path_length,
-                     const struct GNUNET_PeerIdentity *get_path,
-                     const void *data,
-                     size_t data_size);
+                     const struct GNUNET_PeerIdentity *get_path);
 
 
 /**
diff --git a/src/include/gnunet_datacache_plugin.h 
b/src/include/gnunet_datacache_plugin.h
index d7fa8fde0..5d5cac12c 100644
--- a/src/include/gnunet_datacache_plugin.h
+++ b/src/include/gnunet_datacache_plugin.h
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet
-     Copyright (C) 2006, 2009, 2015 GNUnet e.V.
+     Copyright (C) 2006, 2009, 2015, 2022 GNUnet e.V.
 
      GNUnet is free software: you can redistribute it and/or modify it
      under the terms of the GNU Affero General Public License as published
@@ -115,15 +115,17 @@ struct GNUNET_DATACACHE_PluginFunctions
    * @param path_info a path through the network
    * @return 0 if duplicate, -1 on error, number of bytes used otherwise
    */
-  ssize_t (*put) (void *cls,
-                  const struct GNUNET_HashCode *key,
-                  uint32_t xor_distance,
-                  size_t size,
-                  const char *data,
-                  enum GNUNET_BLOCK_Type type,
-                  struct GNUNET_TIME_Absolute discard_time,
-                  unsigned int path_info_len,
-                  const struct GNUNET_PeerIdentity *path_info);
+  ssize_t
+  (*put) (void *cls,
+          const struct GNUNET_HashCode *key,
+          uint32_t xor_distance,
+          size_t size,
+          const char *data,
+          enum GNUNET_BLOCK_Type type,
+          struct GNUNET_TIME_Absolute discard_time,
+          unsigned int path_info_len,
+          const struct GNUNET_PeerIdentity *path_info);
+
 
   /**
    * Iterate over the results for a particular key
@@ -136,11 +138,13 @@ struct GNUNET_DATACACHE_PluginFunctions
    * @param iter_cls closure for @a iter
    * @return the number of results found
    */
-  unsigned int (*get) (void *cls,
-                       const struct GNUNET_HashCode *key,
-                       enum GNUNET_BLOCK_Type type,
-                       GNUNET_DATACACHE_Iterator iter,
-                       void *iter_cls);
+  unsigned int
+  (*get) (void *cls,
+          const struct GNUNET_HashCode *key,
+          enum GNUNET_BLOCK_Type type,
+          GNUNET_DATACACHE_Iterator iter,
+          void *iter_cls);
+
 
   /**
    * Delete the entry with the lowest expiration value
@@ -149,19 +153,8 @@ struct GNUNET_DATACACHE_PluginFunctions
    * @param cls closure (internal context for the plugin)
    * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
    */
-  int (*del) (void *cls);
-
-  /**
-   * Return a random value from the datastore.
-   *
-   * @param cls closure (internal context for the plugin)
-   * @param iter maybe NULL (to just count)
-   * @param iter_cls closure for @a iter
-   * @return the number of results found (zero or one)
-   */
-  unsigned int (*get_random) (void *cls,
-                              GNUNET_DATACACHE_Iterator iter,
-                              void *iter_cls);
+  enum GNUNET_GenericReturnValue
+  (*del)(void *cls);
 
 
   /**
@@ -177,11 +170,12 @@ struct GNUNET_DATACACHE_PluginFunctions
    * @param iter_cls closure for @a iter
    * @return the number of results found
    */
-  unsigned int (*get_closest) (void *cls,
-                               const struct GNUNET_HashCode *key,
-                               unsigned int num_results,
-                               GNUNET_DATACACHE_Iterator iter,
-                               void *iter_cls);
+  unsigned int
+  (*get_closest) (void *cls,
+                  const struct GNUNET_HashCode *key,
+                  unsigned int num_results,
+                  GNUNET_DATACACHE_Iterator iter,
+                  void *iter_cls);
 };
 
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]