diff options
-rw-r--r-- | src/mesh/gnunet-service-mesh.c | 174 | ||||
-rw-r--r-- | src/mesh/test_mesh_local_traffic.c | 2 |
2 files changed, 167 insertions, 9 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index 24a1c4611..93bfbf579 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c | |||
@@ -303,7 +303,7 @@ struct MeshTunnel | |||
303 | struct GNUNET_CONTAINER_MultiHashMap *children_fc; | 303 | struct GNUNET_CONTAINER_MultiHashMap *children_fc; |
304 | 304 | ||
305 | /** | 305 | /** |
306 | * Last ACK. | 306 | * Last ACK sent towards the origin. |
307 | */ | 307 | */ |
308 | uint32_t last_ack; | 308 | uint32_t last_ack; |
309 | 309 | ||
@@ -366,17 +366,22 @@ struct MeshTunnel | |||
366 | struct MeshClient *owner; | 366 | struct MeshClient *owner; |
367 | 367 | ||
368 | /** | 368 | /** |
369 | * Clients that have been informed about the tunnel, if any | 369 | * Clients that have been informed about and want to stay in the tunnel. |
370 | */ | 370 | */ |
371 | struct MeshClient **clients; | 371 | struct MeshClient **clients; |
372 | 372 | ||
373 | /** | 373 | /** |
374 | * Number of elements in clients | 374 | * ACK value of each active client. |
375 | */ | ||
376 | uint32_t *clients_acks; | ||
377 | |||
378 | /** | ||
379 | * Number of elements in clients/clients_acks | ||
375 | */ | 380 | */ |
376 | unsigned int nclients; | 381 | unsigned int nclients; |
377 | 382 | ||
378 | /** | 383 | /** |
379 | * Clients that have requested to leave the tunnel | 384 | * Clients that have been informed but requested to leave the tunnel. |
380 | */ | 385 | */ |
381 | struct MeshClient **ignore; | 386 | struct MeshClient **ignore; |
382 | 387 | ||
@@ -986,6 +991,15 @@ tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1, | |||
986 | static uint32_t | 991 | static uint32_t |
987 | tunnel_get_ack (struct MeshTunnel *t); | 992 | tunnel_get_ack (struct MeshTunnel *t); |
988 | 993 | ||
994 | /** | ||
995 | * Add a client to a tunnel, initializing all needed data structures. | ||
996 | * | ||
997 | * @param t Tunnel to which add the client. | ||
998 | * @param c Client which to add to the tunnel. | ||
999 | */ | ||
1000 | static void | ||
1001 | tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c); | ||
1002 | |||
989 | 1003 | ||
990 | /** | 1004 | /** |
991 | * Iterator over edges in a regex block retrieved from the DHT. | 1005 | * Iterator over edges in a regex block retrieved from the DHT. |
@@ -1757,7 +1771,7 @@ client_ignore_tunnel (struct MeshClient *c, struct MeshTunnel *t) | |||
1757 | { | 1771 | { |
1758 | struct GNUNET_HashCode hash; | 1772 | struct GNUNET_HashCode hash; |
1759 | 1773 | ||
1760 | GNUNET_CRYPTO_hash(&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash); | 1774 | GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash); |
1761 | GNUNET_break (GNUNET_YES == | 1775 | GNUNET_break (GNUNET_YES == |
1762 | GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels, | 1776 | GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels, |
1763 | &hash, t)); | 1777 | &hash, t)); |
@@ -1888,7 +1902,7 @@ send_subscribed_clients (const struct GNUNET_MessageHeader *msg, | |||
1888 | tmsg.tunnel_id = htonl (t->local_tid_dest); | 1902 | tmsg.tunnel_id = htonl (t->local_tid_dest); |
1889 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, | 1903 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, |
1890 | &tmsg.header, GNUNET_NO); | 1904 | &tmsg.header, GNUNET_NO); |
1891 | GNUNET_array_append (t->clients, t->nclients, c); | 1905 | tunnel_add_client (t, c); |
1892 | GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), | 1906 | GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), |
1893 | &hash); | 1907 | &hash); |
1894 | GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put ( | 1908 | GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put ( |
@@ -2855,7 +2869,10 @@ tunnel_delete_active_client (struct MeshTunnel *t, const struct MeshClient *c) | |||
2855 | if (t->clients[i] == c) | 2869 | if (t->clients[i] == c) |
2856 | { | 2870 | { |
2857 | t->clients[i] = t->clients[t->nclients - 1]; | 2871 | t->clients[i] = t->clients[t->nclients - 1]; |
2872 | t->clients_acks[i] = t->clients_acks[t->nclients - 1]; | ||
2858 | GNUNET_array_grow (t->clients, t->nclients, t->nclients - 1); | 2873 | GNUNET_array_grow (t->clients, t->nclients, t->nclients - 1); |
2874 | t->nclients++; | ||
2875 | GNUNET_array_grow (t->clients_acks, t->nclients, t->nclients - 1); | ||
2859 | break; | 2876 | break; |
2860 | } | 2877 | } |
2861 | } | 2878 | } |
@@ -3266,7 +3283,8 @@ tunnel_get_child_ack (void *cls, | |||
3266 | 3283 | ||
3267 | /** | 3284 | /** |
3268 | * Get the maximum PID allowed to transmit to any | 3285 | * Get the maximum PID allowed to transmit to any |
3269 | * tunnel child of the local peer. | 3286 | * tunnel child of the local peer, depending on the tunnel |
3287 | * buffering/speed settings. | ||
3270 | * | 3288 | * |
3271 | * @param t Tunnel. | 3289 | * @param t Tunnel. |
3272 | * | 3290 | * |
@@ -3282,6 +3300,105 @@ tunnel_get_children_ack (struct MeshTunnel *t) | |||
3282 | 3300 | ||
3283 | 3301 | ||
3284 | /** | 3302 | /** |
3303 | * Add a client to a tunnel, initializing all needed data structures. | ||
3304 | * | ||
3305 | * @param t Tunnel to which add the client. | ||
3306 | * @param c Client which to add to the tunnel. | ||
3307 | */ | ||
3308 | static void | ||
3309 | tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c) | ||
3310 | { | ||
3311 | uint32_t ack; | ||
3312 | |||
3313 | GNUNET_array_append (t->clients, t->nclients, c); | ||
3314 | t->nclients--; | ||
3315 | ack = t->pid + 1; | ||
3316 | GNUNET_array_append (t->clients_acks, t->nclients, ack); | ||
3317 | } | ||
3318 | |||
3319 | |||
3320 | /** | ||
3321 | * Set the ACK value of a client in a particular tunnel. | ||
3322 | * | ||
3323 | * @param t Tunnel affected. | ||
3324 | * @param c Client whose ACK to set. | ||
3325 | * @param ack ACK value. | ||
3326 | */ | ||
3327 | static void | ||
3328 | tunnel_set_client_ack (struct MeshTunnel *t, | ||
3329 | struct MeshClient *c, | ||
3330 | uint32_t ack) | ||
3331 | { | ||
3332 | unsigned int i; | ||
3333 | |||
3334 | for (i = 0; i < t->nclients; i++) | ||
3335 | { | ||
3336 | if (t->clients[i] != c) | ||
3337 | continue; | ||
3338 | t->clients_acks[i] = ack; | ||
3339 | return; | ||
3340 | } | ||
3341 | GNUNET_break (0); | ||
3342 | } | ||
3343 | |||
3344 | |||
3345 | /** | ||
3346 | * Get the ACK value of a client in a particular tunnel. | ||
3347 | * | ||
3348 | * @param t Tunnel on which to look. | ||
3349 | * @param c Client whose ACK to get. | ||
3350 | * | ||
3351 | * @return ACK value. | ||
3352 | */ | ||
3353 | uint32_t // FIXME static when used!! | ||
3354 | tunnel_get_client_ack (struct MeshTunnel *t, | ||
3355 | struct MeshClient *c) | ||
3356 | { | ||
3357 | unsigned int i; | ||
3358 | |||
3359 | for (i = 0; i < t->nclients; i++) | ||
3360 | { | ||
3361 | if (t->clients[i] != c) | ||
3362 | continue; | ||
3363 | return t->clients_acks[i]; | ||
3364 | } | ||
3365 | GNUNET_break (0); | ||
3366 | return t->clients_acks[0]; | ||
3367 | } | ||
3368 | |||
3369 | |||
3370 | /** | ||
3371 | * Get the highest ACK value of all clients in a particular tunnel, | ||
3372 | * according to the buffering/speed settings. | ||
3373 | * | ||
3374 | * @param t Tunnel on which to look. | ||
3375 | * | ||
3376 | * @return Corresponding ACK value. | ||
3377 | */ | ||
3378 | static uint32_t | ||
3379 | tunnel_get_clients_ack (struct MeshTunnel *t) | ||
3380 | { | ||
3381 | unsigned int i; | ||
3382 | uint32_t ack; | ||
3383 | |||
3384 | for (ack = 0, i = 0; i < t->nclients; i++) | ||
3385 | { | ||
3386 | if (0 == ack || | ||
3387 | (GNUNET_YES == t->speed_min && t->clients_acks[i] < ack) || | ||
3388 | (GNUNET_NO == t->speed_min && t->clients_acks[i] > ack)) | ||
3389 | { | ||
3390 | ack = t->clients_acks[i]; | ||
3391 | } | ||
3392 | } | ||
3393 | |||
3394 | if (GNUNET_YES == t->nobuffer && ack > t->pid) | ||
3395 | ack = t->pid + 1; | ||
3396 | |||
3397 | return ack; | ||
3398 | } | ||
3399 | |||
3400 | |||
3401 | /** | ||
3285 | * Get the current ack value for a tunnel, taking in account the tunnel | 3402 | * Get the current ack value for a tunnel, taking in account the tunnel |
3286 | * mode and the status of all children nodes. | 3403 | * mode and the status of all children nodes. |
3287 | * | 3404 | * |
@@ -3295,22 +3412,27 @@ tunnel_get_ack (struct MeshTunnel *t) | |||
3295 | uint32_t count; | 3412 | uint32_t count; |
3296 | uint32_t buffer_free; | 3413 | uint32_t buffer_free; |
3297 | uint32_t child_ack; | 3414 | uint32_t child_ack; |
3415 | uint32_t client_ack; | ||
3298 | uint32_t ack; | 3416 | uint32_t ack; |
3299 | 3417 | ||
3300 | count = t->pid - t->skip; | 3418 | count = t->pid - t->skip; |
3301 | buffer_free = t->queue_max - t->queue_n; | 3419 | buffer_free = t->queue_max - t->queue_n; |
3302 | ack = count + buffer_free; | 3420 | ack = count + buffer_free; |
3303 | child_ack = tunnel_get_children_ack (t); | 3421 | child_ack = tunnel_get_children_ack (t); |
3422 | client_ack = tunnel_get_clients_ack (t); | ||
3304 | 3423 | ||
3305 | if (GNUNET_YES == t->speed_min) | 3424 | if (GNUNET_YES == t->speed_min) |
3306 | { | 3425 | { |
3307 | ack = child_ack > ack ? ack : child_ack; | 3426 | ack = child_ack > ack ? ack : child_ack; |
3427 | ack = client_ack > ack ? ack : client_ack; | ||
3308 | } | 3428 | } |
3309 | else | 3429 | else |
3310 | { | 3430 | { |
3311 | ack = child_ack > ack ? child_ack : ack; | 3431 | ack = child_ack > ack ? child_ack : ack; |
3432 | ack = client_ack > ack ? client_ack : ack; | ||
3312 | } | 3433 | } |
3313 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "c %u, bf %u, ch %u\n", count, buffer_free, child_ack); | 3434 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "c %u, bf %u, ch %u, cl %u\n", |
3435 | count, buffer_free, child_ack, client_ack); | ||
3314 | return ack; | 3436 | return ack; |
3315 | } | 3437 | } |
3316 | 3438 | ||
@@ -6449,6 +6571,42 @@ static void | |||
6449 | handle_local_ack (void *cls, struct GNUNET_SERVER_Client *client, | 6571 | handle_local_ack (void *cls, struct GNUNET_SERVER_Client *client, |
6450 | const struct GNUNET_MessageHeader *message) | 6572 | const struct GNUNET_MessageHeader *message) |
6451 | { | 6573 | { |
6574 | struct GNUNET_MESH_LocalAck *msg; | ||
6575 | struct MeshTunnel *t; | ||
6576 | struct MeshClient *c; | ||
6577 | MESH_TunnelNumber tid; | ||
6578 | |||
6579 | /* Sanity check for client registration */ | ||
6580 | if (NULL == (c = client_get (client))) | ||
6581 | { | ||
6582 | GNUNET_break (0); | ||
6583 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
6584 | return; | ||
6585 | } | ||
6586 | |||
6587 | msg = (struct GNUNET_MESH_LocalAck *) message; | ||
6588 | /* Tunnel exists? */ | ||
6589 | tid = ntohl (msg->tunnel_id); | ||
6590 | t = tunnel_get_by_local_id (c, tid); | ||
6591 | if (NULL == t) | ||
6592 | { | ||
6593 | GNUNET_break (0); | ||
6594 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
6595 | return; | ||
6596 | } | ||
6597 | |||
6598 | /* Does client own tunnel? */ | ||
6599 | if (t->owner->handle != client) | ||
6600 | { | ||
6601 | GNUNET_break (0); | ||
6602 | // FIXME TODO | ||
6603 | } | ||
6604 | else | ||
6605 | { | ||
6606 | tunnel_set_client_ack (t, c, ntohl (msg->max_pid)); | ||
6607 | } | ||
6608 | |||
6609 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
6452 | return; | 6610 | return; |
6453 | } | 6611 | } |
6454 | 6612 | ||
diff --git a/src/mesh/test_mesh_local_traffic.c b/src/mesh/test_mesh_local_traffic.c index 0138cb623..78e1049f6 100644 --- a/src/mesh/test_mesh_local_traffic.c +++ b/src/mesh/test_mesh_local_traffic.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | 33 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) |
34 | 34 | ||
35 | #define TARGET 100 | 35 | #define TARGET 1000 |
36 | 36 | ||
37 | GNUNET_NETWORK_STRUCT_BEGIN | 37 | GNUNET_NETWORK_STRUCT_BEGIN |
38 | 38 | ||