aboutsummaryrefslogtreecommitdiff
path: root/src/mesh/mesh_tunnel_tree.c
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-09-20 17:22:58 +0000
committerBart Polot <bart@net.in.tum.de>2011-09-20 17:22:58 +0000
commit62cf5f2f6da72d38adac69e239400edd501ef9cb (patch)
treed60c7b9e70328628d81ad2176a5cc9f96c441c37 /src/mesh/mesh_tunnel_tree.c
parent73e047c74d351257f8b6cf0815a56ff650520cc1 (diff)
downloadgnunet-62cf5f2f6da72d38adac69e239400edd501ef9cb.tar.gz
gnunet-62cf5f2f6da72d38adac69e239400edd501ef9cb.zip
Cleaned and fixed refactoring to improve separation, only 3 structs are now shared
Diffstat (limited to 'src/mesh/mesh_tunnel_tree.c')
-rw-r--r--src/mesh/mesh_tunnel_tree.c234
1 files changed, 56 insertions, 178 deletions
diff --git a/src/mesh/mesh_tunnel_tree.c b/src/mesh/mesh_tunnel_tree.c
index 10298ca5a..e838cefc1 100644
--- a/src/mesh/mesh_tunnel_tree.c
+++ b/src/mesh/mesh_tunnel_tree.c
@@ -28,10 +28,6 @@
28#include "mesh_tunnel_tree.h" 28#include "mesh_tunnel_tree.h"
29 29
30 30
31extern GNUNET_PEER_Id myid;
32extern struct GNUNET_PeerIdentity my_full_id;
33
34
35/** 31/**
36 * Invert the path 32 * Invert the path
37 * 33 *
@@ -72,19 +68,19 @@ path_destroy (struct MeshPeerPath *p)
72/** 68/**
73 * Find the first peer whom to send a packet to go down this path 69 * Find the first peer whom to send a packet to go down this path
74 * 70 *
75 * @param t The tunnel to use 71 * @param t The tunnel tree to use
76 * @param peer The peerinfo of the peer we are trying to reach 72 * @param peer The peerinfo of the peer we are trying to reach
77 * 73 *
78 * @return peerinfo of the peer who is the first hop in the tunnel 74 * @return peerinfo of the peer who is the first hop in the tunnel
79 * NULL on error 75 * NULL on error
80 */ 76 */
81struct GNUNET_PeerIdentity * 77struct GNUNET_PeerIdentity *
82path_get_first_hop (struct MeshTunnel *t, struct MeshPeerInfo *peer) 78path_get_first_hop (struct MeshTunnelTree *t, GNUNET_PEER_Id peer)
83{ 79{
84 struct GNUNET_PeerIdentity id; 80 struct GNUNET_PeerIdentity id;
85 81
86 GNUNET_PEER_resolve (peer->id, &id); 82 GNUNET_PEER_resolve (peer, &id);
87 return GNUNET_CONTAINER_multihashmap_get (t->tree->first_hops, 83 return GNUNET_CONTAINER_multihashmap_get (t->first_hops,
88 &id.hashPubKey); 84 &id.hashPubKey);
89} 85}
90 86
@@ -109,7 +105,7 @@ path_get_length (struct MeshPeerPath *path)
109/** 105/**
110 * Get the cost of the path relative to the already built tunnel tree 106 * Get the cost of the path relative to the already built tunnel tree
111 * 107 *
112 * @param t The tunnel to which compare 108 * @param t The tunnel tree to which compare
113 * @param path The individual path to reach a peer 109 * @param path The individual path to reach a peer
114 * 110 *
115 * @return Number of hops to reach destination, UINT_MAX in case the peer is not 111 * @return Number of hops to reach destination, UINT_MAX in case the peer is not
@@ -118,97 +114,13 @@ path_get_length (struct MeshPeerPath *path)
118 * TODO: remove dummy implementation, look into the tunnel tree 114 * TODO: remove dummy implementation, look into the tunnel tree
119 */ 115 */
120unsigned int 116unsigned int
121path_get_cost (struct MeshTunnel *t, struct MeshPeerPath *path) 117path_get_cost (struct MeshTunnelTree *t, struct MeshPeerPath *path)
122{ 118{
123 return path_get_length (path); 119 return path_get_length (path);
124} 120}
125 121
126 122
127/** 123/**
128 * Add the path to the peer and update the path used to reach it in case this
129 * is the shortest.
130 *
131 * @param peer_info Destination peer to add the path to.
132 * @param path New path to add. Last peer must be the peer in arg 1.
133 * Path will be either used of freed if already known.
134 *
135 * TODO: trim the part from origin to us? Add it as path to origin?
136 */
137void
138path_add_to_peer (struct MeshPeerInfo *peer_info, struct MeshPeerPath *path)
139{
140 struct MeshPeerPath *aux;
141 unsigned int l;
142 unsigned int l2;
143
144 if (NULL == peer_info || NULL == path)
145 {
146 GNUNET_break (0);
147 return;
148 }
149
150 l = path_get_length (path);
151
152 for (aux = peer_info->path_head; aux != NULL; aux = aux->next)
153 {
154 l2 = path_get_length (aux);
155 if (l2 > l)
156 {
157 GNUNET_CONTAINER_DLL_insert_before (peer_info->path_head,
158 peer_info->path_tail, aux, path);
159 }
160 else
161 {
162 if (l2 == l && memcmp(path->peers, aux->peers, l) == 0)
163 {
164 path_destroy(path);
165 return;
166 }
167 }
168 }
169 GNUNET_CONTAINER_DLL_insert_tail (peer_info->path_head, peer_info->path_tail,
170 path);
171 return;
172}
173
174
175/**
176 * Send keepalive packets for a peer
177 *
178 * @param cls unused
179 * @param tc unused
180 *
181 * FIXME path
182 */
183void
184path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
185{
186 struct MeshTunnel *t = cls;
187
188// struct GNUNET_PeerIdentity id;
189
190 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
191 {
192 return;
193 }
194 /* FIXME implement multicast keepalive. Just an empty multicast packet? */
195// GNUNET_PEER_resolve (path_get_first_hop (path->t, path->peer)->id, &id);
196// GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
197// GNUNET_TIME_UNIT_FOREVER_REL, &id,
198// sizeof (struct GNUNET_MESH_ManipulatePath)
199// +
200// (path->path->length *
201// sizeof (struct GNUNET_PeerIdentity)),
202// &send_core_create_path,
203// t);
204 t->path_refresh_task =
205 GNUNET_SCHEDULER_add_delayed (t->tree->refresh, &path_refresh, t);
206 return;
207}
208
209
210
211/**
212 * Recursively find the given peer in the tree. 124 * Recursively find the given peer in the tree.
213 * 125 *
214 * @param t Tunnel where to look for the peer. 126 * @param t Tunnel where to look for the peer.
@@ -216,10 +128,10 @@ path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
216 * 128 *
217 * @return Pointer to the node of the peer. NULL if not found. 129 * @return Pointer to the node of the peer. NULL if not found.
218 */ 130 */
219struct MeshTunnelPathNode * 131struct MeshTunnelTreeNode *
220tunnel_find_peer (struct MeshTunnelPathNode *root, GNUNET_PEER_Id peer_id) 132tunnel_find_peer (struct MeshTunnelTreeNode *root, GNUNET_PEER_Id peer_id)
221{ 133{
222 struct MeshTunnelPathNode *n; 134 struct MeshTunnelTreeNode *n;
223 unsigned int i; 135 unsigned int i;
224 136
225 if (root->peer == peer_id) 137 if (root->peer == peer_id)
@@ -238,30 +150,34 @@ tunnel_find_peer (struct MeshTunnelPathNode *root, GNUNET_PEER_Id peer_id)
238 * Recusively mark peer and children as disconnected, notify client 150 * Recusively mark peer and children as disconnected, notify client
239 * 151 *
240 * @param parent Node to be clean, potentially with children 152 * @param parent Node to be clean, potentially with children
241 * @param nc Notification context to use to alert the client 153 * @param cb Callback to use to notify about disconnected peers.
242 */ 154 */
243void 155void
244tunnel_mark_peers_disconnected (struct MeshTunnelPathNode *parent, 156tunnel_mark_peers_disconnected (struct MeshTunnelTreeNode *parent,
245 struct GNUNET_SERVER_NotificationContext *nc) 157 MeshNodeDisconnectCB cb)
246{ 158{
247 struct GNUNET_MESH_PeerControl msg;
248 unsigned int i; 159 unsigned int i;
249 160
161 if (MESH_PEER_READY == parent->status)
162 {
163 cb (parent);
164 }
250 parent->status = MESH_PEER_RECONNECTING; 165 parent->status = MESH_PEER_RECONNECTING;
251 for (i = 0; i < parent->nchildren; i++) 166 for (i = 0; i < parent->nchildren; i++)
252 { 167 {
253 tunnel_mark_peers_disconnected (&parent->children[i], nc); 168 tunnel_mark_peers_disconnected (&parent->children[i], cb);
254 } 169 }
255 if (NULL == parent->t->client) 170// struct GNUNET_MESH_PeerControl msg;
256 return; 171// if (NULL == parent->t->client)
257 msg.header.size = htons (sizeof (msg)); 172// return;
258 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL); 173// msg.header.size = htons (sizeof (msg));
259 msg.tunnel_id = htonl (parent->t->local_tid); 174// msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL);
260 GNUNET_PEER_resolve (parent->peer, &msg.peer); 175// msg.tunnel_id = htonl (parent->t->local_tid);
261 if (NULL == nc) 176// GNUNET_PEER_resolve (parent->peer, &msg.peer);
262 return; 177// if (NULL == nc)
263 GNUNET_SERVER_notification_context_unicast (nc, parent->t->client->handle, 178// return;
264 &msg.header, GNUNET_NO); 179// GNUNET_SERVER_notification_context_unicast (nc, parent->t->client->handle,
180// &msg.header, GNUNET_NO);
265} 181}
266 182
267 183
@@ -272,23 +188,23 @@ tunnel_mark_peers_disconnected (struct MeshTunnelPathNode *parent,
272 * The destination peer is NOT destroyed, it is returned in order to either set 188 * The destination peer is NOT destroyed, it is returned in order to either set
273 * a new path to it or destroy it explicitly, taking care of it's child nodes. 189 * a new path to it or destroy it explicitly, taking care of it's child nodes.
274 * 190 *
275 * @param t Tunnel where to delete the path from. 191 * @param t Tunnel tree where to delete the path from.
276 * @param peer Destination peer whose path we want to remove. 192 * @param peer Destination peer whose path we want to remove.
277 * @param nc Notification context to alert the client of disconnected peers. 193 * @param cb Callback to use to notify about disconnected peers.
278 * 194 *
279 * @return pointer to the pathless node, NULL on error 195 * @return pointer to the pathless node, NULL on error
280 */ 196 */
281struct MeshTunnelPathNode * 197struct MeshTunnelTreeNode *
282tunnel_del_path (struct MeshTunnel *t, GNUNET_PEER_Id peer_id, 198tunnel_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id,
283 struct GNUNET_SERVER_NotificationContext *nc) 199 MeshNodeDisconnectCB cb)
284{ 200{
285 struct MeshTunnelPathNode *parent; 201 struct MeshTunnelTreeNode *parent;
286 struct MeshTunnelPathNode *node; 202 struct MeshTunnelTreeNode *node;
287 struct MeshTunnelPathNode *n; 203 struct MeshTunnelTreeNode *n;
288 204
289 if (peer_id == t->tree->root->peer) 205 if (peer_id == t->root->peer)
290 return NULL; 206 return NULL;
291 node = n = tunnel_find_peer (t->tree->me, peer_id); 207 node = n = tunnel_find_peer (t->me, peer_id);
292 if (NULL == n) 208 if (NULL == n)
293 return NULL; 209 return NULL;
294 parent = n->parent; 210 parent = n->parent;
@@ -306,7 +222,7 @@ tunnel_del_path (struct MeshTunnel *t, GNUNET_PEER_Id peer_id,
306 parent->nchildren--; 222 parent->nchildren--;
307 parent->children = GNUNET_realloc (parent->children, parent->nchildren); 223 parent->children = GNUNET_realloc (parent->children, parent->nchildren);
308 224
309 tunnel_mark_peers_disconnected (node, nc); 225 tunnel_mark_peers_disconnected (node, cb);
310 226
311 return node; 227 return node;
312} 228}
@@ -323,13 +239,13 @@ tunnel_del_path (struct MeshTunnel *t, GNUNET_PEER_Id peer_id,
323 * Path must be destroyed afterwards. 239 * Path must be destroyed afterwards.
324 */ 240 */
325struct MeshPeerPath * 241struct MeshPeerPath *
326tunnel_get_path_to_peer(struct MeshTunnel *t, struct MeshPeerInfo *peer_info) 242tunnel_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer)
327{ 243{
328 struct MeshTunnelPathNode *n; 244 struct MeshTunnelTreeNode *n;
329 struct MeshPeerPath *p; 245 struct MeshPeerPath *p;
330 GNUNET_PEER_Id myid = t->tree->me->peer; 246 GNUNET_PEER_Id myid = t->me->peer;
331 247
332 n = tunnel_find_peer(t->tree->me, peer_info->id); 248 n = tunnel_find_peer(t->me, peer);
333 p = GNUNET_malloc(sizeof(struct MeshPeerPath)); 249 p = GNUNET_malloc(sizeof(struct MeshPeerPath));
334 250
335 /* Building the path (inverted!) */ 251 /* Building the path (inverted!) */
@@ -354,8 +270,7 @@ tunnel_get_path_to_peer(struct MeshTunnel *t, struct MeshPeerInfo *peer_info)
354 * 270 *
355 * @param t Tunnel where to add the new path. 271 * @param t Tunnel where to add the new path.
356 * @param p Path to be integrated. 272 * @param p Path to be integrated.
357 * @param nc Notification context to alert clients of peers 273 * @param cb Callback to use to notify about peers temporarily disconnecting
358 * temporarily disconnected
359 * 274 *
360 * @return GNUNET_OK in case of success. 275 * @return GNUNET_OK in case of success.
361 * GNUNET_SYSERR in case of error. 276 * GNUNET_SYSERR in case of error.
@@ -365,20 +280,21 @@ tunnel_get_path_to_peer(struct MeshTunnel *t, struct MeshPeerInfo *peer_info)
365 * - do not disconnect peers until new path is created & connected 280 * - do not disconnect peers until new path is created & connected
366 */ 281 */
367int 282int
368tunnel_add_path (struct MeshTunnel *t, const struct MeshPeerPath *p) 283tunnel_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p,
284 MeshNodeDisconnectCB cb)
369{ 285{
370 struct MeshTunnelPathNode *parent; 286 struct MeshTunnelTreeNode *parent;
371 struct MeshTunnelPathNode *oldnode; 287 struct MeshTunnelTreeNode *oldnode;
372 struct MeshTunnelPathNode *n; 288 struct MeshTunnelTreeNode *n;
373 struct GNUNET_PeerIdentity id; 289 struct GNUNET_PeerIdentity id;
374 struct GNUNET_PeerIdentity *hop; 290 struct GNUNET_PeerIdentity *hop;
375 GNUNET_PEER_Id myid = t->tree->me->peer; 291 GNUNET_PEER_Id myid = t->me->peer;
376 int me; 292 int me;
377 unsigned int i; 293 unsigned int i;
378 unsigned int j; 294 unsigned int j;
379 295
380 GNUNET_assert(0 != p->length); 296 GNUNET_assert(0 != p->length);
381 n = t->tree->root; 297 n = t->root;
382 if (n->peer != p->peers[0]) 298 if (n->peer != p->peers[0])
383 { 299 {
384 GNUNET_break (0); 300 GNUNET_break (0);
@@ -386,7 +302,7 @@ tunnel_add_path (struct MeshTunnel *t, const struct MeshPeerPath *p)
386 } 302 }
387 if (1 == p->length) 303 if (1 == p->length)
388 return GNUNET_OK; 304 return GNUNET_OK;
389 oldnode = tunnel_del_path (t, p->peers[p->length - 1], NULL); 305 oldnode = tunnel_del_path (t, p->peers[p->length - 1], cb);
390 /* Look for the first node that is not already present in the tree 306 /* Look for the first node that is not already present in the tree
391 * 307 *
392 * Assuming that the tree is somewhat balanced, O(log n * log N). 308 * Assuming that the tree is somewhat balanced, O(log n * log N).
@@ -423,17 +339,17 @@ tunnel_add_path (struct MeshTunnel *t, const struct MeshPeerPath *p)
423 parent->nchildren++; 339 parent->nchildren++;
424 parent->children = GNUNET_realloc (parent->children, 340 parent->children = GNUNET_realloc (parent->children,
425 parent->nchildren * 341 parent->nchildren *
426 sizeof(struct MeshTunnelPathNode)); 342 sizeof(struct MeshTunnelTreeNode));
427 n = &parent->children[parent->nchildren - 1]; 343 n = &parent->children[parent->nchildren - 1];
428 if (i == p->length - 1 && NULL != oldnode) 344 if (i == p->length - 1 && NULL != oldnode)
429 { 345 {
430 /* Assignation and free can be misleading, using explicit mempcy */ 346 /* Assignation and free can be misleading, using explicit mempcy */
431 memcpy (n, oldnode, sizeof (struct MeshTunnelPathNode)); 347 memcpy (n, oldnode, sizeof (struct MeshTunnelTreeNode));
432 GNUNET_free (oldnode); 348 GNUNET_free (oldnode);
433 } 349 }
434 else 350 else
435 { 351 {
436 n->t = t; 352 n->t = t->t;
437 n->status = MESH_PEER_RELAY; 353 n->status = MESH_PEER_RELAY;
438 n->peer = p->peers[i]; 354 n->peer = p->peers[i];
439 } 355 }
@@ -448,47 +364,9 @@ tunnel_add_path (struct MeshTunnel *t, const struct MeshPeerPath *p)
448 GNUNET_PEER_resolve (p->peers[p->length - 1], &id); 364 GNUNET_PEER_resolve (p->peers[p->length - 1], &id);
449 hop = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); 365 hop = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
450 GNUNET_PEER_resolve (p->peers[me + 1], hop); 366 GNUNET_PEER_resolve (p->peers[me + 1], hop);
451 GNUNET_CONTAINER_multihashmap_put (t->tree->first_hops, &id.hashPubKey, 367 GNUNET_CONTAINER_multihashmap_put (t->first_hops, &id.hashPubKey,
452 hop, 368 hop,
453 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 369 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
454 } 370 }
455 return GNUNET_OK; 371 return GNUNET_OK;
456} 372}
457
458
459/**
460 * Add a peer to a tunnel, accomodating paths accordingly and initializing all
461 * needed rescources.
462 *
463 * @param t Tunnel we want to add a new peer to
464 * @param peer PeerInfo of the peer being added
465 *
466 */
467void
468tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer)
469{
470 struct MeshPeerPath *p;
471 struct MeshPeerPath *best_p;
472 unsigned int best_cost;
473 unsigned int cost;
474
475 GNUNET_array_append (peer->tunnels, peer->ntunnels, t);
476 if (NULL == (p = peer->path_head))
477 return;
478
479 best_p = p;
480 best_cost = UINT_MAX;
481 while (NULL != p)
482 {
483 if ((cost = path_get_cost (t, p)) < best_cost)
484 {
485 best_cost = cost;
486 best_p = p;
487 }
488 p = p->next;
489 }
490 tunnel_add_path (t, best_p);
491 if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task)
492 t->path_refresh_task =
493 GNUNET_SCHEDULER_add_delayed (t->tree->refresh, &path_refresh, t);
494}