aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesh/gnunet-service-mesh.c174
-rw-r--r--src/mesh/test_mesh_local_traffic.c2
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,
986static uint32_t 991static uint32_t
987tunnel_get_ack (struct MeshTunnel *t); 992tunnel_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 */
1000static void
1001tunnel_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 */
3308static void
3309tunnel_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 */
3327static void
3328tunnel_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 */
3353uint32_t // FIXME static when used!!
3354tunnel_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 */
3378static uint32_t
3379tunnel_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
6449handle_local_ack (void *cls, struct GNUNET_SERVER_Client *client, 6571handle_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
37GNUNET_NETWORK_STRUCT_BEGIN 37GNUNET_NETWORK_STRUCT_BEGIN
38 38