GNUnet  0.11.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 #ifdef BSD
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 {
126 
130  const struct GNUNET_PeerIdentity *id;
131 
136 
143 
144 #if ENABLE_NSE_HISTOGRAM
145 
148  unsigned int received_messages;
149 
153  unsigned int transmitted_messages;
154 
158  unsigned int last_transmitted_size;
159 #endif
160 };
161 
162 
164 
171 {
175  struct GNUNET_MessageHeader header;
176 
180  uint32_t hop_count GNUNET_PACKED;
181 
186 
191  struct GNUNET_TIME_AbsoluteNBO timestamp;
192 
199 
203  struct GNUNET_PeerIdentity origin;
204 
208  uint64_t proof_of_work GNUNET_PACKED;
209 
214 };
216 
220 static const struct GNUNET_CONFIGURATION_Handle *cfg;
221 
226 
231 
236 
241 static double current_size_estimate;
242 
247 static double current_std_dev = NAN;
248 
252 static uint32_t hop_count_max;
253 
258 
263 
267 static unsigned int estimate_index;
268 
272 static unsigned int estimate_count;
273 
278 
283 
288 
293 
298 
303 
308 
312 static uint64_t my_proof;
313 
314 
321 static void
323 {
324  double mean;
325  double sum;
326  double std_dev;
327  double variance;
328  double val;
329  double nsize;
330 
331 #define WEST 1
332  /* Weighted incremental algorithm for stddev according to West (1979) */
333 #if WEST
334  double sumweight;
335  double weight;
336  double q;
337  double r;
338  double temp;
339 
340  mean = 0.0;
341  sum = 0.0;
342  sumweight = 0.0;
343  variance = 0.0;
344  for (unsigned int i = 0; i < estimate_count; i++)
345  {
346  unsigned int j = (estimate_index - i + HISTORY_SIZE) % HISTORY_SIZE;
347 
348  val = htonl (size_estimate_messages[j].matching_bits);
349  weight = estimate_count + 1 - i;
350 
351  temp = weight + sumweight;
352  q = val - mean;
353  r = q * weight / temp;
354  mean += r;
355  sum += sumweight * q * r;
356  sumweight = temp;
357  }
358  if (estimate_count > 0)
359  variance = (sum / sumweight) * estimate_count / (estimate_count - 1.0);
360 #else
361  /* trivial version for debugging */
362  double vsq;
363 
364  /* non-weighted trivial version */
365  sum = 0.0;
366  vsq = 0.0;
367  variance = 0.0;
368  mean = 0.0;
369 
370  for (unsigned int i = 0; i < estimate_count; i++)
371  {
372  unsigned int j = (estimate_index - i + HISTORY_SIZE) % HISTORY_SIZE;
373 
374  val = htonl (size_estimate_messages[j].matching_bits);
375  sum += val;
376  vsq += val * val;
377  }
378  if (0 != estimate_count)
379  {
380  mean = sum / estimate_count;
381  variance = (vsq - mean * sum)
382  / (estimate_count - 1.0); // terrible for numerical stability...
383  }
384 #endif
385  if (variance >= 0)
386  std_dev = sqrt (variance);
387  else
388  std_dev = variance; /* must be infinity due to estimate_count == 0 */
389  current_std_dev = std_dev;
390  current_size_estimate = mean;
391 
392  em->header.size = htons (sizeof(struct GNUNET_NSE_ClientMessage));
394  em->reserved = htonl (0);
396  {
397  double se = mean - 0.332747;
398  unsigned int j = GNUNET_CONTAINER_multipeermap_size (peers);
399  if (0 == j)
400  j = 1; /* Avoid log2(0); can only happen if CORE didn't report
401  connection to self yet */
402  nsize = log2 (j);
403  em->size_estimate = GNUNET_hton_double (GNUNET_MAX (se, nsize));
404  em->std_deviation = GNUNET_hton_double (std_dev);
405  GNUNET_STATISTICS_set (stats,
406  "# nodes in the network (estimate)",
407  (uint64_t) pow (2, GNUNET_MAX (se, nsize)),
408  GNUNET_NO);
409  }
410 }
411 
412 
422 static void
423 handle_start (void *cls, const struct GNUNET_MessageHeader *message)
424 {
425  struct GNUNET_SERVICE_Client *client = cls;
426  struct GNUNET_MQ_Handle *mq;
427  struct GNUNET_NSE_ClientMessage em;
428  struct GNUNET_MQ_Envelope *env;
429 
430  (void) message;
431  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received START message from client\n");
432  mq = GNUNET_SERVICE_client_get_mq (client);
435  env = GNUNET_MQ_msg_copy (&em.header);
436  GNUNET_MQ_send (mq, env);
438 }
439 
440 
447 static double
449 {
450  /* Calculated as: S + f/2 - (f / pi) * (atan(x - p')) */
451  // S is next_timestamp (ignored in return value)
452  // f is frequency (gnunet_nse_interval)
453  // x is matching_bits
454  // p' is current_size_estimate
455  return ((double) gnunet_nse_interval.rel_value_us / (double) 2.0)
457  * atan (matching_bits - current_size_estimate));
458 }
459 
460 
467 static struct GNUNET_TIME_Relative
469 {
470 #if USE_RANDOM_DELAYS
471  struct GNUNET_TIME_Relative ret;
472  uint32_t i;
473  double d;
474 
476  i = (uint32_t) (d / (double) (hop_count_max + 1));
477  ret.rel_value_us = i;
479  "Randomizing flood using latencies up to %s\n",
481  ret.rel_value_us =
483  return ret;
484 #else
485  return GNUNET_TIME_UNIT_ZERO;
486 #endif
487 }
488 
489 
497 static uint32_t
499  const struct GNUNET_PeerIdentity *id)
500 {
501  struct GNUNET_HashCode timestamp_hash;
502  struct GNUNET_HashCode pid_hash;
503 
504  GNUNET_CRYPTO_hash (&timestamp.abs_value_us,
505  sizeof(timestamp.abs_value_us),
506  &timestamp_hash);
507  GNUNET_CRYPTO_hash (id, sizeof(struct GNUNET_PeerIdentity), &pid_hash);
508  return GNUNET_CRYPTO_hash_matching_bits (&timestamp_hash, &pid_hash);
509 }
510 
511 
520 static struct GNUNET_TIME_Relative
521 get_transmit_delay (int round_offset)
522 {
523  struct GNUNET_TIME_Relative ret;
524  struct GNUNET_TIME_Absolute tgt;
525  double dist_delay;
526  uint32_t matching_bits;
527 
528  switch (round_offset)
529  {
530  case -1:
531  /* previous round is randomized between 0 and 50 ms */
532 #if USE_RANDOM_DELAYS
533  ret.rel_value_us =
535 #else
536  ret = GNUNET_TIME_UNIT_ZERO;
537 #endif
539  "Transmitting previous round behind schedule in %s\n",
541  return ret;
542 
543  case 0:
544  /* current round is based on best-known matching_bits */
545  matching_bits =
546  ntohl (size_estimate_messages[estimate_index].matching_bits);
547  dist_delay = get_matching_bits_delay (matching_bits);
548  dist_delay += get_delay_randomization (matching_bits).rel_value_us;
549  ret.rel_value_us = (uint64_t) dist_delay;
551  "For round %s, delay for %u matching bits is %s\n",
553  (unsigned int) matching_bits,
555  /* now consider round start time and add delay to it */
558  }
559  GNUNET_break (0);
561 }
562 
563 
569 static void
570 transmit_task_cb (void *cls)
571 {
572  struct NSEPeerEntry *peer_entry = cls;
573  unsigned int idx;
574  struct GNUNET_MQ_Envelope *env;
575 
576  peer_entry->transmit_task = NULL;
577  idx = estimate_index;
578  if (GNUNET_NO == peer_entry->previous_round)
579  {
580  idx = (idx + HISTORY_SIZE - 1) % HISTORY_SIZE;
581  peer_entry->previous_round = GNUNET_YES;
582  peer_entry->transmit_task =
585  peer_entry);
586  }
587  if ((0 == ntohl (size_estimate_messages[idx].hop_count)) &&
588  (NULL != proof_task))
589  {
591  "# flood messages not generated (no proof yet)",
592  1,
593  GNUNET_NO);
594  return;
595  }
596  if (0 == ntohs (size_estimate_messages[idx].header.size))
597  {
599  "# flood messages not generated (lack of history)",
600  1,
601  GNUNET_NO);
602  return;
603  }
605  "In round %s, sending to `%s' estimate with %u bits\n",
608  size_estimate_messages[idx].timestamp)),
609  GNUNET_i2s (peer_entry->id),
610  (unsigned int) ntohl (size_estimate_messages[idx].matching_bits));
611  if (0 == ntohl (size_estimate_messages[idx].hop_count))
612  GNUNET_STATISTICS_update (stats, "# flood messages started", 1, GNUNET_NO);
614  "# flood messages transmitted",
615  1,
616  GNUNET_NO);
617 #if ENABLE_NSE_HISTOGRAM
618  peer_entry->transmitted_messages++;
619  peer_entry->last_transmitted_size =
620  ntohl (size_estimate_messages[idx].matching_bits);
621 #endif
622  env = GNUNET_MQ_msg_copy (&size_estimate_messages[idx].header);
623  GNUNET_MQ_send (peer_entry->mq, env);
624 }
625 
626 
633 static void
635 {
636  struct GNUNET_NSE_ClientMessage em;
637 
640 }
641 
642 
650 static void
651 setup_flood_message (unsigned int slot, struct GNUNET_TIME_Absolute ts)
652 {
653  struct GNUNET_NSE_FloodMessage *fm;
654  uint32_t matching_bits;
655 
656  matching_bits = get_matching_bits (ts, &my_identity);
657  fm = &size_estimate_messages[slot];
658  fm->header.size = htons (sizeof(struct GNUNET_NSE_FloodMessage));
660  fm->hop_count = htonl (0);
662  fm->purpose.size =
663  htonl (sizeof(struct GNUNET_NSE_FloodMessage)
664  - sizeof(struct GNUNET_MessageHeader) - sizeof(uint32_t)
665  - sizeof(struct GNUNET_CRYPTO_EddsaSignature));
666  fm->matching_bits = htonl (matching_bits);
668  fm->origin = my_identity;
669  fm->proof_of_work = my_proof;
670  if (nse_work_required > 0)
672  &fm->purpose,
673  &fm->signature));
674  else
675  memset (&fm->signature, 0, sizeof(fm->signature));
676 }
677 
678 
688 static int
690  const struct GNUNET_PeerIdentity *key,
691  void *value)
692 {
693  struct NSEPeerEntry *peer_entry = value;
694  struct GNUNET_TIME_Relative delay;
695 
696  (void) cls;
697  (void) key;
698  if (NULL != peer_entry->transmit_task)
699  {
701  peer_entry->previous_round = GNUNET_NO;
702  }
703 #if ENABLE_NSE_HISTOGRAM
704  if (peer_entry->received_messages > 1)
706  "# extra messages",
707  peer_entry->received_messages - 1,
708  GNUNET_NO);
709  peer_entry->transmitted_messages = 0;
710  peer_entry->last_transmitted_size = 0;
711  peer_entry->received_messages = 0;
712 #endif
713  delay =
714  get_transmit_delay ((GNUNET_NO == peer_entry->previous_round) ? -1 : 0);
715  peer_entry->transmit_task =
716  GNUNET_SCHEDULER_add_delayed (delay, &transmit_task_cb, peer_entry);
717  return GNUNET_OK;
718 }
719 
720 
726 static void
728 {
729  struct GNUNET_TIME_Relative offset;
730 
731  (void) cls;
732  flood_task = NULL;
734  if (0 != offset.rel_value_us)
735  {
736  /* somehow run early, delay more */
737  flood_task =
739  return;
740  }
743  estimate_count++;
750  ntohl (next_message.matching_bits)))
751  {
752  /* we received a message for this round way early, use it! */
755  htonl (1 + ntohl (next_message.hop_count));
756  }
757  else
759  next_message.matching_bits = htonl (0); /* reset for 'next' round */
760  hop_count_max = 0;
761  for (unsigned int i = 0; i < HISTORY_SIZE; i++)
762  hop_count_max =
763  GNUNET_MAX (ntohl (size_estimate_messages[i].hop_count), hop_count_max);
765  flood_task =
767 }
768 
769 
776 static unsigned int
778 {
779  unsigned int hash_count;
780 
781  hash_count = 0;
782  while (0 == GNUNET_CRYPTO_hash_get_bit (hash, hash_count))
783  hash_count++;
784  return hash_count;
785 }
786 
787 
796 static int
798  uint64_t val)
799 {
800  char buf[sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)
801  + sizeof(val)] GNUNET_ALIGN;
802  struct GNUNET_HashCode result;
803 
804  GNUNET_memcpy (buf, &val, sizeof(val));
805  GNUNET_memcpy (&buf[sizeof(val)],
806  pkey,
807  sizeof(struct GNUNET_CRYPTO_EddsaPublicKey));
808  GNUNET_CRYPTO_pow_hash ("gnunet-nse-proof-of-work",
809  buf,
810  sizeof(buf),
811  &result);
812  return (count_leading_zeroes (&result) >= nse_work_required) ? GNUNET_YES
813  : GNUNET_NO;
814 }
815 
816 
820 static void
822 {
823  char *proof;
824 
825  if (GNUNET_OK !=
826  GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "PROOFFILE", &proof))
827  return;
828  if (sizeof(my_proof) != GNUNET_DISK_fn_write (proof,
829  &my_proof,
830  sizeof(my_proof),
834  GNUNET_free (proof);
835 }
836 
837 
843 static void
844 find_proof (void *cls)
845 {
846 #define ROUND_SIZE 10
847  uint64_t counter;
848  char buf[sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)
849  + sizeof(uint64_t)] GNUNET_ALIGN;
850  struct GNUNET_HashCode result;
851  unsigned int i;
852 
853  (void) cls;
854  proof_task = NULL;
855  GNUNET_memcpy (&buf[sizeof(uint64_t)],
856  &my_identity,
857  sizeof(struct GNUNET_PeerIdentity));
858  i = 0;
859  counter = my_proof;
860  while ((counter != UINT64_MAX) && (i < ROUND_SIZE))
861  {
862  GNUNET_memcpy (buf, &counter, sizeof(uint64_t));
863  GNUNET_CRYPTO_pow_hash ("gnunet-nse-proof-of-work",
864  buf,
865  sizeof(buf),
866  &result);
867  if (nse_work_required <= count_leading_zeroes (&result))
868  {
869  my_proof = counter;
871  "Proof of work found: %llu!\n",
872  (unsigned long long) GNUNET_ntohll (counter));
873  write_proof ();
875  return;
876  }
877  counter++;
878  i++;
879  }
880  if (my_proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE))
881  {
883  "Testing proofs currently at %llu\n",
884  (unsigned long long) counter);
885  /* remember progress every 100 rounds */
886  my_proof = counter;
887  write_proof ();
888  }
889  else
890  {
891  my_proof = counter;
892  }
893  proof_task =
896  &find_proof,
897  NULL);
898 }
899 
900 
910 static int
911 verify_message_crypto (const struct GNUNET_NSE_FloodMessage *incoming_flood)
912 {
913  if (GNUNET_YES != check_proof_of_work (&incoming_flood->origin.public_key,
914  incoming_flood->proof_of_work))
915  {
917  "Proof of work invalid: %llu!\n",
918  (unsigned long long) GNUNET_ntohll (
919  incoming_flood->proof_of_work));
920  GNUNET_break_op (0);
921  return GNUNET_NO;
922  }
923  if ((nse_work_required > 0) &&
924  (GNUNET_OK !=
926  &incoming_flood->purpose,
927  &incoming_flood->signature,
928  &incoming_flood->origin.public_key)))
929  {
930  GNUNET_break_op (0);
931  return GNUNET_NO;
932  }
933  return GNUNET_YES;
934 }
935 
936 
946 static int
948  const struct GNUNET_PeerIdentity *key,
949  void *value)
950 {
951  struct NSEPeerEntry *exclude = cls;
952  struct NSEPeerEntry *peer_entry = value;
953  struct GNUNET_TIME_Relative delay;
954 
955  (void) key;
956  if (peer_entry == exclude)
957  return GNUNET_OK; /* trigger of the update */
958  if (GNUNET_NO == peer_entry->previous_round)
959  {
960  /* still stuck in previous round, no point to update, check that
961  * we are active here though... */
962  if (NULL == peer_entry->transmit_task)
963  {
964  GNUNET_break (0);
965  }
966  return GNUNET_OK;
967  }
968  if (NULL != peer_entry->transmit_task)
969  {
971  peer_entry->transmit_task = NULL;
972  }
973  delay = get_transmit_delay (0);
974  peer_entry->transmit_task =
975  GNUNET_SCHEDULER_add_delayed (delay, &transmit_task_cb, peer_entry);
976  return GNUNET_OK;
977 }
978 
979 
986 static void
988  const struct GNUNET_NSE_FloodMessage *incoming_flood)
989 {
990  struct NSEPeerEntry *peer_entry = cls;
991  struct GNUNET_TIME_Absolute ts;
992  uint32_t matching_bits;
993  unsigned int idx;
994 
995 #if ENABLE_NSE_HISTOGRAM
996  {
997  uint64_t t;
998 
1000  if (NULL != lh)
1001  GNUNET_TESTBED_LOGGER_write (lh, &t, sizeof(uint64_t));
1002  if (NULL != histogram)
1003  GNUNET_BIO_write_int64 (histogram, t);
1004  }
1005 #endif
1006  GNUNET_STATISTICS_update (stats, "# flood messages received", 1, GNUNET_NO);
1007  matching_bits = ntohl (incoming_flood->matching_bits);
1008 #if DEBUG_NSE
1009  {
1010  char origin[5];
1011  char pred[5];
1012  struct GNUNET_PeerIdentity os;
1013 
1014  GNUNET_snprintf (origin,
1015  sizeof(origin),
1016  "%s",
1017  GNUNET_i2s (&incoming_flood->origin));
1018  GNUNET_snprintf (pred, sizeof(pred), "%s", GNUNET_i2s (peer_entry->id));
1020  "Flood at %s from `%s' via `%s' at `%s' with bits %u\n",
1022  GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp)),
1023  origin,
1024  pred,
1026  (unsigned int) matching_bits);
1027  }
1028 #endif
1029 
1030 #if ENABLE_NSE_HISTOGRAM
1031  peer_entry->received_messages++;
1032  if ((peer_entry->transmitted_messages > 0) &&
1033  (peer_entry->last_transmitted_size >= matching_bits) )
1034  GNUNET_STATISTICS_update (stats, "# cross messages", 1, GNUNET_NO);
1035 #endif
1036 
1037  ts = GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp);
1039  idx = estimate_index;
1040  else if (ts.abs_value_us ==
1042  idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE;
1043  else if (ts.abs_value_us == next_timestamp.abs_value_us)
1044  {
1045  if (matching_bits <= ntohl (next_message.matching_bits))
1046  return; /* ignore, simply too early/late */
1047  if (GNUNET_YES != verify_message_crypto (incoming_flood))
1048  {
1050  "Peer %s is likely ill-configured!\n",
1051  GNUNET_i2s (peer_entry->id));
1052  GNUNET_break_op (0);
1053  return;
1054  }
1055  next_message = *incoming_flood;
1056  return;
1057  }
1058  else
1059  {
1060  GNUNET_STATISTICS_update (stats,
1061  "# flood messages discarded (clock skew too large)",
1062  1,
1063  GNUNET_NO);
1064  return;
1065  }
1066  if (0 == (GNUNET_memcmp (peer_entry->id, &my_identity)))
1067  {
1068  /* send to self, update our own estimate IF this also comes from us! */
1069  if (0 == GNUNET_memcmp (&incoming_flood->origin, &my_identity))
1071  return;
1072  }
1073  if (matching_bits == ntohl (size_estimate_messages[idx].matching_bits))
1074  {
1075  /* Cancel transmission in the other direction, as this peer clearly has
1076  up-to-date information already. Even if we didn't talk to this peer in
1077  the previous round, we should no longer send it stale information as it
1078  told us about the current round! */
1079  peer_entry->previous_round = GNUNET_YES;
1080  if (idx != estimate_index)
1081  {
1082  /* do not transmit information for the previous round to this peer
1083  anymore (but allow current round) */
1084  return;
1085  }
1086  /* got up-to-date information for current round, cancel transmission to
1087  * this peer altogether */
1088  if (NULL != peer_entry->transmit_task)
1089  {
1090  GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
1091  peer_entry->transmit_task = NULL;
1092  }
1093  return;
1094  }
1095  if (matching_bits < ntohl (size_estimate_messages[idx].matching_bits))
1096  {
1097  if ((idx < estimate_index) && (peer_entry->previous_round == GNUNET_YES))
1098  {
1099  peer_entry->previous_round = GNUNET_NO;
1100  }
1101  /* push back our result now, that peer is spreading bad information... */
1102  if (NULL != peer_entry->transmit_task)
1103  GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
1104  peer_entry->transmit_task =
1106  /* Not closer than our most recent message, no need to do work here */
1107  GNUNET_STATISTICS_update (stats,
1108  "# flood messages ignored (had closer already)",
1109  1,
1110  GNUNET_NO);
1111  return;
1112  }
1113  if (GNUNET_YES != verify_message_crypto (incoming_flood))
1114  {
1115  GNUNET_break_op (0);
1116  return;
1117  }
1118  GNUNET_assert (matching_bits >
1119  ntohl (size_estimate_messages[idx].matching_bits));
1120  /* Cancel transmission in the other direction, as this peer clearly has
1121  * up-to-date information already.
1122  */
1123  peer_entry->previous_round = GNUNET_YES;
1124  if (idx == estimate_index)
1125  {
1126  /* cancel any activity for current round */
1127  if (NULL != peer_entry->transmit_task)
1128  {
1129  GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
1130  peer_entry->transmit_task = NULL;
1131  }
1132  }
1133  size_estimate_messages[idx] = *incoming_flood;
1135  htonl (ntohl (incoming_flood->hop_count) + 1);
1136  hop_count_max =
1137  GNUNET_MAX (ntohl (incoming_flood->hop_count) + 1, hop_count_max);
1138  GNUNET_STATISTICS_set (stats,
1139  "# estimated network diameter",
1140  hop_count_max,
1141  GNUNET_NO);
1142 
1143  /* have a new, better size estimate, inform clients */
1145 
1146  /* flood to rest */
1149  peer_entry);
1150 }
1151 
1152 
1160 static void *
1162  const struct GNUNET_PeerIdentity *peer,
1163  struct GNUNET_MQ_Handle *mq)
1164 {
1165  struct NSEPeerEntry *peer_entry;
1166 
1167  (void) cls;
1169  "Peer `%s' connected to us\n",
1170  GNUNET_i2s (peer));
1171  /* set our default transmission options */
1173  /* create our peer entry for this peer */
1174  peer_entry = GNUNET_new (struct NSEPeerEntry);
1175  peer_entry->id = peer;
1176  peer_entry->mq = mq;
1179  peers,
1180  peer_entry->id,
1181  peer_entry,
1183  peer_entry->transmit_task =
1186  peer_entry);
1187  GNUNET_STATISTICS_update (stats, "# peers connected", 1, GNUNET_NO);
1188  return peer_entry;
1189 }
1190 
1191 
1200 static void
1202  const struct GNUNET_PeerIdentity *peer,
1203  void *internal_cls)
1204 {
1205  struct NSEPeerEntry *pos = internal_cls;
1206 
1207  (void) cls;
1209  "Peer `%s' disconnected from us\n",
1210  GNUNET_i2s (peer));
1212  GNUNET_CONTAINER_multipeermap_remove (peers, peer, pos));
1213  if (NULL != pos->transmit_task)
1214  {
1216  pos->transmit_task = NULL;
1217  }
1218  GNUNET_free (pos);
1219  GNUNET_STATISTICS_update (stats, "# peers connected", -1, GNUNET_NO);
1220 }
1221 
1222 
1223 #if ENABLE_NSE_HISTOGRAM
1224 
1231 static void
1232 flush_comp_cb (void *cls, size_t size)
1233 {
1234  (void) cls;
1235  (void) size;
1237  lh = NULL;
1238 }
1239 
1240 
1241 #endif
1242 
1243 
1249 static void
1250 shutdown_task (void *cls)
1251 {
1252  (void) cls;
1253  if (NULL != flood_task)
1254  {
1255  GNUNET_SCHEDULER_cancel (flood_task);
1256  flood_task = NULL;
1257  }
1258  if (NULL != proof_task)
1259  {
1260  GNUNET_SCHEDULER_cancel (proof_task);
1261  proof_task = NULL;
1262  write_proof (); /* remember progress */
1263  }
1264  if (NULL != nc)
1265  {
1267  nc = NULL;
1268  }
1269  if (NULL != core_api)
1270  {
1271  GNUNET_CORE_disconnect (core_api);
1272  core_api = NULL;
1273  }
1274  if (NULL != stats)
1275  {
1277  stats = NULL;
1278  }
1279  if (NULL != peers)
1280  {
1282  peers = NULL;
1283  }
1284  if (NULL != my_private_key)
1285  {
1286  GNUNET_free (my_private_key);
1287  my_private_key = NULL;
1288  }
1289 #if ENABLE_NSE_HISTOGRAM
1290  if (NULL != logger_test)
1291  {
1292  GNUNET_CLIENT_service_test_cancel (logger_test);
1293  logger_test = NULL;
1294  }
1295  if (NULL != lh)
1296  {
1297  GNUNET_TESTBED_LOGGER_flush (lh, &flush_comp_cb, NULL);
1298  }
1299  if (NULL != histogram)
1300  {
1301  GNUNET_BIO_write_close (histogram);
1302  histogram = NULL;
1303  }
1304 #endif
1305 }
1306 
1307 
1314 static void
1315 core_init (void *cls, const struct GNUNET_PeerIdentity *identity)
1316 {
1317  struct GNUNET_TIME_Absolute now;
1318  struct GNUNET_TIME_Absolute prev_time;
1319 
1320  (void) cls;
1321  if (NULL == identity)
1322  {
1323  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection to core FAILED!\n");
1325  return;
1326  }
1327  GNUNET_assert (0 == GNUNET_memcmp (&my_identity, identity));
1328  now = GNUNET_TIME_absolute_get ();
1332  next_timestamp =
1335  estimate_count = 0;
1337  {
1338  int idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE;
1339  prev_time.abs_value_us =
1341  setup_flood_message (idx, prev_time);
1343  estimate_count++;
1344  }
1345  flood_task =
1347 }
1348 
1349 
1350 #if ENABLE_NSE_HISTOGRAM
1351 
1359 static void
1360 status_cb (void *cls, int status)
1361 {
1362  (void) cls;
1363  logger_test = NULL;
1364  if (GNUNET_YES != status)
1365  {
1366  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Testbed logger not running\n");
1367  return;
1368  }
1369  if (NULL == (lh = GNUNET_TESTBED_LOGGER_connect (cfg)))
1370  {
1372  "Cannot connect to the testbed logger. Exiting.\n");
1374  }
1375 }
1376 
1377 
1378 #endif
1379 
1380 
1388 static void
1389 run (void *cls,
1390  const struct GNUNET_CONFIGURATION_Handle *c,
1392 {
1393  struct GNUNET_MQ_MessageHandler core_handlers[] =
1394  { GNUNET_MQ_hd_fixed_size (p2p_estimate,
1396  struct GNUNET_NSE_FloodMessage,
1397  NULL),
1398  GNUNET_MQ_handler_end () };
1399  char *proof;
1401 
1402  (void) cls;
1403  (void) service;
1404  cfg = c;
1406  "NSE",
1407  "INTERVAL",
1409  {
1412  return;
1413  }
1415  "NSE",
1416  "WORKDELAY",
1417  &proof_find_delay))
1418  {
1419  GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKDELAY");
1421  return;
1422  }
1424  "NSE",
1425  "WORKBITS",
1427  {
1430  return;
1431  }
1432  if (nse_work_required >= sizeof(struct GNUNET_HashCode) * 8)
1433  {
1435  "NSE",
1436  "WORKBITS",
1437  _ ("Value is too large.\n"));
1439  return;
1440  }
1441 
1442 #if ENABLE_NSE_HISTOGRAM
1443  {
1444  char *histogram_dir;
1445  char *histogram_fn;
1446 
1448  "NSE",
1449  "HISTOGRAM_DIR",
1450  &histogram_dir))
1451  {
1452  GNUNET_assert (
1453  0 < GNUNET_asprintf (&histogram_fn, "%s/timestamps", histogram_dir));
1454  GNUNET_free (histogram_dir);
1455  histogram = GNUNET_BIO_write_open (histogram_fn);
1456  if (NULL == histogram)
1458  "Unable to open histogram file `%s'\n",
1459  histogram_fn);
1460  GNUNET_free (histogram_fn);
1461  }
1462  logger_test = GNUNET_CLIENT_service_test ("testbed-logger",
1463  cfg,
1465  &status_cb,
1466  NULL);
1467  }
1468 #endif
1469 
1472  GNUNET_assert (NULL != pk);
1473  my_private_key = pk;
1475  if (GNUNET_OK !=
1476  GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "PROOFFILE", &proof))
1477  {
1478  GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "PROOFFILE");
1479  GNUNET_free (my_private_key);
1480  my_private_key = NULL;
1482  return;
1483  }
1484  if ((GNUNET_YES != GNUNET_DISK_file_test (proof)) ||
1485  (sizeof(my_proof) !=
1486  GNUNET_DISK_fn_read (proof, &my_proof, sizeof(my_proof))))
1487  my_proof = 0;
1488  GNUNET_free (proof);
1489  proof_task =
1491  &find_proof,
1492  NULL);
1493 
1496  /* Connect to core service and register core handlers */
1497  core_api =
1498  GNUNET_CORE_connect (cfg, /* Main configuration */
1499  NULL, /* Closure passed to functions */
1500  &core_init, /* Call core_init once connected */
1501  &handle_core_connect, /* Handle connects */
1502  &handle_core_disconnect, /* Handle disconnects */
1503  core_handlers); /* Register these handlers */
1504  if (NULL == core_api)
1505  {
1507  return;
1508  }
1509  stats = GNUNET_STATISTICS_create ("nse", cfg);
1510 }
1511 
1512 
1521 static void *
1523  struct GNUNET_SERVICE_Client *c,
1524  struct GNUNET_MQ_Handle *mq)
1525 {
1526  (void) cls;
1527  (void) mq;
1528  return c;
1529 }
1530 
1531 
1539 static void
1541  struct GNUNET_SERVICE_Client *c,
1542  void *internal_cls)
1543 {
1544  (void) cls;
1545  GNUNET_assert (c == internal_cls);
1546 }
1547 
1548 
1552 GNUNET_SERVICE_MAIN ("nse",
1554  &run,
1557  NULL,
1560  struct GNUNET_MessageHeader,
1561  NULL),
1563 
1564 
1565 #if defined(__linux__) && defined(__GLIBC__)
1566 #include <malloc.h>
1567 
1571 void __attribute__ ((constructor))
1572 GNUNET_ARM_memory_init ()
1573 {
1574  mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1575  mallopt (M_TOP_PAD, 1 * 1024);
1576  malloc_trim (0);
1577 }
1578 
1579 
1580 #endif
1581 
1582 
1583 /* 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:544
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:662
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition: nc.c:75
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:673
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:77
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:1201
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2433
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:1333
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:272
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:599
#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:745
Network size estimate sent from the service to clients.
Definition: nse.h:42
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
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:86
#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:83
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:395
#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:531
static struct GNUNET_TIME_Relative gnunet_nse_interval
Interval for sending network size estimation flood requests.
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:160
uint64_t abs_value_us
The actual value.
ssize_t GNUNET_DISK_fn_write(const char *fn, const void *buffer, size_t n, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file.
Definition: disk.c:879
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:180
Handle to a client that is connected to a service.
Definition: service.c:250
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:1271
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:1225
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:844
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:48
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:90
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:1298
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:701
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]
#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:379
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.
void GNUNET_CRYPTO_pow_hash(const char *salt, const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
Calculate the &#39;proof-of-work&#39; hash (an expensive hash).
Definition: crypto_pow.c:41
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 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:251
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:692
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition: core_api.c:730
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:438
#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:189
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:121
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:1079
void GNUNET_notification_context_broadcast(struct GNUNET_NotificationContext *nc, const struct GNUNET_MessageHeader *msg, int can_drop)
Send a message to all subscribers of this context.
Definition: nc.c:189
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:84
struct GNUNET_BIO_WriteHandle * GNUNET_BIO_write_open(const char *fn)
Open a file for writing.
Definition: bio.c:410
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:85
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:137
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:355
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:756
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:1248
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
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:2239
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:74
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:794
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:53
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:974
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...