diff options
author | Bart Polot <bart@net.in.tum.de> | 2011-10-19 13:48:34 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2011-10-19 13:48:34 +0000 |
commit | 4e63debfc95ce68336d16711d0469aac5bb6954a (patch) | |
tree | 341ec35d1f62e817483c4b6c90bff6d03436e436 | |
parent | 83d0dccb750279dcd0e3ec1635b4952d2e42cb1e (diff) | |
download | gnunet-4e63debfc95ce68336d16711d0469aac5bb6954a.tar.gz gnunet-4e63debfc95ce68336d16711d0469aac5bb6954a.zip |
Added peer in tunnel deletion, changes to tree management
-rw-r--r-- | src/mesh/gnunet-service-mesh.c | 294 | ||||
-rw-r--r-- | src/mesh/mesh.h | 5 | ||||
-rw-r--r-- | src/mesh/mesh_tunnel_tree.c | 28 | ||||
-rw-r--r-- | src/mesh/mesh_tunnel_tree.h | 14 |
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 | */ | ||
1073 | static size_t | ||
1074 | send_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 | */ | ||
1116 | static void | ||
1117 | send_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 | 1794 | static void |
1713 | tunnel_send_destroy (struct MeshTunnel *t) | 1795 | tunnel_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 | */ | ||
1897 | static void | ||
1898 | tunnel_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 | ¬ify_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 | */ | ||
2096 | static size_t | ||
2097 | send_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 | */ | ||
2431 | static int | ||
2432 | handle_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 | */ | ||
2515 | static int | ||
2516 | handle_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 | */ |
2639 | static struct GNUNET_CORE_MessageHandler core_handlers[] = { | 2815 | static 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 | |||
221 | enum MeshPeerState | 221 | enum 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 | */ | ||
359 | int | ||
360 | tree_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 |