aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-10-19 13:48:34 +0000
committerBart Polot <bart@net.in.tum.de>2011-10-19 13:48:34 +0000
commit4e63debfc95ce68336d16711d0469aac5bb6954a (patch)
tree341ec35d1f62e817483c4b6c90bff6d03436e436 /src
parent83d0dccb750279dcd0e3ec1635b4952d2e42cb1e (diff)
downloadgnunet-4e63debfc95ce68336d16711d0469aac5bb6954a.tar.gz
gnunet-4e63debfc95ce68336d16711d0469aac5bb6954a.zip
Added peer in tunnel deletion, changes to tree management
Diffstat (limited to 'src')
-rw-r--r--src/mesh/gnunet-service-mesh.c294
-rw-r--r--src/mesh/mesh.h5
-rw-r--r--src/mesh/mesh_tunnel_tree.c28
-rw-r--r--src/mesh/mesh_tunnel_tree.h14
4 files changed, 267 insertions, 74 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index dee424989..d7cf59f03 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -1061,6 +1061,89 @@ send_create_path (struct MeshPeerInfo *peer,
1061 path_info); /* cls */ 1061 path_info); /* cls */
1062} 1062}
1063 1063
1064/**
1065 * Core callback to write a
1066 *
1067 * @param cls Closure (MeshDataDescriptor with data in "data" member).
1068 * @param size Number of bytes available in buf.
1069 * @param buf Where the to write the message.
1070 *
1071 * @return number of bytes written to buf
1072 */
1073static size_t
1074send_core_data_raw (void *cls, size_t size, void *buf)
1075{
1076 struct MeshDataDescriptor *info = cls;
1077 struct GNUNET_MessageHeader *msg;
1078 size_t total_size;
1079
1080 GNUNET_assert (NULL != info);
1081 GNUNET_assert (NULL != info->data);
1082 msg = (struct GNUNET_MessageHeader *) info->data;
1083 total_size = ntohs (msg->size);
1084
1085 if (total_size > size)
1086 {
1087 struct GNUNET_PeerIdentity id;
1088
1089 GNUNET_PEER_resolve (info->peer->id, &id);
1090 info->peer->core_transmit[info->handler_n] =
1091 GNUNET_CORE_notify_transmit_ready(core_handle,
1092 0,
1093 100,
1094 GNUNET_TIME_UNIT_FOREVER_REL,
1095 &id,
1096 size,
1097 &send_core_data_raw,
1098 info);
1099 return 0;
1100 }
1101 info->peer->core_transmit[info->handler_n] = NULL;
1102 memcpy (buf, msg, total_size);
1103 GNUNET_free (info->data);
1104 GNUNET_free (info);
1105 return total_size;
1106}
1107
1108
1109/**
1110 * Sends an already built message to a peer, properly registrating
1111 * all used resources.
1112 *
1113 * @param message Message to send.
1114 * @param peer Short ID of the neighbor whom to send the message.
1115 */
1116static void
1117send_message (const struct GNUNET_MessageHeader *message,
1118 const struct GNUNET_PeerIdentity *peer)
1119{
1120 struct MeshDataDescriptor *info;
1121 struct MeshPeerInfo *neighbor;
1122 unsigned int i;
1123 size_t size;
1124
1125 size = ntohs (message->size);
1126 info = GNUNET_malloc (sizeof (struct MeshDataDescriptor));
1127 info->data = GNUNET_malloc (size);
1128 memcpy (info->data, message, size);
1129 neighbor = peer_info_get (peer);
1130 i = peer_info_transmit_slot (neighbor);
1131 info->handler_n = i;
1132 info->peer = neighbor;
1133 neighbor->types[i] = GNUNET_MESSAGE_TYPE_MESH_UNICAST;
1134 neighbor->infos[i] = info;
1135 neighbor->core_transmit[i] =
1136 GNUNET_CORE_notify_transmit_ready(core_handle,
1137 0,
1138 100,
1139 GNUNET_TIME_UNIT_FOREVER_REL,
1140 peer,
1141 size,
1142 &send_core_data_raw,
1143 info);
1144
1145}
1146
1064 1147
1065/** 1148/**
1066 * Try to establish a new connection to this peer. 1149 * Try to establish a new connection to this peer.
@@ -1667,7 +1750,6 @@ tunnel_send_multicast (struct MeshTunnel *t,
1667 while (NULL != n) 1750 while (NULL != n)
1668 { 1751 {
1669 info = GNUNET_malloc (sizeof (struct MeshDataDescriptor)); 1752 info = GNUNET_malloc (sizeof (struct MeshDataDescriptor));
1670 info->origin = &t->id;
1671 info->data = data; 1753 info->data = data;
1672 info->size = size; 1754 info->size = size;
1673 info->copies = copies; 1755 info->copies = copies;
@@ -1709,7 +1791,7 @@ tunnel_send_multicast (struct MeshTunnel *t,
1709 * 1791 *
1710 * @param t The tunnel whose peers to notify. 1792 * @param t The tunnel whose peers to notify.
1711 */ 1793 */
1712/* static */ void 1794static void
1713tunnel_send_destroy (struct MeshTunnel *t) 1795tunnel_send_destroy (struct MeshTunnel *t)
1714{ 1796{
1715 struct GNUNET_MESH_TunnelDestroy msg; 1797 struct GNUNET_MESH_TunnelDestroy msg;
@@ -1722,6 +1804,7 @@ tunnel_send_destroy (struct MeshTunnel *t)
1722} 1804}
1723 1805
1724 1806
1807
1725/** 1808/**
1726 * Destroy the tunnel and free any allocated resources linked to it 1809 * Destroy the tunnel and free any allocated resources linked to it
1727 * 1810 *
@@ -1804,6 +1887,27 @@ tunnel_destroy (struct MeshTunnel *t)
1804 1887
1805 1888
1806/** 1889/**
1890 * Removes an explicit path from a tunnel, freeing all intermediate nodes
1891 * that are no longer needed, as well as nodes of no longer reachable peers.
1892 * The tunnel itself is also destoyed if results in a remote empty tunnel.
1893 *
1894 * @param t Tunnel from which to remove the path.
1895 * @param p Path which should be removed.
1896 */
1897static void
1898tunnel_delete_path (struct MeshTunnel *t,
1899 struct MeshPeerPath *p)
1900{
1901 GNUNET_break (GNUNET_OK ==
1902 tree_del_peer (t->tree,
1903 p->peers[p->length - 1],
1904 &notify_peer_disconnected));
1905 if (NULL == t->tree->root)
1906 tunnel_destroy (t);
1907}
1908
1909
1910/**
1807 * tunnel_destroy_iterator: iterator for deleting each tunnel that belongs to a 1911 * tunnel_destroy_iterator: iterator for deleting each tunnel that belongs to a
1808 * client when the client disconnects. 1912 * client when the client disconnects.
1809 * 1913 *
@@ -2082,37 +2186,6 @@ send_core_path_ack (void *cls, size_t size, void *buf)
2082} 2186}
2083 2187
2084 2188
2085/**
2086 * Function called to notify a client about the socket
2087 * being ready to queue more data. "buf" will be
2088 * NULL and "size" zero if the socket was closed for
2089 * writing in the meantime.
2090 *
2091 * @param cls closure (data itself)
2092 * @param size number of bytes available in buf
2093 * @param buf where the callee should write the message
2094 * @return number of bytes written to buf
2095 */
2096static size_t
2097send_core_data_raw (void *cls, size_t size, void *buf)
2098{
2099 struct GNUNET_MessageHeader *msg = cls;
2100 size_t total_size;
2101
2102 GNUNET_assert (NULL != msg);
2103 total_size = ntohs (msg->size);
2104
2105 if (total_size > size)
2106 {
2107 GNUNET_break (0);
2108 return 0;
2109 }
2110 memcpy (buf, msg, total_size);
2111 GNUNET_free (cls);
2112 return total_size;
2113}
2114
2115
2116#if LATER 2189#if LATER
2117/** 2190/**
2118 * Send another peer a notification to destroy a tunnel 2191 * Send another peer a notification to destroy a tunnel
@@ -2148,7 +2221,6 @@ send_core_tunnel_destroy (void *cls, size_t size, void *buf)
2148 2221
2149/** 2222/**
2150 * Core handler for path creation 2223 * Core handler for path creation
2151 * struct GNUNET_CORE_MessageHandler
2152 * 2224 *
2153 * @param cls closure 2225 * @param cls closure
2154 * @param message message 2226 * @param message message
@@ -2226,9 +2298,9 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
2226 tunnels, 2298 tunnels,
2227 &hash, 2299 &hash,
2228 t, 2300 t,
2229 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) 2301 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
2230 { 2302 {
2231 tunnel_destroy(t); 2303 tunnel_destroy (t);
2232 GNUNET_break (0); 2304 GNUNET_break (0);
2233 return GNUNET_OK; 2305 return GNUNET_OK;
2234 } 2306 }
@@ -2239,9 +2311,9 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
2239 incoming_tunnels, 2311 incoming_tunnels,
2240 &hash, 2312 &hash,
2241 t, 2313 t,
2242 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) 2314 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
2243 { 2315 {
2244 tunnel_destroy(t); 2316 tunnel_destroy (t);
2245 GNUNET_break (0); 2317 GNUNET_break (0);
2246 return GNUNET_OK; 2318 return GNUNET_OK;
2247 } 2319 }
@@ -2346,6 +2418,126 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
2346 2418
2347 2419
2348/** 2420/**
2421 * Core handler for path destruction
2422 *
2423 * @param cls closure
2424 * @param message message
2425 * @param peer peer identity this notification is about
2426 * @param atsi performance data
2427 *
2428 * @return GNUNET_OK to keep the connection open,
2429 * GNUNET_SYSERR to close it (signal serious error)
2430 */
2431static int
2432handle_mesh_path_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
2433 const struct GNUNET_MessageHeader *message,
2434 const struct GNUNET_ATS_Information *atsi)
2435{
2436 struct GNUNET_MESH_ManipulatePath *msg;
2437 struct GNUNET_PeerIdentity *pi;
2438 struct MeshPeerPath *path;
2439 struct MeshTunnel *t;
2440 unsigned int own_pos;
2441 unsigned int i;
2442 size_t size;
2443
2444 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2445 "MESH: Received a PATH DESTROY msg from %s\n",
2446 GNUNET_i2s(peer));
2447 size = ntohs (message->size);
2448 if (size < sizeof (struct GNUNET_MESH_ManipulatePath))
2449 {
2450 GNUNET_break_op (0);
2451 return GNUNET_OK;
2452 }
2453
2454 size -= sizeof (struct GNUNET_MESH_ManipulatePath);
2455 if (size % sizeof (struct GNUNET_PeerIdentity))
2456 {
2457 GNUNET_break_op (0);
2458 return GNUNET_OK;
2459 }
2460 size /= sizeof (struct GNUNET_PeerIdentity);
2461 if (size < 2)
2462 {
2463 GNUNET_break_op (0);
2464 return GNUNET_OK;
2465 }
2466 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2467 "MESH: path has %u hops.\n",
2468 size);
2469
2470 msg = (struct GNUNET_MESH_ManipulatePath *) message;
2471 pi = (struct GNUNET_PeerIdentity *) &msg[1];
2472 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2473 "MESH: path is for tunnel %s [%X].\n",
2474 GNUNET_i2s(pi),
2475 msg->tid);
2476 t = tunnel_get (pi, ntohl (msg->tid));
2477 if (NULL == t)
2478 {
2479 /* TODO notify back: we don't know this tunnel */
2480 GNUNET_break_op (0);
2481 return GNUNET_OK;
2482 }
2483 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Creating path...\n");
2484 path = path_new (size);
2485 own_pos = 0;
2486 for (i = 0; i < size; i++)
2487 {
2488 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2489 "MESH: ... adding %s\n",
2490 GNUNET_i2s(&pi[i]));
2491 path->peers[i] = GNUNET_PEER_intern (&pi[i]);
2492 if (path->peers[i] == myid)
2493 own_pos = i;
2494 }
2495 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2496 "MESH: Own position: %u\n", own_pos);
2497 if (own_pos < path->length - 1)
2498 send_message (message, &pi[own_pos + 1]);
2499 tunnel_delete_path (t, path);
2500 return GNUNET_OK;
2501}
2502
2503
2504/**
2505 * Core handler for tunnel destruction
2506 *
2507 * @param cls closure
2508 * @param message message
2509 * @param peer peer identity this notification is about
2510 * @param atsi performance data
2511 *
2512 * @return GNUNET_OK to keep the connection open,
2513 * GNUNET_SYSERR to close it (signal serious error)
2514 */
2515static int
2516handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
2517 const struct GNUNET_MessageHeader *message,
2518 const struct GNUNET_ATS_Information *atsi)
2519{
2520 struct GNUNET_MESH_TunnelDestroy *msg;
2521 struct MeshTunnel *t;
2522
2523 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2524 "MESH: Got a TUNNEL DESTROY packet from %s\n",
2525 GNUNET_i2s (peer));
2526 msg = (struct GNUNET_MESH_TunnelDestroy *) message;
2527 t = tunnel_get (&msg->oid, ntohl (msg->tid));
2528 if (NULL == t)
2529 {
2530 /* TODO notify back: we don't know this tunnel */
2531 GNUNET_break_op (0);
2532 return GNUNET_OK;
2533 }
2534 tunnel_send_destroy (t);
2535 tunnel_destroy (t);
2536 return GNUNET_OK;
2537}
2538
2539
2540/**
2349 * Core handler for mesh network traffic going from the origin to a peer 2541 * Core handler for mesh network traffic going from the origin to a peer
2350 * 2542 *
2351 * @param cls closure 2543 * @param cls closure
@@ -2398,13 +2590,7 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
2398 } 2590 }
2399 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2591 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2400 "MESH: not for us, retransmitting...\n"); 2592 "MESH: not for us, retransmitting...\n");
2401 msg = GNUNET_malloc (size); 2593 send_message (message, path_get_first_hop(t->tree, pid));
2402 memcpy (msg, message, size);
2403 GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
2404 GNUNET_TIME_UNIT_FOREVER_REL,
2405 path_get_first_hop (t->tree, pid),
2406 size,
2407 &send_core_data_raw, msg);
2408 return GNUNET_OK; 2594 return GNUNET_OK;
2409} 2595}
2410 2596
@@ -2543,11 +2729,7 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
2543 return GNUNET_OK; 2729 return GNUNET_OK;
2544 } 2730 }
2545 GNUNET_PEER_resolve (t->tree->me->parent->peer, &id); 2731 GNUNET_PEER_resolve (t->tree->me->parent->peer, &id);
2546 msg = GNUNET_malloc (size); 2732 send_message (message, &id);
2547 memcpy (msg, message, size);
2548 GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
2549 GNUNET_TIME_UNIT_FOREVER_REL, &id, size,
2550 &send_core_data_raw, msg);
2551 2733
2552 return GNUNET_OK; 2734 return GNUNET_OK;
2553} 2735}
@@ -2622,13 +2804,7 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
2622 GNUNET_break (0); 2804 GNUNET_break (0);
2623 return GNUNET_OK; 2805 return GNUNET_OK;
2624 } 2806 }
2625 msg = GNUNET_malloc (sizeof (struct GNUNET_MESH_PathACK)); 2807 send_message (message, &id);
2626 memcpy (msg, message, sizeof (struct GNUNET_MESH_PathACK));
2627 GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
2628 GNUNET_TIME_UNIT_FOREVER_REL,
2629 &id,
2630 sizeof (struct GNUNET_MESH_PathACK),
2631 &send_core_data_raw, msg);
2632 return GNUNET_OK; 2808 return GNUNET_OK;
2633} 2809}
2634 2810
@@ -2638,6 +2814,8 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
2638 */ 2814 */
2639static struct GNUNET_CORE_MessageHandler core_handlers[] = { 2815static struct GNUNET_CORE_MessageHandler core_handlers[] = {
2640 {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0}, 2816 {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
2817 {&handle_mesh_path_destroy, GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY, 0},
2818 {&handle_mesh_tunnel_destroy, GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY, 0},
2641 {&handle_mesh_data_unicast, GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0}, 2819 {&handle_mesh_data_unicast, GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
2642 {&handle_mesh_data_multicast, GNUNET_MESSAGE_TYPE_MESH_MULTICAST, 0}, 2820 {&handle_mesh_data_multicast, GNUNET_MESSAGE_TYPE_MESH_MULTICAST, 0},
2643 {&handle_mesh_data_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0}, 2821 {&handle_mesh_data_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
@@ -3193,6 +3371,8 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
3193 t = GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash); 3371 t = GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash);
3194 GNUNET_CONTAINER_multihashmap_remove (c->tunnels, &hash, t); 3372 GNUNET_CONTAINER_multihashmap_remove (c->tunnels, &hash, t);
3195 3373
3374 t->client = NULL;
3375 tunnel_send_destroy (t);
3196 tunnel_destroy(t); 3376 tunnel_destroy(t);
3197 GNUNET_SERVER_receive_done (client, GNUNET_OK); 3377 GNUNET_SERVER_receive_done (client, GNUNET_OK);
3198 return; 3378 return;
diff --git a/src/mesh/mesh.h b/src/mesh/mesh.h
index 0c54d72c9..8d6985a31 100644
--- a/src/mesh/mesh.h
+++ b/src/mesh/mesh.h
@@ -221,6 +221,11 @@ struct GNUNET_MESH_ConnectPeerByType
221enum MeshPeerState 221enum MeshPeerState
222{ 222{
223 /** 223 /**
224 * Peer is the root and owner of the tree
225 */
226 MESH_PEER_ROOT,
227
228 /**
224 * Peer only retransmits traffic, is not a final destination 229 * Peer only retransmits traffic, is not a final destination
225 */ 230 */
226 MESH_PEER_RELAY, 231 MESH_PEER_RELAY,
diff --git a/src/mesh/mesh_tunnel_tree.c b/src/mesh/mesh_tunnel_tree.c
index 090681517..50a8d57d4 100644
--- a/src/mesh/mesh_tunnel_tree.c
+++ b/src/mesh/mesh_tunnel_tree.c
@@ -263,6 +263,7 @@ tree_new (struct MeshTunnel *t, GNUNET_PEER_Id peer)
263 tree = GNUNET_malloc(sizeof (struct MeshTunnelTree)); 263 tree = GNUNET_malloc(sizeof (struct MeshTunnelTree));
264 tree->first_hops = GNUNET_CONTAINER_multihashmap_create(32); 264 tree->first_hops = GNUNET_CONTAINER_multihashmap_create(32);
265 tree->root = tree_node_new(NULL, peer); 265 tree->root = tree_node_new(NULL, peer);
266 tree->root->status = MESH_PEER_ROOT;
266 tree->t = t; 267 tree->t = t;
267 tree->root->t = t; 268 tree->root->t = t;
268 269
@@ -432,8 +433,7 @@ tree_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id,
432 GNUNET_CONTAINER_DLL_remove(parent->children_head, parent->children_tail, n); 433 GNUNET_CONTAINER_DLL_remove(parent->children_head, parent->children_tail, n);
433 n->parent = NULL; 434 n->parent = NULL;
434 435
435 while (t->root != parent && MESH_PEER_RELAY == parent->status && 436 while (MESH_PEER_RELAY == parent->status && NULL == parent->children_head)
436 NULL == parent->children_head)
437 { 437 {
438 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 438 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
439 "tree: Deleting node %u.\n", 439 "tree: Deleting node %u.\n",
@@ -676,7 +676,8 @@ tree_notify_connection_broken (struct MeshTunnelTree *t,
676 676
677 677
678/** 678/**
679 * Deletes a peer from a tunnel, marking its children as disconnected. 679 * Deletes a peer from a tunnel, liberating all unused resources on the path to
680 * it. It shouldn't have children, if it has they will be destroyed as well.
680 * 681 *
681 * @param t Tunnel tree to use. 682 * @param t Tunnel tree to use.
682 * @param peer Short ID of the peer to remove from the tunnel tree. 683 * @param peer Short ID of the peer to remove from the tunnel tree.
@@ -690,24 +691,17 @@ tree_del_peer (struct MeshTunnelTree *t,
690 MeshNodeDisconnectCB cb) 691 MeshNodeDisconnectCB cb)
691{ 692{
692 struct MeshTunnelTreeNode *n; 693 struct MeshTunnelTreeNode *n;
693 struct MeshTunnelTreeNode *c;
694 struct MeshTunnelTreeNode *aux;
695 694
696 n = tree_del_path(t, peer, cb); 695 n = tree_del_path(t, peer, cb);
697 c = n->children_head; 696 if (NULL == n)
698 while (NULL != c) 697 return GNUNET_SYSERR;
698 GNUNET_break_op (NULL == n->children_head);
699 tree_node_destroy(n);
700 if (NULL == t->root->children_head && t->me != t->root)
699 { 701 {
700 aux = c->next; 702 tree_node_destroy (t->root);
701 GNUNET_CONTAINER_DLL_remove(n->children_head, 703 t->root = NULL;
702 n->children_tail,
703 c);
704 GNUNET_CONTAINER_DLL_insert(t->disconnected_head,
705 t->disconnected_tail,
706 c);
707 cb (c);
708 c = aux;
709 } 704 }
710 tree_node_destroy(n);
711 return GNUNET_OK; 705 return GNUNET_OK;
712} 706}
713 707
diff --git a/src/mesh/mesh_tunnel_tree.h b/src/mesh/mesh_tunnel_tree.h
index 82a1d1d1b..d0976579f 100644
--- a/src/mesh/mesh_tunnel_tree.h
+++ b/src/mesh/mesh_tunnel_tree.h
@@ -348,6 +348,20 @@ tree_notify_connection_broken (struct MeshTunnelTree *t,
348 348
349 349
350/** 350/**
351 * Deletes a peer from a tunnel, marking its children as disconnected.
352 *
353 * @param t Tunnel tree to use.
354 * @param peer Short ID of the peer to remove from the tunnel tree.
355 * @param cb Callback to notify client of disconnected peers.
356 *
357 * @return GNUNET_OK or GNUNET_SYSERR
358 */
359int
360tree_del_peer (struct MeshTunnelTree *t,
361 GNUNET_PEER_Id peer,
362 MeshNodeDisconnectCB cb);
363
364/**
351 * Print the tree on stderr 365 * Print the tree on stderr
352 * 366 *
353 * @param t The tree 367 * @param t The tree