diff options
author | Bart Polot <bart@net.in.tum.de> | 2011-09-21 19:51:37 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2011-09-21 19:51:37 +0000 |
commit | 739aec3d1590e7c80d1322608781cf140c0e9f6a (patch) | |
tree | 41cb6387fd9ca8726cddcd320d6ec73b020b575d /src/mesh/mesh_tunnel_tree.c | |
parent | d3efb620d2503fce79fb4772ce6cc5eefde3a740 (diff) | |
download | gnunet-739aec3d1590e7c80d1322608781cf140c0e9f6a.tar.gz gnunet-739aec3d1590e7c80d1322608781cf140c0e9f6a.zip |
Fixed memory leaks
Diffstat (limited to 'src/mesh/mesh_tunnel_tree.c')
-rw-r--r-- | src/mesh/mesh_tunnel_tree.c | 108 |
1 files changed, 67 insertions, 41 deletions
diff --git a/src/mesh/mesh_tunnel_tree.c b/src/mesh/mesh_tunnel_tree.c index 185620125..ef4e4a5a0 100644 --- a/src/mesh/mesh_tunnel_tree.c +++ b/src/mesh/mesh_tunnel_tree.c | |||
@@ -149,24 +149,35 @@ tree_find_peer (struct MeshTunnelTreeNode *root, GNUNET_PEER_Id peer_id) | |||
149 | /** | 149 | /** |
150 | * Recusively mark peer and children as disconnected, notify client | 150 | * Recusively mark peer and children as disconnected, notify client |
151 | * | 151 | * |
152 | * @param tree Tree this node belongs to | ||
152 | * @param parent Node to be clean, potentially with children | 153 | * @param parent Node to be clean, potentially with children |
153 | * @param cb Callback to use to notify about disconnected peers. | 154 | * @param cb Callback to use to notify about disconnected peers. |
154 | */ | 155 | */ |
155 | void | 156 | void |
156 | tree_mark_peers_disconnected (struct MeshTunnelTreeNode *parent, | 157 | tree_mark_peers_disconnected (struct MeshTunnelTree *tree, |
157 | MeshNodeDisconnectCB cb) | 158 | struct MeshTunnelTreeNode *parent, |
159 | MeshNodeDisconnectCB cb) | ||
158 | { | 160 | { |
161 | struct GNUNET_PeerIdentity *pi; | ||
162 | struct GNUNET_PeerIdentity id; | ||
159 | unsigned int i; | 163 | unsigned int i; |
160 | 164 | ||
165 | for (i = 0; i < parent->nchildren; i++) | ||
166 | { | ||
167 | tree_mark_peers_disconnected (tree, &parent->children[i], cb); | ||
168 | } | ||
161 | if (MESH_PEER_READY == parent->status) | 169 | if (MESH_PEER_READY == parent->status) |
162 | { | 170 | { |
163 | cb (parent); | 171 | cb (parent); |
164 | } | 172 | } |
165 | parent->status = MESH_PEER_RECONNECTING; | 173 | parent->status = MESH_PEER_RECONNECTING; |
166 | for (i = 0; i < parent->nchildren; i++) | 174 | |
167 | { | 175 | /* Remove and free info about first hop */ |
168 | tree_mark_peers_disconnected (&parent->children[i], cb); | 176 | GNUNET_PEER_resolve(parent->peer, &id); |
169 | } | 177 | pi = GNUNET_CONTAINER_multihashmap_get(tree->first_hops, &id.hashPubKey); |
178 | GNUNET_CONTAINER_multihashmap_remove_all(tree->first_hops, &id.hashPubKey); | ||
179 | if (NULL != pi) | ||
180 | GNUNET_free(pi); | ||
170 | // struct GNUNET_MESH_PeerControl msg; | 181 | // struct GNUNET_MESH_PeerControl msg; |
171 | // if (NULL == parent->t->client) | 182 | // if (NULL == parent->t->client) |
172 | // return; | 183 | // return; |
@@ -202,27 +213,31 @@ tree_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id, | |||
202 | struct MeshTunnelTreeNode *node; | 213 | struct MeshTunnelTreeNode *node; |
203 | struct MeshTunnelTreeNode *n; | 214 | struct MeshTunnelTreeNode *n; |
204 | 215 | ||
216 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Deleting path to %u.\n", peer_id); | ||
205 | if (peer_id == t->root->peer) | 217 | if (peer_id == t->root->peer) |
206 | return NULL; | 218 | return NULL; |
207 | node = n = tree_find_peer (t->me, peer_id); | 219 | n = tree_find_peer (t->me, peer_id); |
208 | if (NULL == n) | 220 | if (NULL == n) |
209 | return NULL; | 221 | return NULL; |
222 | node = GNUNET_malloc(sizeof(struct MeshTunnelTreeNode)); | ||
223 | *node = *n; | ||
210 | parent = n->parent; | 224 | parent = n->parent; |
225 | parent->nchildren--; | ||
211 | n->parent = NULL; | 226 | n->parent = NULL; |
212 | while (NULL != parent && MESH_PEER_RELAY == parent->status && | 227 | *n = parent->children[parent->nchildren]; |
213 | 1 == parent->nchildren) | 228 | parent->children = GNUNET_realloc(parent->children, |
229 | parent->nchildren | ||
230 | * sizeof(struct MeshTunnelTreeNode)); | ||
231 | while (t->root != parent && MESH_PEER_RELAY == parent->status && | ||
232 | 0 == parent->nchildren) | ||
214 | { | 233 | { |
215 | n = parent; | 234 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Deleting node %u.\n", parent->peer); |
216 | GNUNET_free (parent->children); | 235 | n = parent->parent; |
217 | parent = parent->parent; | 236 | tree_node_destroy(parent); |
237 | parent = n; | ||
218 | } | 238 | } |
219 | if (NULL == parent) | ||
220 | return node; | ||
221 | *n = parent->children[parent->nchildren - 1]; | ||
222 | parent->nchildren--; | ||
223 | parent->children = GNUNET_realloc (parent->children, parent->nchildren); | ||
224 | 239 | ||
225 | tree_mark_peers_disconnected (node, cb); | 240 | tree_mark_peers_disconnected (t, node, cb); |
226 | 241 | ||
227 | return node; | 242 | return node; |
228 | } | 243 | } |
@@ -294,7 +309,7 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, | |||
294 | unsigned int j; | 309 | unsigned int j; |
295 | 310 | ||
296 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 311 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
297 | "test: Adding path [%u] towards peer %u to peer %u.\n", | 312 | "Adding path [%u] towards peer %u to peer %u.\n", |
298 | p->length, | 313 | p->length, |
299 | p->peers[p->length - 1], | 314 | p->peers[p->length - 1], |
300 | t->me->peer); | 315 | t->me->peer); |
@@ -318,17 +333,13 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, | |||
318 | for (i = 1; i < p->length; i++) | 333 | for (i = 1; i < p->length; i++) |
319 | { | 334 | { |
320 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 335 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
321 | "test: Looking for peer %u.\n", | 336 | "Looking for peer %u.\n", |
322 | p->peers[i]); | 337 | p->peers[i]); |
323 | parent = n; | 338 | parent = n; |
324 | if (p->peers[i] == myid) | 339 | if (p->peers[i] == myid) |
325 | me = i; | 340 | me = i; |
326 | for (j = 0; j < n->nchildren; j++) | 341 | for (j = 0; j < n->nchildren; j++) |
327 | { | 342 | { |
328 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
329 | "test: Child %u. is %u\n", | ||
330 | j, | ||
331 | n->children[j].peer); | ||
332 | if (n->children[j].peer == p->peers[i]) | 343 | if (n->children[j].peer == p->peers[i]) |
333 | { | 344 | { |
334 | n = &n->children[j]; | 345 | n = &n->children[j]; |
@@ -341,7 +352,7 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, | |||
341 | break; | 352 | break; |
342 | } | 353 | } |
343 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 354 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
344 | "test: All childen visited.\n"); | 355 | "All childen visited.\n"); |
345 | if (-1 == me) | 356 | if (-1 == me) |
346 | { | 357 | { |
347 | /* New path deviates from tree before reaching us. What happened? */ | 358 | /* New path deviates from tree before reaching us. What happened? */ |
@@ -352,32 +363,28 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, | |||
352 | while (i < p->length) | 363 | while (i < p->length) |
353 | { | 364 | { |
354 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 365 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
355 | "test: Adding peer %u, to %u.\n", | 366 | "Adding peer %u, to %u.\n", |
356 | p->peers[i], | 367 | p->peers[i], |
357 | parent->peer); | 368 | parent->peer); |
358 | parent->nchildren++; | 369 | parent->nchildren++; |
359 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
360 | "test: realloc %p, %u\n", parent->children, | ||
361 | parent->nchildren * | ||
362 | sizeof(struct MeshTunnelTreeNode)); | ||
363 | parent->children = GNUNET_realloc (parent->children, | 370 | parent->children = GNUNET_realloc (parent->children, |
364 | parent->nchildren * | 371 | parent->nchildren * |
365 | sizeof(struct MeshTunnelTreeNode)); | 372 | sizeof(struct MeshTunnelTreeNode)); |
366 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
367 | "test: done: %p\n", parent->children); | ||
368 | n = &parent->children[parent->nchildren - 1]; | 373 | n = &parent->children[parent->nchildren - 1]; |
369 | if (i == p->length - 1 && NULL != oldnode) | 374 | if (i == p->length - 1 && NULL != oldnode) |
370 | { | 375 | { |
371 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 376 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Putting old note into place.\n"); |
372 | "test: Putting old note into place.\n"); | ||
373 | /* Assignation and free can be misleading, using explicit mempcy */ | 377 | /* Assignation and free can be misleading, using explicit mempcy */ |
374 | memcpy (n, oldnode, sizeof (struct MeshTunnelTreeNode)); | 378 | memcpy (n, oldnode, sizeof (struct MeshTunnelTreeNode)); |
375 | tree_node_destroy(oldnode); | 379 | GNUNET_free (oldnode); |
380 | for (j = 0; j < n->nchildren; j++) | ||
381 | { | ||
382 | n->children[j].parent = n; | ||
383 | } | ||
376 | } | 384 | } |
377 | else | 385 | else |
378 | { | 386 | { |
379 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 387 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Creating new node.\n"); |
380 | "test: Creating new node.\n"); | ||
381 | n->t = t->t; | 388 | n->t = t->t; |
382 | n->status = MESH_PEER_RELAY; | 389 | n->status = MESH_PEER_RELAY; |
383 | n->peer = p->peers[i]; | 390 | n->peer = p->peers[i]; |
@@ -394,12 +401,16 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, | |||
394 | if (me < p->length - 1) | 401 | if (me < p->length - 1) |
395 | { | 402 | { |
396 | GNUNET_PEER_resolve (p->peers[p->length - 1], &id); | 403 | GNUNET_PEER_resolve (p->peers[p->length - 1], &id); |
404 | hop = GNUNET_CONTAINER_multihashmap_get(t->first_hops, &id.hashPubKey); | ||
405 | if (NULL != hop) | ||
406 | GNUNET_free(hop); | ||
397 | hop = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); | 407 | hop = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); |
398 | GNUNET_PEER_resolve (p->peers[me + 1], hop); | 408 | GNUNET_PEER_resolve (p->peers[me + 1], hop); |
399 | GNUNET_CONTAINER_multihashmap_put (t->first_hops, &id.hashPubKey, | 409 | GNUNET_CONTAINER_multihashmap_put (t->first_hops, &id.hashPubKey, |
400 | hop, | 410 | hop, |
401 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 411 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
402 | } | 412 | } |
413 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New node added.\n"); | ||
403 | return GNUNET_OK; | 414 | return GNUNET_OK; |
404 | } | 415 | } |
405 | 416 | ||
@@ -412,14 +423,29 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, | |||
412 | void | 423 | void |
413 | tree_node_destroy (struct MeshTunnelTreeNode *n) | 424 | tree_node_destroy (struct MeshTunnelTreeNode *n) |
414 | { | 425 | { |
426 | struct MeshTunnelTreeNode *parent; | ||
415 | unsigned int i; | 427 | unsigned int i; |
416 | 428 | ||
417 | if (n->nchildren == 0) return; | 429 | if (n->nchildren != 0) |
418 | for (i = 0; i < n->nchildren; i++) | ||
419 | { | 430 | { |
420 | tree_node_destroy(&n->children[i]); | 431 | for (i = 0; i < n->nchildren; i++) |
432 | { | ||
433 | tree_node_destroy(&n->children[i]); | ||
434 | } | ||
435 | if (n->children != NULL) | ||
436 | GNUNET_free(n->children); | ||
421 | } | 437 | } |
422 | GNUNET_free(n->children); | 438 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Destroying node %u.\n", n->peer); |
439 | if (NULL == (parent = n->parent)) | ||
440 | return; | ||
441 | i = (n - parent->children) / sizeof(struct MeshTunnelTreeNode); | ||
442 | parent->children[i] = parent->children[parent->nchildren - 1]; | ||
443 | parent->nchildren--; | ||
444 | parent->children = realloc(parent->children, | ||
445 | parent->nchildren | ||
446 | * sizeof(struct MeshTunnelTreeNode)); | ||
447 | |||
448 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Destroyed.\n"); | ||
423 | } | 449 | } |
424 | 450 | ||
425 | 451 | ||