GNUnet  0.19.4
gnunet-daemon-topology.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2007-2016 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
39 #include "platform.h"
40 #include "gnunet_util_lib.h"
41 #include "gnunet_friends_lib.h"
42 #include "gnunet_constants.h"
43 #include "gnunet_core_service.h"
44 #include "gnunet_protocols.h"
48 #include "gnunet_ats_service.h"
49 
50 
54 #define HELLO_ADVERTISEMENT_MIN_FREQUENCY \
55  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
56 
60 #define HELLO_ADVERTISEMENT_MIN_REPEAT_FREQUENCY \
61  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
62 
63 
67 struct Peer
68 {
72  struct GNUNET_PeerIdentity pid;
73 
79 
84 
90 
95 
100 
106 
111 
115  uint32_t strength;
116 
121 };
122 
123 
129 
133 static const struct GNUNET_CONFIGURATION_Handle *cfg;
134 
138 static struct GNUNET_CORE_Handle *handle;
139 
143 static struct GNUNET_PEERINFO_Handle *pi;
144 
149 
153 static struct GNUNET_PeerIdentity my_identity;
154 
161 
166 
171 
177 
182 
186 static int friends_only;
187 
192 static unsigned int minimum_friend_count;
193 
197 static unsigned int connection_count;
198 
202 static unsigned int target_connection_count;
203 
207 static unsigned int friend_count;
208 
209 
219 static int
221 {
222  struct Peer *pos;
223 
225  if ((NULL != pos) && (GNUNET_YES == pos->is_friend))
226  return GNUNET_OK;
228  gettext_noop ("# peers blacklisted"),
229  1,
230  GNUNET_NO);
231  return GNUNET_SYSERR;
232 }
233 
234 
239 static void
241 {
242  if (NULL != blacklist)
243  {
245  blacklist = NULL;
246  }
247 }
248 
249 
258 static int
259 free_peer (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
260 {
261  struct Peer *pos = value;
262 
263  GNUNET_break (NULL == pos->mq);
266  if (NULL != pos->hello_delay_task)
267  {
269  pos->hello_delay_task = NULL;
270  }
271  if (NULL != pos->sh)
272  {
274  pos->sh = NULL;
275  }
276  if (NULL != pos->hello)
277  {
278  GNUNET_free (pos->hello);
279  pos->hello = NULL;
280  }
281  if (NULL != pos->filter)
282  {
284  pos->filter = NULL;
285  }
286  GNUNET_free (pos);
287  return GNUNET_YES;
288 }
289 
290 
297 static void
298 attempt_connect (struct Peer *pos)
299 {
300  uint32_t strength;
301 
302  if (0 == GNUNET_memcmp (&my_identity, &pos->pid))
303  return; /* This is myself, nothing to do. */
305  strength = 1;
306  else
307  strength = 0;
309  {
310  if (pos->is_friend)
311  strength += 10; /* urgently needed */
312  else
313  strength = 0; /* disallowed */
314  }
315  if (pos->is_friend)
316  strength *= 2; /* friends always count more */
317  if (NULL != pos->mq)
318  strength *= 2; /* existing connections preferred */
319  if (strength == pos->strength)
320  return; /* nothing to do */
321  if (NULL != pos->sh)
322  {
324  pos->sh = NULL;
325  }
326  pos->strength = strength;
327  if (0 != strength)
328  {
330  "Asking to connect to `%s' with strength %u\n",
331  GNUNET_i2s (&pos->pid),
332  (unsigned int) strength);
334  gettext_noop ("# connect requests issued to ATS"),
335  1,
336  GNUNET_NO);
338  }
339 }
340 
341 
350 static struct Peer *
352  const struct GNUNET_HELLO_Message *hello,
353  int is_friend)
354 {
355  struct Peer *ret;
356 
357  ret = GNUNET_new (struct Peer);
358  ret->pid = *peer;
359  ret->is_friend = is_friend;
360  if (NULL != hello)
361  {
364  }
367  peers,
368  peer,
369  ret,
371  return ret;
372 }
373 
374 
380 static void
382 {
383  struct GNUNET_HashCode hc;
384 
385  /* 2^{-5} chance of not sending a HELLO to a peer is
386  * acceptably small (if the filter is 50% full);
387  * 64 bytes of memory are small compared to the rest
388  * of the data structure and would only really become
389  * "useless" once a HELLO has been passed on to ~100
390  * other peers, which is likely more than enough in
391  * any case; hence 64, 5 as bloomfilter parameters. */peer->filter = GNUNET_CONTAINER_bloomfilter_init (NULL, 64, 5);
392  peer->filter_expiration =
394  /* never send a peer its own HELLO */
395  GNUNET_CRYPTO_hash (&peer->pid, sizeof(struct GNUNET_PeerIdentity), &hc);
396  GNUNET_CONTAINER_bloomfilter_add (peer->filter, &hc);
397 }
398 
399 
404 {
408  struct Peer *peer;
409 
413  struct Peer *result;
414 
418  size_t max_size;
419 
421 };
422 
423 
432 static int
434  const struct GNUNET_PeerIdentity *pid,
435  void *value)
436 {
437  struct FindAdvHelloContext *fah = cls;
438  struct Peer *pos = value;
439  struct GNUNET_TIME_Relative rst_time;
440  struct GNUNET_HashCode hc;
441  size_t hs;
442 
443  if (pos == fah->peer)
444  return GNUNET_YES;
445  if (pos->hello == NULL)
446  return GNUNET_YES;
448  if (0 == rst_time.rel_value_us)
449  {
450  /* time to discard... */
452  setup_filter (pos);
453  }
454  fah->next_adv = GNUNET_TIME_relative_min (rst_time, fah->next_adv);
455  hs = GNUNET_HELLO_size (pos->hello);
456  if (hs > fah->max_size)
457  return GNUNET_YES;
458  GNUNET_CRYPTO_hash (&fah->peer->pid,
459  sizeof(struct GNUNET_PeerIdentity),
460  &hc);
462  fah->result = pos;
463  return GNUNET_YES;
464 }
465 
466 
473 static void
475 {
476  struct Peer *pl = cls;
477  struct FindAdvHelloContext fah;
478  struct GNUNET_MQ_Envelope *env;
479  size_t want;
481  struct GNUNET_HashCode hc;
482 
483  pl->hello_delay_task = NULL;
484  GNUNET_assert (NULL != pl->mq);
485  /* find applicable HELLOs */
486  fah.peer = pl;
487  fah.result = NULL;
491  pl->hello_delay_task =
493  if (NULL == fah.result)
494  return;
496  if (0 != delay.rel_value_us)
497  return;
498 
499  want = GNUNET_HELLO_size (fah.result->hello);
501  "Sending HELLO with %u bytes",
502  (unsigned int) want);
504  GNUNET_MQ_send (pl->mq, env);
505 
506  /* avoid sending this one again soon */
507  GNUNET_CRYPTO_hash (&pl->pid, sizeof(struct GNUNET_PeerIdentity), &hc);
509 
511  gettext_noop ("# HELLO messages gossipped"),
512  1,
513  GNUNET_NO);
514  /* prepare to send the next one */
515  pl->next_hello_allowed =
517  if (NULL != pl->hello_delay_task)
520 }
521 
522 
533 static int
534 reschedule_hellos (void *cls,
535  const struct GNUNET_PeerIdentity *pid,
536  void *value)
537 {
538  struct Peer *peer = value;
539  struct Peer *skip = cls;
540 
541  if (skip == peer)
542  return GNUNET_YES;
543  if (NULL == peer->mq)
544  return GNUNET_YES;
545  if (NULL != peer->hello_delay_task)
546  {
547  GNUNET_SCHEDULER_cancel (peer->hello_delay_task);
548  peer->hello_delay_task = NULL;
549  }
550  peer->hello_delay_task =
552  return GNUNET_YES;
553 }
554 
555 
564 static void *
565 connect_notify (void *cls,
566  const struct GNUNET_PeerIdentity *peer,
567  struct GNUNET_MQ_Handle *mq)
568 {
569  struct Peer *pos;
570 
572  "Core told us that we are connecting to `%s'\n",
573  GNUNET_i2s (peer));
574  if (0 == GNUNET_memcmp (&my_identity, peer))
575  return NULL;
579  gettext_noop ("# peers connected"),
581  GNUNET_NO);
583  if (NULL == pos)
584  {
585  pos = make_peer (peer, NULL, GNUNET_NO);
586  }
587  else
588  {
589  GNUNET_assert (NULL == pos->mq);
590  }
591  pos->mq = mq;
592  if (pos->is_friend)
593  {
594  friend_count++;
596  whitelist_peers ();
598  gettext_noop ("# friends connected"),
599  friend_count,
600  GNUNET_NO);
601  }
602  reschedule_hellos (NULL, peer, pos);
603  return pos;
604 }
605 
606 
615 static int
616 try_add_peers (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
617 {
618  struct Peer *pos = value;
619 
620  attempt_connect (pos);
621  return GNUNET_YES;
622 }
623 
624 
630 static void
631 add_peer_task (void *cls)
632 {
633  add_task = NULL;
634 
636 }
637 
638 
646 static void
647 disconnect_notify (void *cls,
648  const struct GNUNET_PeerIdentity *peer,
649  void *internal_cls)
650 {
651  struct Peer *pos = internal_cls;
652 
653  if (NULL == pos)
654  return; /* myself, we're shutting down */
656  "Core told us that we disconnected from `%s'\n",
657  GNUNET_i2s (peer));
658  if (NULL == pos->mq)
659  {
660  GNUNET_break (0);
661  return;
662  }
663  pos->mq = NULL;
665  if (NULL != pos->hello_delay_task)
666  {
668  pos->hello_delay_task = NULL;
669  }
671  gettext_noop ("# peers connected"),
673  GNUNET_NO);
674  if (pos->is_friend)
675  {
676  friend_count--;
678  gettext_noop ("# friends connected"),
679  friend_count,
680  GNUNET_NO);
681  }
684  (NULL == add_task))
686  if ((friend_count < minimum_friend_count) && (NULL == blacklist))
688 }
689 
690 
699 static int
700 address_iterator (void *cls,
701  const struct GNUNET_HELLO_Address *address,
703 {
704  int *flag = cls;
705 
706  *flag = GNUNET_YES;
707  return GNUNET_SYSERR;
708 }
709 
710 
717 static void
719 {
720  int have_address;
721  struct GNUNET_PeerIdentity pid;
722  struct GNUNET_TIME_Absolute dt;
723  struct GNUNET_HELLO_Message *nh;
724  struct Peer *peer;
725  uint16_t size;
726 
728  {
729  GNUNET_break (0);
730  return;
731  }
732  if (0 == GNUNET_memcmp (&pid, &my_identity))
733  return; /* that's me! */
734  have_address = GNUNET_NO;
736  GNUNET_NO,
738  &have_address);
739  if (GNUNET_NO == have_address)
740  return; /* no point in advertising this one... */
742  if (NULL == peer)
743  {
745  }
746  else if (NULL != peer->hello)
747  {
749  if (dt.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
750  return; /* nothing new here */
751  }
753  "Found HELLO from peer `%s' for advertising\n",
754  GNUNET_i2s (&pid));
755  if (NULL != peer->hello)
756  {
757  nh = GNUNET_HELLO_merge (peer->hello, hello);
758  GNUNET_free (peer->hello);
759  peer->hello = nh;
760  }
761  else
762  {
764  peer->hello = GNUNET_malloc (size);
765  GNUNET_memcpy (peer->hello, hello, size);
766  }
767  if (NULL != peer->filter)
768  {
770  peer->filter = NULL;
771  }
772  setup_filter (peer);
773  /* since we have a new HELLO to pick from, re-schedule all
774  * HELLO requests that are not bound by the HELLO send rate! */
776 }
777 
778 
788 static void
789 process_peer (void *cls,
790  const struct GNUNET_PeerIdentity *peer,
791  const struct GNUNET_HELLO_Message *hello,
792  const char *err_msg)
793 {
794  struct Peer *pos;
795 
796  if (NULL != err_msg)
797  {
799  _ ("Error in communication with PEERINFO service: %s\n"),
800  err_msg);
804  return;
805  }
806  GNUNET_assert (NULL != peer);
807  if (0 == GNUNET_memcmp (&my_identity, peer))
808  return; /* that's me! */
809  if (NULL == hello)
810  {
811  /* free existing HELLO, if any */
813  if (NULL != pos)
814  {
815  GNUNET_free (pos->hello);
816  pos->hello = NULL;
817  if (NULL != pos->filter)
818  {
820  pos->filter = NULL;
821  }
822  if ((NULL == pos->mq) && (GNUNET_NO == pos->is_friend))
823  free_peer (NULL, &pos->pid, pos);
824  }
825  return;
826  }
829  if (NULL == pos)
830  pos = make_peer (peer, hello, GNUNET_NO);
831  attempt_connect (pos);
832 }
833 
834 
842 static void
843 core_init (void *cls, const struct GNUNET_PeerIdentity *my_id)
844 {
845  if (NULL == my_id)
846  {
847  GNUNET_log (
849  _ ("Failed to connect to core service, can not manage topology!\n"));
851  return;
852  }
853  my_identity = *my_id;
854  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "I am peer `%s'\n", GNUNET_i2s (my_id));
857 }
858 
859 
866 static void
867 handle_friend (void *cls, const struct GNUNET_PeerIdentity *pid)
868 {
869  unsigned int *entries_found = cls;
870  struct Peer *fl;
871 
872  if (0 == GNUNET_memcmp (pid, &my_identity))
873  {
875  _ ("Found myself `%s' in friend list (useless, ignored)\n"),
876  GNUNET_i2s (pid));
877  return;
878  }
879  (*entries_found)++;
880  fl = make_peer (pid, NULL, GNUNET_YES);
882  _ ("Found friend `%s' in configuration\n"),
883  GNUNET_i2s (&fl->pid));
884 }
885 
886 
890 static void
892 {
893  unsigned int entries_found;
894 
895  entries_found = 0;
896  if (GNUNET_OK != GNUNET_FRIENDS_parse (cfg, &handle_friend, &entries_found))
897  {
898  if ((GNUNET_YES == friends_only) || (minimum_friend_count > 0))
900  _ ("Encountered errors parsing friends list!\n"));
901  }
903  gettext_noop ("# friends in configuration"),
904  entries_found,
905  GNUNET_NO);
906  if ((minimum_friend_count > entries_found) && (GNUNET_NO == friends_only))
907  {
908  GNUNET_log (
910  _ (
911  "Fewer friends specified than required by minimum friend count. Will only connect to friends.\n"));
912  }
914  (GNUNET_NO == friends_only))
915  {
916  GNUNET_log (
918  _ (
919  "More friendly connections required than target total number of connections.\n"));
920  }
921 }
922 
923 
933 static int
934 check_hello (void *cls, const struct GNUNET_HELLO_Message *message)
935 {
936  struct GNUNET_PeerIdentity pid;
937 
938  if (GNUNET_OK != GNUNET_HELLO_get_id (message, &pid))
939  {
940  GNUNET_break_op (0);
941  return GNUNET_SYSERR;
942  }
943  return GNUNET_OK;
944 }
945 
946 
954 static void
955 handle_hello (void *cls, const struct GNUNET_HELLO_Message *message)
956 {
957  const struct GNUNET_PeerIdentity *other = cls;
958  struct Peer *peer;
959  struct GNUNET_PeerIdentity pid;
960 
962  "Received encrypted HELLO from peer `%s'",
963  GNUNET_i2s (other));
966  gettext_noop ("# HELLO messages received"),
967  1,
968  GNUNET_NO);
970  if (NULL == peer)
971  {
973  return;
974  }
975  else
976  {
977  if ((GNUNET_YES != peer->is_friend) && (GNUNET_YES == friends_only))
978  return;
979  if ((GNUNET_YES != peer->is_friend) &&
981  return;
982  }
983  (void) GNUNET_PEERINFO_add_peer (pi, message, NULL, NULL);
984 }
985 
986 
993 static void
994 cleaning_task (void *cls)
995 {
996  if (NULL != peerinfo_notify)
997  {
999  peerinfo_notify = NULL;
1000  }
1001  if (NULL != handle)
1002  {
1004  handle = NULL;
1005  }
1006  whitelist_peers ();
1007  if (NULL != add_task)
1008  {
1010  add_task = NULL;
1011  }
1012  if (NULL != oh)
1013  {
1015  oh = NULL;
1016  }
1019  peers = NULL;
1020  if (NULL != ats)
1021  {
1023  ats = NULL;
1024  }
1025  if (NULL != pi)
1026  {
1028  pi = NULL;
1029  }
1030  if (NULL != stats)
1031  {
1033  stats = NULL;
1034  }
1035 }
1036 
1037 
1046 static void
1047 run (void *cls,
1048  char *const *args,
1049  const char *cfgfile,
1050  const struct GNUNET_CONFIGURATION_Handle *c)
1051 {
1053  { GNUNET_MQ_hd_var_size (hello,
1055  struct GNUNET_HELLO_Message,
1056  NULL),
1057  GNUNET_MQ_handler_end () };
1058  unsigned long long opt;
1059 
1060  cfg = c;
1061  stats = GNUNET_STATISTICS_create ("topology", cfg);
1062  friends_only =
1063  GNUNET_CONFIGURATION_get_value_yesno (cfg, "TOPOLOGY", "FRIENDS-ONLY");
1065  "TOPOLOGY",
1066  "MINIMUM-FRIENDS",
1067  &opt))
1068  opt = 0;
1069  minimum_friend_count = (unsigned int) opt;
1070  if (GNUNET_OK !=
1072  "TOPOLOGY",
1073  "TARGET-CONNECTION-COUNT",
1074  &opt))
1075  opt = 16;
1076  target_connection_count = (unsigned int) opt;
1078  GNUNET_NO);
1081  "Topology would like %u connections with at least %u friends\n",
1084  if ((GNUNET_YES == friends_only) || (minimum_friend_count > 0))
1089  NULL,
1090  &core_init,
1091  &connect_notify,
1093  handlers);
1095  if (NULL == handle)
1096  {
1098  _ ("Failed to connect to `%s' service.\n"),
1099  "core");
1101  return;
1102  }
1103 }
1104 
1105 
1113 int
1114 main (int argc, char *const *argv)
1115 {
1116  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1118  };
1119  int ret;
1120 
1121  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1122  return 2;
1123 
1124  ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
1125  argv,
1126  "gnunet-daemon-topology",
1127  _ ("GNUnet topology control"),
1128  options,
1129  &run,
1130  NULL))
1131  ? 0
1132  : 1;
1133  GNUNET_free_nz ((void *) argv);
1134  return ret;
1135 }
1136 
1137 
1138 #if defined(__linux__) && defined(__GLIBC__)
1139 #include <malloc.h>
1140 
1144 void __attribute__ ((constructor))
1145 GNUNET_ARM_memory_init ()
1146 {
1147  mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1148  mallopt (M_TOP_PAD, 1 * 1024);
1149  malloc_trim (0);
1150 }
1151 
1152 
1153 #endif
1154 
1155 /* end of gnunet-daemon-topology.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define gettext_noop(String)
Definition: gettext.h:70
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static char * address
GNS address for this phone.
static struct GNUNET_CORE_Handle * handle
Handle to the CORE service.
static struct GNUNET_CONTAINER_MultiPeerMap * peers
All of our friends, all of our current neighbours and all peers for which we have HELLOs.
static void handle_hello(void *cls, const struct GNUNET_HELLO_Message *message)
This function is called whenever an encrypted HELLO message is received.
static struct GNUNET_ATS_ConnectivityHandle * ats
Handle to the ATS service.
static void read_friends_file(const struct GNUNET_CONFIGURATION_Handle *cfg)
Read the friends file.
static struct GNUNET_TRANSPORT_Blacklist * blacklist
Blacklist (NULL if we have none).
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 int blacklist_check(void *cls, const struct GNUNET_PeerIdentity *pid)
Function that decides if a connection is acceptable or not.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
static struct Peer * make_peer(const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello, int is_friend)
Create a new entry in the peer list.
static void whitelist_peers()
Whitelist all peers that we blacklisted; we've passed the minimum number of friends.
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 void consider_for_advertising(const struct GNUNET_HELLO_Message *hello)
We've gotten a HELLO from another peer.
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 void * connect_notify(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a peer connects.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static int friends_only
Flag to disallow non-friend connections (pure F2F mode).
static unsigned int connection_count
Number of peers (friends and others) that we are currently connected to.
static void process_peer(void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello, const char *err_msg)
PEERINFO calls this function to let us know about a possible peer that we might want to connect to.
static struct GNUNET_PEERINFO_Handle * pi
Handle to the PEERINFO service.
static struct GNUNET_PEERINFO_NotifyContext * peerinfo_notify
Our peerinfo notification context.
static unsigned int friend_count
Number of friends that we are currently connected 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 int address_iterator(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Iterator called on each address.
#define HELLO_ADVERTISEMENT_MIN_REPEAT_FREQUENCY
After what time period do we expire the HELLO Bloom filter?
static struct GNUNET_TRANSPORT_OfferHelloHandle * oh
Active HELLO offering to transport service.
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...
#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.
static int free_peer(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Free all resources associated with the given peer.
int main(int argc, char *const *argv)
The main function for the topology daemon.
static int check_hello(void *cls, const struct GNUNET_HELLO_Message *message)
This function is called whenever an encrypted HELLO message is received.
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 void handle_friend(void *cls, const struct GNUNET_PeerIdentity *pid)
Process friend found in FRIENDS file.
static int find_advertisable_hello(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Find a peer that would be reasonable for advertising.
static int try_add_peers(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Try to add more peers to our connection set.
static unsigned int minimum_friend_count
Minimum number of friends to have in the connection set before we allow non-friends.
static char * value
Value of the record to add/remove.
static struct GNUNET_NAT_Handle * nh
Handle to NAT operation.
Definition: gnunet-nat.c:80
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
Automatic transport selection and outbound bandwidth determination.
Core service; the main API for encrypted P2P communications.
Library to read and write the FRIENDS file.
Maintain the list of currently known hosts.
Constants for network protocols.
API to create, modify and access statistics.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
struct GNUNET_ATS_ConnectivityHandle * GNUNET_ATS_connectivity_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the ATS connectivity suggestion client handle.
struct GNUNET_ATS_ConnectivitySuggestHandle * GNUNET_ATS_connectivity_suggest(struct GNUNET_ATS_ConnectivityHandle *ch, const struct GNUNET_PeerIdentity *peer, uint32_t strength)
We would like to receive address suggestions for a peer.
void GNUNET_ATS_connectivity_done(struct GNUNET_ATS_ConnectivityHandle *ch)
Client is done with ATS connectivity management, release resources.
void GNUNET_ATS_connectivity_suggest_cancel(struct GNUNET_ATS_ConnectivitySuggestHandle *sh)
We no longer care about being connected to a peer.
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.
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_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.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
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)
Connect to the core service.
Definition: core_api.c:691
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition: core_api.c:729
int GNUNET_FRIENDS_parse(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_FRIENDS_Callback cb, void *cb_cls)
Parse the FRIENDS file.
Definition: friends.c:39
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
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).
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.
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...
int GNUNET_HELLO_get_id(const struct GNUNET_HELLO_Message *hello, struct GNUNET_PeerIdentity *peer)
Get the peer identity from a HELLO message.
Definition: hello.c:649
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:630
struct GNUNET_HELLO_Message * GNUNET_HELLO_merge(const struct GNUNET_HELLO_Message *h1, const struct GNUNET_HELLO_Message *h2)
Construct a HELLO message by merging the addresses in two existing HELLOs (which must be for the same...
Definition: hello.c:515
struct GNUNET_TIME_Absolute GNUNET_HELLO_equals(const struct GNUNET_HELLO_Message *h1, const struct GNUNET_HELLO_Message *h2, struct GNUNET_TIME_Absolute now)
Test if two HELLO messages contain the same addresses.
Definition: hello.c:812
struct GNUNET_HELLO_Message * GNUNET_HELLO_iterate_addresses(const struct GNUNET_HELLO_Message *msg, int return_modified, GNUNET_HELLO_AddressIterator it, void *it_cls)
Iterate over all of the addresses in the HELLO.
Definition: hello.c:254
#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.
@ 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_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#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.
#define GNUNET_free_nz(ptr)
Wrapper around free.
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:871
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:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
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:533
@ GNUNET_MQ_PRIO_BEST_EFFORT
Best-effort traffic (e.g.
struct GNUNET_MQ_Envelope * GNUNET_PEERINFO_add_peer(struct GNUNET_PEERINFO_Handle *h, const struct GNUNET_HELLO_Message *hello, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Add a host to the persistent list.
Definition: peerinfo_api.c:530
struct GNUNET_PEERINFO_NotifyContext * GNUNET_PEERINFO_notify(const struct GNUNET_CONFIGURATION_Handle *cfg, int include_friend_only, GNUNET_PEERINFO_Processor callback, void *callback_cls)
Call a method whenever our known information about peers changes.
struct GNUNET_PEERINFO_Handle * GNUNET_PEERINFO_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the peerinfo service.
Definition: peerinfo_api.c:123
void GNUNET_PEERINFO_notify_cancel(struct GNUNET_PEERINFO_NotifyContext *nc)
Stop notifying about changes.
void GNUNET_PEERINFO_disconnect(struct GNUNET_PEERINFO_Handle *h)
Disconnect from the peerinfo service.
Definition: peerinfo_api.c:149
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(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:400
#define GNUNET_MESSAGE_TYPE_HELLO
HELLO message with friend only flag used for communicating peer addresses.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:562
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:1299
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:1334
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
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:1272
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).
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1222
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:343
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
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:405
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_UNIT_FOREVER_ABS
Constant used to specify "forever".
void GNUNET_TRANSPORT_offer_hello_cancel(struct GNUNET_TRANSPORT_OfferHelloHandle *ohh)
Cancel the request to transport to offer the HELLO message.
struct GNUNET_TRANSPORT_Blacklist * GNUNET_TRANSPORT_blacklist(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_TRANSPORT_BlacklistCallback cb, void *cb_cls)
Install a blacklist callback.
void GNUNET_TRANSPORT_blacklist_cancel(struct GNUNET_TRANSPORT_Blacklist *br)
Abort the blacklist.
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
enum array_types __attribute__
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).
Handle to the ATS subsystem for connectivity management.
Handle for ATS address suggestion requests.
Internal representation of the hash map.
Context for the core service connection.
Definition: core_api.c:78
Definition of a command line option.
An address for communicating with a peer.
A HELLO message is used to exchange information about transports with other peers.
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_HELLO.
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
Handle to the peerinfo service.
Definition: peerinfo_api.c:85
Context for the info handler.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:136
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Handle for blacklisting requests.
Entry in linked list for all offer-HELLO requests.
struct GNUNET_PeerIdentity pid
Which peer is this entry about?
struct GNUNET_TIME_Absolute next_hello_allowed
Next time we are allowed to transmit a HELLO to this peer?
int is_friend
Is this peer listed here because it is a friend?
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?
uint32_t strength
How much would we like to connect to this peer?
struct GNUNET_HELLO_Message * hello
Pointer to the HELLO message of this peer; can be NULL.
struct GNUNET_ATS_ConnectivitySuggestHandle * sh
Handle for our connectivity suggestion for this peer.
struct GNUNET_MQ_Handle * mq
Our handle for transmitting to this peer; NULL if peer is not connected.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.