diff options
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r-- | src/transport/gnunet-service-tng.c | 274 |
1 files changed, 262 insertions, 12 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index e5fb51bd2..efbaf6fc9 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -21,16 +21,17 @@ | |||
21 | * @author Christian Grothoff | 21 | * @author Christian Grothoff |
22 | * | 22 | * |
23 | * TODO: | 23 | * TODO: |
24 | * - MTU information is missing for queues! | 24 | * - monitor start: iterate to inform monitor about all existing queues! |
25 | * - start supporting monitor logic (add functions to signal monitors!) | ||
26 | * - manage fragmentation/defragmentation, retransmission, track RTT, loss, etc. | 25 | * - manage fragmentation/defragmentation, retransmission, track RTT, loss, etc. |
27 | * - ask ATS about bandwidth allocation | 26 | * - inform ATS about RTT, goodput/loss, overheads, etc. |
27 | * - ask ATS about bandwidth allocation! | ||
28 | * - | 28 | * - |
29 | */ | 29 | */ |
30 | #include "platform.h" | 30 | #include "platform.h" |
31 | #include "gnunet_util_lib.h" | 31 | #include "gnunet_util_lib.h" |
32 | #include "gnunet_statistics_service.h" | 32 | #include "gnunet_statistics_service.h" |
33 | #include "gnunet_transport_service.h" | 33 | #include "gnunet_transport_service.h" |
34 | #include "gnunet_transport_monitor_service.h" | ||
34 | #include "gnunet_peerstore_service.h" | 35 | #include "gnunet_peerstore_service.h" |
35 | #include "gnunet_ats_service.h" | 36 | #include "gnunet_ats_service.h" |
36 | #include "gnunet-service-transport.h" | 37 | #include "gnunet-service-transport.h" |
@@ -137,6 +138,11 @@ struct Queue | |||
137 | uint32_t qid; | 138 | uint32_t qid; |
138 | 139 | ||
139 | /** | 140 | /** |
141 | * Maximum transmission unit supported by this queue. | ||
142 | */ | ||
143 | uint32_t mtu; | ||
144 | |||
145 | /** | ||
140 | * Network type offered by this queue. | 146 | * Network type offered by this queue. |
141 | */ | 147 | */ |
142 | enum GNUNET_ATS_Network_Type nt; | 148 | enum GNUNET_ATS_Network_Type nt; |
@@ -454,6 +460,127 @@ lookup_neighbour (const struct GNUNET_PeerIdentity *pid) | |||
454 | 460 | ||
455 | 461 | ||
456 | /** | 462 | /** |
463 | * Details about what to notify monitors about. | ||
464 | */ | ||
465 | struct MonitorEvent | ||
466 | { | ||
467 | /** | ||
468 | * @deprecated To be discussed if we keep these... | ||
469 | */ | ||
470 | struct GNUNET_TIME_Absolute last_validation; | ||
471 | struct GNUNET_TIME_Absolute valid_until; | ||
472 | struct GNUNET_TIME_Absolute next_validation; | ||
473 | |||
474 | /** | ||
475 | * Current round-trip time estimate. | ||
476 | */ | ||
477 | struct GNUNET_TIME_Relative rtt; | ||
478 | |||
479 | /** | ||
480 | * Connection status. | ||
481 | */ | ||
482 | enum GNUNET_TRANSPORT_ConnectionStatus cs; | ||
483 | |||
484 | /** | ||
485 | * Messages pending. | ||
486 | */ | ||
487 | uint32_t num_msg_pending; | ||
488 | |||
489 | /** | ||
490 | * Bytes pending. | ||
491 | */ | ||
492 | uint32_t num_bytes_pending; | ||
493 | |||
494 | |||
495 | }; | ||
496 | |||
497 | |||
498 | /** | ||
499 | * Notify monitor @a tc about an event. That @a tc | ||
500 | * cares about the event has already been checked. | ||
501 | * | ||
502 | * Send @a tc information in @a me about a @a peer's status with | ||
503 | * respect to some @a address to all monitors that care. | ||
504 | * | ||
505 | * @param tc monitor to inform | ||
506 | * @param peer peer the information is about | ||
507 | * @param address address the information is about | ||
508 | * @param nt network type associated with @a address | ||
509 | * @param me detailed information to transmit | ||
510 | */ | ||
511 | static void | ||
512 | notify_monitor (struct TransportClient *tc, | ||
513 | const struct GNUNET_PeerIdentity *peer, | ||
514 | const char *address, | ||
515 | enum GNUNET_ATS_Network_Type nt, | ||
516 | const struct MonitorEvent *me) | ||
517 | { | ||
518 | struct GNUNET_MQ_Envelope *env; | ||
519 | struct GNUNET_TRANSPORT_MonitorData *md; | ||
520 | size_t addr_len = strlen (address) + 1; | ||
521 | |||
522 | env = GNUNET_MQ_msg_extra (md, | ||
523 | addr_len, | ||
524 | GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_DATA); | ||
525 | md->nt = htonl ((uint32_t) nt); | ||
526 | md->peer = *peer; | ||
527 | md->last_validation = GNUNET_TIME_absolute_hton (me->last_validation); | ||
528 | md->valid_until = GNUNET_TIME_absolute_hton (me->valid_until); | ||
529 | md->next_validation = GNUNET_TIME_absolute_hton (me->next_validation); | ||
530 | md->rtt = GNUNET_TIME_relative_hton (me->rtt); | ||
531 | md->cs = htonl ((uint32_t) me->cs); | ||
532 | md->num_msg_pending = htonl (me->num_msg_pending); | ||
533 | md->num_bytes_pending = htonl (me->num_bytes_pending); | ||
534 | memcpy (&md[1], | ||
535 | address, | ||
536 | addr_len); | ||
537 | GNUNET_MQ_send (tc->mq, | ||
538 | env); | ||
539 | } | ||
540 | |||
541 | |||
542 | /** | ||
543 | * Send information in @a me about a @a peer's status with respect | ||
544 | * to some @a address to all monitors that care. | ||
545 | * | ||
546 | * @param peer peer the information is about | ||
547 | * @param address address the information is about | ||
548 | * @param nt network type associated with @a address | ||
549 | * @param me detailed information to transmit | ||
550 | */ | ||
551 | static void | ||
552 | notify_monitors (const struct GNUNET_PeerIdentity *peer, | ||
553 | const char *address, | ||
554 | enum GNUNET_ATS_Network_Type nt, | ||
555 | const struct MonitorEvent *me) | ||
556 | { | ||
557 | static struct GNUNET_PeerIdentity zero; | ||
558 | |||
559 | for (struct TransportClient *tc = clients_head; | ||
560 | NULL != tc; | ||
561 | tc = tc->next) | ||
562 | { | ||
563 | if (CT_MONITOR != tc->type) | ||
564 | continue; | ||
565 | if (tc->details.monitor.one_shot) | ||
566 | continue; | ||
567 | if ( (0 != memcmp (&tc->details.monitor.peer, | ||
568 | &zero, | ||
569 | sizeof (zero))) && | ||
570 | (0 != memcmp (&tc->details.monitor.peer, | ||
571 | peer, | ||
572 | sizeof (*peer))) ) | ||
573 | continue; | ||
574 | notify_monitor (tc, | ||
575 | peer, | ||
576 | address, | ||
577 | nt, | ||
578 | me); | ||
579 | } | ||
580 | } | ||
581 | |||
582 | |||
583 | /** | ||
457 | * Called whenever a client connects. Allocates our | 584 | * Called whenever a client connects. Allocates our |
458 | * data structures associated with that client. | 585 | * data structures associated with that client. |
459 | * | 586 | * |
@@ -500,6 +627,80 @@ free_neighbour (struct Neighbour *neighbour) | |||
500 | 627 | ||
501 | 628 | ||
502 | /** | 629 | /** |
630 | * Send message to CORE clients that we lost a connection. | ||
631 | * | ||
632 | * @param tc client to inform (must be CORE client) | ||
633 | * @param pid peer the connection is for | ||
634 | * @param quota_out current quota for the peer | ||
635 | */ | ||
636 | static void | ||
637 | core_send_connect_info (struct TransportClient *tc, | ||
638 | const struct GNUNET_PeerIdentity *pid, | ||
639 | struct GNUNET_BANDWIDTH_Value32NBO quota_out) | ||
640 | { | ||
641 | struct GNUNET_MQ_Envelope *env; | ||
642 | struct ConnectInfoMessage *cim; | ||
643 | |||
644 | GNUNET_assert (CT_CORE == tc->type); | ||
645 | env = GNUNET_MQ_msg (cim, | ||
646 | GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); | ||
647 | cim->quota_out = quota_out; | ||
648 | cim->id = *pid; | ||
649 | GNUNET_MQ_send (tc->mq, | ||
650 | env); | ||
651 | } | ||
652 | |||
653 | |||
654 | /** | ||
655 | * Send message to CORE clients that we gained a connection | ||
656 | * | ||
657 | * @param pid peer the queue was for | ||
658 | * @param quota_out current quota for the peer | ||
659 | */ | ||
660 | static void | ||
661 | cores_send_connect_info (const struct GNUNET_PeerIdentity *pid, | ||
662 | struct GNUNET_BANDWIDTH_Value32NBO quota_out) | ||
663 | { | ||
664 | for (struct TransportClient *tc = clients_head; | ||
665 | NULL != tc; | ||
666 | tc = tc->next) | ||
667 | { | ||
668 | if (CT_CORE != tc->type) | ||
669 | continue; | ||
670 | core_send_connect_info (tc, | ||
671 | pid, | ||
672 | quota_out); | ||
673 | } | ||
674 | } | ||
675 | |||
676 | |||
677 | /** | ||
678 | * Send message to CORE clients that we lost a connection. | ||
679 | * | ||
680 | * @param pid peer the connection was for | ||
681 | */ | ||
682 | static void | ||
683 | cores_send_disconnect_info (const struct GNUNET_PeerIdentity *pid) | ||
684 | { | ||
685 | for (struct TransportClient *tc = clients_head; | ||
686 | NULL != tc; | ||
687 | tc = tc->next) | ||
688 | { | ||
689 | struct GNUNET_MQ_Envelope *env; | ||
690 | struct DisconnectInfoMessage *dim; | ||
691 | |||
692 | if (CT_CORE != tc->type) | ||
693 | continue; | ||
694 | env = GNUNET_MQ_msg (dim, | ||
695 | GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT); | ||
696 | dim->peer = *pid; | ||
697 | GNUNET_MQ_send (tc->mq, | ||
698 | env); | ||
699 | } | ||
700 | } | ||
701 | |||
702 | |||
703 | /** | ||
503 | * Free @a queue. | 704 | * Free @a queue. |
504 | * | 705 | * |
505 | * @param queue the queue to free | 706 | * @param queue the queue to free |
@@ -509,6 +710,10 @@ free_queue (struct Queue *queue) | |||
509 | { | 710 | { |
510 | struct Neighbour *neighbour = queue->neighbour; | 711 | struct Neighbour *neighbour = queue->neighbour; |
511 | struct TransportClient *tc = queue->tc; | 712 | struct TransportClient *tc = queue->tc; |
713 | struct MonitorEvent me = { | ||
714 | .cs = GNUNET_TRANSPORT_CS_DOWN, | ||
715 | .rtt = GNUNET_TIME_UNIT_FOREVER_REL | ||
716 | }; | ||
512 | 717 | ||
513 | GNUNET_CONTAINER_MDLL_remove (neighbour, | 718 | GNUNET_CONTAINER_MDLL_remove (neighbour, |
514 | neighbour->queue_head, | 719 | neighbour->queue_head, |
@@ -518,10 +723,15 @@ free_queue (struct Queue *queue) | |||
518 | tc->details.communicator.queue_head, | 723 | tc->details.communicator.queue_head, |
519 | tc->details.communicator.queue_tail, | 724 | tc->details.communicator.queue_tail, |
520 | queue); | 725 | queue); |
726 | |||
727 | notify_monitors (&neighbour->pid, | ||
728 | queue->address, | ||
729 | queue->nt, | ||
730 | &me); | ||
521 | GNUNET_free (queue); | 731 | GNUNET_free (queue); |
522 | if (NULL == neighbour->queue_head) | 732 | if (NULL == neighbour->queue_head) |
523 | { | 733 | { |
524 | // FIXME: notify cores/monitors! | 734 | cores_send_disconnect_info (&neighbour->pid); |
525 | free_neighbour (neighbour); | 735 | free_neighbour (neighbour); |
526 | } | 736 | } |
527 | } | 737 | } |
@@ -613,6 +823,30 @@ client_disconnect_cb (void *cls, | |||
613 | 823 | ||
614 | 824 | ||
615 | /** | 825 | /** |
826 | * Iterator telling new CORE client about all existing | ||
827 | * connections to peers. | ||
828 | * | ||
829 | * @param cls the new `struct TransportClient` | ||
830 | * @param pid a connected peer | ||
831 | * @param value the `struct Neighbour` with more information | ||
832 | * @return #GNUNET_OK (continue to iterate) | ||
833 | */ | ||
834 | static int | ||
835 | notify_client_connect_info (void *cls, | ||
836 | const struct GNUNET_PeerIdentity *pid, | ||
837 | void *value) | ||
838 | { | ||
839 | struct TransportClient *tc = cls; | ||
840 | struct Neighbour *neighbour = value; | ||
841 | |||
842 | core_send_connect_info (tc, | ||
843 | pid, | ||
844 | neighbour->quota_out); | ||
845 | return GNUNET_OK; | ||
846 | } | ||
847 | |||
848 | |||
849 | /** | ||
616 | * Initialize a "CORE" client. We got a start message from this | 850 | * Initialize a "CORE" client. We got a start message from this |
617 | * client, so add it to the list of clients for broadcasting of | 851 | * client, so add it to the list of clients for broadcasting of |
618 | * inbound messages. | 852 | * inbound messages. |
@@ -646,6 +880,9 @@ handle_client_start (void *cls, | |||
646 | return; | 880 | return; |
647 | } | 881 | } |
648 | tc->type = CT_CORE; | 882 | tc->type = CT_CORE; |
883 | GNUNET_CONTAINER_multipeermap_iterate (neighbours, | ||
884 | ¬ify_client_connect_info, | ||
885 | tc); | ||
649 | GNUNET_SERVICE_client_continue (tc->client); | 886 | GNUNET_SERVICE_client_continue (tc->client); |
650 | } | 887 | } |
651 | 888 | ||
@@ -786,7 +1023,7 @@ handle_client_send (void *cls, | |||
786 | tc->details.core.pending_msg_head, | 1023 | tc->details.core.pending_msg_head, |
787 | tc->details.core.pending_msg_tail, | 1024 | tc->details.core.pending_msg_tail, |
788 | pm); | 1025 | pm); |
789 | // FIXME: do the work, continuation with: | 1026 | // FIXME: do the work, final continuation with call to: |
790 | client_send_response (pm, | 1027 | client_send_response (pm, |
791 | GNUNET_NO, | 1028 | GNUNET_NO, |
792 | 0); | 1029 | 0); |
@@ -930,6 +1167,7 @@ store_pi (void *cls) | |||
930 | ale->st = NULL; | 1167 | ale->st = NULL; |
931 | expiration = GNUNET_TIME_relative_to_absolute (ale->expiration); | 1168 | expiration = GNUNET_TIME_relative_to_absolute (ale->expiration); |
932 | GNUNET_HELLO_sign_address (ale->address, | 1169 | GNUNET_HELLO_sign_address (ale->address, |
1170 | ale->nt, | ||
933 | expiration, | 1171 | expiration, |
934 | GST_my_private_key, | 1172 | GST_my_private_key, |
935 | &addr, | 1173 | &addr, |
@@ -1123,7 +1361,7 @@ handle_add_queue_message (void *cls, | |||
1123 | struct Queue *queue; | 1361 | struct Queue *queue; |
1124 | struct Neighbour *neighbour; | 1362 | struct Neighbour *neighbour; |
1125 | const char *addr; | 1363 | const char *addr; |
1126 | uint16_t addr_len; | 1364 | uint16_t addr_len; |
1127 | 1365 | ||
1128 | neighbour = lookup_neighbour (&aqm->receiver); | 1366 | neighbour = lookup_neighbour (&aqm->receiver); |
1129 | if (NULL == neighbour) | 1367 | if (NULL == neighbour) |
@@ -1135,12 +1373,15 @@ handle_add_queue_message (void *cls, | |||
1135 | &neighbour->pid, | 1373 | &neighbour->pid, |
1136 | neighbour, | 1374 | neighbour, |
1137 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 1375 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
1138 | // FIXME: notify ATS/COREs/monitors! | 1376 | cores_send_connect_info (&neighbour->pid, |
1377 | GNUNET_BANDWIDTH_ZERO); | ||
1378 | // FIXME: notify ATS! | ||
1139 | } | 1379 | } |
1140 | addr_len = ntohs (aqm->header.size) - sizeof (*aqm); | 1380 | addr_len = ntohs (aqm->header.size) - sizeof (*aqm); |
1141 | addr = (const char *) &aqm[1]; | 1381 | addr = (const char *) &aqm[1]; |
1142 | 1382 | ||
1143 | queue = GNUNET_malloc (sizeof (struct Queue) + addr_len); | 1383 | queue = GNUNET_malloc (sizeof (struct Queue) + addr_len); |
1384 | queue->mtu = ntohl (aqm->mtu); | ||
1144 | queue->qid = aqm->qid; | 1385 | queue->qid = aqm->qid; |
1145 | queue->nt = (enum GNUNET_ATS_Network_Type) ntohl (aqm->nt); | 1386 | queue->nt = (enum GNUNET_ATS_Network_Type) ntohl (aqm->nt); |
1146 | queue->tc = tc; | 1387 | queue->tc = tc; |
@@ -1149,6 +1390,17 @@ handle_add_queue_message (void *cls, | |||
1149 | memcpy (&queue[1], | 1390 | memcpy (&queue[1], |
1150 | addr, | 1391 | addr, |
1151 | addr_len); | 1392 | addr_len); |
1393 | /* notify monitors about new queue */ | ||
1394 | { | ||
1395 | struct MonitorEvent me = { | ||
1396 | .cs = (enum GNUNET_TRANSPORT_ConnectionStatus) ntohl (aqm->cs) | ||
1397 | }; | ||
1398 | |||
1399 | notify_monitors (&neighbour->pid, | ||
1400 | queue->address, | ||
1401 | queue->nt, | ||
1402 | &me); | ||
1403 | } | ||
1152 | GNUNET_CONTAINER_MDLL_insert (neighbour, | 1404 | GNUNET_CONTAINER_MDLL_insert (neighbour, |
1153 | neighbour->queue_head, | 1405 | neighbour->queue_head, |
1154 | neighbour->queue_tail, | 1406 | neighbour->queue_tail, |
@@ -1244,6 +1496,8 @@ handle_monitor_start (void *cls, | |||
1244 | tc->details.monitor.peer = start->peer; | 1496 | tc->details.monitor.peer = start->peer; |
1245 | tc->details.monitor.one_shot = ntohl (start->one_shot); | 1497 | tc->details.monitor.one_shot = ntohl (start->one_shot); |
1246 | // FIXME: do work! | 1498 | // FIXME: do work! |
1499 | |||
1500 | GNUNET_SERVICE_client_mark_monitor (tc->client); | ||
1247 | GNUNET_SERVICE_client_continue (tc->client); | 1501 | GNUNET_SERVICE_client_continue (tc->client); |
1248 | } | 1502 | } |
1249 | 1503 | ||
@@ -1286,10 +1540,6 @@ do_shutdown (void *cls) | |||
1286 | GNUNET_CONTAINER_multipeermap_iterate (neighbours, | 1540 | GNUNET_CONTAINER_multipeermap_iterate (neighbours, |
1287 | &free_neighbour_cb, | 1541 | &free_neighbour_cb, |
1288 | NULL); | 1542 | NULL); |
1289 | /* FIXME: if this assertion fails (likely!), make sure we | ||
1290 | clean up clients *before* doing the rest of the | ||
1291 | shutdown! (i.e. by scheduling rest asynchronously!) */ | ||
1292 | GNUNET_assert (NULL == clients_head); | ||
1293 | if (NULL != peerstore) | 1543 | if (NULL != peerstore) |
1294 | { | 1544 | { |
1295 | GNUNET_PEERSTORE_disconnect (peerstore, | 1545 | GNUNET_PEERSTORE_disconnect (peerstore, |
@@ -1362,7 +1612,7 @@ run (void *cls, | |||
1362 | */ | 1612 | */ |
1363 | GNUNET_SERVICE_MAIN | 1613 | GNUNET_SERVICE_MAIN |
1364 | ("transport", | 1614 | ("transport", |
1365 | GNUNET_SERVICE_OPTION_NONE, | 1615 | GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN, |
1366 | &run, | 1616 | &run, |
1367 | &client_connect_cb, | 1617 | &client_connect_cb, |
1368 | &client_disconnect_cb, | 1618 | &client_disconnect_cb, |