aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-tng.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r--src/transport/gnunet-service-tng.c274
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 */
465struct 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 */
511static void
512notify_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 */
551static void
552notify_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 */
636static void
637core_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 */
660static void
661cores_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 */
682static void
683cores_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 */
834static int
835notify_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 &notify_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 */
1363GNUNET_SERVICE_MAIN 1613GNUNET_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,