diff options
author | Bart Polot <bart@net.in.tum.de> | 2011-09-23 10:17:48 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2011-09-23 10:17:48 +0000 |
commit | a44aa9923dd14613116939e659817f985cb89ef5 (patch) | |
tree | a1ceb1826bf2dbc02db9ddb2bc0f12a9d03a4d89 /src/mesh/mesh_tunnel_tree.c | |
parent | 17e4c95ee4c555db7ab3ab9c57412b7866ee5411 (diff) | |
download | gnunet-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.c | 245 |
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 | ||
31 | static void | 31 | /** |
32 | debug_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 | */ | ||
38 | struct MeshPeerPath * | ||
39 | path_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 | ||
59 | void | 43 | p = GNUNET_malloc (sizeof(struct MeshPeerPath)); |
60 | tree_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 | */ | ||
94 | int | ||
95 | path_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 | */ | ||
136 | int | ||
137 | path_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 | */ | ||
156 | static struct MeshTunnelTreeNode * | ||
157 | tree_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 | |||
174 | static void | ||
175 | tree_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 | */ | ||
206 | static void | ||
207 | tree_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 | */ | ||
237 | struct MeshTunnelTree * | ||
238 | tree_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 | */ |
192 | void | 285 | static void |
193 | tree_mark_peers_disconnected (struct MeshTunnelTree *tree, | 286 | tree_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 | */ |
228 | void | 321 | static void |
229 | tree_update_first_hops (struct MeshTunnelTree *tree, | 322 | tree_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 | */ | ||
507 | struct MeshTunnelTreeNode * | ||
508 | tree_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 | */ |
530 | void | 596 | void |
531 | tree_node_destroy (struct MeshTunnelTreeNode *parent) | 597 | tree_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 | } |