aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-tng.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-04-22 11:48:12 +0200
committerChristian Grothoff <christian@grothoff.org>2019-04-22 11:48:12 +0200
commit38300a8d3b441cc492adcd72d4a60b861eea0e95 (patch)
tree5a1b3dd4cb7dee4fb9ec819399eb015a4ad5f262 /src/transport/gnunet-service-tng.c
parent2429db6e434feff044cafc71bd25efe104799b47 (diff)
downloadgnunet-38300a8d3b441cc492adcd72d4a60b861eea0e95.tar.gz
gnunet-38300a8d3b441cc492adcd72d4a60b861eea0e95.zip
changing UUID types (in preparation for RTT tracking)
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r--src/transport/gnunet-service-tng.c137
1 files changed, 116 insertions, 21 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index c4974ca23..a35357d9b 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -25,6 +25,21 @@
25 * TODO: 25 * TODO:
26 * Implement next: 26 * Implement next:
27 * - track RTT, distance, loss, etc. => requires extra data structures! 27 * - track RTT, distance, loss, etc. => requires extra data structures!
28 * => fragment UUIDs should be 'sequential' 32-bit numbers, for cummulative
29 * acks with Bitmask
30 * => fragments carry their own offsets, so receiver will NOT require
31 * seeing all the possible values
32 * => can generate 'fresh' UUIDs for each retransmission to track it
33 * => but need to keep 'map' of 32-bit UUID to queue!
34 * => message UUIDs are currently overkill with 256 bits
35 * => cummulative acks for messages include full UUID list
36 * => message UUID size should be chosen to result in 8 byte alignment
37 * => could encode 32-bit counter + 32-bit queue UUID in 64-bit message
38 * UUID?
39 * => Use multihashmap32 on counter for lookup in hashmap?
40 * => FIXME: 2x32 bit introduced, but still set to random value
41 * instead of using the generators!
42 * (and generators not initialized to random starting values either)
28 * - consider replacing random `struct GNUNET_ShortHashCode` message UUIDs 43 * - consider replacing random `struct GNUNET_ShortHashCode` message UUIDs
29 * with (incrementing) 64-bit numbers (compacting both 44 * with (incrementing) 64-bit numbers (compacting both
30 * `struct TransportReliabilityBox` and `struct 45 * `struct TransportReliabilityBox` and `struct
@@ -260,9 +275,16 @@ GNUNET_NETWORK_STRUCT_BEGIN
260struct MessageUUIDP 275struct MessageUUIDP
261{ 276{
262 /** 277 /**
263 * Unique value. 278 * Unique value, generated by incrementing the
279 * `message_uuid_ctr` of `struct Neighbour`.
264 */ 280 */
265 struct GNUNET_ShortHashCode uuid; // FIXME: change to 8 bytes 281 uint32_t uuid GNUNET_PACKED;
282
283 /**
284 * UUID of the queue that was used to transmit this message.
285 * Used to map acknowledgements back to the respective queue.
286 */
287 uint32_t queue_uuid GNUNET_PACKED;
266}; 288};
267 289
268 290
@@ -274,7 +296,7 @@ struct FragmentUUIDP
274 /** 296 /**
275 * Unique value identifying a fragment, in NBO. 297 * Unique value identifying a fragment, in NBO.
276 */ 298 */
277 uint32_t uuid GNUNET_PACKED; // FIXME: change to 2x 2 bytes? 299 uint32_t uuid GNUNET_PACKED;
278}; 300};
279 301
280 302
@@ -1278,6 +1300,14 @@ struct Queue
1278 uint32_t qid; 1300 uint32_t qid;
1279 1301
1280 /** 1302 /**
1303 * UUID used to map acknowledgements back to the queue that
1304 * was used for transmission. Note that @e queue_uuid-s are
1305 * only unique per neighbour (generated via `queue_uuid_gen`
1306 * of `struct Neighbour`).
1307 */
1308 uint32_t queue_uuid;
1309
1310 /**
1281 * Maximum transmission unit supported by this queue. 1311 * Maximum transmission unit supported by this queue.
1282 */ 1312 */
1283 uint32_t mtu; 1313 uint32_t mtu;
@@ -1426,7 +1456,7 @@ struct Neighbour
1426 * reassembly. May be NULL if we currently have no fragments from 1456 * reassembly. May be NULL if we currently have no fragments from
1427 * this @e pid (lazy initialization). 1457 * this @e pid (lazy initialization).
1428 */ 1458 */
1429 struct GNUNET_CONTAINER_MultiShortmap *reassembly_map; 1459 struct GNUNET_CONTAINER_MultiHashMap32 *reassembly_map;
1430 1460
1431 /** 1461 /**
1432 * Heap with `struct ReassemblyContext` structs for fragments under 1462 * Heap with `struct ReassemblyContext` structs for fragments under
@@ -1497,6 +1527,26 @@ struct Neighbour
1497 struct GNUNET_TIME_Absolute earliest_timeout; 1527 struct GNUNET_TIME_Absolute earliest_timeout;
1498 1528
1499 /** 1529 /**
1530 * Incremented by one for each queue to generate
1531 * unique queue identifiers. Initially set to a random value.
1532 *
1533 * FIXME: Deal with wrap around (might be triggered by very
1534 * persistent adversary).
1535 */
1536 uint32_t queue_uuid_gen;
1537
1538 /**
1539 * Incremented by one for each message sent to this neighbour, to
1540 * uniquely identify that message in replies (note that fragments
1541 * use another additional counter). Initially set to a random value.
1542 *
1543 * It should be safe to assume that by the time this value may wrap
1544 * around, the original message is long "gone" and no longer
1545 * relevant.
1546 */
1547 uint32_t message_uuid_ctr;
1548
1549 /**
1500 * Do we have a confirmed working queue and are thus visible to 1550 * Do we have a confirmed working queue and are thus visible to
1501 * CORE? 1551 * CORE?
1502 */ 1552 */
@@ -2421,9 +2471,9 @@ free_reassembly_context (struct ReassemblyContext *rc)
2421 2471
2422 GNUNET_assert (rc == GNUNET_CONTAINER_heap_remove_node (rc->hn)); 2472 GNUNET_assert (rc == GNUNET_CONTAINER_heap_remove_node (rc->hn));
2423 GNUNET_assert (GNUNET_OK == 2473 GNUNET_assert (GNUNET_OK ==
2424 GNUNET_CONTAINER_multishortmap_remove (n->reassembly_map, 2474 GNUNET_CONTAINER_multihashmap32_remove (n->reassembly_map,
2425 &rc->msg_uuid.uuid, 2475 rc->msg_uuid.uuid,
2426 rc)); 2476 rc));
2427 GNUNET_free (rc); 2477 GNUNET_free (rc);
2428} 2478}
2429 2479
@@ -2467,9 +2517,7 @@ reassembly_cleanup_task (void *cls)
2467 * @return #GNUNET_OK (continue iteration) 2517 * @return #GNUNET_OK (continue iteration)
2468 */ 2518 */
2469static int 2519static int
2470free_reassembly_cb (void *cls, 2520free_reassembly_cb (void *cls, uint32_t key, void *value)
2471 const struct GNUNET_ShortHashCode *key,
2472 void *value)
2473{ 2521{
2474 struct ReassemblyContext *rc = value; 2522 struct ReassemblyContext *rc = value;
2475 2523
@@ -2499,10 +2547,10 @@ free_neighbour (struct Neighbour *neighbour)
2499 GNUNET_SCHEDULER_cancel (neighbour->timeout_task); 2547 GNUNET_SCHEDULER_cancel (neighbour->timeout_task);
2500 if (NULL != neighbour->reassembly_map) 2548 if (NULL != neighbour->reassembly_map)
2501 { 2549 {
2502 GNUNET_CONTAINER_multishortmap_iterate (neighbour->reassembly_map, 2550 GNUNET_CONTAINER_multihashmap32_iterate (neighbour->reassembly_map,
2503 &free_reassembly_cb, 2551 &free_reassembly_cb,
2504 NULL); 2552 NULL);
2505 GNUNET_CONTAINER_multishortmap_destroy (neighbour->reassembly_map); 2553 GNUNET_CONTAINER_multihashmap32_destroy (neighbour->reassembly_map);
2506 neighbour->reassembly_map = NULL; 2554 neighbour->reassembly_map = NULL;
2507 GNUNET_CONTAINER_heap_destroy (neighbour->reassembly_heap); 2555 GNUNET_CONTAINER_heap_destroy (neighbour->reassembly_heap);
2508 neighbour->reassembly_heap = NULL; 2556 neighbour->reassembly_heap = NULL;
@@ -4242,6 +4290,48 @@ send_fragment_ack (struct ReassemblyContext *rc)
4242 4290
4243 4291
4244/** 4292/**
4293 * Closure for #find_by_message_uuid.
4294 */
4295struct FindByMessageUuidContext
4296{
4297 /**
4298 * UUID to look for.
4299 */
4300 struct MessageUUIDP message_uuid;
4301
4302 /**
4303 * Set to the reassembly context if found.
4304 */
4305 struct ReassemblyContext *rc;
4306};
4307
4308
4309/**
4310 * Iterator called to find a reassembly context by the message UUID in the
4311 * multihashmap32.
4312 *
4313 * @param cls a `struct FindByMessageUuidContext`
4314 * @param key a key (unused)
4315 * @param value a `struct ReassemblyContext`
4316 * @return #GNUNET_YES if not found, #GNUNET_NO if found
4317 */
4318static int
4319find_by_message_uuid (void *cls, uint32_t key, void *value)
4320{
4321 struct FindByMessageUuidContext *fc = cls;
4322 struct ReassemblyContext *rc = value;
4323
4324 (void) key;
4325 if (0 == GNUNET_memcmp (&fc->message_uuid, &rc->msg_uuid))
4326 {
4327 fc->rc = rc;
4328 return GNUNET_NO;
4329 }
4330 return GNUNET_YES;
4331}
4332
4333
4334/**
4245 * Communicator gave us a fragment. Process the request. 4335 * Communicator gave us a fragment. Process the request.
4246 * 4336 *
4247 * @param cls a `struct CommunicatorMessageContext` (must call 4337 * @param cls a `struct CommunicatorMessageContext` (must call
@@ -4262,6 +4352,7 @@ handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb)
4262 char *target; 4352 char *target;
4263 struct GNUNET_TIME_Relative cdelay; 4353 struct GNUNET_TIME_Relative cdelay;
4264 int ack_now; 4354 int ack_now;
4355 struct FindByMessageUuidContext fc;
4265 4356
4266 n = GNUNET_CONTAINER_multipeermap_get (neighbours, &cmc->im.sender); 4357 n = GNUNET_CONTAINER_multipeermap_get (neighbours, &cmc->im.sender);
4267 if (NULL == n) 4358 if (NULL == n)
@@ -4275,7 +4366,7 @@ handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb)
4275 } 4366 }
4276 if (NULL == n->reassembly_map) 4367 if (NULL == n->reassembly_map)
4277 { 4368 {
4278 n->reassembly_map = GNUNET_CONTAINER_multishortmap_create (8, GNUNET_YES); 4369 n->reassembly_map = GNUNET_CONTAINER_multihashmap32_create (8);
4279 n->reassembly_heap = 4370 n->reassembly_heap =
4280 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 4371 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
4281 n->reassembly_timeout_task = 4372 n->reassembly_timeout_task =
@@ -4284,9 +4375,13 @@ handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb)
4284 n); 4375 n);
4285 } 4376 }
4286 msize = ntohs (fb->msg_size); 4377 msize = ntohs (fb->msg_size);
4287 rc = 4378 fc.message_uuid = fb->msg_uuid;
4288 GNUNET_CONTAINER_multishortmap_get (n->reassembly_map, &fb->msg_uuid.uuid); 4379 fc.rc = NULL;
4289 if (NULL == rc) 4380 GNUNET_CONTAINER_multihashmap32_get_multiple (n->reassembly_map,
4381 fb->msg_uuid.uuid,
4382 &find_by_message_uuid,
4383 &fc);
4384 if (NULL == (rc = fc.rc))
4290 { 4385 {
4291 rc = GNUNET_malloc (sizeof (*rc) + msize + /* reassembly payload buffer */ 4386 rc = GNUNET_malloc (sizeof (*rc) + msize + /* reassembly payload buffer */
4292 (msize + 7) / 8 * sizeof (uint8_t) /* bitfield */); 4387 (msize + 7) / 8 * sizeof (uint8_t) /* bitfield */);
@@ -4300,11 +4395,11 @@ handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb)
4300 rc, 4395 rc,
4301 rc->reassembly_timeout.abs_value_us); 4396 rc->reassembly_timeout.abs_value_us);
4302 GNUNET_assert (GNUNET_OK == 4397 GNUNET_assert (GNUNET_OK ==
4303 GNUNET_CONTAINER_multishortmap_put ( 4398 GNUNET_CONTAINER_multihashmap32_put (
4304 n->reassembly_map, 4399 n->reassembly_map,
4305 &rc->msg_uuid.uuid, 4400 rc->msg_uuid.uuid,
4306 rc, 4401 rc,
4307 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 4402 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
4308 target = (char *) &rc[1]; 4403 target = (char *) &rc[1];
4309 rc->bitfield = (uint8_t *) (target + rc->msg_size); 4404 rc->bitfield = (uint8_t *) (target + rc->msg_size);
4310 rc->msg_missing = rc->msg_size; 4405 rc->msg_missing = rc->msg_size;