aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/Makefile.am2
-rw-r--r--src/transport/gnunet-service-tng.c245
2 files changed, 201 insertions, 46 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index deeb39b48..0693a0b9f 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -328,6 +328,8 @@ gnunet_service_tng_SOURCES = \
328 gnunet-service-tng.c 328 gnunet-service-tng.c
329gnunet_service_tng_LDADD = \ 329gnunet_service_tng_LDADD = \
330 $(top_builddir)/src/ats/libgnunetats.la \ 330 $(top_builddir)/src/ats/libgnunetats.la \
331 $(top_builddir)/src/peerstore/libgnunetpeerstore.la \
332 $(top_builddir)/src/hello/libgnunethello.la \
331 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 333 $(top_builddir)/src/statistics/libgnunetstatistics.la \
332 $(top_builddir)/src/util/libgnunetutil.la \ 334 $(top_builddir)/src/util/libgnunetutil.la \
333 $(GN_LIBINTL) 335 $(GN_LIBINTL)
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index c7bdfd77c..e5fb51bd2 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -21,8 +21,6 @@
21 * @author Christian Grothoff 21 * @author Christian Grothoff
22 * 22 *
23 * TODO: 23 * TODO:
24 * - make *our* collected addresses available somehow somewhere
25 * => Choices: in peerstore or revive/keep peerinfo?
26 * - MTU information is missing for queues! 24 * - MTU information is missing for queues!
27 * - start supporting monitor logic (add functions to signal monitors!) 25 * - start supporting monitor logic (add functions to signal monitors!)
28 * - manage fragmentation/defragmentation, retransmission, track RTT, loss, etc. 26 * - manage fragmentation/defragmentation, retransmission, track RTT, loss, etc.
@@ -33,7 +31,7 @@
33#include "gnunet_util_lib.h" 31#include "gnunet_util_lib.h"
34#include "gnunet_statistics_service.h" 32#include "gnunet_statistics_service.h"
35#include "gnunet_transport_service.h" 33#include "gnunet_transport_service.h"
36#include "gnunet_peerinfo_service.h" 34#include "gnunet_peerstore_service.h"
37#include "gnunet_ats_service.h" 35#include "gnunet_ats_service.h"
38#include "gnunet-service-transport.h" 36#include "gnunet-service-transport.h"
39#include "transport.h" 37#include "transport.h"
@@ -263,6 +261,16 @@ struct AddressListEntry
263 const char *address; 261 const char *address;
264 262
265 /** 263 /**
264 * Current context for storing this address in the peerstore.
265 */
266 struct GNUNET_PEERSTORE_StoreContext *sc;
267
268 /**
269 * Task to periodically do @e st operation.
270 */
271 struct GNUNET_SCHEDULER_Task *st;
272
273 /**
266 * What is a typical lifetime the communicator expects this 274 * What is a typical lifetime the communicator expects this
267 * address to have? (Always from now.) 275 * address to have? (Always from now.)
268 */ 276 */
@@ -425,6 +433,11 @@ struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
425 */ 433 */
426static struct GNUNET_CONTAINER_MultiPeerMap *neighbours; 434static struct GNUNET_CONTAINER_MultiPeerMap *neighbours;
427 435
436/**
437 * Database for peer's HELLOs.
438 */
439static struct GNUNET_PEERSTORE_Handle *peerstore;
440
428 441
429/** 442/**
430 * Lookup neighbour record for peer @a pid. 443 * Lookup neighbour record for peer @a pid.
@@ -470,6 +483,78 @@ client_connect_cb (void *cls,
470 483
471 484
472/** 485/**
486 * Release memory used by @a neighbour.
487 *
488 * @param neighbour neighbour entry to free
489 */
490static void
491free_neighbour (struct Neighbour *neighbour)
492{
493 GNUNET_assert (NULL == neighbour->queue_head);
494 GNUNET_assert (GNUNET_YES ==
495 GNUNET_CONTAINER_multipeermap_remove (neighbours,
496 &neighbour->pid,
497 neighbour));
498 GNUNET_free (neighbour);
499}
500
501
502/**
503 * Free @a queue.
504 *
505 * @param queue the queue to free
506 */
507static void
508free_queue (struct Queue *queue)
509{
510 struct Neighbour *neighbour = queue->neighbour;
511 struct TransportClient *tc = queue->tc;
512
513 GNUNET_CONTAINER_MDLL_remove (neighbour,
514 neighbour->queue_head,
515 neighbour->queue_tail,
516 queue);
517 GNUNET_CONTAINER_MDLL_remove (client,
518 tc->details.communicator.queue_head,
519 tc->details.communicator.queue_tail,
520 queue);
521 GNUNET_free (queue);
522 if (NULL == neighbour->queue_head)
523 {
524 // FIXME: notify cores/monitors!
525 free_neighbour (neighbour);
526 }
527}
528
529
530/**
531 * Free @a ale
532 *
533 * @param ale address list entry to free
534 */
535static void
536free_address_list_entry (struct AddressListEntry *ale)
537{
538 struct TransportClient *tc = ale->tc;
539
540 GNUNET_CONTAINER_DLL_remove (tc->details.communicator.addr_head,
541 tc->details.communicator.addr_tail,
542 ale);
543 if (NULL != ale->sc)
544 {
545 GNUNET_PEERSTORE_store_cancel (ale->sc);
546 ale->sc = NULL;
547 }
548 if (NULL != ale->st)
549 {
550 GNUNET_SCHEDULER_cancel (ale->st);
551 ale->st = NULL;
552 }
553 GNUNET_free (ale);
554}
555
556
557/**
473 * Called whenever a client is disconnected. Frees our 558 * Called whenever a client is disconnected. Frees our
474 * resources associated with that client. 559 * resources associated with that client.
475 * 560 *
@@ -511,7 +596,16 @@ client_disconnect_cb (void *cls,
511 case CT_MONITOR: 596 case CT_MONITOR:
512 break; 597 break;
513 case CT_COMMUNICATOR: 598 case CT_COMMUNICATOR:
514 GNUNET_free (tc->details.communicator.address_prefix); 599 {
600 struct Queue *q;
601 struct AddressListEntry *ale;
602
603 while (NULL != (q = tc->details.communicator.queue_head))
604 free_queue (q);
605 while (NULL != (ale = tc->details.communicator.addr_head))
606 free_address_list_entry (ale);
607 GNUNET_free (tc->details.communicator.address_prefix);
608 }
515 break; 609 break;
516 } 610 }
517 GNUNET_free (tc); 611 GNUNET_free (tc);
@@ -789,6 +883,81 @@ check_add_address (void *cls,
789 883
790 884
791/** 885/**
886 * Ask peerstore to store our address.
887 *
888 * @param cls an `struct AddressListEntry *`
889 */
890static void
891store_pi (void *cls);
892
893
894/**
895 * Function called when peerstore is done storing our address.
896 */
897static void
898peerstore_store_cb (void *cls,
899 int success)
900{
901 struct AddressListEntry *ale = cls;
902
903 ale->sc = NULL;
904 if (GNUNET_YES != success)
905 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
906 "Failed to store our own address `%s' in peerstore!\n",
907 ale->address);
908 /* refresh period is 1/4 of expiration time, that should be plenty
909 without being excessive. */
910 ale->st = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide (ale->expiration,
911 4ULL),
912 &store_pi,
913 ale);
914}
915
916
917/**
918 * Ask peerstore to store our address.
919 *
920 * @param cls an `struct AddressListEntry *`
921 */
922static void
923store_pi (void *cls)
924{
925 struct AddressListEntry *ale = cls;
926 void *addr;
927 size_t addr_len;
928 struct GNUNET_TIME_Absolute expiration;
929
930 ale->st = NULL;
931 expiration = GNUNET_TIME_relative_to_absolute (ale->expiration);
932 GNUNET_HELLO_sign_address (ale->address,
933 expiration,
934 GST_my_private_key,
935 &addr,
936 &addr_len);
937 ale->sc = GNUNET_PEERSTORE_store (peerstore,
938 "transport",
939 &GST_my_identity,
940 "hello",
941 addr,
942 addr_len,
943 expiration,
944 GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
945 &peerstore_store_cb,
946 ale);
947 GNUNET_free (addr);
948 if (NULL == ale->sc)
949 {
950 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
951 "Failed to store our address `%s' with peerstore\n",
952 ale->address);
953 ale->st = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
954 &store_pi,
955 ale);
956 }
957}
958
959
960/**
792 * Address of our peer added. Process the request. 961 * Address of our peer added. Process the request.
793 * 962 *
794 * @param cls the client 963 * @param cls the client
@@ -815,7 +984,8 @@ handle_add_address (void *cls,
815 GNUNET_CONTAINER_DLL_insert (tc->details.communicator.addr_head, 984 GNUNET_CONTAINER_DLL_insert (tc->details.communicator.addr_head,
816 tc->details.communicator.addr_tail, 985 tc->details.communicator.addr_tail,
817 ale); 986 ale);
818 // FIXME: notify somebody?! 987 ale->st = GNUNET_SCHEDULER_add_now (&store_pi,
988 ale);
819 GNUNET_SERVICE_client_continue (tc->client); 989 GNUNET_SERVICE_client_continue (tc->client);
820} 990}
821 991
@@ -845,11 +1015,7 @@ handle_del_address (void *cls,
845 if (dam->aid != ale->aid) 1015 if (dam->aid != ale->aid)
846 continue; 1016 continue;
847 GNUNET_assert (ale->tc == tc); 1017 GNUNET_assert (ale->tc == tc);
848 GNUNET_CONTAINER_DLL_remove (tc->details.communicator.addr_head, 1018 free_address_list_entry (ale);
849 tc->details.communicator.addr_tail,
850 ale);
851 // FIXME: notify somebody?
852 GNUNET_free (ale);
853 GNUNET_SERVICE_client_continue (tc->client); 1019 GNUNET_SERVICE_client_continue (tc->client);
854 } 1020 }
855 GNUNET_break (0); 1021 GNUNET_break (0);
@@ -997,23 +1163,6 @@ handle_add_queue_message (void *cls,
997 1163
998 1164
999/** 1165/**
1000 * Release memory used by @a neighbour.
1001 *
1002 * @param neighbour neighbour entry to free
1003 */
1004static void
1005free_neighbour (struct Neighbour *neighbour)
1006{
1007 GNUNET_assert (NULL == neighbour->queue_head);
1008 GNUNET_assert (GNUNET_YES ==
1009 GNUNET_CONTAINER_multipeermap_remove (neighbours,
1010 &neighbour->pid,
1011 neighbour));
1012 GNUNET_free (neighbour);
1013}
1014
1015
1016/**
1017 * Queue to a peer went down. Process the request. 1166 * Queue to a peer went down. Process the request.
1018 * 1167 *
1019 * @param cls the client 1168 * @param cls the client
@@ -1042,20 +1191,7 @@ handle_del_queue_message (void *cls,
1042 &neighbour->pid, 1191 &neighbour->pid,
1043 sizeof (struct GNUNET_PeerIdentity))) ) 1192 sizeof (struct GNUNET_PeerIdentity))) )
1044 continue; 1193 continue;
1045 GNUNET_CONTAINER_MDLL_remove (neighbour, 1194 free_queue (queue);
1046 neighbour->queue_head,
1047 neighbour->queue_tail,
1048 queue);
1049 GNUNET_CONTAINER_MDLL_remove (client,
1050 tc->details.communicator.queue_head,
1051 tc->details.communicator.queue_tail,
1052 queue);
1053 GNUNET_free (queue);
1054 if (NULL == neighbour->queue_head)
1055 {
1056 // FIXME: notify cores/monitors!
1057 free_neighbour (neighbour);
1058 }
1059 GNUNET_SERVICE_client_continue (tc->client); 1195 GNUNET_SERVICE_client_continue (tc->client);
1060 return; 1196 return;
1061 } 1197 }
@@ -1094,7 +1230,7 @@ handle_send_message_ack (void *cls,
1094 */ 1230 */
1095static void 1231static void
1096handle_monitor_start (void *cls, 1232handle_monitor_start (void *cls,
1097 const struct GNUNET_TRANSPORT_MonitorStart *start) 1233 const struct GNUNET_TRANSPORT_MonitorStart *start)
1098{ 1234{
1099 struct TransportClient *tc = cls; 1235 struct TransportClient *tc = cls;
1100 1236
@@ -1147,20 +1283,30 @@ do_shutdown (void *cls)
1147{ 1283{
1148 (void) cls; 1284 (void) cls;
1149 1285
1286 GNUNET_CONTAINER_multipeermap_iterate (neighbours,
1287 &free_neighbour_cb,
1288 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)
1294 {
1295 GNUNET_PEERSTORE_disconnect (peerstore,
1296 GNUNET_NO);
1297 peerstore = NULL;
1298 }
1150 if (NULL != GST_stats) 1299 if (NULL != GST_stats)
1151 { 1300 {
1152 GNUNET_STATISTICS_destroy (GST_stats, 1301 GNUNET_STATISTICS_destroy (GST_stats,
1153 GNUNET_NO); 1302 GNUNET_NO);
1154 GST_stats = NULL; 1303 GST_stats = NULL;
1155 } 1304 }
1156 if (NULL != GST_my_private_key) 1305 if (NULL != GST_my_private_key)
1157 { 1306 {
1158 GNUNET_free (GST_my_private_key); 1307 GNUNET_free (GST_my_private_key);
1159 GST_my_private_key = NULL; 1308 GST_my_private_key = NULL;
1160 } 1309 }
1161 GNUNET_CONTAINER_multipeermap_iterate (neighbours,
1162 &free_neighbour_cb,
1163 NULL);
1164 GNUNET_CONTAINER_multipeermap_destroy (neighbours); 1310 GNUNET_CONTAINER_multipeermap_destroy (neighbours);
1165} 1311}
1166 1312
@@ -1200,6 +1346,13 @@ run (void *cls,
1200 GST_cfg); 1346 GST_cfg);
1201 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, 1347 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
1202 NULL); 1348 NULL);
1349 peerstore = GNUNET_PEERSTORE_connect (GST_cfg);
1350 if (NULL == peerstore)
1351 {
1352 GNUNET_break (0);
1353 GNUNET_SCHEDULER_shutdown ();
1354 return;
1355 }
1203 /* start subsystems */ 1356 /* start subsystems */
1204} 1357}
1205 1358