GNUnet 0.28.1-dev.5-1-gae1c02d74
 
Loading...
Searching...
No Matches
gnunet-daemon-topology.c File Reference

code for maintaining the overlay topology More...

Include dependency graph for gnunet-daemon-topology.c:

Go to the source code of this file.

Data Structures

struct  Peer
 Record for neighbours and blacklisted peers. More...
 
struct  StoreHelloEntry
 Context for a add hello uri request. More...
 
struct  FindAdvHelloContext
 Closure for find_advertisable_hello(). More...
 

Macros

#define HELLO_ADVERTISEMENT_MIN_FREQUENCY    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
 At what frequency do we sent HELLOs to a peer?
 
#define HELLO_ADVERTISEMENT_MIN_REPEAT_FREQUENCY    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
 After what time period do we expire the HELLO Bloom filter?
 
#define RECONSIDER_FREQUENCY    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1)
 How often do we reconsider which peers we would like to be connected to?
 

Functions

static int free_peer (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
 Free all resources associated with the given peer.
 
static void attempt_connect (struct Peer *pos)
 Recalculate how much we want to be connected to the specified peer and let ATS know about the result.
 
static struct Peermake_peer (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *hello)
 Create a new entry in the peer list.
 
static void setup_filter (struct Peer *peer)
 Setup bloom filter for the given peer entry.
 
static int find_advertisable_hello (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
 Find a peer that would be reasonable for advertising.
 
static void schedule_next_hello (void *cls)
 Calculate when we would like to send the next HELLO to this peer and ask for it.
 
static int reschedule_hellos (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
 Cancel existing requests for sending HELLOs to this peer and recalculate when we should send HELLOs to it based on our current state (something changed!).
 
static void * connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq, enum GNUNET_CORE_PeerClass class)
 Method called whenever a peer connects.
 
static int try_add_peers (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
 Try to add more peers to our connection set.
 
static void add_peer_task (void *cls)
 Add peers and schedule connection attempt.
 
static void disconnect_notify (void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
 Method called whenever a peer disconnects.
 
static void address_iterator (void *cls, const struct GNUNET_PeerIdentity *pid, const char *uri)
 Iterator called on each address.
 
static void consider_for_advertising (const struct GNUNET_MessageHeader *hello)
 We've gotten a HELLO from another peer.
 
static void error_cb (void *cls)
 
static void sync_cb (void *cls)
 
static void process_peer (void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *err_msg)
 PEERSTORE calls this function to let us know about a possible peer that we might want to connect to.
 
static void start_notify (void *cls)
 
static void pid_change_cb (void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *addr_hash)
 
static void core_init (void *cls, const struct GNUNET_PeerIdentity *my_id)
 Function called after GNUNET_CORE_connect has succeeded (or failed for good).
 
static int check_hello (void *cls, const struct GNUNET_MessageHeader *msg)
 This function is called whenever an encrypted HELLO message is received.
 
static void shc_cont (void *cls, int success)
 
static void handle_hello (void *cls, const struct GNUNET_MessageHeader *msg)
 This function is called whenever an encrypted HELLO message is received.
 
static void cleaning_task (void *cls)
 Last task run during shutdown.
 
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
 Main function that will be run.
 
int main (int argc, char *const *argv)
 The main function for the topology daemon.
 

Variables

struct GNUNET_SCHEDULER_Taskpeerstore_notify_task
 The task to delayed start the notification process initially.
 
static struct GNUNET_PEERSTORE_Monitorpeerstore_notify
 Our peerstore notification context.
 
static const struct GNUNET_CONFIGURATION_Handlecfg
 Our configuration.
 
static struct GNUNET_PILS_Handlepils
 Handle to the PILS service.
 
static struct GNUNET_CORE_Handlehandle
 Handle to the CORE service.
 
static struct GNUNET_PEERSTORE_Handleps
 Handle to the PEERSTORE service.
 
struct GNUNET_TRANSPORT_ApplicationHandletransport
 Handle to Transport service.
 
static struct GNUNET_PeerIdentity my_identity
 Identity of this peer.
 
static struct GNUNET_CONTAINER_MultiPeerMappeers
 All of our current neighbours and all peers for which we have HELLOs.
 
static struct GNUNET_STATISTICS_Handlestats
 Handle for reporting statistics.
 
static struct GNUNET_SCHEDULER_Taskadd_task
 Task scheduled to asynchronously reconsider adding/removing peer connectivity suggestions.
 
static unsigned int connection_count
 Number of peers that we are currently connected to.
 
static unsigned int target_connection_count
 Target number of connections.
 
static struct StoreHelloEntryshe_head
 Head of the linkd list to store the store context for hellos.
 
static struct StoreHelloEntryshe_tail
 Tail of the linkd list to store the store context for hellos.
 

Detailed Description

code for maintaining the overlay topology

Author
Christian Grothoff

This daemon combines one Function:

  • gossping HELLOs

Definition in file gnunet-daemon-topology.c.

Macro Definition Documentation

◆ HELLO_ADVERTISEMENT_MIN_FREQUENCY

#define HELLO_ADVERTISEMENT_MIN_FREQUENCY    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)

At what frequency do we sent HELLOs to a peer?

Definition at line 46 of file gnunet-daemon-topology.c.

65{
69 struct GNUNET_PeerIdentity pid;
70
75 struct GNUNET_MQ_Handle *mq;
76
80 struct GNUNET_MessageHeader *hello;
81
87
91 struct GNUNET_TIME_Absolute next_hello_allowed;
92
96 struct GNUNET_TIME_Absolute filter_expiration;
97
102 struct GNUNET_SCHEDULER_Task *hello_delay_task;
103
108
112 uint32_t strength;
113
114};
115
119struct StoreHelloEntry
120{
124 struct StoreHelloEntry *prev;
125
129 struct StoreHelloEntry *next;
130
135};
136
142
143
149
153static const struct GNUNET_CONFIGURATION_Handle *cfg;
154
158static struct GNUNET_PILS_Handle *pils;
159
163static struct GNUNET_CORE_Handle *handle;
164
168static struct GNUNET_PEERSTORE_Handle *ps;
169
174
178static struct GNUNET_PeerIdentity my_identity;
179
186
190static struct GNUNET_STATISTICS_Handle *stats;
191
196static struct GNUNET_SCHEDULER_Task *add_task;
197
201static unsigned int connection_count;
202
206static unsigned int target_connection_count;
207
211static struct StoreHelloEntry *she_head;
212
216static struct StoreHelloEntry *she_tail;
217
226static int
227free_peer (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
228{
229 struct Peer *pos = value;
230
231 GNUNET_break (NULL == pos->mq);
234 if (NULL != pos->hello_delay_task)
235 {
237 pos->hello_delay_task = NULL;
238 }
239 if (NULL != pos->ash)
240 {
242 pos->ash = NULL;
243 }
244 if (NULL != pos->hello)
245 {
246 GNUNET_free (pos->hello);
247 pos->hello = NULL;
248 }
249 if (NULL != pos->filter)
250 {
252 pos->filter = NULL;
253 }
254 GNUNET_free (pos);
255 return GNUNET_YES;
256}
257
258
265static void
266attempt_connect (struct Peer *pos)
267{
268 uint32_t strength;
270
272 "Checking if we want to attempt connection to `%s'\n",
273 GNUNET_i2s (&pos->pid));
274 if (0 == GNUNET_memcmp (&my_identity, &pos->pid))
275 return; /* This is myself, nothing to do. */
277 strength = 1;
278 else
279 strength = 0;
280 if (NULL != pos->mq)
281 strength *= 2; /* existing connections preferred */
282 if ((strength == pos->strength) &&
283 ((NULL == pos->ash) == (0 == strength)))
284 return; /* nothing changed; re-issuing the suggestion would only reset
285 the retry state transport keeps for it */
286 if (NULL != pos->ash)
287 {
289 pos->ash = NULL;
290 }
291 pos->strength = strength;
292 if (0 != strength)
293 {
295 "Asking to connect to `%s' with strength %u\n",
296 GNUNET_i2s (&pos->pid),
297 (unsigned int) strength);
299 gettext_noop ("# connect requests issued to ATS"),
300 1,
301 GNUNET_NO);
302 // TODO Use strength somehow.
303 bw.value__ = 0;
305 &pos->pid,
307 bw);
308 }
309}
310
311
319static struct Peer *
320make_peer (const struct GNUNET_PeerIdentity *peer,
321 const struct GNUNET_MessageHeader *hello)
322{
323 struct Peer *ret;
324
325 ret = GNUNET_new (struct Peer);
326 ret->pid = *peer;
327 if (NULL != hello)
328 {
329 ret->hello = GNUNET_malloc (ntohs (hello->size));
330 GNUNET_memcpy (ret->hello, hello, ntohs (hello->size));
331 }
334 peers,
335 peer,
336 ret,
338 return ret;
339}
340
341
347static void
348setup_filter (struct Peer *peer)
349{
350 struct GNUNET_HashCode hc;
351
352 /* 2^{-5} chance of not sending a HELLO to a peer is
353 * acceptably small (if the filter is 50% full);
354 * 64 bytes of memory are small compared to the rest
355 * of the data structure and would only really become
356 * "useless" once a HELLO has been passed on to ~100
357 * other peers, which is likely more than enough in
358 * any case; hence 64, 5 as bloomfilter parameters. */peer->filter = GNUNET_CONTAINER_bloomfilter_init (NULL, 64, 5);
359 peer->filter_expiration =
361 /* never send a peer its own HELLO */
362 GNUNET_CRYPTO_hash (&peer->pid, sizeof(struct GNUNET_PeerIdentity), &hc);
364}
365
366
371{
375 struct Peer *peer;
376
380 struct Peer *result;
381
385 size_t max_size;
386
388};
389
390
399static int
400find_advertisable_hello (void *cls,
401 const struct GNUNET_PeerIdentity *pid,
402 void *value)
403{
404 struct FindAdvHelloContext *fah = cls;
405 struct Peer *pos = value;
406 struct GNUNET_TIME_Relative rst_time;
407 struct GNUNET_HashCode hc;
408 size_t hs;
409
411 "find_advertisable_hello\n");
412 if (pos == fah->peer)
413 return GNUNET_YES;
415 "find_advertisable_hello 2\n");
416 if (pos->hello == NULL)
417 return GNUNET_YES;
419 "find_advertisable_hello 3\n");
421 if (0 == rst_time.rel_value_us)
422 {
423 /* time to discard... */
425 setup_filter (pos);
426 }
427 fah->next_adv = GNUNET_TIME_relative_min (rst_time, fah->next_adv);
428 hs = pos->hello->size;
429 if (hs > fah->max_size)
430 return GNUNET_YES;
432 "find_advertisable_hello 4\n");
434 sizeof(struct GNUNET_PeerIdentity),
435 &hc);
437 fah->result = pos;
438 return GNUNET_YES;
439}
440
441
448static void
449schedule_next_hello (void *cls)
450{
451 struct Peer *pl = cls;
452 struct FindAdvHelloContext fah;
453 struct GNUNET_MQ_Envelope *env;
454 size_t want;
455 struct GNUNET_TIME_Relative delay;
456 struct GNUNET_HashCode hc;
457
459 "schedule_next_hello\n");
460 pl->hello_delay_task = NULL;
461 GNUNET_assert (NULL != pl->mq);
462 /* find applicable HELLOs */
463 fah.peer = pl;
464 fah.result = NULL;
468 if (NULL == fah.result)
469 {
470 pl->hello_delay_task =
472
473 return;
474 }
475 want = ntohs (fah.result->hello->size);
477 "Sending HELLO with %u bytes for peer %s\n",
478 (unsigned int) want,
479 GNUNET_i2s (&pl->pid));
481 GNUNET_MQ_send (pl->mq, env);
482
483 /* avoid sending this one again soon */
484 GNUNET_CRYPTO_hash (&pl->pid, sizeof(struct GNUNET_PeerIdentity), &hc);
486
488 gettext_noop ("# HELLO messages gossipped"),
489 1,
490 GNUNET_NO);
491 /* prepare to send the next one */
497}
498
499
510static int
511reschedule_hellos (void *cls,
512 const struct GNUNET_PeerIdentity *pid,
513 void *value)
514{
515 struct Peer *peer = value;
516 (void) cls;
517
519 "Reschedule for `%s'\n",
520 GNUNET_i2s (&peer->pid));
521 if (NULL == peer->mq)
522 return GNUNET_YES;
523 if (NULL != peer->hello_delay_task)
524 {
526 peer->hello_delay_task = NULL;
527 }
529 "Schedule_next_hello\n");
530 peer->hello_delay_task =
532 return GNUNET_YES;
533}
534
535
545static void *
546connect_notify (void *cls,
547 const struct GNUNET_PeerIdentity *peer,
548 struct GNUNET_MQ_Handle *mq,
549 enum GNUNET_CORE_PeerClass class)
550{
551 struct Peer *pos;
552
554 "Core told us that we are connecting to `%s'\n",
555 GNUNET_i2s (peer));
556 if (0 == GNUNET_memcmp (&my_identity, peer))
557 return NULL;
561 gettext_noop ("# peers connected"),
563 GNUNET_NO);
565 if (NULL == pos)
566 {
567 pos = make_peer (peer, NULL);
568 }
569 else
570 {
571 GNUNET_assert (NULL == pos->mq);
572 }
573 pos->mq = mq;
574 reschedule_hellos (NULL, peer, pos);
575 return pos;
576}
577
578
587static int
588try_add_peers (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
589{
590 struct Peer *pos = value;
591
592 attempt_connect (pos);
593 return GNUNET_YES;
594}
595
596
602static void
603add_peer_task (void *cls)
604{
605 add_task = NULL;
606
608 /* Keep going. A suggestion that did not work out produces no event of
609 its own -- the peer simply never connects -- so without a periodic
610 re-run the only things that ever call attempt_connect() again are a
611 CORE disconnect and a HELLO showing up in PEERSTORE. A peer we cannot
612 reach delivers neither, and a peer whose HELLO we learned while we were
613 already at the target connection count never gets a suggestion at
614 all. */
617 NULL);
618}
619
620
628static void
629disconnect_notify (void *cls,
630 const struct GNUNET_PeerIdentity *peer,
631 void *internal_cls)
632{
633 struct Peer *pos = internal_cls;
634
635 if (NULL == pos)
636 return; /* myself, we're shutting down */
638 "Core told us that we disconnected from `%s'\n",
639 GNUNET_i2s (peer));
640 if (NULL == pos->mq)
641 {
642 GNUNET_break (0);
643 return;
644 }
645 pos->mq = NULL;
647 if (NULL != pos->hello_delay_task)
648 {
650 pos->hello_delay_task = NULL;
651 }
653 gettext_noop ("# peers connected"),
655 GNUNET_NO);
657 {
658 /* Do not wait for the next periodic run. */
659 if (NULL != add_task)
662 }
663}
664
665
673static void
674address_iterator (void *cls,
675 const struct GNUNET_PeerIdentity *pid,
676 const char *uri)
677{
678 int *flag = cls;
679 (void) pid;
680
681 *flag = *flag + 1;
682 // *flag = GNUNET_YES;
683}
684
685
692static void
694{
695 int num_addresses_old = 0;
696 int num_addresses_new = 0;
698 const struct GNUNET_PeerIdentity *pid;
699 struct Peer *peer;
700 uint16_t size;
701
703 if (NULL == parser)
704 {
705 return;
706 }
709 &num_addresses_new);
711 "consider 0 for %s\n",
712 GNUNET_i2s (pid));
713 if (0 == num_addresses_new)
714 {
716 return; /* no point in advertising this one... */
717 }
719 if (NULL == peer)
720 {
721 peer = make_peer (pid, hello);
722 }
723 else if (NULL != peer->hello)
724 {
726 struct GNUNET_TIME_Absolute new_hello_exp =
728 struct GNUNET_TIME_Absolute old_hello_exp =
730 struct GNUNET_HELLO_Parser *parser_old =
731 GNUNET_HELLO_parser_from_msg (peer->hello, &peer->pid);
732
733 GNUNET_HELLO_parser_iterate (parser_old,
735 &num_addresses_old);
736 GNUNET_HELLO_parser_free (parser_old);
737 if (GNUNET_TIME_absolute_cmp (new_hello_exp, >, now) &&
738 (GNUNET_TIME_absolute_cmp (new_hello_exp, >, old_hello_exp) ||
739 num_addresses_old < num_addresses_new))
740 {
741 GNUNET_free (peer->hello);
742 size = ntohs (hello->size);
743 peer->hello = GNUNET_malloc (size);
744 GNUNET_memcpy (peer->hello, hello, size);
745 }
746 else
747 {
749 "consider 3\n");
751 return;
752 }
753 }
754 else
755 {
756 size = ntohs (hello->size);
757 peer->hello = GNUNET_malloc (size);
758 GNUNET_memcpy (peer->hello, hello, size);
759 }
761 "Found HELLO from peer `%s' for advertising\n",
762 GNUNET_i2s (pid));
763 if (NULL != peer->filter)
764 {
766 peer->filter = NULL;
767 }
768 setup_filter (peer);
769 /* since we have a new HELLO to pick from, re-schedule all
770 * HELLO requests that are not bound by the HELLO send rate! */
773}
774
775
776static void
777error_cb (void *cls)
778{
780 _ (
781 "Error in communication with PEERSTORE service to monitor.\n"));
782 return;
783}
784
785
786static void
787sync_cb (void *cls)
788{
790 _ ("Finished initial PEERSTORE iteration in monitor.\n"));
791 return;
792}
793
794
804static void
805process_peer (void *cls,
806 const struct GNUNET_PEERSTORE_Record *record,
807 const char *err_msg)
808{
809 struct Peer *pos;
810 struct GNUNET_MessageHeader *hello;
811
812 if (NULL != err_msg)
813 {
815 _ ("Error in communication with PEERSTORE service: %s\n"),
816 err_msg);
821 "peerstore",
822 NULL,
824 error_cb,
825 NULL,
826 sync_cb,
827 NULL,
829 NULL);
830 return;
831 }
832 GNUNET_assert (NULL != record);
834 "Processing HELLO from peerstore from peer `%s'\n",
835 GNUNET_i2s (&record->peer));
836 hello = record->value;
837 if (NULL == hello)
838 {
839 /* free existing HELLO, if any */
841 if (NULL != pos)
842 {
843 GNUNET_free (pos->hello);
844 pos->hello = NULL;
845 if (NULL != pos->filter)
846 {
848 pos->filter = NULL;
849 }
850 if (NULL == pos->mq)
851 free_peer (NULL, &pos->pid, pos);
852 }
854 return;
855 }
858 if (NULL == pos)
859 pos = make_peer (&record->peer, hello);
860 attempt_connect (pos);
862}
863
864
865static void
866start_notify (void *cls)
867{
868 (void) cls;
869
871 "Starting to process new hellos for gossiping.\n");
875 "peerstore",
876 NULL,
878 &error_cb,
879 NULL,
880 &sync_cb,
881 NULL,
883 NULL);
884}
885
886
887static void
888pid_change_cb (void *cls,
889 const struct GNUNET_HELLO_Parser *parser,
890 const struct GNUNET_HashCode *addr_hash)
891{
893}
894
895
903static void
904core_init (void *cls, const struct GNUNET_PeerIdentity *my_id)
905{
906 if (NULL == my_id)
907 {
908 GNUNET_log (
910 _ ("Failed to connect to core service, can not manage topology!\n"));
912 return;
913 }
914 my_identity = *my_id;
915 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "I am peer `%s'\n", GNUNET_i2s (my_id));
919 NULL);
920}
921
922
932static int
933check_hello (void *cls, const struct GNUNET_MessageHeader *msg)
934{
936 const struct GNUNET_PeerIdentity *pid = GNUNET_HELLO_parser_get_id (parser);
937
938 if (NULL == pid)
939 {
940 GNUNET_break_op (0);
941 return GNUNET_SYSERR;
942 }
943 return GNUNET_OK;
944}
945
946
947static void
948shc_cont (void *cls, int success)
949{
950 struct StoreHelloEntry *she = cls;
951
952 she->sc = NULL;
953 if (GNUNET_YES == success)
955 "Hello stored successfully!\n");
956 else
958 "Error storing hello!\n");
960 GNUNET_free (she);
961}
962
963
971static void
972handle_hello (void *cls, const struct GNUNET_MessageHeader *msg)
973{
974 struct StoreHelloEntry *she;
975 const struct GNUNET_PeerIdentity *other = cls;
977
979 "Received encrypted HELLO from peer `%s'\n",
980 GNUNET_i2s (other));
982 gettext_noop ("# HELLO messages received"),
983 1,
984 GNUNET_NO);
986 she = GNUNET_new (struct StoreHelloEntry);
988 if (NULL != she->sc)
989 {
991 }
992 else
993 GNUNET_free (she);
995}
996
997
1004static void
1005cleaning_task (void *cls)
1006{
1007 struct StoreHelloEntry *pos;
1008
1009 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Topology shutdown\n");
1010 while (NULL != (pos = she_head))
1011 {
1013 if (NULL != pos->sc)
1015 GNUNET_free (pos);
1016 }
1017 if (NULL != peerstore_notify)
1018 {
1020 peerstore_notify = NULL;
1021 }
1022 else if (NULL != peerstore_notify_task)
1023 {
1025 }
1026 if (NULL != pils)
1027 {
1029 pils = NULL;
1030 }
1031 if (NULL != handle)
1032 {
1034 handle = NULL;
1035 }
1036 if (NULL != add_task)
1037 {
1039 add_task = NULL;
1040 }
1043 peers = NULL;
1044 if (NULL != transport)
1045 {
1047 transport = NULL;
1048 }
1049 if (NULL != ps)
1050 {
1052 ps = NULL;
1053 }
1054 if (NULL != stats)
1055 {
1057 stats = NULL;
1058 }
1059}
1060
1061
1070static void
1071run (void *cls,
1072 char *const *args,
1073 const char *cfgfile,
1074 const struct GNUNET_CONFIGURATION_Handle *c)
1075{
1077 { GNUNET_MQ_hd_var_size (hello,
1079 struct GNUNET_MessageHeader,
1080 NULL),
1082 unsigned long long opt;
1083 const struct GNUNET_CORE_ServiceInfo service_info = {
1085 .version = { 1, 0 },
1086 .version_max = { 1, 0 },
1087 .version_min = { 1, 0 },
1088 };
1089
1090 cfg = c;
1091 stats = GNUNET_STATISTICS_create ("topology", cfg);
1092
1093 if (GNUNET_OK !=
1095 "TOPOLOGY",
1096 "TARGET-CONNECTION-COUNT",
1097 &opt))
1098 opt = 16;
1099 target_connection_count = (unsigned int) opt;
1101 GNUNET_NO);
1105 NULL,
1106 &core_init,
1109 handlers,
1110 &service_info);
1113 if (NULL == pils)
1114 {
1116 _ ("Failed to connect to `%s' service.\n"),
1117 "pils");
1119 return;
1120 }
1121 if (NULL == handle)
1122 {
1124 _ ("Failed to connect to `%s' service.\n"),
1125 "core");
1127 return;
1128 }
1131 NULL);
1132}
1133
1134
1142int
1143main (int argc, char *const *argv)
1144{
1145 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1147 };
1148 int ret;
1149
1150 ret = (GNUNET_OK ==
1152 argc,
1153 argv,
1154 "gnunet-daemon-topology",
1155 _ ("GNUnet topology control"),
1156 options,
1157 &run,
1158 NULL))
1159 ? 0
1160 : 1;
1161 return ret;
1162}
1163
1164
1165#if defined(__linux__) && defined(__GLIBC__)
1166#include <malloc.h>
1167
1168void __attribute__ ((constructor))
1169GNUNET_TOPOLOGY_memory_init (void);
1170
1174void __attribute__ ((constructor))
1175GNUNET_TOPOLOGY_memory_init (void)
1176{
1177 mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1178 mallopt (M_TOP_PAD, 1 * 1024);
1179 malloc_trim (0);
1180}
1181
1182
1183#endif
1184
1185/* end of gnunet-daemon-topology.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
struct GNUNET_MQ_MessageHandlers handlers[]
Definition 003.c:1
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
int main()
Program to simulate results from GCP_get_desirability_of_path() for various plausible inputs.
#define gettext_noop(String)
Definition gettext.h:74
static int ret
Final status code.
Definition gnunet-arm.c:93
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static struct GNUNET_CORE_Handle * handle
Handle to the CORE service.
static struct GNUNET_CONTAINER_MultiPeerMap * peers
All of our current neighbours and all peers for which we have HELLOs.
static void handle_hello(void *cls, const struct GNUNET_MessageHeader *msg)
This function is called whenever an encrypted HELLO message is received.
static int check_hello(void *cls, const struct GNUNET_MessageHeader *msg)
This function is called whenever an encrypted HELLO message is received.
static void sync_cb(void *cls)
static void cleaning_task(void *cls)
Last task run during shutdown.
static void add_peer_task(void *cls)
Add peers and schedule connection attempt.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
static void consider_for_advertising(const struct GNUNET_MessageHeader *hello)
We've gotten a HELLO from another peer.
static unsigned int target_connection_count
Target number of connections.
static void schedule_next_hello(void *cls)
Calculate when we would like to send the next HELLO to this peer and ask for it.
static struct GNUNET_PEERSTORE_Handle * ps
Handle to the PEERSTORE service.
static struct GNUNET_PEERSTORE_Monitor * peerstore_notify
Our peerstore notification context.
static void disconnect_notify(void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
Method called whenever a peer disconnects.
static struct GNUNET_STATISTICS_Handle * stats
Handle for reporting statistics.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static void address_iterator(void *cls, const struct GNUNET_PeerIdentity *pid, const char *uri)
Iterator called on each address.
static unsigned int connection_count
Number of peers that we are currently connected to.
static struct StoreHelloEntry * she_head
Head of the linkd list to store the store context for hellos.
static void start_notify(void *cls)
static struct StoreHelloEntry * she_tail
Tail of the linkd list to store the store context for hellos.
struct GNUNET_SCHEDULER_Task * peerstore_notify_task
The task to delayed start the notification process initially.
static void process_peer(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *err_msg)
PEERSTORE calls this function to let us know about a possible peer that we might want to connect to.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run.
static void core_init(void *cls, const struct GNUNET_PeerIdentity *my_id)
Function called after GNUNET_CORE_connect has succeeded (or failed for good).
static void shc_cont(void *cls, int success)
#define HELLO_ADVERTISEMENT_MIN_REPEAT_FREQUENCY
After what time period do we expire the HELLO Bloom filter?
static int reschedule_hellos(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Cancel existing requests for sending HELLOs to this peer and recalculate when we should send HELLOs t...
static void pid_change_cb(void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *addr_hash)
struct GNUNET_TRANSPORT_ApplicationHandle * transport
Handle to Transport service.
#define HELLO_ADVERTISEMENT_MIN_FREQUENCY
At what frequency do we sent HELLOs to a peer?
static void setup_filter(struct Peer *peer)
Setup bloom filter for the given peer entry.
#define RECONSIDER_FREQUENCY
How often do we reconsider which peers we would like to be connected to?
static int free_peer(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Free all resources associated with the given peer.
static void error_cb(void *cls)
static struct GNUNET_SCHEDULER_Task * add_task
Task scheduled to asynchronously reconsider adding/removing peer connectivity suggestions.
static void attempt_connect(struct Peer *pos)
Recalculate how much we want to be connected to the specified peer and let ATS know about the result.
static int find_advertisable_hello(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Find a peer that would be reasonable for advertising.
static struct Peer * make_peer(const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *hello)
Create a new entry in the peer list.
static int try_add_peers(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Try to add more peers to our connection set.
static void * connect_notify(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq, enum GNUNET_CORE_PeerClass class)
Method called whenever a peer connects.
static struct GNUNET_PILS_Handle * pils
Handle to the PILS service.
static char * value
Value of the record to add/remove.
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
static struct GNUNET_CONTAINER_BloomFilter * filter
Bloomfilter to quickly tell if we don't have the content.
struct GNUNET_PILS_Handle * GNUNET_PILS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_PILS_PidChangeCallback pid_change_cb, void *cls)
Connect to the PILS service.
Definition pils_api.c:624
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:647
struct GNUNET_PQ_ResultSpec __attribute__
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
struct GNUNET_TRANSPORT_ApplicationSuggestHandle * GNUNET_TRANSPORT_application_suggest(struct GNUNET_TRANSPORT_ApplicationHandle *ch, const struct GNUNET_PeerIdentity *peer, enum GNUNET_MQ_PriorityPreferences pk, struct GNUNET_BANDWIDTH_Value32NBO bw)
An application would like TRANSPORT to connect to a peer.
void GNUNET_TRANSPORT_application_done(struct GNUNET_TRANSPORT_ApplicationHandle *ch)
Shutdown TRANSPORT application client.
void GNUNET_TRANSPORT_application_suggest_cancel(struct GNUNET_TRANSPORT_ApplicationSuggestHandle *sh)
We no longer care about being connected to a peer.
struct GNUNET_TRANSPORT_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to the filter.
bool GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associated with a filter in memory, flush to drive if needed (do not free the space on...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
struct GNUNET_CORE_Handle * GNUNET_CORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls, GNUNET_CORE_StartupCallback init, GNUNET_CORE_ConnectEventHandler connects, GNUNET_CORE_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers, const struct GNUNET_CORE_ServiceInfo *service_info)
Connect to the core service.
Definition core_api.c:698
GNUNET_CORE_PeerClass
The peer class gives a hint about the capabilities of a peer.
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition core_api.c:744
@ GNUNET_CORE_SERVICE_TOPOLOGY
Identifier for topology service.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_GETOPT_OPTION_END
Marker for the end of the list of options.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:40
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
void GNUNET_HELLO_parser_free(struct GNUNET_HELLO_Parser *parser)
Release resources of a builder.
Definition hello-uri.c:380
const struct GNUNET_PeerIdentity * GNUNET_HELLO_parser_iterate(const struct GNUNET_HELLO_Parser *parser, GNUNET_HELLO_UriCallback uc, void *uc_cls)
Iterate over URIs in a parser.
Definition hello-uri.c:1052
struct GNUNET_TIME_Absolute GNUNET_HELLO_get_expiration_time_from_msg(const struct GNUNET_MessageHeader *msg)
Get the expiration time for this HELLO.
Definition hello-uri.c:655
const struct GNUNET_PeerIdentity * GNUNET_HELLO_parser_get_id(const struct GNUNET_HELLO_Parser *parser)
Get the PeerIdentity for this builder.
Definition hello-uri.c:354
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_msg(const struct GNUNET_MessageHeader *msg, const struct GNUNET_PeerIdentity *pid)
Parse msg.
Definition hello-uri.c:416
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_MQ_Envelope * GNUNET_MQ_msg_copy(const struct GNUNET_MessageHeader *hdr)
Create a new envelope by copying an existing message.
Definition mq.c:582
void GNUNET_MQ_set_options(struct GNUNET_MQ_Handle *mq, enum GNUNET_MQ_PriorityPreferences pp)
Set application-specific options for this queue.
Definition mq.c:920
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition mq.c:337
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
@ GNUNET_MQ_PRIO_BEST_EFFORT
Best-effort traffic (e.g.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
void GNUNET_PEERSTORE_monitor_stop(struct GNUNET_PEERSTORE_Monitor *zm)
Stop monitoring.
void GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h)
Disconnect from the PEERSTORE service.
struct GNUNET_PEERSTORE_Monitor * GNUNET_PEERSTORE_monitor_start(const struct GNUNET_CONFIGURATION_Handle *cfg, int iterate_first, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_SCHEDULER_TaskCallback sync_cb, void *sync_cb_cls, GNUNET_PEERSTORE_Processor callback, void *callback_cls)
Request watching a given key The monitoring can be filtered to contain only records matching peer and...
struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the PEERSTORE service.
void GNUNET_PEERSTORE_monitor_next(struct GNUNET_PEERSTORE_Monitor *zm, uint64_t limit)
Calls the monitor processor specified in GNUNET_PEERSTORE_monitor_start for the next record(s).
void GNUNET_PEERSTORE_hello_add_cancel(struct GNUNET_PEERSTORE_StoreHelloContext *huc)
Cancel the request to add a hello.
#define GNUNET_PEERSTORE_HELLO_KEY
Key used for storing HELLO in the peerstore.
struct GNUNET_PEERSTORE_StoreHelloContext * GNUNET_PEERSTORE_hello_add(struct GNUNET_PEERSTORE_Handle *h, const struct GNUNET_MessageHeader *msg, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Add hello to peerstore.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(const struct GNUNET_OS_ProjectData *pd, int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition program.c:406
#define GNUNET_MESSAGE_TYPE_HELLO_URI
Latest HELLO messages used for communicating peer addresses.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:572
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1345
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition time.c:344
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
#define GNUNET_TIME_absolute_cmp(t1, op, t2)
Compare two absolute times.
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
Closure for find_advertisable_hello().
size_t max_size
Maximum HELLO size we can use right now.
struct Peer * peer
Peer we want to advertise to.
struct GNUNET_TIME_Relative next_adv
struct Peer * result
Where to store the result (peer selected for advertising).
32-bit bandwidth used for network exchange by GNUnet, in bytes per second.
Internal representation of the hash map.
Context for the core service connection.
Definition core_api.c:78
Gnunet service info - identifying compatibility with a range of version of a service communicating ov...
enum GNUNET_CORE_Service service
Identifier of the service on top of CORE.
Definition of a command line option.
Context for parsing HELLOs.
Definition hello-uri.c:233
struct GNUNET_PeerIdentity pid
Public key of the peer.
Definition hello-uri.c:237
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Message handler for a specific message type.
Header for all communications.
Handle to the PEERSTORE service.
Context for a add hello uri request.
A handle for the PILS service.
Definition pils_api.c:86
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition scheduler.c:141
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
Handle to the TRANSPORT subsystem for application management.
Handle for TRANSPORT address suggestion requests.
Record for neighbours and blacklisted peers.
struct GNUNET_PeerIdentity pid
Which peer is this entry about?
struct GNUNET_MessageHeader * hello
Pointer to the hello uri of this peer; can be NULL.
struct GNUNET_TIME_Absolute next_hello_allowed
Next time we are allowed to transmit a HELLO to this peer?
struct GNUNET_CONTAINER_BloomFilter * filter
Bloom filter used to mark which peers already got the HELLO from this peer.
struct GNUNET_SCHEDULER_Task * hello_delay_task
ID of task we use to wait for the time to send the next HELLO to this peer.
struct GNUNET_TIME_Absolute filter_expiration
When should we reset the bloom filter of this entry?
struct GNUNET_TRANSPORT_ApplicationSuggestHandle * ash
Transport suggest handle.
uint32_t strength
How much would we like to connect to this peer?
struct GNUNET_MQ_Handle * mq
Our handle for transmitting to this peer; NULL if peer is not connected.
Context for a add hello uri request.
struct GNUNET_PEERSTORE_StoreHelloContext * sc
Store hello ctx.
struct StoreHelloEntry * prev
Kept (also) in a DLL.
struct StoreHelloEntry * next
Kept (also) in a DLL.

◆ HELLO_ADVERTISEMENT_MIN_REPEAT_FREQUENCY

#define HELLO_ADVERTISEMENT_MIN_REPEAT_FREQUENCY    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)

After what time period do we expire the HELLO Bloom filter?

Definition at line 52 of file gnunet-daemon-topology.c.

◆ RECONSIDER_FREQUENCY

#define RECONSIDER_FREQUENCY    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1)

How often do we reconsider which peers we would like to be connected to?

Definition at line 58 of file gnunet-daemon-topology.c.

Function Documentation

◆ free_peer()

static int free_peer ( void *  cls,
const struct GNUNET_PeerIdentity pid,
void *  value 
)
static

Free all resources associated with the given peer.

Parameters
clsclosure (not used)
pididentity of the peer
valuepeer to free
Returns
GNUNET_YES (always: continue to iterate)

Definition at line 228 of file gnunet-daemon-topology.c.

229{
230 struct Peer *pos = value;
231
232 GNUNET_break (NULL == pos->mq);
235 if (NULL != pos->hello_delay_task)
236 {
238 pos->hello_delay_task = NULL;
239 }
240 if (NULL != pos->ash)
241 {
243 pos->ash = NULL;
244 }
245 if (NULL != pos->hello)
246 {
247 GNUNET_free (pos->hello);
248 pos->hello = NULL;
249 }
250 if (NULL != pos->filter)
251 {
253 pos->filter = NULL;
254 }
255 GNUNET_free (pos);
256 return GNUNET_YES;
257}

References Peer::ash, Peer::filter, GNUNET_break, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_multipeermap_remove(), GNUNET_free, GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_TRANSPORT_application_suggest_cancel(), GNUNET_YES, Peer::hello, Peer::hello_delay_task, Peer::mq, peers, Peer::pid, and value.

Referenced by cleaning_task(), and process_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ attempt_connect()

static void attempt_connect ( struct Peer pos)
static

Recalculate how much we want to be connected to the specified peer and let ATS know about the result.

Parameters
pospeer to consider connecting to

Definition at line 267 of file gnunet-daemon-topology.c.

268{
269 uint32_t strength;
271
273 "Checking if we want to attempt connection to `%s'\n",
274 GNUNET_i2s (&pos->pid));
275 if (0 == GNUNET_memcmp (&my_identity, &pos->pid))
276 return; /* This is myself, nothing to do. */
278 strength = 1;
279 else
280 strength = 0;
281 if (NULL != pos->mq)
282 strength *= 2; /* existing connections preferred */
283 if ((strength == pos->strength) &&
284 ((NULL == pos->ash) == (0 == strength)))
285 return; /* nothing changed; re-issuing the suggestion would only reset
286 the retry state transport keeps for it */
287 if (NULL != pos->ash)
288 {
290 pos->ash = NULL;
291 }
292 pos->strength = strength;
293 if (0 != strength)
294 {
296 "Asking to connect to `%s' with strength %u\n",
297 GNUNET_i2s (&pos->pid),
298 (unsigned int) strength);
300 gettext_noop ("# connect requests issued to ATS"),
301 1,
302 GNUNET_NO);
303 // TODO Use strength somehow.
304 bw.value__ = 0;
306 &pos->pid,
308 bw);
309 }
310}

References Peer::ash, connection_count, gettext_noop, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_memcmp, GNUNET_MQ_PRIO_BEST_EFFORT, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TRANSPORT_application_suggest(), GNUNET_TRANSPORT_application_suggest_cancel(), Peer::mq, my_identity, Peer::pid, stats, Peer::strength, target_connection_count, transport, and GNUNET_BANDWIDTH_Value32NBO::value__.

Referenced by process_peer(), and try_add_peers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_peer()

static struct Peer * make_peer ( const struct GNUNET_PeerIdentity peer,
const struct GNUNET_MessageHeader hello 
)
static

Create a new entry in the peer list.

Parameters
peeridentity of the new entry
hellohello message, can be NULL
Returns
the new entry

Definition at line 321 of file gnunet-daemon-topology.c.

323{
324 struct Peer *ret;
325
326 ret = GNUNET_new (struct Peer);
327 ret->pid = *peer;
328 if (NULL != hello)
329 {
330 ret->hello = GNUNET_malloc (ntohs (hello->size));
331 GNUNET_memcpy (ret->hello, hello, ntohs (hello->size));
332 }
335 peers,
336 peer,
337 ret,
339 return ret;
340}

References GNUNET_break, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_put(), GNUNET_malloc, GNUNET_memcpy, GNUNET_new, GNUNET_OK, Peer::hello, peers, ret, and GNUNET_MessageHeader::size.

Referenced by connect_notify(), consider_for_advertising(), and process_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setup_filter()

static void setup_filter ( struct Peer peer)
static

Setup bloom filter for the given peer entry.

Parameters
peerentry to initialize

Definition at line 349 of file gnunet-daemon-topology.c.

350{
351 struct GNUNET_HashCode hc;
352
353 /* 2^{-5} chance of not sending a HELLO to a peer is
354 * acceptably small (if the filter is 50% full);
355 * 64 bytes of memory are small compared to the rest
356 * of the data structure and would only really become
357 * "useless" once a HELLO has been passed on to ~100
358 * other peers, which is likely more than enough in
359 * any case; hence 64, 5 as bloomfilter parameters. */peer->filter = GNUNET_CONTAINER_bloomfilter_init (NULL, 64, 5);
360 peer->filter_expiration =
362 /* never send a peer its own HELLO */
363 GNUNET_CRYPTO_hash (&peer->pid, sizeof(struct GNUNET_PeerIdentity), &hc);
365}

References Peer::filter, Peer::filter_expiration, GNUNET_CONTAINER_bloomfilter_add(), GNUNET_CONTAINER_bloomfilter_init(), GNUNET_CRYPTO_hash(), GNUNET_TIME_relative_to_absolute(), HELLO_ADVERTISEMENT_MIN_REPEAT_FREQUENCY, and Peer::pid.

Referenced by consider_for_advertising(), and find_advertisable_hello().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_advertisable_hello()

static int find_advertisable_hello ( void *  cls,
const struct GNUNET_PeerIdentity pid,
void *  value 
)
static

Find a peer that would be reasonable for advertising.

Parameters
clsclosure
pididentity of a peer
value'struct Peer*' for the peer we are considering
Returns
GNUNET_YES (continue iteration)

Definition at line 401 of file gnunet-daemon-topology.c.

404{
405 struct FindAdvHelloContext *fah = cls;
406 struct Peer *pos = value;
407 struct GNUNET_TIME_Relative rst_time;
408 struct GNUNET_HashCode hc;
409 size_t hs;
410
412 "find_advertisable_hello\n");
413 if (pos == fah->peer)
414 return GNUNET_YES;
416 "find_advertisable_hello 2\n");
417 if (pos->hello == NULL)
418 return GNUNET_YES;
420 "find_advertisable_hello 3\n");
422 if (0 == rst_time.rel_value_us)
423 {
424 /* time to discard... */
426 setup_filter (pos);
427 }
428 fah->next_adv = GNUNET_TIME_relative_min (rst_time, fah->next_adv);
429 hs = pos->hello->size;
430 if (hs > fah->max_size)
431 return GNUNET_YES;
433 "find_advertisable_hello 4\n");
435 sizeof(struct GNUNET_PeerIdentity),
436 &hc);
438 fah->result = pos;
439 return GNUNET_YES;
440}

References Peer::filter, Peer::filter_expiration, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_bloomfilter_test(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_relative_min(), GNUNET_YES, Peer::hello, FindAdvHelloContext::max_size, FindAdvHelloContext::next_adv, FindAdvHelloContext::peer, Peer::pid, GNUNET_TIME_Relative::rel_value_us, FindAdvHelloContext::result, setup_filter(), GNUNET_MessageHeader::size, and value.

Referenced by schedule_next_hello().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ schedule_next_hello()

static void schedule_next_hello ( void *  cls)
static

Calculate when we would like to send the next HELLO to this peer and ask for it.

Parameters
clsfor which peer to schedule the HELLO

Definition at line 450 of file gnunet-daemon-topology.c.

451{
452 struct Peer *pl = cls;
453 struct FindAdvHelloContext fah;
454 struct GNUNET_MQ_Envelope *env;
455 size_t want;
456 struct GNUNET_TIME_Relative delay;
457 struct GNUNET_HashCode hc;
458
460 "schedule_next_hello\n");
461 pl->hello_delay_task = NULL;
462 GNUNET_assert (NULL != pl->mq);
463 /* find applicable HELLOs */
464 fah.peer = pl;
465 fah.result = NULL;
466 fah.max_size = GNUNET_MAX_MESSAGE_SIZE - 1;
467 fah.next_adv = GNUNET_TIME_UNIT_FOREVER_REL;
469 if (NULL == fah.result)
470 {
471 pl->hello_delay_task =
473
474 return;
475 }
476 want = ntohs (fah.result->hello->size);
478 "Sending HELLO with %u bytes for peer %s\n",
479 (unsigned int) want,
480 GNUNET_i2s (&pl->pid));
481 env = GNUNET_MQ_msg_copy (fah.result->hello);
482 GNUNET_MQ_send (pl->mq, env);
483
484 /* avoid sending this one again soon */
485 GNUNET_CRYPTO_hash (&pl->pid, sizeof(struct GNUNET_PeerIdentity), &hc);
486 GNUNET_CONTAINER_bloomfilter_add (fah.result->filter, &hc);
487
489 gettext_noop ("# HELLO messages gossipped"),
490 1,
491 GNUNET_NO);
492 /* prepare to send the next one */
498}

References env, Peer::filter, find_advertisable_hello(), gettext_noop, GNUNET_assert, GNUNET_CONTAINER_bloomfilter_add(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_MQ_msg_copy(), GNUNET_MQ_send(), GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_UNIT_FOREVER_REL, Peer::hello, HELLO_ADVERTISEMENT_MIN_FREQUENCY, Peer::hello_delay_task, FindAdvHelloContext::max_size, Peer::mq, FindAdvHelloContext::next_adv, Peer::next_hello_allowed, FindAdvHelloContext::peer, peers, Peer::pid, FindAdvHelloContext::result, schedule_next_hello(), GNUNET_MessageHeader::size, and stats.

Referenced by reschedule_hellos(), and schedule_next_hello().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reschedule_hellos()

static int reschedule_hellos ( void *  cls,
const struct GNUNET_PeerIdentity pid,
void *  value 
)
static

Cancel existing requests for sending HELLOs to this peer and recalculate when we should send HELLOs to it based on our current state (something changed!).

Parameters
clsclosure struct Peer to skip, or NULL
pididentity of a peer
valuestruct Peer * for the peer
Returns
GNUNET_YES (always)

Definition at line 512 of file gnunet-daemon-topology.c.

515{
516 struct Peer *peer = value;
517 (void) cls;
518
520 "Reschedule for `%s'\n",
521 GNUNET_i2s (&peer->pid));
522 if (NULL == peer->mq)
523 return GNUNET_YES;
524 if (NULL != peer->hello_delay_task)
525 {
527 peer->hello_delay_task = NULL;
528 }
530 "Schedule_next_hello\n");
531 peer->hello_delay_task =
533 return GNUNET_YES;
534}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_YES, Peer::hello_delay_task, Peer::mq, Peer::pid, schedule_next_hello(), and value.

Referenced by connect_notify(), and consider_for_advertising().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ connect_notify()

static void * connect_notify ( void *  cls,
const struct GNUNET_PeerIdentity peer,
struct GNUNET_MQ_Handle mq,
enum GNUNET_CORE_PeerClass  class 
)
static

Method called whenever a peer connects.

Parameters
clsclosure
peerpeer identity this notification is about
mqmessage queue for communicating with peer
classclass of the connecting peer
Returns
our struct Peer for peer

Definition at line 547 of file gnunet-daemon-topology.c.

551{
552 struct Peer *pos;
553
555 "Core told us that we are connecting to `%s'\n",
556 GNUNET_i2s (peer));
557 if (0 == GNUNET_memcmp (&my_identity, peer))
558 return NULL;
562 gettext_noop ("# peers connected"),
564 GNUNET_NO);
566 if (NULL == pos)
567 {
568 pos = make_peer (peer, NULL);
569 }
570 else
571 {
572 GNUNET_assert (NULL == pos->mq);
573 }
574 pos->mq = mq;
575 reschedule_hellos (NULL, peer, pos);
576 return pos;
577}

References connection_count, gettext_noop, GNUNET_assert, GNUNET_CONTAINER_multipeermap_get(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_memcmp, GNUNET_MQ_PRIO_BEST_EFFORT, GNUNET_MQ_set_options(), GNUNET_NO, GNUNET_STATISTICS_set(), make_peer(), mq, Peer::mq, my_identity, peers, reschedule_hellos(), and stats.

Referenced by reconnect(), and run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_add_peers()

static int try_add_peers ( void *  cls,
const struct GNUNET_PeerIdentity pid,
void *  value 
)
static

Try to add more peers to our connection set.

Parameters
clsclosure, not used
pididentity of a peer
valuestruct Peer * for the peer
Returns
GNUNET_YES (continue to iterate)

Definition at line 589 of file gnunet-daemon-topology.c.

590{
591 struct Peer *pos = value;
592
593 attempt_connect (pos);
594 return GNUNET_YES;
595}

References attempt_connect(), GNUNET_YES, and value.

Referenced by add_peer_task().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_peer_task()

static void add_peer_task ( void *  cls)
static

Add peers and schedule connection attempt.

Parameters
clsunused, NULL

Definition at line 604 of file gnunet-daemon-topology.c.

605{
606 add_task = NULL;
607
609 /* Keep going. A suggestion that did not work out produces no event of
610 its own -- the peer simply never connects -- so without a periodic
611 re-run the only things that ever call attempt_connect() again are a
612 CORE disconnect and a HELLO showing up in PEERSTORE. A peer we cannot
613 reach delivers neither, and a peer whose HELLO we learned while we were
614 already at the target connection count never gets a suggestion at
615 all. */
618 NULL);
619}

References add_peer_task(), add_task, GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_SCHEDULER_add_delayed(), peers, RECONSIDER_FREQUENCY, and try_add_peers().

Referenced by add_peer_task(), disconnect_notify(), and run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ disconnect_notify()

static void disconnect_notify ( void *  cls,
const struct GNUNET_PeerIdentity peer,
void *  internal_cls 
)
static

Method called whenever a peer disconnects.

Parameters
clsclosure
peerpeer identity this notification is about
internal_clsthe struct Peer for this peer

Definition at line 630 of file gnunet-daemon-topology.c.

633{
634 struct Peer *pos = internal_cls;
635
636 if (NULL == pos)
637 return; /* myself, we're shutting down */
639 "Core told us that we disconnected from `%s'\n",
640 GNUNET_i2s (peer));
641 if (NULL == pos->mq)
642 {
643 GNUNET_break (0);
644 return;
645 }
646 pos->mq = NULL;
648 if (NULL != pos->hello_delay_task)
649 {
651 pos->hello_delay_task = NULL;
652 }
654 gettext_noop ("# peers connected"),
656 GNUNET_NO);
658 {
659 /* Do not wait for the next periodic run. */
660 if (NULL != add_task)
663 }
664}

References add_peer_task(), add_task, connection_count, gettext_noop, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_set(), Peer::hello_delay_task, Peer::mq, stats, and target_connection_count.

Referenced by reconnect(), and run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ address_iterator()

static void address_iterator ( void *  cls,
const struct GNUNET_PeerIdentity pid,
const char *  uri 
)
static

Iterator called on each address.

Parameters
clsflag that we will set if we see any addresses
addressthe address of the peer
Returns
GNUNET_SYSERR always, to terminate iteration

Definition at line 675 of file gnunet-daemon-topology.c.

678{
679 int *flag = cls;
680 (void) pid;
681
682 *flag = *flag + 1;
683 // *flag = GNUNET_YES;
684}

References Peer::pid.

Referenced by consider_for_advertising().

Here is the caller graph for this function:

◆ consider_for_advertising()

static void consider_for_advertising ( const struct GNUNET_MessageHeader hello)
static

We've gotten a HELLO from another peer.

Consider it for advertising.

Parameters
hellothe HELLO we got

Definition at line 694 of file gnunet-daemon-topology.c.

695{
696 int num_addresses_old = 0;
697 int num_addresses_new = 0;
699 const struct GNUNET_PeerIdentity *pid;
700 struct Peer *peer;
701 uint16_t size;
702
704 if (NULL == parser)
705 {
706 return;
707 }
710 &num_addresses_new);
712 "consider 0 for %s\n",
713 GNUNET_i2s (pid));
714 if (0 == num_addresses_new)
715 {
717 return; /* no point in advertising this one... */
718 }
720 if (NULL == peer)
721 {
722 peer = make_peer (pid, hello);
723 }
724 else if (NULL != peer->hello)
725 {
727 struct GNUNET_TIME_Absolute new_hello_exp =
729 struct GNUNET_TIME_Absolute old_hello_exp =
731 struct GNUNET_HELLO_Parser *parser_old =
732 GNUNET_HELLO_parser_from_msg (peer->hello, &peer->pid);
733
734 GNUNET_HELLO_parser_iterate (parser_old,
736 &num_addresses_old);
737 GNUNET_HELLO_parser_free (parser_old);
738 if (GNUNET_TIME_absolute_cmp (new_hello_exp, >, now) &&
739 (GNUNET_TIME_absolute_cmp (new_hello_exp, >, old_hello_exp) ||
740 num_addresses_old < num_addresses_new))
741 {
742 GNUNET_free (peer->hello);
743 size = ntohs (hello->size);
744 peer->hello = GNUNET_malloc (size);
745 GNUNET_memcpy (peer->hello, hello, size);
746 }
747 else
748 {
750 "consider 3\n");
752 return;
753 }
754 }
755 else
756 {
757 size = ntohs (hello->size);
758 peer->hello = GNUNET_malloc (size);
759 GNUNET_memcpy (peer->hello, hello, size);
760 }
762 "Found HELLO from peer `%s' for advertising\n",
763 GNUNET_i2s (pid));
764 if (NULL != peer->filter)
765 {
767 peer->filter = NULL;
768 }
769 setup_filter (peer);
770 /* since we have a new HELLO to pick from, re-schedule all
771 * HELLO requests that are not bound by the HELLO send rate! */
774}

References address_iterator(), Peer::filter, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_multipeermap_get(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_HELLO_get_expiration_time_from_msg(), GNUNET_HELLO_parser_free(), GNUNET_HELLO_parser_from_msg(), GNUNET_HELLO_parser_iterate(), GNUNET_i2s(), GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_TIME_absolute_cmp, GNUNET_TIME_absolute_get(), Peer::hello, make_peer(), peers, GNUNET_HELLO_Parser::pid, Peer::pid, reschedule_hellos(), setup_filter(), GNUNET_MessageHeader::size, and size.

Referenced by process_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ error_cb()

static void error_cb ( void *  cls)
static

Definition at line 778 of file gnunet-daemon-topology.c.

779{
781 _ (
782 "Error in communication with PEERSTORE service to monitor.\n"));
783 return;
784}

References _, GNUNET_ERROR_TYPE_DEBUG, and GNUNET_log.

Referenced by process_peer(), and start_notify().

Here is the caller graph for this function:

◆ sync_cb()

static void sync_cb ( void *  cls)
static

Definition at line 788 of file gnunet-daemon-topology.c.

789{
791 _ ("Finished initial PEERSTORE iteration in monitor.\n"));
792 return;
793}

References _, GNUNET_ERROR_TYPE_DEBUG, and GNUNET_log.

Referenced by process_peer(), and start_notify().

Here is the caller graph for this function:

◆ process_peer()

static void process_peer ( void *  cls,
const struct GNUNET_PEERSTORE_Record record,
const char *  err_msg 
)
static

PEERSTORE calls this function to let us know about a possible peer that we might want to connect to.

Parameters
clsclosure (not used)
peerpotential peer to connect to
helloHELLO for this peer (or NULL)
err_msgNULL if successful, otherwise contains error message

Definition at line 806 of file gnunet-daemon-topology.c.

809{
810 struct Peer *pos;
811 struct GNUNET_MessageHeader *hello;
812
813 if (NULL != err_msg)
814 {
816 _ ("Error in communication with PEERSTORE service: %s\n"),
817 err_msg);
822 "peerstore",
823 NULL,
825 error_cb,
826 NULL,
827 sync_cb,
828 NULL,
830 NULL);
831 return;
832 }
833 GNUNET_assert (NULL != record);
835 "Processing HELLO from peerstore from peer `%s'\n",
836 GNUNET_i2s (&record->peer));
837 hello = record->value;
838 if (NULL == hello)
839 {
840 /* free existing HELLO, if any */
842 if (NULL != pos)
843 {
844 GNUNET_free (pos->hello);
845 pos->hello = NULL;
846 if (NULL != pos->filter)
847 {
849 pos->filter = NULL;
850 }
851 if (NULL == pos->mq)
852 free_peer (NULL, &pos->pid, pos);
853 }
855 return;
856 }
859 if (NULL == pos)
860 pos = make_peer (&record->peer, hello);
861 attempt_connect (pos);
863}

References _, attempt_connect(), cfg, consider_for_advertising(), error_cb(), Peer::filter, free_peer(), GNUNET_assert, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_multipeermap_get(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_PEERSTORE_HELLO_KEY, GNUNET_PEERSTORE_monitor_next(), GNUNET_PEERSTORE_monitor_start(), GNUNET_PEERSTORE_monitor_stop(), GNUNET_YES, Peer::hello, make_peer(), Peer::mq, peers, peerstore_notify, Peer::pid, process_peer(), record(), and sync_cb().

Referenced by process_peer(), and start_notify().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ start_notify()

static void start_notify ( void *  cls)
static

Definition at line 867 of file gnunet-daemon-topology.c.

868{
869 (void) cls;
870
872 "Starting to process new hellos for gossiping.\n");
876 "peerstore",
877 NULL,
879 &error_cb,
880 NULL,
881 &sync_cb,
882 NULL,
884 NULL);
885}

References cfg, error_cb(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_PEERSTORE_HELLO_KEY, GNUNET_PEERSTORE_monitor_start(), GNUNET_YES, peerstore_notify, process_peer(), and sync_cb().

Referenced by core_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pid_change_cb()

static void pid_change_cb ( void *  cls,
const struct GNUNET_HELLO_Parser parser,
const struct GNUNET_HashCode addr_hash 
)
static

Definition at line 889 of file gnunet-daemon-topology.c.

892{
894}

References GNUNET_HELLO_parser_get_id(), and my_identity.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ core_init()

static void core_init ( void *  cls,
const struct GNUNET_PeerIdentity my_id 
)
static

Function called after GNUNET_CORE_connect has succeeded (or failed for good).

Parameters
clsclosure
my_idID of this peer, NULL if we failed

Definition at line 905 of file gnunet-daemon-topology.c.

906{
907 if (NULL == my_id)
908 {
909 GNUNET_log (
911 _ ("Failed to connect to core service, can not manage topology!\n"));
913 return;
914 }
915 my_identity = *my_id;
916 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "I am peer `%s'\n", GNUNET_i2s (my_id));
920 NULL);
921}

References _, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_i2s(), GNUNET_log, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_shutdown(), GNUNET_TIME_UNIT_SECONDS, my_identity, peerstore_notify_task, and start_notify().

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_hello()

static int check_hello ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

This function is called whenever an encrypted HELLO message is received.

Parameters
clsclosure with the peer identity of the sender
messagethe actual HELLO message
Returns
GNUNET_OK if message is well-formed GNUNET_SYSERR if message is invalid

Definition at line 934 of file gnunet-daemon-topology.c.

935{
937 const struct GNUNET_PeerIdentity *pid = GNUNET_HELLO_parser_get_id (parser);
938
939 if (NULL == pid)
940 {
941 GNUNET_break_op (0);
942 return GNUNET_SYSERR;
943 }
944 return GNUNET_OK;
945}

References GNUNET_break_op, GNUNET_HELLO_parser_from_msg(), GNUNET_HELLO_parser_get_id(), GNUNET_OK, GNUNET_SYSERR, and msg.

Here is the call graph for this function:

◆ shc_cont()

static void shc_cont ( void *  cls,
int  success 
)
static

Definition at line 949 of file gnunet-daemon-topology.c.

950{
951 struct StoreHelloEntry *she = cls;
952
953 she->sc = NULL;
954 if (GNUNET_YES == success)
956 "Hello stored successfully!\n");
957 else
959 "Error storing hello!\n");
961 GNUNET_free (she);
962}

References GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_YES, StoreHelloEntry::sc, she_head, and she_tail.

Referenced by handle_hello().

Here is the caller graph for this function:

◆ handle_hello()

static void handle_hello ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

This function is called whenever an encrypted HELLO message is received.

Parameters
clsclosure with the peer identity of the sender
messagethe actual HELLO message

Definition at line 973 of file gnunet-daemon-topology.c.

974{
975 struct StoreHelloEntry *she;
976 const struct GNUNET_PeerIdentity *other = cls;
978
980 "Received encrypted HELLO from peer `%s'\n",
981 GNUNET_i2s (other));
983 gettext_noop ("# HELLO messages received"),
984 1,
985 GNUNET_NO);
987 she = GNUNET_new (struct StoreHelloEntry);
989 if (NULL != she->sc)
990 {
992 }
993 else
994 GNUNET_free (she);
996}

References gettext_noop, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_HELLO_parser_free(), GNUNET_HELLO_parser_from_msg(), GNUNET_i2s(), GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_PEERSTORE_hello_add(), GNUNET_STATISTICS_update(), msg, ps, StoreHelloEntry::sc, shc_cont(), she_head, she_tail, and stats.

Here is the call graph for this function:

◆ cleaning_task()

static void cleaning_task ( void *  cls)
static

Last task run during shutdown.

Disconnects us from the transport and core.

Parameters
clsunused, NULL

Definition at line 1006 of file gnunet-daemon-topology.c.

1007{
1008 struct StoreHelloEntry *pos;
1009
1010 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Topology shutdown\n");
1011 while (NULL != (pos = she_head))
1012 {
1014 if (NULL != pos->sc)
1016 GNUNET_free (pos);
1017 }
1018 if (NULL != peerstore_notify)
1019 {
1021 peerstore_notify = NULL;
1022 }
1023 else if (NULL != peerstore_notify_task)
1024 {
1026 }
1027 if (NULL != pils)
1028 {
1030 pils = NULL;
1031 }
1032 if (NULL != handle)
1033 {
1035 handle = NULL;
1036 }
1037 if (NULL != add_task)
1038 {
1040 add_task = NULL;
1041 }
1044 peers = NULL;
1045 if (NULL != transport)
1046 {
1048 transport = NULL;
1049 }
1050 if (NULL != ps)
1051 {
1053 ps = NULL;
1054 }
1055 if (NULL != stats)
1056 {
1058 stats = NULL;
1059 }
1060}

References add_task, free_peer(), GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multipeermap_destroy(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_CORE_disconnect(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_PEERSTORE_disconnect(), GNUNET_PEERSTORE_hello_add_cancel(), GNUNET_PEERSTORE_monitor_stop(), GNUNET_PILS_disconnect(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_destroy(), GNUNET_TRANSPORT_application_done(), handle, peers, peerstore_notify, peerstore_notify_task, pils, ps, StoreHelloEntry::sc, she_head, she_tail, stats, and transport.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ run()

static void run ( void *  cls,
char *const *  args,
const char *  cfgfile,
const struct GNUNET_CONFIGURATION_Handle c 
)
static

Main function that will be run.

Parameters
clsclosure
argsremaining command-line arguments
cfgfilename of the configuration file used (for saving, can be NULL!)
cconfiguration

Definition at line 1072 of file gnunet-daemon-topology.c.

1076{
1078 { GNUNET_MQ_hd_var_size (hello,
1080 struct GNUNET_MessageHeader,
1081 NULL),
1083 unsigned long long opt;
1084 const struct GNUNET_CORE_ServiceInfo service_info = {
1086 .version = { 1, 0 },
1087 .version_max = { 1, 0 },
1088 .version_min = { 1, 0 },
1089 };
1090
1091 cfg = c;
1092 stats = GNUNET_STATISTICS_create ("topology", cfg);
1093
1094 if (GNUNET_OK !=
1096 "TOPOLOGY",
1097 "TARGET-CONNECTION-COUNT",
1098 &opt))
1099 opt = 16;
1100 target_connection_count = (unsigned int) opt;
1102 GNUNET_NO);
1106 NULL,
1107 &core_init,
1110 handlers,
1111 &service_info);
1114 if (NULL == pils)
1115 {
1117 _ ("Failed to connect to `%s' service.\n"),
1118 "pils");
1120 return;
1121 }
1122 if (NULL == handle)
1123 {
1125 _ ("Failed to connect to `%s' service.\n"),
1126 "core");
1128 return;
1129 }
1132 NULL);
1133}

References _, add_peer_task(), add_task, cfg, cleaning_task(), connect_notify(), core_init(), disconnect_notify(), GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONTAINER_multipeermap_create(), GNUNET_CORE_connect(), GNUNET_CORE_SERVICE_TOPOLOGY, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_MESSAGE_TYPE_HELLO_URI, GNUNET_MQ_handler_end, GNUNET_MQ_hd_var_size, GNUNET_NO, GNUNET_OK, GNUNET_PEERSTORE_connect(), GNUNET_PILS_connect(), GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_STATISTICS_create(), GNUNET_TRANSPORT_application_init(), handle, handlers, peers, pid_change_cb(), pils, ps, RECONSIDER_FREQUENCY, GNUNET_CORE_ServiceInfo::service, stats, target_connection_count, and transport.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char *const *  argv 
)

The main function for the topology daemon.

Parameters
argcnumber of arguments from the command line
argvcommand line arguments
Returns
0 ok, 1 on error

Definition at line 1144 of file gnunet-daemon-topology.c.

1145{
1146 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1148 };
1149 int ret;
1150
1151 ret = (GNUNET_OK ==
1153 argc,
1154 argv,
1155 "gnunet-daemon-topology",
1156 _ ("GNUnet topology control"),
1157 options,
1158 &run,
1159 NULL))
1160 ? 0
1161 : 1;
1162 return ret;
1163}

References _, GNUNET_GETOPT_OPTION_END, GNUNET_OK, GNUNET_OS_project_data_gnunet(), GNUNET_PROGRAM_run(), options, ret, and run().

Here is the call graph for this function:

Variable Documentation

◆ peerstore_notify_task

struct GNUNET_SCHEDULER_Task* peerstore_notify_task

The task to delayed start the notification process initially.

We like to give transport some time to give us our hello to distribute it.

Definition at line 142 of file gnunet-daemon-topology.c.

Referenced by cleaning_task(), and core_init().

◆ peerstore_notify

struct GNUNET_PEERSTORE_Monitor* peerstore_notify
static

Our peerstore notification context.

We use notification to instantly learn about new peers as they are discovered.

Definition at line 149 of file gnunet-daemon-topology.c.

Referenced by cleaning_task(), process_peer(), and start_notify().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Our configuration.

Definition at line 154 of file gnunet-daemon-topology.c.

Referenced by process_peer(), run(), and start_notify().

◆ pils

struct GNUNET_PILS_Handle* pils
static

Handle to the PILS service.

Definition at line 159 of file gnunet-daemon-topology.c.

Referenced by cleaning_task(), and run().

◆ handle

struct GNUNET_CORE_Handle* handle
static

Handle to the CORE service.

Definition at line 164 of file gnunet-daemon-topology.c.

Referenced by cleaning_task(), and run().

◆ ps

◆ transport

Handle to Transport service.

Definition at line 174 of file gnunet-daemon-topology.c.

Referenced by attempt_connect(), cleaning_task(), and run().

◆ my_identity

struct GNUNET_PeerIdentity my_identity
static

Identity of this peer.

Definition at line 179 of file gnunet-daemon-topology.c.

Referenced by attempt_connect(), connect_notify(), core_init(), and pid_change_cb().

◆ peers

struct GNUNET_CONTAINER_MultiPeerMap* peers
static

All of our current neighbours and all peers for which we have HELLOs.

So pretty much everyone. Maps peer identities to struct Peer * values.

Definition at line 186 of file gnunet-daemon-topology.c.

Referenced by add_peer_task(), cleaning_task(), connect_notify(), consider_for_advertising(), free_peer(), make_peer(), process_peer(), run(), and schedule_next_hello().

◆ stats

struct GNUNET_STATISTICS_Handle* stats
static

Handle for reporting statistics.

Definition at line 191 of file gnunet-daemon-topology.c.

Referenced by attempt_connect(), cleaning_task(), connect_notify(), disconnect_notify(), handle_hello(), run(), and schedule_next_hello().

◆ add_task

struct GNUNET_SCHEDULER_Task* add_task
static

Task scheduled to asynchronously reconsider adding/removing peer connectivity suggestions.

Definition at line 197 of file gnunet-daemon-topology.c.

Referenced by add_peer_task(), cleaning_task(), disconnect_notify(), and run().

◆ connection_count

unsigned int connection_count
static

Number of peers that we are currently connected to.

Definition at line 202 of file gnunet-daemon-topology.c.

Referenced by attempt_connect(), connect_notify(), and disconnect_notify().

◆ target_connection_count

unsigned int target_connection_count
static

Target number of connections.

Definition at line 207 of file gnunet-daemon-topology.c.

Referenced by attempt_connect(), disconnect_notify(), and run().

◆ she_head

struct StoreHelloEntry* she_head
static

Head of the linkd list to store the store context for hellos.

Definition at line 212 of file gnunet-daemon-topology.c.

Referenced by cleaning_task(), handle_hello(), and shc_cont().

◆ she_tail

struct StoreHelloEntry* she_tail
static

Tail of the linkd list to store the store context for hellos.

Definition at line 217 of file gnunet-daemon-topology.c.

Referenced by cleaning_task(), handle_hello(), and shc_cont().