clean up for configs
[oweals/gnunet.git] / src / mesh / mesh_path.c
index 05444655aa546a1fae0701e329165ba3a6a60527..f1c68c00561a285dcf9149a0eb6b911428b4f16f 100644 (file)
  * @author Bartlomiej Polot
  */
 
-#include "mesh2.h"
+#include "mesh.h"
 #include "mesh_path.h"
+#include "gnunet-service-mesh_peer.h"
+
+/**
+ * @brief Destroy a path after some time has past.
+ *
+ * If the path is returned from DHT again after a while, try again.
+ *
+ * @param cls Closure (path to destroy).
+ * @param tc Task context.
+ */
+static void
+path_destroy_delayed (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct MeshPeerPath *path = cls;
+  struct MeshPeer *peer;
+
+  path->path_delete = GNUNET_SCHEDULER_NO_TASK;
+  peer = GMP_get_short (path->peers[path->length - 1]);
+  GMP_remove_path (peer, path);
+}
 
 
 /**
@@ -76,15 +96,15 @@ path_invert (struct MeshPeerPath *path)
  * @param path The path to duplicate.
  */
 struct MeshPeerPath *
-path_duplicate (struct MeshPeerPath *path)
+path_duplicate (const struct MeshPeerPath *path)
 {
   struct MeshPeerPath *aux;
   unsigned int i;
 
   aux = path_new (path->length);
   memcpy (aux->peers, path->peers, path->length * sizeof (GNUNET_PEER_Id));
-  for (i = 0; i < path->length; i++)
-    GNUNET_PEER_change_rc (path->peers[i], 1);
+  for (i = 0; i < aux->length; i++)
+    GNUNET_PEER_change_rc (aux->peers[i], 1);
   return aux;
 }
 
@@ -106,6 +126,41 @@ path_get_length (struct MeshPeerPath *path)
 }
 
 
+
+/**
+ * Mark path as invalid: keep it aroud for a while to avoid trying it in a loop.
+ *
+ * DHT_get sometimes returns bad cached results, for instance, on a locally
+ * cached result where the PUT followed a path that is no longer current.
+ *
+ * @param p Path to invalidate.
+ */
+void
+path_invalidate (struct MeshPeerPath *p)
+{
+  if (GNUNET_SCHEDULER_NO_TASK != p->path_delete)
+    return;
+
+  p->path_delete = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
+                                                 &path_destroy_delayed, p);
+}
+
+
+/**
+ * Test if a path is valid (or at least not known to be invalid).
+ *
+ * @param path Path to test.
+ *
+ * @return #GNUNET_YES If the path is valid or unknown,
+ *         #GNUNET_NO If the path is known to be invalid.
+ */
+int
+path_is_valid (const struct MeshPeerPath *path)
+{
+  return (GNUNET_SCHEDULER_NO_TASK == path->path_delete);
+}
+
+
 /**
  * Destroy the path and free any allocated resources linked to it
  *
@@ -118,8 +173,23 @@ path_destroy (struct MeshPeerPath *p)
 {
   if (NULL == p)
     return GNUNET_OK;
+
   GNUNET_PEER_decrement_rcs (p->peers, p->length);
   GNUNET_free_non_null (p->peers);
+  if (GNUNET_SCHEDULER_NO_TASK != p->path_delete)
+    GNUNET_SCHEDULER_cancel (p->path_delete);
   GNUNET_free (p);
   return GNUNET_OK;
 }
+
+void
+path_debug (struct MeshPeerPath *p)
+{
+  unsigned int i;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH:\n");
+  for (i = 0; i < p->length; i++)
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  %s\n",
+                GNUNET_i2s (GNUNET_PEER_resolve2 (p->peers[i])));
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "END\n");
+}