- cancel SYNACK retry task when forced to SYNACK by an incoming SYN
[oweals/gnunet.git] / src / mesh / mesh_path.c
index 536fb0da6316a0b0c35f97dc1e1534d31312d91a..c68a2ea7813629f8d28961594a9b2d62fb13c066 100644 (file)
 
 #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);
+}
 
 
 /**
@@ -40,7 +60,7 @@ path_new (unsigned int length)
 {
   struct MeshPeerPath *p;
 
-  p = GNUNET_malloc (sizeof (struct MeshPeerPath));
+  p = GNUNET_new (struct MeshPeerPath);
   if (length > 0)
   {
     p->length = length;
@@ -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,41 @@ 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;
 }
+
+char *
+path_2s (struct MeshPeerPath *p)
+{
+  char *s;
+  char *old;
+  unsigned int i;
+
+  s = old = NULL;
+  for (i = 0; i < p->length; i++)
+  {
+    GNUNET_asprintf (&s, "%s %s",
+                     old, GNUNET_i2s (GNUNET_PEER_resolve2 (p->peers[i])));
+    GNUNET_free_non_null (old);
+    old = s;
+  }
+  return s;
+}
+
+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");
+}