diff options
-rw-r--r-- | src/transport/gnunet-service-tng.c | 203 |
1 files changed, 199 insertions, 4 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index 5a8bf5bc1..707fe49a7 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -33,9 +33,7 @@ | |||
33 | * transport-to-transport traffic) | 33 | * transport-to-transport traffic) |
34 | * | 34 | * |
35 | * Implement: | 35 | * Implement: |
36 | * - data structures for defragmentation | 36 | * - ACK handling / retransmission |
37 | * - manage defragmentation | ||
38 | * - ACK handling / retransmission | ||
39 | * - track RTT, distance, loss, etc. | 37 | * - track RTT, distance, loss, etc. |
40 | * - DV data structures, learning, forgetting & using them! | 38 | * - DV data structures, learning, forgetting & using them! |
41 | * | 39 | * |
@@ -610,6 +608,98 @@ struct Neighbour; | |||
610 | 608 | ||
611 | 609 | ||
612 | /** | 610 | /** |
611 | * Entry in our #dv_routes table, representing a (set of) distance | ||
612 | * vector routes to a particular peer. | ||
613 | */ | ||
614 | struct DistanceVector; | ||
615 | |||
616 | /** | ||
617 | * One possible hop towards a DV target. | ||
618 | */ | ||
619 | struct DistanceVectorHop | ||
620 | { | ||
621 | |||
622 | /** | ||
623 | * Kept in a MDLL, sorted by @e timeout. | ||
624 | */ | ||
625 | struct DistanceVectorHop *next_dv; | ||
626 | |||
627 | /** | ||
628 | * Kept in a MDLL, sorted by @e timeout. | ||
629 | */ | ||
630 | struct DistanceVectorHop *prev_dv; | ||
631 | |||
632 | /** | ||
633 | * Kept in a MDLL. | ||
634 | */ | ||
635 | struct DistanceVectorHop *next_neighbour; | ||
636 | |||
637 | /** | ||
638 | * Kept in a MDLL. | ||
639 | */ | ||
640 | struct DistanceVectorHop *prev_neighbour; | ||
641 | |||
642 | /** | ||
643 | * What would be the next hop to @e target? | ||
644 | */ | ||
645 | struct Neighbour *next_hop; | ||
646 | |||
647 | /** | ||
648 | * Distance vector entry this hop belongs with. | ||
649 | */ | ||
650 | struct DistanceVector *dv; | ||
651 | |||
652 | /** | ||
653 | * Array of @e distance hops to the target, excluding @e next_hop. | ||
654 | * NULL if the entire path is us to @e next_hop to `target`. Allocated | ||
655 | * at the end of this struct. | ||
656 | */ | ||
657 | const struct GNUNET_PeerIdentity *path; | ||
658 | |||
659 | /** | ||
660 | * At what time do we forget about this path unless we see it again | ||
661 | * while learning? | ||
662 | */ | ||
663 | struct GNUNET_TIME_Absolute timeout; | ||
664 | |||
665 | /** | ||
666 | * How many hops in total to the `target` (excluding @e next_hop and `target` itself), | ||
667 | * thus 0 still means a distance of 2 hops (to @e next_hop and then to `target`)? | ||
668 | */ | ||
669 | unsigned int distance; | ||
670 | }; | ||
671 | |||
672 | |||
673 | /** | ||
674 | * Entry in our #dv_routes table, representing a (set of) distance | ||
675 | * vector routes to a particular peer. | ||
676 | */ | ||
677 | struct DistanceVector | ||
678 | { | ||
679 | |||
680 | /** | ||
681 | * To which peer is this a route? | ||
682 | */ | ||
683 | struct GNUNET_PeerIdentity target; | ||
684 | |||
685 | /** | ||
686 | * Known paths to @e target. | ||
687 | */ | ||
688 | struct DistanceVectorHop *dv_head; | ||
689 | |||
690 | /** | ||
691 | * Known paths to @e target. | ||
692 | */ | ||
693 | struct DistanceVectorHop *dv_tail; | ||
694 | |||
695 | /** | ||
696 | * Task scheduled to purge expired paths from @e dv_head MDLL. | ||
697 | */ | ||
698 | struct GNUNET_SCHEDULER_Task *timeout_task; | ||
699 | }; | ||
700 | |||
701 | |||
702 | /** | ||
613 | * Entry identifying transmission in one of our `struct | 703 | * Entry identifying transmission in one of our `struct |
614 | * GNUNET_ATS_Sessions` which still awaits an ACK. This is used to | 704 | * GNUNET_ATS_Sessions` which still awaits an ACK. This is used to |
615 | * ensure we do not overwhelm a communicator and limit the number of | 705 | * ensure we do not overwhelm a communicator and limit the number of |
@@ -898,6 +988,18 @@ struct Neighbour | |||
898 | struct PendingMessage *pending_msg_tail; | 988 | struct PendingMessage *pending_msg_tail; |
899 | 989 | ||
900 | /** | 990 | /** |
991 | * Head of MDLL of DV hops that have this neighbour as next hop. Must be | ||
992 | * purged if this neighbour goes down. | ||
993 | */ | ||
994 | struct DistanceVectorHop *dv_head; | ||
995 | |||
996 | /** | ||
997 | * Tail of MDLL of DV hops that have this neighbour as next hop. Must be | ||
998 | * purged if this neighbour goes down. | ||
999 | */ | ||
1000 | struct DistanceVectorHop *dv_tail; | ||
1001 | |||
1002 | /** | ||
901 | * Head of DLL of ATS sessions to this peer. | 1003 | * Head of DLL of ATS sessions to this peer. |
902 | */ | 1004 | */ |
903 | struct GNUNET_ATS_Session *session_head; | 1005 | struct GNUNET_ATS_Session *session_head; |
@@ -1308,6 +1410,12 @@ static struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key; | |||
1308 | static struct GNUNET_CONTAINER_MultiPeerMap *neighbours; | 1410 | static struct GNUNET_CONTAINER_MultiPeerMap *neighbours; |
1309 | 1411 | ||
1310 | /** | 1412 | /** |
1413 | * Map from PIDs to `struct DistanceVector` entries describing | ||
1414 | * known paths to the peer. | ||
1415 | */ | ||
1416 | static struct GNUNET_CONTAINER_MultiPeerMap *dv_routes; | ||
1417 | |||
1418 | /** | ||
1311 | * Database for peer's HELLOs. | 1419 | * Database for peer's HELLOs. |
1312 | */ | 1420 | */ |
1313 | static struct GNUNET_PEERSTORE_Handle *peerstore; | 1421 | static struct GNUNET_PEERSTORE_Handle *peerstore; |
@@ -1405,6 +1513,56 @@ struct MonitorEvent | |||
1405 | 1513 | ||
1406 | 1514 | ||
1407 | /** | 1515 | /** |
1516 | * Free a @dvh, and if it is the last path to the `target`,also | ||
1517 | * free the associated DV entry in #dv_routes. | ||
1518 | * | ||
1519 | * @param dvh hop to free | ||
1520 | */ | ||
1521 | static void | ||
1522 | free_distance_vector_hop (struct DistanceVectorHop *dvh) | ||
1523 | { | ||
1524 | struct Neighbour *n = dvh->next_hop; | ||
1525 | struct DistanceVector *dv = dvh->dv; | ||
1526 | |||
1527 | GNUNET_CONTAINER_MDLL_remove (neighbour, | ||
1528 | n->dv_head, | ||
1529 | n->dv_tail, | ||
1530 | dvh); | ||
1531 | GNUNET_CONTAINER_MDLL_remove (dv, | ||
1532 | dv->dv_head, | ||
1533 | dv->dv_tail, | ||
1534 | dvh); | ||
1535 | GNUNET_free (dvh); | ||
1536 | if (NULL == dv->dv_head) | ||
1537 | { | ||
1538 | GNUNET_assert (GNUNET_YES == | ||
1539 | GNUNET_CONTAINER_multipeermap_remove (dv_routes, | ||
1540 | &dv->target, | ||
1541 | dv)); | ||
1542 | if (NULL != dv->timeout_task) | ||
1543 | GNUNET_SCHEDULER_cancel (dv->timeout_task); | ||
1544 | GNUNET_free (dv); | ||
1545 | } | ||
1546 | } | ||
1547 | |||
1548 | |||
1549 | /** | ||
1550 | * Free entry in #dv_routes. First frees all hops to the target, and | ||
1551 | * the last target will implicitly free @a dv as well. | ||
1552 | * | ||
1553 | * @param dv route to free | ||
1554 | */ | ||
1555 | static void | ||
1556 | free_dv_route (struct DistanceVector *dv) | ||
1557 | { | ||
1558 | struct DistanceVectorHop *dvh; | ||
1559 | |||
1560 | while (NULL != (dvh = dv->dv_head)) | ||
1561 | free_distance_vector_hop (dvh); | ||
1562 | } | ||
1563 | |||
1564 | |||
1565 | /** | ||
1408 | * Notify monitor @a tc about an event. That @a tc | 1566 | * Notify monitor @a tc about an event. That @a tc |
1409 | * cares about the event has already been checked. | 1567 | * cares about the event has already been checked. |
1410 | * | 1568 | * |
@@ -1596,6 +1754,8 @@ free_reassembly_cb (void *cls, | |||
1596 | static void | 1754 | static void |
1597 | free_neighbour (struct Neighbour *neighbour) | 1755 | free_neighbour (struct Neighbour *neighbour) |
1598 | { | 1756 | { |
1757 | struct DistanceVectorHop *dvh; | ||
1758 | |||
1599 | GNUNET_assert (NULL == neighbour->session_head); | 1759 | GNUNET_assert (NULL == neighbour->session_head); |
1600 | GNUNET_assert (GNUNET_YES == | 1760 | GNUNET_assert (GNUNET_YES == |
1601 | GNUNET_CONTAINER_multipeermap_remove (neighbours, | 1761 | GNUNET_CONTAINER_multipeermap_remove (neighbours, |
@@ -1613,6 +1773,8 @@ free_neighbour (struct Neighbour *neighbour) | |||
1613 | GNUNET_CONTAINER_heap_destroy (neighbour->reassembly_heap); | 1773 | GNUNET_CONTAINER_heap_destroy (neighbour->reassembly_heap); |
1614 | neighbour->reassembly_heap = NULL; | 1774 | neighbour->reassembly_heap = NULL; |
1615 | } | 1775 | } |
1776 | while (NULL != (dvh = neighbour->dv_head)) | ||
1777 | free_distance_vector_hop (dvh); | ||
1616 | if (NULL != neighbour->reassembly_timeout_task) | 1778 | if (NULL != neighbour->reassembly_timeout_task) |
1617 | GNUNET_SCHEDULER_cancel (neighbour->reassembly_timeout_task); | 1779 | GNUNET_SCHEDULER_cancel (neighbour->reassembly_timeout_task); |
1618 | GNUNET_free (neighbour); | 1780 | GNUNET_free (neighbour); |
@@ -3019,7 +3181,10 @@ handle_fragment_ack (void *cls, | |||
3019 | { | 3181 | { |
3020 | struct CommunicatorMessageContext *cmc = cls; | 3182 | struct CommunicatorMessageContext *cmc = cls; |
3021 | 3183 | ||
3022 | // FIXME: do work! | 3184 | // FIXME: do work: identify original message; then identify fragments being acked; |
3185 | // remove those from the tree to prevent retransmission; | ||
3186 | // compute RTT | ||
3187 | // if entire message is ACKed, handle that as well. | ||
3023 | finish_cmc_handling (cmc); | 3188 | finish_cmc_handling (cmc); |
3024 | } | 3189 | } |
3025 | 3190 | ||
@@ -4372,6 +4537,29 @@ free_neighbour_cb (void *cls, | |||
4372 | 4537 | ||
4373 | 4538 | ||
4374 | /** | 4539 | /** |
4540 | * Free DV route entry. | ||
4541 | * | ||
4542 | * @param cls NULL | ||
4543 | * @param pid unused | ||
4544 | * @param value a `struct DistanceVector` | ||
4545 | * @return #GNUNET_OK (always) | ||
4546 | */ | ||
4547 | static int | ||
4548 | free_dv_routes_cb (void *cls, | ||
4549 | const struct GNUNET_PeerIdentity *pid, | ||
4550 | void *value) | ||
4551 | { | ||
4552 | struct DistanceVector *dv = value; | ||
4553 | |||
4554 | (void) cls; | ||
4555 | (void) pid; | ||
4556 | free_dv_route (dv); | ||
4557 | |||
4558 | return GNUNET_OK; | ||
4559 | } | ||
4560 | |||
4561 | |||
4562 | /** | ||
4375 | * Free ephemeral entry. | 4563 | * Free ephemeral entry. |
4376 | * | 4564 | * |
4377 | * @param cls NULL | 4565 | * @param cls NULL |
@@ -4436,6 +4624,11 @@ do_shutdown (void *cls) | |||
4436 | } | 4624 | } |
4437 | GNUNET_CONTAINER_multipeermap_destroy (neighbours); | 4625 | GNUNET_CONTAINER_multipeermap_destroy (neighbours); |
4438 | neighbours = NULL; | 4626 | neighbours = NULL; |
4627 | GNUNET_CONTAINER_multipeermap_iterate (dv_routes, | ||
4628 | &free_dv_routes_cb, | ||
4629 | NULL); | ||
4630 | GNUNET_CONTAINER_multipeermap_destroy (dv_routes); | ||
4631 | dv_routes = NULL; | ||
4439 | GNUNET_CONTAINER_multipeermap_iterate (ephemeral_map, | 4632 | GNUNET_CONTAINER_multipeermap_iterate (ephemeral_map, |
4440 | &free_ephemeral_cb, | 4633 | &free_ephemeral_cb, |
4441 | NULL); | 4634 | NULL); |
@@ -4463,6 +4656,8 @@ run (void *cls, | |||
4463 | GST_cfg = c; | 4656 | GST_cfg = c; |
4464 | neighbours = GNUNET_CONTAINER_multipeermap_create (1024, | 4657 | neighbours = GNUNET_CONTAINER_multipeermap_create (1024, |
4465 | GNUNET_YES); | 4658 | GNUNET_YES); |
4659 | dv_routes = GNUNET_CONTAINER_multipeermap_create (1024, | ||
4660 | GNUNET_YES); | ||
4466 | ephemeral_map = GNUNET_CONTAINER_multipeermap_create (32, | 4661 | ephemeral_map = GNUNET_CONTAINER_multipeermap_create (32, |
4467 | GNUNET_YES); | 4662 | GNUNET_YES); |
4468 | ephemeral_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | 4663 | ephemeral_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); |