diff options
author | Bart Polot <bart@net.in.tum.de> | 2011-11-02 18:46:43 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2011-11-02 18:46:43 +0000 |
commit | 1c91d8d5152a33db3522cc98c0b44eeeffb7eaa0 (patch) | |
tree | 364160a1550865161346901130b39ab1707b551f /src/mesh | |
parent | b8c9942ee1470ead06fbf0825a3265ebf8904ed6 (diff) | |
download | gnunet-1c91d8d5152a33db3522cc98c0b44eeeffb7eaa0.tar.gz gnunet-1c91d8d5152a33db3522cc98c0b44eeeffb7eaa0.zip |
Changed tree library to be completely detached from mesh, adapted testcases
Diffstat (limited to 'src/mesh')
-rw-r--r-- | src/mesh/Makefile.am | 12 | ||||
-rw-r--r-- | src/mesh/gnunet-service-mesh.c | 191 | ||||
-rw-r--r-- | src/mesh/mesh.h | 5 | ||||
-rw-r--r-- | src/mesh/mesh_tunnel_tree.c | 417 | ||||
-rw-r--r-- | src/mesh/mesh_tunnel_tree.h | 172 | ||||
-rw-r--r-- | src/mesh/test_mesh_path_api.c | 314 |
6 files changed, 520 insertions, 591 deletions
diff --git a/src/mesh/Makefile.am b/src/mesh/Makefile.am index aebe06e6e..860e7a205 100644 --- a/src/mesh/Makefile.am +++ b/src/mesh/Makefile.am | |||
@@ -39,7 +39,7 @@ libgnunetmesh_la_LDFLAGS = \ | |||
39 | 39 | ||
40 | check_PROGRAMS = \ | 40 | check_PROGRAMS = \ |
41 | test_mesh_api \ | 41 | test_mesh_api \ |
42 | test_mesh_path_api \ | 42 | test_mesh_tree_api \ |
43 | test_mesh_local_1 \ | 43 | test_mesh_local_1 \ |
44 | test_mesh_local_2 \ | 44 | test_mesh_local_2 \ |
45 | test_mesh_small_unicast \ | 45 | test_mesh_small_unicast \ |
@@ -55,12 +55,12 @@ test_mesh_api_DEPENDENCIES = \ | |||
55 | libgnunetmesh.la \ | 55 | libgnunetmesh.la \ |
56 | $(top_builddir)/src/util/libgnunetutil.la | 56 | $(top_builddir)/src/util/libgnunetutil.la |
57 | 57 | ||
58 | test_mesh_path_api_SOURCES = \ | 58 | test_mesh_tree_api_SOURCES = \ |
59 | test_mesh_path_api.c mesh_tunnel_tree.c | 59 | test_mesh_tree_api.c |
60 | test_mesh_path_api_LDADD = \ | 60 | test_mesh_tree_api_LDADD = \ |
61 | $(top_builddir)/src/util/libgnunetutil.la \ | 61 | $(top_builddir)/src/util/libgnunetutil.la \ |
62 | $(top_builddir)/src/dht/libgnunetdht.la | 62 | $(top_builddir)/src/dht/libgnunetdht.la |
63 | test_mesh_path_api_DEPENDENCIES = \ | 63 | test_mesh_tree_api_DEPENDENCIES = \ |
64 | libgnunetmesh.la \ | 64 | libgnunetmesh.la \ |
65 | $(top_builddir)/src/dht/libgnunetdht.la | 65 | $(top_builddir)/src/dht/libgnunetdht.la |
66 | 66 | ||
@@ -109,7 +109,7 @@ test_mesh_small_multicast_DEPENDENCIES = \ | |||
109 | 109 | ||
110 | 110 | ||
111 | if ENABLE_TEST_RUN | 111 | if ENABLE_TEST_RUN |
112 | TESTS = test_0 test_mesh_api test_mesh_path_api test_mesh_local_1 test_mesh_local_2 test_1 test_mesh_small_unicast | 112 | TESTS = test_0 test_mesh_api test_mesh_tree_api test_mesh_local_1 test_mesh_local_2 test_1 test_mesh_small_unicast |
113 | endif | 113 | endif |
114 | 114 | ||
115 | EXTRA_DIST = \ | 115 | EXTRA_DIST = \ |
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index bfcfec92b..4b1fca931 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c | |||
@@ -1883,7 +1883,7 @@ tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer) | |||
1883 | tree_add_path (t->tree, best_p, ¬ify_peer_disconnected, t); | 1883 | tree_add_path (t->tree, best_p, ¬ify_peer_disconnected, t); |
1884 | if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task) | 1884 | if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task) |
1885 | t->path_refresh_task = | 1885 | t->path_refresh_task = |
1886 | GNUNET_SCHEDULER_add_delayed (t->tree->refresh, &path_refresh, t); | 1886 | GNUNET_SCHEDULER_add_delayed (REFRESH_PATH_TIME, &path_refresh, t); |
1887 | } | 1887 | } |
1888 | else | 1888 | else |
1889 | { | 1889 | { |
@@ -1911,12 +1911,14 @@ tunnel_add_path (struct MeshTunnel *t, | |||
1911 | 1911 | ||
1912 | GNUNET_assert (0 != own_pos); | 1912 | GNUNET_assert (0 != own_pos); |
1913 | tree_add_path(t->tree, p, NULL, NULL); | 1913 | tree_add_path(t->tree, p, NULL, NULL); |
1914 | if (NULL == t->tree->me) | 1914 | if (tree_get_me (t->tree) == 0) |
1915 | t->tree->me = tree_find_peer(t->tree->root, p->peers[own_pos]); | 1915 | tree_set_me (t->tree, p->peers[own_pos]); |
1916 | if (own_pos < p->length - 1) | 1916 | if (own_pos < p->length - 1) |
1917 | { | 1917 | { |
1918 | GNUNET_PEER_resolve (p->peers[own_pos + 1], &id); | 1918 | GNUNET_PEER_resolve (p->peers[own_pos + 1], &id); |
1919 | tree_update_first_hops(t->tree, t->tree->me, &id); | 1919 | tree_update_first_hops(t->tree, |
1920 | tree_get_me (t->tree), | ||
1921 | &id); | ||
1920 | } | 1922 | } |
1921 | } | 1923 | } |
1922 | 1924 | ||
@@ -1952,7 +1954,7 @@ tunnel_notify_connection_broken (struct MeshTunnel *t, | |||
1952 | } | 1954 | } |
1953 | if (pid != myid) | 1955 | if (pid != myid) |
1954 | { | 1956 | { |
1955 | if (NULL != t->tree->me->parent) | 1957 | if (tree_get_predecessor(t->tree) != 0) |
1956 | { | 1958 | { |
1957 | /* We are the peer still connected, notify owner of the disconnection. */ | 1959 | /* We are the peer still connected, notify owner of the disconnection. */ |
1958 | struct GNUNET_MESH_PathBroken msg; | 1960 | struct GNUNET_MESH_PathBroken msg; |
@@ -1964,7 +1966,7 @@ tunnel_notify_connection_broken (struct MeshTunnel *t, | |||
1964 | msg.tid = htonl (t->id.tid); | 1966 | msg.tid = htonl (t->id.tid); |
1965 | msg.peer1 = my_full_id; | 1967 | msg.peer1 = my_full_id; |
1966 | GNUNET_PEER_resolve (pid, &msg.peer2); | 1968 | GNUNET_PEER_resolve (pid, &msg.peer2); |
1967 | GNUNET_PEER_resolve (t->tree->me->parent->peer, &neighbor); | 1969 | GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor); |
1968 | send_message (&msg.header, &neighbor); | 1970 | send_message (&msg.header, &neighbor); |
1969 | } | 1971 | } |
1970 | } | 1972 | } |
@@ -1972,9 +1974,13 @@ tunnel_notify_connection_broken (struct MeshTunnel *t, | |||
1972 | } | 1974 | } |
1973 | 1975 | ||
1974 | 1976 | ||
1975 | struct AliasedData | 1977 | struct MeshMulticastData |
1976 | { | 1978 | { |
1977 | unsigned int reference_counter; | 1979 | struct MeshTunnel *t; |
1980 | |||
1981 | GNUNET_SCHEDULER_TaskIdentifier *task; | ||
1982 | |||
1983 | unsigned int *reference_counter; | ||
1978 | 1984 | ||
1979 | size_t data_len; | 1985 | size_t data_len; |
1980 | 1986 | ||
@@ -1983,93 +1989,99 @@ struct AliasedData | |||
1983 | 1989 | ||
1984 | 1990 | ||
1985 | /** | 1991 | /** |
1992 | * Send a multicast packet to a neighbor. | ||
1993 | */ | ||
1994 | static void | ||
1995 | tunnel_send_multicast_iterator (void *cls, | ||
1996 | GNUNET_PEER_Id neighbor_id) | ||
1997 | { | ||
1998 | struct MeshMulticastData *mdata = cls; | ||
1999 | struct MeshDataDescriptor *info; | ||
2000 | struct GNUNET_PeerIdentity neighbor; | ||
2001 | unsigned int i; | ||
2002 | |||
2003 | info = GNUNET_malloc (sizeof (struct MeshDataDescriptor)); | ||
2004 | |||
2005 | info->data = mdata->data; | ||
2006 | info->size = mdata->data_len; | ||
2007 | info->copies = mdata->reference_counter; | ||
2008 | (*(mdata->reference_counter))++; | ||
2009 | |||
2010 | if (NULL != mdata->t->client) | ||
2011 | { | ||
2012 | info->client = mdata->t->client->handle; | ||
2013 | info->timeout_task = mdata->task; | ||
2014 | } | ||
2015 | info->destination = neighbor_id; | ||
2016 | GNUNET_PEER_resolve (neighbor_id, &neighbor); | ||
2017 | #if MESH_DEBUG | ||
2018 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2019 | "MESH: sending to %s...\n", | ||
2020 | GNUNET_i2s (&neighbor)); | ||
2021 | #endif | ||
2022 | info->peer = peer_info_get(&neighbor); | ||
2023 | GNUNET_assert (NULL != info->peer); | ||
2024 | i = peer_info_transmit_slot(info->peer); | ||
2025 | info->handler_n = i; | ||
2026 | info->peer->infos[i] = info; | ||
2027 | info->peer->types[i] = GNUNET_MESSAGE_TYPE_MESH_MULTICAST; | ||
2028 | info->peer->core_transmit[i] = | ||
2029 | GNUNET_CORE_notify_transmit_ready (core_handle, | ||
2030 | 0, | ||
2031 | 0, | ||
2032 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
2033 | &neighbor, | ||
2034 | info->size, | ||
2035 | &send_core_data_multicast, info); | ||
2036 | } | ||
2037 | |||
2038 | /** | ||
1986 | * Send a message in a tunnel in multicast, sending a copy to each child node | 2039 | * Send a message in a tunnel in multicast, sending a copy to each child node |
1987 | * down the local one in the tunnel tree. | 2040 | * down the local one in the tunnel tree. |
1988 | * | 2041 | * |
1989 | * @param t Tunnel in which to send the data. | 2042 | * @param t Tunnel in which to send the data. |
1990 | * @param msg Message to be sent | 2043 | * @param msg Message to be sent |
1991 | * | ||
1992 | * @return Number of copies sent. | ||
1993 | * | ||
1994 | * TODO: unifiy shared resources and reference counter management | ||
1995 | */ | 2044 | */ |
1996 | static int | 2045 | static void |
1997 | tunnel_send_multicast (struct MeshTunnel *t, | 2046 | tunnel_send_multicast (struct MeshTunnel *t, |
1998 | const struct GNUNET_MessageHeader *msg) | 2047 | const struct GNUNET_MessageHeader *msg) |
1999 | { | 2048 | { |
2000 | struct GNUNET_PeerIdentity neighbor; | 2049 | struct MeshMulticastData *mdata; |
2001 | struct MeshDataDescriptor *info; | ||
2002 | struct MeshTunnelTreeNode *n; | ||
2003 | struct MeshTunnelTreeNode *counter; | ||
2004 | GNUNET_SCHEDULER_TaskIdentifier *task; | ||
2005 | unsigned int *copies; | ||
2006 | unsigned int i; | ||
2007 | size_t size; | ||
2008 | void *data; | ||
2009 | 2050 | ||
2051 | #if MESH_DEBUG | ||
2010 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2052 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2011 | "MESH: sending a multicast packet...\n"); | 2053 | "MESH: sending a multicast packet...\n"); |
2012 | size = ntohs (msg->size); | 2054 | #endif |
2013 | GNUNET_assert (NULL != t->tree->me); | 2055 | GNUNET_assert (tree_get_me (t->tree) != 0); |
2014 | n = t->tree->me->children_head; | 2056 | mdata = GNUNET_malloc (sizeof (struct MeshMulticastData)); |
2015 | if (NULL == n) | 2057 | mdata->data_len = ntohs (msg->size); |
2016 | { | 2058 | mdata->reference_counter = GNUNET_malloc (sizeof (unsigned int)); |
2017 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2059 | mdata->data = GNUNET_malloc (mdata->data_len); |
2018 | "MESH: no children in the tree, no one to send.\n"); | 2060 | memcpy (mdata->data, msg, mdata->data_len); |
2019 | return 0; | ||
2020 | } | ||
2021 | copies = GNUNET_malloc (sizeof (unsigned int)); | ||
2022 | for (counter = n; NULL != counter; counter = counter->next) | ||
2023 | (*copies)++; | ||
2024 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: (%u copies)\n", *copies); | ||
2025 | data = GNUNET_malloc (size); | ||
2026 | memcpy (data, msg, size); | ||
2027 | if (NULL != t->client) | 2061 | if (NULL != t->client) |
2028 | { | 2062 | { |
2029 | task = GNUNET_malloc (sizeof (GNUNET_SCHEDULER_TaskIdentifier)); | 2063 | mdata->task = GNUNET_malloc (sizeof (GNUNET_SCHEDULER_TaskIdentifier)); |
2030 | *task = GNUNET_SCHEDULER_add_delayed (UNACKNOWLEDGED_WAIT, | 2064 | *(mdata->task) = GNUNET_SCHEDULER_add_delayed (UNACKNOWLEDGED_WAIT, |
2031 | &client_allow_send, | 2065 | &client_allow_send, |
2032 | t->client->handle); | 2066 | t->client->handle); |
2033 | } | 2067 | } |
2034 | else | ||
2035 | task = NULL; // So GCC shuts up about task being potentially uninitialized | ||
2036 | while (NULL != n) | ||
2037 | { | ||
2038 | info = GNUNET_malloc (sizeof (struct MeshDataDescriptor)); | ||
2039 | // info->shared_data = aliased_data; | ||
2040 | // info->shared_data->reference_counter++; | ||
2041 | |||
2042 | info->data = data; | ||
2043 | info->size = size; | ||
2044 | info->copies = copies; | ||
2045 | 2068 | ||
2046 | if (NULL != t->client) | 2069 | tree_iterate_children (t->tree, &tunnel_send_multicast_iterator, mdata); |
2070 | if (*(mdata->reference_counter) == 0) | ||
2071 | { | ||
2072 | GNUNET_free (mdata->data); | ||
2073 | GNUNET_free (mdata->reference_counter); | ||
2074 | if (NULL != mdata->task) | ||
2047 | { | 2075 | { |
2048 | info->client = t->client->handle; | 2076 | GNUNET_free (mdata->task); |
2049 | info->timeout_task = task; | ||
2050 | } | 2077 | } |
2051 | info->destination = n->peer; | 2078 | } |
2052 | GNUNET_PEER_resolve (n->peer, &neighbor); | 2079 | GNUNET_free (mdata); |
2053 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2080 | #if MESH_DEBUG |
2054 | "MESH: sending to %s...\n", | 2081 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2055 | GNUNET_i2s (&neighbor)); | 2082 | "MESH: sending a multicast packet done\n"); |
2056 | info->peer = peer_info_get(&neighbor); | 2083 | #endif |
2057 | GNUNET_assert (NULL != info->peer); | 2084 | return; |
2058 | i = peer_info_transmit_slot(info->peer); | ||
2059 | info->handler_n = i; | ||
2060 | info->peer->infos[i] = info; | ||
2061 | info->peer->types[i] = GNUNET_MESSAGE_TYPE_MESH_MULTICAST; | ||
2062 | info->peer->core_transmit[i] = | ||
2063 | GNUNET_CORE_notify_transmit_ready (core_handle, | ||
2064 | 0, | ||
2065 | 0, | ||
2066 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
2067 | &neighbor, | ||
2068 | size, | ||
2069 | &send_core_data_multicast, info); | ||
2070 | n = n->next; | ||
2071 | } | ||
2072 | return *copies; | ||
2073 | } | 2085 | } |
2074 | 2086 | ||
2075 | 2087 | ||
@@ -2145,7 +2157,6 @@ tunnel_destroy (struct MeshTunnel *t) | |||
2145 | GNUNET_break (GNUNET_YES == | 2157 | GNUNET_break (GNUNET_YES == |
2146 | GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t)); | 2158 | GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t)); |
2147 | } | 2159 | } |
2148 | |||
2149 | if (NULL != t->peers) | 2160 | if (NULL != t->peers) |
2150 | { | 2161 | { |
2151 | GNUNET_CONTAINER_multihashmap_iterate(t->peers, | 2162 | GNUNET_CONTAINER_multihashmap_iterate(t->peers, |
@@ -2186,8 +2197,7 @@ static void | |||
2186 | tunnel_delete_peer (struct MeshTunnel *t, | 2197 | tunnel_delete_peer (struct MeshTunnel *t, |
2187 | GNUNET_PEER_Id peer) | 2198 | GNUNET_PEER_Id peer) |
2188 | { | 2199 | { |
2189 | GNUNET_break (GNUNET_OK == tree_del_peer (t->tree, peer, NULL, NULL)); | 2200 | if (GNUNET_NO == tree_del_peer (t->tree, peer, NULL, NULL)) |
2190 | if (NULL == t->tree->root) | ||
2191 | tunnel_destroy (t); | 2201 | tunnel_destroy (t); |
2192 | } | 2202 | } |
2193 | 2203 | ||
@@ -3039,7 +3049,7 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3039 | GNUNET_break (0); | 3049 | GNUNET_break (0); |
3040 | return GNUNET_OK; | 3050 | return GNUNET_OK; |
3041 | } | 3051 | } |
3042 | GNUNET_PEER_resolve (t->tree->me->parent->peer, &id); | 3052 | GNUNET_PEER_resolve (tree_get_predecessor(t->tree), &id); |
3043 | send_message (message, &id); | 3053 | send_message (message, &id); |
3044 | 3054 | ||
3045 | return GNUNET_OK; | 3055 | return GNUNET_OK; |
@@ -3066,7 +3076,6 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3066 | { | 3076 | { |
3067 | struct GNUNET_MESH_PathACK *msg; | 3077 | struct GNUNET_MESH_PathACK *msg; |
3068 | struct GNUNET_PeerIdentity id; | 3078 | struct GNUNET_PeerIdentity id; |
3069 | struct MeshTunnelTreeNode *n; | ||
3070 | struct MeshPeerInfo *peer_info; | 3079 | struct MeshPeerInfo *peer_info; |
3071 | struct MeshTunnel *t; | 3080 | struct MeshTunnel *t; |
3072 | 3081 | ||
@@ -3096,20 +3105,14 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3096 | t->dht_get_type = NULL; | 3105 | t->dht_get_type = NULL; |
3097 | } | 3106 | } |
3098 | peer_info = peer_info_get (&msg->peer_id); | 3107 | peer_info = peer_info_get (&msg->peer_id); |
3099 | n = tree_find_peer(t->tree->root, peer_info->id); | 3108 | tree_set_status(t->tree, peer_info->id, MESH_PEER_READY); |
3100 | if (NULL == n) | ||
3101 | { | ||
3102 | GNUNET_break_op (0); | ||
3103 | return GNUNET_OK; | ||
3104 | } | ||
3105 | n->status = MESH_PEER_READY; | ||
3106 | send_client_peer_connected(t, peer_info->id); | 3109 | send_client_peer_connected(t, peer_info->id); |
3107 | return GNUNET_OK; | 3110 | return GNUNET_OK; |
3108 | } | 3111 | } |
3109 | 3112 | ||
3110 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3113 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3111 | "MESH: not for us, retransmitting...\n"); | 3114 | "MESH: not for us, retransmitting...\n"); |
3112 | GNUNET_PEER_resolve(t->tree->me->parent->peer, &id); | 3115 | GNUNET_PEER_resolve(tree_get_predecessor(t->tree), &id); |
3113 | peer_info = peer_info_get (&msg->oid); | 3116 | peer_info = peer_info_get (&msg->oid); |
3114 | if (NULL == peer_info) | 3117 | if (NULL == peer_info) |
3115 | { | 3118 | { |
@@ -3241,7 +3244,7 @@ path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
3241 | tunnel_send_multicast (t, &msg->header); | 3244 | tunnel_send_multicast (t, &msg->header); |
3242 | 3245 | ||
3243 | t->path_refresh_task = | 3246 | t->path_refresh_task = |
3244 | GNUNET_SCHEDULER_add_delayed (t->tree->refresh, &path_refresh, t); | 3247 | GNUNET_SCHEDULER_add_delayed (REFRESH_PATH_TIME, &path_refresh, t); |
3245 | return; | 3248 | return; |
3246 | } | 3249 | } |
3247 | 3250 | ||
@@ -3606,9 +3609,7 @@ handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client, | |||
3606 | return; | 3609 | return; |
3607 | } | 3610 | } |
3608 | t->tree = tree_new (myid); | 3611 | t->tree = tree_new (myid); |
3609 | t->tree->refresh = REFRESH_PATH_TIME; | 3612 | tree_set_me(t->tree, myid); |
3610 | t->tree->root->status = MESH_PEER_READY; | ||
3611 | t->tree->me = t->tree->root; | ||
3612 | 3613 | ||
3613 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 3614 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
3614 | return; | 3615 | return; |
diff --git a/src/mesh/mesh.h b/src/mesh/mesh.h index d0648bd3e..fcddb2eb9 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 | * Uninitialized status, should never appear in operation. | ||
225 | */ | ||
226 | MESH_PEER_INVALID, | ||
227 | |||
228 | /** | ||
224 | * Peer is the root and owner of the tree | 229 | * Peer is the root and owner of the tree |
225 | */ | 230 | */ |
226 | MESH_PEER_ROOT, | 231 | MESH_PEER_ROOT, |
diff --git a/src/mesh/mesh_tunnel_tree.c b/src/mesh/mesh_tunnel_tree.c index deb702604..332a022c1 100644 --- a/src/mesh/mesh_tunnel_tree.c +++ b/src/mesh/mesh_tunnel_tree.c | |||
@@ -31,6 +31,83 @@ | |||
31 | 31 | ||
32 | 32 | ||
33 | /** | 33 | /** |
34 | * Node of path tree for a tunnel | ||
35 | */ | ||
36 | struct MeshTunnelTreeNode | ||
37 | { | ||
38 | /** | ||
39 | * Peer this node describes | ||
40 | */ | ||
41 | GNUNET_PEER_Id peer; | ||
42 | |||
43 | /** | ||
44 | * Parent node in the tree | ||
45 | */ | ||
46 | struct MeshTunnelTreeNode *parent; | ||
47 | |||
48 | /** | ||
49 | * DLL of siblings | ||
50 | */ | ||
51 | struct MeshTunnelTreeNode *next; | ||
52 | |||
53 | /** | ||
54 | * DLL of siblings | ||
55 | */ | ||
56 | struct MeshTunnelTreeNode *prev; | ||
57 | |||
58 | /** | ||
59 | * DLL of children | ||
60 | */ | ||
61 | struct MeshTunnelTreeNode *children_head; | ||
62 | |||
63 | /** | ||
64 | * DLL of children | ||
65 | */ | ||
66 | struct MeshTunnelTreeNode *children_tail; | ||
67 | |||
68 | /** | ||
69 | * Status of the peer in the tunnel | ||
70 | */ | ||
71 | enum MeshPeerState status; | ||
72 | }; | ||
73 | |||
74 | |||
75 | /** | ||
76 | * Tree to reach all peers in the tunnel | ||
77 | */ | ||
78 | struct MeshTunnelTree | ||
79 | { | ||
80 | /** | ||
81 | * Root node of peer tree | ||
82 | */ | ||
83 | struct MeshTunnelTreeNode *root; | ||
84 | |||
85 | /** | ||
86 | * Node that represents our position in the tree (for non local tunnels) | ||
87 | */ | ||
88 | struct MeshTunnelTreeNode *me; | ||
89 | |||
90 | /** | ||
91 | * DLL of disconneted nodes | ||
92 | */ | ||
93 | struct MeshTunnelTreeNode *disconnected_head; | ||
94 | |||
95 | /** | ||
96 | * DLL of disconneted nodes | ||
97 | */ | ||
98 | struct MeshTunnelTreeNode *disconnected_tail; | ||
99 | |||
100 | /** | ||
101 | * Cache of all peers and the first hop to them. | ||
102 | * Indexed by PeerIdentity, contains a pointer to the PeerIdentity | ||
103 | * of 1st hop. | ||
104 | */ | ||
105 | struct GNUNET_CONTAINER_MultiHashMap *first_hops; | ||
106 | |||
107 | }; | ||
108 | |||
109 | |||
110 | /** | ||
34 | * Create a new path | 111 | * Create a new path |
35 | * | 112 | * |
36 | * @param lenght How many hops will the path have. | 113 | * @param lenght How many hops will the path have. |
@@ -92,6 +169,19 @@ path_duplicate (struct MeshPeerPath *path) | |||
92 | 169 | ||
93 | 170 | ||
94 | /** | 171 | /** |
172 | * Recusively update the info about what is the first hop to reach the node | ||
173 | * | ||
174 | * @param tree Tree this nodes belongs to. | ||
175 | * @param parent_id Short ID from node form which to start updating. | ||
176 | * @param hop If known, ID of the first hop. | ||
177 | * If not known, NULL to find out and pass on children. | ||
178 | */ | ||
179 | static void | ||
180 | tree_node_update_first_hops (struct MeshTunnelTree *tree, | ||
181 | struct MeshTunnelTreeNode *parent, | ||
182 | struct GNUNET_PeerIdentity *hop); | ||
183 | |||
184 | /** | ||
95 | * Find the first peer whom to send a packet to go down this path | 185 | * Find the first peer whom to send a packet to go down this path |
96 | * | 186 | * |
97 | * @param t The tunnel tree to use | 187 | * @param t The tunnel tree to use |
@@ -112,10 +202,10 @@ path_get_first_hop (struct MeshTunnelTree *t, GNUNET_PEER_Id peer) | |||
112 | { | 202 | { |
113 | struct MeshTunnelTreeNode *n; | 203 | struct MeshTunnelTreeNode *n; |
114 | 204 | ||
115 | n = tree_find_peer(t->root, peer); | 205 | n = tree_find_peer(t, peer); |
116 | if (NULL != t->me && NULL != n) | 206 | if (NULL != t->me && NULL != n) |
117 | { | 207 | { |
118 | tree_update_first_hops(t, n, NULL); | 208 | tree_node_update_first_hops(t, n, NULL); |
119 | r = GNUNET_CONTAINER_multihashmap_get (t->first_hops, &id.hashPubKey); | 209 | r = GNUNET_CONTAINER_multihashmap_get (t->first_hops, &id.hashPubKey); |
120 | GNUNET_assert (NULL != r); | 210 | GNUNET_assert (NULL != r); |
121 | } | 211 | } |
@@ -214,6 +304,103 @@ tree_node_new(struct MeshTunnelTreeNode *parent, GNUNET_PEER_Id peer) | |||
214 | } | 304 | } |
215 | 305 | ||
216 | 306 | ||
307 | /** | ||
308 | * Recursively find the given peer. | ||
309 | * | ||
310 | * @param parent Node where to start looking. | ||
311 | * @param peer Peer to find. | ||
312 | * | ||
313 | * @return Pointer to the node of the peer. NULL if not found. | ||
314 | */ | ||
315 | static struct MeshTunnelTreeNode * | ||
316 | tree_node_find_peer (struct MeshTunnelTreeNode *parent, | ||
317 | GNUNET_PEER_Id peer_id) | ||
318 | { | ||
319 | struct MeshTunnelTreeNode *n; | ||
320 | struct MeshTunnelTreeNode *r; | ||
321 | |||
322 | if (parent->peer == peer_id) | ||
323 | return parent; | ||
324 | for (n = parent->children_head; NULL != n; n = n->next) | ||
325 | { | ||
326 | r = tree_node_find_peer (n, peer_id); | ||
327 | if (NULL != r) | ||
328 | return r; | ||
329 | } | ||
330 | return NULL; | ||
331 | } | ||
332 | |||
333 | |||
334 | /** | ||
335 | * Recusively update the info about what is the first hop to reach the node | ||
336 | * | ||
337 | * @param tree Tree this nodes belongs to. | ||
338 | * @param parent_id Short ID from node form which to start updating. | ||
339 | * @param hop If known, ID of the first hop. | ||
340 | * If not known, NULL to find out and pass on children. | ||
341 | */ | ||
342 | static void | ||
343 | tree_node_update_first_hops (struct MeshTunnelTree *tree, | ||
344 | struct MeshTunnelTreeNode *parent, | ||
345 | struct GNUNET_PeerIdentity *hop) | ||
346 | { | ||
347 | struct GNUNET_PeerIdentity pi; | ||
348 | struct GNUNET_PeerIdentity *copy; | ||
349 | struct GNUNET_PeerIdentity id; | ||
350 | struct MeshTunnelTreeNode *n; | ||
351 | |||
352 | #if MESH_TREE_DEBUG | ||
353 | GNUNET_PEER_resolve(parent->peer, &id); | ||
354 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
355 | "tree: Finding first hop for %s.\n", | ||
356 | GNUNET_i2s (&id)); | ||
357 | #endif | ||
358 | if (NULL == hop) | ||
359 | { | ||
360 | struct MeshTunnelTreeNode *aux; | ||
361 | struct MeshTunnelTreeNode *old; | ||
362 | |||
363 | aux = old = parent; | ||
364 | while (aux != tree->me) | ||
365 | { | ||
366 | #if MESH_TREE_DEBUG | ||
367 | GNUNET_PEER_resolve(old->peer, &id); | ||
368 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
369 | "tree: ... its not %s.\n", | ||
370 | GNUNET_i2s (&id)); | ||
371 | #endif | ||
372 | old = aux; | ||
373 | aux = aux->parent; | ||
374 | GNUNET_assert(NULL != aux); | ||
375 | } | ||
376 | #if MESH_TREE_DEBUG | ||
377 | GNUNET_PEER_resolve(old->peer, &id); | ||
378 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
379 | "tree: It's %s!\n", | ||
380 | GNUNET_i2s (&id)); | ||
381 | #endif | ||
382 | hop = π | ||
383 | GNUNET_PEER_resolve(old->peer, hop); | ||
384 | } | ||
385 | GNUNET_PEER_resolve(parent->peer, &id); | ||
386 | copy = GNUNET_CONTAINER_multihashmap_get (tree->first_hops, &id.hashPubKey); | ||
387 | if (NULL == copy) | ||
388 | copy = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); | ||
389 | *copy = *hop; | ||
390 | |||
391 | (void) GNUNET_CONTAINER_multihashmap_put( | ||
392 | tree->first_hops, | ||
393 | &id.hashPubKey, | ||
394 | copy, | ||
395 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | ||
396 | |||
397 | for (n = parent->children_head; NULL != n; n = n->next) | ||
398 | { | ||
399 | tree_node_update_first_hops (tree, n, hop); | ||
400 | } | ||
401 | } | ||
402 | |||
403 | |||
217 | static void | 404 | static void |
218 | tree_node_debug(struct MeshTunnelTreeNode *n, uint16_t level) | 405 | tree_node_debug(struct MeshTunnelTreeNode *n, uint16_t level) |
219 | { | 406 | { |
@@ -307,28 +494,102 @@ tree_new (GNUNET_PEER_Id peer) | |||
307 | 494 | ||
308 | 495 | ||
309 | /** | 496 | /** |
310 | * Recursively find the given peer in the tree. | 497 | * Set own identity in the tree |
311 | * | 498 | * |
312 | * @param t Tunnel where to look for the peer. | 499 | * @param tree Tree. |
313 | * @param peer Peer to find | 500 | * @param peer A short peer id of local peer. |
501 | */ | ||
502 | void | ||
503 | tree_set_me (struct MeshTunnelTree *tree, GNUNET_PEER_Id peer) | ||
504 | { | ||
505 | tree->me = tree_find_peer(tree, peer); | ||
506 | } | ||
507 | |||
508 | |||
509 | /** | ||
510 | * Get the id of the local node of the tree. | ||
314 | * | 511 | * |
315 | * @return Pointer to the node of the peer. NULL if not found. | 512 | * @param tree Tree whose local id we want to now. |
513 | * | ||
514 | * @return Short peer id of local peer. | ||
316 | */ | 515 | */ |
317 | struct MeshTunnelTreeNode * | 516 | GNUNET_PEER_Id |
318 | tree_find_peer (struct MeshTunnelTreeNode *parent, GNUNET_PEER_Id peer_id) | 517 | tree_get_me (struct MeshTunnelTree *tree) |
518 | { | ||
519 | if (NULL != tree->me) | ||
520 | return tree->me->peer; | ||
521 | else | ||
522 | return (GNUNET_PEER_Id) 0; | ||
523 | } | ||
524 | |||
525 | /** | ||
526 | * Set the status of a node. | ||
527 | * | ||
528 | * @param tree Tree. | ||
529 | * @param peer A short peer id of local peer. | ||
530 | */ | ||
531 | void | ||
532 | tree_set_status (struct MeshTunnelTree *tree, | ||
533 | GNUNET_PEER_Id peer, | ||
534 | enum MeshPeerState status) | ||
319 | { | 535 | { |
320 | struct MeshTunnelTreeNode *n; | 536 | struct MeshTunnelTreeNode *n; |
321 | struct MeshTunnelTreeNode *r; | ||
322 | 537 | ||
323 | if (parent->peer == peer_id) | 538 | n = tree_find_peer(tree, peer); |
324 | return parent; | 539 | if (NULL == n) |
325 | for (n = parent->children_head; NULL != n; n = n->next) | 540 | return; |
326 | { | 541 | n->status = status; |
327 | r = tree_find_peer (n, peer_id); | 542 | } |
328 | if (NULL != r) | 543 | |
329 | return r; | 544 | |
330 | } | 545 | /** |
331 | return NULL; | 546 | * Get the status of a node. |
547 | * | ||
548 | * @param tree Tree whose local id we want to now. | ||
549 | * | ||
550 | * @return Short peer id of local peer. | ||
551 | */ | ||
552 | enum MeshPeerState | ||
553 | tree_get_status (struct MeshTunnelTree *tree, GNUNET_PEER_Id peer) | ||
554 | { | ||
555 | struct MeshTunnelTreeNode *n; | ||
556 | |||
557 | n = tree_find_peer(tree, peer); | ||
558 | if (NULL == n) | ||
559 | return MESH_PEER_INVALID; | ||
560 | return n->status; | ||
561 | } | ||
562 | |||
563 | |||
564 | /** | ||
565 | * Get the id of the predecessor of the local node. | ||
566 | * | ||
567 | * @param tree Tree whose local id we want to now. | ||
568 | * | ||
569 | * @return Short peer id of local peer. | ||
570 | */ | ||
571 | GNUNET_PEER_Id | ||
572 | tree_get_predecessor (struct MeshTunnelTree *tree) | ||
573 | { | ||
574 | if (NULL != tree->me && NULL != tree->me->parent) | ||
575 | return tree->me->parent->peer; | ||
576 | else | ||
577 | return (GNUNET_PEER_Id) 0; | ||
578 | } | ||
579 | |||
580 | |||
581 | /** | ||
582 | * Find the given peer in the tree. | ||
583 | * | ||
584 | * @param tree Tree where to look for the peer. | ||
585 | * @param peer Peer to find. | ||
586 | * | ||
587 | * @return Pointer to the node of the peer. NULL if not found. | ||
588 | */ | ||
589 | struct MeshTunnelTreeNode * | ||
590 | tree_find_peer (struct MeshTunnelTree *tree, GNUNET_PEER_Id peer_id) | ||
591 | { | ||
592 | return tree_node_find_peer(tree->root, peer_id); | ||
332 | } | 593 | } |
333 | 594 | ||
334 | 595 | ||
@@ -342,7 +603,7 @@ tree_find_peer (struct MeshTunnelTreeNode *parent, GNUNET_PEER_Id peer_id) | |||
342 | static void | 603 | static void |
343 | tree_mark_peers_disconnected (struct MeshTunnelTree *tree, | 604 | tree_mark_peers_disconnected (struct MeshTunnelTree *tree, |
344 | struct MeshTunnelTreeNode *parent, | 605 | struct MeshTunnelTreeNode *parent, |
345 | MeshNodeDisconnectCB cb, | 606 | MeshTreeCallback cb, |
346 | void *cbcls) | 607 | void *cbcls) |
347 | { | 608 | { |
348 | struct GNUNET_PeerIdentity *pi; | 609 | struct GNUNET_PeerIdentity *pi; |
@@ -370,76 +631,51 @@ tree_mark_peers_disconnected (struct MeshTunnelTree *tree, | |||
370 | 631 | ||
371 | 632 | ||
372 | /** | 633 | /** |
373 | * Recusively update the info about what is the first hop to reach the node | 634 | * Iterate over all children of the local node. |
374 | * | 635 | * |
375 | * @param tree Tree this nodes belongs to | 636 | * @param tree Tree to use. Must have "me" set. |
376 | * @param parent Node to be start updating | 637 | * @param cb Callback to call over each child. |
377 | * @param hop If known, ID of the first hop. | 638 | * @param cls Closure. |
378 | * If not known, NULL to find out and pass on children. | ||
379 | */ | 639 | */ |
380 | void | 640 | void |
381 | tree_update_first_hops (struct MeshTunnelTree *tree, | 641 | tree_iterate_children (struct MeshTunnelTree *tree, |
382 | struct MeshTunnelTreeNode *parent, | 642 | MeshTreeCallback cb, |
383 | struct GNUNET_PeerIdentity *hop) | 643 | void *cls) |
384 | { | 644 | { |
385 | struct GNUNET_PeerIdentity pi; | ||
386 | struct GNUNET_PeerIdentity *copy; | ||
387 | struct GNUNET_PeerIdentity id; | ||
388 | struct MeshTunnelTreeNode *n; | 645 | struct MeshTunnelTreeNode *n; |
389 | 646 | ||
390 | #if MESH_TREE_DEBUG | 647 | if (NULL == tree->me) |
391 | GNUNET_PEER_resolve(parent->peer, &id); | ||
392 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
393 | "tree: Finding first hop for %s.\n", | ||
394 | GNUNET_i2s (&id)); | ||
395 | #endif | ||
396 | if (NULL == hop) | ||
397 | { | 648 | { |
398 | struct MeshTunnelTreeNode *aux; | 649 | GNUNET_break (0); |
399 | struct MeshTunnelTreeNode *old; | 650 | return; |
400 | |||
401 | aux = old = parent; | ||
402 | while (aux != tree->me) | ||
403 | { | ||
404 | #if MESH_TREE_DEBUG | ||
405 | GNUNET_PEER_resolve(old->peer, &id); | ||
406 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
407 | "tree: ... its not %s.\n", | ||
408 | GNUNET_i2s (&id)); | ||
409 | #endif | ||
410 | old = aux; | ||
411 | aux = aux->parent; | ||
412 | GNUNET_assert(NULL != aux); | ||
413 | } | ||
414 | #if MESH_TREE_DEBUG | ||
415 | GNUNET_PEER_resolve(old->peer, &id); | ||
416 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
417 | "tree: It's %s!\n", | ||
418 | GNUNET_i2s (&id)); | ||
419 | #endif | ||
420 | hop = π | ||
421 | GNUNET_PEER_resolve(old->peer, hop); | ||
422 | } | 651 | } |
423 | GNUNET_PEER_resolve(parent->peer, &id); | 652 | for (n = tree->me->children_head; NULL != n; n = n->next) |
424 | copy = GNUNET_CONTAINER_multihashmap_get (tree->first_hops, &id.hashPubKey); | ||
425 | if (NULL == copy) | ||
426 | copy = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); | ||
427 | *copy = *hop; | ||
428 | |||
429 | (void) GNUNET_CONTAINER_multihashmap_put( | ||
430 | tree->first_hops, | ||
431 | &id.hashPubKey, | ||
432 | copy, | ||
433 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | ||
434 | |||
435 | for (n = parent->children_head; NULL != n; n = n->next) | ||
436 | { | 653 | { |
437 | tree_update_first_hops (tree, n, hop); | 654 | cb (cls, n->peer); |
438 | } | 655 | } |
439 | } | 656 | } |
440 | 657 | ||
441 | 658 | ||
442 | /** | 659 | /** |
660 | * Recusively update the info about what is the first hop to reach the node | ||
661 | * | ||
662 | * @param tree Tree this nodes belongs to. | ||
663 | * @param parent_id Short ID from node form which to start updating. | ||
664 | * @param hop If known, ID of the first hop. | ||
665 | * If not known, NULL to find out and pass on children. | ||
666 | */ | ||
667 | void | ||
668 | tree_update_first_hops (struct MeshTunnelTree *tree, | ||
669 | GNUNET_PEER_Id parent_id, | ||
670 | struct GNUNET_PeerIdentity *hop) | ||
671 | { | ||
672 | tree_node_update_first_hops(tree, | ||
673 | tree_find_peer(tree, parent_id), | ||
674 | hop); | ||
675 | } | ||
676 | |||
677 | |||
678 | /** | ||
443 | * Delete the current path to the peer, including all now unused relays. | 679 | * Delete the current path to the peer, including all now unused relays. |
444 | * The destination peer is NOT destroyed, it is returned in order to either set | 680 | * The destination peer is NOT destroyed, it is returned in order to either set |
445 | * a new path to it or destroy it explicitly, taking care of it's child nodes. | 681 | * a new path to it or destroy it explicitly, taking care of it's child nodes. |
@@ -455,7 +691,7 @@ tree_update_first_hops (struct MeshTunnelTree *tree, | |||
455 | struct MeshTunnelTreeNode * | 691 | struct MeshTunnelTreeNode * |
456 | tree_del_path (struct MeshTunnelTree *t, | 692 | tree_del_path (struct MeshTunnelTree *t, |
457 | GNUNET_PEER_Id peer_id, | 693 | GNUNET_PEER_Id peer_id, |
458 | MeshNodeDisconnectCB cb, | 694 | MeshTreeCallback cb, |
459 | void *cbcls) | 695 | void *cbcls) |
460 | { | 696 | { |
461 | struct MeshTunnelTreeNode *parent; | 697 | struct MeshTunnelTreeNode *parent; |
@@ -483,7 +719,7 @@ tree_del_path (struct MeshTunnelTree *t, | |||
483 | return n; | 719 | return n; |
484 | } | 720 | } |
485 | } | 721 | } |
486 | n = tree_find_peer (t->root, peer_id); | 722 | n = tree_find_peer (t, peer_id); |
487 | if (NULL == n) | 723 | if (NULL == n) |
488 | return NULL; | 724 | return NULL; |
489 | node = n; | 725 | node = n; |
@@ -534,7 +770,7 @@ tree_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer) | |||
534 | struct MeshPeerPath *p; | 770 | struct MeshPeerPath *p; |
535 | GNUNET_PEER_Id myid = t->me->peer; | 771 | GNUNET_PEER_Id myid = t->me->peer; |
536 | 772 | ||
537 | n = tree_find_peer(t->me, peer); | 773 | n = tree_find_peer(t, peer); |
538 | if (NULL == n) | 774 | if (NULL == n) |
539 | return NULL; | 775 | return NULL; |
540 | p = path_new(0); | 776 | p = path_new(0); |
@@ -545,7 +781,8 @@ tree_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer) | |||
545 | GNUNET_array_append(p->peers, p->length, n->peer); | 781 | GNUNET_array_append(p->peers, p->length, n->peer); |
546 | GNUNET_PEER_change_rc(n->peer, 1); | 782 | GNUNET_PEER_change_rc(n->peer, 1); |
547 | n = n->parent; | 783 | n = n->parent; |
548 | GNUNET_assert(NULL != n); | 784 | if (NULL == n) |
785 | return NULL; | ||
549 | } | 786 | } |
550 | GNUNET_array_append(p->peers, p->length, myid); | 787 | GNUNET_array_append(p->peers, p->length, myid); |
551 | GNUNET_PEER_change_rc(myid, 1); | 788 | GNUNET_PEER_change_rc(myid, 1); |
@@ -581,7 +818,7 @@ tree_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer) | |||
581 | int | 818 | int |
582 | tree_add_path (struct MeshTunnelTree *t, | 819 | tree_add_path (struct MeshTunnelTree *t, |
583 | const struct MeshPeerPath *p, | 820 | const struct MeshPeerPath *p, |
584 | MeshNodeDisconnectCB cb, | 821 | MeshTreeCallback cb, |
585 | void *cbcls) | 822 | void *cbcls) |
586 | { | 823 | { |
587 | struct MeshTunnelTreeNode *parent; | 824 | struct MeshTunnelTreeNode *parent; |
@@ -683,7 +920,7 @@ tree_add_path (struct MeshTunnelTree *t, | |||
683 | GNUNET_CONTAINER_DLL_insert(parent->children_head, | 920 | GNUNET_CONTAINER_DLL_insert(parent->children_head, |
684 | parent->children_tail, | 921 | parent->children_tail, |
685 | oldnode); | 922 | oldnode); |
686 | tree_update_first_hops (t, oldnode, NULL); | 923 | tree_node_update_first_hops (t, oldnode, NULL); |
687 | n = oldnode; | 924 | n = oldnode; |
688 | } | 925 | } |
689 | else | 926 | else |
@@ -711,7 +948,7 @@ tree_add_path (struct MeshTunnelTree *t, | |||
711 | #endif | 948 | #endif |
712 | GNUNET_PEER_resolve (p->peers[me + 1], &id); | 949 | GNUNET_PEER_resolve (p->peers[me + 1], &id); |
713 | tree_update_first_hops(t, | 950 | tree_update_first_hops(t, |
714 | tree_find_peer(t->root, p->peers[p->length - 1]), | 951 | p->peers[p->length - 1], |
715 | &id); | 952 | &id); |
716 | } | 953 | } |
717 | #if MESH_TREE_DEBUG | 954 | #if MESH_TREE_DEBUG |
@@ -737,13 +974,13 @@ GNUNET_PEER_Id | |||
737 | tree_notify_connection_broken (struct MeshTunnelTree *t, | 974 | tree_notify_connection_broken (struct MeshTunnelTree *t, |
738 | GNUNET_PEER_Id p1, | 975 | GNUNET_PEER_Id p1, |
739 | GNUNET_PEER_Id p2, | 976 | GNUNET_PEER_Id p2, |
740 | MeshNodeDisconnectCB cb, | 977 | MeshTreeCallback cb, |
741 | void *cbcls) | 978 | void *cbcls) |
742 | { | 979 | { |
743 | struct MeshTunnelTreeNode *n; | 980 | struct MeshTunnelTreeNode *n; |
744 | struct MeshTunnelTreeNode *c; | 981 | struct MeshTunnelTreeNode *c; |
745 | 982 | ||
746 | n = tree_find_peer(t->me, p1); | 983 | n = tree_find_peer(t, p1); |
747 | if (NULL == n) | 984 | if (NULL == n) |
748 | return 0; | 985 | return 0; |
749 | if (NULL != n->parent && n->parent->peer == p2) | 986 | if (NULL != n->parent && n->parent->peer == p2) |
@@ -791,22 +1028,26 @@ tree_notify_connection_broken (struct MeshTunnelTree *t, | |||
791 | int | 1028 | int |
792 | tree_del_peer (struct MeshTunnelTree *t, | 1029 | tree_del_peer (struct MeshTunnelTree *t, |
793 | GNUNET_PEER_Id peer, | 1030 | GNUNET_PEER_Id peer, |
794 | MeshNodeDisconnectCB cb, | 1031 | MeshTreeCallback cb, |
795 | void *cbcls) | 1032 | void *cbcls) |
796 | { | 1033 | { |
797 | struct MeshTunnelTreeNode *n; | 1034 | struct MeshTunnelTreeNode *n; |
798 | 1035 | ||
799 | n = tree_del_path(t, peer, cb, cbcls); | 1036 | n = tree_del_path(t, peer, cb, cbcls); |
800 | if (NULL == n) | 1037 | if (NULL == n) |
801 | return GNUNET_SYSERR; | 1038 | { |
1039 | GNUNET_break (0); | ||
1040 | return GNUNET_YES; | ||
1041 | } | ||
802 | GNUNET_break_op (NULL == n->children_head); | 1042 | GNUNET_break_op (NULL == n->children_head); |
803 | tree_node_destroy(n); | 1043 | tree_node_destroy(n); |
804 | if (NULL == t->root->children_head && t->me != t->root) | 1044 | if (NULL == t->root->children_head && t->me != t->root) |
805 | { | 1045 | { |
806 | tree_node_destroy (t->root); | 1046 | tree_node_destroy (t->root); |
807 | t->root = NULL; | 1047 | t->root = NULL; |
1048 | return GNUNET_NO; | ||
808 | } | 1049 | } |
809 | return GNUNET_OK; | 1050 | return GNUNET_YES; |
810 | } | 1051 | } |
811 | 1052 | ||
812 | 1053 | ||
diff --git a/src/mesh/mesh_tunnel_tree.h b/src/mesh/mesh_tunnel_tree.h index 2cb28a28c..e946259da 100644 --- a/src/mesh/mesh_tunnel_tree.h +++ b/src/mesh/mesh_tunnel_tree.h | |||
@@ -58,83 +58,13 @@ struct MeshPeerPath | |||
58 | /** | 58 | /** |
59 | * Node of path tree for a tunnel | 59 | * Node of path tree for a tunnel |
60 | */ | 60 | */ |
61 | struct MeshTunnelTreeNode | 61 | struct MeshTunnelTreeNode; |
62 | { | ||
63 | /** | ||
64 | * Peer this node describes | ||
65 | */ | ||
66 | GNUNET_PEER_Id peer; | ||
67 | |||
68 | /** | ||
69 | * Parent node in the tree | ||
70 | */ | ||
71 | struct MeshTunnelTreeNode *parent; | ||
72 | |||
73 | /** | ||
74 | * DLL of siblings | ||
75 | */ | ||
76 | struct MeshTunnelTreeNode *next; | ||
77 | |||
78 | /** | ||
79 | * DLL of siblings | ||
80 | */ | ||
81 | struct MeshTunnelTreeNode *prev; | ||
82 | |||
83 | /** | ||
84 | * DLL of children | ||
85 | */ | ||
86 | struct MeshTunnelTreeNode *children_head; | ||
87 | |||
88 | /** | ||
89 | * DLL of children | ||
90 | */ | ||
91 | struct MeshTunnelTreeNode *children_tail; | ||
92 | |||
93 | /** | ||
94 | * Status of the peer in the tunnel | ||
95 | */ | ||
96 | enum MeshPeerState status; | ||
97 | }; | ||
98 | 62 | ||
99 | 63 | ||
100 | /** | 64 | /** |
101 | * Tree to reach all peers in the tunnel | 65 | * Tree to reach all peers in the tunnel |
102 | */ | 66 | */ |
103 | struct MeshTunnelTree | 67 | struct MeshTunnelTree; |
104 | { | ||
105 | /** | ||
106 | * How often to refresh the path | ||
107 | */ | ||
108 | struct GNUNET_TIME_Relative refresh; | ||
109 | |||
110 | /** | ||
111 | * Root node of peer tree | ||
112 | */ | ||
113 | struct MeshTunnelTreeNode *root; | ||
114 | |||
115 | /** | ||
116 | * Node that represents our position in the tree (for non local tunnels) | ||
117 | */ | ||
118 | struct MeshTunnelTreeNode *me; | ||
119 | |||
120 | /** | ||
121 | * DLL of disconneted nodes | ||
122 | */ | ||
123 | struct MeshTunnelTreeNode *disconnected_head; | ||
124 | |||
125 | /** | ||
126 | * DLL of disconneted nodes | ||
127 | */ | ||
128 | struct MeshTunnelTreeNode *disconnected_tail; | ||
129 | |||
130 | /** | ||
131 | * Cache of all peers and the first hop to them. | ||
132 | * Indexed by PeerIdentity, contains a pointer to the PeerIdentity | ||
133 | * of 1st hop. | ||
134 | */ | ||
135 | struct GNUNET_CONTAINER_MultiHashMap *first_hops; | ||
136 | |||
137 | }; | ||
138 | 68 | ||
139 | 69 | ||
140 | /******************************************************************************/ | 70 | /******************************************************************************/ |
@@ -229,14 +159,13 @@ path_destroy (struct MeshPeerPath *p); | |||
229 | * @param cls Closure. | 159 | * @param cls Closure. |
230 | * @param peer_id short ID of peer that is no longer reachable. | 160 | * @param peer_id short ID of peer that is no longer reachable. |
231 | */ | 161 | */ |
232 | typedef void (*MeshNodeDisconnectCB) (void *cls, | 162 | typedef void (*MeshTreeCallback) (void *cls, |
233 | GNUNET_PEER_Id peer_id); | 163 | GNUNET_PEER_Id peer_id); |
234 | 164 | ||
235 | 165 | ||
236 | /** | 166 | /** |
237 | * Create a new tunnel tree associated to a tunnel | 167 | * Create a new tunnel tree associated to a tunnel |
238 | * | 168 | * |
239 | * @param t Tunnel this tree will represent | ||
240 | * @param peer A short peer id of the root of the tree | 169 | * @param peer A short peer id of the root of the tree |
241 | * | 170 | * |
242 | * @return A newly allocated and initialized tunnel tree | 171 | * @return A newly allocated and initialized tunnel tree |
@@ -246,29 +175,96 @@ tree_new (GNUNET_PEER_Id peer); | |||
246 | 175 | ||
247 | 176 | ||
248 | /** | 177 | /** |
249 | * Recursively find the given peer in the tree. | 178 | * Set own identity in the tree |
179 | * | ||
180 | * @param tree Tree. | ||
181 | * @param peer A short peer id of local peer. | ||
182 | */ | ||
183 | void | ||
184 | tree_set_me (struct MeshTunnelTree *tree, GNUNET_PEER_Id peer); | ||
185 | |||
186 | |||
187 | /** | ||
188 | * Get the id of the local id of the tree. | ||
189 | * | ||
190 | * @param tree Tree whose local id we want to now. | ||
191 | * | ||
192 | * @return Short peer id of local peer. | ||
193 | */ | ||
194 | GNUNET_PEER_Id | ||
195 | tree_get_me (struct MeshTunnelTree *tree); | ||
196 | |||
197 | |||
198 | /** | ||
199 | * Set the status of a node. | ||
200 | * | ||
201 | * @param tree Tree. | ||
202 | * @param peer A short peer id of local peer. | ||
203 | */ | ||
204 | void | ||
205 | tree_set_status (struct MeshTunnelTree *tree, | ||
206 | GNUNET_PEER_Id peer, | ||
207 | enum MeshPeerState status); | ||
208 | |||
209 | |||
210 | /** | ||
211 | * Get the status of a node. | ||
212 | * | ||
213 | * @param tree Tree whose local id we want to now. | ||
214 | * | ||
215 | * @return Short peer id of local peer. | ||
216 | */ | ||
217 | enum MeshPeerState | ||
218 | tree_get_status (struct MeshTunnelTree *tree, GNUNET_PEER_Id peer); | ||
219 | |||
220 | |||
221 | /** | ||
222 | * Get the id of the predecessor of the local node. | ||
250 | * | 223 | * |
251 | * @param parent Parent node where to start looking. | 224 | * @param tree Tree whose local id we want to now. |
252 | * @param peer Short ID of peer to find. | 225 | * |
226 | * @return Short peer id of local peer. | ||
227 | */ | ||
228 | GNUNET_PEER_Id | ||
229 | tree_get_predecessor (struct MeshTunnelTree *tree); | ||
230 | |||
231 | |||
232 | /** | ||
233 | * Find the given peer in the tree. | ||
234 | * | ||
235 | * @param tree Tree where to look for the peer. | ||
236 | * @param peer Peer to find. | ||
253 | * | 237 | * |
254 | * @return Pointer to the node of the peer. NULL if not found. | 238 | * @return Pointer to the node of the peer. NULL if not found. |
255 | */ | 239 | */ |
256 | struct MeshTunnelTreeNode * | 240 | struct MeshTunnelTreeNode * |
257 | tree_find_peer (struct MeshTunnelTreeNode *parent, | 241 | tree_find_peer (struct MeshTunnelTree *tree, GNUNET_PEER_Id peer_id); |
258 | GNUNET_PEER_Id peer); | 242 | |
243 | |||
244 | /** | ||
245 | * Iterate over all children of the local node. | ||
246 | * | ||
247 | * @param tree Tree to use. Must have "me" set. | ||
248 | * @param cb Callback to call over each child. | ||
249 | * @param cls Closure. | ||
250 | */ | ||
251 | void | ||
252 | tree_iterate_children (struct MeshTunnelTree *tree, | ||
253 | MeshTreeCallback cb, | ||
254 | void *cls); | ||
259 | 255 | ||
260 | 256 | ||
261 | /** | 257 | /** |
262 | * Recusively update the info about what is the first hop to reach the node | 258 | * Recusively update the info about what is the first hop to reach the node |
263 | * | 259 | * |
264 | * @param tree Tree this nodes belongs to | 260 | * @param tree Tree this nodes belongs to. |
265 | * @param parent Node to be start updating | 261 | * @param parent_id Short ID from node form which to start updating. |
266 | * @param hop If known, ID of the first hop. | 262 | * @param hop If known, ID of the first hop. |
267 | * If not known, NULL to find out and pass on children. | 263 | * If not known, NULL to find out and pass on children. |
268 | */ | 264 | */ |
269 | void | 265 | void |
270 | tree_update_first_hops (struct MeshTunnelTree *tree, | 266 | tree_update_first_hops (struct MeshTunnelTree *tree, |
271 | struct MeshTunnelTreeNode *parent, | 267 | GNUNET_PEER_Id parent_id, |
272 | struct GNUNET_PeerIdentity *hop); | 268 | struct GNUNET_PeerIdentity *hop); |
273 | 269 | ||
274 | /** | 270 | /** |
@@ -288,7 +284,7 @@ tree_update_first_hops (struct MeshTunnelTree *tree, | |||
288 | struct MeshTunnelTreeNode * | 284 | struct MeshTunnelTreeNode * |
289 | tree_del_path (struct MeshTunnelTree *t, | 285 | tree_del_path (struct MeshTunnelTree *t, |
290 | GNUNET_PEER_Id peer, | 286 | GNUNET_PEER_Id peer, |
291 | MeshNodeDisconnectCB cb, | 287 | MeshTreeCallback cb, |
292 | void *cbcls); | 288 | void *cbcls); |
293 | 289 | ||
294 | 290 | ||
@@ -321,7 +317,7 @@ tree_get_path_to_peer(struct MeshTunnelTree *t, | |||
321 | int | 317 | int |
322 | tree_add_path (struct MeshTunnelTree *t, | 318 | tree_add_path (struct MeshTunnelTree *t, |
323 | const struct MeshPeerPath *p, | 319 | const struct MeshPeerPath *p, |
324 | MeshNodeDisconnectCB cb, | 320 | MeshTreeCallback cb, |
325 | void *cbcls); | 321 | void *cbcls); |
326 | 322 | ||
327 | 323 | ||
@@ -341,7 +337,7 @@ GNUNET_PEER_Id | |||
341 | tree_notify_connection_broken (struct MeshTunnelTree *t, | 337 | tree_notify_connection_broken (struct MeshTunnelTree *t, |
342 | GNUNET_PEER_Id p1, | 338 | GNUNET_PEER_Id p1, |
343 | GNUNET_PEER_Id p2, | 339 | GNUNET_PEER_Id p2, |
344 | MeshNodeDisconnectCB cb, | 340 | MeshTreeCallback cb, |
345 | void *cbcls); | 341 | void *cbcls); |
346 | 342 | ||
347 | 343 | ||
@@ -356,12 +352,12 @@ tree_notify_connection_broken (struct MeshTunnelTree *t, | |||
356 | * @param cb Callback to notify client of disconnected peers. | 352 | * @param cb Callback to notify client of disconnected peers. |
357 | * @param cbcls Closure for cb. | 353 | * @param cbcls Closure for cb. |
358 | * | 354 | * |
359 | * @return GNUNET_OK or GNUNET_SYSERR | 355 | * @return GNUNET_YES if the tunnel still has nodes |
360 | */ | 356 | */ |
361 | int | 357 | int |
362 | tree_del_peer (struct MeshTunnelTree *t, | 358 | tree_del_peer (struct MeshTunnelTree *t, |
363 | GNUNET_PEER_Id peer, | 359 | GNUNET_PEER_Id peer, |
364 | MeshNodeDisconnectCB cb, | 360 | MeshTreeCallback cb, |
365 | void *cbcls); | 361 | void *cbcls); |
366 | 362 | ||
367 | /** | 363 | /** |
diff --git a/src/mesh/test_mesh_path_api.c b/src/mesh/test_mesh_path_api.c deleted file mode 100644 index 45c4f3c14..000000000 --- a/src/mesh/test_mesh_path_api.c +++ /dev/null | |||
@@ -1,314 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2011 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file mesh/test_mesh_path.c | ||
23 | * @brief test mesh path: test of path management api | ||
24 | * @author Bartlomiej Polot | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_common.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_dht_service.h" | ||
31 | #include "gnunet_mesh_service.h" | ||
32 | #include "mesh.h" | ||
33 | #include "mesh_tunnel_tree.h" | ||
34 | |||
35 | #define VERBOSE 1 | ||
36 | |||
37 | int failed; | ||
38 | int cb_call; | ||
39 | struct GNUNET_PeerIdentity* pi[10]; | ||
40 | struct MeshTunnelTree *tree; | ||
41 | |||
42 | static void | ||
43 | cb (void *cls, GNUNET_PEER_Id peer_id) | ||
44 | { | ||
45 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: CB: Disconnected %u\n", peer_id); | ||
46 | if(0 == cb_call) | ||
47 | { | ||
48 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: and it shouldn't!\n"); | ||
49 | failed++; | ||
50 | } | ||
51 | cb_call--; | ||
52 | } | ||
53 | |||
54 | |||
55 | /** | ||
56 | * Check if a node has all expected properties. | ||
57 | * | ||
58 | * @param peer_id Short ID of the peer to test. | ||
59 | * @param status Expected status of the peer. | ||
60 | * @param children Expected number of children of the peer. | ||
61 | * @param first_hop Short ID of the expected first hop towards the peer. | ||
62 | */ | ||
63 | static void | ||
64 | test_assert (GNUNET_PEER_Id peer_id, | ||
65 | enum MeshPeerState status, | ||
66 | unsigned int children, | ||
67 | GNUNET_PEER_Id first_hop) | ||
68 | { | ||
69 | struct MeshTunnelTreeNode *n; | ||
70 | struct MeshTunnelTreeNode *c; | ||
71 | unsigned int i; | ||
72 | int pre_failed; | ||
73 | |||
74 | pre_failed = failed; | ||
75 | n = tree_find_peer(tree->root, peer_id); | ||
76 | if (n->peer != peer_id) | ||
77 | { | ||
78 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
79 | "Retrieved peer != original (%u, %u)\n", | ||
80 | n->peer, peer_id); | ||
81 | failed++; | ||
82 | } | ||
83 | if (n->status != status) | ||
84 | { | ||
85 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
86 | "Retrieved peer has wrong status! (%u, %u)\n", | ||
87 | n->status, status); | ||
88 | failed++; | ||
89 | } | ||
90 | for (c = n->children_head, i = 0; NULL != c; c = c->next, i++); | ||
91 | if (i != children) | ||
92 | { | ||
93 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
94 | "Retrieved peer wrong has number of children! (%u, %u)\n", | ||
95 | i, children); | ||
96 | failed++; | ||
97 | } | ||
98 | if (0 != first_hop && | ||
99 | GNUNET_PEER_search(path_get_first_hop(tree, peer_id)) != first_hop) | ||
100 | { | ||
101 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
102 | "Wrong first hop! (%u, %u)\n", | ||
103 | GNUNET_PEER_search(path_get_first_hop(tree, peer_id)), | ||
104 | first_hop); | ||
105 | failed++; | ||
106 | } | ||
107 | if (pre_failed != failed) | ||
108 | { | ||
109 | struct GNUNET_PeerIdentity id; | ||
110 | GNUNET_PEER_resolve (peer_id, &id); | ||
111 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
112 | "*** Peer %s (%u) has failed %d checks! (real, expected)\n", | ||
113 | GNUNET_i2s (&id), peer_id, failed - pre_failed); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | |||
118 | static void | ||
119 | finish(void) | ||
120 | { | ||
121 | unsigned int i; | ||
122 | |||
123 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Finishing...\n"); | ||
124 | for (i = 0; i < 10; i++) | ||
125 | { | ||
126 | GNUNET_free(pi[i]); | ||
127 | } | ||
128 | exit(0); | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * Convert an integer int to a peer identity | ||
133 | */ | ||
134 | static struct GNUNET_PeerIdentity * | ||
135 | get_pi (uint32_t id) | ||
136 | { | ||
137 | struct GNUNET_PeerIdentity *pi; | ||
138 | |||
139 | pi = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); | ||
140 | pi->hashPubKey.bits[0] = id + 1; | ||
141 | return pi; | ||
142 | } | ||
143 | |||
144 | |||
145 | int | ||
146 | main (int argc, char *argv[]) | ||
147 | { | ||
148 | struct MeshTunnelTreeNode *node; | ||
149 | struct MeshTunnelTreeNode *node2; | ||
150 | struct MeshPeerPath *path; | ||
151 | struct MeshPeerPath *path1; | ||
152 | unsigned int i; | ||
153 | |||
154 | failed = 0; | ||
155 | cb_call = 0; | ||
156 | GNUNET_log_setup ("test_mesh_api_path", | ||
157 | #if VERBOSE | ||
158 | "DEBUG", | ||
159 | #else | ||
160 | "WARNING", | ||
161 | #endif | ||
162 | NULL); | ||
163 | for (i = 0; i < 10; i++) | ||
164 | { | ||
165 | pi[i] = get_pi(i); | ||
166 | GNUNET_break (i + 1 == GNUNET_PEER_intern(pi[i])); | ||
167 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Peer %u: %s\n", | ||
168 | i + 1, | ||
169 | GNUNET_h2s(&pi[i]->hashPubKey)); | ||
170 | } | ||
171 | tree = GNUNET_malloc(sizeof(struct MeshTunnelTree)); | ||
172 | tree->first_hops = GNUNET_CONTAINER_multihashmap_create(32); | ||
173 | tree->root = GNUNET_malloc(sizeof(struct MeshTunnelTreeNode)); | ||
174 | tree->root->peer = 1; | ||
175 | tree->me = tree->root; | ||
176 | path = path_new (4); | ||
177 | path->peers[0] = 1; | ||
178 | path->peers[1] = 2; | ||
179 | path->peers[2] = 3; | ||
180 | path->peers[3] = 4; | ||
181 | path->length = 4; | ||
182 | |||
183 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding first path: 1 2 3 4\n"); | ||
184 | tree_add_path(tree, path, &cb, NULL); | ||
185 | tree_debug(tree); | ||
186 | path1 = tree_get_path_to_peer(tree, 4); | ||
187 | if (path->length != path1->length || | ||
188 | memcmp(path->peers, path1->peers, path->length) != 0) | ||
189 | { | ||
190 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved path != original\n"); | ||
191 | failed++; | ||
192 | } | ||
193 | path_destroy(path1); | ||
194 | test_assert (4, MESH_PEER_SEARCHING, 0, 2); | ||
195 | test_assert (3, MESH_PEER_RELAY, 1, 0); | ||
196 | test_assert (2, MESH_PEER_RELAY, 1, 0); | ||
197 | test_assert (1, MESH_PEER_ROOT, 1, 0); | ||
198 | |||
199 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding second path: 1 2 3\n"); | ||
200 | path->length--; | ||
201 | tree_add_path(tree, path, &cb, NULL); | ||
202 | tree_debug(tree); | ||
203 | |||
204 | test_assert (4, MESH_PEER_SEARCHING, 0, 2); | ||
205 | test_assert (3, MESH_PEER_SEARCHING, 1, 2); | ||
206 | test_assert (2, MESH_PEER_RELAY, 1, 0); | ||
207 | test_assert (1, MESH_PEER_ROOT, 1, 0); | ||
208 | |||
209 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding third path...\n"); | ||
210 | path->length++; | ||
211 | path->peers[3] = 5; | ||
212 | tree_add_path(tree, path, &cb, NULL); | ||
213 | tree_debug(tree); | ||
214 | |||
215 | test_assert (5, MESH_PEER_SEARCHING, 0, 2); | ||
216 | test_assert (4, MESH_PEER_SEARCHING, 0, 2); | ||
217 | test_assert (3, MESH_PEER_SEARCHING, 2, 2); | ||
218 | test_assert (2, MESH_PEER_RELAY, 1, 0); | ||
219 | test_assert (1, MESH_PEER_ROOT, 1, 0); | ||
220 | |||
221 | node = tree_find_peer(tree->root, 5); | ||
222 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Deleting third path...\n"); | ||
223 | node->status = MESH_PEER_READY; | ||
224 | cb_call = 1; | ||
225 | node2 = tree_del_path(tree, 5, &cb, NULL); | ||
226 | tree_debug(tree); | ||
227 | if (cb_call != 0) | ||
228 | { | ||
229 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call); | ||
230 | failed++; | ||
231 | } | ||
232 | if (node2->peer != 5) | ||
233 | { | ||
234 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); | ||
235 | failed++; | ||
236 | } | ||
237 | |||
238 | test_assert (4, MESH_PEER_SEARCHING, 0, 2); | ||
239 | test_assert (3, MESH_PEER_SEARCHING, 1, 2); | ||
240 | test_assert (2, MESH_PEER_RELAY, 1, 0); | ||
241 | test_assert (1, MESH_PEER_ROOT, 1, 0); | ||
242 | |||
243 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Destroying node copy...\n"); | ||
244 | GNUNET_free (node2); | ||
245 | |||
246 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
247 | "test: Adding new shorter first path...\n"); | ||
248 | path->length = 2; | ||
249 | path->peers[1] = 4; | ||
250 | cb_call = 1; | ||
251 | tree_find_peer(tree->root, 4)->status = MESH_PEER_READY; | ||
252 | tree_add_path(tree, path, &cb, NULL); | ||
253 | tree_debug(tree); | ||
254 | if (cb_call != 0) | ||
255 | { | ||
256 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call); | ||
257 | failed++; | ||
258 | } | ||
259 | |||
260 | test_assert (4, MESH_PEER_SEARCHING, 0, 4); | ||
261 | test_assert (3, MESH_PEER_SEARCHING, 0, 2); | ||
262 | test_assert (2, MESH_PEER_RELAY, 1, 0); | ||
263 | test_assert (1, MESH_PEER_ROOT, 2, 0); | ||
264 | |||
265 | GNUNET_free (path->peers); | ||
266 | GNUNET_free (path); | ||
267 | tree_destroy (tree); | ||
268 | |||
269 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test:\n"); | ||
270 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Testing relay trees\n"); | ||
271 | for (i = 0; i < 10; i++) | ||
272 | { | ||
273 | pi[i] = get_pi(i); | ||
274 | GNUNET_break (i + 1 == GNUNET_PEER_intern(pi[i])); | ||
275 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Peer %u: %s\n", | ||
276 | i + 1, | ||
277 | GNUNET_h2s(&pi[i]->hashPubKey)); | ||
278 | } | ||
279 | tree = GNUNET_malloc(sizeof(struct MeshTunnelTree)); | ||
280 | tree->first_hops = GNUNET_CONTAINER_multihashmap_create(32); | ||
281 | tree->root = GNUNET_malloc(sizeof(struct MeshTunnelTreeNode)); | ||
282 | tree->root->peer = 1; | ||
283 | path = path_new (3); | ||
284 | path->peers[0] = 1; | ||
285 | path->peers[1] = 2; | ||
286 | path->peers[2] = 3; | ||
287 | path->length = 3; | ||
288 | |||
289 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding first path: 1 2 3\n"); | ||
290 | tree_add_path(tree, path, &cb, NULL); | ||
291 | tree_debug(tree); | ||
292 | tree->me = tree_find_peer (tree->root, 2); | ||
293 | |||
294 | test_assert (3, MESH_PEER_SEARCHING, 0, 3); | ||
295 | test_assert (2, MESH_PEER_RELAY, 1, 0); | ||
296 | test_assert (1, MESH_PEER_ROOT, 1, 0); | ||
297 | |||
298 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test: Adding same path: 1 2 3\n"); | ||
299 | tree_add_path(tree, path, &cb, NULL); | ||
300 | |||
301 | GNUNET_free (path->peers); | ||
302 | GNUNET_free (path); | ||
303 | tree_destroy (tree); | ||
304 | |||
305 | if (failed > 0) | ||
306 | { | ||
307 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%u tests failed\n", failed); | ||
308 | return 1; | ||
309 | } | ||
310 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: OK\n"); | ||
311 | finish(); | ||
312 | |||
313 | return 0; | ||
314 | } | ||