GNUnet 0.28.1-dev.4-46-g92a0edb0d
 
Loading...
Searching...
No Matches
gnunet-daemon-topology.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2007-2016, 2026 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
30#include "platform.h"
31#include "gnunet_util_lib.h"
33#include "gnunet_constants.h"
34#include "gnunet_core_service.h"
35#include "gnunet_pils_service.h"
36#include "gnunet_protocols.h"
40#include <assert.h>
41
42
46#define HELLO_ADVERTISEMENT_MIN_FREQUENCY \
47 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
48
52#define HELLO_ADVERTISEMENT_MIN_REPEAT_FREQUENCY \
53 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
54
58#define RECONSIDER_FREQUENCY \
59 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1)
60
61
116
120struct StoreHelloEntry
121{
125 struct StoreHelloEntry *prev;
126
130 struct StoreHelloEntry *next;
131
136};
137
143
144
150
154static const struct GNUNET_CONFIGURATION_Handle *cfg;
155
160
165
170
175
180
187
192
198
202static unsigned int connection_count;
203
207static unsigned int target_connection_count;
208
213
218
227static int
228free_peer (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
229{
230 struct Peer *pos = value;
231
232 GNUNET_break (NULL == pos->mq);
235 if (NULL != pos->hello_delay_task)
236 {
238 pos->hello_delay_task = NULL;
239 }
240 if (NULL != pos->ash)
241 {
243 pos->ash = NULL;
244 }
245 if (NULL != pos->hello)
246 {
247 GNUNET_free (pos->hello);
248 pos->hello = NULL;
249 }
250 if (NULL != pos->filter)
251 {
253 pos->filter = NULL;
254 }
255 GNUNET_free (pos);
256 return GNUNET_YES;
257}
258
259
266static void
268{
269 uint32_t strength;
271
273 "Checking if we want to attempt connection to `%s'\n",
274 GNUNET_i2s (&pos->pid));
275 if (0 == GNUNET_memcmp (&my_identity, &pos->pid))
276 return; /* This is myself, nothing to do. */
278 strength = 1;
279 else
280 strength = 0;
281 if (NULL != pos->mq)
282 strength *= 2; /* existing connections preferred */
283 if ((strength == pos->strength) &&
284 ((NULL == pos->ash) == (0 == strength)))
285 return; /* nothing changed; re-issuing the suggestion would only reset
286 the retry state transport keeps for it */
287 if (NULL != pos->ash)
288 {
290 pos->ash = NULL;
291 }
292 pos->strength = strength;
293 if (0 != strength)
294 {
296 "Asking to connect to `%s' with strength %u\n",
297 GNUNET_i2s (&pos->pid),
298 (unsigned int) strength);
300 gettext_noop ("# connect requests issued to ATS"),
301 1,
302 GNUNET_NO);
303 // TODO Use strength somehow.
304 bw.value__ = 0;
306 &pos->pid,
308 bw);
309 }
310}
311
312
320static struct Peer *
321make_peer (const struct GNUNET_PeerIdentity *peer,
322 const struct GNUNET_MessageHeader *hello)
323{
324 struct Peer *ret;
325
326 ret = GNUNET_new (struct Peer);
327 ret->pid = *peer;
328 if (NULL != hello)
329 {
330 ret->hello = GNUNET_malloc (ntohs (hello->size));
331 GNUNET_memcpy (ret->hello, hello, ntohs (hello->size));
332 }
335 peers,
336 peer,
337 ret,
339 return ret;
340}
341
342
348static void
349setup_filter (struct Peer *peer)
350{
351 struct GNUNET_HashCode hc;
352
353 /* 2^{-5} chance of not sending a HELLO to a peer is
354 * acceptably small (if the filter is 50% full);
355 * 64 bytes of memory are small compared to the rest
356 * of the data structure and would only really become
357 * "useless" once a HELLO has been passed on to ~100
358 * other peers, which is likely more than enough in
359 * any case; hence 64, 5 as bloomfilter parameters. */peer->filter = GNUNET_CONTAINER_bloomfilter_init (NULL, 64, 5);
360 peer->filter_expiration =
362 /* never send a peer its own HELLO */
363 GNUNET_CRYPTO_hash (&peer->pid, sizeof(struct GNUNET_PeerIdentity), &hc);
365}
366
367
372{
376 struct Peer *peer;
377
381 struct Peer *result;
382
386 size_t max_size;
387
389};
390
391
400static int
402 const struct GNUNET_PeerIdentity *pid,
403 void *value)
404{
405 struct FindAdvHelloContext *fah = cls;
406 struct Peer *pos = value;
407 struct GNUNET_TIME_Relative rst_time;
408 struct GNUNET_HashCode hc;
409 size_t hs;
410
412 "find_advertisable_hello\n");
413 if (pos == fah->peer)
414 return GNUNET_YES;
416 "find_advertisable_hello 2\n");
417 if (pos->hello == NULL)
418 return GNUNET_YES;
420 "find_advertisable_hello 3\n");
422 if (0 == rst_time.rel_value_us)
423 {
424 /* time to discard... */
426 setup_filter (pos);
427 }
428 fah->next_adv = GNUNET_TIME_relative_min (rst_time, fah->next_adv);
429 hs = pos->hello->size;
430 if (hs > fah->max_size)
431 return GNUNET_YES;
433 "find_advertisable_hello 4\n");
435 sizeof(struct GNUNET_PeerIdentity),
436 &hc);
438 fah->result = pos;
439 return GNUNET_YES;
440}
441
442
449static void
451{
452 struct Peer *pl = cls;
453 struct FindAdvHelloContext fah;
454 struct GNUNET_MQ_Envelope *env;
455 size_t want;
456 struct GNUNET_TIME_Relative delay;
457 struct GNUNET_HashCode hc;
458
460 "schedule_next_hello\n");
461 pl->hello_delay_task = NULL;
462 GNUNET_assert (NULL != pl->mq);
463 /* find applicable HELLOs */
464 fah.peer = pl;
465 fah.result = NULL;
469 if (NULL == fah.result)
470 {
471 pl->hello_delay_task =
473
474 return;
475 }
476 want = ntohs (fah.result->hello->size);
478 "Sending HELLO with %u bytes for peer %s\n",
479 (unsigned int) want,
480 GNUNET_i2s (&pl->pid));
482 GNUNET_MQ_send (pl->mq, env);
483
484 /* avoid sending this one again soon */
485 GNUNET_CRYPTO_hash (&pl->pid, sizeof(struct GNUNET_PeerIdentity), &hc);
487
489 gettext_noop ("# HELLO messages gossipped"),
490 1,
491 GNUNET_NO);
492 /* prepare to send the next one */
498}
499
500
511static int
513 const struct GNUNET_PeerIdentity *pid,
514 void *value)
515{
516 struct Peer *peer = value;
517 (void) cls;
518
520 "Reschedule for `%s'\n",
521 GNUNET_i2s (&peer->pid));
522 if (NULL == peer->mq)
523 return GNUNET_YES;
524 if (NULL != peer->hello_delay_task)
525 {
527 peer->hello_delay_task = NULL;
528 }
530 "Schedule_next_hello\n");
531 peer->hello_delay_task =
533 return GNUNET_YES;
534}
535
536
546static void *
547connect_notify (void *cls,
548 const struct GNUNET_PeerIdentity *peer,
549 struct GNUNET_MQ_Handle *mq,
550 enum GNUNET_CORE_PeerClass class)
551{
552 struct Peer *pos;
553
555 "Core told us that we are connecting to `%s'\n",
556 GNUNET_i2s (peer));
557 if (0 == GNUNET_memcmp (&my_identity, peer))
558 return NULL;
562 gettext_noop ("# peers connected"),
564 GNUNET_NO);
566 if (NULL == pos)
567 {
568 pos = make_peer (peer, NULL);
569 }
570 else
571 {
572 GNUNET_assert (NULL == pos->mq);
573 }
574 pos->mq = mq;
575 reschedule_hellos (NULL, peer, pos);
576 return pos;
577}
578
579
588static int
589try_add_peers (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
590{
591 struct Peer *pos = value;
592
593 attempt_connect (pos);
594 return GNUNET_YES;
595}
596
597
603static void
604add_peer_task (void *cls)
605{
606 add_task = NULL;
607
609 /* Keep going. A suggestion that did not work out produces no event of
610 its own -- the peer simply never connects -- so without a periodic
611 re-run the only things that ever call attempt_connect() again are a
612 CORE disconnect and a HELLO showing up in PEERSTORE. A peer we cannot
613 reach delivers neither, and a peer whose HELLO we learned while we were
614 already at the target connection count never gets a suggestion at
615 all. */
618 NULL);
619}
620
621
629static void
631 const struct GNUNET_PeerIdentity *peer,
632 void *internal_cls)
633{
634 struct Peer *pos = internal_cls;
635
636 if (NULL == pos)
637 return; /* myself, we're shutting down */
639 "Core told us that we disconnected from `%s'\n",
640 GNUNET_i2s (peer));
641 if (NULL == pos->mq)
642 {
643 GNUNET_break (0);
644 return;
645 }
646 pos->mq = NULL;
648 if (NULL != pos->hello_delay_task)
649 {
651 pos->hello_delay_task = NULL;
652 }
654 gettext_noop ("# peers connected"),
656 GNUNET_NO);
658 {
659 /* Do not wait for the next periodic run. */
660 if (NULL != add_task)
663 }
664}
665
666
674static void
676 const struct GNUNET_PeerIdentity *pid,
677 const char *uri)
678{
679 int *flag = cls;
680 (void) pid;
681
682 *flag = *flag + 1;
683 // *flag = GNUNET_YES;
684}
685
686
693static void
695{
696 int num_addresses_old = 0;
697 int num_addresses_new = 0;
698 struct GNUNET_HELLO_Parser *parser;
699 const struct GNUNET_PeerIdentity *pid;
700 struct Peer *peer;
701 uint16_t size;
702
703 parser = GNUNET_HELLO_parser_from_msg (hello, NULL);
704 if (NULL == parser)
705 {
706 return;
707 }
710 &num_addresses_new);
712 "consider 0 for %s\n",
713 GNUNET_i2s (pid));
714 if (0 == num_addresses_new)
715 {
717 return; /* no point in advertising this one... */
718 }
720 if (NULL == peer)
721 {
722 peer = make_peer (pid, hello);
723 }
724 else if (NULL != peer->hello)
725 {
727 struct GNUNET_TIME_Absolute new_hello_exp =
729 struct GNUNET_TIME_Absolute old_hello_exp =
731 struct GNUNET_HELLO_Parser *parser_old =
732 GNUNET_HELLO_parser_from_msg (peer->hello, &peer->pid);
733
734 GNUNET_HELLO_parser_iterate (parser_old,
736 &num_addresses_old);
737 GNUNET_HELLO_parser_free (parser_old);
738 if (GNUNET_TIME_absolute_cmp (new_hello_exp, >, now) &&
739 (GNUNET_TIME_absolute_cmp (new_hello_exp, >, old_hello_exp) ||
740 num_addresses_old < num_addresses_new))
741 {
742 GNUNET_free (peer->hello);
743 size = ntohs (hello->size);
744 peer->hello = GNUNET_malloc (size);
745 GNUNET_memcpy (peer->hello, hello, size);
746 }
747 else
748 {
750 "consider 3\n");
752 return;
753 }
754 }
755 else
756 {
757 size = ntohs (hello->size);
758 peer->hello = GNUNET_malloc (size);
759 GNUNET_memcpy (peer->hello, hello, size);
760 }
762 "Found HELLO from peer `%s' for advertising\n",
763 GNUNET_i2s (pid));
764 if (NULL != peer->filter)
765 {
767 peer->filter = NULL;
768 }
769 setup_filter (peer);
770 /* since we have a new HELLO to pick from, re-schedule all
771 * HELLO requests that are not bound by the HELLO send rate! */
774}
775
776
777static void
778error_cb (void *cls)
779{
781 _ (
782 "Error in communication with PEERSTORE service to monitor.\n"));
783 return;
784}
785
786
787static void
788sync_cb (void *cls)
789{
791 _ ("Finished initial PEERSTORE iteration in monitor.\n"));
792 return;
793}
794
795
805static void
806process_peer (void *cls,
807 const struct GNUNET_PEERSTORE_Record *record,
808 const char *err_msg)
809{
810 struct Peer *pos;
811 struct GNUNET_MessageHeader *hello;
812
813 if (NULL != err_msg)
814 {
816 _ ("Error in communication with PEERSTORE service: %s\n"),
817 err_msg);
822 "peerstore",
823 NULL,
825 error_cb,
826 NULL,
827 sync_cb,
828 NULL,
830 NULL);
831 return;
832 }
833 GNUNET_assert (NULL != record);
835 "Processing HELLO from peerstore from peer `%s'\n",
836 GNUNET_i2s (&record->peer));
837 hello = record->value;
838 if (NULL == hello)
839 {
840 /* free existing HELLO, if any */
842 if (NULL != pos)
843 {
844 GNUNET_free (pos->hello);
845 pos->hello = NULL;
846 if (NULL != pos->filter)
847 {
849 pos->filter = NULL;
850 }
851 if (NULL == pos->mq)
852 free_peer (NULL, &pos->pid, pos);
853 }
855 return;
856 }
859 if (NULL == pos)
860 pos = make_peer (&record->peer, hello);
861 attempt_connect (pos);
863}
864
865
866static void
867start_notify (void *cls)
868{
869 (void) cls;
870
872 "Starting to process new hellos for gossiping.\n");
876 "peerstore",
877 NULL,
879 &error_cb,
880 NULL,
881 &sync_cb,
882 NULL,
884 NULL);
885}
886
887
888static void
889pid_change_cb (void *cls,
890 const struct GNUNET_HELLO_Parser *parser,
891 const struct GNUNET_HashCode *addr_hash)
892{
894}
895
896
904static void
905core_init (void *cls, const struct GNUNET_PeerIdentity *my_id)
906{
907 if (NULL == my_id)
908 {
909 GNUNET_log (
911 _ ("Failed to connect to core service, can not manage topology!\n"));
913 return;
914 }
915 my_identity = *my_id;
916 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "I am peer `%s'\n", GNUNET_i2s (my_id));
920 NULL);
921}
922
923
933static int
934check_hello (void *cls, const struct GNUNET_MessageHeader *msg)
935{
937 const struct GNUNET_PeerIdentity *pid = GNUNET_HELLO_parser_get_id (parser);
938
939 if (NULL == pid)
940 {
941 GNUNET_break_op (0);
942 return GNUNET_SYSERR;
943 }
944 return GNUNET_OK;
945}
946
947
948static void
949shc_cont (void *cls, int success)
950{
951 struct StoreHelloEntry *she = cls;
952
953 she->sc = NULL;
954 if (GNUNET_YES == success)
956 "Hello stored successfully!\n");
957 else
959 "Error storing hello!\n");
961 GNUNET_free (she);
962}
963
964
972static void
973handle_hello (void *cls, const struct GNUNET_MessageHeader *msg)
974{
975 struct StoreHelloEntry *she;
976 const struct GNUNET_PeerIdentity *other = cls;
977 struct GNUNET_HELLO_Parser *parser;
978
980 "Received encrypted HELLO from peer `%s'\n",
981 GNUNET_i2s (other));
983 gettext_noop ("# HELLO messages received"),
984 1,
985 GNUNET_NO);
986 parser = GNUNET_HELLO_parser_from_msg (msg, NULL);
987 she = GNUNET_new (struct StoreHelloEntry);
989 if (NULL != she->sc)
990 {
992 }
993 else
994 GNUNET_free (she);
996}
997
998
1005static void
1006cleaning_task (void *cls)
1007{
1008 struct StoreHelloEntry *pos;
1009
1010 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Topology shutdown\n");
1011 while (NULL != (pos = she_head))
1012 {
1014 if (NULL != pos->sc)
1016 GNUNET_free (pos);
1017 }
1018 if (NULL != peerstore_notify)
1019 {
1021 peerstore_notify = NULL;
1022 }
1023 else if (NULL != peerstore_notify_task)
1024 {
1026 }
1027 if (NULL != pils)
1028 {
1030 pils = NULL;
1031 }
1032 if (NULL != handle)
1033 {
1035 handle = NULL;
1036 }
1037 if (NULL != add_task)
1038 {
1040 add_task = NULL;
1041 }
1044 peers = NULL;
1045 if (NULL != transport)
1046 {
1048 transport = NULL;
1049 }
1050 if (NULL != ps)
1051 {
1053 ps = NULL;
1054 }
1055 if (NULL != stats)
1056 {
1058 stats = NULL;
1059 }
1060}
1061
1062
1071static void
1072run (void *cls,
1073 char *const *args,
1074 const char *cfgfile,
1075 const struct GNUNET_CONFIGURATION_Handle *c)
1076{
1078 { GNUNET_MQ_hd_var_size (hello,
1080 struct GNUNET_MessageHeader,
1081 NULL),
1083 unsigned long long opt;
1084 const struct GNUNET_CORE_ServiceInfo service_info = {
1086 .version = { 1, 0 },
1087 .version_max = { 1, 0 },
1088 .version_min = { 1, 0 },
1089 };
1090
1091 cfg = c;
1092 stats = GNUNET_STATISTICS_create ("topology", cfg);
1093
1094 if (GNUNET_OK !=
1096 "TOPOLOGY",
1097 "TARGET-CONNECTION-COUNT",
1098 &opt))
1099 opt = 16;
1100 target_connection_count = (unsigned int) opt;
1102 GNUNET_NO);
1106 NULL,
1107 &core_init,
1110 handlers,
1111 &service_info);
1114 if (NULL == pils)
1115 {
1117 _ ("Failed to connect to `%s' service.\n"),
1118 "pils");
1120 return;
1121 }
1122 if (NULL == handle)
1123 {
1125 _ ("Failed to connect to `%s' service.\n"),
1126 "core");
1128 return;
1129 }
1132 NULL);
1133}
1134
1135
1143int
1144main (int argc, char *const *argv)
1145{
1146 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1148 };
1149 int ret;
1150
1151 ret = (GNUNET_OK ==
1153 argc,
1154 argv,
1155 "gnunet-daemon-topology",
1156 _ ("GNUnet topology control"),
1157 options,
1158 &run,
1159 NULL))
1160 ? 0
1161 : 1;
1162 return ret;
1163}
1164
1165
1166#if defined(__linux__) && defined(__GLIBC__)
1167#include <malloc.h>
1168
1169void __attribute__ ((constructor))
1170GNUNET_TOPOLOGY_memory_init (void);
1171
1175void __attribute__ ((constructor))
1176GNUNET_TOPOLOGY_memory_init (void)
1177{
1178 mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1179 mallopt (M_TOP_PAD, 1 * 1024);
1180 malloc_trim (0);
1181}
1182
1183
1184#endif
1185
1186/* end of gnunet-daemon-topology.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
struct GNUNET_MQ_MessageHandlers handlers[]
Definition 003.c:1
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
int main()
Program to simulate results from GCP_get_desirability_of_path() for various plausible inputs.
#define gettext_noop(String)
Definition gettext.h:74
static int ret
Final status code.
Definition gnunet-arm.c:93
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static struct GNUNET_CORE_Handle * handle
Handle to the CORE service.
static struct GNUNET_CONTAINER_MultiPeerMap * peers
All of our current neighbours and all peers for which we have HELLOs.
static void handle_hello(void *cls, const struct GNUNET_MessageHeader *msg)
This function is called whenever an encrypted HELLO message is received.
static int check_hello(void *cls, const struct GNUNET_MessageHeader *msg)
This function is called whenever an encrypted HELLO message is received.
static void sync_cb(void *cls)
static void cleaning_task(void *cls)
Last task run during shutdown.
static void add_peer_task(void *cls)
Add peers and schedule connection attempt.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
static void consider_for_advertising(const struct GNUNET_MessageHeader *hello)
We've gotten a HELLO from another peer.
static unsigned int target_connection_count
Target number of connections.
static void schedule_next_hello(void *cls)
Calculate when we would like to send the next HELLO to this peer and ask for it.
static struct GNUNET_PEERSTORE_Handle * ps
Handle to the PEERSTORE service.
static struct GNUNET_PEERSTORE_Monitor * peerstore_notify
Our peerstore notification context.
static void disconnect_notify(void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
Method called whenever a peer disconnects.
static struct GNUNET_STATISTICS_Handle * stats
Handle for reporting statistics.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static void address_iterator(void *cls, const struct GNUNET_PeerIdentity *pid, const char *uri)
Iterator called on each address.
static unsigned int connection_count
Number of peers that we are currently connected to.
static struct StoreHelloEntry * she_head
Head of the linkd list to store the store context for hellos.
static void start_notify(void *cls)
static struct StoreHelloEntry * she_tail
Tail of the linkd list to store the store context for hellos.
struct GNUNET_SCHEDULER_Task * peerstore_notify_task
The task to delayed start the notification process initially.
static void process_peer(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *err_msg)
PEERSTORE calls this function to let us know about a possible peer that we might want to connect to.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run.
static void core_init(void *cls, const struct GNUNET_PeerIdentity *my_id)
Function called after GNUNET_CORE_connect has succeeded (or failed for good).
static void shc_cont(void *cls, int success)
#define HELLO_ADVERTISEMENT_MIN_REPEAT_FREQUENCY
After what time period do we expire the HELLO Bloom filter?
static int reschedule_hellos(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Cancel existing requests for sending HELLOs to this peer and recalculate when we should send HELLOs t...
static void pid_change_cb(void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *addr_hash)
struct GNUNET_TRANSPORT_ApplicationHandle * transport
Handle to Transport service.
#define HELLO_ADVERTISEMENT_MIN_FREQUENCY
At what frequency do we sent HELLOs to a peer?
static void setup_filter(struct Peer *peer)
Setup bloom filter for the given peer entry.
#define RECONSIDER_FREQUENCY
How often do we reconsider which peers we would like to be connected to?
static int free_peer(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Free all resources associated with the given peer.
static void error_cb(void *cls)
static struct GNUNET_SCHEDULER_Task * add_task
Task scheduled to asynchronously reconsider adding/removing peer connectivity suggestions.
static void attempt_connect(struct Peer *pos)
Recalculate how much we want to be connected to the specified peer and let ATS know about the result.
static int find_advertisable_hello(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Find a peer that would be reasonable for advertising.
static struct Peer * make_peer(const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *hello)
Create a new entry in the peer list.
static int try_add_peers(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Try to add more peers to our connection set.
static void * connect_notify(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq, enum GNUNET_CORE_PeerClass class)
Method called whenever a peer connects.
static struct GNUNET_PILS_Handle * pils
Handle to the PILS service.
static char * value
Value of the record to add/remove.
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
Core service; the main API for encrypted P2P communications.
Helper library for handling HELLO URIs.
API to the peerstore service.
struct GNUNET_PILS_Handle * GNUNET_PILS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_PILS_PidChangeCallback pid_change_cb, void *cls)
Connect to the PILS service.
Definition pils_api.c:624
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:647
struct GNUNET_PQ_ResultSpec __attribute__
Constants for network protocols.
API to create, modify and access statistics.
Bandwidth allocation API for applications to interact with.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
struct GNUNET_TRANSPORT_ApplicationSuggestHandle * GNUNET_TRANSPORT_application_suggest(struct GNUNET_TRANSPORT_ApplicationHandle *ch, const struct GNUNET_PeerIdentity *peer, enum GNUNET_MQ_PriorityPreferences pk, struct GNUNET_BANDWIDTH_Value32NBO bw)
An application would like TRANSPORT to connect to a peer.
void GNUNET_TRANSPORT_application_done(struct GNUNET_TRANSPORT_ApplicationHandle *ch)
Shutdown TRANSPORT application client.
void GNUNET_TRANSPORT_application_suggest_cancel(struct GNUNET_TRANSPORT_ApplicationSuggestHandle *sh)
We no longer care about being connected to a peer.
struct GNUNET_TRANSPORT_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to the filter.
bool GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associated with a filter in memory, flush to drive if needed (do not free the space on...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
struct GNUNET_CORE_Handle * GNUNET_CORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls, GNUNET_CORE_StartupCallback init, GNUNET_CORE_ConnectEventHandler connects, GNUNET_CORE_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers, const struct GNUNET_CORE_ServiceInfo *service_info)
Connect to the core service.
Definition core_api.c:698
GNUNET_CORE_PeerClass
The peer class gives a hint about the capabilities of a peer.
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition core_api.c:744
@ GNUNET_CORE_SERVICE_TOPOLOGY
Identifier for topology service.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_GETOPT_OPTION_END
Marker for the end of the list of options.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:40
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
void GNUNET_HELLO_parser_free(struct GNUNET_HELLO_Parser *parser)
Release resources of a builder.
Definition hello-uri.c:380
const struct GNUNET_PeerIdentity * GNUNET_HELLO_parser_iterate(const struct GNUNET_HELLO_Parser *parser, GNUNET_HELLO_UriCallback uc, void *uc_cls)
Iterate over URIs in a parser.
Definition hello-uri.c:1052
struct GNUNET_TIME_Absolute GNUNET_HELLO_get_expiration_time_from_msg(const struct GNUNET_MessageHeader *msg)
Get the expiration time for this HELLO.
Definition hello-uri.c:655
const struct GNUNET_PeerIdentity * GNUNET_HELLO_parser_get_id(const struct GNUNET_HELLO_Parser *parser)
Get the PeerIdentity for this builder.
Definition hello-uri.c:354
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_msg(const struct GNUNET_MessageHeader *msg, const struct GNUNET_PeerIdentity *pid)
Parse msg.
Definition hello-uri.c:416
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_MQ_Envelope * GNUNET_MQ_msg_copy(const struct GNUNET_MessageHeader *hdr)
Create a new envelope by copying an existing message.
Definition mq.c:582
void GNUNET_MQ_set_options(struct GNUNET_MQ_Handle *mq, enum GNUNET_MQ_PriorityPreferences pp)
Set application-specific options for this queue.
Definition mq.c:920
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition mq.c:337
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
@ GNUNET_MQ_PRIO_BEST_EFFORT
Best-effort traffic (e.g.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
void GNUNET_PEERSTORE_monitor_stop(struct GNUNET_PEERSTORE_Monitor *zm)
Stop monitoring.
void GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h)
Disconnect from the PEERSTORE service.
struct GNUNET_PEERSTORE_Monitor * GNUNET_PEERSTORE_monitor_start(const struct GNUNET_CONFIGURATION_Handle *cfg, int iterate_first, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_SCHEDULER_TaskCallback sync_cb, void *sync_cb_cls, GNUNET_PEERSTORE_Processor callback, void *callback_cls)
Request watching a given key The monitoring can be filtered to contain only records matching peer and...
struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the PEERSTORE service.
void GNUNET_PEERSTORE_monitor_next(struct GNUNET_PEERSTORE_Monitor *zm, uint64_t limit)
Calls the monitor processor specified in GNUNET_PEERSTORE_monitor_start for the next record(s).
void GNUNET_PEERSTORE_hello_add_cancel(struct GNUNET_PEERSTORE_StoreHelloContext *huc)
Cancel the request to add a hello.
#define GNUNET_PEERSTORE_HELLO_KEY
Key used for storing HELLO in the peerstore.
struct GNUNET_PEERSTORE_StoreHelloContext * GNUNET_PEERSTORE_hello_add(struct GNUNET_PEERSTORE_Handle *h, const struct GNUNET_MessageHeader *msg, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Add hello to peerstore.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(const struct GNUNET_OS_ProjectData *pd, int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition program.c:406
#define GNUNET_MESSAGE_TYPE_HELLO_URI
Latest HELLO messages used for communicating peer addresses.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:572
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1345
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition time.c:344
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
#define GNUNET_TIME_absolute_cmp(t1, op, t2)
Compare two absolute times.
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
Closure for find_advertisable_hello().
size_t max_size
Maximum HELLO size we can use right now.
struct Peer * peer
Peer we want to advertise to.
struct GNUNET_TIME_Relative next_adv
struct Peer * result
Where to store the result (peer selected for advertising).
32-bit bandwidth used for network exchange by GNUnet, in bytes per second.
uint32_t value__
The actual value (bytes per second).
Internal representation of the hash map.
Context for the core service connection.
Definition core_api.c:78
Gnunet service info - identifying compatibility with a range of version of a service communicating ov...
enum GNUNET_CORE_Service service
Identifier of the service on top of CORE.
Definition of a command line option.
Context for parsing HELLOs.
Definition hello-uri.c:233
struct GNUNET_PeerIdentity pid
Public key of the peer.
Definition hello-uri.c:237
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Message handler for a specific message type.
Header for all communications.
Handle to the PEERSTORE service.
Context for a add hello uri request.
A handle for the PILS service.
Definition pils_api.c:86
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition scheduler.c:141
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Handle to the TRANSPORT subsystem for application management.
Handle for TRANSPORT address suggestion requests.
Record for neighbours and blacklisted peers.
struct GNUNET_PeerIdentity pid
Which peer is this entry about?
struct GNUNET_MessageHeader * hello
Pointer to the hello uri of this peer; can be NULL.
struct GNUNET_TIME_Absolute next_hello_allowed
Next time we are allowed to transmit a HELLO to this peer?
struct GNUNET_CONTAINER_BloomFilter * filter
Bloom filter used to mark which peers already got the HELLO from this peer.
struct GNUNET_SCHEDULER_Task * hello_delay_task
ID of task we use to wait for the time to send the next HELLO to this peer.
struct GNUNET_TIME_Absolute filter_expiration
When should we reset the bloom filter of this entry?
struct GNUNET_TRANSPORT_ApplicationSuggestHandle * ash
Transport suggest handle.
uint32_t strength
How much would we like to connect to this peer?
struct GNUNET_MQ_Handle * mq
Our handle for transmitting to this peer; NULL if peer is not connected.
Context for a add hello uri request.
struct GNUNET_PEERSTORE_StoreHelloContext * sc
Store hello ctx.
struct StoreHelloEntry * prev
Kept (also) in a DLL.
struct StoreHelloEntry * next
Kept (also) in a DLL.