fix shutdown logic
authorChristian Grothoff <christian@grothoff.org>
Sun, 22 Jan 2017 15:33:01 +0000 (16:33 +0100)
committerChristian Grothoff <christian@grothoff.org>
Sun, 22 Jan 2017 15:33:01 +0000 (16:33 +0100)
src/cadet/gnunet-service-cadet-new.c
src/cadet/gnunet-service-cadet-new_core.c
src/cadet/gnunet-service-cadet-new_paths.c
src/cadet/gnunet-service-cadet-new_peer.c
src/cadet/gnunet-service-cadet-new_peer.h
src/cadet/gnunet-service-cadet-new_tunnels.c

index b0d8fc32d1a605dcd868b778fea2665eec7381aa..2e431c034857783e452eb34b5ad1067ac49179c8 100644 (file)
@@ -334,6 +334,27 @@ destroy_tunnels_now (void *cls,
 }
 
 
+/**
+ * Callback invoked on all peers to destroy all tunnels
+ * that may still exist.
+ *
+ * @param cls NULL
+ * @param pid identify of a peer
+ * @param value a `struct CadetPeer` that may still have a tunnel
+ * @return #GNUNET_OK (iterate over all entries)
+ */
+static int
+destroy_paths_now (void *cls,
+                   const struct GNUNET_PeerIdentity *pid,
+                   void *value)
+{
+  struct CadetPeer *cp = value;
+
+  GCP_drop_owned_paths (cp);
+  return GNUNET_OK;
+}
+
+
 /**
  * Task run during shutdown.
  *
@@ -366,6 +387,9 @@ shutdown_task (void *cls)
   GCP_iterate_all (&destroy_tunnels_now,
                    NULL);
   /* All tunnels, channels, connections and CORE must be down before this point. */
+  GCP_iterate_all (&destroy_paths_now,
+                   NULL);
+  /* All paths, tunnels, channels, connections and CORE must be down before this point. */
   GCP_destroy_all_peers ();
   if (NULL != peers)
   {
index 7cff68f4abfe5e9c53fb569fb86a81f730ae2548..1e35a5102eff487b2f82ba21d6103ebdace494c4 100644 (file)
@@ -476,7 +476,8 @@ handle_connection_create (void *cls,
          GNUNET_sh2s (&msg->cid.connection_of_tunnel));
     path = GCPP_get_path_from_route (path_length - 1,
                                      pids);
-    GCT_add_inbound_connection (GCT_create_tunnel (origin),
+    GCT_add_inbound_connection (GCP_get_tunnel (origin,
+                                                GNUNET_YES),
                                 &msg->cid,
                                 path);
     return;
index d0df2a1f4246029f709282ba3a686aba7b35f850..39658d4e8e9da3dce947e21fc031c63c85490987 100644 (file)
@@ -54,13 +54,6 @@ struct CadetPeerPath
    */
   struct GNUNET_CONTAINER_HeapNode *hn;
 
-  /**
-   * Connections using this path, by destination peer
-   * (each hop of the path could correspond to an
-   * active connection).
-   */
-  struct GNUNET_CONTAINER_MultiPeerMap *connections;
-
   /**
    * Desirability of the path. How unique is it for the various peers
    * on it?
@@ -185,9 +178,6 @@ path_destroy (struct CadetPeerPath *path)
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Destroying path %s\n",
        GCPP_2s (path));
-  GNUNET_assert (0 ==
-                 GNUNET_CONTAINER_multipeermap_size (path->connections));
-  GNUNET_CONTAINER_multipeermap_destroy (path->connections);
   for (unsigned int i=0;i<path->entries_length;i++)
     GNUNET_free (path->entries[i]);
   GNUNET_free (path->entries);
@@ -214,10 +204,7 @@ GCPP_release (struct CadetPeerPath *path)
   entry = path->entries[path->entries_length - 1];
   while (1)
   {
-    /* cut 'off' end of path, verifying it is not in use */
-    GNUNET_assert (NULL ==
-                   GNUNET_CONTAINER_multipeermap_get (path->connections,
-                                                      GCP_get_id (entry->peer)));
+    /* cut 'off' end of path */
     GCP_path_entry_remove (entry->peer,
                            entry,
                            path->entries_length - 1);
index fa1cc9ed9e402e8ac7db9994007f8cc892caead6..1505914a19944cd96132631278324b7c32779727 100644 (file)
@@ -40,7 +40,6 @@
 #include "gnunet_core_service.h"
 #include "gnunet_statistics_service.h"
 #include "cadet_protocol.h"
-#include "cadet_path.h"
 #include "gnunet-service-cadet-new.h"
 #include "gnunet-service-cadet-new_connection.h"
 #include "gnunet-service-cadet-new_dht.h"
@@ -257,7 +256,8 @@ destroy_peer (void *cls)
   cp->destroy_task = NULL;
   GNUNET_assert (NULL == cp->t);
   GNUNET_assert (NULL == cp->core_mq);
-  GNUNET_assert (0 == cp->path_dll_length);
+  for (unsigned int i=0;i<cp->path_dll_length;i++)
+    GNUNET_assert (NULL == cp->path_heads[i]);
   GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections));
   GNUNET_assert (GNUNET_YES ==
                  GNUNET_CONTAINER_multipeermap_remove (peers,
@@ -284,7 +284,11 @@ destroy_peer (void *cls)
     cp->connectivity_suggestion = NULL;
   }
   GNUNET_CONTAINER_multishortmap_destroy (cp->connections);
-  GNUNET_CONTAINER_heap_destroy (cp->path_heap);
+  if (NULL != cp->path_heap)
+  {
+    GNUNET_CONTAINER_heap_destroy (cp->path_heap);
+    cp->path_heap = NULL;
+  }
   GNUNET_free_non_null (cp->hello);
   /* Peer should not be freed if paths exist; if there are no paths,
      there ought to be no connections, and without connections, no
@@ -418,8 +422,9 @@ consider_peer_destroy (struct CadetPeer *cp)
                                                      cp);
     return;
   }
-  if (0 < cp->path_dll_length)
-    return; /* still relevant! */
+  for (unsigned int i=0;i<cp->path_dll_length;i++)
+    if (NULL != cp->path_heads[i])
+      return; /* still relevant! */
   if (NULL != cp->hello)
   {
     /* relevant only until HELLO expires */
@@ -627,6 +632,28 @@ GCP_destroy_all_peers ()
 }
 
 
+/**
+ * Drop all paths owned by this peer, and do not
+ * allow new ones to be added: We are shutting down.
+ *
+ * @param cp peer to drop paths to
+ */
+void
+GCP_drop_owned_paths (struct CadetPeer *cp)
+{
+  struct CadetPeerPath *path;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Destroying all paths to %s\n",
+       GCP_2s (cp));
+  while (NULL != (path =
+                  GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
+    GCPP_release (path);
+  GNUNET_CONTAINER_heap_destroy (cp->path_heap);
+  cp->path_heap = NULL;
+}
+
+
 /**
  * Add an entry to the DLL of all of the paths that this peer is on.
  *
@@ -730,6 +757,12 @@ GCP_attach_path (struct CadetPeer *cp,
   GNUNET_CONTAINER_HeapCostType root_desirability;
   struct GNUNET_CONTAINER_HeapNode *hn;
 
+  if (NULL == cp->path_heap)
+  {
+    /* #GCP_drop_owned_paths() was already called, we cannot take new ones! */
+    GNUNET_assert (GNUNET_NO == force);
+    return NULL;
+  }
   desirability = GCPP_get_desirability (path);
   if (GNUNET_NO == force)
   {
index 8a1d3ed5c4ea58eba3965c88dfd1ccc3414d77e2..aaaef15b8bdae102a44b677484d5746eb047c0b5 100644 (file)
@@ -90,6 +90,16 @@ unsigned int
 GCP_count_paths (const struct CadetPeer *cp);
 
 
+/**
+ * Drop all paths owned by this peer, and do not
+ * allow new ones to be added: We are shutting down.
+ *
+ * @param cp peer to drop paths to
+ */
+void
+GCP_drop_owned_paths (struct CadetPeer *cp);
+
+
 /**
  * Peer path iterator.
  *
index 1afa451ec33b2c74d2ad8d568b69da625ebf4765..a1a7b80fda49cf304ed715a16b5283733912907b 100644 (file)
@@ -1601,7 +1601,11 @@ GCT_destroy_tunnel_now (struct CadetTunnel *t)
 {
   GNUNET_assert (0 ==
                  GNUNET_CONTAINER_multihashmap32_size (t->channels));
-  GNUNET_SCHEDULER_cancel (t->destroy_task);
+  if (NULL != t->destroy_task)
+  {
+    GNUNET_SCHEDULER_cancel (t->destroy_task);
+    t->destroy_task = NULL;
+  }
   destroy_tunnel (t);
 }