2 This file is part of GNUnet.
3 (C) 2001 - 2013 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file mesh/mesh_path.c
23 * @brief Path handling functions
24 * @author Bartlomiej Polot
28 #include "mesh_path.h"
29 #include "gnunet-service-mesh_peer.h"
32 * @brief Destroy a path after some time has past.
34 * If the path is returned from DHT again after a while, try again.
36 * @param cls Closure (path to destroy).
37 * @param tc Task context.
40 path_destroy_delayed (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
42 struct MeshPeerPath *path = cls;
43 struct MeshPeer *peer;
45 path->path_delete = GNUNET_SCHEDULER_NO_TASK;
46 peer = GMP_get_short (path->peers[path->length - 1]);
47 GMP_remove_path (peer, path);
54 * @param length How many hops will the path have.
56 * @return A newly allocated path with a peer array of the specified length.
59 path_new (unsigned int length)
61 struct MeshPeerPath *p;
63 p = GNUNET_new (struct MeshPeerPath);
67 p->peers = GNUNET_malloc (length * sizeof (GNUNET_PEER_Id));
76 * @param path the path to invert
79 path_invert (struct MeshPeerPath *path)
84 for (i = 0; i < path->length / 2; i++)
87 path->peers[i] = path->peers[path->length - i - 1];
88 path->peers[path->length - i - 1] = aux;
94 * Duplicate a path, incrementing short peer's rc.
96 * @param path The path to duplicate.
99 path_duplicate (const struct MeshPeerPath *path)
101 struct MeshPeerPath *aux;
104 aux = path_new (path->length);
105 memcpy (aux->peers, path->peers, path->length * sizeof (GNUNET_PEER_Id));
106 for (i = 0; i < aux->length; i++)
107 GNUNET_PEER_change_rc (aux->peers[i], 1);
113 * Get the length of a path.
115 * @param path The path to measure, with the local peer at any point of it.
117 * @return Number of hops to reach destination.
118 * UINT_MAX in case the peer is not in the path.
121 path_get_length (struct MeshPeerPath *path)
131 * Mark path as invalid: keep it aroud for a while to avoid trying it in a loop.
133 * DHT_get sometimes returns bad cached results, for instance, on a locally
134 * cached result where the PUT followed a path that is no longer current.
136 * @param p Path to invalidate.
139 path_invalidate (struct MeshPeerPath *p)
141 if (GNUNET_SCHEDULER_NO_TASK != p->path_delete)
144 p->path_delete = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
145 &path_destroy_delayed, p);
150 * Test if a path is valid (or at least not known to be invalid).
152 * @param path Path to test.
154 * @return #GNUNET_YES If the path is valid or unknown,
155 * #GNUNET_NO If the path is known to be invalid.
158 path_is_valid (const struct MeshPeerPath *path)
160 return (GNUNET_SCHEDULER_NO_TASK == path->path_delete);
165 * Destroy the path and free any allocated resources linked to it
167 * @param p the path to destroy
169 * @return GNUNET_OK on success
172 path_destroy (struct MeshPeerPath *p)
177 GNUNET_PEER_decrement_rcs (p->peers, p->length);
178 GNUNET_free_non_null (p->peers);
179 if (GNUNET_SCHEDULER_NO_TASK != p->path_delete)
180 GNUNET_SCHEDULER_cancel (p->path_delete);
186 path_debug (struct MeshPeerPath *p)
190 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH:\n");
191 for (i = 0; i < p->length; i++)
192 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n",
193 GNUNET_i2s (GNUNET_PEER_resolve2 (p->peers[i])));
194 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "END\n");