aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/transport/gnunet-service-tng.c203
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 */
614struct DistanceVector;
615
616/**
617 * One possible hop towards a DV target.
618 */
619struct 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 */
677struct 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;
1308static struct GNUNET_CONTAINER_MultiPeerMap *neighbours; 1410static 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 */
1416static struct GNUNET_CONTAINER_MultiPeerMap *dv_routes;
1417
1418/**
1311 * Database for peer's HELLOs. 1419 * Database for peer's HELLOs.
1312 */ 1420 */
1313static struct GNUNET_PEERSTORE_Handle *peerstore; 1421static 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 */
1521static void
1522free_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 */
1555static void
1556free_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,
1596static void 1754static void
1597free_neighbour (struct Neighbour *neighbour) 1755free_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 */
4547static int
4548free_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);