GNUnet  0.10.x
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 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 "platform.h"
39 #include <math.h>
40 #include "gnunet_util_lib.h"
41 #include "gnunet_constants.h"
42 #include "gnunet_protocols.h"
43 #include "gnunet_signatures.h"
45 #include "gnunet_core_service.h"
46 #include "gnunet_nse_service.h"
47 #if ENABLE_NSE_HISTOGRAM
49 #endif
50 #include "nse.h"
51 #include <gcrypt.h>
52 
53 
58 #define USE_RANDOM_DELAYS GNUNET_YES
59 
63 #define DEBUG_NSE GNUNET_NO
64 
68 #define HISTORY_SIZE 64
69 
74 #define NSE_PRIORITY \
75  (GNUNET_MQ_PRIO_BACKGROUND | GNUNET_MQ_PREF_UNRELIABLE | \
76  GNUNET_MQ_PREF_CORK_ALLOWED)
77 
78 #if FREEBSD
79 #define log2(a) (log (a) / log (2))
80 #endif
81 
85 static unsigned long long nse_work_required;
86 
91 
96 
97 #if ENABLE_NSE_HISTOGRAM
98 
102 struct GNUNET_CLIENT_TestHandle *logger_test;
103 
107 static struct GNUNET_TESTBED_LOGGER_Handle *lh;
108 
112 static struct GNUNET_BIO_WriteHandle *histogram;
113 
114 #endif
115 
116 
121 {
122 
127 
131  const struct GNUNET_PeerIdentity *id;
132 
137 
144 
145 #if ENABLE_NSE_HISTOGRAM
146 
150  unsigned int received_messages;
151 
155  unsigned int transmitted_messages;
156 
160  unsigned int last_transmitted_size;
161 
162 #endif
163 };
164 
165 
167 
174 {
178  struct GNUNET_MessageHeader header;
179 
183  uint32_t hop_count GNUNET_PACKED;
184 
189 
194  struct GNUNET_TIME_AbsoluteNBO timestamp;
195 
202 
206  struct GNUNET_PeerIdentity origin;
207 
211  uint64_t proof_of_work GNUNET_PACKED;
212 
217 };
219 
223 static const struct GNUNET_CONFIGURATION_Handle *cfg;
224 
229 
234 
239 
244 static double current_size_estimate;
245 
250 static double current_std_dev = NAN;
251 
255 static uint32_t hop_count_max;
256 
261 
266 
270 static unsigned int estimate_index;
271 
275 static unsigned int estimate_count;
276 
281 
286 
291 
296 
301 
306 
311 
315 static uint64_t my_proof;
316 
317 
324 static void
326 {
327  double mean;
328  double sum;
329  double std_dev;
330  double variance;
331  double val;
332  double nsize;
333 
334 #define WEST 1
335  /* Weighted incremental algorithm for stddev according to West (1979) */
336 #if WEST
337  double sumweight;
338  double weight;
339  double q;
340  double r;
341  double temp;
342 
343  mean = 0.0;
344  sum = 0.0;
345  sumweight = 0.0;
346  variance = 0.0;
347  for (unsigned int i = 0; i < estimate_count; i++)
348  {
349  unsigned int j = (estimate_index - i + HISTORY_SIZE) % HISTORY_SIZE;
350 
351  val = htonl (size_estimate_messages[j].matching_bits);
352  weight = estimate_count + 1 - i;
353 
354  temp = weight + sumweight;
355  q = val - mean;
356  r = q * weight / temp;
357  mean += r;
358  sum += sumweight * q * r;
359  sumweight = temp;
360  }
361  if (estimate_count > 0)
362  variance = (sum / sumweight) * estimate_count / (estimate_count - 1.0);
363 #else
364  /* trivial version for debugging */
365  double vsq;
366 
367  /* non-weighted trivial version */
368  sum = 0.0;
369  vsq = 0.0;
370  variance = 0.0;
371  mean = 0.0;
372 
373  for (unsigned int i = 0; i < estimate_count; i++)
374  {
375  unsigned int j = (estimate_index - i + HISTORY_SIZE) % HISTORY_SIZE;
376 
377  val = htonl (size_estimate_messages[j].matching_bits);
378  sum += val;
379  vsq += val * val;
380  }
381  if (0 != estimate_count)
382  {
383  mean = sum / estimate_count;
384  variance = (vsq - mean * sum) /
385  (estimate_count - 1.0); // terrible for numerical stability...
386  }
387 #endif
388  if (variance >= 0)
389  std_dev = sqrt (variance);
390  else
391  std_dev = variance; /* must be infinity due to estimate_count == 0 */
392  current_std_dev = std_dev;
393  current_size_estimate = mean;
394 
395  em->header.size = htons (sizeof (struct GNUNET_NSE_ClientMessage));
397  em->reserved = htonl (0);
399  {
400  double se = mean - 0.332747;
401  unsigned int j = GNUNET_CONTAINER_multipeermap_size (peers);
402  if (0 == j)
403  j = 1; /* Avoid log2(0); can only happen if CORE didn't report
404  connection to self yet */
405  nsize = log2 (j);
406  em->size_estimate = GNUNET_hton_double (GNUNET_MAX (se, nsize));
407  em->std_deviation = GNUNET_hton_double (std_dev);
408  GNUNET_STATISTICS_set (stats,
409  "# nodes in the network (estimate)",
410  (uint64_t) pow (2, GNUNET_MAX (se, nsize)),
411  GNUNET_NO);
412  }
413 }
414 
415 
425 static void
426 handle_start (void *cls, const struct GNUNET_MessageHeader *message)
427 {
428  struct GNUNET_SERVICE_Client *client = cls;
429  struct GNUNET_MQ_Handle *mq;
430  struct GNUNET_NSE_ClientMessage em;
431  struct GNUNET_MQ_Envelope *env;
432 
433  (void) message;
434  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received START message from client\n");
435  mq = GNUNET_SERVICE_client_get_mq (client);
438  env = GNUNET_MQ_msg_copy (&em.header);
439  GNUNET_MQ_send (mq, env);
441 }
442 
443 
450 static double
452 {
453  /* Calculated as: S + f/2 - (f / pi) * (atan(x - p')) */
454  // S is next_timestamp (ignored in return value)
455  // f is frequency (gnunet_nse_interval)
456  // x is matching_bits
457  // p' is current_size_estimate
458  return ((double) gnunet_nse_interval.rel_value_us / (double) 2.0) -
460  atan (matching_bits - current_size_estimate));
461 }
462 
463 
470 static struct GNUNET_TIME_Relative
472 {
473 #if USE_RANDOM_DELAYS
474  struct GNUNET_TIME_Relative ret;
475  uint32_t i;
476  double d;
477 
479  i = (uint32_t) (d / (double) (hop_count_max + 1));
480  ret.rel_value_us = i;
482  "Randomizing flood using latencies up to %s\n",
484  ret.rel_value_us =
486  return ret;
487 #else
488  return GNUNET_TIME_UNIT_ZERO;
489 #endif
490 }
491 
492 
500 static void
501 pow_hash (const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
502 {
503  GNUNET_break (
504  0 == gcry_kdf_derive (buf,
505  buf_len,
506  GCRY_KDF_SCRYPT,
507  1 /* subalgo */,
508  "gnunet-proof-of-work",
509  strlen ("gnunet-proof-of-work"),
510  2 /* iterations; keep cost of individual op small */,
511  sizeof (struct GNUNET_HashCode),
512  result));
513 }
514 
515 
523 static uint32_t
525  const struct GNUNET_PeerIdentity *id)
526 {
527  struct GNUNET_HashCode timestamp_hash;
528  struct GNUNET_HashCode pid_hash;
529 
530  GNUNET_CRYPTO_hash (&timestamp.abs_value_us,
531  sizeof (timestamp.abs_value_us),
532  &timestamp_hash);
533  GNUNET_CRYPTO_hash (id, sizeof (struct GNUNET_PeerIdentity), &pid_hash);
534  return GNUNET_CRYPTO_hash_matching_bits (&timestamp_hash, &pid_hash);
535 }
536 
537 
546 static struct GNUNET_TIME_Relative
547 get_transmit_delay (int round_offset)
548 {
549  struct GNUNET_TIME_Relative ret;
550  struct GNUNET_TIME_Absolute tgt;
551  double dist_delay;
552  uint32_t matching_bits;
553 
554  switch (round_offset)
555  {
556  case -1:
557  /* previous round is randomized between 0 and 50 ms */
558 #if USE_RANDOM_DELAYS
559  ret.rel_value_us =
561 #else
562  ret = GNUNET_TIME_UNIT_ZERO;
563 #endif
565  "Transmitting previous round behind schedule in %s\n",
567  return ret;
568  case 0:
569  /* current round is based on best-known matching_bits */
570  matching_bits =
571  ntohl (size_estimate_messages[estimate_index].matching_bits);
572  dist_delay = get_matching_bits_delay (matching_bits);
573  dist_delay += get_delay_randomization (matching_bits).rel_value_us;
574  ret.rel_value_us = (uint64_t) dist_delay;
576  "For round %s, delay for %u matching bits is %s\n",
578  (unsigned int) matching_bits,
580  /* now consider round start time and add delay to it */
583  }
584  GNUNET_break (0);
586 }
587 
588 
594 static void
595 transmit_task_cb (void *cls)
596 {
597  struct NSEPeerEntry *peer_entry = cls;
598  unsigned int idx;
599  struct GNUNET_MQ_Envelope *env;
600 
601  peer_entry->transmit_task = NULL;
602  idx = estimate_index;
603  if (GNUNET_NO == peer_entry->previous_round)
604  {
605  idx = (idx + HISTORY_SIZE - 1) % HISTORY_SIZE;
606  peer_entry->previous_round = GNUNET_YES;
607  peer_entry->transmit_task =
610  peer_entry);
611  }
612  if ((0 == ntohl (size_estimate_messages[idx].hop_count)) &&
613  (NULL != proof_task))
614  {
616  "# flood messages not generated (no proof yet)",
617  1,
618  GNUNET_NO);
619  return;
620  }
621  if (0 == ntohs (size_estimate_messages[idx].header.size))
622  {
624  "# flood messages not generated (lack of history)",
625  1,
626  GNUNET_NO);
627  return;
628  }
630  "In round %s, sending to `%s' estimate with %u bits\n",
633  size_estimate_messages[idx].timestamp)),
634  GNUNET_i2s (peer_entry->id),
635  (unsigned int) ntohl (size_estimate_messages[idx].matching_bits));
636  if (0 == ntohl (size_estimate_messages[idx].hop_count))
637  GNUNET_STATISTICS_update (stats, "# flood messages started", 1, GNUNET_NO);
639  "# flood messages transmitted",
640  1,
641  GNUNET_NO);
642 #if ENABLE_NSE_HISTOGRAM
643  peer_entry->transmitted_messages++;
644  peer_entry->last_transmitted_size =
645  ntohl (size_estimate_messages[idx].matching_bits);
646 #endif
647  env = GNUNET_MQ_msg_copy (&size_estimate_messages[idx].header);
648  GNUNET_MQ_send (peer_entry->mq, env);
649 }
650 
651 
658 static void
660 {
661  struct GNUNET_NSE_ClientMessage em;
662 
665 }
666 
667 
675 static void
676 setup_flood_message (unsigned int slot, struct GNUNET_TIME_Absolute ts)
677 {
678  struct GNUNET_NSE_FloodMessage *fm;
679  uint32_t matching_bits;
680 
681  matching_bits = get_matching_bits (ts, &my_identity);
682  fm = &size_estimate_messages[slot];
683  fm->header.size = htons (sizeof (struct GNUNET_NSE_FloodMessage));
685  fm->hop_count = htonl (0);
687  fm->purpose.size =
688  htonl (sizeof (struct GNUNET_NSE_FloodMessage) -
689  sizeof (struct GNUNET_MessageHeader) - sizeof (uint32_t) -
690  sizeof (struct GNUNET_CRYPTO_EddsaSignature));
691  fm->matching_bits = htonl (matching_bits);
693  fm->origin = my_identity;
694  fm->proof_of_work = my_proof;
695  if (nse_work_required > 0)
697  &fm->purpose,
698  &fm->signature));
699  else
700  memset (&fm->signature, 0, sizeof (fm->signature));
701 }
702 
703 
713 static int
715  const struct GNUNET_PeerIdentity *key,
716  void *value)
717 {
718  struct NSEPeerEntry *peer_entry = value;
719  struct GNUNET_TIME_Relative delay;
720 
721  (void) cls;
722  (void) key;
723  if (NULL != peer_entry->transmit_task)
724  {
726  peer_entry->previous_round = GNUNET_NO;
727  }
728 #if ENABLE_NSE_HISTOGRAM
729  if (peer_entry->received_messages > 1)
731  "# extra messages",
732  peer_entry->received_messages - 1,
733  GNUNET_NO);
734  peer_entry->transmitted_messages = 0;
735  peer_entry->last_transmitted_size = 0;
736  peer_entry->received_messages = 0;
737 #endif
738  delay =
739  get_transmit_delay ((GNUNET_NO == peer_entry->previous_round) ? -1 : 0);
740  peer_entry->transmit_task =
741  GNUNET_SCHEDULER_add_delayed (delay, &transmit_task_cb, peer_entry);
742  return GNUNET_OK;
743 }
744 
745 
751 static void
753 {
754  struct GNUNET_TIME_Relative offset;
755 
756  (void) cls;
757  flood_task = NULL;
759  if (0 != offset.rel_value_us)
760  {
761  /* somehow run early, delay more */
762  flood_task =
764  return;
765  }
768  estimate_count++;
775  ntohl (next_message.matching_bits)))
776  {
777  /* we received a message for this round way early, use it! */
780  htonl (1 + ntohl (next_message.hop_count));
781  }
782  else
784  next_message.matching_bits = htonl (0); /* reset for 'next' round */
785  hop_count_max = 0;
786  for (unsigned int i = 0; i < HISTORY_SIZE; i++)
787  hop_count_max =
788  GNUNET_MAX (ntohl (size_estimate_messages[i].hop_count), hop_count_max);
790  flood_task =
792 }
793 
794 
801 static unsigned int
803 {
804  unsigned int hash_count;
805 
806  hash_count = 0;
807  while (0 == GNUNET_CRYPTO_hash_get_bit (hash, hash_count))
808  hash_count++;
809  return hash_count;
810 }
811 
812 
821 static int
823  uint64_t val)
824 {
825  char buf[sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) +
826  sizeof (val)] GNUNET_ALIGN;
827  struct GNUNET_HashCode result;
828 
829  GNUNET_memcpy (buf, &val, sizeof (val));
830  GNUNET_memcpy (&buf[sizeof (val)],
831  pkey,
832  sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
833  pow_hash (buf, sizeof (buf), &result);
834  return (count_leading_zeroes (&result) >= nse_work_required) ? GNUNET_YES
835  : GNUNET_NO;
836 }
837 
838 
842 static void
844 {
845  char *proof;
846 
847  if (GNUNET_OK !=
848  GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "PROOFFILE", &proof))
849  return;
850  if (sizeof (my_proof) != GNUNET_DISK_fn_write (proof,
851  &my_proof,
852  sizeof (my_proof),
856  GNUNET_free (proof);
857 }
858 
859 
865 static void
866 find_proof (void *cls)
867 {
868 #define ROUND_SIZE 10
869  uint64_t counter;
870  char buf[sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) +
871  sizeof (uint64_t)] GNUNET_ALIGN;
872  struct GNUNET_HashCode result;
873  unsigned int i;
874 
875  (void) cls;
876  proof_task = NULL;
877  GNUNET_memcpy (&buf[sizeof (uint64_t)],
878  &my_identity,
879  sizeof (struct GNUNET_PeerIdentity));
880  i = 0;
881  counter = my_proof;
882  while ((counter != UINT64_MAX) && (i < ROUND_SIZE))
883  {
884  GNUNET_memcpy (buf, &counter, sizeof (uint64_t));
885  pow_hash (buf, sizeof (buf), &result);
886  if (nse_work_required <= count_leading_zeroes (&result))
887  {
888  my_proof = counter;
890  "Proof of work found: %llu!\n",
891  (unsigned long long) GNUNET_ntohll (counter));
892  write_proof ();
894  return;
895  }
896  counter++;
897  i++;
898  }
899  if (my_proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE))
900  {
902  "Testing proofs currently at %llu\n",
903  (unsigned long long) counter);
904  /* remember progress every 100 rounds */
905  my_proof = counter;
906  write_proof ();
907  }
908  else
909  {
910  my_proof = counter;
911  }
912  proof_task =
915  &find_proof,
916  NULL);
917 }
918 
919 
929 static int
930 verify_message_crypto (const struct GNUNET_NSE_FloodMessage *incoming_flood)
931 {
932  if (GNUNET_YES != check_proof_of_work (&incoming_flood->origin.public_key,
933  incoming_flood->proof_of_work))
934  {
936  "Proof of work invalid: %llu!\n",
937  (unsigned long long) GNUNET_ntohll (
938  incoming_flood->proof_of_work));
939  GNUNET_break_op (0);
940  return GNUNET_NO;
941  }
942  if ((nse_work_required > 0) &&
943  (GNUNET_OK !=
945  &incoming_flood->purpose,
946  &incoming_flood->signature,
947  &incoming_flood->origin.public_key)))
948  {
949  GNUNET_break_op (0);
950  return GNUNET_NO;
951  }
952  return GNUNET_YES;
953 }
954 
955 
965 static int
967  const struct GNUNET_PeerIdentity *key,
968  void *value)
969 {
970  struct NSEPeerEntry *exclude = cls;
971  struct NSEPeerEntry *peer_entry = value;
972  struct GNUNET_TIME_Relative delay;
973 
974  (void) key;
975  if (peer_entry == exclude)
976  return GNUNET_OK; /* trigger of the update */
977  if (GNUNET_NO == peer_entry->previous_round)
978  {
979  /* still stuck in previous round, no point to update, check that
980  * we are active here though... */
981  if (NULL == peer_entry->transmit_task)
982  {
983  GNUNET_break (0);
984  }
985  return GNUNET_OK;
986  }
987  if (NULL != peer_entry->transmit_task)
988  {
990  peer_entry->transmit_task = NULL;
991  }
992  delay = get_transmit_delay (0);
993  peer_entry->transmit_task =
994  GNUNET_SCHEDULER_add_delayed (delay, &transmit_task_cb, peer_entry);
995  return GNUNET_OK;
996 }
997 
998 
1005 static void
1007  const struct GNUNET_NSE_FloodMessage *incoming_flood)
1008 {
1009  struct NSEPeerEntry *peer_entry = cls;
1010  struct GNUNET_TIME_Absolute ts;
1011  uint32_t matching_bits;
1012  unsigned int idx;
1013 
1014 #if ENABLE_NSE_HISTOGRAM
1015  {
1016  uint64_t t;
1017 
1019  if (NULL != lh)
1020  GNUNET_TESTBED_LOGGER_write (lh, &t, sizeof (uint64_t));
1021  if (NULL != histogram)
1022  GNUNET_BIO_write_int64 (histogram, t);
1023  }
1024 #endif
1025  GNUNET_STATISTICS_update (stats, "# flood messages received", 1, GNUNET_NO);
1026  matching_bits = ntohl (incoming_flood->matching_bits);
1027 #if DEBUG_NSE
1028  {
1029  char origin[5];
1030  char pred[5];
1031  struct GNUNET_PeerIdentity os;
1032 
1033  GNUNET_snprintf (origin,
1034  sizeof (origin),
1035  "%s",
1036  GNUNET_i2s (&incoming_flood->origin));
1037  GNUNET_snprintf (pred, sizeof (pred), "%s", GNUNET_i2s (peer_entry->id));
1039  "Flood at %s from `%s' via `%s' at `%s' with bits %u\n",
1041  GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp)),
1042  origin,
1043  pred,
1045  (unsigned int) matching_bits);
1046  }
1047 #endif
1048 
1049 #if ENABLE_NSE_HISTOGRAM
1050  peer_entry->received_messages++;
1051  if (peer_entry->transmitted_messages > 0 &&
1052  peer_entry->last_transmitted_size >= matching_bits)
1053  GNUNET_STATISTICS_update (stats, "# cross messages", 1, GNUNET_NO);
1054 #endif
1055 
1056  ts = GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp);
1058  idx = estimate_index;
1059  else if (ts.abs_value_us ==
1061  idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE;
1062  else if (ts.abs_value_us == next_timestamp.abs_value_us)
1063  {
1064  if (matching_bits <= ntohl (next_message.matching_bits))
1065  return; /* ignore, simply too early/late */
1066  if (GNUNET_YES != verify_message_crypto (incoming_flood))
1067  {
1069  "Peer %s is likely ill-configured!\n",
1070  GNUNET_i2s (peer_entry->id));
1071  GNUNET_break_op (0);
1072  return;
1073  }
1074  next_message = *incoming_flood;
1075  return;
1076  }
1077  else
1078  {
1079  GNUNET_STATISTICS_update (stats,
1080  "# flood messages discarded (clock skew too large)",
1081  1,
1082  GNUNET_NO);
1083  return;
1084  }
1085  if (0 == (GNUNET_memcmp (peer_entry->id, &my_identity)))
1086  {
1087  /* send to self, update our own estimate IF this also comes from us! */
1088  if (0 == GNUNET_memcmp (&incoming_flood->origin, &my_identity))
1090  return;
1091  }
1092  if (matching_bits == ntohl (size_estimate_messages[idx].matching_bits))
1093  {
1094  /* Cancel transmission in the other direction, as this peer clearly has
1095  up-to-date information already. Even if we didn't talk to this peer in
1096  the previous round, we should no longer send it stale information as it
1097  told us about the current round! */
1098  peer_entry->previous_round = GNUNET_YES;
1099  if (idx != estimate_index)
1100  {
1101  /* do not transmit information for the previous round to this peer
1102  anymore (but allow current round) */
1103  return;
1104  }
1105  /* got up-to-date information for current round, cancel transmission to
1106  * this peer altogether */
1107  if (NULL != peer_entry->transmit_task)
1108  {
1109  GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
1110  peer_entry->transmit_task = NULL;
1111  }
1112  return;
1113  }
1114  if (matching_bits < ntohl (size_estimate_messages[idx].matching_bits))
1115  {
1116  if ((idx < estimate_index) && (peer_entry->previous_round == GNUNET_YES))
1117  {
1118  peer_entry->previous_round = GNUNET_NO;
1119  }
1120  /* push back our result now, that peer is spreading bad information... */
1121  if (NULL != peer_entry->transmit_task)
1122  GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
1123  peer_entry->transmit_task =
1125  /* Not closer than our most recent message, no need to do work here */
1126  GNUNET_STATISTICS_update (stats,
1127  "# flood messages ignored (had closer already)",
1128  1,
1129  GNUNET_NO);
1130  return;
1131  }
1132  if (GNUNET_YES != verify_message_crypto (incoming_flood))
1133  {
1134  GNUNET_break_op (0);
1135  return;
1136  }
1137  GNUNET_assert (matching_bits >
1138  ntohl (size_estimate_messages[idx].matching_bits));
1139  /* Cancel transmission in the other direction, as this peer clearly has
1140  * up-to-date information already.
1141  */
1142  peer_entry->previous_round = GNUNET_YES;
1143  if (idx == estimate_index)
1144  {
1145  /* cancel any activity for current round */
1146  if (NULL != peer_entry->transmit_task)
1147  {
1148  GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
1149  peer_entry->transmit_task = NULL;
1150  }
1151  }
1152  size_estimate_messages[idx] = *incoming_flood;
1154  htonl (ntohl (incoming_flood->hop_count) + 1);
1155  hop_count_max =
1156  GNUNET_MAX (ntohl (incoming_flood->hop_count) + 1, hop_count_max);
1157  GNUNET_STATISTICS_set (stats,
1158  "# estimated network diameter",
1159  hop_count_max,
1160  GNUNET_NO);
1161 
1162  /* have a new, better size estimate, inform clients */
1164 
1165  /* flood to rest */
1168  peer_entry);
1169 }
1170 
1171 
1179 static void *
1181  const struct GNUNET_PeerIdentity *peer,
1182  struct GNUNET_MQ_Handle *mq)
1183 {
1184  struct NSEPeerEntry *peer_entry;
1185 
1186  (void) cls;
1188  "Peer `%s' connected to us\n",
1189  GNUNET_i2s (peer));
1190  /* set our default transmission options */
1192  /* create our peer entry for this peer */
1193  peer_entry = GNUNET_new (struct NSEPeerEntry);
1194  peer_entry->id = peer;
1195  peer_entry->mq = mq;
1198  peers,
1199  peer_entry->id,
1200  peer_entry,
1202  peer_entry->transmit_task =
1205  peer_entry);
1206  GNUNET_STATISTICS_update (stats, "# peers connected", 1, GNUNET_NO);
1207  return peer_entry;
1208 }
1209 
1210 
1219 static void
1221  const struct GNUNET_PeerIdentity *peer,
1222  void *internal_cls)
1223 {
1224  struct NSEPeerEntry *pos = internal_cls;
1225 
1226  (void) cls;
1228  "Peer `%s' disconnected from us\n",
1229  GNUNET_i2s (peer));
1231  GNUNET_CONTAINER_multipeermap_remove (peers, peer, pos));
1232  if (NULL != pos->transmit_task)
1233  {
1235  pos->transmit_task = NULL;
1236  }
1237  GNUNET_free (pos);
1238  GNUNET_STATISTICS_update (stats, "# peers connected", -1, GNUNET_NO);
1239 }
1240 
1241 
1242 #if ENABLE_NSE_HISTOGRAM
1243 
1250 static void
1251 flush_comp_cb (void *cls, size_t size)
1252 {
1253  (void) cls;
1254  (void) size;
1256  lh = NULL;
1257 }
1258 #endif
1259 
1260 
1266 static void
1267 shutdown_task (void *cls)
1268 {
1269  (void) cls;
1270  if (NULL != flood_task)
1271  {
1272  GNUNET_SCHEDULER_cancel (flood_task);
1273  flood_task = NULL;
1274  }
1275  if (NULL != proof_task)
1276  {
1277  GNUNET_SCHEDULER_cancel (proof_task);
1278  proof_task = NULL;
1279  write_proof (); /* remember progress */
1280  }
1281  if (NULL != nc)
1282  {
1284  nc = NULL;
1285  }
1286  if (NULL != core_api)
1287  {
1288  GNUNET_CORE_disconnect (core_api);
1289  core_api = NULL;
1290  }
1291  if (NULL != stats)
1292  {
1294  stats = NULL;
1295  }
1296  if (NULL != peers)
1297  {
1299  peers = NULL;
1300  }
1301  if (NULL != my_private_key)
1302  {
1303  GNUNET_free (my_private_key);
1304  my_private_key = NULL;
1305  }
1306 #if ENABLE_NSE_HISTOGRAM
1307  if (NULL != logger_test)
1308  {
1309  GNUNET_CLIENT_service_test_cancel (logger_test);
1310  logger_test = NULL;
1311  }
1312  if (NULL != lh)
1313  {
1314  GNUNET_TESTBED_LOGGER_flush (lh, &flush_comp_cb, NULL);
1315  }
1316  if (NULL != histogram)
1317  {
1318  GNUNET_BIO_write_close (histogram);
1319  histogram = NULL;
1320  }
1321 #endif
1322 }
1323 
1324 
1331 static void
1332 core_init (void *cls, const struct GNUNET_PeerIdentity *identity)
1333 {
1334  struct GNUNET_TIME_Absolute now;
1335  struct GNUNET_TIME_Absolute prev_time;
1336 
1337  (void) cls;
1338  if (NULL == identity)
1339  {
1340  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection to core FAILED!\n");
1342  return;
1343  }
1344  GNUNET_assert (0 == GNUNET_memcmp (&my_identity, identity));
1345  now = GNUNET_TIME_absolute_get ();
1349  next_timestamp =
1352  estimate_count = 0;
1354  {
1355  int idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE;
1356  prev_time.abs_value_us =
1358  setup_flood_message (idx, prev_time);
1360  estimate_count++;
1361  }
1362  flood_task =
1364 }
1365 
1366 
1367 #if ENABLE_NSE_HISTOGRAM
1368 
1376 static void
1377 status_cb (void *cls, int status)
1378 {
1379  (void) cls;
1380  logger_test = NULL;
1381  if (GNUNET_YES != status)
1382  {
1383  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Testbed logger not running\n");
1384  return;
1385  }
1386  if (NULL == (lh = GNUNET_TESTBED_LOGGER_connect (cfg)))
1387  {
1389  "Cannot connect to the testbed logger. Exiting.\n");
1391  }
1392 }
1393 #endif
1394 
1395 
1403 static void
1404 run (void *cls,
1405  const struct GNUNET_CONFIGURATION_Handle *c,
1407 {
1408  struct GNUNET_MQ_MessageHandler core_handlers[] =
1409  {GNUNET_MQ_hd_fixed_size (p2p_estimate,
1411  struct GNUNET_NSE_FloodMessage,
1412  NULL),
1414  char *proof;
1416 
1417  (void) cls;
1418  (void) service;
1419  cfg = c;
1421  "NSE",
1422  "INTERVAL",
1424  {
1427  return;
1428  }
1430  "NSE",
1431  "WORKDELAY",
1432  &proof_find_delay))
1433  {
1434  GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKDELAY");
1436  return;
1437  }
1439  "NSE",
1440  "WORKBITS",
1442  {
1445  return;
1446  }
1447  if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8)
1448  {
1450  "NSE",
1451  "WORKBITS",
1452  _ ("Value is too large.\n"));
1454  return;
1455  }
1456 
1457 #if ENABLE_NSE_HISTOGRAM
1458  {
1459  char *histogram_dir;
1460  char *histogram_fn;
1461 
1463  "NSE",
1464  "HISTOGRAM_DIR",
1465  &histogram_dir))
1466  {
1467  GNUNET_assert (
1468  0 < GNUNET_asprintf (&histogram_fn, "%s/timestamps", histogram_dir));
1469  GNUNET_free (histogram_dir);
1470  histogram = GNUNET_BIO_write_open (histogram_fn);
1471  if (NULL == histogram)
1473  "Unable to open histogram file `%s'\n",
1474  histogram_fn);
1475  GNUNET_free (histogram_fn);
1476  }
1477  logger_test = GNUNET_CLIENT_service_test ("testbed-logger",
1478  cfg,
1480  &status_cb,
1481  NULL);
1482  }
1483 #endif
1484 
1487  GNUNET_assert (NULL != pk);
1488  my_private_key = pk;
1490  if (GNUNET_OK !=
1491  GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "PROOFFILE", &proof))
1492  {
1493  GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "PROOFFILE");
1494  GNUNET_free (my_private_key);
1495  my_private_key = NULL;
1497  return;
1498  }
1499  if ((GNUNET_YES != GNUNET_DISK_file_test (proof)) ||
1500  (sizeof (my_proof) !=
1501  GNUNET_DISK_fn_read (proof, &my_proof, sizeof (my_proof))))
1502  my_proof = 0;
1503  GNUNET_free (proof);
1504  proof_task =
1506  &find_proof,
1507  NULL);
1508 
1511  /* Connect to core service and register core handlers */
1512  core_api =
1513  GNUNET_CORE_connect (cfg, /* Main configuration */
1514  NULL, /* Closure passed to functions */
1515  &core_init, /* Call core_init once connected */
1516  &handle_core_connect, /* Handle connects */
1517  &handle_core_disconnect, /* Handle disconnects */
1518  core_handlers); /* Register these handlers */
1519  if (NULL == core_api)
1520  {
1522  return;
1523  }
1524  stats = GNUNET_STATISTICS_create ("nse", cfg);
1525 }
1526 
1527 
1536 static void *
1538  struct GNUNET_SERVICE_Client *c,
1539  struct GNUNET_MQ_Handle *mq)
1540 {
1541  (void) cls;
1542  (void) mq;
1543  return c;
1544 }
1545 
1546 
1554 static void
1556  struct GNUNET_SERVICE_Client *c,
1557  void *internal_cls)
1558 {
1559  (void) cls;
1560  GNUNET_assert (c == internal_cls);
1561 }
1562 
1563 
1567 GNUNET_SERVICE_MAIN ("nse",
1569  &run,
1572  NULL,
1575  struct GNUNET_MessageHeader,
1576  NULL),
1578 
1579 
1580 #if defined(LINUX) && defined(__GLIBC__)
1581 #include <malloc.h>
1582 
1586 void __attribute__ ((constructor)) GNUNET_ARM_memory_init ()
1587 {
1588  mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1589  mallopt (M_TOP_PAD, 1 * 1024);
1590  malloc_trim (0);
1591 }
1592 #endif
1593 
1594 
1595 /* end of gnunet-service-nse.c */
#define GNUNET_MESSAGE_TYPE_NSE_START
client->service message indicating start
int GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:669
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
struct GNUNET_MQ_Envelope * GNUNET_MQ_msg_copy(const struct GNUNET_MessageHeader *hdr)
Create a new envelope by copying an existing message.
Definition: mq.c:653
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition: nc.c:77
static struct GNUNET_CRYPTO_EddsaPrivateKey * pk
Private key of this peer.
int previous_round
Did we receive or send a message about the previous round to this peer yet? GNUNET_YES if the previou...
int 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_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:670
static void shutdown_task(void *cls)
Task run during shutdown.
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
uint64_t rel_value_us
The actual value.
static struct GNUNET_TIME_Relative get_transmit_delay(int round_offset)
Get the transmission delay that should be applied for a particular round.
static char * pkey
Public key of the zone to look in, in ASCII.
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...
const struct GNUNET_PeerIdentity * id
What is the identity of the peer?
static struct GNUNET_TIME_Relative proof_find_delay
Interval between proof find runs.
Context for the core service connection.
Definition: core_api.c:78
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
static void handle_core_disconnect(void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
Method called whenever a peer disconnects.
Handle to a service.
Definition: service.c:116
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed_with_priority(struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1178
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2734
struct GNUNET_TIME_AbsoluteNBO timestamp
Timestamp at which the server received the message.
Definition: nse.h:57
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static struct GNUNET_CONTAINER_MultiPeerMap * peers
Map of all connected peers.
unsigned int GNUNET_CRYPTO_hash_matching_bits(const struct GNUNET_HashCode *first, const struct GNUNET_HashCode *second)
Determine how many low order bits match in two struct GNUNET_HashCodes.
Definition: crypto_hash.c:256
static struct GNUNET_SCHEDULER_Task * proof_task
Task scheduled to compute our proof.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD
P2P message sent from nearest peer.
int GNUNET_BIO_write_int64(struct GNUNET_BIO_WriteHandle *h, int64_t i)
Write an (u)int64_t.
Definition: bio.c:623
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TESTBED_LOGGER_Handle * GNUNET_TESTBED_LOGGER_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the testbed logger service.
static struct GNUNET_SCHEDULER_Task * flood_task
Task scheduled to update our flood message for the next round.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_NSE_ESTIMATE.
Definition: nse.h:47
uint32_t matching_bits
Number of matching bits between the hash of timestamp and the initiator&#39;s public key.
static struct GNUNET_NSE_FloodMessage next_message
Message for the next round, if we got any.
int GNUNET_CRYPTO_eddsa_sign(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
EdDSA sign a given block.
Definition: crypto_ecc.c:989
Network size estimate sent from the service to clients.
Definition: nse.h:42
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
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...
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define HISTORY_SIZE
Over how many values do we calculate the weighted average?
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:393
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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.
static struct GNUNET_SCHEDULER_Task * t
Main task.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static struct GNUNET_PeerIdentity my_identity
The peer identity of this peer.
#define GNUNET_MESSAGE_TYPE_NSE_ESTIMATE
service->client message indicating
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
static struct GNUNET_TIME_Relative gnunet_nse_interval
Interval for sending network size estimation flood requests.
static int ret
Final status code.
Definition: gnunet-arm.c:89
Handle for the service.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Handle network size estimate clients.
static unsigned long long nse_work_required
Amount of work required (W-bit collisions) for NSE proofs, in collision-bits.
Time for absolute time used by GNUnet, in microseconds and in network byte order. ...
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:164
uint64_t abs_value_us
The actual value.
ssize_t GNUNET_DISK_fn_write(const char *fn, const void *buffer, size_t n, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file.
Definition: disk.c:1203
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.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32.
static void transmit_task_cb(void *cls)
Task that triggers a NSE P2P transmission.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
GNUNET_SERVICE_MAIN("nse", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(start, GNUNET_MESSAGE_TYPE_NSE_START, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
Handle to a client that is connected to a service.
Definition: service.c:249
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()
Write our current proof to disk.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
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?
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1246
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_with_priority(enum GNUNET_SCHEDULER_Priority prio, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified priority.
Definition: scheduler.c:1200
#define GNUNET_memcpy(dst, src, n)
static uint32_t hop_count_max
Current hop counter estimate (estimate for network diameter).
int GNUNET_CRYPTO_eddsa_verify(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Verify EdDSA signature.
Definition: crypto_ecc.c:1116
struct GNUNET_CRYPTO_EddsaSignature signature
Signature (over range specified in purpose).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
static char * value
Value of the record to add/remove.
static uint64_t proof
Definition: gnunet-scrypt.c:41
Network size estimate reply; sent when "this" peer&#39;s timer has run out before receiving a valid reply...
#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_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
double std_deviation
The standard deviation (rounded down to the nearest integer) of size estimations. ...
Definition: nse.h:69
#define GNUNET_MAX(a, b)
Definition: gnunet_common.h:85
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:1273
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.
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:727
static void find_proof(void *cls)
Find our proof of work.
static unsigned int estimate_index
Index of most recent estimate.
static double current_size_estimate
The current network size estimate.
uint16_t status
See PRISM_STATUS_*-constants.
static struct GNUNET_NotificationContext * nc
Notification context, simplifies client broadcasts.
static char buf[2048]
static int result
Global testing status.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static struct GNUNET_NSE_FloodMessage size_estimate_messages[64]
Array of recent size estimate messages.
Handle for buffered writing.
Definition: bio.c:399
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
Internal representation of the hash map.
struct GNUNET_PeerIdentity origin
Public key of the originator.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
A 512-bit hashcode.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose.
Message handler for a specific message type.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static void pow_hash(const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
Calculate the &#39;proof-of-work&#39; hash (an expensive hash).
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?
#define NSE_PRIORITY
Message priority to use.
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
Run when otherwise idle.
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
static struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
static void handle_p2p_estimate(void *cls, const struct GNUNET_NSE_FloodMessage *incoming_flood)
Core handler for size estimate flooding messages.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GNUNET_HashCode key
The key used in the DHT.
static unsigned int size
Size of the "table".
Definition: peer.c:67
uint64_t proof_of_work
Proof of work, causing leading zeros when hashed with pkey.
int GNUNET_CRYPTO_hash_get_bit(const struct GNUNET_HashCode *code, unsigned int bit)
Obtain a bit from a hashcode.
Definition: crypto_hash.c:236
struct GNUNET_CORE_Handle * GNUNET_CORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls, GNUNET_CORE_StartupCallback init, GNUNET_CORE_ConnectEventHandler connects, GNUNET_CORE_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Connect to the core service.
Definition: core_api.c:694
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition: core_api.c:732
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static double current_std_dev
The standard deviation of the last HISTORY_SIZE network size estimates.
static void setup_estimate_message(struct GNUNET_NSE_ClientMessage *em)
Initialize a message to clients with the current network size estimate.
static unsigned int count_leading_zeroes(const struct GNUNET_HashCode *hash)
Count the leading zeroes in hash.
struct GNUNET_SCHEDULER_Task * transmit_task
Task scheduled to send message to this peer.
static void update_network_size_estimate()
We&#39;ve sent on our flood message or one that we received which was validated and closer than ours...
double size_estimate
The current estimated network size.
Definition: nse.h:62
#define ROUND_SIZE
int GNUNET_BIO_write_close(struct GNUNET_BIO_WriteHandle *h)
Close an open file for writing.
Definition: bio.c:457
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
an ECC signature using EdDSA.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:272
static struct GNUNET_CORE_Handle * core_api
Handle to the core service.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD.
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:125
static void * handle_core_connect(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a peer connects.
Handle to a message queue.
Definition: mq.c:85
struct GNUNET_TIME_AbsoluteNBO timestamp
The current timestamp value (which all peers should agree on).
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.
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
Private ECC key encoded for transmission.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_MQ_set_options(struct GNUNET_MQ_Handle *mq, enum GNUNET_MQ_PriorityPreferences pp)
Set application-specific options for this queue.
Definition: mq.c:1066
void GNUNET_notification_context_broadcast(struct GNUNET_NotificationContext *nc, const struct GNUNET_MessageHeader *msg, int can_drop)
Send a message to all subscribers of this context.
Definition: nc.c:192
enum RadiotapType __attribute__
The identity of the host (wraps the signing key of the peer).
Connection handle for the logger service.
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
The private key of this peer.
struct GNUNET_MQ_Handle * mq
Core handle for sending messages to this peer.
#define GNUNET_PACKED
gcc-ism to get packed structs.
static unsigned int estimate_count
Number of valid entries in the history.
configuration data
Definition: configuration.c:85
struct GNUNET_BIO_WriteHandle * GNUNET_BIO_write_open(const char *fn)
Open a file for writing.
Definition: bio.c:430
static struct GNUNET_TIME_Absolute next_timestamp
The next major time.
static int 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 uint64_t my_proof
Proof of work for this peer.
static struct GNUNET_TIME_Absolute current_timestamp
The current major time.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
uint32_t hop_count
Number of hops this message has taken so far.
#define GNUNET_SIGNATURE_PURPOSE_NSE_SEND
Signature of a network size estimate message.
Common type definitions for the network size estimation service and API.
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.
void GNUNET_TESTBED_LOGGER_write(struct GNUNET_TESTBED_LOGGER_Handle *h, const void *data, size_t size)
Send data to be logged to the logger service.
static void handle_start(void *cls, const struct GNUNET_MessageHeader *message)
Handler for START message from client, triggers an immediate current network estimate notification...
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer&#39;s key from the file specified in the configuration...
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
static void core_init(void *cls, const struct GNUNET_PeerIdentity *identity)
Called on core init/fail.
#define GNUNET_YES
Definition: gnunet_common.h:80
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:141
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
void GNUNET_TESTBED_LOGGER_flush(struct GNUNET_TESTBED_LOGGER_Handle *h, GNUNET_TESTBED_LOGGER_FlushCompletion cb, void *cb_cls)
Flush the buffered data to the logger service.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:792
static unsigned long long matching_bits
Number of matching bits required for revocation.
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:1223
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:654
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
void GNUNET_TESTBED_LOGGER_disconnect(struct GNUNET_TESTBED_LOGGER_Handle *h)
Disconnect from the logger service.
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 ...
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static void update_flood_message(void *cls)
Update our flood message to be sent (and our timestamps).
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
double GNUNET_hton_double(double d)
Convert double to network byte order.
Definition: common_endian.c:66
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...
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:1019
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
uint32_t reserved
For alignment.
Definition: nse.h:52
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
static GNUNET_NETWORK_STRUCT_END const struct GNUNET_CONFIGURATION_Handle * cfg
Handle to our current configuration.
Per-peer information.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...