GNUnet 0.26.2-114-g7c6b613e3
 
Loading...
Searching...
No Matches
gnunet-service-nse.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011, 2012, 2013, 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
38#include "gnunet_common.h"
39#include "platform.h"
40#include <math.h>
41#include "gnunet_util_lib.h"
43#include "gnunet_protocols.h"
44#include "gnunet_signatures.h"
46#include "gnunet_core_service.h"
47#include "gnunet_pils_service.h"
48#if ENABLE_NSE_HISTOGRAM
49#include "gnunet_testbed_logger_service.h"
50#endif
51#include "nse.h"
52#include <gcrypt.h>
53
54
59#define USE_RANDOM_DELAYS GNUNET_YES
60
64#define DEBUG_NSE GNUNET_NO
65
69#define HISTORY_SIZE 64
70
75#define NSE_PRIORITY \
76 (GNUNET_MQ_PRIO_BACKGROUND | GNUNET_MQ_PREF_UNRELIABLE \
77 | GNUNET_MQ_PREF_CORK_ALLOWED)
78
79#ifdef BSD
80#define log2(a) (log (a) / log (2))
81#endif
82
86static unsigned long long nse_work_required;
87
92
97
98#if ENABLE_NSE_HISTOGRAM
99
103struct GNUNET_CLIENT_TestHandle *logger_test;
104
108static struct GNUNET_TESTBED_LOGGER_Handle *lh;
109
113static struct GNUNET_BIO_WriteHandle *histogram;
114
115#endif
116
120static struct GNUNET_CRYPTO_PowSalt salt = { "gnunet-nse-proof" };
121
122
127{
132
136 const struct GNUNET_PeerIdentity *id;
137
142
147
152
159
160#if ENABLE_NSE_HISTOGRAM
164 unsigned int received_messages;
165
169 unsigned int transmitted_messages;
170
174 unsigned int last_transmitted_size;
175#endif
176};
177
178
180
232
236static const struct GNUNET_CONFIGURATION_Handle *cfg;
237
242
247
252
257
263
268static double current_std_dev = NAN;
269
273static uint32_t hop_count_max;
274
279
284
288static unsigned int estimate_index;
289
293static unsigned int estimate_count;
294
299
304
309
314
319
323static uint64_t my_proof;
324
325
332static void
334{
335 double mean;
336 double sum;
337 double std_dev;
338 double variance;
339 double val;
340 double nsize;
341
342#define WEST 1
343 /* Weighted incremental algorithm for stddev according to West (1979) */
344#if WEST
345 double sumweight;
346 double weight;
347 double q;
348 double r;
349 double temp;
350
351 mean = 0.0;
352 sum = 0.0;
353 sumweight = 0.0;
354 variance = 0.0;
355 for (unsigned int i = 0; i < estimate_count; i++)
356 {
357 unsigned int j = (estimate_index - i + HISTORY_SIZE) % HISTORY_SIZE;
358
359 val = htonl (size_estimate_messages[j].matching_bits);
360 weight = estimate_count + 1 - i;
361
362 temp = weight + sumweight;
363 q = val - mean;
364 r = q * weight / temp;
365 mean += r;
366 sum += sumweight * q * r;
367 sumweight = temp;
368 }
369 if (estimate_count > 0)
370 variance = (sum / sumweight) * estimate_count / (estimate_count - 1.0);
371#else
372 /* trivial version for debugging */
373 double vsq;
374
375 /* non-weighted trivial version */
376 sum = 0.0;
377 vsq = 0.0;
378 variance = 0.0;
379 mean = 0.0;
380
381 for (unsigned int i = 0; i < estimate_count; i++)
382 {
383 unsigned int j = (estimate_index - i + HISTORY_SIZE) % HISTORY_SIZE;
384
385 val = htonl (size_estimate_messages[j].matching_bits);
386 sum += val;
387 vsq += val * val;
388 }
389 if (0 != estimate_count)
390 {
391 mean = sum / estimate_count;
392 variance = (vsq - mean * sum)
393 / (estimate_count - 1.0); // terrible for numerical stability...
394 }
395#endif
396 if (variance >= 0)
397 std_dev = sqrt (variance);
398 else
399 std_dev = variance; /* return NaN (due to estimate_count == 0 causing 0.0/0.0) */
400 current_std_dev = std_dev;
402
403 em->header.size = htons (sizeof(struct GNUNET_NSE_ClientMessage));
405 em->reserved = htonl (0);
407 {
408 double se = mean - 0.332747;
409 unsigned int j = GNUNET_CONTAINER_multipeermap_size (peers);
410 if (0 == j)
411 j = 1; /* Avoid log2(0); can only happen if CORE didn't report
412 connection to self yet */
413 nsize = log2 (j);
414 em->size_estimate = GNUNET_hton_double (GNUNET_MAX (se, nsize));
415 em->std_deviation = GNUNET_hton_double (std_dev);
417 "# nodes in the network (estimate)",
418 (uint64_t) pow (2, GNUNET_MAX (se, nsize)),
419 GNUNET_NO);
420 }
421}
422
423
433static void
434handle_start (void *cls, const struct GNUNET_MessageHeader *message)
435{
436 struct GNUNET_SERVICE_Client *client = cls;
437 struct GNUNET_MQ_Handle *mq;
438 struct GNUNET_NSE_ClientMessage em;
439 struct GNUNET_MQ_Envelope *env;
440
441 (void) message;
442 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received START message from client\n");
449}
450
451
458static double
460{
461 /* Calculated as: S + f/2 - (f / pi) * (atan(x - p')) */
462 // S is next_timestamp (ignored in return value)
463 // f is frequency (gnunet_nse_interval)
464 // x is matching_bits
465 // p' is current_size_estimate
466 return ((double) gnunet_nse_interval.rel_value_us / (double) 2.0)
469}
470
471
478static struct GNUNET_TIME_Relative
480{
481#if USE_RANDOM_DELAYS
483 uint32_t i;
484 double d;
485
487 i = (uint32_t) (d / (double) (hop_count_max + 1));
488 ret.rel_value_us = i;
490 "Randomizing flood using latencies up to %s\n",
492 ret.rel_value_us =
494 return ret;
495#else
497#endif
498}
499
500
508static uint32_t
510 const struct GNUNET_PeerIdentity *id)
511{
512 struct GNUNET_HashCode timestamp_hash;
513 struct GNUNET_HashCode pid_hash;
514 struct GNUNET_HashCode xor;
515
516 GNUNET_CRYPTO_hash (&timestamp.abs_value_us,
517 sizeof(timestamp.abs_value_us),
518 &timestamp_hash);
520 sizeof(struct GNUNET_PeerIdentity),
521 &pid_hash);
522 GNUNET_CRYPTO_hash_xor (&pid_hash,
523 &timestamp_hash,
524 &xor);
526}
527
528
537static struct GNUNET_TIME_Relative
538get_transmit_delay (int round_offset)
539{
541 struct GNUNET_TIME_Absolute tgt;
542 double dist_delay;
543 uint32_t matching_bits;
544
545 switch (round_offset)
546 {
547 case -1:
548 /* previous round is randomized between 0 and 50 ms */
549#if USE_RANDOM_DELAYS
550 ret.rel_value_us =
552#else
554#endif
556 "Transmitting previous round behind schedule in %s\n",
558 return ret;
559
560 case 0:
561 /* current round is based on best-known matching_bits */
566 ret.rel_value_us = (uint64_t) dist_delay;
568 "For round %s, delay for %u matching bits is %s\n",
570 (unsigned int) matching_bits,
572 /* now consider round start time and add delay to it */
575 }
576 GNUNET_break (0);
578}
579
580
581static void
583 const struct GNUNET_PeerIdentity *pid,
584 const struct GNUNET_CRYPTO_EddsaSignature *sig)
585{
586 struct NSEPeerEntry *pe = cls;
587 struct GNUNET_MQ_Envelope *env;
588 struct GNUNET_NSE_FloodMessage *fm;
589
590 pe->pils_op = NULL;
592 fm->signature = *sig;
594 GNUNET_MQ_send (pe->mq, env);
595}
596
597
603static void
605{
606 struct NSEPeerEntry *peer_entry = cls;
607 unsigned int idx;
608
609 peer_entry->transmit_task = NULL;
610 idx = estimate_index;
611 if (GNUNET_NO == peer_entry->previous_round)
612 {
613 idx = (idx + HISTORY_SIZE - 1) % HISTORY_SIZE;
614 peer_entry->previous_round = GNUNET_YES;
615 peer_entry->transmit_task =
618 peer_entry);
619 }
620 if ((0 == ntohl (size_estimate_messages[idx].hop_count)) &&
621 (NULL != proof_task))
622 {
624 "# flood messages not generated (no proof yet)",
625 1,
626 GNUNET_NO);
627 return;
628 }
629 if (0 == ntohs (size_estimate_messages[idx].header.size))
630 {
632 "# flood messages not generated (lack of history)",
633 1,
634 GNUNET_NO);
635 return;
636 }
638 "In round %s, sending to `%s' estimate with %u bits\n",
642 GNUNET_i2s (peer_entry->id),
643 (unsigned int) ntohl (size_estimate_messages[idx].matching_bits));
644 if (0 == ntohl (size_estimate_messages[idx].hop_count))
645 GNUNET_STATISTICS_update (stats, "# flood messages started", 1, GNUNET_NO);
647 "# flood messages transmitted",
648 1,
649 GNUNET_NO);
650#if ENABLE_NSE_HISTOGRAM
651 peer_entry->transmitted_messages++;
652 peer_entry->last_transmitted_size =
654#endif
655 peer_entry->next_index_to_send = idx;
657 pils,
658 &size_estimate_messages[idx].purpose,
660 peer_entry);
661}
662
663
670static void
678
679
687static void
688setup_flood_message (unsigned int slot, struct GNUNET_TIME_Absolute ts)
689{
690 const struct GNUNET_PeerIdentity *my_identity;
691 struct GNUNET_NSE_FloodMessage *fm;
692 uint32_t matching_bits;
693
696
698 fm = &size_estimate_messages[slot];
699 fm->header.size = htons (sizeof(struct GNUNET_NSE_FloodMessage));
701 fm->hop_count = htonl (0);
703 fm->purpose.size =
704 htonl (sizeof(struct GNUNET_NSE_FloodMessage)
705 - sizeof(struct GNUNET_MessageHeader) - sizeof(uint32_t)
706 - sizeof(struct GNUNET_CRYPTO_EddsaSignature));
707 fm->matching_bits = htonl (matching_bits);
709 fm->origin = *my_identity;
711 memset (&fm->signature, 0, sizeof(fm->signature));
712}
713
714
724static int
726 const struct GNUNET_PeerIdentity *key,
727 void *value)
728{
729 struct NSEPeerEntry *peer_entry = value;
730 struct GNUNET_TIME_Relative delay;
731
732 (void) cls;
733 (void) key;
734 if (NULL != peer_entry->transmit_task)
735 {
737 peer_entry->previous_round = GNUNET_NO;
738 }
739#if ENABLE_NSE_HISTOGRAM
740 if (peer_entry->received_messages > 1)
742 "# extra messages",
743 peer_entry->received_messages - 1,
744 GNUNET_NO);
745 peer_entry->transmitted_messages = 0;
746 peer_entry->last_transmitted_size = 0;
747 peer_entry->received_messages = 0;
748#endif
749 delay =
750 get_transmit_delay ((GNUNET_NO == peer_entry->previous_round) ? -1 : 0);
751 peer_entry->transmit_task =
753 return GNUNET_OK;
754}
755
756
762static void
764{
765 const struct GNUNET_PeerIdentity *my_identity;
766 struct GNUNET_TIME_Relative offset;
767
768 (void) cls;
769 flood_task = NULL;
771 if (! my_identity)
772 return;
773
775 if (0 != offset.rel_value_us)
776 {
777 /* somehow run early, delay more */
778 flood_task =
780 return;
781 }
792 {
793 /* we received a message for this round way early, use it! */
796 htonl (1 + ntohl (next_message.hop_count));
797 }
798 else
800 next_message.matching_bits = htonl (0); /* reset for 'next' round */
801 hop_count_max = 0;
802 for (unsigned int i = 0; i < HISTORY_SIZE; i++)
804 GNUNET_MAX (ntohl (size_estimate_messages[i].hop_count), hop_count_max);
806 flood_task =
808}
809
810
821 uint64_t val)
822{
823 char buf[sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)
824 + sizeof(val)] GNUNET_ALIGN;
825 struct GNUNET_HashCode result;
826
827 GNUNET_memcpy (buf, &val, sizeof(val));
828 GNUNET_memcpy (&buf[sizeof(val)],
829 pkey,
830 sizeof(struct GNUNET_CRYPTO_EddsaPublicKey));
832 buf,
833 sizeof(buf),
834 &result);
837 ? GNUNET_YES
838 : GNUNET_NO;
839}
840
841
845static void
847{
848 char *proof;
849
850 if (GNUNET_OK !=
852 "NSE",
853 "PROOFFILE",
854 &proof))
855 return;
857 if (GNUNET_OK !=
859 &my_proof,
860 sizeof(my_proof),
864 "write",
865 proof);
867}
868
869
875static void
876find_proof (void *cls)
877{
878#define ROUND_SIZE 10
879 uint64_t counter;
880 char buf[sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)
881 + sizeof(uint64_t)] GNUNET_ALIGN;
882 struct GNUNET_HashCode result;
883 const struct GNUNET_PeerIdentity *my_identity;
884 unsigned int i;
885
886 (void) cls;
887 proof_task = NULL;
890 GNUNET_memcpy (&buf[sizeof(uint64_t)],
892 sizeof(struct GNUNET_PeerIdentity));
893 i = 0;
894 counter = my_proof;
895 while ((counter != UINT64_MAX) && (i < ROUND_SIZE))
896 {
897 GNUNET_memcpy (buf, &counter, sizeof(uint64_t));
899 buf,
900 sizeof(buf),
901 &result);
902 if (nse_work_required <=
904 {
905 my_proof = counter;
907 "Proof of work found: %llu!\n",
908 (unsigned long long) GNUNET_ntohll (counter));
909 write_proof ();
911 return;
912 }
913 counter++;
914 i++;
915 }
916 if (my_proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE))
917 {
919 "Testing proofs currently at %llu\n",
920 (unsigned long long) counter);
921 /* remember progress every 100 rounds */
922 my_proof = counter;
923 write_proof ();
924 }
925 else
926 {
927 my_proof = counter;
928 }
929 proof_task =
932 &find_proof,
933 NULL);
934}
935
936
946static int
947verify_message_crypto (const struct GNUNET_NSE_FloodMessage *incoming_flood)
948{
949 if (GNUNET_YES != check_proof_of_work (&incoming_flood->origin.public_key,
950 incoming_flood->proof_of_work))
951 {
953 "Proof of work invalid: %llu!\n",
954 (unsigned long long) GNUNET_ntohll (
955 incoming_flood->proof_of_work));
956 GNUNET_break_op (0);
957 return GNUNET_NO;
958 }
959 if ((nse_work_required > 0) &&
960 (GNUNET_OK !=
962 &incoming_flood->purpose,
963 &incoming_flood->signature,
964 &incoming_flood->origin.public_key)))
965 {
966 GNUNET_break_op (0);
967 return GNUNET_NO;
968 }
969 return GNUNET_YES;
970}
971
972
982static int
984 const struct GNUNET_PeerIdentity *key,
985 void *value)
986{
987 struct NSEPeerEntry *exclude = cls;
988 struct NSEPeerEntry *peer_entry = value;
989 struct GNUNET_TIME_Relative delay;
990
991 (void) key;
992 if (peer_entry == exclude)
993 return GNUNET_OK; /* trigger of the update */
994 if (GNUNET_NO == peer_entry->previous_round)
995 {
996 /* still stuck in previous round, no point to update, check that
997 * we are active here though... */
998 if (NULL == peer_entry->transmit_task)
999 {
1000 GNUNET_break (0);
1001 }
1002 return GNUNET_OK;
1003 }
1004 if (NULL != peer_entry->transmit_task)
1005 {
1007 peer_entry->transmit_task = NULL;
1008 }
1009 delay = get_transmit_delay (0);
1010 peer_entry->transmit_task =
1011 GNUNET_SCHEDULER_add_delayed (delay, &transmit_task_cb, peer_entry);
1012 return GNUNET_OK;
1013}
1014
1015
1022static void
1024 const struct GNUNET_NSE_FloodMessage *incoming_flood)
1025{
1026 const struct GNUNET_PeerIdentity *my_identity;
1027 struct NSEPeerEntry *peer_entry = cls;
1028 struct GNUNET_TIME_Absolute ts;
1029 uint32_t matching_bits;
1030 unsigned int idx;
1031
1033 if (! my_identity)
1034 return;
1035
1036#if ENABLE_NSE_HISTOGRAM
1037 {
1038 uint64_t t;
1039
1041 if (NULL != lh)
1042 GNUNET_TESTBED_LOGGER_write (lh, &t, sizeof(uint64_t));
1043 if (NULL != histogram)
1044 GNUNET_BIO_write_int64 (histogram, "histogram-time", t);
1045 }
1046#endif
1047 GNUNET_STATISTICS_update (stats, "# flood messages received", 1, GNUNET_NO);
1048 matching_bits = ntohl (incoming_flood->matching_bits);
1049#if DEBUG_NSE
1050 {
1051 char origin[5];
1052 char pred[5];
1053 struct GNUNET_PeerIdentity os;
1054
1056 sizeof(origin),
1057 "%s",
1058 GNUNET_i2s (&incoming_flood->origin));
1059 GNUNET_snprintf (pred, sizeof(pred), "%s", GNUNET_i2s (peer_entry->id));
1061 "Flood at %s from `%s' via `%s' at `%s' with bits %u\n",
1063 GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp)),
1064 origin,
1065 pred,
1067 (unsigned int) matching_bits);
1068 }
1069#endif
1070
1071#if ENABLE_NSE_HISTOGRAM
1072 peer_entry->received_messages++;
1073 if ((peer_entry->transmitted_messages > 0) &&
1074 (peer_entry->last_transmitted_size >= matching_bits) )
1075 GNUNET_STATISTICS_update (stats, "# cross messages", 1, GNUNET_NO);
1076#endif
1077
1078 ts = GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp);
1080 idx = estimate_index;
1081 else if (ts.abs_value_us ==
1085 {
1087 return; /* ignore, simply too early/late */
1088 if (GNUNET_YES != verify_message_crypto (incoming_flood))
1089 {
1091 "Peer %s is likely ill-configured!\n",
1092 GNUNET_i2s (peer_entry->id));
1093 GNUNET_break_op (0);
1094 return;
1095 }
1096 next_message = *incoming_flood;
1097 return;
1098 }
1099 else
1100 {
1102 "# flood messages discarded (clock skew too large)",
1103 1,
1104 GNUNET_NO);
1105 return;
1106 }
1107 if (0 == (GNUNET_memcmp (peer_entry->id, my_identity)))
1108 {
1109 /* send to self, update our own estimate IF this also comes from us! */
1110 if (0 == GNUNET_memcmp (&incoming_flood->origin, my_identity))
1112 return;
1113 }
1115 {
1116 /* Cancel transmission in the other direction, as this peer clearly has
1117 up-to-date information already. Even if we didn't talk to this peer in
1118 the previous round, we should no longer send it stale information as it
1119 told us about the current round! */
1120 peer_entry->previous_round = GNUNET_YES;
1121 if (idx != estimate_index)
1122 {
1123 /* do not transmit information for the previous round to this peer
1124 anymore (but allow current round) */
1125 return;
1126 }
1127 /* got up-to-date information for current round, cancel transmission to
1128 * this peer altogether */
1129 if (NULL != peer_entry->transmit_task)
1130 {
1132 peer_entry->transmit_task = NULL;
1133 }
1134 return;
1135 }
1137 {
1138 if ((idx < estimate_index) && (peer_entry->previous_round == GNUNET_YES))
1139 {
1140 peer_entry->previous_round = GNUNET_NO;
1141 }
1142 /* push back our result now, that peer is spreading bad information... */
1143 if (NULL != peer_entry->transmit_task)
1145 peer_entry->transmit_task =
1147 /* Not closer than our most recent message, no need to do work here */
1149 "# flood messages ignored (had closer already)",
1150 1,
1151 GNUNET_NO);
1152 return;
1153 }
1154 if (GNUNET_YES != verify_message_crypto (incoming_flood))
1155 {
1156 GNUNET_break_op (0);
1157 return;
1158 }
1161 /* Cancel transmission in the other direction, as this peer clearly has
1162 * up-to-date information already.
1163 */
1164 peer_entry->previous_round = GNUNET_YES;
1165 if (idx == estimate_index)
1166 {
1167 /* cancel any activity for current round */
1168 if (NULL != peer_entry->transmit_task)
1169 {
1171 peer_entry->transmit_task = NULL;
1172 }
1173 }
1174 size_estimate_messages[idx] = *incoming_flood;
1176 htonl (ntohl (incoming_flood->hop_count) + 1);
1178 GNUNET_MAX (ntohl (incoming_flood->hop_count) + 1, hop_count_max);
1180 "# estimated network diameter",
1182 GNUNET_NO);
1183
1184 /* have a new, better size estimate, inform clients */
1186
1187 /* flood to rest */
1190 peer_entry);
1191}
1192
1193
1202static void *
1204 const struct GNUNET_PeerIdentity *peer,
1205 struct GNUNET_MQ_Handle *mq,
1206 enum GNUNET_CORE_PeerClass class)
1207{
1208 struct NSEPeerEntry *peer_entry;
1209
1210 (void) cls;
1212 "Peer `%s' connected to us\n",
1213 GNUNET_i2s (peer));
1214 /* set our default transmission options */
1216 /* create our peer entry for this peer */
1217 peer_entry = GNUNET_new (struct NSEPeerEntry);
1218 peer_entry->id = peer;
1219 peer_entry->mq = mq;
1222 peers,
1223 peer_entry->id,
1224 peer_entry,
1226 peer_entry->transmit_task =
1229 peer_entry);
1230 GNUNET_STATISTICS_update (stats, "# peers connected", 1, GNUNET_NO);
1231 return peer_entry;
1232}
1233
1234
1243static void
1245 const struct GNUNET_PeerIdentity *peer,
1246 void *internal_cls)
1247{
1248 struct NSEPeerEntry *pos = internal_cls;
1249
1250 (void) cls;
1252 "Peer `%s' disconnected from us\n",
1253 GNUNET_i2s (peer));
1256 if (NULL != pos->transmit_task)
1257 {
1259 pos->transmit_task = NULL;
1260 }
1261 GNUNET_free (pos);
1262 GNUNET_STATISTICS_update (stats, "# peers connected", -1, GNUNET_NO);
1263}
1264
1265
1266#if ENABLE_NSE_HISTOGRAM
1274static void
1275flush_comp_cb (void *cls, size_t size)
1276{
1277 (void) cls;
1278 (void) size;
1279 GNUNET_TESTBED_LOGGER_disconnect (lh);
1280 lh = NULL;
1281}
1282
1283
1284#endif
1285
1286
1292static void
1293shutdown_task (void *cls)
1294{
1295 (void) cls;
1296 if (NULL != flood_task)
1297 {
1299 flood_task = NULL;
1300 }
1301 if (NULL != proof_task)
1302 {
1304 proof_task = NULL;
1305 write_proof (); /* remember progress */
1306 }
1307 if (NULL != nc)
1308 {
1310 nc = NULL;
1311 }
1312 if (NULL != core_api)
1313 {
1315 core_api = NULL;
1316 }
1317 if (NULL != stats)
1318 {
1320 stats = NULL;
1321 }
1322 if (NULL != peers)
1323 {
1325 peers = NULL;
1326 }
1327 if (NULL != pils)
1328 {
1330 pils = NULL;
1331 }
1332#if ENABLE_NSE_HISTOGRAM
1333 if (NULL != logger_test)
1334 {
1335 GNUNET_CLIENT_service_test_cancel (logger_test);
1336 logger_test = NULL;
1337 }
1338 if (NULL != lh)
1339 {
1340 GNUNET_TESTBED_LOGGER_flush (lh, &flush_comp_cb, NULL);
1341 }
1342 if (NULL != histogram)
1343 {
1344 GNUNET_BIO_write_close (histogram, NULL);
1345 histogram = NULL;
1346 }
1347#endif
1348}
1349
1350
1351static void
1353 const struct GNUNET_HELLO_Parser *parser,
1354 const struct GNUNET_HashCode *addr_hash)
1355{
1356 const struct GNUNET_PeerIdentity *my_identity;
1357 struct GNUNET_TIME_Absolute now;
1358 struct GNUNET_TIME_Absolute prev_time;
1359
1361
1362 if (NULL != proof_task)
1363 {
1365 proof_task = NULL;
1366 }
1367
1368 if (NULL == my_identity)
1369 {
1371 "Connection to core FAILED!\n");
1373 return;
1374 }
1375 proof_task =
1377 &find_proof,
1378 NULL);
1379 now = GNUNET_TIME_absolute_get ();
1386 estimate_count = 0;
1388 {
1389 int idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE;
1390 prev_time.abs_value_us =
1392 setup_flood_message (idx, prev_time);
1395 }
1396 if (NULL != flood_task)
1398 flood_task =
1400}
1401
1402
1403#if ENABLE_NSE_HISTOGRAM
1412static void
1413status_cb (void *cls, int status)
1414{
1415 (void) cls;
1416 logger_test = NULL;
1417 if (GNUNET_YES != status)
1418 {
1419 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Testbed logger not running\n");
1420 return;
1421 }
1422 if (NULL == (lh = GNUNET_TESTBED_LOGGER_connect (cfg)))
1423 {
1425 "Cannot connect to the testbed logger. Exiting.\n");
1427 }
1428}
1429
1430
1431#endif
1432
1433
1441static void
1442run (void *cls,
1443 const struct GNUNET_CONFIGURATION_Handle *c,
1445{
1446 struct GNUNET_MQ_MessageHandler core_handlers[] =
1447 { GNUNET_MQ_hd_fixed_size (p2p_estimate,
1450 NULL),
1452 char *proof;
1453 const struct GNUNET_CORE_ServiceInfo service_info = {
1455 .version = { 1, 0 },
1456 .version_max = { 1, 0 },
1457 .version_min = { 1, 0 },
1458 };
1459
1460 (void) cls;
1461 (void) service;
1462 cfg = c;
1464 "NSE",
1465 "INTERVAL",
1467 {
1470 return;
1471 }
1473 "NSE",
1474 "WORKDELAY",
1476 {
1479 return;
1480 }
1482 "NSE",
1483 "WORKBITS",
1485 {
1488 return;
1489 }
1490 if (nse_work_required >= sizeof(struct GNUNET_HashCode) * 8)
1491 {
1493 "NSE",
1494 "WORKBITS",
1495 _ ("Value is too large.\n"));
1497 return;
1498 }
1499
1500#if ENABLE_NSE_HISTOGRAM
1501 {
1502 char *histogram_dir;
1503 char *histogram_fn;
1504
1506 "NSE",
1507 "HISTOGRAM_DIR",
1508 &histogram_dir))
1509 {
1511 0 < GNUNET_asprintf (&histogram_fn, "%s/timestamps", histogram_dir));
1512 GNUNET_free (histogram_dir);
1513 histogram = GNUNET_BIO_write_open_file (histogram_fn);
1514 if (NULL == histogram)
1516 "Unable to open histogram file `%s'\n",
1517 histogram_fn);
1518 GNUNET_free (histogram_fn);
1519 }
1520 logger_test = GNUNET_CLIENT_service_test ("testbed-logger",
1521 cfg,
1523 &status_cb,
1524 NULL);
1525 }
1526#endif
1527
1529 if (GNUNET_OK !=
1530 GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "PROOFFILE", &proof))
1531 {
1534 return;
1535 }
1537 (sizeof(my_proof) !=
1539 my_proof = 0;
1541
1544 /* Connect to core service and register core handlers */
1545 core_api =
1546 GNUNET_CORE_connect (cfg, /* Main configuration */
1547 NULL, /* Closure passed to functions */
1548 NULL, /* Call core_init once connected */
1549 &handle_core_connect, /* Handle connects */
1550 &handle_core_disconnect, /* Handle disconnects */
1551 core_handlers, /* Register these handlers */
1552 &service_info);
1553 if (NULL == core_api)
1554 {
1556 return;
1557 }
1559 if (NULL == pils)
1560 {
1561 GNUNET_break (0);
1563 return;
1564 }
1566}
1567
1568
1577static void *
1579 struct GNUNET_SERVICE_Client *c,
1580 struct GNUNET_MQ_Handle *mq)
1581{
1582 (void) cls;
1583 (void) mq;
1584 return c;
1585}
1586
1587
1595static void
1597 struct GNUNET_SERVICE_Client *c,
1598 void *internal_cls)
1599{
1600 (void) cls;
1601 GNUNET_assert (c == internal_cls);
1602}
1603
1604
1609 "nse",
1611 &run,
1614 NULL,
1617 struct GNUNET_MessageHeader,
1618 NULL),
1620
1621
1622#if defined(__linux__) && defined(__GLIBC__)
1623#include <malloc.h>
1624
1625void __attribute__ ((constructor))
1626GNUNET_NSE_memory_init (void);
1627
1631void __attribute__ ((constructor))
1632GNUNET_NSE_memory_init (void)
1633{
1634 mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1635 mallopt (M_TOP_PAD, 1 * 1024);
1636 malloc_trim (0);
1637}
1638
1639
1640#endif
1641
1642
1643/* end of gnunet-service-nse.c */
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static mp_limb_t d[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static int start
Set if we are to start default services (including ARM).
Definition gnunet-arm.c:38
static int ret
Final status code.
Definition gnunet-arm.c:93
static uint64_t timestamp(void)
Get current timestamp.
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_SCHEDULER_Task * shutdown_task
static char * pkey
Public key of the zone to look in, in ASCII.
static struct GNUNET_SCHEDULER_Task * t
Main task.
static char origin[GNUNET_DNSPARSER_MAX_NAME_LENGTH]
Current origin.
static char * value
Value of the record to add/remove.
static int status
The program status; 0 for success.
Definition gnunet-nse.c:39
static int result
Global testing status.
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
static unsigned long long matching_bits
Number of matching bits required for revocation.
static uint64_t proof
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
static struct GNUNET_CONTAINER_MultiPeerMap * peers
Map of all connected peers.
static double current_std_dev
The standard deviation of the last HISTORY_SIZE network size estimates.
static struct GNUNET_NSE_FloodMessage size_estimate_messages[64]
Array of recent size estimate messages.
static void update_flood_message(void *cls)
Update our flood message to be sent (and our timestamps).
static void transmit_task_cb(void *cls)
Task that triggers a NSE P2P transmission.
static int update_flood_times(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Update transmissions for the given peer for the current round based on updated proximity information.
static double get_matching_bits_delay(uint32_t matching_bits)
How long should we delay a message to go the given number of matching bits?
static unsigned int estimate_index
Index of most recent estimate.
static struct GNUNET_TIME_Relative gnunet_nse_interval
Interval for sending network size estimation flood requests.
#define NSE_PRIORITY
Message priority to use.
#define HISTORY_SIZE
Over how many values do we calculate the weighted average?
static enum GNUNET_GenericReturnValue check_proof_of_work(const struct GNUNET_CRYPTO_EddsaPublicKey *pkey, uint64_t val)
Check whether the given public key and integer are a valid proof of work.
static struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
static void setup_estimate_message(struct GNUNET_NSE_ClientMessage *em)
Initialize a message to clients with the current network size estimate.
static struct GNUNET_SCHEDULER_Task * proof_task
Task scheduled to compute our proof.
static struct GNUNET_TIME_Absolute current_timestamp
The current major time.
static void sign_message_before_send_cb(void *cls, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *sig)
static struct GNUNET_NotificationContext * nc
Notification context, simplifies client broadcasts.
static void find_proof(void *cls)
Find our proof of work.
static unsigned int estimate_count
Number of valid entries in the history.
static void update_network_size_estimate()
We've sent on our flood message or one that we received which was validated and closer than ours.
static struct GNUNET_TIME_Relative proof_find_delay
Interval between proof find runs.
static int verify_message_crypto(const struct GNUNET_NSE_FloodMessage *incoming_flood)
An incoming flood message has been received which claims to have more bits matching than any we know ...
static uint64_t my_proof
Proof of work for this peer.
static struct GNUNET_CORE_Handle * core_api
Handle to the core service.
static unsigned long long nse_work_required
Amount of work required (W-bit collisions) for NSE proofs, in collision-bits.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Handle network size estimate clients.
static GNUNET_NETWORK_STRUCT_END const struct GNUNET_CONFIGURATION_Handle * cfg
Handle to our current configuration.
static void setup_flood_message(unsigned int slot, struct GNUNET_TIME_Absolute ts)
Setup a flood message in our history array at the given slot offset for the given timestamp.
static int schedule_current_round(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Schedule transmission for the given peer for the current round based on what we know about the desire...
static uint32_t hop_count_max
Current hop counter estimate (estimate for network diameter).
static struct GNUNET_TIME_Relative get_transmit_delay(int round_offset)
Get the transmission delay that should be applied for a particular round.
#define ROUND_SIZE
static void handle_start(void *cls, const struct GNUNET_MessageHeader *message)
Handler for START message from client, triggers an immediate current network estimate notification.
static struct GNUNET_NSE_FloodMessage next_message
Message for the next round, if we got any.
static struct GNUNET_SCHEDULER_Task * flood_task
Task scheduled to update our flood message for the next round.
static struct GNUNET_TIME_Absolute next_timestamp
The next major time.
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calculations.
static struct GNUNET_TIME_Relative get_delay_randomization(uint32_t matching_bits)
What delay randomization should we apply for a given number of matching bits?
static double current_size_estimate
The current network size estimate.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
Callback called when a client connects to the service.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *c, void *internal_cls)
Callback called when a client disconnected from the service.
static void write_proof(void)
Write our current proof to disk.
static void handle_p2p_estimate(void *cls, const struct GNUNET_NSE_FloodMessage *incoming_flood)
Core handler for size estimate flooding messages.
static void handle_core_disconnect(void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
Method called whenever a peer disconnects.
static void * handle_core_connect(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 uint32_t get_matching_bits(struct GNUNET_TIME_Absolute timestamp, const struct GNUNET_PeerIdentity *id)
Get the number of matching bits that the given timestamp has to the given peer ID.
static void pils_id_change_cb(void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *addr_hash)
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
Core service; the main API for encrypted P2P communications.
Helper library for handling HELLO URIs.
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:465
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:488
struct GNUNET_PILS_Operation * GNUNET_PILS_sign_by_peer_identity(struct GNUNET_PILS_Handle *handle, const struct GNUNET_CRYPTO_SignaturePurpose *purpose, GNUNET_PILS_SignResultCallback cb, void *cb_cls)
Sign data with the peer id.
Definition pils_api.c:528
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:727
struct GNUNET_PQ_ResultSpec __attribute__
Constants for network protocols.
#define GNUNET_SIGNATURE_PURPOSE_NSE_SEND
Signature of a network size estimate message.
API to create, modify and access statistics.
enum GNUNET_GenericReturnValue GNUNET_BIO_write_close(struct GNUNET_BIO_WriteHandle *h, char **emsg)
Close an IO handle.
Definition bio.c:556
struct GNUNET_BIO_WriteHandle * GNUNET_BIO_write_open_file(const char *fn)
Open a file for writing.
Definition bio.c:508
enum GNUNET_GenericReturnValue GNUNET_BIO_write_int64(struct GNUNET_BIO_WriteHandle *h, const char *what, int64_t i)
Write an (u)int64_t.
Definition bio.c:865
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
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_NSE
Identifier for nse (network size estimation) service.
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_verify_(uint32_t purpose, const struct GNUNET_CRYPTO_SignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Verify EdDSA signature.
Definition crypto_ecc.c:708
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
enum GNUNET_GenericReturnValue 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:557
enum GNUNET_GenericReturnValue GNUNET_DISK_fn_write(const char *fn, const void *buf, size_t buf_size, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file atomically.
Definition disk.c:792
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition disk.c:1140
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:720
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:41
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
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).
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
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...
unsigned int GNUNET_CRYPTO_hash_count_leading_zeros(const struct GNUNET_HashCode *h)
Count the number of leading 0 bits in h.
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
#define GNUNET_MAX(a, b)
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
void GNUNET_CRYPTO_pow_hash(const struct GNUNET_CRYPTO_PowSalt *salt, const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
Calculate the 'proof-of-work' hash (an expensive hash).
Definition crypto_pow.c:42
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
double GNUNET_hton_double(double d)
Convert double to network byte order.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
#define GNUNET_PACKED
gcc-ism to get packed structs.
@ GNUNET_SCHEDULER_PRIORITY_IDLE
Run when otherwise idle.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
#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.
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition nc.c:138
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:550
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:888
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:305
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition nc.c:122
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:190
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition nc.c:161
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
#define GNUNET_MESSAGE_TYPE_NSE_START
client->service message indicating start
#define GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD
P2P message sent from nearest peer.
#define GNUNET_MESSAGE_TYPE_NSE_ESTIMATE
service->client message indicating
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:572
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition scheduler.c:1260
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_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:1213
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:1237
#define GNUNET_SERVICE_MAIN(pd, service_name, service_options, init_cb, connect_cb, disconnect_cb, cls,...)
Creates the "main" function for a GNUnet service.
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition service.c:2545
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition service.c:2434
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
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).
#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
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition strings.c:604
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition time.c:737
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition time.c:452
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition time.c:636
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition strings.c:665
Common type definitions for the network size estimation service and API.
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.
Handle for buffered writing.
Definition bio.c:466
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.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
an ECC signature using EdDSA.
Value for a salt for GNUNET_CRYPTO_pow_hash().
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
Context for parsing HELLOs.
Definition hello-uri.c:233
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Message handler for a specific message type.
Header for all communications.
Network size estimate sent from the service to clients.
Definition nse.h:43
uint32_t reserved
For alignment.
Definition nse.h:52
double size_estimate
The current estimated network size.
Definition nse.h:62
struct GNUNET_TIME_AbsoluteNBO timestamp
Timestamp at which the server received the message.
Definition nse.h:57
double std_deviation
The standard deviation (rounded down to the nearest integer) of size estimations.
Definition nse.h:69
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_NSE_ESTIMATE.
Definition nse.h:47
Network size estimate reply; sent when "this" peer's timer has run out before receiving a valid reply...
uint32_t hop_count
Number of hops this message has taken so far.
uint32_t matching_bits
Number of matching bits between the hash of timestamp and the initiator's public key.
struct GNUNET_TIME_AbsoluteNBO timestamp
The current timestamp value (which all peers should agree on).
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD.
struct GNUNET_CRYPTO_SignaturePurpose purpose
Purpose.
struct GNUNET_PeerIdentity origin
Public key of the originator.
uint64_t proof_of_work
Proof of work, causing leading zeros when hashed with pkey.
struct GNUNET_CRYPTO_EddsaSignature signature
Signature (over range specified in purpose).
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition nc.c:77
A handle for the PILS service.
Definition pils_api.c:82
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition scheduler.c:141
Handle to a client that is connected to a service.
Definition service.c:249
Handle to a service.
Definition service.c:116
Handle for the service.
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Per-peer information.
struct GNUNET_PILS_Operation * pils_op
PILS Operation.
struct GNUNET_MQ_Handle * mq
Core handle for sending messages to this peer.
struct GNUNET_SCHEDULER_Task * transmit_task
Task scheduled to send message to this peer.
const struct GNUNET_PeerIdentity * id
What is the identity of the peer?
int previous_round
Did we receive or send a message about the previous round to this peer yet? GNUNET_YES if the previou...
uint32_t next_index_to_send
Message to be sent.