gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [GNUnet-SVN] r17031 - gnunet/src/dht
Date: Tue, 27 Sep 2011 10:12:07 +0200

Author: grothoff
Date: 2011-09-27 10:12:07 +0200 (Tue, 27 Sep 2011)
New Revision: 17031

Modified:
   gnunet/src/dht/gnunet-service-dht_neighbours.c
   gnunet/src/dht/gnunet-service-dht_routing.c
   gnunet/src/dht/gnunet-service-dht_routing.h
Log:
hxing

Modified: gnunet/src/dht/gnunet-service-dht_neighbours.c
===================================================================
--- gnunet/src/dht/gnunet-service-dht_neighbours.c      2011-09-26 22:02:03 UTC 
(rev 17030)
+++ gnunet/src/dht/gnunet-service-dht_neighbours.c      2011-09-27 08:12:07 UTC 
(rev 17031)
@@ -1053,7 +1053,8 @@
   msize = data_size + sizeof (struct PeerResultMessage) + 
     (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity);
   if ( (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
-       (get_path_length + put_path_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / 
sizeof (struct GNUNET_PeerIdentity)) ||
+       (get_path_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct 
GNUNET_PeerIdentity)) ||
+       (put_path_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct 
GNUNET_PeerIdentity)) ||
        (data_size > GNUNET_SERVER_MAX_MESSAGE_SIZE) )
   {
     GNUNET_break (0);
@@ -1439,19 +1440,69 @@
                       const struct GNUNET_TRANSPORT_ATS_Information
                       *atsi)
 {
-  // FIXME!
-  // 1) validate result format
-  // 2) append 'peer' to put path
-  // 3) forward to local clients
-  // 4) p2p routing
-  const struct GNUNET_DHT_P2PRouteResultMessage *incoming =
-      (const struct GNUNET_DHT_P2PRouteResultMessage *) message;
-  struct GNUNET_MessageHeader *enc_msg =
-      (struct GNUNET_MessageHeader *) &incoming[1];
-  struct DHT_MessageContext msg_ctx;
+  const struct PeerResultMessage *prm;
+  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;
+                       
+  /* parse and validate message */
+  msize = ntohs (message->size);
+  if (msize < sizeof (struct PeerResultMessage))
+  {
+    GNUNET_break_op (0);
+    return GNUNET_YES;
+  }
+  prm = (struct PeerResultMessage *) message;
+  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_SERVER_MAX_MESSAGE_SIZE / sizeof (struct 
GNUNET_PeerIdentity)) ||
+       (put_path_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct 
GNUNET_PeerIdentity)) )
+  {
+    GNUNET_break_op (0);
+    return GNUNET_YES;
+  } 
+  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));
+  /* append 'peer' to 'get_path' */
+  {    
+    struct GNUNET_PeerIdentity xget_path[get_path_length+1];
+    
+    memcpy (xget_path, get_path, get_path_length * sizeof (struct 
GNUNET_PeerIdentity));
+    xget_path[get_path_length] = *peer;
 
+    /* forward to local clients */   
+    GDS_CLIENT_handle_reply (GNUNET_TIME_absolute_ntoh (prm->expiration),
+                            &prm->key,
+                            get_path_length + 1,
+                            xget_path,
+                            put_path_length,
+                            put_path,
+                            type,
+                            data_size, 
+                            data);
 
-
+    /* forward to other peers */
+    GDS_ROUTING_process (type,
+                        GNUNET_TIME_absolute_ntoh (prm->expiration),
+                        &prm->key,
+                        put_path_length,
+                        put_path,
+                        get_path_length + 1,
+                        xget_path,
+                        data,
+                        data_size);                     
+  }
   return GNUNET_YES;
 }
 

Modified: gnunet/src/dht/gnunet-service-dht_routing.c
===================================================================
--- gnunet/src/dht/gnunet-service-dht_routing.c 2011-09-26 22:02:03 UTC (rev 
17030)
+++ gnunet/src/dht/gnunet-service-dht_routing.c 2011-09-27 08:12:07 UTC (rev 
17031)
@@ -46,6 +46,11 @@
   struct GNUNET_PeerIdentity peer;
 
   /**
+   * Key of this request.
+   */
+  GNUNET_HashCode key;
+
+  /**
    * Position of this node in the min heap.
    */
   struct GNUNET_CONTAINER_HeapNode *heap_node;
@@ -56,12 +61,6 @@
   struct GNUNET_CONTAINER_BloomFilter *reply_bf;
 
   /**
-   * Timestamp of this request, for ordering
-   * the min heap.
-   */
-  struct GNUNET_TIME_Absolute timestamp;
-
-  /**
    * Type of the requested block.
    */
   enum GNUNET_BLOCK_Type type;
@@ -82,11 +81,6 @@
    */
   uint32_t reply_bf_mutator;
 
-  /**
-   * Key of this request.
-   */
-  GNUNET_HashCode key;
-
 };
 
 
@@ -102,6 +96,118 @@
 
 
 /**
+ * Closure for the 'process' function.
+ */
+struct ProcessContext
+{
+  /**
+   * Path of the original PUT
+   */
+  const struct GNUNET_PeerIdentity *put_path;
+
+  /**
+   * Path of the reply.
+   */ 
+  const struct GNUNET_PeerIdentity *get_path;
+
+  /**
+   * Payload of the reply.
+   */
+  const void *data;
+
+  /**
+   * Expiration time of the result.
+   */
+  GNUNET_TIME_Absolute expiration_time;
+
+  /**
+   * Number of entries in 'put_path'.
+   */
+  unsigned int put_path_length;
+
+  /**
+   * Number of entries in 'get_path'.
+   */
+  unsigned int get_path_length;
+
+  /**
+   * Number of bytes in 'data'.
+   */
+  size_t data_size;
+
+  /**
+   * Type of the reply.
+   */
+  enum GNUNET_BLOCK_Type type;
+
+};
+
+
+/**
+ * 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 value the 'struct RecentRequest' with the request
+ * @return GNUNET_OK (continue to iterate), 
+ *         GNUNET_SYSERR if the result is malformed or type unsupported
+ */
+static int
+process (void *cls,
+        const GNUNET_HashCode *key,
+        void *value)
+{
+  struct ProcessContext *pc = cls;
+  struct RecentRequest *rr = value;
+  enum GNUNET_BLOCK_EvaluationResult eval;
+
+  if ( (rr->type != GNUNET_BLOCK_TYPE_ANY) &&
+       (rr->type != pc->type) )
+    return GNUNET_OK; /* type missmatch */
+  eval = GNUNET_BLOCK_evaluate (block_context,
+                               pc->type,
+                               key,
+                               &rr->reply_bf,
+                               rr->reply_bf_mutator,
+                               rr->xquery,
+                               rr->xquery_size,
+                               pc->data,
+                               pc->data_size);
+  switch (eval)
+  {
+  case GNUNET_BLOCK_EVALUATION_OK_MORE:
+  case GNUNET_BLOCK_EVALUATION_OK_LAST:
+    GDS_NEIGHBOURS_handle_reply (&rr->target,
+                                pc->type,
+                                pc->expiration_time,
+                                key,
+                                pc->put_path_length,
+                                pc->put_path,
+                                pc->get_path_length,
+                                pc->get_path,
+                                pc->data,
+                                pc->data_size);
+    break;
+  case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
+    return GNUNET_OK;
+  case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
+  case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
+    GNUNET_break (0);
+    return GNUNET_OK;
+  case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
+    return GNUNET_SYSERR;
+  default:
+    GNUNET_break (0);
+    return GNUNET_SYSERR;  
+  }
+  return GNUNET_OK;
+}
+
+
+/**
  * 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
@@ -123,12 +229,26 @@
                     GNUNET_TIME_Absolute expiration_time,
                     const GNUNET_HashCode *key,
                     unsigned int put_path_length,
-                    struct GNUNET_PeerIdentity *put_path,
+                    const struct GNUNET_PeerIdentity *put_path,
                     unsigned int get_path_length,
-                    struct GNUNET_PeerIdentity *get_path,
+                    const struct GNUNET_PeerIdentity *get_path,
                     const void *data,
                     size_t data_size)
 {
+  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;
+  GNUNET_CONTAINER_multihashmap_iterate (recent_map,
+                                        key,
+                                        &process,
+                                        &pc);
 }
 
 
@@ -152,24 +272,33 @@
                 const struct GNUNET_CONTAINER_BloomFilter *reply_bf,
                 uint32_t reply_bf_mutator)
 {
-  if (GNUNET_CONTAINER_heap_get_size (recent_heap) >= DHT_MAX_RECENT)
+  struct RecentRequest *recent_req;
+
+  while (GNUNET_CONTAINER_heap_get_size (recent_heap) >= DHT_MAX_RECENT)
   {
     recent_req = GNUNET_CONTAINER_heap_peek (recent_heap);
     GNUNET_assert (recent_req != NULL);
-    GNUNET_SCHEDULER_cancel (recent_req->remove_task);
     GNUNET_CONTAINER_heap_remove_node (recent_req->heap_node);
     GNUNET_CONTAINER_bloomfilter_free (recent_req->bloom);
     GNUNET_free (recent_req);
   }
 
-  recent_req = GNUNET_malloc (sizeof (struct RecentRequest));
-  recent_req->uid = msg_ctx->unique_id;
-  memcpy (&recent_req->key, &msg_ctx->key, sizeof (GNUNET_HashCode));
+  recent_req = GNUNET_malloc (sizeof (struct RecentRequest) + xquery_size);
+  recent_req->peer = *sender;
+  recent_req->key = *key;
   recent_req->heap_node =
     GNUNET_CONTAINER_heap_insert (recent_heap, recent_req,
                                  GNUNET_TIME_absolute_get ().abs_value);
-  recent_req->bloom =
-    GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
+  recent_req->reply_bf =
+    GNUNET_CONTAINER_bloomfilter_copy (reply_bf);
+  recent_req->type = type;
+  recent_req->xquery = &recent_req[1];
+  recent_req->xquery_size = xquery_size;
+  recent_req->reply_bf_mutator = reply_bf_mutator;
+  GNUNET_CONTAINER_multihashmap_put (recent_map,
+                                    key,
+                                    recent_req,
+                                    
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
 
 
 }
@@ -194,6 +323,8 @@
 void
 GDS_ROUTING_done ()
 {
+  struct RecentRequest *recent_req;
+
   while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0)
   {
     recent_req = GNUNET_CONTAINER_heap_peek (recent_heap);
@@ -202,6 +333,7 @@
     GNUNET_CONTAINER_bloomfilter_free (recent_req->bloom);
     GNUNET_free (recent_req);
   }
+  GNUNET_assert (0 == GNUNET_CONTAINER_heap_size (recent_heap));
   GNUNET_CONTAINER_heap_destroy (recent_heap);
   recent_heap = NULL;
   GNUNET_CONTAINER_multihashmap_destroy (recent_map);

Modified: gnunet/src/dht/gnunet-service-dht_routing.h
===================================================================
--- gnunet/src/dht/gnunet-service-dht_routing.h 2011-09-26 22:02:03 UTC (rev 
17030)
+++ gnunet/src/dht/gnunet-service-dht_routing.h 2011-09-27 08:12:07 UTC (rev 
17031)
@@ -49,9 +49,9 @@
                     GNUNET_TIME_Absolute expiration_time,
                     const GNUNET_HashCode *key,
                     unsigned int put_path_length,
-                    struct GNUNET_PeerIdentity *put_path,
+                    const struct GNUNET_PeerIdentity *put_path,
                     unsigned int get_path_length,
-                    struct GNUNET_PeerIdentity *get_path,
+                    const struct GNUNET_PeerIdentity *get_path,
                     const void *data,
                     size_t data_size);
 




reply via email to

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