GNUnet  0.11.x
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 {
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 
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 
224  pos = GNUNET_CONTAINER_multipeermap_get (peers, pid);
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);
265  GNUNET_CONTAINER_multipeermap_remove (peers, pid, pos));
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  {
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);
337  pos->sh = GNUNET_ATS_connectivity_suggest (ats, &pos->pid, strength);
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  {
362  ret->hello = GNUNET_malloc (GNUNET_HELLO_size (hello));
363  GNUNET_memcpy (ret->hello, hello, GNUNET_HELLO_size (hello));
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);
397 }
398 
399 
404 {
408  struct Peer *peer;
409 
413  struct Peer *result;
414 
418  size_t max_size;
419 
420  struct GNUNET_TIME_Relative next_adv;
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;
480  struct GNUNET_TIME_Relative delay;
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);
503  env = GNUNET_MQ_msg_copy (&fah.result->hello->header);
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  {
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;
578  GNUNET_STATISTICS_set (stats,
579  gettext_noop ("# peers connected"),
581  GNUNET_NO);
582  pos = GNUNET_CONTAINER_multipeermap_get (peers, peer);
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 ();
597  GNUNET_STATISTICS_set (stats,
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  }
670  GNUNET_STATISTICS_set (stats,
671  gettext_noop ("# peers connected"),
673  GNUNET_NO);
674  if (pos->is_friend)
675  {
676  friend_count--;
677  GNUNET_STATISTICS_set (stats,
678  gettext_noop ("# friends connected"),
679  friend_count,
680  GNUNET_NO);
681  }
684  (NULL == add_task))
685  add_task = GNUNET_SCHEDULER_add_now (&add_peer_task, NULL);
686  if ((friend_count < minimum_friend_count) && (NULL == blacklist))
687  blacklist = GNUNET_TRANSPORT_blacklist (cfg, &blacklist_check, NULL);
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 
727  if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid))
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... */
741  peer = GNUNET_CONTAINER_multipeermap_get (peers, &pid);
742  if (NULL == peer)
743  {
744  peer = make_peer (&pid, hello, GNUNET_NO);
745  }
746  else if (NULL != peer->hello)
747  {
748  dt = GNUNET_HELLO_equals (peer->hello, hello, GNUNET_TIME_absolute_get ());
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  {
763  size = GNUNET_HELLO_size (hello);
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);
801  GNUNET_PEERINFO_notify_cancel (peerinfo_notify);
802  peerinfo_notify =
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 */
812  pos = GNUNET_CONTAINER_multipeermap_get (peers, peer);
813  if (NULL != pos)
814  {
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  }
827  consider_for_advertising (hello);
828  pos = GNUNET_CONTAINER_multipeermap_get (peers, peer);
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));
855  peerinfo_notify =
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));
964  GNUNET_assert (GNUNET_OK == GNUNET_HELLO_get_id (message, &pid));
966  gettext_noop ("# HELLO messages received"),
967  1,
968  GNUNET_NO);
969  peer = GNUNET_CONTAINER_multipeermap_get (peers, &pid);
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  {
998  GNUNET_PEERINFO_notify_cancel (peerinfo_notify);
999  peerinfo_notify = NULL;
1000  }
1001  if (NULL != handle)
1002  {
1003  GNUNET_CORE_disconnect (handle);
1004  handle = NULL;
1005  }
1006  whitelist_peers ();
1007  if (NULL != add_task)
1008  {
1009  GNUNET_SCHEDULER_cancel (add_task);
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 {
1052  struct GNUNET_MQ_MessageHandler handlers[] =
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);
1079  read_friends_file (cfg);
1081  "Topology would like %u connections with at least %u friends\n",
1084  if ((GNUNET_YES == friends_only) || (minimum_friend_count > 0))
1085  blacklist = GNUNET_TRANSPORT_blacklist (cfg, &blacklist_check, NULL);
1086  ats = GNUNET_ATS_connectivity_init (cfg);
1087  pi = GNUNET_PEERINFO_connect (cfg);
1088  handle = GNUNET_CORE_connect (cfg,
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 ((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_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
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:671
static int friends_only
Flag to disallow non-friend connections (pure F2F mode).
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:653
Handle to the peerinfo service.
Definition: peerinfo_api.c:84
A HELLO message is used to exchange information about transports with other peers.
Entry in linked list for all offer-HELLO requests.
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to the filter.
int 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.
uint64_t rel_value_us
The actual value.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
Context for the core service connection.
Definition: core_api.c:77
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:524
uint32_t strength
How much would we like to connect to this peer?
static struct GNUNET_SCHEDULER_Task * add_task
Task scheduled to asynchronously reconsider adding/removing peer connectivity suggestions.
struct GNUNET_PEERINFO_Handle * GNUNET_PEERINFO_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the peerinfo service.
Definition: peerinfo_api.c:130
Context for the info handler.
static int blacklist_check(void *cls, const struct GNUNET_PeerIdentity *pid)
Function that decides if a connection is acceptable or not.
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
#define HELLO_ADVERTISEMENT_MIN_FREQUENCY
At what frequency do we sent HELLOs to a peer?
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1438
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:246
static void whitelist_peers()
Whitelist all peers that we blacklisted; we&#39;ve passed the minimum number of friends.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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_PEERINFO_notify_cancel(struct GNUNET_PEERINFO_NotifyContext *nc)
Stop notifying about changes.
static void schedule_next_hello(void *cls)
Calculate when we would like to send the next HELLO to this peer and ask for it.
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:834
static struct GNUNET_TRANSPORT_Blacklist * blacklist
Blacklist (NULL if we have none).
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
int 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.
static int try_add_peers(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Try to add more peers to our connection set.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
void GNUNET_ATS_connectivity_suggest_cancel(struct GNUNET_ATS_ConnectivitySuggestHandle *sh)
We no longer care about being connected to a peer.
void GNUNET_TRANSPORT_blacklist_cancel(struct GNUNET_TRANSPORT_Blacklist *br)
Abort the blacklist.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
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_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
Handle for the service.
uint64_t abs_value_us
The actual value.
static void setup_filter(struct Peer *peer)
Setup bloom filter for the given peer entry.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static void read_friends_file(const struct GNUNET_CONFIGURATION_Handle *cfg)
Read the friends file.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
int main(int argc, char *const *argv)
The main function for the topology daemon.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
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_ATS_ConnectivitySuggestHandle * sh
Handle for our connectivity suggestion for this peer.
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
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.
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.
Best-effort traffic (i.e.
static unsigned int target_connection_count
Target number of connections.
static struct GNUNET_ATS_ConnectivityHandle * ats
Handle to the ATS 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...
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:1253
static struct GNUNET_STATISTICS_Handle * stats
Handle for reporting statistics.
static char * value
Value of the record to add/remove.
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
static struct GNUNET_TRANSPORT_OfferHelloHandle * oh
Active HELLO offering to transport service.
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_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
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:1280
struct GNUNET_TRANSPORT_Blacklist * GNUNET_TRANSPORT_blacklist(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_TRANSPORT_BlacklistCallback cb, void *cb_cls)
Install a blacklist callback.
struct GNUNET_CONFIGURATION_Handle * cfg
The modified (by GNUNET_TESTING_peer_configure) configuration this peer is configured with...
struct Peer * peer
Peer we want to advertise to.
Handle for ATS address suggestion requests.
static void core_init(void *cls, const struct GNUNET_PeerIdentity *my_id)
Function called after GNUNET_CORE_connect has succeeded (or failed for good).
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TESTING_Peer * peer
The peer handle from testing API.
Internal representation of the hash map.
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 consider_for_advertising(const struct GNUNET_HELLO_Message *hello)
We&#39;ve gotten a HELLO from another peer.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
A 512-bit hashcode.
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:553
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
Message handler for a specific message type.
static struct GNUNET_NAT_Handle * nh
Handle to NAT operation.
Definition: gnunet-nat.c:80
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
void GNUNET_TRANSPORT_offer_hello_cancel(struct GNUNET_TRANSPORT_OfferHelloHandle *ohh)
Cancel the request to transport to offer the HELLO message.
static int address_iterator(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Iterator called on each address.
static struct GNUNET_PEERINFO_Handle * pi
Handle to the PEERINFO service.
Handle for blacklisting requests.
static void add_peer_task(void *cls)
Add peers and schedule connection attempt.
static void handle_hello(void *cls, const struct GNUNET_HELLO_Message *message)
This function is called whenever an encrypted HELLO message is received.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
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:272
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:67
struct GNUNET_TIME_Relative next_adv
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:692
int is_friend
Is this peer listed here because it is a friend?
struct GNUNET_TIME_Absolute next_hello_allowed
Next time we are allowed to transmit a HELLO to this peer?
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition: core_api.c:730
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
struct GNUNET_PeerIdentity pid
Which peer is this entry about?
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 int find_advertisable_hello(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Find a peer that would be reasonable for advertising.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
Handle to a message queue.
Definition: mq.c:85
static int check_hello(void *cls, const struct GNUNET_HELLO_Message *message)
This function is called whenever an encrypted HELLO message is received.
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.
struct GNUNET_ATS_ConnectivityHandle * GNUNET_ATS_connectivity_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the ATS connectivity suggestion client handle.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
static unsigned int connection_count
Number of peers (friends and others) that we are currently connected to.
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:1066
enum RadiotapType __attribute__
The identity of the host (wraps the signing key of the peer).
struct GNUNET_MQ_Handle * mq
Our handle for transmitting to this peer; NULL if peer is not connected.
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_HELLO.
configuration data
Definition: configuration.c:85
An address for communicating with a peer.
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.
Automatic transport selection and outbound bandwidth determination.
#define GNUNET_log(kind,...)
static struct GNUNET_PEERINFO_NotifyContext * peerinfo_notify
Our peerinfo notification context.
static void * connect_notify(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a peer connects.
Entry in list of pending tasks.
Definition: scheduler.c:134
size_t max_size
Maximum HELLO size we can use right now.
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:652
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run.
void GNUNET_PEERINFO_disconnect(struct GNUNET_PEERINFO_Handle *h)
Disconnect from the peerinfo service.
Definition: peerinfo_api.c:156
struct GNUNET_HELLO_Message * hello
Pointer to the HELLO message of this peer; can be NULL.
int 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, parse options).
Definition: program.c:367
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:331
struct GNUNET_CONTAINER_BloomFilter * filter
Bloom filter used to mark which peers already got the HELLO from this peer.
static struct GNUNET_CORE_Handle * handle
Handle to the CORE service.
#define HELLO_ADVERTISEMENT_MIN_REPEAT_FREQUENCY
After what time period do we expire the HELLO Bloom filter?
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
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.
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:353
struct GNUNET_TIME_Absolute filter_expiration
When should we reset the bloom filter of this entry?
Closure for find_advertisable_hello().
static void handle_friend(void *cls, const struct GNUNET_PeerIdentity *pid)
Process friend found in FRIENDS file.
#define GNUNET_MESSAGE_TYPE_HELLO
HELLO message with friend only flag used for communicating peer addresses.
static struct GNUNET_CONTAINER_MultiPeerMap * peers
All of our friends, all of our current neighbours and all peers for which we have HELLOs...
int 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".
Handle to the ATS subsystem for connectivity management.
void GNUNET_ATS_connectivity_done(struct GNUNET_ATS_ConnectivityHandle *ch)
Client is done with ATS connectivity management, release resources.
static char * address
GNS address for this phone.
static int free_peer(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Free all resources associated with the given peer.
static unsigned int minimum_friend_count
Minimum number of friends to have in the connection set before we allow non-friends.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associcated with a filter in memory, flush to drive if needed (do not free the space o...
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
struct Peer * result
Where to store the result (peer selected for advertising).
#define GNUNET_malloc(size)
Wrapper around malloc.
static void cleaning_task(void *cls)
Last task run during shutdown.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
#define gettext_noop(String)
Definition: gettext.h:69
static unsigned int friend_count
Number of friends that we are currently connected to.
static void disconnect_notify(void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
Method called whenever a peer disconnects.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966