aboutsummaryrefslogtreecommitdiff
path: root/src/mesh/mesh_tunnel_tree.c
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-09-23 10:17:48 +0000
committerBart Polot <bart@net.in.tum.de>2011-09-23 10:17:48 +0000
commita44aa9923dd14613116939e659817f985cb89ef5 (patch)
treea1ceb1826bf2dbc02db9ddb2bc0f12a9d03a4d89 /src/mesh/mesh_tunnel_tree.c
parent17e4c95ee4c555db7ab3ab9c57412b7866ee5411 (diff)
downloadgnunet-a44aa9923dd14613116939e659817f985cb89ef5.tar.gz
gnunet-a44aa9923dd14613116939e659817f985cb89ef5.zip
Fixed bugs and completed API
Diffstat (limited to 'src/mesh/mesh_tunnel_tree.c')
-rw-r--r--src/mesh/mesh_tunnel_tree.c245
1 files changed, 148 insertions, 97 deletions
diff --git a/src/mesh/mesh_tunnel_tree.c b/src/mesh/mesh_tunnel_tree.c
index 766960dd4..748683a34 100644
--- a/src/mesh/mesh_tunnel_tree.c
+++ b/src/mesh/mesh_tunnel_tree.c
@@ -28,42 +28,28 @@
28#include "mesh_tunnel_tree.h" 28#include "mesh_tunnel_tree.h"
29 29
30 30
31static void 31/**
32debug_node(struct MeshTunnelTreeNode *n, uint16_t level) 32 * Create a new path
33 *
34 * @param lenght How many hops will the path have.
35 *
36 * @return A newly allocated path with a peer array of the specified length.
37 */
38struct MeshPeerPath *
39path_new (unsigned int length)
33{ 40{
34 struct MeshTunnelTreeNode *c; 41 struct MeshPeerPath *p;
35 uint16_t i;
36
37 for (i = 0; i < level; i++)
38 fprintf(stderr, " ");
39 if (n->status == MESH_PEER_READY)
40 fprintf(stderr, "#");
41 if (n->status == MESH_PEER_SEARCHING)
42 fprintf(stderr, "+");
43 if (n->status == MESH_PEER_RELAY)
44 fprintf(stderr, "-");
45 if (n->status == MESH_PEER_RECONNECTING)
46 fprintf(stderr, "*");
47
48 fprintf(stderr, "%u [%p] ", n->peer, n);
49 if (NULL != n->parent)
50 fprintf(stderr, "(-> %u)\n", n->parent->peer);
51 else
52 fprintf(stderr, "(root)\n");
53 for (c = n->children_head; NULL != c; c = c->next)
54 debug_node(c, level + 1);
55}
56
57
58 42
59void 43 p = GNUNET_malloc (sizeof(struct MeshPeerPath));
60tree_debug(struct MeshTunnelTree *t) 44 if (length > 0)
61{ 45 {
62 debug_node(t->root, 0); 46 p->length = length;
47 p->peers = GNUNET_malloc (length * sizeof(GNUNET_PEER_Id));
48 }
49 return p;
63} 50}
64 51
65 52
66
67/** 53/**
68 * Invert the path 54 * Invert the path
69 * 55 *
@@ -84,22 +70,6 @@ path_invert (struct MeshPeerPath *path)
84} 70}
85 71
86 72
87/**
88 * Destroy the path and free any allocated resources linked to it
89 *
90 * @param p the path to destroy
91 *
92 * @return GNUNET_OK on success
93 */
94int
95path_destroy (struct MeshPeerPath *p)
96{
97 GNUNET_PEER_decrement_rcs (p->peers, p->length);
98 GNUNET_free (p->peers);
99 GNUNET_free (p);
100 return GNUNET_OK;
101}
102
103 73
104/** 74/**
105 * Find the first peer whom to send a packet to go down this path 75 * Find the first peer whom to send a packet to go down this path
@@ -157,6 +127,129 @@ path_get_cost (struct MeshTunnelTree *t, struct MeshPeerPath *path)
157 127
158 128
159/** 129/**
130 * Destroy the path and free any allocated resources linked to it
131 *
132 * @param p the path to destroy
133 *
134 * @return GNUNET_OK on success
135 */
136int
137path_destroy (struct MeshPeerPath *p)
138{
139 GNUNET_PEER_decrement_rcs (p->peers, p->length);
140 GNUNET_free (p->peers);
141 GNUNET_free (p);
142 return GNUNET_OK;
143}
144
145
146
147/**
148 * Allocates and initializes a new node.
149 * Sets ID and parent of the new node and inserts it in the DLL of the parent
150 *
151 * @param parent Node that will be the parent from the new node, NULL for root
152 * @param peer Short Id of the new node
153 *
154 * @return Newly allocated node
155 */
156static struct MeshTunnelTreeNode *
157tree_node_new(struct MeshTunnelTreeNode *parent, GNUNET_PEER_Id peer)
158{
159 struct MeshTunnelTreeNode *node;
160
161 node = GNUNET_malloc(sizeof(struct MeshTunnelTreeNode));
162 node->peer = peer;
163 GNUNET_PEER_change_rc(peer, 1);
164 node->parent = parent;
165 if (NULL != parent)
166 GNUNET_CONTAINER_DLL_insert(parent->children_head,
167 parent->children_tail,
168 node);
169
170 return node;
171}
172
173
174static void
175tree_node_debug(struct MeshTunnelTreeNode *n, uint16_t level)
176{
177 struct MeshTunnelTreeNode *c;
178 uint16_t i;
179
180 for (i = 0; i < level; i++)
181 fprintf(stderr, " ");
182 if (n->status == MESH_PEER_READY)
183 fprintf(stderr, "#");
184 if (n->status == MESH_PEER_SEARCHING)
185 fprintf(stderr, "+");
186 if (n->status == MESH_PEER_RELAY)
187 fprintf(stderr, "-");
188 if (n->status == MESH_PEER_RECONNECTING)
189 fprintf(stderr, "*");
190
191 fprintf(stderr, "%u [%p] ", n->peer, n);
192 if (NULL != n->parent)
193 fprintf(stderr, "(-> %u)\n", n->parent->peer);
194 else
195 fprintf(stderr, "(root)\n");
196 for (c = n->children_head; NULL != c; c = c->next)
197 tree_node_debug(c, level + 1);
198}
199
200
201/**
202 * Destroys and frees the node and all children
203 *
204 * @param n Parent node to be destroyed
205 */
206static void
207tree_node_destroy (struct MeshTunnelTreeNode *parent)
208{
209 struct MeshTunnelTreeNode *n;
210 struct MeshTunnelTreeNode *next;
211
212 n = parent->children_head;
213 while (NULL != n)
214 {
215 next = n->next;
216 tree_node_destroy(n);
217 n = next;
218 }
219 GNUNET_PEER_change_rc(parent->peer, -1);
220 if (NULL != parent->parent)
221 GNUNET_CONTAINER_DLL_remove(parent->parent->children_head,
222 parent->parent->children_tail,
223 parent);
224 GNUNET_free(parent);
225}
226
227
228
229/**
230 * Create a new tunnel tree associated to a tunnel
231 *
232 * @param t Tunnel this tree will represent
233 * @param peer A short peer id of the root of the tree
234 *
235 * @return A newly allocated and initialized tunnel tree
236 */
237struct MeshTunnelTree *
238tree_new (struct MeshTunnel *t, GNUNET_PEER_Id peer)
239{
240 struct MeshTunnelTree *tree;
241
242 tree = GNUNET_malloc(sizeof (struct MeshTunnelTree));
243 tree->first_hops = GNUNET_CONTAINER_multihashmap_create(32);
244 tree->root = tree_node_new(NULL, peer);
245 tree->t = t;
246 tree->root->t = t;
247
248 return tree;
249}
250
251
252/**
160 * Recursively find the given peer in the tree. 253 * Recursively find the given peer in the tree.
161 * 254 *
162 * @param t Tunnel where to look for the peer. 255 * @param t Tunnel where to look for the peer.
@@ -189,7 +282,7 @@ tree_find_peer (struct MeshTunnelTreeNode *parent, GNUNET_PEER_Id peer_id)
189 * @param parent Node to be clean, potentially with children 282 * @param parent Node to be clean, potentially with children
190 * @param cb Callback to use to notify about disconnected peers. 283 * @param cb Callback to use to notify about disconnected peers.
191 */ 284 */
192void 285static void
193tree_mark_peers_disconnected (struct MeshTunnelTree *tree, 286tree_mark_peers_disconnected (struct MeshTunnelTree *tree,
194 struct MeshTunnelTreeNode *parent, 287 struct MeshTunnelTreeNode *parent,
195 MeshNodeDisconnectCB cb) 288 MeshNodeDisconnectCB cb)
@@ -225,7 +318,7 @@ tree_mark_peers_disconnected (struct MeshTunnelTree *tree,
225 * @param hop If known, ID of the first hop. 318 * @param hop If known, ID of the first hop.
226 * If not known, NULL to find out and pass on children. 319 * If not known, NULL to find out and pass on children.
227 */ 320 */
228void 321static void
229tree_update_first_hops (struct MeshTunnelTree *tree, 322tree_update_first_hops (struct MeshTunnelTree *tree,
230 struct MeshTunnelTreeNode *parent, 323 struct MeshTunnelTreeNode *parent,
231 struct GNUNET_PeerIdentity *hop) 324 struct GNUNET_PeerIdentity *hop)
@@ -343,7 +436,7 @@ tree_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer)
343 GNUNET_PEER_Id myid = t->me->peer; 436 GNUNET_PEER_Id myid = t->me->peer;
344 437
345 n = tree_find_peer(t->me, peer); 438 n = tree_find_peer(t->me, peer);
346 p = GNUNET_malloc(sizeof(struct MeshPeerPath)); 439 p = path_new(0);
347 440
348 /* Building the path (inverted!) */ 441 /* Building the path (inverted!) */
349 while (n->peer != myid) 442 while (n->peer != myid)
@@ -496,56 +589,14 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p,
496 589
497 590
498/** 591/**
499 * Allocates and initializes a new node. 592 * Print the tree on stderr
500 * Sets ID and parent of the new node and inserts it in the DLL of the parent
501 *
502 * @param parent Node that will be the parent from the new node, NULL for root
503 * @param id Short Id of the new node
504 * 593 *
505 * @return Newly allocated node 594 * @param t The tree
506 */
507struct MeshTunnelTreeNode *
508tree_node_new(struct MeshTunnelTreeNode *parent, GNUNET_PEER_Id id)
509{
510 struct MeshTunnelTreeNode *node;
511
512 node = GNUNET_malloc(sizeof(struct MeshTunnelTreeNode));
513 node->peer = id;
514 GNUNET_PEER_change_rc(id, 1);
515 node->parent = parent;
516 if (NULL != parent)
517 GNUNET_CONTAINER_DLL_insert(parent->children_head,
518 parent->children_tail,
519 node);
520
521 return node;
522}
523
524
525/**
526 * Destroys and frees the node and all children
527 *
528 * @param n Parent node to be destroyed
529 */ 595 */
530void 596void
531tree_node_destroy (struct MeshTunnelTreeNode *parent) 597tree_debug(struct MeshTunnelTree *t)
532{ 598{
533 struct MeshTunnelTreeNode *n; 599 tree_node_debug(t->root, 0);
534 struct MeshTunnelTreeNode *next;
535
536 n = parent->children_head;
537 while (NULL != n)
538 {
539 next = n->next;
540 tree_node_destroy(n);
541 n = next;
542 }
543 GNUNET_PEER_change_rc(parent->peer, -1);
544 if (NULL != parent->parent)
545 GNUNET_CONTAINER_DLL_remove(parent->parent->children_head,
546 parent->parent->children_tail,
547 parent);
548 GNUNET_free(parent);
549} 600}
550 601
551 602
@@ -578,4 +629,4 @@ tree_destroy (struct MeshTunnelTree *t)
578 GNUNET_CONTAINER_multihashmap_iterate(t->first_hops, &iterate_free, NULL); 629 GNUNET_CONTAINER_multihashmap_iterate(t->first_hops, &iterate_free, NULL);
579 GNUNET_CONTAINER_multihashmap_destroy(t->first_hops); 630 GNUNET_CONTAINER_multihashmap_destroy(t->first_hops);
580 GNUNET_free(t); 631 GNUNET_free(t);
581} \ No newline at end of file 632}