add find peer to api, went a bit continuation crazy but i think it's better this...
authorNathan S. Evans <evans@in.tum.de>
Sun, 4 Apr 2010 11:34:11 +0000 (11:34 +0000)
committerNathan S. Evans <evans@in.tum.de>
Sun, 4 Apr 2010 11:34:11 +0000 (11:34 +0000)
src/dht/dht.h
src/dht/dht_api.c
src/dht/gnunet-service-dht.c
src/dht/test_dht_api.c
src/dht/test_dht_api_peer1.conf

index 0cfd9b3bfb2a30038aebc6a64537d494b5370403..68591a97edd101cb4184b41c4028915999dfd309 100644 (file)
@@ -27,7 +27,7 @@
 #ifndef DHT_H_
 #define DHT_H_
 
-#define DEBUG_DHT GNUNET_YES
+#define DEBUG_DHT GNUNET_NO
 
 typedef void (*GNUNET_DHT_MessageReceivedHandler) (void *cls,
                                                   struct GNUNET_MessageHeader *msg);
@@ -166,7 +166,7 @@ struct GNUNET_DHT_GetResultMessage
 };
 
 /**
- * Message to request data from the DHT
+ * Message to issue find peer request to the DHT
  */
 struct GNUNET_DHT_FindPeerMessage
 {
@@ -175,6 +175,13 @@ struct GNUNET_DHT_FindPeerMessage
    */
   struct GNUNET_MessageHeader header;
 
+  /**
+   * Size of inject message (may be zero)
+   */
+  size_t msg_len;
+
+  /* Followed by message to inject at found peers */
+
 };
 
 /**
@@ -188,14 +195,15 @@ struct GNUNET_DHT_FindPeerResultMessage
   struct GNUNET_MessageHeader header;
 
   /**
-   * The peer that was searched for
+   * The peer that was found
    */
   struct GNUNET_PeerIdentity peer;
 
   /**
-   * The size of the HELLO for the returned peer,
+   * The size of the return message from the peer
+   * (defaults to HELLO for the peer),
    * appended to the end of this message, 0 if
-   * no hello.
+   * no message.
    */
   size_t data_size;
 
index 9fb77d5d4fab0c014e0314a24d34288949df1f9c..f935d69d324f703f6e81ec669e9f93aacdb03757 100644 (file)
  * @author Christian Grothoff
  * @author Nathan Evans
  *
- * TODO: Only allow a single message until confirmed as received by
- *       the service.  For put messages call continuation as soon as
- *       receipt acknowledged (then remove), for GET or other messages
- *       only call continuation when data received.
- *       Add unique identifier to message types requesting data to be
- *       returned.
  */
+
 #include "platform.h"
 #include "gnunet_bandwidth_lib.h"
 #include "gnunet_client_lib.h"
@@ -44,7 +39,7 @@
 #include "gnunet_dht_service.h"
 #include "dht.h"
 
-#define DEBUG_DHT_API GNUNET_YES
+#define DEBUG_DHT_API GNUNET_NO
 
 #define DEFAULT_DHT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
 
@@ -86,8 +81,6 @@ struct PendingMessage
 
 struct GNUNET_DHT_GetContext
 {
-
-
   /**
    * Iterator to call on data receipt
    */
@@ -100,6 +93,20 @@ struct GNUNET_DHT_GetContext
 
 };
 
+struct GNUNET_DHT_FindPeerContext
+{
+  /**
+   * Iterator to call on data receipt
+   */
+  GNUNET_DHT_FindPeerProcessor proc;
+
+  /**
+   * Closure for the iterator callback
+   */
+  void *proc_cls;
+
+};
+
 /**
  * Handle to control a unique operation (one that is
  * expected to return results)
@@ -162,6 +169,38 @@ struct GNUNET_DHT_NonUniqueHandle
   void *cont_cls;
 };
 
+/**
+ * Handle to control a get operation.
+ */
+struct GNUNET_DHT_GetHandle
+{
+  /**
+   * Handle to the actual route operation for the get
+   */
+  struct GNUNET_DHT_RouteHandle *route_handle;
+
+  /**
+   * The context of the get request
+   */
+  struct GNUNET_DHT_GetContext get_context;
+};
+
+/**
+ * Handle to control a find peer operation.
+ */
+struct GNUNET_DHT_FindPeerHandle
+{
+  /**
+     * Handle to the actual route operation for the request
+     */
+    struct GNUNET_DHT_RouteHandle *route_handle;
+
+    /**
+     * The context of the get request
+     */
+    struct GNUNET_DHT_FindPeerContext find_peer_context;
+};
+
 
 /**
  * Connection to the DHT service.
@@ -565,6 +604,17 @@ void get_reply_iterator (void *cls,
 
 }
 
+
+/**
+ * Iterator called on each result obtained from a generic route
+ * operation
+ */
+void find_peer_reply_iterator (void *cls,
+                               const struct GNUNET_MessageHeader *reply)
+{
+
+}
+
 /**
  * Perform an asynchronous FIND_PEER operation on the DHT.
  *
@@ -674,8 +724,7 @@ GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle,
 }
 
 void
-GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *fph);
-
+GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle, GNUNET_SCHEDULER_Task cont, void *cont_cls);
 
 /**
  * Perform an asynchronous GET operation on the DHT identified.
@@ -691,7 +740,7 @@ GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *fph);
  *
  * @return handle to stop the async get
  */
-struct GNUNET_DHT_RouteHandle *
+struct GNUNET_DHT_GetHandle *
 GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle,
                       struct GNUNET_TIME_Relative timeout,
                       uint32_t type,
@@ -701,15 +750,15 @@ GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle,
                       GNUNET_SCHEDULER_Task cont,
                       void *cont_cls)
 {
-  struct GNUNET_DHT_GetContext *get_context;
+  struct GNUNET_DHT_GetHandle *get_handle;
   struct GNUNET_DHT_GetMessage *get_msg;
 
   if (handle->current != NULL) /* Can't send right now, we have a pending message... */
     return NULL;
 
-  get_context = GNUNET_malloc(sizeof(struct GNUNET_DHT_GetContext));
-  get_context->iter = iter;
-  get_context->iter_cls = iter_cls;
+  get_handle = GNUNET_malloc(sizeof(struct GNUNET_DHT_GetHandle));
+  get_handle->get_context.iter = iter;
+  get_handle->get_context.iter_cls = iter_cls;
 
 #if DEBUG_DHT_API
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -721,13 +770,13 @@ GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle,
   get_msg->header.size = htons(sizeof(struct GNUNET_DHT_GetMessage));
   get_msg->type = htonl(type);
 
-  return GNUNET_DHT_route_start(handle, key, 0, 0, &get_msg->header, timeout, &get_reply_iterator, get_context, cont, cont_cls);
-
+  get_handle->route_handle = GNUNET_DHT_route_start(handle, key, 0, 0, &get_msg->header, timeout, &get_reply_iterator, get_handle, cont, cont_cls);
+  return get_handle;
 }
 
 
 void
-GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle)
+GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle, GNUNET_SCHEDULER_Task cont, void *cont_cls)
 {
   struct PendingMessage *pending;
   struct GNUNET_DHT_StopMessage *message;
@@ -750,8 +799,8 @@ GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle)
   pending = GNUNET_malloc(sizeof(struct PendingMessage));
   pending->msg = (struct GNUNET_MessageHeader *)message;
   pending->timeout = DEFAULT_DHT_TIMEOUT;
-  pending->cont = NULL;
-  pending->cont_cls = NULL;
+  pending->cont = cont;
+  pending->cont_cls = cont_cls;
   pending->is_unique = GNUNET_NO;
   pending->unique_id = route_handle->uid;
 
@@ -781,33 +830,95 @@ GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle)
  * @param get_handle handle to the GET operation to stop
  */
 void
-GNUNET_DHT_get_stop (struct GNUNET_DHT_RouteHandle *get_handle)
+GNUNET_DHT_get_stop (struct GNUNET_DHT_GetHandle *get_handle, GNUNET_SCHEDULER_Task cont, void *cont_cls)
 {
-#if OLDREMOVE
-  struct GNUNET_DHT_GetMessage *get_msg;
-  struct GNUNET_DHT_Handle *handle;
-  GNUNET_HashCode *uid_key;
+#if DEBUG_DHT_API
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "`%s': Removing pending get request with key %s, uid %llu\n", "DHT API", GNUNET_h2s(&get_handle->route_handle->key), get_handle->route_handle->uid);
 #endif
+  GNUNET_DHT_route_stop(get_handle->route_handle, cont, cont_cls);
+  GNUNET_free(get_handle);
 
-  GNUNET_DHT_route_stop(get_handle);
+}
 
-#if OLDREMOVE
-  uid_key = hash_from_uid(get_handle->uid);
-  GNUNET_assert(GNUNET_CONTAINER_multihashmap_remove(handle->outstanding_requests, uid_key, get_handle) == GNUNET_YES);
 
-  if (handle->do_destroy == GNUNET_NO)
-    {
-      get_msg = GNUNET_malloc(sizeof(struct GNUNET_DHT_GetMessage));
-      get_msg->header.type = htons(GNUNET_MESSAGE_TYPE_DHT_GET_STOP);
-      get_msg->header.size = htons(sizeof(struct GNUNET_DHT_GetMessage));
+/**
+ * Perform an asynchronous FIND PEER operation on the DHT.
+ *
+ * @param handle handle to the DHT service
+ * @param timeout timeout for this request to be sent to the
+ *        service
+ * @param options routing options for this message
+ * @param message a message to inject at found peers (may be null)
+ * @param key the key to look up
+ * @param iter function to call on each result
+ * @param iter_cls closure for iter
+ * @param cont continuation to call once message sent
+ * @param cont_cls closure for continuation
+ *
+ * @return handle to stop the async get, NULL on error
+ */
+struct GNUNET_DHT_FindPeerHandle *
+GNUNET_DHT_find_peer_start (struct GNUNET_DHT_Handle *handle,
+                      struct GNUNET_TIME_Relative timeout,
+                      enum GNUNET_DHT_RouteOption options,
+                      struct GNUNET_MessageHeader *message,
+                      const GNUNET_HashCode * key,
+                      GNUNET_DHT_FindPeerProcessor proc,
+                      void *proc_cls,
+                      GNUNET_SCHEDULER_Task cont,
+                      void *cont_cls)
+{
+  struct GNUNET_DHT_FindPeerHandle *find_peer_handle;
+  struct GNUNET_DHT_FindPeerMessage *find_peer_msg;
+  size_t msize;
+
+  if (handle->current != NULL) /* Can't send right now, we have a pending message... */
+    return NULL;
 
+  if (message != NULL)
+    msize = ntohs(message->size);
+  else
+    msize = 0;
 
-    }
+  find_peer_handle = GNUNET_malloc(sizeof(struct GNUNET_DHT_FindPeerHandle));
+  find_peer_handle->find_peer_context.proc = proc;
+  find_peer_handle->find_peer_context.proc_cls = proc_cls;
+
+#if DEBUG_DHT_API
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "`%s': Inserting pending `%s' request with key %s\n", "DHT API", "FIND PEER", GNUNET_h2s(key));
 #endif
+
+  find_peer_msg = GNUNET_malloc(sizeof(struct GNUNET_DHT_FindPeerMessage) + msize);
+  find_peer_msg->header.type = htons(GNUNET_MESSAGE_TYPE_DHT_FIND_PEER);
+  find_peer_msg->header.size = htons(sizeof(struct GNUNET_DHT_FindPeerMessage));
+  find_peer_msg->msg_len = msize;
+
+  if (message != NULL)
+  {
+    memcpy(&find_peer_msg[1], message, msize);
+  }
+
+  find_peer_handle->route_handle = GNUNET_DHT_route_start(handle, key, 0, options, &find_peer_msg->header, timeout, &find_peer_reply_iterator, find_peer_handle, cont, cont_cls);
+  return find_peer_handle;
+}
+
+/**
+ * Stop async find peer.  Frees associated resources.
+ *
+ * @param find_peer_handle GET operation to stop.
+ */
+void
+GNUNET_DHT_find_peer_stop (struct GNUNET_DHT_FindPeerHandle *find_peer_handle, GNUNET_SCHEDULER_Task cont, void *cont_cls)
+{
 #if DEBUG_DHT_API
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "`%s': Removing pending get request with key %s, uid %llu\n", "DHT API", GNUNET_h2s(&get_handle->key), get_handle->uid);
+              "`%s': Removing pending `%s' request with key %s, uid %llu\n", "DHT API", "FIND PEER", GNUNET_h2s(&find_peer_handle->route_handle->key), find_peer_handle->route_handle->uid);
 #endif
+  GNUNET_DHT_route_stop(find_peer_handle->route_handle, cont, cont_cls);
+  GNUNET_free(find_peer_handle);
+
 }
 
 
index b8a45e5d15d60e4bfe76e5fdee4e428d81bcf0f9..c6ddb0ab9304d0d78ff462d869690db125930860 100644 (file)
@@ -144,7 +144,9 @@ static struct GNUNET_CORE_MessageHandler core_handlers[] = {
  */
 static void handle_dht_get (void *cls, struct GNUNET_DHT_GetMessage *get_msg, GNUNET_HashCode *key)
 {
+#if DEBUG_DHT
   GNUNET_HashCode get_key;
+#endif
   size_t get_type;
 
   GNUNET_assert(ntohs(get_msg->header.size) >= sizeof(struct GNUNET_DHT_GetMessage));
@@ -164,14 +166,13 @@ static void handle_dht_get (void *cls, struct GNUNET_DHT_GetMessage *get_msg, GN
  */
 static void handle_dht_find_peer (void *cls, struct GNUNET_DHT_FindPeerMessage *find_msg, GNUNET_HashCode *key)
 {
-
-  GNUNET_assert(ntohs(find_msg->header.size) == sizeof(struct GNUNET_DHT_FindPeerMessage));
-
 #if DEBUG_DHT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "`%s': Received `%s' request from client, key %s\n", "DHT", "FIND PEER", GNUNET_h2s(key));
+              "`%s': Received `%s' request from client, key %s (msg size %d, we expected %d)\n", "DHT", "FIND PEER", GNUNET_h2s(key), ntohs(find_msg->header.size), sizeof(struct GNUNET_DHT_FindPeerMessage));
 #endif
 
+  GNUNET_assert(ntohs(find_msg->header.size) >= sizeof(struct GNUNET_DHT_FindPeerMessage));
+
   /* FIXME: Implement find peer functionality here */
 }
 
@@ -298,10 +299,8 @@ handle_dht_start_message(void *cls, struct GNUNET_SERVER_Client * client,
       handle_dht_find_peer(cls, (struct GNUNET_DHT_FindPeerMessage *)enc_msg, &dht_msg->key);
       break;
     default:
-#if DEBUG_DHT
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                   "`%s': Message type (%d) not handled\n", "DHT", enc_type);
-#endif
     }
 
   GNUNET_SERVER_receive_done(client, GNUNET_OK);
index dd940a6e45c2d19ae429dadc0b3eaac3c93471be..9dc429148129917e61053e3bd35cd545f5cc3b58 100644 (file)
@@ -51,8 +51,8 @@ struct PeerContext
   struct GNUNET_CONFIGURATION_Handle *cfg;
   struct GNUNET_DHT_Handle *dht_handle;
   struct GNUNET_PeerIdentity id;
-  struct GNUNET_DHT_RouteHandle *get_handle;
-  struct GNUNET_DHT_RouteHandle *find_peer_handle;
+  struct GNUNET_DHT_GetHandle *get_handle;
+  struct GNUNET_DHT_FindPeerHandle *find_peer_handle;
 
 #if START_ARM
   pid_t arm_pid;
@@ -123,6 +123,50 @@ end_badly ()
   return;
 }
 
+/**
+ * Signature of the main function of a task.
+ *
+ * @param cls closure
+ * @param tc context information (why was this task triggered now)
+ */
+void test_find_peer_stop (void *cls,
+               const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+  struct PeerContext *peer = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_find_peer_stop!\n");
+  if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT)
+    GNUNET_SCHEDULER_add_now(sched, &end_badly, NULL);
+
+  GNUNET_assert (peer->dht_handle != NULL);
+
+  GNUNET_DHT_find_peer_stop(peer->find_peer_handle, &end, &p1);
+
+  //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &end, &p1);
+
+}
+
+/**
+ * Signature of the main function of a task.
+ *
+ * @param cls closure
+ * @param tc context information (why was this task triggered now)
+ */
+void test_find_peer (void *cls,
+               const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+  struct PeerContext *peer = cls;
+  GNUNET_HashCode hash;
+  memset(&hash, 42, sizeof(GNUNET_HashCode));
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_find_peer!\n");
+  GNUNET_assert (peer->dht_handle != NULL);
+
+  peer->find_peer_handle = GNUNET_DHT_find_peer_start(peer->dht_handle, TIMEOUT, 0, NULL, &hash, NULL, NULL, &test_find_peer_stop, &p1);
+
+  if (peer->find_peer_handle == NULL)
+    GNUNET_SCHEDULER_add_now(sched, &end_badly, &p1);
+}
 
 /**
  * Signature of the main function of a task.
@@ -143,11 +187,8 @@ void test_put (void *cls,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_put!\n");
   GNUNET_assert (peer->dht_handle != NULL);
 
-  GNUNET_DHT_put(peer->dht_handle, &hash, 0, data_size, data, GNUNET_TIME_relative_to_absolute(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 360)) ,GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 360), &end, NULL);
+  GNUNET_DHT_put(peer->dht_handle, &hash, 0, data_size, data, GNUNET_TIME_relative_to_absolute(TIMEOUT), TIMEOUT, &test_find_peer, &p1);
 
-  //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &test_put, &p1);
-
-  //GNUNET_SCHEDULER_add_now(sched, &end, NULL);
 }
 
 /**
@@ -160,8 +201,6 @@ void test_get_stop (void *cls,
                const struct GNUNET_SCHEDULER_TaskContext * tc)
 {
   struct PeerContext *peer = cls;
-  GNUNET_HashCode hash;
-  memset(&hash, 42, sizeof(GNUNET_HashCode));
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get_stop!\n");
   if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT)
@@ -169,10 +208,9 @@ void test_get_stop (void *cls,
 
   GNUNET_assert (peer->dht_handle != NULL);
 
-  GNUNET_DHT_get_stop(peer->get_handle);
+  GNUNET_DHT_get_stop(peer->get_handle, &test_put, &p1);
 
   //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &test_put, &p1);
-  GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &test_put, &p1);
 
 }
 
@@ -193,12 +231,10 @@ void test_get (void *cls,
   peer->dht_handle = GNUNET_DHT_connect (sched, peer->cfg, 100);
   GNUNET_assert (peer->dht_handle != NULL);
 
-  peer->get_handle = GNUNET_DHT_get_start(peer->dht_handle, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 100), 42, &hash, NULL, NULL, &test_get_stop, &p1);
+  peer->get_handle = GNUNET_DHT_get_start(peer->dht_handle, TIMEOUT, 42, &hash, NULL, NULL, &test_get_stop, &p1);
 
   if (peer->get_handle == NULL)
     GNUNET_SCHEDULER_add_now(sched, &end_badly, &p1);
-
-  //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &test_get_stop, &p1);
 }
 
 static void
index 45a0adde24462d8a436e7568158ffc0708ae2eb8..b9d9ab4173be189665217251078f77b5465cde70 100644 (file)
@@ -31,7 +31,7 @@ ALLOW_SHUTDOWN = 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
+#BINARY = /root/documents/research/gnunet/gnunet-ng/src/dht/.libs/gnunet-service-dht
 #PREFIX = xterm -T dvservice -e gdb --args
 OPTIONS=""
 CONFIG = $DEFAULTCONFIG
@@ -39,6 +39,10 @@ HOME = $SERVICEHOME
 HOSTNAME = localhost
 PORT = 2100
 
+[dhtcache]
+QUOTA = 1000000
+DATABASE = sqlite
+
 [hostlist]
 HTTP-PROXY = 
 SERVERS = http://gnunet.org:8080/