GNUnet  0.19.4
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 
119 static struct GNUNET_CRYPTO_PowSalt salt = { "gnunet-nse-proof" };
120 
121 
126 {
131 
135  const struct GNUNET_PeerIdentity *id;
136 
141 
148 
149 #if ENABLE_NSE_HISTOGRAM
153  unsigned int received_messages;
154 
158  unsigned int transmitted_messages;
159 
163  unsigned int last_transmitted_size;
164 #endif
165 };
166 
167 
169 
176 {
181 
186 
191 
197 
204 
209 
214 
219 };
221 
225 static const struct GNUNET_CONFIGURATION_Handle *cfg;
226 
231 
236 
241 
246 static double current_size_estimate;
247 
252 static double current_std_dev = NAN;
253 
257 static uint32_t hop_count_max;
258 
263 
268 
272 static unsigned int estimate_index;
273 
277 static unsigned int estimate_count;
278 
283 
288 
293 
298 
303 
308 
312 static struct GNUNET_PeerIdentity my_identity;
313 
317 static uint64_t my_proof;
318 
319 
326 static void
328 {
329  double mean;
330  double sum;
331  double std_dev;
332  double variance;
333  double val;
334  double nsize;
335 
336 #define WEST 1
337  /* Weighted incremental algorithm for stddev according to West (1979) */
338 #if WEST
339  double sumweight;
340  double weight;
341  double q;
342  double r;
343  double temp;
344 
345  mean = 0.0;
346  sum = 0.0;
347  sumweight = 0.0;
348  variance = 0.0;
349  for (unsigned int i = 0; i < estimate_count; i++)
350  {
351  unsigned int j = (estimate_index - i + HISTORY_SIZE) % HISTORY_SIZE;
352 
353  val = htonl (size_estimate_messages[j].matching_bits);
354  weight = estimate_count + 1 - i;
355 
356  temp = weight + sumweight;
357  q = val - mean;
358  r = q * weight / temp;
359  mean += r;
360  sum += sumweight * q * r;
361  sumweight = temp;
362  }
363  if (estimate_count > 0)
364  variance = (sum / sumweight) * estimate_count / (estimate_count - 1.0);
365 #else
366  /* trivial version for debugging */
367  double vsq;
368 
369  /* non-weighted trivial version */
370  sum = 0.0;
371  vsq = 0.0;
372  variance = 0.0;
373  mean = 0.0;
374 
375  for (unsigned int i = 0; i < estimate_count; i++)
376  {
377  unsigned int j = (estimate_index - i + HISTORY_SIZE) % HISTORY_SIZE;
378 
379  val = htonl (size_estimate_messages[j].matching_bits);
380  sum += val;
381  vsq += val * val;
382  }
383  if (0 != estimate_count)
384  {
385  mean = sum / estimate_count;
386  variance = (vsq - mean * sum)
387  / (estimate_count - 1.0); // terrible for numerical stability...
388  }
389 #endif
390  if (variance >= 0)
391  std_dev = sqrt (variance);
392  else
393  std_dev = variance; /* return NaN (due to estimate_count == 0 causing 0.0/0.0) */
394  current_std_dev = std_dev;
395  current_size_estimate = mean;
396 
397  em->header.size = htons (sizeof(struct GNUNET_NSE_ClientMessage));
399  em->reserved = htonl (0);
401  {
402  double se = mean - 0.332747;
403  unsigned int j = GNUNET_CONTAINER_multipeermap_size (peers);
404  if (0 == j)
405  j = 1; /* Avoid log2(0); can only happen if CORE didn't report
406  connection to self yet */
407  nsize = log2 (j);
408  em->size_estimate = GNUNET_hton_double (GNUNET_MAX (se, nsize));
409  em->std_deviation = GNUNET_hton_double (std_dev);
411  "# nodes in the network (estimate)",
412  (uint64_t) pow (2, GNUNET_MAX (se, nsize)),
413  GNUNET_NO);
414  }
415 }
416 
417 
427 static void
428 handle_start (void *cls, const struct GNUNET_MessageHeader *message)
429 {
430  struct GNUNET_SERVICE_Client *client = cls;
431  struct GNUNET_MQ_Handle *mq;
432  struct GNUNET_NSE_ClientMessage em;
433  struct GNUNET_MQ_Envelope *env;
434 
435  (void) message;
436  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received START message from client\n");
437  mq = GNUNET_SERVICE_client_get_mq (client);
440  env = GNUNET_MQ_msg_copy (&em.header);
441  GNUNET_MQ_send (mq, env);
443 }
444 
445 
452 static double
454 {
455  /* Calculated as: S + f/2 - (f / pi) * (atan(x - p')) */
456  // S is next_timestamp (ignored in return value)
457  // f is frequency (gnunet_nse_interval)
458  // x is matching_bits
459  // p' is current_size_estimate
460  return ((double) gnunet_nse_interval.rel_value_us / (double) 2.0)
463 }
464 
465 
472 static struct GNUNET_TIME_Relative
474 {
475 #if USE_RANDOM_DELAYS
476  struct GNUNET_TIME_Relative ret;
477  uint32_t i;
478  double d;
479 
481  i = (uint32_t) (d / (double) (hop_count_max + 1));
482  ret.rel_value_us = i;
484  "Randomizing flood using latencies up to %s\n",
486  ret.rel_value_us =
488  return ret;
489 #else
490  return GNUNET_TIME_UNIT_ZERO;
491 #endif
492 }
493 
494 
502 static uint32_t
504  const struct GNUNET_PeerIdentity *id)
505 {
506  struct GNUNET_HashCode timestamp_hash;
507  struct GNUNET_HashCode pid_hash;
508  struct GNUNET_HashCode xor;
509 
510  GNUNET_CRYPTO_hash (&timestamp.abs_value_us,
511  sizeof(timestamp.abs_value_us),
512  &timestamp_hash);
513  GNUNET_CRYPTO_hash (id,
514  sizeof(struct GNUNET_PeerIdentity),
515  &pid_hash);
516  GNUNET_CRYPTO_hash_xor (&pid_hash,
517  &timestamp_hash,
518  &xor);
520 }
521 
522 
531 static struct GNUNET_TIME_Relative
532 get_transmit_delay (int round_offset)
533 {
534  struct GNUNET_TIME_Relative ret;
535  struct GNUNET_TIME_Absolute tgt;
536  double dist_delay;
537  uint32_t matching_bits;
538 
539  switch (round_offset)
540  {
541  case -1:
542  /* previous round is randomized between 0 and 50 ms */
543 #if USE_RANDOM_DELAYS
544  ret.rel_value_us =
546 #else
548 #endif
550  "Transmitting previous round behind schedule in %s\n",
552  return ret;
553 
554  case 0:
555  /* current round is based on best-known matching_bits */
556  matching_bits =
558  dist_delay = get_matching_bits_delay (matching_bits);
560  ret.rel_value_us = (uint64_t) dist_delay;
562  "For round %s, delay for %u matching bits is %s\n",
564  (unsigned int) matching_bits,
566  /* now consider round start time and add delay to it */
569  }
570  GNUNET_break (0);
572 }
573 
574 
580 static void
581 transmit_task_cb (void *cls)
582 {
583  struct NSEPeerEntry *peer_entry = cls;
584  unsigned int idx;
585  struct GNUNET_MQ_Envelope *env;
586 
587  peer_entry->transmit_task = NULL;
588  idx = estimate_index;
589  if (GNUNET_NO == peer_entry->previous_round)
590  {
591  idx = (idx + HISTORY_SIZE - 1) % HISTORY_SIZE;
592  peer_entry->previous_round = GNUNET_YES;
593  peer_entry->transmit_task =
596  peer_entry);
597  }
598  if ((0 == ntohl (size_estimate_messages[idx].hop_count)) &&
599  (NULL != proof_task))
600  {
602  "# flood messages not generated (no proof yet)",
603  1,
604  GNUNET_NO);
605  return;
606  }
607  if (0 == ntohs (size_estimate_messages[idx].header.size))
608  {
610  "# flood messages not generated (lack of history)",
611  1,
612  GNUNET_NO);
613  return;
614  }
616  "In round %s, sending to `%s' estimate with %u bits\n",
619  size_estimate_messages[idx].timestamp)),
620  GNUNET_i2s (peer_entry->id),
621  (unsigned int) ntohl (size_estimate_messages[idx].matching_bits));
622  if (0 == ntohl (size_estimate_messages[idx].hop_count))
623  GNUNET_STATISTICS_update (stats, "# flood messages started", 1, GNUNET_NO);
625  "# flood messages transmitted",
626  1,
627  GNUNET_NO);
628 #if ENABLE_NSE_HISTOGRAM
629  peer_entry->transmitted_messages++;
630  peer_entry->last_transmitted_size =
632 #endif
634  GNUNET_MQ_send (peer_entry->mq, env);
635 }
636 
637 
644 static void
646 {
647  struct GNUNET_NSE_ClientMessage em;
648 
651 }
652 
653 
661 static void
662 setup_flood_message (unsigned int slot, struct GNUNET_TIME_Absolute ts)
663 {
664  struct GNUNET_NSE_FloodMessage *fm;
665  uint32_t matching_bits;
666 
668  fm = &size_estimate_messages[slot];
669  fm->header.size = htons (sizeof(struct GNUNET_NSE_FloodMessage));
671  fm->hop_count = htonl (0);
673  fm->purpose.size =
674  htonl (sizeof(struct GNUNET_NSE_FloodMessage)
675  - sizeof(struct GNUNET_MessageHeader) - sizeof(uint32_t)
676  - sizeof(struct GNUNET_CRYPTO_EddsaSignature));
677  fm->matching_bits = htonl (matching_bits);
679  fm->origin = my_identity;
680  fm->proof_of_work = my_proof;
681  if (nse_work_required > 0)
684  &fm->purpose,
685  &fm->signature));
686  else
687  memset (&fm->signature, 0, sizeof(fm->signature));
688 }
689 
690 
700 static int
702  const struct GNUNET_PeerIdentity *key,
703  void *value)
704 {
705  struct NSEPeerEntry *peer_entry = value;
707 
708  (void) cls;
709  (void) key;
710  if (NULL != peer_entry->transmit_task)
711  {
713  peer_entry->previous_round = GNUNET_NO;
714  }
715 #if ENABLE_NSE_HISTOGRAM
716  if (peer_entry->received_messages > 1)
718  "# extra messages",
719  peer_entry->received_messages - 1,
720  GNUNET_NO);
721  peer_entry->transmitted_messages = 0;
722  peer_entry->last_transmitted_size = 0;
723  peer_entry->received_messages = 0;
724 #endif
725  delay =
726  get_transmit_delay ((GNUNET_NO == peer_entry->previous_round) ? -1 : 0);
727  peer_entry->transmit_task =
729  return GNUNET_OK;
730 }
731 
732 
738 static void
740 {
741  struct GNUNET_TIME_Relative offset;
742 
743  (void) cls;
744  flood_task = NULL;
746  if (0 != offset.rel_value_us)
747  {
748  /* somehow run early, delay more */
749  flood_task =
751  return;
752  }
755  estimate_count++;
762  ntohl (next_message.matching_bits)))
763  {
764  /* we received a message for this round way early, use it! */
767  htonl (1 + ntohl (next_message.hop_count));
768  }
769  else
771  next_message.matching_bits = htonl (0); /* reset for 'next' round */
772  hop_count_max = 0;
773  for (unsigned int i = 0; i < HISTORY_SIZE; i++)
774  hop_count_max =
775  GNUNET_MAX (ntohl (size_estimate_messages[i].hop_count), hop_count_max);
777  flood_task =
779 }
780 
781 
790 static enum GNUNET_GenericReturnValue
792  uint64_t val)
793 {
794  char buf[sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)
795  + sizeof(val)] GNUNET_ALIGN;
796  struct GNUNET_HashCode result;
797 
798  GNUNET_memcpy (buf, &val, sizeof(val));
799  GNUNET_memcpy (&buf[sizeof(val)],
800  pkey,
801  sizeof(struct GNUNET_CRYPTO_EddsaPublicKey));
803  buf,
804  sizeof(buf),
805  &result);
808  ? GNUNET_YES
809  : GNUNET_NO;
810 }
811 
812 
816 static void
818 {
819  char *proof;
820 
821  if (GNUNET_OK !=
823  "NSE",
824  "PROOFFILE",
825  &proof))
826  return;
828  if (GNUNET_OK !=
830  &my_proof,
831  sizeof(my_proof),
835  "write",
836  proof);
837  GNUNET_free (proof);
838 }
839 
840 
846 static void
847 find_proof (void *cls)
848 {
849 #define ROUND_SIZE 10
850  uint64_t counter;
851  char buf[sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)
852  + sizeof(uint64_t)] GNUNET_ALIGN;
853  struct GNUNET_HashCode result;
854  unsigned int i;
855 
856  (void) cls;
857  proof_task = NULL;
858  GNUNET_memcpy (&buf[sizeof(uint64_t)],
859  &my_identity,
860  sizeof(struct GNUNET_PeerIdentity));
861  i = 0;
862  counter = my_proof;
863  while ((counter != UINT64_MAX) && (i < ROUND_SIZE))
864  {
865  GNUNET_memcpy (buf, &counter, sizeof(uint64_t));
867  buf,
868  sizeof(buf),
869  &result);
870  if (nse_work_required <=
872  {
873  my_proof = counter;
875  "Proof of work found: %llu!\n",
876  (unsigned long long) GNUNET_ntohll (counter));
877  write_proof ();
879  return;
880  }
881  counter++;
882  i++;
883  }
884  if (my_proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE))
885  {
887  "Testing proofs currently at %llu\n",
888  (unsigned long long) counter);
889  /* remember progress every 100 rounds */
890  my_proof = counter;
891  write_proof ();
892  }
893  else
894  {
895  my_proof = counter;
896  }
897  proof_task =
900  &find_proof,
901  NULL);
902 }
903 
904 
914 static int
915 verify_message_crypto (const struct GNUNET_NSE_FloodMessage *incoming_flood)
916 {
917  if (GNUNET_YES != check_proof_of_work (&incoming_flood->origin.public_key,
918  incoming_flood->proof_of_work))
919  {
921  "Proof of work invalid: %llu!\n",
922  (unsigned long long) GNUNET_ntohll (
923  incoming_flood->proof_of_work));
924  GNUNET_break_op (0);
925  return GNUNET_NO;
926  }
927  if ((nse_work_required > 0) &&
928  (GNUNET_OK !=
930  &incoming_flood->purpose,
931  &incoming_flood->signature,
932  &incoming_flood->origin.public_key)))
933  {
934  GNUNET_break_op (0);
935  return GNUNET_NO;
936  }
937  return GNUNET_YES;
938 }
939 
940 
950 static int
952  const struct GNUNET_PeerIdentity *key,
953  void *value)
954 {
955  struct NSEPeerEntry *exclude = cls;
956  struct NSEPeerEntry *peer_entry = value;
958 
959  (void) key;
960  if (peer_entry == exclude)
961  return GNUNET_OK; /* trigger of the update */
962  if (GNUNET_NO == peer_entry->previous_round)
963  {
964  /* still stuck in previous round, no point to update, check that
965  * we are active here though... */
966  if (NULL == peer_entry->transmit_task)
967  {
968  GNUNET_break (0);
969  }
970  return GNUNET_OK;
971  }
972  if (NULL != peer_entry->transmit_task)
973  {
975  peer_entry->transmit_task = NULL;
976  }
978  peer_entry->transmit_task =
980  return GNUNET_OK;
981 }
982 
983 
990 static void
992  const struct GNUNET_NSE_FloodMessage *incoming_flood)
993 {
994  struct NSEPeerEntry *peer_entry = cls;
995  struct GNUNET_TIME_Absolute ts;
996  uint32_t matching_bits;
997  unsigned int idx;
998 
999 #if ENABLE_NSE_HISTOGRAM
1000  {
1001  uint64_t t;
1002 
1004  if (NULL != lh)
1005  GNUNET_TESTBED_LOGGER_write (lh, &t, sizeof(uint64_t));
1006  if (NULL != histogram)
1007  GNUNET_BIO_write_int64 (histogram, "histogram-time", t);
1008  }
1009 #endif
1010  GNUNET_STATISTICS_update (stats, "# flood messages received", 1, GNUNET_NO);
1011  matching_bits = ntohl (incoming_flood->matching_bits);
1012 #if DEBUG_NSE
1013  {
1014  char origin[5];
1015  char pred[5];
1016  struct GNUNET_PeerIdentity os;
1017 
1019  sizeof(origin),
1020  "%s",
1021  GNUNET_i2s (&incoming_flood->origin));
1022  GNUNET_snprintf (pred, sizeof(pred), "%s", GNUNET_i2s (peer_entry->id));
1024  "Flood at %s from `%s' via `%s' at `%s' with bits %u\n",
1026  GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp)),
1027  origin,
1028  pred,
1030  (unsigned int) matching_bits);
1031  }
1032 #endif
1033 
1034 #if ENABLE_NSE_HISTOGRAM
1035  peer_entry->received_messages++;
1036  if ((peer_entry->transmitted_messages > 0) &&
1037  (peer_entry->last_transmitted_size >= matching_bits) )
1038  GNUNET_STATISTICS_update (stats, "# cross messages", 1, GNUNET_NO);
1039 #endif
1040 
1041  ts = GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp);
1043  idx = estimate_index;
1044  else if (ts.abs_value_us ==
1046  idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE;
1047  else if (ts.abs_value_us == next_timestamp.abs_value_us)
1048  {
1049  if (matching_bits <= ntohl (next_message.matching_bits))
1050  return; /* ignore, simply too early/late */
1051  if (GNUNET_YES != verify_message_crypto (incoming_flood))
1052  {
1054  "Peer %s is likely ill-configured!\n",
1055  GNUNET_i2s (peer_entry->id));
1056  GNUNET_break_op (0);
1057  return;
1058  }
1059  next_message = *incoming_flood;
1060  return;
1061  }
1062  else
1063  {
1065  "# flood messages discarded (clock skew too large)",
1066  1,
1067  GNUNET_NO);
1068  return;
1069  }
1070  if (0 == (GNUNET_memcmp (peer_entry->id, &my_identity)))
1071  {
1072  /* send to self, update our own estimate IF this also comes from us! */
1073  if (0 == GNUNET_memcmp (&incoming_flood->origin, &my_identity))
1075  return;
1076  }
1078  {
1079  /* Cancel transmission in the other direction, as this peer clearly has
1080  up-to-date information already. Even if we didn't talk to this peer in
1081  the previous round, we should no longer send it stale information as it
1082  told us about the current round! */
1083  peer_entry->previous_round = GNUNET_YES;
1084  if (idx != estimate_index)
1085  {
1086  /* do not transmit information for the previous round to this peer
1087  anymore (but allow current round) */
1088  return;
1089  }
1090  /* got up-to-date information for current round, cancel transmission to
1091  * this peer altogether */
1092  if (NULL != peer_entry->transmit_task)
1093  {
1094  GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
1095  peer_entry->transmit_task = NULL;
1096  }
1097  return;
1098  }
1100  {
1101  if ((idx < estimate_index) && (peer_entry->previous_round == GNUNET_YES))
1102  {
1103  peer_entry->previous_round = GNUNET_NO;
1104  }
1105  /* push back our result now, that peer is spreading bad information... */
1106  if (NULL != peer_entry->transmit_task)
1107  GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
1108  peer_entry->transmit_task =
1110  /* Not closer than our most recent message, no need to do work here */
1112  "# flood messages ignored (had closer already)",
1113  1,
1114  GNUNET_NO);
1115  return;
1116  }
1117  if (GNUNET_YES != verify_message_crypto (incoming_flood))
1118  {
1119  GNUNET_break_op (0);
1120  return;
1121  }
1123  ntohl (size_estimate_messages[idx].matching_bits));
1124  /* Cancel transmission in the other direction, as this peer clearly has
1125  * up-to-date information already.
1126  */
1127  peer_entry->previous_round = GNUNET_YES;
1128  if (idx == estimate_index)
1129  {
1130  /* cancel any activity for current round */
1131  if (NULL != peer_entry->transmit_task)
1132  {
1133  GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
1134  peer_entry->transmit_task = NULL;
1135  }
1136  }
1137  size_estimate_messages[idx] = *incoming_flood;
1139  htonl (ntohl (incoming_flood->hop_count) + 1);
1140  hop_count_max =
1141  GNUNET_MAX (ntohl (incoming_flood->hop_count) + 1, hop_count_max);
1143  "# estimated network diameter",
1144  hop_count_max,
1145  GNUNET_NO);
1146 
1147  /* have a new, better size estimate, inform clients */
1149 
1150  /* flood to rest */
1153  peer_entry);
1154 }
1155 
1156 
1164 static void *
1166  const struct GNUNET_PeerIdentity *peer,
1167  struct GNUNET_MQ_Handle *mq)
1168 {
1169  struct NSEPeerEntry *peer_entry;
1170 
1171  (void) cls;
1173  "Peer `%s' connected to us\n",
1174  GNUNET_i2s (peer));
1175  /* set our default transmission options */
1177  /* create our peer entry for this peer */
1178  peer_entry = GNUNET_new (struct NSEPeerEntry);
1179  peer_entry->id = peer;
1180  peer_entry->mq = mq;
1183  peers,
1184  peer_entry->id,
1185  peer_entry,
1187  peer_entry->transmit_task =
1190  peer_entry);
1191  GNUNET_STATISTICS_update (stats, "# peers connected", 1, GNUNET_NO);
1192  return peer_entry;
1193 }
1194 
1195 
1204 static void
1206  const struct GNUNET_PeerIdentity *peer,
1207  void *internal_cls)
1208 {
1209  struct NSEPeerEntry *pos = internal_cls;
1210 
1211  (void) cls;
1213  "Peer `%s' disconnected from us\n",
1214  GNUNET_i2s (peer));
1217  if (NULL != pos->transmit_task)
1218  {
1220  pos->transmit_task = NULL;
1221  }
1222  GNUNET_free (pos);
1223  GNUNET_STATISTICS_update (stats, "# peers connected", -1, GNUNET_NO);
1224 }
1225 
1226 
1227 #if ENABLE_NSE_HISTOGRAM
1235 static void
1236 flush_comp_cb (void *cls, size_t size)
1237 {
1238  (void) cls;
1239  (void) size;
1241  lh = NULL;
1242 }
1243 
1244 
1245 #endif
1246 
1247 
1253 static void
1254 shutdown_task (void *cls)
1255 {
1256  (void) cls;
1257  if (NULL != flood_task)
1258  {
1260  flood_task = NULL;
1261  }
1262  if (NULL != proof_task)
1263  {
1265  proof_task = NULL;
1266  write_proof (); /* remember progress */
1267  }
1268  if (NULL != nc)
1269  {
1271  nc = NULL;
1272  }
1273  if (NULL != core_api)
1274  {
1276  core_api = NULL;
1277  }
1278  if (NULL != stats)
1279  {
1281  stats = NULL;
1282  }
1283  if (NULL != peers)
1284  {
1286  peers = NULL;
1287  }
1288  if (NULL != my_private_key)
1289  {
1291  my_private_key = NULL;
1292  }
1293 #if ENABLE_NSE_HISTOGRAM
1294  if (NULL != logger_test)
1295  {
1296  GNUNET_CLIENT_service_test_cancel (logger_test);
1297  logger_test = NULL;
1298  }
1299  if (NULL != lh)
1300  {
1301  GNUNET_TESTBED_LOGGER_flush (lh, &flush_comp_cb, NULL);
1302  }
1303  if (NULL != histogram)
1304  {
1305  GNUNET_BIO_write_close (histogram, NULL);
1306  histogram = NULL;
1307  }
1308 #endif
1309 }
1310 
1311 
1318 static void
1319 core_init (void *cls, const struct GNUNET_PeerIdentity *identity)
1320 {
1321  struct GNUNET_TIME_Absolute now;
1322  struct GNUNET_TIME_Absolute prev_time;
1323 
1324  (void) cls;
1325  if (NULL == identity)
1326  {
1327  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection to core FAILED!\n");
1329  return;
1330  }
1332  now = GNUNET_TIME_absolute_get ();
1336  next_timestamp =
1339  estimate_count = 0;
1341  {
1342  int idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE;
1343  prev_time.abs_value_us =
1345  setup_flood_message (idx, prev_time);
1347  estimate_count++;
1348  }
1349  flood_task =
1351 }
1352 
1353 
1354 #if ENABLE_NSE_HISTOGRAM
1363 static void
1364 status_cb (void *cls, int status)
1365 {
1366  (void) cls;
1367  logger_test = NULL;
1368  if (GNUNET_YES != status)
1369  {
1370  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Testbed logger not running\n");
1371  return;
1372  }
1373  if (NULL == (lh = GNUNET_TESTBED_LOGGER_connect (cfg)))
1374  {
1376  "Cannot connect to the testbed logger. Exiting.\n");
1378  }
1379 }
1380 
1381 
1382 #endif
1383 
1384 
1392 static void
1393 run (void *cls,
1394  const struct GNUNET_CONFIGURATION_Handle *c,
1396 {
1397  struct GNUNET_MQ_MessageHandler core_handlers[] =
1398  { GNUNET_MQ_hd_fixed_size (p2p_estimate,
1400  struct GNUNET_NSE_FloodMessage,
1401  NULL),
1402  GNUNET_MQ_handler_end () };
1403  char *proof;
1405 
1406  (void) cls;
1407  (void) service;
1408  cfg = c;
1410  "NSE",
1411  "INTERVAL",
1413  {
1416  return;
1417  }
1419  "NSE",
1420  "WORKDELAY",
1421  &proof_find_delay))
1422  {
1423  GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKDELAY");
1425  return;
1426  }
1428  "NSE",
1429  "WORKBITS",
1431  {
1434  return;
1435  }
1436  if (nse_work_required >= sizeof(struct GNUNET_HashCode) * 8)
1437  {
1439  "NSE",
1440  "WORKBITS",
1441  _ ("Value is too large.\n"));
1443  return;
1444  }
1445 
1446 #if ENABLE_NSE_HISTOGRAM
1447  {
1448  char *histogram_dir;
1449  char *histogram_fn;
1450 
1452  "NSE",
1453  "HISTOGRAM_DIR",
1454  &histogram_dir))
1455  {
1456  GNUNET_assert (
1457  0 < GNUNET_asprintf (&histogram_fn, "%s/timestamps", histogram_dir));
1458  GNUNET_free (histogram_dir);
1459  histogram = GNUNET_BIO_write_open_file (histogram_fn);
1460  if (NULL == histogram)
1462  "Unable to open histogram file `%s'\n",
1463  histogram_fn);
1464  GNUNET_free (histogram_fn);
1465  }
1466  logger_test = GNUNET_CLIENT_service_test ("testbed-logger",
1467  cfg,
1469  &status_cb,
1470  NULL);
1471  }
1472 #endif
1473 
1476  GNUNET_assert (NULL != pk);
1477  my_private_key = pk;
1479  if (GNUNET_OK !=
1480  GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "PROOFFILE", &proof))
1481  {
1482  GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "PROOFFILE");
1484  my_private_key = NULL;
1486  return;
1487  }
1488  if ((GNUNET_YES != GNUNET_DISK_file_test (proof)) ||
1489  (sizeof(my_proof) !=
1491  my_proof = 0;
1492  GNUNET_free (proof);
1493  proof_task =
1495  &find_proof,
1496  NULL);
1497 
1500  /* Connect to core service and register core handlers */
1501  core_api =
1502  GNUNET_CORE_connect (cfg, /* Main configuration */
1503  NULL, /* Closure passed to functions */
1504  &core_init, /* Call core_init once connected */
1505  &handle_core_connect, /* Handle connects */
1506  &handle_core_disconnect, /* Handle disconnects */
1507  core_handlers); /* Register these handlers */
1508  if (NULL == core_api)
1509  {
1511  return;
1512  }
1513  stats = GNUNET_STATISTICS_create ("nse", cfg);
1514 }
1515 
1516 
1525 static void *
1527  struct GNUNET_SERVICE_Client *c,
1528  struct GNUNET_MQ_Handle *mq)
1529 {
1530  (void) cls;
1531  (void) mq;
1532  return c;
1533 }
1534 
1535 
1543 static void
1545  struct GNUNET_SERVICE_Client *c,
1546  void *internal_cls)
1547 {
1548  (void) cls;
1549  GNUNET_assert (c == internal_cls);
1550 }
1551 
1552 
1558  &run,
1561  NULL,
1564  struct GNUNET_MessageHeader,
1565  NULL),
1567 
1568 
1569 #if defined(__linux__) && defined(__GLIBC__)
1570 #include <malloc.h>
1571 
1575 void __attribute__ ((constructor))
1576 GNUNET_ARM_memory_init ()
1577 {
1578  mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1579  mallopt (M_TOP_PAD, 1 * 1024);
1580  malloc_trim (0);
1581 }
1582 
1583 
1584 #endif
1585 
1586 
1587 /* end of gnunet-service-nse.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_SIGNATURE_PURPOSE_NSE_SEND
Signature of a network size estimate message.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
struct GNUNET_HashCode key
The key used in the DHT.
static ogg_stream_state os
Ogg stream state.
uint16_t status
See PRISM_STATUS_*-constants.
struct GNUNET_IDENTITY_PrivateKey pk
Private key from command line option, or NULL.
static char * pkey
Public key of the zone to look in, in ASCII.
static char origin[GNUNET_DNSPARSER_MAX_NAME_LENGTH]
Current origin.
static char * value
Value of the record to add/remove.
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
static int result
Global testing status.
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
static unsigned long long matching_bits
Number of matching bits required for revocation.
static uint64_t proof
Definition: gnunet-scrypt.c:49
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GNUNET_CONTAINER_MultiPeerMap * peers
Map of all connected peers.
static double current_std_dev
The standard deviation of the last HISTORY_SIZE network size estimates.
static struct GNUNET_NSE_FloodMessage size_estimate_messages[64]
Array of recent size estimate messages.
static void update_flood_message(void *cls)
Update our flood message to be sent (and our timestamps).
static void transmit_task_cb(void *cls)
Task that triggers a NSE P2P transmission.
static void core_init(void *cls, const struct GNUNET_PeerIdentity *identity)
Called on core init/fail.
static int update_flood_times(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Update transmissions for the given peer for the current round based on updated proximity information.
static double get_matching_bits_delay(uint32_t matching_bits)
How long should we delay a message to go the given number of matching bits?
static unsigned int estimate_index
Index of most recent estimate.
static struct GNUNET_TIME_Relative gnunet_nse_interval
Interval for sending network size estimation flood requests.
static struct GNUNET_PeerIdentity my_identity
The peer identity of this peer.
#define NSE_PRIORITY
Message priority to use.
#define HISTORY_SIZE
Over how many values do we calculate the weighted average?
static enum GNUNET_GenericReturnValue check_proof_of_work(const struct GNUNET_CRYPTO_EddsaPublicKey *pkey, uint64_t val)
Check whether the given public key and integer are a valid proof of work.
static struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
static void setup_estimate_message(struct GNUNET_NSE_ClientMessage *em)
Initialize a message to clients with the current network size estimate.
static struct GNUNET_SCHEDULER_Task * proof_task
Task scheduled to compute our proof.
static struct GNUNET_TIME_Absolute current_timestamp
The current major time.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
Callback called when a client connects to the service.
static struct GNUNET_NotificationContext * nc
Notification context, simplifies client broadcasts.
static void find_proof(void *cls)
Find our proof of work.
static unsigned int estimate_count
Number of valid entries in the history.
static void update_network_size_estimate()
We've sent on our flood message or one that we received which was validated and closer than ours.
static struct GNUNET_TIME_Relative proof_find_delay
Interval between proof find runs.
static void shutdown_task(void *cls)
Task run during shutdown.
static int verify_message_crypto(const struct GNUNET_NSE_FloodMessage *incoming_flood)
An incoming flood message has been received which claims to have more bits matching than any we know ...
static uint64_t my_proof
Proof of work for this peer.
static struct GNUNET_CORE_Handle * core_api
Handle to the core service.
static unsigned long long nse_work_required
Amount of work required (W-bit collisions) for NSE proofs, in collision-bits.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Handle network size estimate clients.
static GNUNET_NETWORK_STRUCT_END const struct GNUNET_CONFIGURATION_Handle * cfg
Handle to our current configuration.
static void setup_flood_message(unsigned int slot, struct GNUNET_TIME_Absolute ts)
Setup a flood message in our history array at the given slot offset for the given timestamp.
static int schedule_current_round(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Schedule transmission for the given peer for the current round based on what we know about the desire...
static uint32_t hop_count_max
Current hop counter estimate (estimate for network diameter).
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.
static struct GNUNET_TIME_Relative get_transmit_delay(int round_offset)
Get the transmission delay that should be applied for a particular round.
#define ROUND_SIZE
static void handle_start(void *cls, const struct GNUNET_MessageHeader *message)
Handler for START message from client, triggers an immediate current network estimate notification.
static struct GNUNET_NSE_FloodMessage next_message
Message for the next round, if we got any.
static struct GNUNET_SCHEDULER_Task * flood_task
Task scheduled to update our flood message for the next round.
static struct GNUNET_TIME_Absolute next_timestamp
The next major time.
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calcualations.
static struct GNUNET_TIME_Relative get_delay_randomization(uint32_t matching_bits)
What delay randomization should we apply for a given number of matching bits?
static double current_size_estimate
The current network size estimate.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *c, void *internal_cls)
Callback called when a client disconnected from the service.
static void write_proof(void)
Write our current proof to disk.
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
The private key of this peer.
static void handle_p2p_estimate(void *cls, const struct GNUNET_NSE_FloodMessage *incoming_flood)
Core handler for size estimate flooding messages.
static void handle_core_disconnect(void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
Method called whenever a peer disconnects.
static void * handle_core_connect(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a peer connects.
static uint32_t get_matching_bits(struct GNUNET_TIME_Absolute timestamp, const struct GNUNET_PeerIdentity *id)
Get the number of matching bits that the given timestamp has to the given peer ID.
static char buf[2048]
static struct GNUNET_SCHEDULER_Task * t
Main task.
Core service; the main API for encrypted P2P communications.
API to retrieve the current network size estimate.
Constants for network protocols.
API to create, modify and access statistics.
API for submitting data to the testbed logger service.
int GNUNET_BIO_write_close(struct GNUNET_BIO_WriteHandle *h, char **emsg)
Close an IO handle.
Definition: bio.c:556
int GNUNET_BIO_write_int64(struct GNUNET_BIO_WriteHandle *h, const char *what, int64_t i)
Write an (u)int64_t.
Definition: bio.c:867
struct GNUNET_BIO_WriteHandle * GNUNET_BIO_write_open_file(const char *fn)
Open a file for writing.
Definition: bio.c:508
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
struct GNUNET_CORE_Handle * GNUNET_CORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls, GNUNET_CORE_StartupCallback init, GNUNET_CORE_ConnectEventHandler connects, GNUNET_CORE_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Connect to the core service.
Definition: core_api.c:691
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition: core_api.c:729
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
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's key from the file specified in the configuration.
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:197
enum GNUNET_GenericReturnValue 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:619
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
enum GNUNET_GenericReturnValue 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:702
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition: disk.c:482
enum GNUNET_GenericReturnValue GNUNET_DISK_fn_write(const char *fn, const void *buf, size_t buf_size, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file atomically.
Definition: disk.c:725
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:1087
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:664
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
Definition: crypto_hash.c:135
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
unsigned int GNUNET_CRYPTO_hash_count_leading_zeros(const struct GNUNET_HashCode *h)
Count the number of leading 0 bits in h.
Definition: crypto_hash.c:176
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
#define GNUNET_log(kind,...)
#define GNUNET_MAX(a, b)
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:54
void GNUNET_CRYPTO_pow_hash(const struct GNUNET_CRYPTO_PowSalt *salt, const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
Calculate the 'proof-of-work' hash (an expensive hash).
Definition: crypto_pow.c:42
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
double GNUNET_hton_double(double d)
Convert double to network byte order.
Definition: common_endian.c:70
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
#define GNUNET_PACKED
gcc-ism to get packed structs.
@ GNUNET_SCHEDULER_PRIORITY_IDLE
Run when otherwise idle.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:138
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:871
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:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
void GNUNET_notification_context_broadcast(struct GNUNET_NotificationContext *nc, const struct GNUNET_MessageHeader *msg, int can_drop)
Send a message to all subscribers of this context.
Definition: nc.c:190
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:533
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:122
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:161
#define GNUNET_MESSAGE_TYPE_NSE_START
client->service message indicating start
#define GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD
P2P message sent from nearest peer.
#define GNUNET_MESSAGE_TYPE_NSE_ESTIMATE
service->client message indicating
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:562
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:1299
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:1202
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:1226
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1334
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:1249
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
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:1272
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2443
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2249
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
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.
struct GNUNET_TESTBED_LOGGER_Handle * GNUNET_TESTBED_LOGGER_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the testbed logger service.
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.
void GNUNET_TESTBED_LOGGER_disconnect(struct GNUNET_TESTBED_LOGGER_Handle *h)
Disconnect from the logger service.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:405
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:616
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition: time.c:450
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:569
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
Common type definitions for the network size estimation service and API.
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
enum array_types __attribute__
Handle for buffered writing.
Definition: bio.c:466
Internal representation of the hash map.
Context for the core service connection.
Definition: core_api.c:78
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
Private ECC key encoded for transmission.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
an ECC signature using EdDSA.
Value for a salt for GNUNET_CRYPTO_pow_hash().
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Network size estimate sent from the service to clients.
Definition: nse.h:43
uint32_t reserved
For alignment.
Definition: nse.h:52
double size_estimate
The current estimated network size.
Definition: nse.h:62
struct GNUNET_TIME_AbsoluteNBO timestamp
Timestamp at which the server received the message.
Definition: nse.h:57
double std_deviation
The standard deviation (rounded down to the nearest integer) of size estimations.
Definition: nse.h:69
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_NSE_ESTIMATE.
Definition: nse.h:47
Network size estimate reply; sent when "this" peer's timer has run out before receiving a valid reply...
uint32_t hop_count
Number of hops this message has taken so far.
uint32_t matching_bits
Number of matching bits between the hash of timestamp and the initiator's public key.
struct GNUNET_TIME_AbsoluteNBO timestamp
The current timestamp value (which all peers should agree on).
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD.
struct GNUNET_PeerIdentity origin
Public key of the originator.
uint64_t proof_of_work
Proof of work, causing leading zeros when hashed with pkey.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose.
struct GNUNET_CRYPTO_EddsaSignature signature
Signature (over range specified in purpose).
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition: nc.c:77
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition: scheduler.c:136
Handle to a client that is connected to a service.
Definition: service.c:252
Handle to a service.
Definition: service.c:118
Handle for the service.
Connection handle for the logger service.
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Per-peer information.
struct GNUNET_MQ_Handle * mq
Core handle for sending messages to this peer.
struct GNUNET_SCHEDULER_Task * transmit_task
Task scheduled to send message to this peer.
const struct GNUNET_PeerIdentity * id
What is the identity of the peer?
int previous_round
Did we receive or send a message about the previous round to this peer yet? GNUNET_YES if the previou...
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.