+ * @param tree Tree this nodes belongs to.
+ * @param parent ID from node form which to start updating.
+ * @param hop If known, ID of the first hop.
+ * If not known, NULL to find out and pass on children.
+ */
+static void
+tree_node_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;
+ struct MeshTunnelTreeNode *n;
+
+#if MESH_TREE_DEBUG
+ GNUNET_PEER_resolve (parent->peer, &id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Finding first hop for %s.\n",
+ GNUNET_i2s (&id));
+#endif
+ if (NULL == hop)
+ {
+ struct MeshTunnelTreeNode *aux;
+ struct MeshTunnelTreeNode *old;
+
+ aux = old = parent;
+ while (aux != tree->me)
+ {
+#if MESH_TREE_DEBUG
+ GNUNET_PEER_resolve (aux->peer, &id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: ... checking %s.\n",
+ GNUNET_i2s (&id));
+#endif
+ old = aux;
+ aux = aux->parent;
+ GNUNET_assert (NULL != aux);
+ }
+#if MESH_TREE_DEBUG
+ GNUNET_PEER_resolve (old->peer, &id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: It's %s!\n",
+ GNUNET_i2s (&id));
+#endif
+ hop = π
+ GNUNET_PEER_resolve (old->peer, hop);
+ }
+ GNUNET_PEER_resolve (parent->peer, &id);
+ copy = GNUNET_CONTAINER_multihashmap_get (tree->first_hops, &id.hashPubKey);
+ if (NULL == copy)
+ copy = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
+ *copy = *hop;
+
+ (void) GNUNET_CONTAINER_multihashmap_put (tree->first_hops, &id.hashPubKey,
+ copy,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
+
+ for (n = parent->children_head; NULL != n; n = n->next)
+ {
+ tree_node_update_first_hops (tree, n, hop);
+ }
+}
+
+
+static void
+tree_node_debug (struct MeshTunnelTreeNode *n, uint16_t level)
+{
+ struct MeshTunnelTreeNode *c;
+ struct GNUNET_PeerIdentity id;;
+ uint16_t i;
+
+ for (i = 0; i < level; i++)
+ fprintf (stderr, " ");
+ if (n->status == MESH_PEER_READY)
+ fprintf (stderr, "#");
+ if (n->status == MESH_PEER_SEARCHING)
+ fprintf (stderr, "+");
+ if (n->status == MESH_PEER_RELAY)
+ fprintf (stderr, "-");
+ if (n->status == MESH_PEER_RECONNECTING)
+ fprintf (stderr, "*");
+
+ GNUNET_PEER_resolve (n->peer, &id);
+ fprintf (stderr, "%s, [%u, %p] ", GNUNET_i2s (&id), n->peer, n);
+ if (NULL != n->parent)
+ {
+ GNUNET_PEER_resolve (n->parent->peer, &id);
+ fprintf (stderr, "(-> %s [%u])\n", GNUNET_i2s (&id), n->parent->peer);
+ }
+ else
+ fprintf (stderr, "(root)\n");
+ for (c = n->children_head; NULL != c; c = c->next)
+ tree_node_debug (c, level + 1);
+}
+
+
+/**
+ * Destroys and frees the node and all children