gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r14308 - gnunet/src/dht


From: gnunet
Subject: [GNUnet-SVN] r14308 - gnunet/src/dht
Date: Wed, 2 Feb 2011 12:54:21 +0100

Author: nevans
Date: 2011-02-02 12:54:21 +0100 (Wed, 02 Feb 2011)
New Revision: 14308

Added:
   gnunet/src/dht/test_dht_twopeer_path_tracking.c
Modified:
   gnunet/src/dht/Makefile.am
   gnunet/src/dht/dht.h
   gnunet/src/dht/dht_api.c
   gnunet/src/dht/dht_api_find_peer.c
   gnunet/src/dht/dht_api_get_put.c
   gnunet/src/dht/gnunet-service-dht.c
   gnunet/src/dht/test_dht_api_data.conf
   gnunet/src/dht/test_dht_api_peer1.conf
   gnunet/src/dht/test_dht_multipeer.c
   gnunet/src/dht/test_dht_multipeer_data.conf
   gnunet/src/dht/test_dht_twopeer.c
   gnunet/src/dht/test_dht_twopeer_data.conf
   gnunet/src/dht/test_dhtlog.c
   gnunet/src/dht/test_dhtlog_data.conf
Log:
path tracking commit, hopefully a fix for dht_api connect bug, needs tested

Modified: gnunet/src/dht/Makefile.am
===================================================================
--- gnunet/src/dht/Makefile.am  2011-02-02 09:04:42 UTC (rev 14307)
+++ gnunet/src/dht/Makefile.am  2011-02-02 11:54:21 UTC (rev 14308)
@@ -52,7 +52,7 @@
   $(XLIB)
 libgnunet_plugin_dhtlog_mysql_dump_la_LDFLAGS = \
  $(GN_PLUGIN_LDFLAGS)
-
+ 
 libgnunet_plugin_dhtlog_mysql_dump_load_la_SOURCES = \
   plugin_dhtlog_mysql_dump_load.c
 libgnunet_plugin_dhtlog_mysql_dump_load_la_LIBADD = \
@@ -70,6 +70,7 @@
   -version-info 0:0:0
 
 libgnunetdht_la_SOURCES = \
+libgnunetdht_la_SOURCES = \
   dht_api.c dht.h \
   dht_api_get_put.c \
   dht_api_find_peer.c 
@@ -84,12 +85,10 @@
  gnunet-service-dht \
  gnunet-dht-get \
  gnunet-dht-get-peer \
- gnunet-dht-put 
+ gnunet-dht-put \
+ gnunet-dht-driver
 
-if HAVE_MALICIOUS
-noinst_PROGRAMS = \
- gnunet-dht-driver 
-endif
+noinst_PROGRAMS = $(check_PROGRAMS)
 
 gnunet_service_dht_SOURCES = \
  gnunet-service-dht.c         
@@ -151,14 +150,17 @@
  test_dht_api \
  test_dht_twopeer \
  test_dht_twopeer_put_get \
+ test_dht_twopeer_path_tracking \
  test_dht_multipeer \
- test_dhtlog 
-# test_hash_operations
+ test_dhtlog
 
 if !DISABLE_TEST_RUN
 TESTS = test_dht_api $(check_SCRIPTS) \
  test_dht_twopeer \
- test_dht_twopeer_put_get
+ test_dht_twopeer_put_get \
+ test_dht_twopeer_path_tracking \
+ test_dht_multipeer \
+ test_dhtlog
 endif
 
 test_dht_api_SOURCES = \
@@ -179,13 +181,6 @@
 test_dht_multipeer_DEPENDENCIES = \
   libgnunetdht.la                          
  
-#test_hash_operations_SOURCES = \
-# test_hash_operations.c
-#test_hash_operations_LDADD = \
-# $(top_builddir)/src/util/libgnunetutil.la \
-# $(top_builddir)/src/testing/libgnunettesting.la \
-# $(top_builddir)/src/dht/libgnunetdht.la 
-
 test_dht_twopeer_SOURCES = \
  test_dht_twopeer.c
 test_dht_twopeer_LDADD = \
@@ -201,6 +196,13 @@
  $(top_builddir)/src/util/libgnunetutil.la \
  $(top_builddir)/src/testing/libgnunettesting.la \
  $(top_builddir)/src/dht/libgnunetdht.la   
+ 
+test_dht_twopeer_path_tracking_SOURCES = \
+ test_dht_twopeer_path_tracking.c
+test_dht_twopeer_path_tracking_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/dht/libgnunetdht.la   
 
 test_dhtlog_SOURCES = \
  test_dhtlog.c

Modified: gnunet/src/dht/dht.h
===================================================================
--- gnunet/src/dht/dht.h        2011-02-02 09:04:42 UTC (rev 14307)
+++ gnunet/src/dht/dht.h        2011-02-02 11:54:21 UTC (rev 14308)
@@ -199,20 +199,13 @@
   struct GNUNET_MessageHeader header;
 
   /**
-   * Number of peers recorded in the "PUT" path.
-   * (original path message took during "PUT").  These
-   * peer identities follow this message.
+   * Number of peers recorded in the outgoing
+   * path from source to the final destination
+   * of this message.
    */
-  uint16_t put_path_length GNUNET_PACKED;
+  uint32_t outgoing_path_length GNUNET_PACKED;
 
   /**
-   * Number of peers recorded in the "GET" path
-   * (inverse of the path the GET message took).  These
-   * peer identities follow this message.
-   */
-  uint16_t get_path_length GNUNET_PACKED;
-
-  /**
    * Unique ID identifying this request (necessary for
    * client to compare to sent requests)
    */
@@ -223,11 +216,9 @@
    */
   GNUNET_HashCode key;
 
-  /* PUT path */
+  /* GNUNET_MessageHeader *enc actual DHT message, copied to end of this dealy 
do */
 
-  /* GET path */
-
-  /* GNUNET_MessageHeader *enc actual DHT message, copied to end of this dealy 
do */
+  /* OUTGOING path */
 };
 
 
@@ -267,11 +258,11 @@
   uint32_t network_size GNUNET_PACKED;
 
   /**
-   * Route path length; number of GNUNET_PeerIdentity's
-   * copied to the end of this message (before the actual
-   * encapsulated message)
+   * Generic route path length for a message in the
+   * DHT that arrived at a peer and generated
+   * a reply. Copied to the end of this message.
    */
-  uint32_t route_path_length GNUNET_PACKED;
+  uint32_t outgoing_path_length GNUNET_PACKED;
 
   /**
    * Unique ID identifying this request
@@ -290,6 +281,8 @@
 
   /* GNUNET_MessageHeader *enc actual DHT message, copied to end of this dealy 
do */
 
+  /* OUTGOING PATH */
+
 };
 
 /**
@@ -307,7 +300,7 @@
    * (inverse of the path the outgoing message took).
    * These peer identities follow this message.
    */
-  uint16_t outgoing_path_length GNUNET_PACKED;
+  uint32_t outgoing_path_length GNUNET_PACKED;
 
   /**
    * Message options
@@ -341,12 +334,9 @@
   uint32_t network_size GNUNET_PACKED;
 #endif
 
+  /* GNUNET_MessageHeader *enc actual DHT message, copied to end of this dealy 
do */
 
-  /* PUT path */
-
-  /* GET path */
-
-  /* GNUNET_MessageHeader *enc actual DHT message, copied to end of this dealy 
do */
+  /* OUTGOING PATH */
 };
 
 
@@ -449,14 +439,42 @@
   /**
    * The type for the data for the GET request
    */
-  uint32_t type;
+  uint16_t type;
 
   /**
+   * The number of peer identities appended to the end of this
+   * message.
+   */
+  uint16_t put_path_length;
+
+  /**
    * When does this entry expire?
    */
   struct GNUNET_TIME_AbsoluteNBO expiration;
 
 };
 
+/**
+ * Entry for inserting data into datacache from the DHT.
+ * Needed here so block library can verify entries that
+ * are shoveled into the DHT.
+ */
+struct DHTPutEntry
+{
+  /**
+   * Size of data.
+   */
+  uint16_t data_size;
 
+  /**
+   * Length of recorded path.
+   */
+  uint16_t path_length;
+
+  /* PUT DATA */
+
+  /* PATH ENTRIES */
+};
+
+
 #endif /* DHT_H_ */

Modified: gnunet/src/dht/dht_api.c
===================================================================
--- gnunet/src/dht/dht_api.c    2011-02-02 09:04:42 UTC (rev 14307)
+++ gnunet/src/dht/dht_api.c    2011-02-02 11:54:21 UTC (rev 14308)
@@ -182,6 +182,17 @@
   struct GNUNET_CONTAINER_MultiHashMap *active_requests;
 
   /**
+   * Task for trying to reconnect.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
+
+  /**
+   * How quickly should we retry?  Used for exponential back-off on
+   * connect-errors.
+   */
+  struct GNUNET_TIME_Relative retry_time;
+
+  /**
    * Generator for unique ids.
    */
   uint64_t uid_gen;
@@ -266,35 +277,66 @@
 
 
 /**
- * Re-connect to the DHT, re-issue all pending requests if needed.
+ * Try reconnecting to the dht service.
+ *
+ * @param cls GNUNET_DHT_Handle
+ * @param tc scheduler context
  */
 static void
-reconnect (struct GNUNET_DHT_Handle *handle)
+try_reconnect (void *cls,
+               const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  if (handle->client != NULL)
+  struct GNUNET_DHT_Handle *handle = cls;
+
+  if (handle->retry_time.rel_value < GNUNET_CONSTANTS_SERVICE_RETRY.rel_value)
+    handle->retry_time = GNUNET_CONSTANTS_SERVICE_RETRY;
+  else
+    handle->retry_time = GNUNET_TIME_relative_multiply (handle->retry_time, 2);
+  if (handle->retry_time.rel_value > 
GNUNET_CONSTANTS_SERVICE_TIMEOUT.rel_value)
+    handle->retry_time = GNUNET_CONSTANTS_SERVICE_TIMEOUT;
+  handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
+  handle->client = GNUNET_CLIENT_connect ("dht", handle->cfg);
+  if (handle->client == NULL)
     {
-      GNUNET_CLIENT_disconnect (handle->client, 
-                               GNUNET_NO);
-      handle->client = NULL;
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "dht reconnect failed(!)\n");
+      return;
     }
-  if (GNUNET_YES != try_connect (handle))
-    return;
+
   GNUNET_CONTAINER_multihashmap_iterate (handle->active_requests,
-                                        &add_request_to_pending,
-                                        handle);
+                                         &add_request_to_pending,
+                                         handle);
   if (handle->pending_head == NULL)
     return;
   GNUNET_CLIENT_notify_transmit_ready (handle->client,
-                                      ntohs(handle->pending_head->msg->size),
-                                      GNUNET_TIME_UNIT_FOREVER_REL,
-                                      GNUNET_NO,
-                                      &transmit_pending,
-                                      handle);
-                                      
+                                       ntohs(handle->pending_head->msg->size),
+                                       GNUNET_TIME_UNIT_FOREVER_REL,
+                                       GNUNET_NO,
+                                       &transmit_pending,
+                                       handle);
 }
 
 
 /**
+ * Try reconnecting to the DHT service.
+ *
+ * @param handle handle to dht to (possibly) disconnect and reconnect
+ */
+static void
+do_disconnect (struct GNUNET_DHT_Handle *handle)
+{
+  if (handle->client == NULL)
+    return;
+
+  GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO);
+  handle->client = NULL;
+  handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (handle->retry_time,
+                                                         &try_reconnect,
+                                                         handle);
+}
+
+
+/**
  * Try to send messages from list of messages to send
  */
 static void
@@ -302,8 +344,11 @@
 {
   struct PendingMessage *head;
 
-  if (GNUNET_YES != try_connect (handle))
-    return;      
+  if (handle->client == NULL)
+    {
+      do_disconnect(handle);
+      return;
+    }
   if (handle->th != NULL)
     return;
   if (NULL == (head = handle->pending_head))
@@ -316,7 +361,7 @@
                                                    handle);
   if (NULL == handle->th)    
     {
-      reconnect (handle);
+      do_disconnect (handle);
       return;
     }
 }
@@ -337,7 +382,7 @@
   handle->th = NULL;
   if (buf == NULL)
     {
-      reconnect (handle);
+      do_disconnect (handle);
       return 0;
     }
   if (NULL == (head = handle->pending_head))
@@ -377,8 +422,6 @@
 }
 
 
-
-
 /**
  * Process a given reply that might match the given
  * request.
@@ -393,12 +436,11 @@
   const struct GNUNET_MessageHeader *enc_msg;
   size_t enc_size;
   uint64_t uid;
-  const struct GNUNET_PeerIdentity **get_path;
-  const struct GNUNET_PeerIdentity **put_path;
+  const struct GNUNET_PeerIdentity **outgoing_path;
   const struct GNUNET_PeerIdentity *pos;
-  uint16_t gpl;
-  uint16_t ppl;
+  uint32_t outgoing_path_length;
   unsigned int i;
+  char *path_offset;
 
   uid = GNUNET_ntohll (dht_msg->unique_id);
   if (uid != rh->uid)
@@ -407,62 +449,43 @@
                  "Reply UID did not match request UID\n");
       return GNUNET_YES;
     }
-  enc_size = ntohs (dht_msg->header.size) - sizeof (struct 
GNUNET_DHT_RouteResultMessage);
+  enc_msg = (const struct GNUNET_MessageHeader *)&dht_msg[1];
+  enc_size = ntohs (enc_msg->size);
   if (enc_size < sizeof (struct GNUNET_MessageHeader))
     {
       GNUNET_break (0);
       return GNUNET_NO;
     }
-  pos = (const struct GNUNET_PeerIdentity *) &dht_msg[1];
-  ppl = ntohs (dht_msg->put_path_length);
-  gpl = ntohs (dht_msg->get_path_length);
-  if ( (ppl + gpl) * sizeof (struct GNUNET_PeerIdentity) > enc_size)
+  path_offset = (char *)&dht_msg[1];
+  path_offset += enc_size;
+  pos = (const struct GNUNET_PeerIdentity *) path_offset;
+  outgoing_path_length = ntohl (dht_msg->outgoing_path_length);
+  if (outgoing_path_length * sizeof (struct GNUNET_PeerIdentity) > 
ntohs(dht_msg->header.size) - enc_size)
     {
       GNUNET_break (0);
       return GNUNET_NO;
     }
-  if (ppl > 0)
+
+  if (outgoing_path_length > 0)
     {
-      put_path = GNUNET_malloc ((ppl+1) * sizeof (struct 
GNUNET_PeerIdentity*));
-      for (i=0;i<ppl;i++)
+      outgoing_path = GNUNET_malloc ((outgoing_path_length + 1) * sizeof 
(struct GNUNET_PeerIdentity*));
+      for (i = 0; i < outgoing_path_length; i++)
        {
-         put_path[i] = pos;
+         outgoing_path[i] = pos;
          pos++;
        }
-      put_path[ppl] = NULL;
+      outgoing_path[outgoing_path_length] = NULL;
     }
   else
-    put_path = NULL;
-  if (gpl > 0)
-    {
-      get_path = GNUNET_malloc ((gpl+1) * sizeof (struct 
GNUNET_PeerIdentity*));
-      for (i=0;i<gpl;i++)
-       {
-         get_path[i] = pos;
-         pos++;
-       }
-      get_path[gpl] = NULL;
-    }
-  else
-    get_path = NULL;
-  enc_size -= (ppl + gpl) * sizeof (struct GNUNET_PeerIdentity);
-  enc_msg = (const struct GNUNET_MessageHeader *) pos;
-  if (enc_size != ntohs (enc_msg->size))
-    {
-      GNUNET_break (0);
-      GNUNET_free_non_null (get_path);
-      GNUNET_free_non_null (put_path);
-      return GNUNET_NO;
-    }
+    outgoing_path = NULL;
+
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Processing reply.\n");
   rh->iter (rh->iter_cls, 
            &rh->key,
-           get_path,
-           put_path,
+           outgoing_path,
            enc_msg);
-  GNUNET_free_non_null (get_path);
-  GNUNET_free_non_null (put_path);
+  GNUNET_free_non_null (outgoing_path);
   return GNUNET_YES;
 }
 
@@ -485,19 +508,19 @@
     {
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "Error receiving data from DHT service, reconnecting\n");
-      reconnect (handle);
+      do_disconnect (handle);
       return;
     }
   if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE_RESULT)
     {
       GNUNET_break (0);
-      reconnect (handle);
+      do_disconnect (handle);
       return;
     }
   if (ntohs (msg->size) < sizeof (struct GNUNET_DHT_RouteResultMessage))
     {
       GNUNET_break (0);
-      reconnect (handle);
+      do_disconnect (handle);
       return;
     }
   dht_msg = (const struct GNUNET_DHT_RouteResultMessage *) msg;

Modified: gnunet/src/dht/dht_api_find_peer.c
===================================================================
--- gnunet/src/dht/dht_api_find_peer.c  2011-02-02 09:04:42 UTC (rev 14307)
+++ gnunet/src/dht/dht_api_find_peer.c  2011-02-02 11:54:21 UTC (rev 14308)
@@ -65,17 +65,15 @@
  *
  * @param cls closure
  * @param key key that was used
- * @param get_path NULL-terminated array of pointers
- *                 to the peers on reverse GET path (or NULL if not recorded)
- * @param put_path NULL-terminated array of pointers
- *                 to the peers on the PUT path (or NULL if not recorded)
+ * @param outgoing_path NULL-terminated array of pointers
+ *                      to the peers on reverse path
+ *                      (or NULL if not recorded)
  * @param reply response
  */
 static void
 find_peer_reply_iterator (void *cls, 
                          const GNUNET_HashCode *key,
-                         const struct GNUNET_PeerIdentity * const *get_path,
-                         const struct GNUNET_PeerIdentity * const *put_path,
+                         const struct GNUNET_PeerIdentity * const 
*outgoing_path,
                          const struct GNUNET_MessageHeader *reply)
 {
   struct GNUNET_DHT_FindPeerHandle *find_peer_handle = cls;

Modified: gnunet/src/dht/dht_api_get_put.c
===================================================================
--- gnunet/src/dht/dht_api_get_put.c    2011-02-02 09:04:42 UTC (rev 14307)
+++ gnunet/src/dht/dht_api_get_put.c    2011-02-02 11:54:21 UTC (rev 14308)
@@ -124,22 +124,25 @@
  *
  * @param cls the 'struct GNUNET_DHT_GetHandle'
  * @param key key that was used
- * @param get_path NULL-terminated array of pointers
- *                 to the peers on reverse GET path (or NULL if not recorded)
- * @param put_path NULL-terminated array of pointers
- *                 to the peers on the PUT path (or NULL if not recorded)
+ * @param outgoing_path path of the message from this peer
+ *                      to the target
  * @param reply response
  */
 static void
 get_reply_iterator (void *cls, 
                    const GNUNET_HashCode *key,
-                   const struct GNUNET_PeerIdentity * const *get_path,
-                   const struct GNUNET_PeerIdentity * const *put_path,
+                   const struct GNUNET_PeerIdentity * const *outgoing_path,
                    const struct GNUNET_MessageHeader *reply)
 {
   struct GNUNET_DHT_GetHandle *get_handle = cls;
   const struct GNUNET_DHT_GetResultMessage *result;
+  const struct GNUNET_PeerIdentity **put_path;
   size_t payload;
+  char *path_offset;
+  const struct GNUNET_PeerIdentity *pos;
+  unsigned int i;
+  uint16_t put_path_length;
+  uint16_t data_size;
 
   if (ntohs (reply->type) != GNUNET_MESSAGE_TYPE_DHT_GET_RESULT)
     {
@@ -150,15 +153,36 @@
   GNUNET_assert (ntohs (reply->size) >=
                  sizeof (struct GNUNET_DHT_GetResultMessage));
   result = (const struct GNUNET_DHT_GetResultMessage *) reply;
+
+  put_path = NULL;
+  put_path_length = ntohs(result->put_path_length);
+  if (put_path_length > 0)
+    {
+      data_size = ntohs(result->header.size) - (put_path_length * 
sizeof(struct GNUNET_PeerIdentity)) - sizeof(struct 
GNUNET_DHT_GetResultMessage);
+      path_offset = (char *)&result[1];
+      //GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "In get_reply_iterator, 
result->header.size is %d, put_path_length %d, offset is %d, data_size is 
%d\n", ntohs(result->header.size), put_path_length, ntohs(result->header.size) 
- (put_path_length * sizeof(struct GNUNET_PeerIdentity)), data_size);
+      path_offset += data_size;
+      pos = (const struct GNUNET_PeerIdentity *)path_offset;
+      //GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Found put peer %s\n", 
GNUNET_i2s((const struct GNUNET_PeerIdentity *)path_offset));
+      put_path = GNUNET_malloc ((put_path_length + 1) * sizeof (struct 
GNUNET_PeerIdentity*));
+      for (i = 0; i < put_path_length; i++)
+        {
+          put_path[i] = pos;
+          pos++;
+        }
+      put_path[put_path_length] = NULL;
+    }
+
   payload = ntohs (reply->size) - sizeof(struct GNUNET_DHT_GetResultMessage);
   get_handle->iter (get_handle->iter_cls,
                    GNUNET_TIME_absolute_ntoh (result->expiration),
                    key,
-                   get_path,
+                   outgoing_path,
                    put_path,
                    ntohs (result->type), 
                    payload,
                    &result[1]);
+  GNUNET_free_non_null(put_path);
 }
 
 

Modified: gnunet/src/dht/gnunet-service-dht.c
===================================================================
--- gnunet/src/dht/gnunet-service-dht.c 2011-02-02 09:04:42 UTC (rev 14307)
+++ gnunet/src/dht/gnunet-service-dht.c 2011-02-02 11:54:21 UTC (rev 14308)
@@ -1096,6 +1096,10 @@
   size_t msize;
   size_t psize;
   char *path_start;
+  char *path_offset;
+#if DEBUG_PATH
+  unsigned int i;
+#endif
 
   increment_stats (STAT_RESULT_FORWARDS);
   msize =
@@ -1118,6 +1122,13 @@
       /* Offset by the size of the enc_msg */
       path_start += ntohs (msg->size);
       memcpy(path_start, msg_ctx->path_history, msg_ctx->path_history_len * 
(sizeof(struct GNUNET_PeerIdentity)));
+#if DEBUG_PATH
+      for (i = 0; i < msg_ctx->path_history_len; i++)
+        {
+          path_offset = &msg_ctx->path_history[i * sizeof(struct 
GNUNET_PeerIdentity)];
+          GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "(forward_result) Key %s Found 
peer %d:%s\n", GNUNET_h2s(&msg_ctx->key), i, GNUNET_i2s((struct 
GNUNET_PeerIdentity *)path_offset));
+        }
+#endif
     }
   result_message->options = htonl (msg_ctx->msg_options);
   result_message->hop_count = htonl (msg_ctx->hop_count + 1);
@@ -1128,7 +1139,13 @@
                                                             DHT_BLOOM_SIZE));
   result_message->unique_id = GNUNET_htonll (msg_ctx->unique_id);
   memcpy (&result_message->key, &msg_ctx->key, sizeof (GNUNET_HashCode));
+  /* Copy the enc_msg, then the path history as well! */
   memcpy (&result_message[1], msg, ntohs (msg->size));
+  path_offset = (char *)&result_message[1];
+  path_offset += ntohs (msg->size);
+  /* If we have path history, copy it to the end of the whole thing */
+  if (msg_ctx->path_history_len > 0)
+    memcpy(path_offset, msg_ctx->path_history, msg_ctx->path_history_len * 
(sizeof(struct GNUNET_PeerIdentity)));
 #if DEBUG_DHT > 1
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "%s:%s Adding pending message size %d for peer %s\n",
@@ -1774,7 +1791,7 @@
   memcpy (&route_message[1], msg, ntohs (msg->size));
   if (GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx->msg_options & 
GNUNET_DHT_RO_RECORD_ROUTE))
     {
-      route_message->route_path_length = htonl(msg_ctx->path_history_len);
+      route_message->outgoing_path_length = htonl(msg_ctx->path_history_len);
       /* Set pointer to start of enc_msg */
       route_path = (char *)&route_message[1];
       /* Offset to the end of the enc_msg */
@@ -1992,18 +2009,23 @@
 static void
 send_reply_to_client (struct ClientList *client,
                       const struct GNUNET_MessageHeader *message,
-                      unsigned long long uid, const GNUNET_HashCode * key)
+                      struct DHT_MessageContext *msg_ctx)
 {
   struct GNUNET_DHT_RouteResultMessage *reply;
   struct PendingMessage *pending_message;
   uint16_t msize;
   size_t tsize;
+  char *reply_offset;
+#if DEBUG_PATH
+  char *path_offset;
+  unsigned int i;
+#endif
 #if DEBUG_DHT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "`%s:%s': Sending reply to client.\n", my_short_id, "DHT");
 #endif
   msize = ntohs (message->size);
-  tsize = sizeof (struct GNUNET_DHT_RouteResultMessage) + msize;
+  tsize = sizeof (struct GNUNET_DHT_RouteResultMessage) + msize + 
(msg_ctx->path_history_len * sizeof(struct GNUNET_PeerIdentity));
   if (tsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
     {
       GNUNET_break_op (0);
@@ -2014,11 +2036,24 @@
   reply = (struct GNUNET_DHT_RouteResultMessage *) &pending_message[1];
   reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE_RESULT);
   reply->header.size = htons (tsize);
-  reply->put_path_length = htons (0);   /* FIXME: implement */
-  reply->get_path_length = htons (0);   /* FIXME: implement */
-  reply->unique_id = GNUNET_htonll (uid);
-  reply->key = *key;
+  reply->outgoing_path_length = htonl(msg_ctx->path_history_len);
+  reply->unique_id = GNUNET_htonll (msg_ctx->unique_id);
+  memcpy (&reply->key, &msg_ctx->key, sizeof (GNUNET_HashCode));
+  reply_offset = (char *)&reply[1];
   memcpy (&reply[1], message, msize);
+  if (msg_ctx->path_history_len > 0)
+    {
+      reply_offset += msize;
+      memcpy(reply_offset, msg_ctx->path_history, msg_ctx->path_history_len * 
sizeof(struct GNUNET_PeerIdentity));
+    }
+#if DEBUG_PATH
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Returning message with outgoing path 
length %d\n", msg_ctx->path_history_len);
+  for (i = 0; i < msg_ctx->path_history_len; i++)
+    {
+      path_offset = &msg_ctx->path_history[i * sizeof(struct 
GNUNET_PeerIdentity)];
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Found peer %d:%s\n", i, 
GNUNET_i2s((struct GNUNET_PeerIdentity *)path_offset));
+    }
+#endif
   add_pending_message (client, pending_message);
 }
 
@@ -2105,6 +2140,8 @@
   struct DHTRouteSource *pos;
   struct PeerInfo *peer_info;
   const struct GNUNET_MessageHeader *hello_msg;
+  unsigned int i;
+  char *path_offset;
 
   increment_stats (STAT_RESULTS);
   /**
@@ -2221,8 +2258,12 @@
           if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_DHT_GET_RESULT)
             increment_stats (STAT_GET_REPLY);
 
-          send_reply_to_client (pos->client, msg,
-                                msg_ctx->unique_id, &msg_ctx->key);
+          for (i = 0; i < msg_ctx->path_history_len; i++)
+            {
+              path_offset = &msg_ctx->path_history[i * sizeof(struct 
GNUNET_PeerIdentity)];
+              GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "(before client) Key %s 
Found peer %d:%s\n", GNUNET_h2s(&msg_ctx->key), i, GNUNET_i2s((struct 
GNUNET_PeerIdentity *)path_offset));
+            }
+          send_reply_to_client (pos->client, msg, msg_ctx);
         }
       else                      /* Send to peer */
         {
@@ -2313,6 +2354,12 @@
   struct DHT_MessageContext *new_msg_ctx;
   struct GNUNET_DHT_GetResultMessage *get_result;
   enum GNUNET_BLOCK_EvaluationResult eval;
+  const struct DHTPutEntry *put_entry;
+  int get_size;
+  char *path_offset;
+#if DEBUG_PATH
+  unsigned int i;
+#endif
 
 #if DEBUG_DHT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2326,6 +2373,24 @@
                                 msg_ctx->reply_bf_mutator,
                                 msg_ctx->xquery,
                                 msg_ctx->xquery_size, data, size);
+
+  put_entry = (const struct DHTPutEntry *)data;
+
+  if (size != sizeof(struct DHTPutEntry) +
+              put_entry->data_size +
+              (put_entry->path_length * sizeof(struct GNUNET_PeerIdentity)))
+    {
+      GNUNET_log(
+          GNUNET_ERROR_TYPE_WARNING,
+          "Path + data size doesn't add up for data inserted into 
datacache!\nData size %d, path length %d, expected %d, got %d\n",
+          put_entry->data_size, put_entry->path_length,
+          sizeof(struct DHTPutEntry) + put_entry->data_size
+              + (put_entry->path_length * sizeof(struct GNUNET_PeerIdentity)),
+          size);
+      msg_ctx->do_forward = GNUNET_NO;
+      return GNUNET_OK;
+    }
+
   switch (eval)
     {
     case GNUNET_BLOCK_EVALUATION_OK_LAST:
@@ -2339,15 +2404,32 @@
           new_msg_ctx->path_history_len = msg_ctx->path_history_len;
           /* Assign to previous msg_ctx path history, caller should free after 
our return */
           new_msg_ctx->path_history = msg_ctx->path_history;
+#if DEBUG_PATH
+          for (i = 0; i < new_msg_ctx->path_history_len; i++)
+            {
+              path_offset = &new_msg_ctx->path_history[i * sizeof(struct 
GNUNET_PeerIdentity)];
+              GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "(get_iterator) Key %s Found 
peer %d:%s\n", GNUNET_h2s(&msg_ctx->key), i, GNUNET_i2s((struct 
GNUNET_PeerIdentity *)path_offset));
+            }
+#endif
         }
-      get_result =
-        GNUNET_malloc (sizeof (struct GNUNET_DHT_GetResultMessage) + size);
+
+      get_size = sizeof (struct GNUNET_DHT_GetResultMessage) + 
put_entry->data_size + (put_entry->path_length * sizeof(struct 
GNUNET_PeerIdentity));
+      get_result = GNUNET_malloc (get_size);
       get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_GET_RESULT);
-      get_result->header.size =
-        htons (sizeof (struct GNUNET_DHT_GetResultMessage) + size);
+      get_result->header.size = htons (get_size);
       get_result->expiration = GNUNET_TIME_absolute_hton (exp);
       get_result->type = htons (type);
-      memcpy (&get_result[1], data, size);
+      get_result->put_path_length = htons(put_entry->path_length);
+      path_offset = (char *)&put_entry[1];
+      path_offset += put_entry->data_size;
+#if DEBUG_PATH
+      for (i = 0; i < put_entry->path_length; i++)
+        {
+          GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "(get_iterator PUT path) Key %s 
Found peer %d:%s\n", GNUNET_h2s(&msg_ctx->key), i, GNUNET_i2s((struct 
GNUNET_PeerIdentity *)&path_offset[i * sizeof(struct GNUNET_PeerIdentity)]));
+        }
+#endif
+      /* Copy the actual data and the path_history to the end of the get 
result */
+      memcpy (&get_result[1], &put_entry[1], put_entry->data_size + 
(put_entry->path_length * sizeof(struct GNUNET_PeerIdentity)));
       new_msg_ctx->peer = &my_identity;
       new_msg_ctx->bloom =
         GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
@@ -2367,7 +2449,7 @@
       break;
     case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
 #if DEBUG_DHT
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                   "`%s:%s': Invalid request error\n", my_short_id, "DHT");
 #endif
       break;
@@ -2385,7 +2467,7 @@
       break;
     case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
 #if DEBUG_DHT
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                   "`%s:%s': Unsupported block type (%u) in response!\n",
                   my_short_id, "DHT", type);
 #endif
@@ -2781,6 +2863,9 @@
                 struct DHT_MessageContext *msg_ctx)
 {
   const struct GNUNET_DHT_PutMessage *put_msg;
+  struct DHTPutEntry *put_entry;
+  unsigned int put_size;
+  char *path_offset;
   enum GNUNET_BLOCK_Type put_type;
   size_t data_size;
   int ret;
@@ -2789,7 +2874,6 @@
 
   GNUNET_assert (ntohs (msg->size) >= sizeof (struct GNUNET_DHT_PutMessage));
 
-
   put_msg = (const struct GNUNET_DHT_PutMessage *) msg;
   put_type = (enum GNUNET_BLOCK_Type) ntohl (put_msg->type);
 #if HAVE_MALICIOUS
@@ -2897,8 +2981,22 @@
   increment_stats (STAT_PUTS_INSERTED);
   if (datacache != NULL)
     {
-      ret = GNUNET_DATACACHE_put (datacache, &msg_ctx->key, data_size,
-                                  (char *) &put_msg[1], put_type,
+      /* Put size is actual data size plus struct overhead plus path length 
(if any) */
+      put_size = data_size + sizeof(struct DHTPutEntry) + 
(msg_ctx->path_history_len * sizeof(struct GNUNET_PeerIdentity));
+      put_entry = GNUNET_malloc(put_size);
+      put_entry->data_size = data_size;
+      put_entry->path_length = msg_ctx->path_history_len;
+      /* Copy data to end of put entry */
+      memcpy(&put_entry[1], &put_msg[1], data_size);
+      if (msg_ctx->path_history_len > 0)
+        {
+          /* Copy path after data */
+          path_offset = (char *)&put_entry[1];
+          path_offset += data_size;
+          memcpy(path_offset, msg_ctx->path_history, msg_ctx->path_history_len 
* sizeof(struct GNUNET_PeerIdentity));
+        }
+      ret = GNUNET_DATACACHE_put (datacache, &msg_ctx->key, put_size,
+                                  (char *) put_entry, put_type,
                                   GNUNET_TIME_absolute_ntoh
                                   (put_msg->expiration));
 
@@ -4776,7 +4874,7 @@
   msg_ctx->msg_options = ntohl (incoming->options);
   if (GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx->msg_options & 
GNUNET_DHT_RO_RECORD_ROUTE))
     {
-      path_size = ntohl(incoming->route_path_length) * sizeof(struct 
GNUNET_PeerIdentity);
+      path_size = ntohl(incoming->outgoing_path_length) * sizeof(struct 
GNUNET_PeerIdentity);
       GNUNET_assert(ntohs(message->size) ==
                     (sizeof(struct GNUNET_DHT_P2PRouteMessage) +
                      ntohs(enc_msg->size) +
@@ -4786,7 +4884,7 @@
       msg_ctx->path_history = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity) 
+ path_size);
       memcpy(msg_ctx->path_history, route_path, path_size);
       memcpy(&msg_ctx->path_history[path_size], &my_identity, sizeof(struct 
GNUNET_PeerIdentity));
-      msg_ctx->path_history_len = ntohl(incoming->route_path_length) + 1;
+      msg_ctx->path_history_len = ntohl(incoming->outgoing_path_length) + 1;
     }
   msg_ctx->network_size = ntohl (incoming->network_size);
   msg_ctx->peer = peer;
@@ -4829,7 +4927,10 @@
   struct GNUNET_MessageHeader *enc_msg =
     (struct GNUNET_MessageHeader *) &incoming[1];
   struct DHT_MessageContext msg_ctx;
-
+#if DEBUG_PATH
+  char *path_offset;
+  unsigned int i;
+#endif
   if (ntohs (enc_msg->size) >= GNUNET_SERVER_MAX_MESSAGE_SIZE - 1)
     {
       GNUNET_break_op (0);
@@ -4871,16 +4972,22 @@
       if (ntohs(message->size) - sizeof(struct 
GNUNET_DHT_P2PRouteResultMessage) - ntohs(enc_msg->size) !=
           ntohl (incoming->outgoing_path_length) * sizeof(struct 
GNUNET_PeerIdentity))
         {
-          GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Return message indicated a 
path was included, but sizes are wrong!\nTotal message size %d, enc_msg size 
%d, left over %d, expected %d\n",
+          GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Return message indicated a path 
was included, but sizes are wrong!\nTotal message size %d, enc_msg size %d, 
left over %d, expected %d\n",
                                                  ntohs(message->size), 
ntohs(enc_msg->size),
                                                  ntohs(message->size) - 
sizeof(struct GNUNET_DHT_P2PRouteResultMessage) - ntohs(enc_msg->size),
                                                  
ntohl(incoming->outgoing_path_length) * sizeof(struct GNUNET_PeerIdentity));
           return GNUNET_NO;
         }
-
       msg_ctx.path_history = (char *)&incoming[1];
       msg_ctx.path_history += ntohs(enc_msg->size);
       msg_ctx.path_history_len = ntohl (incoming->outgoing_path_length);
+#if DEBUG_PATH
+      for (i = 0; i < msg_ctx.path_history_len; i++)
+        {
+          path_offset = &msg_ctx.path_history[i * sizeof(struct 
GNUNET_PeerIdentity)];
+          GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "(handle_p2p_route_result) Key 
%s Found peer %d:%s\n", GNUNET_h2s(&msg_ctx.key), i, GNUNET_i2s((struct 
GNUNET_PeerIdentity *)path_offset));
+        }
+#endif
     }
   route_result_message (enc_msg, &msg_ctx);
   return GNUNET_YES;
@@ -5057,7 +5164,7 @@
                      const struct GNUNET_TRANSPORT_ATS_Information *atsi)
 {
   struct PeerInfo *ret;
-
+  struct DHTPutEntry *put_entry;
   /* Check for connect to self message */
   if (0 == memcmp(&my_identity, peer, sizeof(struct GNUNET_PeerIdentity)))
     return;
@@ -5079,10 +5186,18 @@
     }
 
   if (datacache != NULL)
-    GNUNET_DATACACHE_put (datacache, &peer->hashPubKey,
-                          sizeof (struct GNUNET_PeerIdentity),
-                          (const char *) peer, GNUNET_BLOCK_TYPE_DHT_HELLO,
-                          GNUNET_TIME_absolute_get_forever ());
+    {
+      put_entry = GNUNET_malloc(sizeof(struct DHTPutEntry) + sizeof (struct 
GNUNET_PeerIdentity));
+      put_entry->path_length = 0;
+      put_entry->data_size = sizeof (struct GNUNET_PeerIdentity);
+      memcpy(&put_entry[1], peer, sizeof (struct GNUNET_PeerIdentity));
+      GNUNET_DATACACHE_put (datacache, &peer->hashPubKey,
+                            sizeof(struct DHTPutEntry) + sizeof (struct 
GNUNET_PeerIdentity),
+                            (char *)put_entry, GNUNET_BLOCK_TYPE_DHT_HELLO,
+                            GNUNET_TIME_absolute_get_forever ());
+    }
+  else
+    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "DHT has no connection to 
datacache!\n");
   ret = try_add_peer (peer, find_current_bucket (&peer->hashPubKey), atsi);
   if (ret != NULL)
     {

Modified: gnunet/src/dht/test_dht_api_data.conf
===================================================================
--- gnunet/src/dht/test_dht_api_data.conf       2011-02-02 09:04:42 UTC (rev 
14307)
+++ gnunet/src/dht/test_dht_api_data.conf       2011-02-02 11:54:21 UTC (rev 
14308)
@@ -5,6 +5,9 @@
 [fs]
 AUTOSTART = NO
 
+[resolver]
+AUTOSTART = NO
+
 [datastore-sqlite]
 FILENAME = $SERVICEHOME/datastore/sqlite.db
 

Modified: gnunet/src/dht/test_dht_api_peer1.conf
===================================================================
--- gnunet/src/dht/test_dht_api_peer1.conf      2011-02-02 09:04:42 UTC (rev 
14307)
+++ gnunet/src/dht/test_dht_api_peer1.conf      2011-02-02 11:54:21 UTC (rev 
14308)
@@ -1,6 +1,9 @@
 [fs]
 AUTOSTART = NO
 
+[resolver]
+AUTOSTART = NO
+
 [dht]
 DEBUG = NO
 AUTOSTART = YES

Modified: gnunet/src/dht/test_dht_multipeer.c
===================================================================
--- gnunet/src/dht/test_dht_multipeer.c 2011-02-02 09:04:42 UTC (rev 14307)
+++ gnunet/src/dht/test_dht_multipeer.c 2011-02-02 11:54:21 UTC (rev 14308)
@@ -53,6 +53,8 @@
 
 #define MAX_OUTSTANDING_GETS 10
 
+#define PATH_TRACKING GNUNET_YES
+
 /* Structs */
 
 struct TestPutContext
@@ -206,6 +208,8 @@
  */
 static unsigned int failed_connections;
 
+enum GNUNET_DHT_RouteOption route_option;
+
 /* Task handle to use to schedule test failure */
 GNUNET_SCHEDULER_TaskIdentifier die_task;
 
@@ -224,7 +228,6 @@
 /* Global return value (0 for success, anything else for failure) */
 static int ok;
 
-
 /**
  * Check whether peers successfully shut down.
  */
@@ -395,13 +398,30 @@
   struct TestGetContext *test_get = cls;
   GNUNET_HashCode search_key; /* Key stored under */
   char original_data[TEST_DATA_SIZE]; /* Made up data to store */
-
+  unsigned int i;
   memset(original_data, test_get->uid, sizeof(original_data));
   GNUNET_CRYPTO_hash(original_data, TEST_DATA_SIZE, &search_key);
 
   if (test_get->succeeded == GNUNET_YES)
     return; /* Get has already been successful, probably ending now */
 
+#if PATH_TRACKING
+  if (put_path != NULL)
+    {
+      fprintf(stderr, "PUT Path: ");
+      for (i = 0; put_path[i] != NULL; i++)
+        fprintf(stderr, "%s%s", i == 0 ? "" : "->", GNUNET_i2s(put_path[i]));
+      fprintf(stderr, "\n");
+    }
+  if (get_path != NULL)
+    {
+      fprintf(stderr, "GET Path: ");
+      for (i = 0; get_path[i] != NULL; i++)
+        fprintf(stderr, "%s%s", i == 0 ? "" : "->", GNUNET_i2s(get_path[i]));
+      fprintf(stderr, "\n");
+    }
+#endif
+
   if ((0 != memcmp(&search_key, key, sizeof (GNUNET_HashCode))) || (0 != 
memcmp(original_data, data, sizeof(original_data))))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Key or data is not the same as was 
inserted!\n");
@@ -448,7 +468,7 @@
                                               GNUNET_BLOCK_TYPE_TEST,
                                               &key,
                                               DEFAULT_GET_REPLICATION,
-                                             GNUNET_DHT_RO_NONE,
+                                              route_option,
                                              NULL, 0,
                                              NULL, 0,
                                               &get_result_iterator,
@@ -517,7 +537,7 @@
   GNUNET_DHT_put(test_put->dht_handle,
                  &key,
                  DEFAULT_PUT_REPLICATION,
-                GNUNET_DHT_RO_NONE,
+                route_option,
                  GNUNET_BLOCK_TYPE_TEST,
                  sizeof(data), data,
                  GNUNET_TIME_UNIT_FOREVER_ABS,
@@ -758,6 +778,12 @@
   char * connect_topology_option_str;
   char * connect_topology_option_modifier_string;
 
+#if PATH_TRACKING
+  route_option = GNUNET_DHT_RO_RECORD_ROUTE;
+#else
+  route_option = GNUNET_DHT_RO_NONE;
+#endif
+
   /* Get path from configuration file */
   if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_string(cfg, "paths", 
"servicehome", &test_directory))
     {

Modified: gnunet/src/dht/test_dht_multipeer_data.conf
===================================================================
--- gnunet/src/dht/test_dht_multipeer_data.conf 2011-02-02 09:04:42 UTC (rev 
14307)
+++ gnunet/src/dht/test_dht_multipeer_data.conf 2011-02-02 11:54:21 UTC (rev 
14308)
@@ -1,19 +1,27 @@
 [fs]
 AUTOSTART = NO
 
+[resolver]
+AUTOSTART = NO
+
 [dht]
 DEBUG = NO
-STOP_ON_CLOSEST = NO
+STOP_ON_CLOSEST = YES
 AUTOSTART = YES
 ACCEPT_FROM6 = ::1;
 ACCEPT_FROM = 127.0.0.1;
-BINARY = gnunet-service-dht
+#BINARY = 
/home/mrwiggles/documents/research/gnunet/gnunet-ng/src/dht/.libs/gnunet-service-dht
 #PREFIX = xterm -T dht -e gdb --args
 #PREFIX = valgrind --log-file=dht_%p
 CONFIG = $DEFAULTCONFIG
 HOME = $SERVICEHOME
 HOSTNAME = localhost
 PORT = 2100
+STOP_FOUND = YES
+USE_MAX_HOPS = YES
+MAX_HOPS = 16
+CONVERGE_BINARY = YES
+CONVERGE_MODIFIER = 4
 
 [block]
 plugins = test dht
@@ -65,9 +73,10 @@
 PORT = 12368
 
 [DHT_TESTING]
-MYSQL_LOGGING_EXTENDED = YES
-NUM_GETS = 10
-NUM_PUTS = 50
+MYSQL_LOGGING_EXTENDED = NO
+MYSQL_LOGGING = NO
+NUM_GETS = 1
+NUM_PUTS = 1
 
 [TESTING]
 TOPOLOGY = CLIQUE
@@ -77,7 +86,7 @@
 #LOGNMODIFIER = .65
 #PERCENTAGE = .75
 WEAKRANDOM = YES
-NUM_PEERS = 15
+NUM_PEERS = 5
 
 [gnunetd]
 HOSTKEY = $SERVICEHOME/.hostkey

Modified: gnunet/src/dht/test_dht_twopeer.c
===================================================================
--- gnunet/src/dht/test_dht_twopeer.c   2011-02-02 09:04:42 UTC (rev 14307)
+++ gnunet/src/dht/test_dht_twopeer.c   2011-02-02 11:54:21 UTC (rev 14308)
@@ -220,7 +220,8 @@
                                                          &stop_retry_get, 
get_context);
   get_context->get_handle = GNUNET_DHT_get_start(get_context->dht_handle,
                                                 
GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5),
-                                                 0 /* FIXME: use real type */, 
&get_context->peer->hashPubKey,
+                                                GNUNET_BLOCK_TYPE_DHT_HELLO,
+                                                &get_context->peer->hashPubKey,
                                                  DEFAULT_GET_REPLICATION,
                                                 GNUNET_DHT_RO_NONE,
                                                 NULL, 0,
@@ -303,7 +304,6 @@
 
       curr_get_ctx.dht_handle = peer1dht;
       curr_get_ctx.peer = &peer2id;
-      //GNUNET_SCHEDULER_add_now (&do_get, &curr_get_ctx);
       GNUNET_SCHEDULER_add_delayed 
(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 2), &do_get, 
&curr_get_ctx);
     }
   else if (total_connections + failed_connections == expected_connections)

Modified: gnunet/src/dht/test_dht_twopeer_data.conf
===================================================================
--- gnunet/src/dht/test_dht_twopeer_data.conf   2011-02-02 09:04:42 UTC (rev 
14307)
+++ gnunet/src/dht/test_dht_twopeer_data.conf   2011-02-02 11:54:21 UTC (rev 
14308)
@@ -1,6 +1,9 @@
 [fs]
 AUTOSTART = NO
 
+[resolver]
+AUTOSTART = YES
+
 [dht]
 DEBUG = NO
 AUTOSTART = YES

Added: gnunet/src/dht/test_dht_twopeer_path_tracking.c
===================================================================
--- gnunet/src/dht/test_dht_twopeer_path_tracking.c                             
(rev 0)
+++ gnunet/src/dht/test_dht_twopeer_path_tracking.c     2011-02-02 11:54:21 UTC 
(rev 14308)
@@ -0,0 +1,513 @@
+/*
+     This file is part of GNUnet.
+     (C) 2009 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file dht/test_dht_twopeer_path_tracking.c
+ * @brief testcase for testing DHT service with
+ *        two running peers, logging the path of the dht requests.
+ */
+#include "platform.h"
+#include "gnunet_testing_lib.h"
+#include "gnunet_core_service.h"
+#include "gnunet_dht_service.h"
+
+/* DEFINES */
+#define VERBOSE GNUNET_NO
+
+/* Timeout for entire testcase */
+#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5)
+
+/* Timeout for waiting for replies to get requests */
+#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)
+
+/* If number of peers not in config file, use this number */
+#define DEFAULT_NUM_PEERS 2
+
+/* Globals */
+
+/**
+ * Directory to store temp data in, defined in config file
+ */
+static char *test_directory;
+
+/**
+ * Variable used to store the number of connections we should wait for.
+ */
+static unsigned int expected_connections;
+
+/**
+ * Variable used to keep track of how many peers aren't yet started.
+ */
+static unsigned long long peers_left;
+
+/**
+ * Handle to the set of all peers run for this test.
+ */
+static struct GNUNET_TESTING_PeerGroup *pg;
+
+/**
+ * Global handle we will use for GET requests.
+ */
+struct GNUNET_DHT_GetHandle *global_get_handle;
+
+
+/**
+ * Total number of peers to run, set based on config file.
+ */
+static unsigned long long num_peers;
+
+/**
+ * Global used to count how many connections we have currently
+ * been notified about (how many times has topology_callback been called
+ * with success?)
+ */
+static unsigned int total_connections;
+
+/**
+ * Global used to count how many failed connections we have
+ * been notified about (how many times has topology_callback
+ * been called with failure?)
+ */
+static unsigned int failed_connections;
+
+/* Task handle to use to schedule test failure */
+GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+/* Global return value (0 for success, anything else for failure) */
+static int ok;
+
+/**
+ * Peer identity of the first peer started.
+ */
+static struct GNUNET_PeerIdentity peer1id;
+
+/**
+ * Peer identity of the second peer started.
+ */
+static struct GNUNET_PeerIdentity peer2id;
+
+/**
+ * Handle to the first peers DHT service (via the API)
+ */
+static struct GNUNET_DHT_Handle *peer1dht;
+
+/**
+ * Handle to the second peers DHT service (via the API)
+ */
+static struct GNUNET_DHT_Handle *peer2dht;
+
+/**
+ * Check whether peers successfully shut down.
+ */
+void shutdown_callback (void *cls,
+                        const char *emsg)
+{
+  if (emsg != NULL)
+    {
+      if (ok == 0)
+        ok = 2;
+    }
+}
+
+/**
+ * Function scheduled to be run on the successful completion of this
+ * testcase.  Specifically, called when our get request completes.
+ */
+static void
+finish_testing (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+  GNUNET_assert (pg != NULL);
+  GNUNET_assert (peer1dht != NULL);
+  GNUNET_assert (peer2dht != NULL);
+  GNUNET_DHT_disconnect(peer1dht);
+  GNUNET_DHT_disconnect(peer2dht);
+  GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
+  ok = 0;
+}
+
+/**
+ * Continuation for the GNUNET_DHT_get_stop call, so that we don't shut
+ * down the peers without freeing memory associated with GET request.
+ */
+static void
+end_badly_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+  if (peer1dht != NULL)
+      GNUNET_DHT_disconnect(peer1dht);
+
+  if (peer2dht != NULL)
+    GNUNET_DHT_disconnect(peer2dht);
+
+  if (pg != NULL)
+    GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
+}
+
+/**
+ * Check if the get_handle is being used, if so stop the request.  Either
+ * way, schedule the end_badly_cont function which actually shuts down the
+ * test.
+ */
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failing test with error: `%s'!\n", 
(char *)cls);
+  if (global_get_handle != NULL)
+    {
+      GNUNET_DHT_get_stop(global_get_handle);
+      global_get_handle = NULL;
+    }
+  GNUNET_SCHEDULER_add_now(&end_badly_cont, NULL);
+  ok = 1;
+}
+
+/**
+ * Iterator called if the GET request initiated returns a response.
+ *
+ * @param cls closure
+ * @param exp when will this value expire
+ * @param key key of the result
+ * @param type type of the result
+ * @param size number of bytes in data
+ * @param data pointer to the result data
+ */
+void get_result_iterator (void *cls,
+                          struct GNUNET_TIME_Absolute exp,
+                          const GNUNET_HashCode * key,
+                         const struct GNUNET_PeerIdentity * const *get_path,
+                         const struct GNUNET_PeerIdentity * const *put_path,
+                         enum GNUNET_BLOCK_Type type,
+                          size_t size,
+                          const void *data)
+{
+  GNUNET_HashCode original_key; /* Key data was stored data under */
+  char original_data[4]; /* Made up data that was stored */
+  memset(&original_key, 42, sizeof(GNUNET_HashCode)); /* Set the key to what 
it was set to previously */
+  memset(original_data, 43, sizeof(original_data));
+#if VERBOSE
+  unsigned int i;
+#endif
+
+  if ((0 != memcmp(&original_key, key, sizeof (GNUNET_HashCode))) || (0 != 
memcmp(original_data, data, sizeof(original_data))))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Key or data is not the same as was 
inserted!\n");
+    GNUNET_SCHEDULER_cancel(die_task);
+    GNUNET_SCHEDULER_add_now(&end_badly, "key or data mismatch in get 
response!\n");
+    return;
+  }
+
+#if VERBOSE
+  if (put_path != NULL)
+    {
+      fprintf(stderr, "PUT Path: ");
+      for (i = 0; put_path[i] != NULL; i++)
+        fprintf(stderr, "%s%s", i == 0 ? "" : "->", GNUNET_i2s(put_path[i]));
+      fprintf(stderr, "\n");
+    }
+  if (get_path != NULL)
+    {
+      fprintf(stderr, "GET Path: ");
+      for (i = 0; get_path[i] != NULL; i++)
+        fprintf(stderr, "%s%s", i == 0 ? "" : "->", GNUNET_i2s(get_path[i]));
+      fprintf(stderr, "\n");
+    }
+#endif
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received correct GET response!\n");
+  GNUNET_SCHEDULER_cancel(die_task);
+  GNUNET_DHT_get_stop(global_get_handle);
+  GNUNET_SCHEDULER_add_now (&finish_testing, NULL);
+}
+
+/**
+ * Start the GET request for the same key/data that was inserted.
+ */
+static void
+do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+  GNUNET_HashCode key; /* Key for data lookup */
+  memset(&key, 42, sizeof(GNUNET_HashCode)); /* Set the key to the same thing 
as when data was inserted */
+  global_get_handle = GNUNET_DHT_get_start(peer2dht, 
GNUNET_TIME_relative_get_forever(),
+                                          GNUNET_BLOCK_TYPE_TEST,
+                                          &key,
+                                          DEFAULT_GET_REPLICATION,
+                                          GNUNET_DHT_RO_RECORD_ROUTE,
+                                          NULL, 0,
+                                          NULL, 0,
+                                          &get_result_iterator, NULL);
+}
+
+/**
+ * Called when the PUT request has been transmitted to the DHT service.
+ * Schedule the GET request for some time in the future.
+ */
+static void
+put_finished (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+  GNUNET_SCHEDULER_cancel (die_task);
+  die_task = GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT,
+                                           &end_badly, "waiting for get 
response (data not found)");
+  
GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,
 10), &do_get, NULL);
+}
+
+/**
+ * Set up some data, and call API PUT function
+ */
+static void
+do_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+  GNUNET_HashCode key; /* Made up key to store data under */
+  char data[4]; /* Made up data to store */
+  memset(&key, 42, sizeof(GNUNET_HashCode)); /* Set the key to something 
simple so we can issue GET request */
+  memset(data, 43, sizeof(data));
+
+  /* Insert the data at the first peer */
+  GNUNET_DHT_put(peer1dht,
+                 &key,
+                 DEFAULT_PUT_REPLICATION,
+                GNUNET_DHT_RO_RECORD_ROUTE,
+                 GNUNET_BLOCK_TYPE_TEST,
+                 sizeof(data), data,
+                 GNUNET_TIME_UNIT_FOREVER_ABS,
+                 GNUNET_TIME_UNIT_FOREVER_REL,
+                 &put_finished, NULL);
+}
+
+/**
+ * This function is called whenever a connection attempt is finished between 
two of
+ * the started peers (started with GNUNET_TESTING_daemons_start).  The total
+ * number of times this function is called should equal the number returned
+ * from the GNUNET_TESTING_connect_topology call.
+ *
+ * The emsg variable is NULL on success (peers connected), and non-NULL on
+ * failure (peers failed to connect).
+ */
+void
+topology_callback (void *cls,
+                   const struct GNUNET_PeerIdentity *first,
+                   const struct GNUNET_PeerIdentity *second,
+                   uint32_t distance,
+                   const struct GNUNET_CONFIGURATION_Handle *first_cfg,
+                   const struct GNUNET_CONFIGURATION_Handle *second_cfg,
+                   struct GNUNET_TESTING_Daemon *first_daemon,
+                   struct GNUNET_TESTING_Daemon *second_daemon,
+                   const char *emsg)
+{
+  if (emsg == NULL)
+    {
+      total_connections++;
+#if VERBOSE
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connected peer %s to peer %s, 
distance %u\n",
+                 first_daemon->shortname,
+                 second_daemon->shortname,
+                 distance);
+#endif
+    }
+#if VERBOSE
+  else
+    {
+      failed_connections++;
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to connect peer %s to peer 
%s with error :\n%s\n",
+                  first_daemon->shortname,
+                  second_daemon->shortname, emsg);
+    }
+#endif
+
+  if (total_connections == expected_connections)
+    {
+#if VERBOSE
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Created %d total connections, which is our target number!  
Starting next phase of testing.\n",
+                  total_connections);
+#endif
+      GNUNET_SCHEDULER_cancel (die_task);
+      die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
+                                               &end_badly, "from test gets");
+
+      GNUNET_SCHEDULER_add_delayed 
(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 2), &do_put, NULL);
+    }
+  else if (total_connections + failed_connections == expected_connections)
+    {
+      GNUNET_SCHEDULER_cancel (die_task);
+      die_task = GNUNET_SCHEDULER_add_now (&end_badly, "from topology_callback 
(too many failed connections)");
+    }
+}
+
+
+/**
+ * Callback which is called whenever a peer is started (as a result of the
+ * GNUNET_TESTING_daemons_start call.
+ *
+ * @param cls closure argument given to GNUNET_TESTING_daemons_start
+ * @param id the GNUNET_PeerIdentity of the started peer
+ * @param cfg the configuration for this specific peer (needed to connect
+ *            to the DHT)
+ * @param d the handle to the daemon started
+ * @param emsg NULL if peer started, non-NULL on error
+ */
+static void
+peers_started_callback (void *cls,
+       const struct GNUNET_PeerIdentity *id,
+       const struct GNUNET_CONFIGURATION_Handle *cfg,
+       struct GNUNET_TESTING_Daemon *d, const char *emsg)
+{
+  if (emsg != NULL)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to start daemon with 
error: `%s'\n",
+                  emsg);
+      return;
+    }
+  GNUNET_assert (id != NULL);
+
+  /* This is the first peer started */
+  if (peers_left == num_peers)
+  {
+    memcpy(&peer1id, id, sizeof(struct GNUNET_PeerIdentity)); /* Save the peer 
id */
+    peer1dht = GNUNET_DHT_connect(cfg, 100); /* Connect to the first peers DHT 
service */
+    if (peer1dht == NULL) /* If DHT connect failed */
+    {
+      GNUNET_SCHEDULER_cancel (die_task);
+      GNUNET_SCHEDULER_add_now(&end_badly, "Failed to get dht handle!\n");
+    }
+  }
+  else /* This is the second peer started */
+  {
+    memcpy(&peer2id, id, sizeof(struct GNUNET_PeerIdentity)); /* Same as for 
first peer... */
+    peer2dht = GNUNET_DHT_connect(cfg, 100);
+    if (peer2dht == NULL)
+    {
+      GNUNET_SCHEDULER_cancel (die_task);
+      GNUNET_SCHEDULER_add_now(&end_badly, "Failed to get dht handle!\n");
+    }
+  }
+
+  /* Decrement number of peers left to start */
+  peers_left--;
+
+  if (peers_left == 0) /* Indicates all peers started */
+    {
+#if VERBOSE
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "All %d daemons started, now connecting peers!\n",
+                  num_peers);
+#endif
+      expected_connections = -1;
+      if ((pg != NULL)) /* Sanity check */
+        {
+          /* Connect peers in a "straight line" topology, return the number of 
expected connections */
+          expected_connections = GNUNET_TESTING_connect_topology (pg, 
GNUNET_TESTING_TOPOLOGY_LINE, GNUNET_TESTING_TOPOLOGY_OPTION_ALL, 0.0, NULL, 
NULL);
+        }
+
+      /* Cancel current timeout fail task */
+      GNUNET_SCHEDULER_cancel (die_task);
+      if (expected_connections == GNUNET_SYSERR) /* Some error happened */
+        die_task = GNUNET_SCHEDULER_add_now (&end_badly, "from connect 
topology (bad return)");
+
+      /* Schedule timeout on failure task */
+      die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
+                                               &end_badly, "from connect 
topology (timeout)");
+      ok = 0;
+    }
+}
+
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+
+  /* Get path from configuration file */
+  if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_string(cfg, "paths", 
"servicehome", &test_directory))
+    {
+      ok = 404;
+      return;
+    }
+
+  /* Get number of peers to start from configuration (should be two) */
+  if (GNUNET_SYSERR ==
+      GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers",
+                                             &num_peers))
+    num_peers = DEFAULT_NUM_PEERS;
+
+  /* Set peers_left so we know when all peers started */
+  peers_left = num_peers;
+
+  /* Set up a task to end testing if peer start fails */
+  die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
+                                           &end_badly, "didn't start all 
daemons in reasonable amount of time!!!");
+
+  /* Start num_peers peers, call peers_started_callback on peer start, 
topology_callback on peer connect */
+  /* Read the API documentation for other parameters! */
+  pg = GNUNET_TESTING_daemons_start (cfg,
+                                     num_peers, TIMEOUT, NULL, NULL, 
&peers_started_callback, NULL,
+                                     &topology_callback, NULL, NULL);
+
+}
+
+static int
+check ()
+{
+  int ret;
+  /* Arguments for GNUNET_PROGRAM_run */
+  char *const argv[] = {"test-dht-twopeer-put-get", /* Name to give running 
binary */
+    "-c",
+    "test_dht_twopeer_data.conf", /* Config file to use */
+#if VERBOSE
+    "-L", "DEBUG",
+#endif
+    NULL
+  };
+  struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_OPTION_END
+  };
+  /* Run the run function as a new program */
+  ret = GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
+                      argv, "test-dht-twopeer-put-get", "nohelp",
+                      options, &run, &ok);
+  if (ret != GNUNET_OK)
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "`test-dht-twopeer': Failed with 
error code %d\n", ret);
+    }
+  return ok;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int ret;
+
+  GNUNET_log_setup ("test-dht-twopeer",
+#if VERBOSE
+                    "DEBUG",
+#else
+                    "WARNING",
+#endif
+                    NULL);
+  ret = check ();
+  /**
+   * Need to remove base directory, subdirectories taken care
+   * of by the testing framework.
+   */
+  if (GNUNET_DISK_directory_remove (test_directory) != GNUNET_OK)
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Failed to remove testing 
directory %s\n", test_directory);
+    }
+  return ret;
+}
+
+/* end of test_dht_twopeer_put_get.c */

Modified: gnunet/src/dht/test_dhtlog.c
===================================================================
--- gnunet/src/dht/test_dhtlog.c        2011-02-02 09:04:42 UTC (rev 14307)
+++ gnunet/src/dht/test_dhtlog.c        2011-02-02 11:54:21 UTC (rev 14308)
@@ -28,7 +28,7 @@
 #include "gnunet_protocols.h"
 #include "dhtlog.h"
 
-#define VERBOSE GNUNET_YES
+#define VERBOSE GNUNET_NO
 
 static int ok;
 

Modified: gnunet/src/dht/test_dhtlog_data.conf
===================================================================
--- gnunet/src/dht/test_dhtlog_data.conf        2011-02-02 09:04:42 UTC (rev 
14307)
+++ gnunet/src/dht/test_dhtlog_data.conf        2011-02-02 11:54:21 UTC (rev 
14308)
@@ -36,7 +36,7 @@
 SERVICEHOME = /tmp/test-dhtlog/
 
 [DHTLOG]
-#PLUGIN = mysql_dump
+#PLUGIN = mysql_dump_load
 PLUGIN = dummy
 #PLUGIN = mysql
 




reply via email to

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