- fix coverity
[oweals/gnunet.git] / src / cadet / gnunet-service-cadet_dht.c
index b187e3cd9d6393b87f802e5f373014bf4505f0e9..da9bf76048976226b2f71e29b08079048331f4f2 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2013 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2013 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -14,8 +14,8 @@
 
      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.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 */
 
 
 /**
  * Handle for DHT searches.
  */
-struct GMD_search_handle
+struct GCD_search_handle
 {
   /** DHT_GET handle. */
   struct GNUNET_DHT_GetHandle *dhtget;
 
   /** Provided callback to call when a path is found. */
-  GMD_search_callback callback;
+  GCD_search_callback callback;
 
   /** Provided closure. */
   void *cls;
@@ -93,7 +93,7 @@ static unsigned long long dht_replication_level;
 /**
  * Task to periodically announce itself in the network.
  */
-static GNUNET_SCHEDULER_TaskIdentifier announce_id_task;
+static struct GNUNET_SCHEDULER_Task * announce_id_task;
 
 /**
  * GET requests to stop on shutdown.
@@ -119,77 +119,28 @@ path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
                      const struct GNUNET_PeerIdentity *put_path,
                      unsigned int put_path_length)
 {
+  size_t size = get_path_length + put_path_length + 1;
+  struct GNUNET_PeerIdentity peers[size];
+  const struct GNUNET_PeerIdentity *peer;
   struct CadetPeerPath *p;
-  GNUNET_PEER_Id id;
+  unsigned int own_pos;
   int i;
 
-  p = path_new (1);
-  p->peers[0] = myid;
-  GNUNET_PEER_change_rc (myid, 1);
-  i = get_path_length;
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "   GET has %d hops.\n", i);
-  for (i--; i >= 0; i--)
+  peers[0] = my_full_id;
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "   GET has %d hops.\n", get_path_length);
+  for (i = 0 ; i < get_path_length; i++)
   {
-    id = GNUNET_PEER_intern (&get_path[i]);
-    if (p->length > 0 && id == p->peers[p->length - 1])
-    {
-      LOG (GNUNET_ERROR_TYPE_DEBUG, "   Optimizing 1 hop out.\n");
-      GNUNET_PEER_change_rc (id, -1);
-    }
-    else
-    {
-      LOG (GNUNET_ERROR_TYPE_DEBUG, "   Adding from GET: %s.\n",
-                  GNUNET_i2s (&get_path[i]));
-      p->length++;
-      p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
-      p->peers[p->length - 1] = id;
-    }
+    peer = &get_path[get_path_length - i - 1];
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "   From GET: %s\n", GNUNET_i2s (peer));
+    peers[i + 1] = *peer;
   }
-  i = put_path_length;
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "   PUT has %d hops.\n", i);
-  for (i--; i >= 0; i--)
+  for (i = 0 ; i < put_path_length; i++)
   {
-    id = GNUNET_PEER_intern (&put_path[i]);
-    if (id == myid)
-    {
-      /* PUT path went through us, so discard the path up until now and start
-       * from here to get a much shorter (and loop-free) path.
-       */
-      path_destroy (p);
-      p = path_new (0);
-    }
-    if (p->length > 0 && id == p->peers[p->length - 1])
-    {
-      LOG (GNUNET_ERROR_TYPE_DEBUG, "   Optimizing 1 hop out.\n");
-      GNUNET_PEER_change_rc (id, -1);
-    }
-    else
-    {
-      LOG (GNUNET_ERROR_TYPE_DEBUG, "   Adding from PUT: %s.\n",
-                  GNUNET_i2s (&put_path[i]));
-      p->length++;
-      p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
-      p->peers[p->length - 1] = id;
-    }
+    peer = &put_path[put_path_length - i - 1];
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "   From PUT: %s\n", GNUNET_i2s (peer));
+    peers[i + get_path_length + 1] = *peer;
   }
-#if CADET_DEBUG
-  if (get_path_length > 0)
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "   (first of GET: %s)\n",
-                GNUNET_i2s (&get_path[0]));
-  if (put_path_length > 0)
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "   (first of PUT: %s)\n",
-                GNUNET_i2s (&put_path[0]));
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "   In total: %d hops\n",
-              p->length);
-  for (i = 0; i < p->length; i++)
-  {
-    struct GNUNET_PeerIdentity peer_id;
-
-    GNUNET_PEER_resolve (p->peers[i], &peer_id);
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "       %u: %s\n", p->peers[i],
-                GNUNET_i2s (&peer_id));
-  }
-#endif
+  p = path_build_from_peer_ids (peers, size, myid, &own_pos);
   return p;
 }
 
@@ -203,9 +154,9 @@ path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
  * @param exp when will this value expire
  * @param key key of the result
  * @param get_path path of the get request
- * @param get_path_length lenght of get_path
+ * @param get_path_length lenght of @a get_path
  * @param put_path path of the put request
- * @param put_path_length length of the put_path
+ * @param put_path_length length of the @a put_path
  * @param type type of the result
  * @param size number of bytes in data
  * @param data pointer to the result data
@@ -219,7 +170,7 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
                     unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
                     size_t size, const void *data)
 {
-  struct GMD_search_handle *h = cls;
+  struct GCD_search_handle *h = cls;
   struct GNUNET_HELLO_Message *hello;
   struct CadetPeerPath *p;
   struct CadetPeer *peer;
@@ -227,17 +178,27 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
 
   p = path_build_from_dht (get_path, get_path_length,
                            put_path, put_path_length);
+  if (NULL == p)
+  {
+    GNUNET_break_op (0);
+    return;
+  }
+
   s = path_2s (p);
-  LOG (GNUNET_ERROR_TYPE_INFO, "Got path from DHT: %s\n", s);
+  LOG (GNUNET_ERROR_TYPE_INFO,
+       "Got path from DHT: %s\n",
+       s);
   GNUNET_free_non_null (s);
-  peer = GMP_get_short (p->peers[p->length - 1]);
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Got HELLO for %s\n", GMP_2s (peer));
+
+  peer = GCP_get_short (p->peers[p->length - 1], GNUNET_YES);
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Got HELLO for %s\n",
+       GCP_2s (peer));
   h->callback (h->cls, p);
   path_destroy (p);
   hello = (struct GNUNET_HELLO_Message *) data;
-  GMP_set_hello (peer, hello);
-  GMP_try_connect (peer);
-  return;
+  GCP_set_hello (peer, hello);
+  GCP_try_connect (peer);
 }
 
 
@@ -245,41 +206,38 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
  * Periodically announce self id in the DHT
  *
  * @param cls closure
- * @param tc task context
  */
 static void
-announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+announce_id (void *cls)
 {
   struct GNUNET_HashCode phash;
   const struct GNUNET_HELLO_Message *hello;
   size_t size;
   struct GNUNET_TIME_Absolute expiration;
-  struct GNUNET_TIME_Relative retry_time;
 
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-  {
-    announce_id_task = GNUNET_SCHEDULER_NO_TASK;
-    return;
-  }
+  announce_id_task = NULL;
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Announce ID\n");
-
   /* TODO
    * - Set data expiration in function of X
    * - Adapt X to churn
    */
-  hello = GMH_get_mine ();
+  hello = GCH_get_mine ();
   if (NULL == hello || (size = GNUNET_HELLO_size (hello)) == 0)
   {
     /* Peerinfo gave us no hello yet, try again in a second. */
     announce_id_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
                                                      &announce_id, cls);
     LOG (GNUNET_ERROR_TYPE_DEBUG, "  no hello, waiting!\n");
+    GNUNET_STATISTICS_update (stats, "# DHT announce skipped (no hello)",
+                              1, GNUNET_NO);
+
     return;
   }
   expiration = GNUNET_HELLO_get_last_expiration (hello);
-  retry_time = GNUNET_TIME_absolute_get_remaining (expiration);
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Hello %p size: %u\n", hello, size);
+  GNUNET_STATISTICS_update (stats, "# DHT announce",
+                            1, GNUNET_NO);
   memset (&phash, 0, sizeof (phash));
   memcpy (&phash, &my_full_id, sizeof (my_full_id));
   GNUNET_DHT_put (dht_handle,   /* DHT handle */
@@ -291,7 +249,6 @@ announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
                   size,  /* Size of the data */
                   (const char *) hello, /* Data itself */
                   expiration,  /* Data expiration */
-                  retry_time, /* Retry time */
                   NULL,         /* Continuation */
                   NULL);        /* Continuation closure */
   announce_id_task =
@@ -304,7 +261,7 @@ announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  *
  * @param cls Closure (unused)
  * @param key Current peer ID.
- * @param value Value in the hash map (GMD_search_handle).
+ * @param value Value in the hash map (GCD_search_handle).
  *
  * @return #GNUNET_YES, we should continue to iterate,
  */
@@ -313,9 +270,9 @@ stop_get (void *cls,
           uint32_t key,
           void *value)
 {
-  struct GMD_search_handle *h = value;
+  struct GCD_search_handle *h = value;
 
-  GMD_search_stop (h);
+  GCD_search_stop (h);
   return GNUNET_YES;
 }
 
@@ -330,7 +287,7 @@ stop_get (void *cls,
  * @param c Configuration.
  */
 void
-GMD_init (const struct GNUNET_CONFIGURATION_Handle *c)
+GCD_init (const struct GNUNET_CONFIGURATION_Handle *c)
 {
   LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
   if (GNUNET_OK !=
@@ -367,8 +324,9 @@ GMD_init (const struct GNUNET_CONFIGURATION_Handle *c)
  * Shut down the DHT subsystem.
  */
 void
-GMD_shutdown (void)
+GCD_shutdown (void)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down DHT\n");
   GNUNET_CONTAINER_multihashmap32_iterate (get_requests, &stop_get, NULL);
   GNUNET_CONTAINER_multihashmap32_destroy (get_requests);
   if (dht_handle != NULL)
@@ -376,25 +334,26 @@ GMD_shutdown (void)
     GNUNET_DHT_disconnect (dht_handle);
     dht_handle = NULL;
   }
-  if (GNUNET_SCHEDULER_NO_TASK != announce_id_task)
+  if (NULL != announce_id_task)
   {
     GNUNET_SCHEDULER_cancel (announce_id_task);
-    announce_id_task = GNUNET_SCHEDULER_NO_TASK;
+    announce_id_task = NULL;
   }
 }
 
-struct GMD_search_handle *
-GMD_search (const struct GNUNET_PeerIdentity *peer_id,
-            GMD_search_callback callback, void *cls)
+struct GCD_search_handle *
+GCD_search (const struct GNUNET_PeerIdentity *peer_id,
+            GCD_search_callback callback, void *cls)
 {
   struct GNUNET_HashCode phash;
-  struct GMD_search_handle *h;
+  struct GCD_search_handle *h;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "  Starting DHT GET for peer %s\n", GNUNET_i2s (peer_id));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting DHT GET for peer %s\n",
+       GNUNET_i2s (peer_id));
+  GNUNET_STATISTICS_update (stats, "# DHT search", 1, GNUNET_NO);
   memset (&phash, 0, sizeof (phash));
   memcpy (&phash, peer_id, sizeof (*peer_id));
-  h = GNUNET_new (struct GMD_search_handle);
+  h = GNUNET_new (struct GCD_search_handle);
   h->peer_id = GNUNET_PEER_intern (peer_id);
   h->callback = callback;
   h->cls = cls;
@@ -412,8 +371,9 @@ GMD_search (const struct GNUNET_PeerIdentity *peer_id,
   return h;
 }
 
+
 void
-GMD_search_stop (struct GMD_search_handle *h)
+GCD_search_stop (struct GCD_search_handle *h)
 {
   GNUNET_break (GNUNET_OK ==
                 GNUNET_CONTAINER_multihashmap32_remove (get_requests,