diff options
author | Bart Polot <bart@net.in.tum.de> | 2012-01-24 01:32:04 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2012-01-24 01:32:04 +0000 |
commit | a7191ca787d1274832aede62b44d58063bde3b15 (patch) | |
tree | a067088fd1241fe979e662cd40ba7d8ffdce1a29 /src/mesh | |
parent | 1ad5bcbf2a889f906307daaa88753f38c8bd5903 (diff) | |
download | gnunet-a7191ca787d1274832aede62b44d58063bde3b15.tar.gz gnunet-a7191ca787d1274832aede62b44d58063bde3b15.zip |
Changed incoming tunnel notification to delay until relvant traffic is received from remote peer. Allowed several remote clients for each tunnel.
Diffstat (limited to 'src/mesh')
-rw-r--r-- | src/mesh/gnunet-service-mesh.c | 331 |
1 files changed, 213 insertions, 118 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index 1c47d7fcf..b91fb3819 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c | |||
@@ -276,8 +276,10 @@ struct MeshTunnel | |||
276 | */ | 276 | */ |
277 | MESH_TunnelNumber local_tid; | 277 | MESH_TunnelNumber local_tid; |
278 | 278 | ||
279 | /** | 279 | /** |
280 | * Local tunnel number for local destination clients | 280 | * Local tunnel number for local destination clients (incoming number) |
281 | * ( >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV or 0). All clients share the same | ||
282 | * number. | ||
281 | */ | 283 | */ |
282 | MESH_TunnelNumber local_tid_dest; | 284 | MESH_TunnelNumber local_tid_dest; |
283 | 285 | ||
@@ -310,12 +312,17 @@ struct MeshTunnel | |||
310 | /** | 312 | /** |
311 | * Client owner of the tunnel, if any | 313 | * Client owner of the tunnel, if any |
312 | */ | 314 | */ |
313 | struct MeshClient *client; | 315 | struct MeshClient *owner; |
314 | 316 | ||
315 | /** | 317 | /** |
316 | * Client destination of the tunnel, if any | 318 | * Clients destination of the tunnel, if any |
317 | */ | 319 | */ |
318 | struct MeshClient *client_dest; | 320 | struct MeshClient **clients; |
321 | |||
322 | /** | ||
323 | * Number of destination clients | ||
324 | */ | ||
325 | unsigned int nclients; | ||
319 | 326 | ||
320 | /** | 327 | /** |
321 | * Messages ready to transmit | 328 | * Messages ready to transmit |
@@ -386,15 +393,24 @@ struct MeshPathInfo | |||
386 | struct MeshClient | 393 | struct MeshClient |
387 | { | 394 | { |
388 | /** | 395 | /** |
389 | * Linked list | 396 | * Linked list next |
390 | */ | 397 | */ |
391 | struct MeshClient *next; | 398 | struct MeshClient *next; |
399 | |||
400 | /** | ||
401 | * Linked list prev | ||
402 | */ | ||
392 | struct MeshClient *prev; | 403 | struct MeshClient *prev; |
393 | 404 | ||
394 | /** | 405 | /** |
395 | * Tunnels that belong to this client, indexed by local id | 406 | * Tunnels that belong to this client, indexed by local id |
396 | */ | 407 | */ |
397 | struct GNUNET_CONTAINER_MultiHashMap *tunnels; | 408 | struct GNUNET_CONTAINER_MultiHashMap *own_tunnels; |
409 | |||
410 | /** | ||
411 | * Tunnels this client has accepted, indexed by incoming local id | ||
412 | */ | ||
413 | struct GNUNET_CONTAINER_MultiHashMap *incoming_tunnels; | ||
398 | 414 | ||
399 | /** | 415 | /** |
400 | * Handle to communicate with the client | 416 | * Handle to communicate with the client |
@@ -761,7 +777,7 @@ client_allow_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
761 | mdata->reference_counter); | 777 | mdata->reference_counter); |
762 | #endif | 778 | #endif |
763 | *(mdata->task) = GNUNET_SCHEDULER_NO_TASK; | 779 | *(mdata->task) = GNUNET_SCHEDULER_NO_TASK; |
764 | GNUNET_SERVER_receive_done (mdata->t->client->handle, GNUNET_OK); | 780 | GNUNET_SERVER_receive_done (mdata->t->owner->handle, GNUNET_OK); |
765 | } | 781 | } |
766 | 782 | ||
767 | 783 | ||
@@ -778,6 +794,18 @@ tunnel_get (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid); | |||
778 | 794 | ||
779 | 795 | ||
780 | /** | 796 | /** |
797 | * Gets the index in t->clients of the client. | ||
798 | * | ||
799 | * @param t Tunnel where to find client. | ||
800 | * @param c Client to be found. | ||
801 | * | ||
802 | * @return Index of the client, -1 if not present | ||
803 | */ | ||
804 | static int | ||
805 | tunnel_get_client_index (struct MeshTunnel *t, struct MeshClient *c); | ||
806 | |||
807 | |||
808 | /** | ||
781 | * Notify a tunnel that a connection has broken that affects at least | 809 | * Notify a tunnel that a connection has broken that affects at least |
782 | * some of its peers. | 810 | * some of its peers. |
783 | * | 811 | * |
@@ -812,9 +840,9 @@ send_subscribed_clients (const struct GNUNET_MessageHeader *msg, | |||
812 | uint16_t type; | 840 | uint16_t type; |
813 | char cbuf[htons (msg->size)]; | 841 | char cbuf[htons (msg->size)]; |
814 | 842 | ||
843 | type = ntohs (payload->type); | ||
815 | #if MESH_DEBUG | 844 | #if MESH_DEBUG |
816 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Sending to clients...\n"); | 845 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Sending to clients...\n"); |
817 | type = ntohs (payload->type); | ||
818 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: message of type %u\n", type); | 846 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: message of type %u\n", type); |
819 | #endif | 847 | #endif |
820 | 848 | ||
@@ -858,13 +886,35 @@ send_subscribed_clients (const struct GNUNET_MessageHeader *msg, | |||
858 | #endif | 886 | #endif |
859 | if (client_is_subscribed (type, c)) | 887 | if (client_is_subscribed (type, c)) |
860 | { | 888 | { |
861 | // FIXME proper client differentiation mechanism required | ||
862 | if (htons (msg->type) == GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN) | 889 | if (htons (msg->type) == GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN) |
890 | { | ||
891 | if (c != t->owner) | ||
892 | continue; | ||
863 | *tid = htonl (t->local_tid); | 893 | *tid = htonl (t->local_tid); |
864 | else if(c == t->client_dest) | 894 | } |
865 | *tid = htonl (t->local_tid_dest); | ||
866 | else | 895 | else |
867 | *tid = htonl (t->local_tid); | 896 | { |
897 | if (-1 == tunnel_get_client_index (t, c)) | ||
898 | { | ||
899 | /* This client isn't in the tunnel */ | ||
900 | struct GNUNET_MESH_TunnelNotification tmsg; | ||
901 | GNUNET_HashCode hash; | ||
902 | |||
903 | tmsg.header.size = htons (sizeof (tmsg)); | ||
904 | tmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE); | ||
905 | GNUNET_PEER_resolve (t->id.oid, &tmsg.peer); | ||
906 | tmsg.tunnel_id = htonl (t->local_tid_dest); | ||
907 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, | ||
908 | &tmsg.header, GNUNET_NO); | ||
909 | GNUNET_array_append (t->clients, t->nclients, c); | ||
910 | GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), | ||
911 | &hash); | ||
912 | GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put ( | ||
913 | c->incoming_tunnels, &hash, t, | ||
914 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); | ||
915 | } | ||
916 | *tid = htonl (t->local_tid_dest); | ||
917 | } | ||
868 | count++; | 918 | count++; |
869 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: sending\n"); | 919 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: sending\n"); |
870 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, | 920 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, |
@@ -892,7 +942,7 @@ send_client_peer_connected (const struct MeshTunnel *t, const GNUNET_PEER_Id id) | |||
892 | pc.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl)); | 942 | pc.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl)); |
893 | pc.tunnel_id = htonl (t->local_tid); | 943 | pc.tunnel_id = htonl (t->local_tid); |
894 | GNUNET_PEER_resolve (id, &pc.peer); | 944 | GNUNET_PEER_resolve (id, &pc.peer); |
895 | GNUNET_SERVER_notification_context_unicast (nc, t->client->handle, &pc.header, | 945 | GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle, &pc.header, |
896 | GNUNET_NO); | 946 | GNUNET_NO); |
897 | } | 947 | } |
898 | 948 | ||
@@ -916,9 +966,12 @@ send_clients_tunnel_destroy (struct MeshTunnel *t) | |||
916 | 966 | ||
917 | 967 | ||
918 | /** | 968 | /** |
919 | * Notify a client that the other local client disconnected, if needed. | 969 | * Notify clients f tunnel disconnections, if needed. |
920 | * In case the origin disconnects, the destination get a tunnel destroy | 970 | * In case the origin disconnects, the destination clients get a tunnel destroy |
921 | * notification. Otherwise, the origin gets a (local ID) peer disconnected. | 971 | * notification. If the last destination disconnects (only one remaining client |
972 | * in tunnel), the origin gets a (local ID) peer disconnected. | ||
973 | * Note that the function must be called BEFORE removing the client from | ||
974 | * the tunnel. | ||
922 | * | 975 | * |
923 | * @param t Tunnel that was destroyed. | 976 | * @param t Tunnel that was destroyed. |
924 | * @param c Client that disconnected. | 977 | * @param c Client that disconnected. |
@@ -926,25 +979,28 @@ send_clients_tunnel_destroy (struct MeshTunnel *t) | |||
926 | static void | 979 | static void |
927 | send_client_tunnel_disconnect (struct MeshTunnel *t, struct MeshClient *c) | 980 | send_client_tunnel_disconnect (struct MeshTunnel *t, struct MeshClient *c) |
928 | { | 981 | { |
929 | if (c == t->client_dest) | 982 | unsigned int i; |
930 | { | ||
931 | struct GNUNET_MESH_PeerControl msg; | ||
932 | 983 | ||
933 | msg.header.size = htons (sizeof (msg)); | 984 | if (c == t->owner) |
934 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL); | ||
935 | msg.tunnel_id = htonl (t->local_tid); | ||
936 | msg.peer = my_full_id; | ||
937 | GNUNET_SERVER_notification_context_unicast (nc, t->client->handle, | ||
938 | &msg.header, GNUNET_NO); | ||
939 | } | ||
940 | else if (NULL != t->client_dest && c == t->client) | ||
941 | { | 985 | { |
942 | struct GNUNET_MESH_TunnelMessage msg; | 986 | struct GNUNET_MESH_TunnelMessage msg; |
943 | 987 | ||
944 | msg.header.size = htons (sizeof (msg)); | 988 | msg.header.size = htons (sizeof (msg)); |
945 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY); | 989 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY); |
946 | msg.tunnel_id = htonl (t->local_tid_dest); | 990 | msg.tunnel_id = htonl (t->local_tid_dest); |
947 | GNUNET_SERVER_notification_context_unicast (nc, t->client_dest->handle, | 991 | for (i = 0; i < t->nclients; i++) |
992 | GNUNET_SERVER_notification_context_unicast (nc, t->clients[i]->handle, | ||
993 | &msg.header, GNUNET_NO); | ||
994 | } | ||
995 | else if (1 == t->nclients && NULL != t->owner) | ||
996 | { | ||
997 | struct GNUNET_MESH_PeerControl msg; | ||
998 | |||
999 | msg.header.size = htons (sizeof (msg)); | ||
1000 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL); | ||
1001 | msg.tunnel_id = htonl (t->local_tid); | ||
1002 | msg.peer = my_full_id; | ||
1003 | GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle, | ||
948 | &msg.header, GNUNET_NO); | 1004 | &msg.header, GNUNET_NO); |
949 | } | 1005 | } |
950 | } | 1006 | } |
@@ -1001,7 +1057,7 @@ data_descriptor_decrement_multicast (struct MeshData *mesh_data) | |||
1001 | { | 1057 | { |
1002 | GNUNET_SCHEDULER_cancel (*(mesh_data->task)); | 1058 | GNUNET_SCHEDULER_cancel (*(mesh_data->task)); |
1003 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: notifying client...\n"); | 1059 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: notifying client...\n"); |
1004 | GNUNET_SERVER_receive_done (mesh_data->t->client->handle, GNUNET_OK); | 1060 | GNUNET_SERVER_receive_done (mesh_data->t->owner->handle, GNUNET_OK); |
1005 | } | 1061 | } |
1006 | GNUNET_free (mesh_data->task); | 1062 | GNUNET_free (mesh_data->task); |
1007 | } | 1063 | } |
@@ -1855,7 +1911,7 @@ tunnel_get_by_local_id (struct MeshClient *c, MESH_TunnelNumber tid) | |||
1855 | GNUNET_HashCode hash; | 1911 | GNUNET_HashCode hash; |
1856 | 1912 | ||
1857 | GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash); | 1913 | GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash); |
1858 | return GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash); | 1914 | return GNUNET_CONTAINER_multihashmap_get (c->own_tunnels, &hash); |
1859 | } | 1915 | } |
1860 | } | 1916 | } |
1861 | 1917 | ||
@@ -1911,7 +1967,7 @@ notify_peer_disconnected (void *cls, GNUNET_PEER_Id peer_id) | |||
1911 | struct MeshPeerInfo *peer; | 1967 | struct MeshPeerInfo *peer; |
1912 | struct MeshPathInfo *path_info; | 1968 | struct MeshPathInfo *path_info; |
1913 | 1969 | ||
1914 | if (NULL != t->client && NULL != nc) | 1970 | if (NULL != t->owner && NULL != nc) |
1915 | { | 1971 | { |
1916 | struct GNUNET_MESH_PeerControl msg; | 1972 | struct GNUNET_MESH_PeerControl msg; |
1917 | 1973 | ||
@@ -1919,7 +1975,7 @@ notify_peer_disconnected (void *cls, GNUNET_PEER_Id peer_id) | |||
1919 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL); | 1975 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL); |
1920 | msg.tunnel_id = htonl (t->local_tid); | 1976 | msg.tunnel_id = htonl (t->local_tid); |
1921 | GNUNET_PEER_resolve (peer_id, &msg.peer); | 1977 | GNUNET_PEER_resolve (peer_id, &msg.peer); |
1922 | GNUNET_SERVER_notification_context_unicast (nc, t->client->handle, | 1978 | GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle, |
1923 | &msg.header, GNUNET_NO); | 1979 | &msg.header, GNUNET_NO); |
1924 | } | 1980 | } |
1925 | peer = peer_info_get_short (peer_id); | 1981 | peer = peer_info_get_short (peer_id); |
@@ -2136,7 +2192,7 @@ tunnel_send_multicast (struct MeshTunnel *t, | |||
2136 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: not a data packet, no ttl\n"); | 2192 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: not a data packet, no ttl\n"); |
2137 | #endif | 2193 | #endif |
2138 | } | 2194 | } |
2139 | if (NULL != t->client && GNUNET_YES != t->client->shutting_down | 2195 | if (NULL != t->owner && GNUNET_YES != t->owner->shutting_down |
2140 | && GNUNET_NO == internal) | 2196 | && GNUNET_NO == internal) |
2141 | { | 2197 | { |
2142 | mdata->task = GNUNET_malloc (sizeof (GNUNET_SCHEDULER_TaskIdentifier)); | 2198 | mdata->task = GNUNET_malloc (sizeof (GNUNET_SCHEDULER_TaskIdentifier)); |
@@ -2156,7 +2212,7 @@ tunnel_send_multicast (struct MeshTunnel *t, | |||
2156 | { | 2212 | { |
2157 | GNUNET_SCHEDULER_cancel(*(mdata->task)); | 2213 | GNUNET_SCHEDULER_cancel(*(mdata->task)); |
2158 | GNUNET_free (mdata->task); | 2214 | GNUNET_free (mdata->task); |
2159 | GNUNET_SERVER_receive_done(t->client->handle, GNUNET_OK); | 2215 | GNUNET_SERVER_receive_done(t->owner->handle, GNUNET_OK); |
2160 | } | 2216 | } |
2161 | // FIXME change order? | 2217 | // FIXME change order? |
2162 | GNUNET_free (mdata); | 2218 | GNUNET_free (mdata); |
@@ -2170,6 +2226,27 @@ tunnel_send_multicast (struct MeshTunnel *t, | |||
2170 | 2226 | ||
2171 | 2227 | ||
2172 | /** | 2228 | /** |
2229 | * Gets the index in t->clients of the client. | ||
2230 | * | ||
2231 | * @param t Tunnel where to find client. | ||
2232 | * @param c Client to be found. | ||
2233 | * | ||
2234 | * @return Index of the client, -1 if not present | ||
2235 | */ | ||
2236 | static int | ||
2237 | tunnel_get_client_index (struct MeshTunnel *t, struct MeshClient *c) | ||
2238 | { | ||
2239 | int i; | ||
2240 | |||
2241 | for (i = 0; i < t->nclients; i++) | ||
2242 | if (t->clients[i] == c) | ||
2243 | break; | ||
2244 | if (i < t->nclients) | ||
2245 | return i; | ||
2246 | return -1; | ||
2247 | } | ||
2248 | |||
2249 | /** | ||
2173 | * Send a message to all peers in this tunnel that the tunnel is no longer | 2250 | * Send a message to all peers in this tunnel that the tunnel is no longer |
2174 | * valid. | 2251 | * valid. |
2175 | * | 2252 | * |
@@ -2190,7 +2267,7 @@ tunnel_send_destroy (struct MeshTunnel *t) | |||
2190 | 2267 | ||
2191 | 2268 | ||
2192 | /** | 2269 | /** |
2193 | * Destroy the tunnel and free any allocated resources linked to it | 2270 | * Destroy the tunnel and free any allocated resources linked to it. |
2194 | * | 2271 | * |
2195 | * @param t the tunnel to destroy | 2272 | * @param t the tunnel to destroy |
2196 | * | 2273 | * |
@@ -2203,13 +2280,14 @@ tunnel_destroy (struct MeshTunnel *t) | |||
2203 | struct MeshQueue *q; | 2280 | struct MeshQueue *q; |
2204 | struct MeshQueue *qn; | 2281 | struct MeshQueue *qn; |
2205 | GNUNET_HashCode hash; | 2282 | GNUNET_HashCode hash; |
2283 | unsigned int i; | ||
2206 | int r; | 2284 | int r; |
2207 | 2285 | ||
2208 | if (NULL == t) | 2286 | if (NULL == t) |
2209 | return GNUNET_OK; | 2287 | return GNUNET_OK; |
2210 | 2288 | ||
2211 | r = GNUNET_OK; | 2289 | r = GNUNET_OK; |
2212 | c = t->client; | 2290 | c = t->owner; |
2213 | #if MESH_DEBUG | 2291 | #if MESH_DEBUG |
2214 | { | 2292 | { |
2215 | struct GNUNET_PeerIdentity id; | 2293 | struct GNUNET_PeerIdentity id; |
@@ -2227,31 +2305,32 @@ tunnel_destroy (struct MeshTunnel *t) | |||
2227 | { | 2305 | { |
2228 | r = GNUNET_SYSERR; | 2306 | r = GNUNET_SYSERR; |
2229 | } | 2307 | } |
2230 | 2308 | ||
2231 | GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash); | 2309 | GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash); |
2232 | if (NULL != c && | 2310 | if (NULL != c && |
2233 | GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (c->tunnels, &hash, t)) | 2311 | GNUNET_YES != |
2312 | GNUNET_CONTAINER_multihashmap_remove (c->own_tunnels, &hash, t)) | ||
2234 | { | 2313 | { |
2235 | r = GNUNET_SYSERR; | 2314 | r = GNUNET_SYSERR; |
2236 | } | 2315 | } |
2237 | c = t->client_dest; | ||
2238 | GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash); | 2316 | GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash); |
2239 | if (NULL != c) | 2317 | for (i = 0; i < t->nclients; i++) |
2240 | { | 2318 | { |
2319 | c = t->clients[i]; | ||
2241 | if (GNUNET_YES != | 2320 | if (GNUNET_YES != |
2242 | GNUNET_CONTAINER_multihashmap_remove (c->tunnels, &hash, t) || | 2321 | GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels, &hash, t)) |
2243 | GNUNET_YES != | ||
2244 | GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t)) | ||
2245 | { | 2322 | { |
2246 | r = GNUNET_SYSERR; | 2323 | r = GNUNET_SYSERR; |
2247 | } | 2324 | } |
2248 | } | 2325 | } |
2249 | if (t->local_tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV) | 2326 | if (t->nclients > 0) |
2250 | { | 2327 | { |
2251 | GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash); | 2328 | if (GNUNET_YES != |
2252 | GNUNET_break (GNUNET_YES == | 2329 | GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t)) |
2253 | GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, | 2330 | { |
2254 | t)); | 2331 | r = GNUNET_SYSERR; |
2332 | } | ||
2333 | GNUNET_free (t->clients); | ||
2255 | } | 2334 | } |
2256 | if (NULL != t->peers) | 2335 | if (NULL != t->peers) |
2257 | { | 2336 | { |
@@ -2298,8 +2377,31 @@ tunnel_delete_peer (struct MeshTunnel *t, GNUNET_PEER_Id peer) | |||
2298 | 2377 | ||
2299 | 2378 | ||
2300 | /** | 2379 | /** |
2380 | * Removes a client from the tunnel. | ||
2381 | * | ||
2382 | * @param t Tunnel from which to remove the client. | ||
2383 | * @param c Client that should be removed. | ||
2384 | * | ||
2385 | * FIXME blacklist client to avoid adding it at next data packet | ||
2386 | */ | ||
2387 | static void | ||
2388 | tunnel_delete_client (struct MeshTunnel *t, struct MeshClient *c) | ||
2389 | { | ||
2390 | unsigned int i; | ||
2391 | |||
2392 | for (i = 0; i < t->nclients; i++) | ||
2393 | if (t->clients[i] == c) | ||
2394 | break; | ||
2395 | GNUNET_assert (i < t->nclients); | ||
2396 | t->clients[i] = t->clients [t->nclients - 1]; | ||
2397 | GNUNET_array_grow (t->clients, t->nclients, t->nclients - 1); | ||
2398 | } | ||
2399 | |||
2400 | /** | ||
2301 | * tunnel_destroy_iterator: iterator for deleting each tunnel that belongs to a | 2401 | * tunnel_destroy_iterator: iterator for deleting each tunnel that belongs to a |
2302 | * client when the client disconnects. | 2402 | * client when the client disconnects. If the client is not the owner, the |
2403 | * owner will get notified if no more clients are in the tunnel and the client | ||
2404 | * get removed from the tunnel's list. | ||
2303 | * | 2405 | * |
2304 | * @param cls closure (client that is disconnecting) | 2406 | * @param cls closure (client that is disconnecting) |
2305 | * @param key the hash of the local tunnel id (used to access the hashmap) | 2407 | * @param key the hash of the local tunnel id (used to access the hashmap) |
@@ -2315,14 +2417,13 @@ tunnel_destroy_iterator (void *cls, const GNUNET_HashCode * key, void *value) | |||
2315 | int r; | 2417 | int r; |
2316 | 2418 | ||
2317 | send_client_tunnel_disconnect(t, c); | 2419 | send_client_tunnel_disconnect(t, c); |
2318 | if (c == t->client_dest) | 2420 | if (c != t->owner) |
2319 | { | 2421 | { |
2320 | #if MESH_DEBUG | 2422 | #if MESH_DEBUG |
2321 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2423 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2322 | "Client %u is destination, keeping the tunnel alive.\n", c->id); | 2424 | "Client %u is destination, keeping the tunnel alive.\n", c->id); |
2323 | #endif | 2425 | #endif |
2324 | t->client_dest = NULL; | 2426 | tunnel_delete_client (t, c); |
2325 | t->local_tid_dest = 0; | ||
2326 | return GNUNET_OK; | 2427 | return GNUNET_OK; |
2327 | } | 2428 | } |
2328 | tunnel_send_destroy(t); | 2429 | tunnel_send_destroy(t); |
@@ -2629,7 +2730,7 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2629 | t->id.tid = tid; | 2730 | t->id.tid = tid; |
2630 | while (NULL != tunnel_get_incoming (next_local_tid)) | 2731 | while (NULL != tunnel_get_incoming (next_local_tid)) |
2631 | next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV; | 2732 | next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV; |
2632 | t->local_tid = next_local_tid++; | 2733 | t->local_tid_dest = next_local_tid++; |
2633 | next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV; | 2734 | next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV; |
2634 | t->tree = tree_new (t->id.oid); | 2735 | t->tree = tree_new (t->id.oid); |
2635 | 2736 | ||
@@ -2643,7 +2744,7 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2643 | return GNUNET_OK; | 2744 | return GNUNET_OK; |
2644 | } | 2745 | } |
2645 | tunnel_reset_timeout (t); | 2746 | tunnel_reset_timeout (t); |
2646 | GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash); | 2747 | GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash); |
2647 | if (GNUNET_OK != | 2748 | if (GNUNET_OK != |
2648 | GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t, | 2749 | GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t, |
2649 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 2750 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
@@ -2708,16 +2809,7 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2708 | peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_NO); | 2809 | peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_NO); |
2709 | if (NULL == t->peers) | 2810 | if (NULL == t->peers) |
2710 | { | 2811 | { |
2711 | /* New tunnel! Notify clients! */ | 2812 | /* New tunnel! Notify clients on data. */ |
2712 | struct GNUNET_MESH_TunnelNotification cmsg; | ||
2713 | |||
2714 | cmsg.header.size = htons (sizeof (cmsg)); | ||
2715 | cmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE); | ||
2716 | GNUNET_PEER_resolve (t->id.oid, &cmsg.peer); | ||
2717 | cmsg.tunnel_id = htonl (t->local_tid); | ||
2718 | GNUNET_SERVER_notification_context_broadcast (nc, &cmsg.header, | ||
2719 | GNUNET_NO); | ||
2720 | |||
2721 | t->peers = GNUNET_CONTAINER_multihashmap_create (4); | 2813 | t->peers = GNUNET_CONTAINER_multihashmap_create (4); |
2722 | } | 2814 | } |
2723 | GNUNET_break (GNUNET_OK == | 2815 | GNUNET_break (GNUNET_OK == |
@@ -2832,6 +2924,9 @@ handle_mesh_path_destroy (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2832 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Own position: %u\n", own_pos); | 2924 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Own position: %u\n", own_pos); |
2833 | if (own_pos < path->length - 1) | 2925 | if (own_pos < path->length - 1) |
2834 | send_message (message, &pi[own_pos + 1]); | 2926 | send_message (message, &pi[own_pos + 1]); |
2927 | else | ||
2928 | send_client_tunnel_disconnect(t, NULL); | ||
2929 | |||
2835 | tunnel_delete_peer (t, path->peers[path->length - 1]); | 2930 | tunnel_delete_peer (t, path->peers[path->length - 1]); |
2836 | path_destroy (path); | 2931 | path_destroy (path); |
2837 | return GNUNET_OK; | 2932 | return GNUNET_OK; |
@@ -3118,7 +3213,7 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3118 | 3213 | ||
3119 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3214 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3120 | "MESH: it's for us! sending to clients...\n"); | 3215 | "MESH: it's for us! sending to clients...\n"); |
3121 | if (NULL == t->client) | 3216 | if (NULL == t->owner) |
3122 | { | 3217 | { |
3123 | /* got data packet for ownerless tunnel */ | 3218 | /* got data packet for ownerless tunnel */ |
3124 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: no clients!\n"); | 3219 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: no clients!\n"); |
@@ -3129,7 +3224,7 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3129 | memcpy (cbuf, message, size); | 3224 | memcpy (cbuf, message, size); |
3130 | copy = (struct GNUNET_MESH_ToOrigin *) cbuf; | 3225 | copy = (struct GNUNET_MESH_ToOrigin *) cbuf; |
3131 | copy->tid = htonl (t->local_tid); | 3226 | copy->tid = htonl (t->local_tid); |
3132 | GNUNET_SERVER_notification_context_unicast (nc, t->client->handle, | 3227 | GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle, |
3133 | ©->header, GNUNET_YES); | 3228 | ©->header, GNUNET_YES); |
3134 | return GNUNET_OK; | 3229 | return GNUNET_OK; |
3135 | } | 3230 | } |
@@ -3202,7 +3297,7 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3202 | if (0 == memcmp (&msg->oid, &my_full_id, sizeof (struct GNUNET_PeerIdentity))) | 3297 | if (0 == memcmp (&msg->oid, &my_full_id, sizeof (struct GNUNET_PeerIdentity))) |
3203 | { | 3298 | { |
3204 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: It's for us!\n"); | 3299 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: It's for us!\n"); |
3205 | if (NULL == t->client) | 3300 | if (NULL == t->owner) |
3206 | { | 3301 | { |
3207 | GNUNET_break_op (0); | 3302 | GNUNET_break_op (0); |
3208 | return GNUNET_OK; | 3303 | return GNUNET_OK; |
@@ -3448,7 +3543,7 @@ dht_get_type_handler (void *cls, struct GNUNET_TIME_Absolute exp, | |||
3448 | GNUNET_break_op (0); | 3543 | GNUNET_break_op (0); |
3449 | return; | 3544 | return; |
3450 | } | 3545 | } |
3451 | GNUNET_assert (NULL != t->client); | 3546 | GNUNET_assert (NULL != t->owner); |
3452 | peer_info = peer_info_get (pi); | 3547 | peer_info = peer_info_get (pi); |
3453 | (void) GNUNET_CONTAINER_multihashmap_put (t->peers, &pi->hashPubKey, | 3548 | (void) GNUNET_CONTAINER_multihashmap_put (t->peers, &pi->hashPubKey, |
3454 | peer_info, | 3549 | peer_info, |
@@ -3506,12 +3601,14 @@ handle_local_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | |||
3506 | #endif | 3601 | #endif |
3507 | GNUNET_SERVER_client_drop (c->handle); | 3602 | GNUNET_SERVER_client_drop (c->handle); |
3508 | c->shutting_down = GNUNET_YES; | 3603 | c->shutting_down = GNUNET_YES; |
3509 | if (NULL != c->tunnels) | 3604 | GNUNET_assert (NULL != c->own_tunnels); |
3510 | { | 3605 | GNUNET_assert (NULL != c->incoming_tunnels); |
3511 | GNUNET_CONTAINER_multihashmap_iterate (c->tunnels, | 3606 | GNUNET_CONTAINER_multihashmap_iterate (c->own_tunnels, |
3512 | &tunnel_destroy_iterator, c); | 3607 | &tunnel_destroy_iterator, c); |
3513 | GNUNET_CONTAINER_multihashmap_destroy (c->tunnels); | 3608 | GNUNET_CONTAINER_multihashmap_iterate (c->incoming_tunnels, |
3514 | } | 3609 | &tunnel_destroy_iterator, c); |
3610 | GNUNET_CONTAINER_multihashmap_destroy (c->own_tunnels); | ||
3611 | GNUNET_CONTAINER_multihashmap_destroy (c->incoming_tunnels); | ||
3515 | 3612 | ||
3516 | /* deregister clients applications */ | 3613 | /* deregister clients applications */ |
3517 | if (NULL != c->apps) | 3614 | if (NULL != c->apps) |
@@ -3638,7 +3735,8 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client, | |||
3638 | "MESH: client has %u+%u subscriptions\n", napps, ntypes); | 3735 | "MESH: client has %u+%u subscriptions\n", napps, ntypes); |
3639 | 3736 | ||
3640 | GNUNET_CONTAINER_DLL_insert (clients, clients_tail, c); | 3737 | GNUNET_CONTAINER_DLL_insert (clients, clients_tail, c); |
3641 | c->tunnels = GNUNET_CONTAINER_multihashmap_create (32); | 3738 | c->own_tunnels = GNUNET_CONTAINER_multihashmap_create (32); |
3739 | c->incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32); | ||
3642 | GNUNET_SERVER_notification_context_add (nc, client); | 3740 | GNUNET_SERVER_notification_context_add (nc, client); |
3643 | 3741 | ||
3644 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 3742 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
@@ -3712,12 +3810,12 @@ handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client, | |||
3712 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: CREATED TUNNEL %s [%x] (%x)\n", | 3810 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: CREATED TUNNEL %s [%x] (%x)\n", |
3713 | GNUNET_i2s (&my_full_id), t->id.tid, t->local_tid); | 3811 | GNUNET_i2s (&my_full_id), t->id.tid, t->local_tid); |
3714 | #endif | 3812 | #endif |
3715 | t->client = c; | 3813 | t->owner = c; |
3716 | t->peers = GNUNET_CONTAINER_multihashmap_create (32); | 3814 | t->peers = GNUNET_CONTAINER_multihashmap_create (32); |
3717 | 3815 | ||
3718 | GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash); | 3816 | GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash); |
3719 | if (GNUNET_OK != | 3817 | if (GNUNET_OK != |
3720 | GNUNET_CONTAINER_multihashmap_put (c->tunnels, &hash, t, | 3818 | GNUNET_CONTAINER_multihashmap_put (c->own_tunnels, &hash, t, |
3721 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | 3819 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) |
3722 | { | 3820 | { |
3723 | GNUNET_break (0); | 3821 | GNUNET_break (0); |
@@ -3785,23 +3883,35 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client, | |||
3785 | 3883 | ||
3786 | /* Remove from local id hashmap */ | 3884 | /* Remove from local id hashmap */ |
3787 | GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash); | 3885 | GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash); |
3788 | t = GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash); | 3886 | t = GNUNET_CONTAINER_multihashmap_get (c->own_tunnels, &hash); |
3789 | send_client_tunnel_disconnect(t, c); | 3887 | send_client_tunnel_disconnect(t, c); |
3790 | GNUNET_assert (GNUNET_YES == | 3888 | if (c != t->owner) |
3791 | GNUNET_CONTAINER_multihashmap_remove (c->tunnels, &hash, t)); | 3889 | { |
3792 | if (c == t->client_dest) | 3890 | tunnel_delete_client (t, c); |
3793 | { | 3891 | if (t->nclients == 0) |
3794 | GNUNET_assert (GNUNET_YES == | 3892 | { |
3795 | GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t)); | 3893 | // TODO: destroy tunnel? what if a packet comes with another message type? |
3796 | GNUNET_assert (GNUNET_YES == | 3894 | #if 0 |
3797 | GNUNET_CONTAINER_multihashmap_remove (t->peers, &my_full_id.hashPubKey, t)); | 3895 | GNUNET_assert (GNUNET_YES == |
3798 | t->client_dest = NULL; | 3896 | GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, |
3897 | &hash, t)); | ||
3898 | #endif | ||
3899 | GNUNET_assert (GNUNET_YES == | ||
3900 | GNUNET_CONTAINER_multihashmap_remove (t->peers, | ||
3901 | &my_full_id.hashPubKey, | ||
3902 | t)); | ||
3903 | } | ||
3799 | t->local_tid_dest = 0; | 3904 | t->local_tid_dest = 0; |
3800 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 3905 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
3801 | return; | 3906 | return; |
3802 | } | 3907 | } |
3908 | GNUNET_assert (GNUNET_YES == | ||
3909 | GNUNET_CONTAINER_multihashmap_remove (c->own_tunnels, | ||
3910 | &hash, | ||
3911 | t)); | ||
3803 | 3912 | ||
3804 | t->client = NULL; | 3913 | /* Don't try to ACK the client about the tunnel_destroy multicast packet */ |
3914 | t->owner = NULL; | ||
3805 | tunnel_send_destroy (t); | 3915 | tunnel_send_destroy (t); |
3806 | tunnel_destroy (t); | 3916 | tunnel_destroy (t); |
3807 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 3917 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
@@ -3855,7 +3965,7 @@ handle_local_connect_add (void *cls, struct GNUNET_SERVER_Client *client, | |||
3855 | } | 3965 | } |
3856 | 3966 | ||
3857 | /* Does client own tunnel? */ | 3967 | /* Does client own tunnel? */ |
3858 | if (t->client->handle != client) | 3968 | if (t->owner->handle != client) |
3859 | { | 3969 | { |
3860 | GNUNET_break (0); | 3970 | GNUNET_break (0); |
3861 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 3971 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -3919,7 +4029,7 @@ handle_local_connect_del (void *cls, struct GNUNET_SERVER_Client *client, | |||
3919 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: on tunnel %X\n", t->id.tid); | 4029 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: on tunnel %X\n", t->id.tid); |
3920 | 4030 | ||
3921 | /* Does client own tunnel? */ | 4031 | /* Does client own tunnel? */ |
3922 | if (t->client->handle != client) | 4032 | if (t->owner->handle != client) |
3923 | { | 4033 | { |
3924 | GNUNET_break (0); | 4034 | GNUNET_break (0); |
3925 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 4035 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -3996,7 +4106,7 @@ handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client, | |||
3996 | } | 4106 | } |
3997 | 4107 | ||
3998 | /* Does client own tunnel? */ | 4108 | /* Does client own tunnel? */ |
3999 | if (t->client->handle != client) | 4109 | if (t->owner->handle != client) |
4000 | { | 4110 | { |
4001 | GNUNET_break (0); | 4111 | GNUNET_break (0); |
4002 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 4112 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -4013,38 +4123,23 @@ handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client, | |||
4013 | /* Yes! Fast forward, add ourselves to the tunnel and send the | 4123 | /* Yes! Fast forward, add ourselves to the tunnel and send the |
4014 | * good news to the client, and alert the destination client of | 4124 | * good news to the client, and alert the destination client of |
4015 | * an incoming tunnel. | 4125 | * an incoming tunnel. |
4126 | * | ||
4127 | * FIXME send a path create to self, avoid code duplication | ||
4016 | */ | 4128 | */ |
4017 | struct GNUNET_MESH_TunnelNotification cmsg; | ||
4018 | struct MeshClient *c; | ||
4019 | |||
4020 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: available locally\n"); | 4129 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: available locally\n"); |
4021 | GNUNET_CONTAINER_multihashmap_put (t->peers, &my_full_id.hashPubKey, | 4130 | GNUNET_CONTAINER_multihashmap_put (t->peers, &my_full_id.hashPubKey, |
4022 | peer_info_get (&my_full_id), | 4131 | peer_info_get (&my_full_id), |
4023 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 4132 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
4024 | 4133 | ||
4025 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: notifying client\n"); | 4134 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: notifying client\n"); |
4026 | send_client_peer_connected (t, myid); | 4135 | send_client_peer_connected (t, myid); |
4027 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Done\n"); | 4136 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Done\n"); |
4028 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 4137 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
4029 | 4138 | ||
4030 | /* FIXME implement a proper handling of this case, | ||
4031 | a client differentiation mechanism */ | ||
4032 | cmsg.header.size = htons (sizeof (cmsg)); | ||
4033 | cmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE); | ||
4034 | cmsg.peer = my_full_id; | ||
4035 | t->local_tid_dest = next_local_tid++; | 4139 | t->local_tid_dest = next_local_tid++; |
4036 | cmsg.tunnel_id = htonl (t->local_tid_dest); | ||
4037 | c = (struct MeshClient *) GNUNET_CONTAINER_multihashmap_get(applications, | ||
4038 | &hash); | ||
4039 | t->client_dest = c; | ||
4040 | GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash); | 4140 | GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash); |
4041 | GNUNET_CONTAINER_multihashmap_put (c->tunnels, &hash, t, | ||
4042 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
4043 | GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t, | 4141 | GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t, |
4044 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 4142 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
4045 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, &cmsg.header, | ||
4046 | GNUNET_NO); | ||
4047 | |||
4048 | 4143 | ||
4049 | return; | 4144 | return; |
4050 | } | 4145 | } |
@@ -4117,8 +4212,7 @@ handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client, | |||
4117 | } | 4212 | } |
4118 | 4213 | ||
4119 | /* Is it a local tunnel? Then, does client own the tunnel? */ | 4214 | /* Is it a local tunnel? Then, does client own the tunnel? */ |
4120 | if (NULL != t->client && NULL != t->client->handle && | 4215 | if (t->owner->handle != client) |
4121 | t->client->handle != client) | ||
4122 | { | 4216 | { |
4123 | GNUNET_break (0); | 4217 | GNUNET_break (0); |
4124 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 4218 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -4174,9 +4268,6 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client, | |||
4174 | MESH_TunnelNumber tid; | 4268 | MESH_TunnelNumber tid; |
4175 | size_t size; | 4269 | size_t size; |
4176 | 4270 | ||
4177 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
4178 | "MESH: Got a ToOrigin request from a client!\n"); | ||
4179 | |||
4180 | /* Sanity check for client registration */ | 4271 | /* Sanity check for client registration */ |
4181 | if (NULL == (c = client_get (client))) | 4272 | if (NULL == (c = client_get (client))) |
4182 | { | 4273 | { |
@@ -4197,6 +4288,10 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client, | |||
4197 | 4288 | ||
4198 | /* Tunnel exists? */ | 4289 | /* Tunnel exists? */ |
4199 | tid = ntohl (data_msg->tid); | 4290 | tid = ntohl (data_msg->tid); |
4291 | #if MESH_DEBUG | ||
4292 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
4293 | "MESH: Got a ToOrigin request from a client! Tunnel %X\n", tid); | ||
4294 | #endif | ||
4200 | if (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV) | 4295 | if (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV) |
4201 | { | 4296 | { |
4202 | GNUNET_break (0); | 4297 | GNUNET_break (0); |
@@ -4211,8 +4306,8 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client, | |||
4211 | return; | 4306 | return; |
4212 | } | 4307 | } |
4213 | 4308 | ||
4214 | /* It shouldn't be a local tunnel. */ | 4309 | /* It should be sent by someone who has this as incoming tunnel. */ |
4215 | if (NULL != t->client && NULL == t->client_dest) | 4310 | if (-1 == tunnel_get_client_index (t, c)) |
4216 | { | 4311 | { |
4217 | GNUNET_break (0); | 4312 | GNUNET_break (0); |
4218 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 4313 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -4289,7 +4384,7 @@ handle_local_multicast (void *cls, struct GNUNET_SERVER_Client *client, | |||
4289 | } | 4384 | } |
4290 | 4385 | ||
4291 | /* Does client own tunnel? */ | 4386 | /* Does client own tunnel? */ |
4292 | if (t->client->handle != client) | 4387 | if (t->owner->handle != client) |
4293 | { | 4388 | { |
4294 | GNUNET_break (0); | 4389 | GNUNET_break (0); |
4295 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 4390 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |