From e73416feea2be995456c62f74b33e714501cdb33 Mon Sep 17 00:00:00 2001 From: Bart Polot Date: Wed, 21 Sep 2011 20:42:20 +0000 Subject: [PATCH] Fixed double chaining on note reattachment --- src/mesh/mesh_tunnel_tree.c | 81 +++++++++++++++++++++++++++++------ src/mesh/mesh_tunnel_tree.h | 15 +------ src/mesh/test_mesh_path_api.c | 20 +++++++-- 3 files changed, 86 insertions(+), 30 deletions(-) diff --git a/src/mesh/mesh_tunnel_tree.c b/src/mesh/mesh_tunnel_tree.c index ef4e4a5a0..929b1b69b 100644 --- a/src/mesh/mesh_tunnel_tree.c +++ b/src/mesh/mesh_tunnel_tree.c @@ -178,6 +178,7 @@ tree_mark_peers_disconnected (struct MeshTunnelTree *tree, GNUNET_CONTAINER_multihashmap_remove_all(tree->first_hops, &id.hashPubKey); if (NULL != pi) GNUNET_free(pi); +// FIXME: add to service code on callback // struct GNUNET_MESH_PeerControl msg; // if (NULL == parent->t->client) // return; @@ -192,6 +193,60 @@ tree_mark_peers_disconnected (struct MeshTunnelTree *tree, } +/** + * Recusively update the info about what is the first hop to reach the node + * + * @param tree Tree this nodes belongs to + * @param parent Node to be start updating + * @param hop If known, ID of the first hop. + * If not known, NULL to find out and pass on children. + */ +void +tree_update_first_hops (struct MeshTunnelTree *tree, + struct MeshTunnelTreeNode *parent, + struct GNUNET_PeerIdentity *hop) +{ + struct GNUNET_PeerIdentity pi; + struct GNUNET_PeerIdentity *copy; + struct GNUNET_PeerIdentity id; + unsigned int i; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "tree: Finding first hop for %u.\n", + parent->peer); + if (NULL == hop) + { + struct MeshTunnelTreeNode *aux; + struct MeshTunnelTreeNode *old; + + old = parent; + aux = old->parent; + while (aux != tree->me) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "tree: ... its not %u.\n", + old->peer); + old = aux; + aux = aux->parent; + GNUNET_assert(NULL != aux); + } + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "tree: It's %u!!\n", + old->peer); + hop = π + GNUNET_PEER_resolve(old->peer, hop); + } + copy = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); + *copy = *hop; + GNUNET_PEER_resolve(parent->peer, &id); + GNUNET_CONTAINER_multihashmap_put(tree->first_hops, &id.hashPubKey, copy, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); + + for (i = 0; i < parent->nchildren; i++) + { + tree_update_first_hops (tree, &parent->children[i], hop); + } +} /** @@ -213,7 +268,7 @@ tree_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id, struct MeshTunnelTreeNode *node; struct MeshTunnelTreeNode *n; - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Deleting path to %u.\n", peer_id); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "tree: Deleting path to %u.\n", peer_id); if (peer_id == t->root->peer) return NULL; n = tree_find_peer (t->me, peer_id); @@ -231,7 +286,7 @@ tree_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id, while (t->root != parent && MESH_PEER_RELAY == parent->status && 0 == parent->nchildren) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Deleting node %u.\n", parent->peer); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "tree: Deleting node %u.\n", parent->peer); n = parent->parent; tree_node_destroy(parent); parent = n; @@ -309,7 +364,7 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, unsigned int j; GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Adding path [%u] towards peer %u to peer %u.\n", + "tree: Adding path [%u] towards peer %u to peer %u.\n", p->length, p->peers[p->length - 1], t->me->peer); @@ -333,7 +388,7 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, for (i = 1; i < p->length; i++) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Looking for peer %u.\n", + "tree: Looking for peer %u.\n", p->peers[i]); parent = n; if (p->peers[i] == myid) @@ -352,7 +407,7 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, break; } GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "All childen visited.\n"); + "tree: All childen visited.\n"); if (-1 == me) { /* New path deviates from tree before reaching us. What happened? */ @@ -363,7 +418,7 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, while (i < p->length) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Adding peer %u, to %u.\n", + "tree: Adding peer %u, to %u.\n", p->peers[i], parent->peer); parent->nchildren++; @@ -371,27 +426,29 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, parent->nchildren * sizeof(struct MeshTunnelTreeNode)); n = &parent->children[parent->nchildren - 1]; + n->parent = parent; if (i == p->length - 1 && NULL != oldnode) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Putting old note into place.\n"); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "tree: Putting old node into place.\n"); /* Assignation and free can be misleading, using explicit mempcy */ memcpy (n, oldnode, sizeof (struct MeshTunnelTreeNode)); + n->parent = parent; GNUNET_free (oldnode); for (j = 0; j < n->nchildren; j++) { n->children[j].parent = n; + tree_update_first_hops (t, &n->children[j], NULL); } } else { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Creating new node.\n"); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "tree: Creating new node.\n"); n->t = t->t; n->status = MESH_PEER_RELAY; n->peer = p->peers[i]; n->nchildren = 0; n->children = NULL; } - n->parent = parent; i++; parent = n; } @@ -410,7 +467,7 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, hop, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); } - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New node added.\n"); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "tree: New node added.\n"); return GNUNET_OK; } @@ -435,7 +492,7 @@ tree_node_destroy (struct MeshTunnelTreeNode *n) if (n->children != NULL) GNUNET_free(n->children); } - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Destroying node %u.\n", n->peer); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "tree: Destroying node %u.\n", n->peer); if (NULL == (parent = n->parent)) return; i = (n - parent->children) / sizeof(struct MeshTunnelTreeNode); @@ -445,7 +502,7 @@ tree_node_destroy (struct MeshTunnelTreeNode *n) parent->nchildren * sizeof(struct MeshTunnelTreeNode)); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Destroyed.\n"); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "tree: Destroyed.\n"); } diff --git a/src/mesh/mesh_tunnel_tree.h b/src/mesh/mesh_tunnel_tree.h index 4d46d734f..401ebb089 100644 --- a/src/mesh/mesh_tunnel_tree.h +++ b/src/mesh/mesh_tunnel_tree.h @@ -189,7 +189,7 @@ path_get_length (struct MeshPeerPath *path); /** * Get the cost of the path relative to the already built tunnel tree * - * @param t The tunnel to which compare + * @param t The tunnel tree to which compare * @param path The individual path to reach a peer * * @return Number of hops to reach destination, UINT_MAX in case the peer is not @@ -211,19 +211,6 @@ struct MeshTunnelTreeNode * tree_find_peer (struct MeshTunnelTreeNode *root, GNUNET_PEER_Id peer_id); -/** - * Recusively mark peer and children as disconnected, notify client - * - * @param tree Tree this node belongs to - * @param parent Node to be clean, potentially with children - * @param cb Callback to use to notify about disconnected peers - */ -void -tree_mark_peers_disconnected (struct MeshTunnelTree *tree, - struct MeshTunnelTreeNode *parent, - MeshNodeDisconnectCB cb); - - /** * Delete the current path to the peer, including all now unused relays. * The destination peer is NOT destroyed, it is returned in order to either set diff --git a/src/mesh/test_mesh_path_api.c b/src/mesh/test_mesh_path_api.c index d033d0c83..36eace93d 100644 --- a/src/mesh/test_mesh_path_api.c +++ b/src/mesh/test_mesh_path_api.c @@ -57,6 +57,7 @@ finish(void) { unsigned int i; + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Finishing...\n"); for (i = 0; i < 10; i++) { GNUNET_free(pi[i]); @@ -117,6 +118,7 @@ main (int argc, char *argv[]) path->peers[3] = 3; path->length = 4; + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding first path: 0 1 2 3\n"); tree_add_path(tree, path, &cb); path1 = tree_get_path_to_peer(tree, 3); if (path->length != path1->length || @@ -182,11 +184,9 @@ main (int argc, char *argv[]) failed++; } + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding second path: 0 1 2\n"); path->length--; tree_add_path(tree, path, &cb); - path->length++; - path_destroy(path); - finish(); node = tree_find_peer(tree->root, 2); if (node->peer != 2) @@ -207,11 +207,13 @@ main (int argc, char *argv[]) if (GNUNET_PEER_search(path_get_first_hop(tree, 3)) != 1) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n"); + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "3 GOT: %u\n", GNUNET_PEER_search(path_get_first_hop(tree, 3))); failed++; } if (GNUNET_PEER_search(path_get_first_hop(tree, 2)) != 1) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Wrong first hop!\n"); + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "2 GOT: %u\n", GNUNET_PEER_search(path_get_first_hop(tree, 2))); failed++; } @@ -231,7 +233,11 @@ main (int argc, char *argv[]) GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n"); failed++; } + path->length++; + path_destroy(path); + finish(); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding third path...\n"); path->length++; path->peers[3] = 4; tree_add_path(tree, path, &cb); @@ -286,6 +292,8 @@ main (int argc, char *argv[]) GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); failed++; } + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Deleting third path...\n"); node->status = MESH_PEER_READY; cb_call = 1; node2 = tree_del_path(tree, 4, &cb); @@ -299,7 +307,7 @@ main (int argc, char *argv[]) GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); failed++; } -// GNUNET_free(node2); FIXME destroy + node = tree_find_peer(tree->root, 2); if (node->peer != 2) { @@ -317,6 +325,10 @@ main (int argc, char *argv[]) failed++; } + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Destroying node copy...\n"); + tree_node_destroy(node2); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding new shorter first path...\n"); path->length = 2; path->peers[1] = 3; cb_call = 1; -- 2.25.1