GNUnet  0.10.x
gnunet-service-peerinfo.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001-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 
31 #include "platform.h"
32 #include "gnunet_util_lib.h"
33 #include "gnunet_hello_lib.h"
34 #include "gnunet_protocols.h"
36 #include "peerinfo.h"
37 
41 #define DATA_HOST_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
42 
46 #define DATA_HOST_CLEAN_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 60)
47 
48 
52 struct HostEntry
53 {
54 
59 
64 
69 
70 };
71 
72 
77 {
82 
87 };
88 
89 
95 
100 
106 
110 static char *networkIdDirectory;
111 
116 
121 
126 
127 
136 static struct InfoMessage *
137 make_info_message (const struct HostEntry *he,
139 {
140  struct InfoMessage *im;
141  struct GNUNET_HELLO_Message *src;
142  size_t hs;
143 
144  if (GNUNET_YES == include_friend_only)
145  src = he->friend_only_hello;
146  else
147  src = he->hello;
148  hs = (NULL == src) ? 0 : GNUNET_HELLO_size (src);
149  im = GNUNET_malloc (sizeof (struct InfoMessage) + hs);
150  im->header.size = htons (hs + sizeof (struct InfoMessage));
152  im->peer = he->identity;
153  GNUNET_memcpy (&im[1],
154  src,
155  hs);
156  return im;
157 }
158 
159 
168 static int
169 discard_expired (void *cls,
170  const struct GNUNET_HELLO_Address *address,
172 {
173  const struct GNUNET_TIME_Absolute *now = cls;
174 
175  if (now->abs_value_us > expiration.abs_value_us)
176  {
178  _("Removing expired address of transport `%s'\n"),
179  address->transport_name);
180  return GNUNET_NO;
181  }
182  return GNUNET_OK;
183 }
184 
185 
194 static int
195 count_addresses (void *cls,
196  const struct GNUNET_HELLO_Address *address,
198 {
199  unsigned int *cnt = cls;
200 
201  (void) address;
202  (void) expiration;
203  (*cnt)++;
204  return GNUNET_OK;
205 }
206 
207 
215 static char *
217 {
218  char *fn;
219 
220  if (NULL == networkIdDirectory)
221  return NULL;
222  GNUNET_asprintf (&fn,
223  "%s%s%s",
226  GNUNET_i2s_full (id));
227  return fn;
228 }
229 
230 
237 static void
238 notify_all (struct HostEntry *entry)
239 {
240  struct InfoMessage *msg_pub;
241  struct InfoMessage *msg_friend;
242 
244  "Notifying all clients about peer `%s'\n",
245  GNUNET_i2s(&entry->identity));
246  msg_pub = make_info_message (entry,
247  GNUNET_NO);
249  &msg_pub->header,
250  GNUNET_NO);
251  GNUNET_free (msg_pub);
252  msg_friend = make_info_message (entry,
253  GNUNET_YES);
254  GNUNET_notification_context_broadcast (notify_friend_only_list,
255  &msg_friend->header,
256  GNUNET_NO);
257  GNUNET_free (msg_friend);
258 }
259 
260 
267 static void
268 update_hello (const struct GNUNET_PeerIdentity *peer,
269  const struct GNUNET_HELLO_Message *hello);
270 
271 
283 static void
284 read_host_file (const char *fn,
285  int unlink_garbage,
286  struct ReadHostFileContext *r)
287 {
288  char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
289  ssize_t size_total;
290  struct GNUNET_TIME_Absolute now;
291  unsigned int left;
292  const struct GNUNET_HELLO_Message *hello;
293  struct GNUNET_HELLO_Message *hello_clean;
294  size_t read_pos;
295  uint16_t size_hello;
296 
297  r->friend_only_hello = NULL;
298  r->hello = NULL;
299 
300  if (GNUNET_YES != GNUNET_DISK_file_test (fn))
301  return;
302  size_total = GNUNET_DISK_fn_read (fn,
303  buffer,
304  sizeof (buffer));
306  "Read %d bytes from `%s'\n",
307  (int) size_total,
308  fn);
309  if ( (size_total < 0) ||
310  (((size_t) size_total) < sizeof (struct GNUNET_MessageHeader)) )
311  {
313  _("Failed to parse HELLO in file `%s': %s\n"),
314  fn,
315  "File has invalid size");
316  if ( (GNUNET_YES == unlink_garbage) &&
317  (0 != UNLINK (fn)) &&
318  (ENOENT != errno) )
320  "unlink",
321  fn);
322  return;
323  }
324 
325  read_pos = 0;
326  while (read_pos < (size_t) size_total)
327  {
328  hello = (const struct GNUNET_HELLO_Message *) &buffer[read_pos];
329  size_hello = GNUNET_HELLO_size (hello);
330  if ( (0 == size_hello) ||
331  (((size_t) size_total) - read_pos < size_hello) )
332  {
334  _("Failed to parse HELLO in file `%s'\n"),
335  fn);
336  if (0 == read_pos)
337  {
338  if ((GNUNET_YES == unlink_garbage) &&
339  (0 != UNLINK (fn)) &&
340  (ENOENT != errno) )
342  "unlink",
343  fn);
344  }
345  else
346  {
347  if ( (GNUNET_YES == unlink_garbage) &&
348  (0 != TRUNCATE (fn, read_pos)) &&
349  (ENOENT != errno) )
351  "truncate",
352  fn);
353  }
354  return;
355  }
356 
357  now = GNUNET_TIME_absolute_get ();
358  hello_clean = GNUNET_HELLO_iterate_addresses (hello,
359  GNUNET_YES,
361  &now);
362  if (NULL == hello_clean)
363  {
365  _("Failed to parse HELLO in file `%s'\n"),
366  fn);
367  if ((GNUNET_YES == unlink_garbage) &&
368  (0 != UNLINK (fn)) &&
369  (ENOENT != errno) )
371  "unlink",
372  fn);
373  return;
374  }
375  left = 0;
376  (void) GNUNET_HELLO_iterate_addresses (hello_clean,
377  GNUNET_NO,
379  &left);
380 
381  if (0 == left)
382  {
383  GNUNET_free (hello_clean);
384  break;
385  }
386 
387  if (GNUNET_NO == GNUNET_HELLO_is_friend_only (hello_clean))
388  {
389  if (NULL == r->hello)
390  r->hello = hello_clean;
391  else
392  {
393  GNUNET_break (0);
394  GNUNET_free (r->hello);
395  r->hello = hello_clean;
396  }
397  }
398  else
399  {
400  if (NULL == r->friend_only_hello)
401  r->friend_only_hello = hello_clean;
402  else
403  {
404  GNUNET_break (0);
406  r->friend_only_hello = hello_clean;
407  }
408  }
409  read_pos += size_hello;
410  }
411 
412  if (0 == left)
413  {
414  /* no addresses left, remove from disk */
415  if ( (GNUNET_YES == unlink_garbage) &&
416  (0 != UNLINK (fn)) )
418  "unlink",
419  fn);
420  }
422  "Found `%s' and `%s' HELLO message in file\n",
423  (NULL != r->hello) ? "public" : "NON-public",
424  (NULL != r->friend_only_hello) ? "friend only" : "NO friend only");
425 }
426 
427 
434 static struct HostEntry *
436 {
437  struct HostEntry *entry;
438  struct ReadHostFileContext r;
439  char *fn;
440 
441  entry = GNUNET_CONTAINER_multipeermap_get (hostmap,
442  identity);
443  if (NULL == entry)
444  {
446  "Adding new peer `%s'\n",
447  GNUNET_i2s (identity));
449  gettext_noop ("# peers known"),
450  1,
451  GNUNET_NO);
452  entry = GNUNET_new (struct HostEntry);
453  entry->identity = *identity;
456  &entry->identity,
457  entry,
459  notify_all (entry);
460  fn = get_host_filename (identity);
461  if (NULL != fn)
462  {
463  read_host_file (fn,
464  GNUNET_YES,
465  &r);
466  if (NULL != r.hello)
467  update_hello (identity,
468  r.hello);
469  if (NULL != r.friend_only_hello)
470  update_hello (identity,
474  GNUNET_free (fn);
475  }
476  }
477  return entry;
478 }
479 
480 
487 static void
488 remove_garbage (const char *fullname)
489 {
490  if (0 == UNLINK (fullname))
492  _("File `%s' in directory `%s' does not match naming convention. Removed.\n"),
493  fullname,
495  else
497  "unlink",
498  fullname);
499 }
500 
501 
506 {
513 
518  unsigned int matched;
519 };
520 
521 
531 static int
533  const char *fullname)
534 {
535  struct DirScanContext *dsc = cls;
536  struct GNUNET_PeerIdentity identity;
537  struct ReadHostFileContext r;
538  const char *filename;
539  struct GNUNET_PeerIdentity id_public;
540  struct GNUNET_PeerIdentity id_friend;
541  struct GNUNET_PeerIdentity id;
542 
543  if (GNUNET_YES != GNUNET_DISK_file_test (fullname))
544  return GNUNET_OK; /* ignore non-files */
545 
546  filename = strrchr (fullname,
547  DIR_SEPARATOR);
548  if ( (NULL == filename) ||
549  (1 > strlen (filename)) )
550  filename = fullname;
551  else
552  filename ++;
553 
554  read_host_file (fullname,
555  dsc->remove_files,
556  &r);
557  if ( (NULL == r.hello) &&
558  (NULL == r.friend_only_hello))
559  return GNUNET_OK;
560  if (NULL != r.friend_only_hello)
561  {
562  if (GNUNET_OK !=
564  &id_friend))
565  {
566  if (GNUNET_YES == dsc->remove_files)
567  remove_garbage (fullname);
568  return GNUNET_OK;
569  }
570  id = id_friend;
571  }
572  if (NULL != r.hello)
573  {
574  if (GNUNET_OK !=
576  &id_public))
577  {
578  if (GNUNET_YES == dsc->remove_files)
579  remove_garbage (fullname);
580  return GNUNET_OK;
581  }
582  id = id_public;
583  }
584 
585  if ( (NULL != r.hello) &&
586  (NULL != r.friend_only_hello) &&
587  (0 != GNUNET_memcmp (&id_friend,
588  &id_public)) )
589  {
590  /* HELLOs are not for the same peer */
591  GNUNET_break (0);
592  if (GNUNET_YES == dsc->remove_files)
593  remove_garbage (fullname);
594  return GNUNET_OK;
595  }
596  if (GNUNET_OK ==
598  strlen (filename),
599  &identity.public_key))
600  {
601  if (0 != GNUNET_memcmp (&id, &identity))
602  {
603  /* HELLOs are not for the same peer */
604  GNUNET_break (0);
605  if (GNUNET_YES == dsc->remove_files)
606  remove_garbage (fullname);
607  return GNUNET_OK;
608  }
609  }
610 
611  /* ok, found something valid, remember HELLO */
613  if (NULL != r.hello)
614  {
616  "Updating peer `%s' public HELLO \n",
617  GNUNET_i2s (&id));
618  update_hello (&id, r.hello);
619  GNUNET_free (r.hello);
620  }
621  if (NULL != r.friend_only_hello)
622  {
624  "Updating peer `%s' friend only HELLO \n",
625  GNUNET_i2s (&id));
628  }
629  dsc->matched++;
630  return GNUNET_OK;
631 }
632 
633 
639 static void
641 {
642  static unsigned int retries;
643  struct DirScanContext dsc;
644 
645  (void) cls;
646  cron_scan = NULL;
647  if (GNUNET_SYSERR ==
649  {
653  return;
654  }
655  dsc.matched = 0;
656  dsc.remove_files = GNUNET_YES;
658  _("Scanning directory `%s'\n"),
662  &dsc);
663  if ( (0 == dsc.matched) &&
664  (0 == (++retries & 31)) )
666  _("Still no peers found in `%s'!\n"),
671  NULL);
672 }
673 
674 
682 static struct GNUNET_HELLO_Message *
684  const struct GNUNET_HELLO_Message *friend_hello)
685 {
686  struct GNUNET_HELLO_Message * res;
687  struct GNUNET_HELLO_Message * tmp;
688  struct GNUNET_PeerIdentity pid;
689 
690  if (NULL != friend_hello)
691  {
692  res = GNUNET_HELLO_merge (hello,
693  friend_hello);
696  return res;
697  }
698 
699  if (GNUNET_OK !=
700  GNUNET_HELLO_get_id (hello, &pid))
701  {
702  GNUNET_break (0);
703  return NULL;
704  }
705  tmp = GNUNET_HELLO_create (&pid.public_key,
706  NULL,
707  NULL,
708  GNUNET_YES);
709  res = GNUNET_HELLO_merge (hello, tmp);
710  GNUNET_free (tmp);
712  return res;
713 }
714 
715 
722 static void
723 update_hello (const struct GNUNET_PeerIdentity *peer,
724  const struct GNUNET_HELLO_Message *hello)
725 {
726  char *fn;
727  struct HostEntry *host;
728  struct GNUNET_HELLO_Message *mrg;
729  struct GNUNET_HELLO_Message **dest;
730  struct GNUNET_TIME_Absolute delta;
731  unsigned int cnt;
732  unsigned int size;
733  int friend_hello_type;
734  int store_hello;
735  int store_friend_hello;
736  unsigned int pos;
737  char *buffer;
738 
739  host = GNUNET_CONTAINER_multipeermap_get (hostmap, peer);
740  GNUNET_assert (NULL != host);
741 
742  friend_hello_type = GNUNET_HELLO_is_friend_only (hello);
744  "Updating %s HELLO for `%s'\n",
745  (GNUNET_YES == friend_hello_type) ? "friend-only" : "public",
746  GNUNET_i2s (peer));
747 
748  dest = NULL;
749  if (GNUNET_YES == friend_hello_type)
750  {
751  dest = &host->friend_only_hello;
752  }
753  else
754  {
755  dest = &host->hello;
756  }
757 
758  if (NULL == (*dest))
759  {
760  (*dest) = GNUNET_malloc (GNUNET_HELLO_size (hello));
761  GNUNET_memcpy ((*dest), hello, GNUNET_HELLO_size (hello));
762  }
763  else
764  {
765  mrg = GNUNET_HELLO_merge ((*dest),
766  hello);
767  delta = GNUNET_HELLO_equals (mrg,
768  (*dest),
770  if (delta.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
771  {
772  /* no differences, just ignore the update */
774  "No change in %s HELLO for `%s'\n",
775  (GNUNET_YES == friend_hello_type) ? "friend-only" : "public",
776  GNUNET_i2s (peer));
777  GNUNET_free (mrg);
778  return;
779  }
780  GNUNET_free ((*dest));
781  (*dest) = mrg;
782  }
783 
784  if ( (NULL != (host->hello)) &&
785  (GNUNET_NO == friend_hello_type) )
786  {
787  /* Update friend only hello */
788  mrg = update_friend_hello (host->hello,
789  host->friend_only_hello);
790  if (NULL != host->friend_only_hello)
792  host->friend_only_hello = mrg;
793  }
794 
795  if (NULL != host->hello)
798  if (NULL != host->friend_only_hello)
801 
802  fn = get_host_filename (peer);
803  if ( (NULL != fn) &&
804  (GNUNET_OK ==
806  {
807  store_hello = GNUNET_NO;
808  size = 0;
809  cnt = 0;
810  if (NULL != host->hello)
812  GNUNET_NO,
814  &cnt);
815  if (cnt > 0)
816  {
817  store_hello = GNUNET_YES;
818  size += GNUNET_HELLO_size (host->hello);
819  }
820  cnt = 0;
821  if (NULL != host->friend_only_hello)
823  GNUNET_NO,
825  &cnt);
826  store_friend_hello = GNUNET_NO;
827  if (0 < cnt)
828  {
829  store_friend_hello = GNUNET_YES;
830  size += GNUNET_HELLO_size (host->friend_only_hello);
831  }
832 
833  if ( (GNUNET_NO == store_hello) &&
834  (GNUNET_NO == store_friend_hello) )
835  {
836  /* no valid addresses, don't put HELLO on disk; in fact,
837  if one exists on disk, remove it */
838  (void) UNLINK (fn);
839  }
840  else
841  {
842  buffer = GNUNET_malloc (size);
843  pos = 0;
844 
845  if (GNUNET_YES == store_hello)
846  {
847  GNUNET_memcpy (buffer,
848  host->hello,
849  GNUNET_HELLO_size (host->hello));
850  pos += GNUNET_HELLO_size (host->hello);
851  }
852  if (GNUNET_YES == store_friend_hello)
853  {
854  GNUNET_memcpy (&buffer[pos],
855  host->friend_only_hello,
857  pos += GNUNET_HELLO_size (host->friend_only_hello);
858  }
859  GNUNET_assert (pos == size);
860 
861  if (GNUNET_SYSERR == GNUNET_DISK_fn_write (fn, buffer, size,
867  else
869  "Stored %s %s HELLO in %s with total size %u\n",
870  (GNUNET_YES == store_friend_hello) ? "friend-only": "",
871  (GNUNET_YES == store_hello) ? "public": "",
872  fn,
873  size);
874  GNUNET_free (buffer);
875  }
876  }
878  notify_all (host);
879 }
880 
881 
886 {
891 
896 };
897 
898 
907 static int
908 add_to_tc (void *cls,
909  const struct GNUNET_PeerIdentity *key,
910  void *value)
911 {
912  struct TransmitContext *tc = cls;
913  struct HostEntry *pos = value;
914  struct InfoMessage *im;
915  uint16_t hs;
916  struct GNUNET_MQ_Envelope *env;
917 
918  hs = 0;
919 
920  if ( (NULL != pos->hello) &&
921  (GNUNET_NO == tc->friend_only) )
922  {
923  /* Copy public HELLO */
924  hs = GNUNET_HELLO_size (pos->hello);
926  sizeof (struct InfoMessage));
927  env = GNUNET_MQ_msg_extra (im,
928  hs,
930  GNUNET_memcpy (&im[1],
931  pos->hello,
932  hs);
934  "Sending public HELLO with size %u for peer `%s'\n",
935  hs,
936  GNUNET_i2s (key));
937  }
938  else if ( (NULL != pos->friend_only_hello) &&
939  (GNUNET_YES == tc->friend_only) )
940  {
941  /* Copy friend only HELLO */
944  sizeof (struct InfoMessage));
945  env = GNUNET_MQ_msg_extra (im,
946  hs,
948  GNUNET_memcpy (&im[1],
949  pos->friend_only_hello,
950  hs);
952  "Sending friend-only HELLO with size %u for peer `%s'\n",
953  hs,
954  GNUNET_i2s (key));
955  }
956  else
957  {
958  env = GNUNET_MQ_msg (im,
961  "Adding no HELLO for peer `%s'\n",
962  GNUNET_i2s (key));
963  }
964  im->peer = pos->identity;
966  env);
967  return GNUNET_YES;
968 }
969 
970 
978 static int
980  const char *fn)
981 {
982  struct GNUNET_TIME_Absolute *now = cls;
983  char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
984  const struct GNUNET_HELLO_Message *hello;
985  struct GNUNET_HELLO_Message *new_hello;
986  int read_size;
987  unsigned int cur_hello_size;
988  unsigned int new_hello_size;
989  int read_pos;
990  int write_pos;
991  unsigned int cnt;
992  char *writebuffer;
993  uint64_t fsize;
994 
995  if (GNUNET_OK !=
997  &fsize,
998  GNUNET_YES,
999  GNUNET_YES))
1000  {
1003  "fstat",
1004  fn);
1005  return GNUNET_OK;
1006  }
1007  read_size = GNUNET_DISK_fn_read (fn,
1008  buffer,
1009  sizeof (buffer));
1010 
1011  if ( (read_size < (int) sizeof (struct GNUNET_MessageHeader)) ||
1012  (fsize > GNUNET_MAX_MESSAGE_SIZE) )
1013  {
1014  if (0 != UNLINK (fn))
1017  "unlink",
1018  fn);
1019  return GNUNET_OK;
1020  }
1021 
1022  writebuffer = GNUNET_malloc (read_size);
1023  read_pos = 0;
1024  write_pos = 0;
1025  while (read_pos < read_size)
1026  {
1027  /* Check each HELLO */
1028  hello = (const struct GNUNET_HELLO_Message *) &buffer[read_pos];
1029  cur_hello_size = GNUNET_HELLO_size (hello);
1030  if (0 == cur_hello_size)
1031  {
1032  /* Invalid data, discard */
1033  if (0 != UNLINK (fn))
1036  "unlink",
1037  fn);
1038  GNUNET_free (writebuffer);
1039  return GNUNET_OK;
1040  }
1041  new_hello = GNUNET_HELLO_iterate_addresses (hello,
1042  GNUNET_YES,
1043  &discard_expired,
1044  now);
1045  cnt = 0;
1046  if (NULL != new_hello)
1047  (void) GNUNET_HELLO_iterate_addresses (hello,
1048  GNUNET_NO,
1049  &count_addresses,
1050  &cnt);
1051  if ( (NULL != new_hello) && (0 < cnt) )
1052  {
1053  /* Store new HELLO to write it when done */
1054  new_hello_size = GNUNET_HELLO_size (new_hello);
1055  GNUNET_memcpy (&writebuffer[write_pos],
1056  new_hello,
1057  new_hello_size);
1058  write_pos += new_hello_size;
1059  }
1060  read_pos += cur_hello_size;
1061  GNUNET_free_non_null (new_hello);
1062  }
1063 
1064  if (0 < write_pos)
1065  {
1067  writebuffer,
1068  write_pos,
1073  }
1074  else if (0 != UNLINK (fn))
1077  "unlink", fn);
1078 
1079  GNUNET_free (writebuffer);
1080  return GNUNET_OK;
1081 }
1082 
1083 
1090 static void
1092 {
1093  struct GNUNET_TIME_Absolute now;
1094 
1095  (void) cls;
1096  cron_clean = NULL;
1097  now = GNUNET_TIME_absolute_get ();
1099  _("Cleaning up directory `%s'\n"),
1103  &now);
1106  NULL);
1107 }
1108 
1109 
1117 static int
1118 check_hello (void *cls,
1119  const struct GNUNET_HELLO_Message *hello)
1120 {
1121  struct GNUNET_PeerIdentity pid;
1122 
1123  (void) cls;
1124  if (GNUNET_OK !=
1125  GNUNET_HELLO_get_id (hello,
1126  &pid))
1127  {
1128  GNUNET_break (0);
1129  return GNUNET_SYSERR;
1130  }
1131  return GNUNET_OK;
1132 }
1133 
1134 
1141 static void
1142 handle_hello (void *cls,
1143  const struct GNUNET_HELLO_Message *hello)
1144 {
1145  struct GNUNET_SERVICE_Client *client = cls;
1146  struct GNUNET_PeerIdentity pid;
1147 
1149  GNUNET_HELLO_get_id (hello,
1150  &pid));
1152  "HELLO message received for peer `%s'\n",
1153  GNUNET_i2s (&pid));
1154  add_host_to_known_hosts (&pid);
1155  update_hello (&pid,
1156  hello);
1158 }
1159 
1160 
1167 static void
1168 handle_get (void *cls,
1169  const struct ListPeerMessage *lpm)
1170 {
1171  struct GNUNET_SERVICE_Client *client = cls;
1172  struct TransmitContext tcx;
1173  struct GNUNET_MessageHeader *msg;
1174  struct GNUNET_MQ_Envelope *env;
1175 
1177  "GET message received for peer `%s'\n",
1178  GNUNET_i2s (&lpm->peer));
1179  tcx.friend_only = ntohl (lpm->include_friend_only);
1180  tcx.client = client;
1182  &lpm->peer,
1183  &add_to_tc,
1184  &tcx);
1185  env = GNUNET_MQ_msg (msg,
1188  env);
1190 }
1191 
1192 
1199 static void
1200 handle_get_all (void *cls,
1201  const struct ListAllPeersMessage *lapm)
1202 {
1203  struct GNUNET_SERVICE_Client *client = cls;
1204  struct TransmitContext tcx;
1205  struct GNUNET_MQ_Envelope *env;
1206  struct GNUNET_MessageHeader *msg;
1207 
1209  "GET_ALL message received\n");
1210  tcx.friend_only = ntohl (lapm->include_friend_only);
1211  tcx.client = client;
1213  &add_to_tc,
1214  &tcx);
1215  env = GNUNET_MQ_msg (msg,
1218  env);
1220 }
1221 
1222 
1229 static void
1230 handle_notify (void *cls,
1231  const struct NotifyMessage *nm)
1232 {
1233  struct GNUNET_SERVICE_Client *client = cls;
1234  struct GNUNET_MQ_Handle *mq;
1235  struct TransmitContext tcx;
1236  struct GNUNET_MQ_Envelope *env;
1237  struct GNUNET_MessageHeader *msg;
1238 
1240  "NOTIFY message received\n");
1241  mq = GNUNET_SERVICE_client_get_mq (client);
1243  if (ntohl (nm->include_friend_only))
1244  GNUNET_notification_context_add (notify_friend_only_list,
1245  mq);
1246  else
1247  GNUNET_notification_context_add (notify_list,
1248  mq);
1249  tcx.friend_only = ntohl (nm->include_friend_only);
1250  tcx.client = client;
1252  &add_to_tc,
1253  &tcx);
1254  env = GNUNET_MQ_msg (msg,
1257  env);
1259 }
1260 
1261 
1270 static void *
1272  struct GNUNET_SERVICE_Client *client,
1273  struct GNUNET_MQ_Handle *mq)
1274 {
1275  (void) cls;
1276  (void) mq;
1277  return client;
1278 }
1279 
1280 
1288 static void
1290  struct GNUNET_SERVICE_Client *client,
1291  void *app_ctx)
1292 {
1293  (void) cls;
1294  GNUNET_assert (app_ctx == client);
1295 }
1296 
1297 
1306 static int
1307 free_host_entry (void *cls,
1308  const struct GNUNET_PeerIdentity *key,
1309  void *value)
1310 {
1311  struct HostEntry *he = value;
1312 
1313  (void) cls;
1314  (void) key;
1317  GNUNET_free (he);
1318  return GNUNET_YES;
1319 }
1320 
1321 
1327 static void
1328 shutdown_task (void *cls)
1329 {
1330  (void) cls;
1332  notify_list = NULL;
1333  GNUNET_notification_context_destroy (notify_friend_only_list);
1334  notify_friend_only_list = NULL;
1335 
1337  &free_host_entry,
1338  NULL);
1340  if (NULL != stats)
1341  {
1343  GNUNET_NO);
1344  stats = NULL;
1345  }
1346  if (NULL != cron_clean)
1347  {
1348  GNUNET_SCHEDULER_cancel (cron_clean);
1349  cron_clean = NULL;
1350  }
1351  if (NULL != cron_scan)
1352  {
1353  GNUNET_SCHEDULER_cancel (cron_scan);
1354  cron_scan = NULL;
1355  }
1356  if (NULL != networkIdDirectory)
1357  {
1359  networkIdDirectory = NULL;
1360  }
1361 }
1362 
1363 
1371 static void
1372 run (void *cls,
1373  const struct GNUNET_CONFIGURATION_Handle *cfg,
1375 {
1376  char *peerdir;
1377  char *ip;
1378  struct DirScanContext dsc;
1379  int noio;
1380  int use_included;
1381 
1382  (void) cls;
1383  (void) service;
1384  hostmap
1386  GNUNET_YES);
1387  stats
1388  = GNUNET_STATISTICS_create ("peerinfo",
1389  cfg);
1390  notify_list
1392  notify_friend_only_list
1395  "peerinfo",
1396  "NO_IO");
1397  use_included
1399  "peerinfo",
1400  "USE_INCLUDED_HELLOS");
1401  if (GNUNET_SYSERR == use_included)
1402  use_included = GNUNET_NO;
1404  NULL);
1405  if (GNUNET_YES != noio)
1406  {
1409  "peerinfo",
1410  "HOSTS",
1411  &networkIdDirectory));
1412  if (GNUNET_OK !=
1414  {
1416  return;
1417  }
1418 
1419  cron_scan
1422  NULL);
1423 
1424  cron_clean
1427  NULL);
1428  if (GNUNET_YES == use_included)
1429  {
1431  GNUNET_asprintf (&peerdir,
1432  "%shellos",
1433  ip);
1434  GNUNET_free (ip);
1435 
1437  _("Importing HELLOs from `%s'\n"),
1438  peerdir);
1439  dsc.matched = 0;
1440  dsc.remove_files = GNUNET_NO;
1441 
1442  GNUNET_DISK_directory_scan (peerdir,
1444  &dsc);
1445  GNUNET_free (peerdir);
1446  }
1447  else
1448  {
1450  _("Skipping import of included HELLOs\n"));
1451  }
1452  }
1453 }
1454 
1455 
1460 ("peerinfo",
1462  &run,
1465  NULL,
1466  GNUNET_MQ_hd_var_size (hello,
1468  struct GNUNET_HELLO_Message,
1469  NULL),
1472  struct ListPeerMessage,
1473  NULL),
1474  GNUNET_MQ_hd_fixed_size (get_all,
1476  struct ListAllPeersMessage,
1477  NULL),
1480  struct NotifyMessage,
1481  NULL),
1483 
1484 
1485 /* end of gnunet-service-peerinfo.c */
static void remove_garbage(const char *fullname)
Remove a file that should not be there.
uint32_t include_friend_only
Include friend only HELLOs and peers in callbacks.
Definition: peerinfo.h:77
#define GNUNET_MESSAGE_TYPE_PEERINFO_GET
Request update and listing of a peer.
uint32_t include_friend_only
Include friend only HELLOs and peers in callbacks.
Definition: peerinfo.h:53
int GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:669
int remove_files
GNUNET_YES if we should remove files that are broken, GNUNET_NO if the directory we are iterating ove...
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:668
struct GNUNET_HELLO_Message * hello
Hello for the peer (can be NULL)
Closure for add_to_tc()
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static int count_addresses(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Address iterator that counts the remaining addresses.
A HELLO message is used to exchange information about transports with other peers.
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition: nc.c:77
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static char * expiration
Credential TTL.
struct GNUNET_SERVICE_Client * client
Client to transmit to.
static struct InfoMessage * make_info_message(const struct HostEntry *he, int include_friend_only)
Notify all clients in the notify list about the given host entry changing.
uint32_t include_friend_only
Include friend only HELLOs and peers in callbacks.
Definition: peerinfo.h:95
static struct GNUNET_SCHEDULER_Task * cron_scan
Handle for task to run cron_scan_directory_data_hosts()
static void handle_hello(void *cls, const struct GNUNET_HELLO_Message *hello)
Handle HELLO-message.
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
static void update_hello(const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello)
Bind a host address (hello) to a hostId.
struct GNUNET_HELLO_Message * GNUNET_HELLO_create(const struct GNUNET_CRYPTO_EddsaPublicKey *public_key, GNUNET_HELLO_GenerateAddressListCallback addrgen, void *addrgen_cls, int friend_only)
Construct a HELLO message given the public key, expiration time and an iterator that spews the transp...
Definition: hello.c:204
Handle to a service.
Definition: service.c:116
struct GNUNET_PeerIdentity peer
Restrict to peers with this identity (optional field, check header.size!).
Definition: peerinfo.h:59
static void cron_scan_directory_data_hosts(void *cls)
Call this method periodically to scan data/hosts for new hosts.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed_with_priority(struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1178
static void cron_clean_data_hosts(void *cls)
Call this method periodically to scan peerinfo/ for ancient HELLOs to expire.
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2734
int GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:714
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:1293
static struct GNUNET_NotificationContext * notify_friend_only_list
Clients to immediately notify about all changes, even for friend-only HELLOs.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Message used to inform the client about a particular peer; this message is optionally followed by a H...
Definition: peerinfo.h:107
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:417
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:832
static int check_hello(void *cls, const struct GNUNET_HELLO_Message *hello)
Check HELLO-message.
#define GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY
Start notifying this client about all changes to the known peers until it disconnects.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:833
static int include_friend_only
Option &#39;-f&#39;.
#define DATA_HOST_CLEAN_FREQ
How often do we discard old entries in data/hosts/?
#define GNUNET_NO
Definition: gnunet_common.h:81
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static char * get_host_filename(const struct GNUNET_PeerIdentity *id)
Get the filename under which we would store the GNUNET_HELLO_Message for the given host and protocol...
#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.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
Start up peerinfo service.
static struct GNUNET_HELLO_Message * update_friend_hello(const struct GNUNET_HELLO_Message *hello, const struct GNUNET_HELLO_Message *friend_hello)
Update the HELLO of a friend by merging the addresses.
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:1233
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
int friend_only
Include friend only HELLOs GNUNET_YES or GNUNET_NO.
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.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
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).
Handle for the service.
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:164
uint64_t abs_value_us
The actual value.
ssize_t GNUNET_DISK_fn_write(const char *fn, const void *buffer, size_t n, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file.
Definition: disk.c:1203
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
#define UNLINK(f)
Definition: plibc.h:666
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
struct GNUNET_PeerIdentity peer
About which peer are we talking here?
Definition: peerinfo.h:123
unsigned int matched
Counter for the number of (valid) entries found, incremented by one for each match.
Handle to a client that is connected to a service.
Definition: service.c:249
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
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:1246
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_with_priority(enum GNUNET_SCHEDULER_Priority prio, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified priority.
Definition: scheduler.c:1200
#define GNUNET_memcpy(dst, src, n)
static char * value
Value of the record to add/remove.
static struct GNUNET_NotificationContext * notify_list
Clients to immediately notify about all changes.
static int discard_hosts_helper(void *cls, const char *fn)
delete expired HELLO entries in directory
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_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
static char * fn
Filename of the unique file.
static struct GNUNET_PEERINFO_NotifyContext * notify
Handle to the peerinfo notify service (NULL until we&#39;ve connected to it).
static void shutdown_task(void *cls)
Clean up our state.
char * GNUNET_OS_installation_get_path(enum GNUNET_OS_InstallationPathKind dirkind)
Get the path to a specific GNUnet installation directory or, with GNUNET_OS_IPK_SELF_PREFIX, the current running apps installation directory.
static struct HostEntry * add_host_to_known_hosts(const struct GNUNET_PeerIdentity *identity)
Add a host to the list and notify clients about this event.
static char * filename
const char * transport_name
Name of the transport plugin enabling the communication using this address.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
Client connect callback.
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the &#39;monitor&#39; flag on this client.
Definition: service.c:2704
Closure for hosts_directory_scan_callback().
Internal representation of the hash map.
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_PEERINFO_INFO.
Definition: peerinfo.h:113
#define DIR_SEPARATOR
Definition: plibc.h:631
static int res
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
Run when otherwise idle.
static int add_to_tc(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Do transmit info about peer to given host.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
static struct GNUNET_STATISTICS_Handle * stats
Handle for reporting statistics.
GUID host
common internal definitions for peerinfo service
int GNUNET_HELLO_is_friend_only(const struct GNUNET_HELLO_Message *h)
Return HELLO type.
Definition: hello.c:89
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct GNUNET_CONTAINER_MultiPeerMap * hostmap
The in-memory list of known hosts, mapping of host IDs to &#39;struct HostEntry*&#39; values.
GNUNET_SERVICE_MAIN("peerinfo", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(hello, GNUNET_MESSAGE_TYPE_HELLO, struct GNUNET_HELLO_Message, NULL), GNUNET_MQ_hd_fixed_size(get, GNUNET_MESSAGE_TYPE_PEERINFO_GET, struct ListPeerMessage, NULL), GNUNET_MQ_hd_fixed_size(get_all, GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL, struct ListAllPeersMessage, NULL), GNUNET_MQ_hd_fixed_size(notify, GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY, struct NotifyMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
#define GNUNET_MESSAGE_TYPE_PEERINFO_INFO
Information about one of the peers.
struct GNUNET_HELLO_Message * friend_only_hello
Friend only hello for the peer (can be NULL)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
int GNUNET_DISK_file_size(const char *filename, uint64_t *size, int include_symbolic_links, int single_file_mode)
Get the size of the file (or directory) of the given file (in bytes).
Definition: disk.c:289
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:125
Handle to a message queue.
Definition: mq.c:85
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.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
int GNUNET_CRYPTO_eddsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:501
Everybody can read.
void GNUNET_notification_context_broadcast(struct GNUNET_NotificationContext *nc, const struct GNUNET_MessageHeader *msg, int can_drop)
Send a message to all subscribers of this context.
Definition: nc.c:192
The identity of the host (wraps the signing key of the peer).
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
configuration data
Definition: configuration.c:85
#define DATA_HOST_FREQ
How often do we scan the HOST_DIR for new entries?
Result of reading a file.
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.
static char * networkIdDirectory
Directory where the hellos are stored in (peerinfo/)
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
Message requesting a listing of all peers, restricted to the specified peer identity.
Definition: peerinfo.h:67
#define TRUNCATE(f, l)
Definition: plibc.h:647
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:649
static void handle_notify(void *cls, const struct NotifyMessage *nm)
Handle NOTIFY-message.
Message requesting a listing of peers, restricted to the specified peer identity. ...
Definition: peerinfo.h:42
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
static void notify_all(struct HostEntry *entry)
Broadcast information about the given entry to all clients that care.
In-memory cache of known hosts.
#define GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL
Request update and listing of all peers.
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:141
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
Client disconnect callback.
static void read_host_file(const char *fn, int unlink_garbage, struct ReadHostFileContext *r)
Try to read the HELLOs in the given filename and discard expired addresses.
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
static int discard_expired(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Address iterator that causes expired entries to be discarded.
#define GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END
End of information about other peers.
#define DIR_SEPARATOR_STR
Definition: plibc.h:632
#define GNUNET_MESSAGE_TYPE_HELLO
HELLO message with friend only flag used for communicating peer addresses.
static int hosts_directory_scan_callback(void *cls, const char *fullname)
Function that is called on each HELLO file in a particular directory.
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".
struct GNUNET_HELLO_Message * hello
Hello for the peer (can be NULL)
static char * address
GNS address for this phone.
struct GNUNET_PeerIdentity identity
Identity of the peer.
static void handle_get_all(void *cls, const struct ListAllPeersMessage *lapm)
Handle GET-ALL-message.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
int GNUNET_CONTAINER_multipeermap_get_multiple(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
static int free_host_entry(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Release memory taken by a host entry.
struct GNUNET_HELLO_Message * friend_only_hello
Friend only hello for the peer (can be NULL)
#define GNUNET_malloc(size)
Wrapper around malloc.
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:1019
static void handle_get(void *cls, const struct ListPeerMessage *lpm)
Handle GET-message.
Return the directory where data is installed (share/gnunet/)
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
#define gettext_noop(String)
Definition: gettext.h:69
static struct GNUNET_SCHEDULER_Task * cron_clean
Handle for task to run cron_clean_data_hosts()
Header for all communications.
Definition: peerinfo.h:85
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965