GNUnet  0.11.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 \
42  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
43 
47 #define DATA_HOST_CLEAN_FREQ \
48  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 60)
49 
50 
54 struct HostEntry
55 {
60 
65 
70 };
71 
72 
77 {
82 
87 };
88 
89 
95 
100 
106 
110 static char *networkIdDirectory;
111 
116 
121 
126 
127 
136 static struct InfoMessage *
138 {
139  struct InfoMessage *im;
140  struct GNUNET_HELLO_Message *src;
141  size_t hs;
142 
143  if (GNUNET_YES == include_friend_only)
144  src = he->friend_only_hello;
145  else
146  src = he->hello;
147  hs = (NULL == src) ? 0 : GNUNET_HELLO_size (src);
148  im = GNUNET_malloc (sizeof(struct InfoMessage) + hs);
149  im->header.size = htons (hs + sizeof(struct InfoMessage));
151  im->peer = he->identity;
152  GNUNET_memcpy (&im[1], src, hs);
153  return im;
154 }
155 
156 
165 static int
166 discard_expired (void *cls,
167  const struct GNUNET_HELLO_Address *address,
169 {
170  const struct GNUNET_TIME_Absolute *now = cls;
171 
172  if (now->abs_value_us > expiration.abs_value_us)
173  {
175  _ ("Removing expired address of transport `%s'\n"),
176  address->transport_name);
177  return GNUNET_NO;
178  }
179  return GNUNET_OK;
180 }
181 
182 
191 static int
192 count_addresses (void *cls,
193  const struct GNUNET_HELLO_Address *address,
195 {
196  unsigned int *cnt = cls;
197 
198  (void) address;
199  (void) expiration;
200  (*cnt)++;
201  return GNUNET_OK;
202 }
203 
204 
212 static char *
214 {
215  char *fn;
216 
217  if (NULL == networkIdDirectory)
218  return NULL;
219  GNUNET_asprintf (&fn,
220  "%s%s%s",
223  GNUNET_i2s_full (id));
224  return fn;
225 }
226 
227 
234 static void
235 notify_all (struct HostEntry *entry)
236 {
237  struct InfoMessage *msg_pub;
238  struct InfoMessage *msg_friend;
239 
241  "Notifying all clients about peer `%s'\n",
242  GNUNET_i2s (&entry->identity));
243  msg_pub = make_info_message (entry, GNUNET_NO);
245  &msg_pub->header,
246  GNUNET_NO);
247  GNUNET_free (msg_pub);
248  msg_friend = make_info_message (entry, GNUNET_YES);
249  GNUNET_notification_context_broadcast (notify_friend_only_list,
250  &msg_friend->header,
251  GNUNET_NO);
252  GNUNET_free (msg_friend);
253 }
254 
255 
262 static void
263 update_hello (const struct GNUNET_PeerIdentity *peer,
264  const struct GNUNET_HELLO_Message *hello);
265 
266 
278 static void
279 read_host_file (const char *fn,
280  int unlink_garbage,
281  struct ReadHostFileContext *r)
282 {
283  char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
284  ssize_t size_total;
285  struct GNUNET_TIME_Absolute now;
286  unsigned int left;
287  const struct GNUNET_HELLO_Message *hello;
288  struct GNUNET_HELLO_Message *hello_clean;
289  size_t read_pos;
290  uint16_t size_hello;
291 
292  r->friend_only_hello = NULL;
293  r->hello = NULL;
294 
295  if (GNUNET_YES != GNUNET_DISK_file_test (fn))
296  return;
297  size_total = GNUNET_DISK_fn_read (fn, buffer, sizeof(buffer));
299  "Read %d bytes from `%s'\n",
300  (int) size_total,
301  fn);
302  if ((size_total < 0) ||
303  (((size_t) size_total) < sizeof(struct GNUNET_MessageHeader)))
304  {
306  _ ("Failed to parse HELLO in file `%s': %s\n"),
307  fn,
308  "File has invalid size");
309  if ((GNUNET_YES == unlink_garbage) && (0 != unlink (fn)) &&
310  (ENOENT != errno))
312  return;
313  }
314 
315  read_pos = 0;
316  while (read_pos < (size_t) size_total)
317  {
318  hello = (const struct GNUNET_HELLO_Message *) &buffer[read_pos];
319  size_hello = GNUNET_HELLO_size (hello);
320  if ((0 == size_hello) || (((size_t) size_total) - read_pos < size_hello))
321  {
323  _ ("Failed to parse HELLO in file `%s'\n"),
324  fn);
325  if (0 == read_pos)
326  {
327  if ((GNUNET_YES == unlink_garbage) && (0 != unlink (fn)) &&
328  (ENOENT != errno))
330  }
331  else
332  {
333  if ((GNUNET_YES == unlink_garbage) && (0 != truncate (fn, read_pos)) &&
334  (ENOENT != errno))
336  }
337  return;
338  }
339 
340  now = GNUNET_TIME_absolute_get ();
341  hello_clean = GNUNET_HELLO_iterate_addresses (hello,
342  GNUNET_YES,
344  &now);
345  if (NULL == hello_clean)
346  {
348  _ ("Failed to parse HELLO in file `%s'\n"),
349  fn);
350  if ((GNUNET_YES == unlink_garbage) && (0 != unlink (fn)) &&
351  (ENOENT != errno))
353  return;
354  }
355  left = 0;
356  (void) GNUNET_HELLO_iterate_addresses (hello_clean,
357  GNUNET_NO,
359  &left);
360 
361  if (0 == left)
362  {
363  GNUNET_free (hello_clean);
364  break;
365  }
366 
367  if (GNUNET_NO == GNUNET_HELLO_is_friend_only (hello_clean))
368  {
369  if (NULL == r->hello)
370  r->hello = hello_clean;
371  else
372  {
373  GNUNET_break (0);
374  GNUNET_free (r->hello);
375  r->hello = hello_clean;
376  }
377  }
378  else
379  {
380  if (NULL == r->friend_only_hello)
381  r->friend_only_hello = hello_clean;
382  else
383  {
384  GNUNET_break (0);
386  r->friend_only_hello = hello_clean;
387  }
388  }
389  read_pos += size_hello;
390  }
391 
392  if (0 == left)
393  {
394  /* no addresses left, remove from disk */
395  if ((GNUNET_YES == unlink_garbage) && (0 != unlink (fn)))
397  }
399  "Found `%s' and `%s' HELLO message in file\n",
400  (NULL != r->hello) ? "public" : "NON-public",
401  (NULL != r->friend_only_hello) ? "friend only"
402  : "NO friend only");
403 }
404 
405 
412 static struct HostEntry *
414 {
415  struct HostEntry *entry;
416  struct ReadHostFileContext r;
417  char *fn;
418 
419  entry = GNUNET_CONTAINER_multipeermap_get (hostmap, identity);
420  if (NULL == entry)
421  {
423  "Adding new peer `%s'\n",
424  GNUNET_i2s (identity));
426  gettext_noop ("# peers known"),
427  1,
428  GNUNET_NO);
429  entry = GNUNET_new (struct HostEntry);
430  entry->identity = *identity;
433  hostmap,
434  &entry->identity,
435  entry,
437  notify_all (entry);
438  fn = get_host_filename (identity);
439  if (NULL != fn)
440  {
441  read_host_file (fn, GNUNET_YES, &r);
442  if (NULL != r.hello)
443  update_hello (identity, r.hello);
444  if (NULL != r.friend_only_hello)
445  update_hello (identity, r.friend_only_hello);
448  GNUNET_free (fn);
449  }
450  }
451  return entry;
452 }
453 
454 
461 static void
462 remove_garbage (const char *fullname)
463 {
464  if (0 == unlink (fullname))
465  GNUNET_log (
467  _ (
468  "File `%s' in directory `%s' does not match naming convention. Removed.\n"),
469  fullname,
471  else
473  "unlink",
474  fullname);
475 }
476 
477 
482 {
489 
494  unsigned int matched;
495 };
496 
497 
507 static int
508 hosts_directory_scan_callback (void *cls, const char *fullname)
509 {
510  struct DirScanContext *dsc = cls;
511  struct GNUNET_PeerIdentity identity;
512  struct ReadHostFileContext r;
513  const char *filename;
514  struct GNUNET_PeerIdentity id_public;
515  struct GNUNET_PeerIdentity id_friend;
516  struct GNUNET_PeerIdentity id;
517 
518  if (GNUNET_YES != GNUNET_DISK_file_test (fullname))
519  return GNUNET_OK; /* ignore non-files */
520 
521  filename = strrchr (fullname, DIR_SEPARATOR);
522  if ((NULL == filename) || (1 > strlen (filename)))
523  filename = fullname;
524  else
525  filename++;
526 
527  read_host_file (fullname, dsc->remove_files, &r);
528  if ((NULL == r.hello) && (NULL == r.friend_only_hello))
529  return GNUNET_OK;
530  if (NULL != r.friend_only_hello)
531  {
532  if (GNUNET_OK != GNUNET_HELLO_get_id (r.friend_only_hello, &id_friend))
533  {
534  if (GNUNET_YES == dsc->remove_files)
535  remove_garbage (fullname);
536  return GNUNET_OK;
537  }
538  id = id_friend;
539  }
540  if (NULL != r.hello)
541  {
542  if (GNUNET_OK != GNUNET_HELLO_get_id (r.hello, &id_public))
543  {
544  if (GNUNET_YES == dsc->remove_files)
545  remove_garbage (fullname);
546  return GNUNET_OK;
547  }
548  id = id_public;
549  }
550 
551  if ((NULL != r.hello) && (NULL != r.friend_only_hello) &&
552  (0 != GNUNET_memcmp (&id_friend, &id_public)))
553  {
554  /* HELLOs are not for the same peer */
555  GNUNET_break (0);
556  if (GNUNET_YES == dsc->remove_files)
557  remove_garbage (fullname);
558  return GNUNET_OK;
559  }
560  if (GNUNET_OK ==
562  strlen (filename),
563  &identity.public_key))
564  {
565  if (0 != GNUNET_memcmp (&id, &identity))
566  {
567  /* HELLOs are not for the same peer */
568  GNUNET_break (0);
569  if (GNUNET_YES == dsc->remove_files)
570  remove_garbage (fullname);
571  return GNUNET_OK;
572  }
573  }
574 
575  /* ok, found something valid, remember HELLO */
577  if (NULL != r.hello)
578  {
580  "Updating peer `%s' public HELLO \n",
581  GNUNET_i2s (&id));
582  update_hello (&id, r.hello);
583  GNUNET_free (r.hello);
584  }
585  if (NULL != r.friend_only_hello)
586  {
588  "Updating peer `%s' friend only HELLO \n",
589  GNUNET_i2s (&id));
592  }
593  dsc->matched++;
594  return GNUNET_OK;
595 }
596 
597 
603 static void
605 {
606  static unsigned int retries;
607  struct DirScanContext dsc;
608 
609  (void) cls;
610  cron_scan = NULL;
612  {
613  cron_scan =
616  &
618  NULL);
619  return;
620  }
621  dsc.matched = 0;
622  dsc.remove_files = GNUNET_YES;
624  _ ("Scanning directory `%s'\n"),
628  &dsc);
629  if ((0 == dsc.matched) && (0 == (++retries & 31)))
631  _ ("Still no peers found in `%s'!\n"),
633  cron_scan =
637  NULL);
638 }
639 
640 
648 static struct GNUNET_HELLO_Message *
650  const struct GNUNET_HELLO_Message *friend_hello)
651 {
652  struct GNUNET_HELLO_Message *res;
653  struct GNUNET_HELLO_Message *tmp;
654  struct GNUNET_PeerIdentity pid;
655 
656  if (NULL != friend_hello)
657  {
658  res = GNUNET_HELLO_merge (hello, friend_hello);
660  return res;
661  }
662 
663  if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid))
664  {
665  GNUNET_break (0);
666  return NULL;
667  }
668  tmp = GNUNET_HELLO_create (&pid.public_key, NULL, NULL, GNUNET_YES);
669  res = GNUNET_HELLO_merge (hello, tmp);
670  GNUNET_free (tmp);
672  return res;
673 }
674 
675 
682 static void
683 update_hello (const struct GNUNET_PeerIdentity *peer,
684  const struct GNUNET_HELLO_Message *hello)
685 {
686  char *fn;
687  struct HostEntry *host;
688  struct GNUNET_HELLO_Message *mrg;
689  struct GNUNET_HELLO_Message **dest;
690  struct GNUNET_TIME_Absolute delta;
691  unsigned int cnt;
692  unsigned int size;
693  int friend_hello_type;
694  int store_hello;
695  int store_friend_hello;
696  unsigned int pos;
697  char *buffer;
698 
699  host = GNUNET_CONTAINER_multipeermap_get (hostmap, peer);
700  GNUNET_assert (NULL != host);
701 
702  friend_hello_type = GNUNET_HELLO_is_friend_only (hello);
704  "Updating %s HELLO for `%s'\n",
705  (GNUNET_YES == friend_hello_type) ? "friend-only" : "public",
706  GNUNET_i2s (peer));
707 
708  dest = NULL;
709  if (GNUNET_YES == friend_hello_type)
710  {
711  dest = &host->friend_only_hello;
712  }
713  else
714  {
715  dest = &host->hello;
716  }
717 
718  if (NULL == (*dest))
719  {
720  (*dest) = GNUNET_malloc (GNUNET_HELLO_size (hello));
721  GNUNET_memcpy ((*dest), hello, GNUNET_HELLO_size (hello));
722  }
723  else
724  {
725  mrg = GNUNET_HELLO_merge ((*dest), hello);
726  delta = GNUNET_HELLO_equals (mrg, (*dest), GNUNET_TIME_absolute_get ());
727  if (delta.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
728  {
729  /* no differences, just ignore the update */
731  "No change in %s HELLO for `%s'\n",
732  (GNUNET_YES == friend_hello_type) ? "friend-only" : "public",
733  GNUNET_i2s (peer));
734  GNUNET_free (mrg);
735  return;
736  }
737  GNUNET_free ((*dest));
738  (*dest) = mrg;
739  }
740 
741  if ((NULL != (host->hello)) && (GNUNET_NO == friend_hello_type))
742  {
743  /* Update friend only hello */
744  mrg = update_friend_hello (host->hello, host->friend_only_hello);
745  if (NULL != host->friend_only_hello)
747  host->friend_only_hello = mrg;
748  }
749 
750  if (NULL != host->hello)
752  if (NULL != host->friend_only_hello)
753  GNUNET_assert (
755 
756  fn = get_host_filename (peer);
757  if ((NULL != fn) && (GNUNET_OK == GNUNET_DISK_directory_create_for_file (fn)))
758  {
759  store_hello = GNUNET_NO;
760  size = 0;
761  cnt = 0;
762  if (NULL != host->hello)
764  GNUNET_NO,
766  &cnt);
767  if (cnt > 0)
768  {
769  store_hello = GNUNET_YES;
770  size += GNUNET_HELLO_size (host->hello);
771  }
772  cnt = 0;
773  if (NULL != host->friend_only_hello)
775  GNUNET_NO,
777  &cnt);
778  store_friend_hello = GNUNET_NO;
779  if (0 < cnt)
780  {
781  store_friend_hello = GNUNET_YES;
782  size += GNUNET_HELLO_size (host->friend_only_hello);
783  }
784 
785  if ((GNUNET_NO == store_hello) && (GNUNET_NO == store_friend_hello))
786  {
787  /* no valid addresses, don't put HELLO on disk; in fact,
788  if one exists on disk, remove it */
789  (void) unlink (fn);
790  }
791  else
792  {
793  buffer = GNUNET_malloc (size);
794  pos = 0;
795 
796  if (GNUNET_YES == store_hello)
797  {
798  GNUNET_memcpy (buffer, host->hello, GNUNET_HELLO_size (host->hello));
799  pos += GNUNET_HELLO_size (host->hello);
800  }
801  if (GNUNET_YES == store_friend_hello)
802  {
803  GNUNET_memcpy (&buffer[pos],
804  host->friend_only_hello,
806  pos += GNUNET_HELLO_size (host->friend_only_hello);
807  }
808  GNUNET_assert (pos == size);
809 
811  buffer,
812  size,
818  else
820  "Stored %s %s HELLO in %s with total size %u\n",
821  (GNUNET_YES == store_friend_hello) ? "friend-only" : "",
822  (GNUNET_YES == store_hello) ? "public" : "",
823  fn,
824  size);
825  GNUNET_free (buffer);
826  }
827  }
829  notify_all (host);
830 }
831 
832 
837 {
842 
847 };
848 
849 
858 static int
859 add_to_tc (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
860 {
861  struct TransmitContext *tc = cls;
862  struct HostEntry *pos = value;
863  struct InfoMessage *im;
864  uint16_t hs;
865  struct GNUNET_MQ_Envelope *env;
866 
867  hs = 0;
868 
869  if ((NULL != pos->hello) && (GNUNET_NO == tc->friend_only))
870  {
871  /* Copy public HELLO */
872  hs = GNUNET_HELLO_size (pos->hello);
873  GNUNET_assert (hs < GNUNET_MAX_MESSAGE_SIZE - sizeof(struct InfoMessage));
875  GNUNET_memcpy (&im[1], pos->hello, hs);
877  "Sending public HELLO with size %u for peer `%s'\n",
878  hs,
879  GNUNET_i2s (key));
880  }
881  else if ((NULL != pos->friend_only_hello) && (GNUNET_YES == tc->friend_only))
882  {
883  /* Copy friend only HELLO */
885  GNUNET_assert (hs < GNUNET_MAX_MESSAGE_SIZE - sizeof(struct InfoMessage));
887  GNUNET_memcpy (&im[1], pos->friend_only_hello, hs);
889  "Sending friend-only HELLO with size %u for peer `%s'\n",
890  hs,
891  GNUNET_i2s (key));
892  }
893  else
894  {
897  "Adding no HELLO for peer `%s'\n",
898  GNUNET_i2s (key));
899  }
900  im->peer = pos->identity;
902  return GNUNET_YES;
903 }
904 
905 
913 static int
914 discard_hosts_helper (void *cls, const char *fn)
915 {
916  struct GNUNET_TIME_Absolute *now = cls;
917  char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
918  const struct GNUNET_HELLO_Message *hello;
919  struct GNUNET_HELLO_Message *new_hello;
920  int read_size;
921  unsigned int cur_hello_size;
922  unsigned int new_hello_size;
923  int read_pos;
924  int write_pos;
925  unsigned int cnt;
926  char *writebuffer;
927  uint64_t fsize;
928 
930  {
933  "fstat",
934  fn);
935  return GNUNET_OK;
936  }
937  read_size = GNUNET_DISK_fn_read (fn, buffer, sizeof(buffer));
938 
939  if ((read_size < (int) sizeof(struct GNUNET_MessageHeader)) ||
940  (fsize > GNUNET_MAX_MESSAGE_SIZE))
941  {
942  if (0 != unlink (fn))
945  "unlink",
946  fn);
947  return GNUNET_OK;
948  }
949 
950  writebuffer = GNUNET_malloc (read_size);
951  read_pos = 0;
952  write_pos = 0;
953  while (read_pos < read_size)
954  {
955  /* Check each HELLO */
956  hello = (const struct GNUNET_HELLO_Message *) &buffer[read_pos];
957  cur_hello_size = GNUNET_HELLO_size (hello);
958  if (0 == cur_hello_size)
959  {
960  /* Invalid data, discard */
961  if (0 != unlink (fn))
964  "unlink",
965  fn);
966  GNUNET_free (writebuffer);
967  return GNUNET_OK;
968  }
969  new_hello =
971  cnt = 0;
972  if (NULL != new_hello)
973  (void) GNUNET_HELLO_iterate_addresses (hello,
974  GNUNET_NO,
976  &cnt);
977  if ((NULL != new_hello) && (0 < cnt))
978  {
979  /* Store new HELLO to write it when done */
980  new_hello_size = GNUNET_HELLO_size (new_hello);
981  GNUNET_memcpy (&writebuffer[write_pos], new_hello, new_hello_size);
982  write_pos += new_hello_size;
983  }
984  read_pos += cur_hello_size;
985  GNUNET_free_non_null (new_hello);
986  }
987 
988  if (0 < write_pos)
989  {
991  writebuffer,
992  write_pos,
997  }
998  else if (0 != unlink (fn))
1001  "unlink",
1002  fn);
1003 
1004  GNUNET_free (writebuffer);
1005  return GNUNET_OK;
1006 }
1007 
1008 
1015 static void
1017 {
1018  struct GNUNET_TIME_Absolute now;
1019 
1020  (void) cls;
1021  cron_clean = NULL;
1022  now = GNUNET_TIME_absolute_get ();
1024  _ ("Cleaning up directory `%s'\n"),
1029  NULL);
1030 }
1031 
1032 
1040 static int
1041 check_hello (void *cls, const struct GNUNET_HELLO_Message *hello)
1042 {
1043  struct GNUNET_PeerIdentity pid;
1044 
1045  (void) cls;
1046  if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid))
1047  {
1048  GNUNET_break (0);
1049  return GNUNET_SYSERR;
1050  }
1051  return GNUNET_OK;
1052 }
1053 
1054 
1061 static void
1062 handle_hello (void *cls, const struct GNUNET_HELLO_Message *hello)
1063 {
1064  struct GNUNET_SERVICE_Client *client = cls;
1065  struct GNUNET_PeerIdentity pid;
1066 
1067  GNUNET_assert (GNUNET_OK == GNUNET_HELLO_get_id (hello, &pid));
1069  "HELLO message received for peer `%s'\n",
1070  GNUNET_i2s (&pid));
1071  add_host_to_known_hosts (&pid);
1072  update_hello (&pid, hello);
1074 }
1075 
1076 
1083 static void
1084 handle_get (void *cls, const struct ListPeerMessage *lpm)
1085 {
1086  struct GNUNET_SERVICE_Client *client = cls;
1087  struct TransmitContext tcx;
1088  struct GNUNET_MessageHeader *msg;
1089  struct GNUNET_MQ_Envelope *env;
1090 
1092  "GET message received for peer `%s'\n",
1093  GNUNET_i2s (&lpm->peer));
1094  tcx.friend_only = ntohl (lpm->include_friend_only);
1095  tcx.client = client;
1097  &lpm->peer,
1098  &add_to_tc,
1099  &tcx);
1103 }
1104 
1105 
1112 static void
1113 handle_get_all (void *cls, const struct ListAllPeersMessage *lapm)
1114 {
1115  struct GNUNET_SERVICE_Client *client = cls;
1116  struct TransmitContext tcx;
1117  struct GNUNET_MQ_Envelope *env;
1118  struct GNUNET_MessageHeader *msg;
1119 
1120  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GET_ALL message received\n");
1121  tcx.friend_only = ntohl (lapm->include_friend_only);
1122  tcx.client = client;
1127 }
1128 
1129 
1136 static void
1137 handle_notify (void *cls, const struct NotifyMessage *nm)
1138 {
1139  struct GNUNET_SERVICE_Client *client = cls;
1140  struct GNUNET_MQ_Handle *mq;
1141  struct TransmitContext tcx;
1142  struct GNUNET_MQ_Envelope *env;
1143  struct GNUNET_MessageHeader *msg;
1144 
1145  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "NOTIFY message received\n");
1146  mq = GNUNET_SERVICE_client_get_mq (client);
1148  if (ntohl (nm->include_friend_only))
1149  GNUNET_notification_context_add (notify_friend_only_list, mq);
1150  else
1151  GNUNET_notification_context_add (notify_list, mq);
1152  tcx.friend_only = ntohl (nm->include_friend_only);
1153  tcx.client = client;
1158 }
1159 
1160 
1169 static void *
1171  struct GNUNET_SERVICE_Client *client,
1172  struct GNUNET_MQ_Handle *mq)
1173 {
1174  (void) cls;
1175  (void) mq;
1176  return client;
1177 }
1178 
1179 
1187 static void
1189  struct GNUNET_SERVICE_Client *client,
1190  void *app_ctx)
1191 {
1192  (void) cls;
1193  GNUNET_assert (app_ctx == client);
1194 }
1195 
1196 
1205 static int
1206 free_host_entry (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
1207 {
1208  struct HostEntry *he = value;
1209 
1210  (void) cls;
1211  (void) key;
1214  GNUNET_free (he);
1215  return GNUNET_YES;
1216 }
1217 
1218 
1224 static void
1225 shutdown_task (void *cls)
1226 {
1227  (void) cls;
1229  notify_list = NULL;
1230  GNUNET_notification_context_destroy (notify_friend_only_list);
1231  notify_friend_only_list = NULL;
1232 
1235  if (NULL != stats)
1236  {
1238  stats = NULL;
1239  }
1240  if (NULL != cron_clean)
1241  {
1242  GNUNET_SCHEDULER_cancel (cron_clean);
1243  cron_clean = NULL;
1244  }
1245  if (NULL != cron_scan)
1246  {
1247  GNUNET_SCHEDULER_cancel (cron_scan);
1248  cron_scan = NULL;
1249  }
1250  if (NULL != networkIdDirectory)
1251  {
1253  networkIdDirectory = NULL;
1254  }
1255 }
1256 
1257 
1265 static void
1266 run (void *cls,
1267  const struct GNUNET_CONFIGURATION_Handle *cfg,
1269 {
1270  char *peerdir;
1271  char *ip;
1272  struct DirScanContext dsc;
1273  int noio;
1274  int use_included;
1275 
1276  (void) cls;
1277  (void) service;
1279  stats = GNUNET_STATISTICS_create ("peerinfo", cfg);
1280  notify_list = GNUNET_notification_context_create (0);
1281  notify_friend_only_list = GNUNET_notification_context_create (0);
1282  noio = GNUNET_CONFIGURATION_get_value_yesno (cfg, "peerinfo", "NO_IO");
1283  use_included = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1284  "peerinfo",
1285  "USE_INCLUDED_HELLOS");
1286  if (GNUNET_SYSERR == use_included)
1287  use_included = GNUNET_NO;
1289  if (GNUNET_YES != noio)
1290  {
1291  GNUNET_assert (
1292  GNUNET_OK ==
1294  "peerinfo",
1295  "HOSTS",
1296  &networkIdDirectory));
1298  {
1300  return;
1301  }
1302 
1303  cron_scan =
1306  NULL);
1307 
1308  cron_clean =
1311  NULL);
1312  if (GNUNET_YES == use_included)
1313  {
1315  GNUNET_asprintf (&peerdir, "%shellos", ip);
1316  GNUNET_free (ip);
1317 
1319  _ ("Importing HELLOs from `%s'\n"),
1320  peerdir);
1321  dsc.matched = 0;
1322  dsc.remove_files = GNUNET_NO;
1323 
1324  GNUNET_DISK_directory_scan (peerdir,
1326  &dsc);
1327  GNUNET_free (peerdir);
1328  }
1329  else
1330  {
1332  _ ("Skipping import of included HELLOs\n"));
1333  }
1334  }
1335 }
1336 
1337 
1342  "peerinfo",
1344  &run,
1347  NULL,
1348  GNUNET_MQ_hd_var_size (hello,
1350  struct GNUNET_HELLO_Message,
1351  NULL),
1354  struct ListPeerMessage,
1355  NULL),
1356  GNUNET_MQ_hd_fixed_size (get_all,
1358  struct ListAllPeersMessage,
1359  NULL),
1362  struct NotifyMessage,
1363  NULL),
1365 
1366 
1367 /* 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:74
#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:51
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:544
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:671
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:75
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
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.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
uint32_t include_friend_only
Include friend only HELLOs and peers in callbacks.
Definition: peerinfo.h:91
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:57
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:1183
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:2437
int GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:589
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
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:102
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:418
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 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_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#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:684
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:78
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:75
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:912
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:526
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:160
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:880
#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 GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
struct GNUNET_PeerIdentity peer
About which peer are we talking here?
Definition: peerinfo.h:117
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:250
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:1253
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:1207
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.
#define DIR_SEPARATOR_STR
Definition: platform.h:168
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:2407
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:107
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
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.
#define DIR_SEPARATOR
Definition: platform.h:167
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:76
static unsigned int size
Size of the "table".
Definition: peer.c:67
static struct GNUNET_STATISTICS_Handle * stats
Handle for reporting statistics.
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:257
#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:121
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:499
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:189
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:64
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 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:41
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:77
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:137
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 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:2243
#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:794
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:81
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966