GNUnet  0.10.x
gnunet_dht_profiler.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2014, 2018 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 
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_testbed_service.h"
30 #include "gnunet_dht_service.h"
31 #include "gnunet_constants.h"
32 
33 
34 #define MESSAGE(...) \
35  GNUNET_log(GNUNET_ERROR_TYPE_MESSAGE, __VA_ARGS__)
36 
37 #define DEBUG(...) \
38  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
39 
43 static unsigned int put_probability = 100;
44 
48 static const struct GNUNET_CONFIGURATION_Handle *cfg;
49 
53 static char *hosts_file;
54 
58 struct ActiveContext;
59 
63 struct Context {
68 
73 
77  struct ActiveContext *ac;
78 };
79 
80 
84 struct ActiveContext {
88  struct Context *ctx;
89 
94 
99 
104 
109 
115 
120 
124  unsigned int put_count;
125 
129  uint16_t nrefs;
130 };
131 
132 
136 static struct Context *a_ctx;
137 
141 static struct ActiveContext *a_ac;
142 
147 
152 
157 
162 
166 static unsigned int num_peers;
167 
171 static unsigned int n_active;
172 
176 static unsigned int n_dht;
177 
181 static unsigned long long n_puts;
182 
186 static unsigned int num_puts_per_peer = 1;
187 
191 static unsigned long long n_puts_ok;
192 
196 static unsigned int n_gets;
197 
201 static unsigned int n_gets_ok;
202 
206 static unsigned int n_gets_fail;
207 
211 static unsigned int replication;
212 
217 
222 
226 static uint64_t outgoing_bandwidth;
227 
231 static uint64_t incoming_bandwidth;
232 
237 
242 
246 static unsigned int total_put_path_length;
247 
251 static unsigned int total_get_path_length;
252 
256 static int peers_started = 0;
257 
261 static enum {
262  MODE_PUT = 0,
263 
265 } mode;
266 
267 
271 static int in_shutdown = 0;
272 
273 
277 static void
278 start_profiling(void);
279 
280 
286 static void
287 do_shutdown(void *cls)
288 {
289  struct ActiveContext *ac;
290 
292  if (NULL != a_ctx)
293  {
294  for (unsigned int cnt = 0; cnt < num_peers; cnt++)
295  {
296  /* Cleanup active context if this peer is an active peer */
297  ac = a_ctx[cnt].ac;
298  if (NULL != ac)
299  {
300  if (NULL != ac->delay_task)
302  if (NULL != ac->hash)
303  free(ac->hash);
304  if (NULL != ac->dht_put)
306  if (NULL != ac->dht_get)
308  }
309  /* Cleanup testbed operation handle at the last as this operation may
310  contain service connection to DHT */
311  if (NULL != a_ctx[cnt].op)
312  GNUNET_TESTBED_operation_done(a_ctx[cnt].op);
313  }
314  GNUNET_free(a_ctx);
315  a_ctx = NULL;
316  }
317  //FIXME: Should we collect stats only for put/get not for other messages.
318  if (NULL != bandwidth_stats_op)
319  {
320  GNUNET_TESTBED_operation_done(bandwidth_stats_op);
321  bandwidth_stats_op = NULL;
322  }
323  GNUNET_free_non_null(a_ac);
324 }
325 
326 
336 static void
339  const char *emsg)
340 {
341  MESSAGE("# Outgoing (core) bandwidth: %llu bytes\n",
342  (unsigned long long)outgoing_bandwidth);
343  MESSAGE("# Incoming (core) bandwidth: %llu bytes\n",
344  (unsigned long long)incoming_bandwidth);
345  fprintf(stderr,
346  "Benchmark done. Collect data via gnunet-statistics, then press ENTER to exit.\n");
347  (void)getchar();
349 }
350 
351 
363 static int
365  const struct GNUNET_TESTBED_Peer *peer,
366  const char *subsystem,
367  const char *name,
368  uint64_t value,
369  int is_persistent)
370 {
371  static const char *s_sent = "# bytes encrypted";
372  static const char *s_recv = "# bytes decrypted";
373 
374  if (0 == strncmp(s_sent, name, strlen(s_sent)))
376  else if (0 == strncmp(s_recv, name, strlen(s_recv)))
378  return GNUNET_OK;
379 }
380 
381 
382 static void
384 {
385  MESSAGE("# PUTS started: %llu\n",
386  n_puts);
387  MESSAGE("# PUTS succeeded: %llu\n",
388  n_puts_ok);
389  MESSAGE("# GETS made: %u\n",
390  n_gets);
391  MESSAGE("# GETS succeeded: %u\n",
392  n_gets_ok);
393  MESSAGE("# GETS failed: %u\n",
394  n_gets_fail);
395  MESSAGE("# average_put_path_length: %f\n",
397  MESSAGE("# average_get_path_length: %f\n",
399 
400  if (NULL == testbed_handles)
401  {
402  MESSAGE("No peers found\n");
403  return;
404  }
405  /* Collect Stats*/
406  bandwidth_stats_op = GNUNET_TESTBED_get_statistics(n_active,
407  testbed_handles,
408  "core",
409  NULL,
412  NULL);
413 }
414 
415 
421 static void
422 cancel_get(void *cls)
423 {
424  struct ActiveContext *ac = cls;
425  struct Context *ctx = ac->ctx;
426 
427  ac->delay_task = NULL;
428  GNUNET_assert(NULL != ac->dht_get);
430  ac->dht_get = NULL;
431  n_gets_fail++;
432  GNUNET_assert(NULL != ctx->op);
434  ctx->op = NULL;
435 
436  /* If profiling is complete, summarize */
437  if (n_active == n_gets_fail + n_gets_ok)
438  {
441  summarize();
442  }
443 }
444 
445 
463 static void
464 get_iter(void *cls,
465  struct GNUNET_TIME_Absolute exp,
466  const struct GNUNET_HashCode *key,
467  const struct GNUNET_PeerIdentity *get_path,
468  unsigned int get_path_length,
469  const struct GNUNET_PeerIdentity *put_path,
470  unsigned int put_path_length,
471  enum GNUNET_BLOCK_Type type,
472  size_t size, const void *data)
473 {
474  struct ActiveContext *ac = cls;
475  struct ActiveContext *get_ac = ac->get_ac;
476  struct Context *ctx = ac->ctx;
477 
478  /* we found the data we are looking for */
479  DEBUG("We found a GET request; %u remaining\n",
480  n_gets - (n_gets_fail + n_gets_ok)); //FIXME: It always prints 1.
481  n_gets_ok++;
482  get_ac->nrefs--;
484  ac->dht_get = NULL;
485  if (ac->delay_task != NULL)
487  ac->delay_task = NULL;
488  GNUNET_assert(NULL != ctx->op);
490  ctx->op = NULL;
491 
492  total_put_path_length = total_put_path_length + (double)put_path_length;
493  total_get_path_length = total_get_path_length + (double)get_path_length;
494  DEBUG("total_put_path_length = %u,put_path \n",
496  /* Summarize if profiling is complete */
497  if (n_active == n_gets_fail + n_gets_ok)
498  {
500  average_get_path_length = (double)total_get_path_length / (double )n_gets_ok;
501  summarize();
502  }
503 }
504 
505 
511 static void
512 delayed_get(void *cls)
513 {
514  struct ActiveContext *ac = cls;
515  struct ActiveContext *get_ac;
516  unsigned int r;
517 
518  ac->delay_task = NULL;
519  get_ac = NULL;
520  while (1)
521  {
523  n_active);
524  get_ac = &a_ac[r];
525  if (NULL != get_ac->hash)
526  break;
527  }
528  get_ac->nrefs++;
529  ac->get_ac = get_ac;
532  DEBUG("GET_REQUEST_START key %s \n",
533  GNUNET_h2s(&get_ac->hash[r]));
534  ac->dht_get = GNUNET_DHT_get_start(ac->dht,
536  &get_ac->hash[r],
537  1, /* replication level */
539  NULL,
540  0, /* extended query and size */
541  &get_iter,
542  ac); /* GET iterator and closure */
543  n_gets++;
544 
545  /* schedule the timeout task for GET */
547  &cancel_get,
548  ac);
549 }
550 
551 
559 static void
560 delayed_put(void *cls);
561 
562 
569 static void
570 put_cont(void *cls)
571 {
572  struct ActiveContext *ac = cls;
573 
574  ac->dht_put = NULL;
575  n_puts_ok++;
577  ac);
578 }
579 
580 
588 static void
589 delayed_put(void *cls)
590 {
591  struct ActiveContext *ac = cls;
592  char block[65536];
593  size_t block_size;
594 
595  ac->delay_task = NULL;
596  if (0 == ac->put_count)
597  {
598  struct Context *ctx = ac->ctx;
600 
601  GNUNET_assert(NULL != ctx);
602  op = ctx->op;
603  ctx->op = NULL;
605  return;
606  }
607 
608 
609  /* Generate and DHT PUT some random data */
610  block_size = 16; /* minimum */
611  /* make random payload, reserve 512 - 16 bytes for DHT headers */
615  block,
616  block_size);
617  ac->put_count--;
618  GNUNET_CRYPTO_hash(block,
619  block_size,
620  &ac->hash[ac->put_count]);
621  DEBUG("PUT_REQUEST_START key %s\n",
622  GNUNET_h2s(&ac->hash[ac->put_count]));
623  ac->dht_put = GNUNET_DHT_put(ac->dht,
624  &ac->hash[ac->put_count],
625  replication,
628  block_size,
629  block,
630  GNUNET_TIME_UNIT_FOREVER_ABS, /* expiration time */
631  &put_cont,
632  ac); /* continuation and its closure */
633  n_puts++;
634 }
635 
636 
646 static void
647 dht_connected(void *cls,
649  void *ca_result,
650  const char *emsg)
651 {
652  struct ActiveContext *ac = cls;
653  struct Context *ctx = ac->ctx;
654 
655  GNUNET_assert(NULL != ctx); //FIXME: Fails
656  GNUNET_assert(NULL != ctx->op);
657  GNUNET_assert(ctx->op == op);
658  ac->dht = (struct GNUNET_DHT_Handle *)ca_result;
659  if (NULL != emsg)
660  {
662  "Connection to DHT service failed: %s\n",
663  emsg);
664  GNUNET_TESTBED_operation_done(ctx->op); /* Calls dht_disconnect() */
665  ctx->op = NULL;
666  return;
667  }
668  switch (mode)
669  {
670  case MODE_PUT:
671  {
672  struct GNUNET_TIME_Relative peer_delay_put;
673 
674  peer_delay_put.rel_value_us =
678  ac->hash = calloc(ac->put_count,
679  sizeof(struct GNUNET_HashCode));
680  if (NULL == ac->hash)
681  {
683  "calloc");
685  return;
686  }
687  ac->delay_task = GNUNET_SCHEDULER_add_delayed(peer_delay_put,
688  &delayed_put,
689  ac);
690  break;
691  }
692 
693  case MODE_GET:
694  {
695  struct GNUNET_TIME_Relative peer_delay_get;
696 
697  peer_delay_get.rel_value_us =
701  ac->delay_task = GNUNET_SCHEDULER_add_delayed(peer_delay_get,
702  &delayed_get,
703  ac);
704  break;
705  }
706  }
707 }
708 
709 
719 static void *
720 dht_connect(void *cls,
721  const struct GNUNET_CONFIGURATION_Handle *cfg)
722 {
723  n_dht++;
724  return GNUNET_DHT_connect(cfg,
725  10);
726 }
727 
728 
736 static void
737 dht_disconnect(void *cls,
738  void *op_result)
739 {
740  struct ActiveContext *ac = cls;
741 
742  GNUNET_assert(NULL != ac->dht);
743  GNUNET_assert(ac->dht == op_result);
745  ac->dht = NULL;
746  n_dht--;
747  if (0 != n_dht)
748  return;
749  if (GNUNET_YES == in_shutdown)
750  return;
751  switch (mode)
752  {
753  case MODE_PUT:
754  if (n_puts_ok != ((unsigned long long)n_active) * num_puts_per_peer)
755  return;
756  /* Start GETs if all PUTs have been made */
757  mode = MODE_GET;
758  start_profiling();
759  return;
760 
761  case MODE_GET:
762  if ((n_gets_ok + n_gets_fail) != n_active)
763  return;
764  break;
765  }
766 }
767 
768 
772 static void
774 {
775  struct Context *ctx;
776 
777  DEBUG("GNUNET_TESTBED_service_connect\n");
779  for (unsigned int i = 0; i < n_active; i++)
780  {
781  struct ActiveContext *ac = &a_ac[i];
782  GNUNET_assert(NULL != (ctx = ac->ctx));
783  GNUNET_assert(NULL == ctx->op);
785  ctx->peer,
786  "dht",
787  &dht_connected, ac,
788  &dht_connect,
790  ac);
791  }
792 }
793 
794 
803 static void
804 service_started(void *cls,
806  const char *emsg)
807 {
808  struct Context *ctx = cls;
809 
810  GNUNET_assert(NULL != ctx);
811  GNUNET_assert(NULL != ctx->op);
813  ctx->op = NULL;
814  peers_started++;
815  DEBUG("Peers Started = %d; num_peers = %d \n",
817  num_peers);
818  if (peers_started == num_peers)
819  start_profiling();
820 }
821 
822 
834 static void
835 test_run(void *cls,
836  struct GNUNET_TESTBED_RunHandle *h,
837  unsigned int num_peers,
838  struct GNUNET_TESTBED_Peer **peers,
839  unsigned int links_succeeded,
840  unsigned int links_failed)
841 {
842  unsigned int ac_cnt;
843 
844  testbed_handles = peers;
845  if (NULL == peers)
846  {
847  /* exit */
848  GNUNET_assert(0);
849  }
850  MESSAGE("%u peers started, %u/%u links up\n",
851  num_peers,
852  links_succeeded,
853  links_succeeded + links_failed);
854  a_ctx = GNUNET_new_array(num_peers,
855  struct Context);
856  /* select the peers which actively participate in profiling */
857  n_active = num_peers * put_probability / 100;
858  if (0 == n_active)
859  {
861  GNUNET_free(a_ctx);
862  a_ctx = NULL;
863  return;
864  }
865 
866  a_ac = GNUNET_new_array(n_active,
867  struct ActiveContext);
868  ac_cnt = 0;
869  for (unsigned int cnt = 0; cnt < num_peers && ac_cnt < n_active; cnt++)
870  {
872  100) >= put_probability)
873  continue;
874 
875  a_ctx[cnt].ac = &a_ac[ac_cnt];
876  a_ac[ac_cnt].ctx = &a_ctx[cnt];
877  ac_cnt++;
878  }
879  n_active = ac_cnt;
880 
881  /* start DHT service on all peers */
882  for (unsigned int cnt = 0; cnt < num_peers; cnt++)
883  {
884  a_ctx[cnt].peer = peers[cnt];
885  a_ctx[cnt].op = GNUNET_TESTBED_peer_manage_service(&a_ctx[cnt],
886  peers[cnt],
887  "dht",
889  &a_ctx[cnt],
890  1);
891  }
892 }
893 
894 
903 static void
904 run(void *cls,
905  char *const *args,
906  const char *cfgfile,
907  const struct GNUNET_CONFIGURATION_Handle *config)
908 {
909  uint64_t event_mask;
910 
911  if (0 == num_peers)
912  {
914  _("Exiting as the number of peers is %u\n"),
915  num_peers);
916  return;
917  }
918  cfg = config;
919  event_mask = 0;
921  cfg,
922  num_peers,
923  event_mask,
924  NULL,
925  NULL,
926  &test_run,
927  NULL);
929  NULL);
930 }
931 
932 
938 int
939 main(int argc,
940  char *const *argv)
941 {
942  int rc;
943  struct GNUNET_GETOPT_CommandLineOption options[] = {
945  "peers",
946  "COUNT",
947  gettext_noop("number of peers to start"),
948  &num_peers),
950  "peer-put-count",
951  "COUNT",
952  gettext_noop("number of PUTs to perform per peer"),
955  "hosts",
956  "FILENAME",
957  gettext_noop("name of the file with the login information for the testbed"),
958  &hosts_file),
960  "delay",
961  "DELAY",
962  gettext_noop("delay between rounds for collecting statistics (default: 30 sec)"),
963  &delay_stats),
965  "PUT-delay",
966  "DELAY",
967  gettext_noop("delay to start doing PUTs (default: 1 sec)"),
968  &delay_put),
970  "GET-delay",
971  "DELAY",
972  gettext_noop("delay to start doing GETs (default: 5 min)"),
973  &delay_get),
975  "replication",
976  "DEGREE",
977  gettext_noop("replication degree for DHT PUTs"),
978  &replication),
980  "random-chance",
981  "PROBABILITY",
982  gettext_noop("chance that a peer is selected at random for PUTs"),
983  &put_probability),
985  "timeout",
986  "TIMEOUT",
987  gettext_noop("timeout for DHT PUT and GET requests (default: 1 min)"),
988  &timeout),
990  };
991 
992  if (GNUNET_OK !=
993  GNUNET_STRINGS_get_utf8_args(argc, argv,
994  &argc, &argv))
995  return 2;
996  /* set default delays */
1001  replication = 1; /* default replication */
1002  rc = 0;
1003  if (GNUNET_OK !=
1004  GNUNET_PROGRAM_run(argc,
1005  argv,
1006  "gnunet-dht-profiler",
1007  gettext_noop("Measure quality and performance of the DHT service."),
1008  options,
1009  &run,
1010  NULL))
1011  rc = 1;
1012  return rc;
1013 }
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_relative_time(char shortName, const char *name, const char *argumentHelp, const char *description, struct GNUNET_TIME_Relative *val)
Allow user to specify a struct GNUNET_TIME_Relative (using human-readable "fancy" time)...
Context to hold data of peer.
static void delayed_put(void *cls)
Task to do DHT PUTs.
static void dht_disconnect(void *cls, void *op_result)
Adapter function called to destroy a connection to a service.
We should keep track of the route that the message took in the P2P network.
struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_get_statistics(unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers, const char *subsystem, const char *name, GNUNET_TESTBED_StatisticsIterator proc, GNUNET_TESTBED_OperationCompletionCallback cont, void *cls)
Convenience method that iterates over all (running) peers and retrieves all statistics from each peer...
static char * subsystem
Set to subsystem that we&#39;re going to get stats for (or NULL for all).
static unsigned int put_probability
Number of peers which should perform a PUT out of 100 peers.
uint64_t rel_value_us
The actual value.
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition: dht_api.c:1030
static uint64_t incoming_bandwidth
Total number of messages received by peer.
static unsigned int n_gets_ok
Number of DHT GETs succeeded.
static unsigned int num_peers
Number of peers.
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
static void bandwidth_stats_cont(void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
Stats callback.
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:1284
static void * dht_connect(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to DHT service and return the DHT client handler.
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1439
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
struct GNUNET_HashCode * hash
The hashes of the values stored via this activity context.
static unsigned int n_dht
Number of DHT service connections we currently have.
unsigned int put_count
How many puts should we still issue?
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Context for a peer which actively does DHT PUT/GET.
static int op_result(struct GNUNET_OP_Handle *h, uint64_t op_id, int64_t result_code, const void *data, uint16_t data_size, void **ctx, uint8_t cancel)
Remove an operation, and call its result callback (unless it was cancelled).
Definition: op.c:243
#define GNUNET_TIME_UNIT_SECONDS
One second.
static unsigned int num_puts_per_peer
Number of DHT PUTs to be made per peer.
static void get_iter(void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length, enum GNUNET_BLOCK_Type type, size_t size, const void *data)
Iterator called on each result obtained for a DHT operation that expects a reply. ...
static struct Context * a_ctx
An array of contexts.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define DEBUG(...)
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
Definition of a command line option.
static int bandwidth_stats_iterator(void *cls, const struct GNUNET_TESTBED_Peer *peer, const char *subsystem, const char *name, uint64_t value, int is_persistent)
Process statistic values.
static void delayed_get(void *cls)
Task to do DHT GETs.
static void put_cont(void *cls)
Conclude individual PUT operation, schedule the next one.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:517
#define GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE
What is the maximum size for encrypted messages? Note that this number imposes a clear limit on the m...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static void service_started(void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
Callback called when DHT service on the peer is started.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
Connection to the DHT service.
Definition: dht_api.c:198
Opaque handle to an abstract operation to be executed by the testing framework.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_string(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a string.
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
struct GNUNET_DHT_Handle * dht
Handler to the DHT service.
static unsigned int total_put_path_length
Total put path length across all peers.
static unsigned int replication
Replication degree.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_service_connect(void *op_cls, struct GNUNET_TESTBED_Peer *peer, const char *service_name, GNUNET_TESTBED_ServiceConnectCompletionCallback cb, void *cb_cls, GNUNET_TESTBED_ConnectAdapter ca, GNUNET_TESTBED_DisconnectAdapter da, void *cada_cls)
Connect to a service offered by the given peer.
static unsigned int n_active
Number of active peers.
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:1237
static char * value
Value of the record to add/remove.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
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:1264
static struct GNUNET_TIME_Relative delay_get
The delay to start puts.
static void summarize()
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
static struct GNUNET_TIME_Relative delay_put
The delay to start puts.
static const struct GNUNET_CONFIGURATION_Handle * config
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:440
static double average_put_path_length
Average number of hops taken to do put.
static void dht_connected(void *cls, struct GNUNET_TESTBED_Operation *op, void *ca_result, const char *emsg)
Connection to DHT has been established.
void GNUNET_TESTBED_operation_done(struct GNUNET_TESTBED_Operation *operation)
This function is used to signal that the event information (struct GNUNET_TESTBED_EventInformation) f...
Definition: testbed_api.c:2037
A 512-bit hashcode.
void GNUNET_TESTBED_run(const char *host_filename, const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int num_peers, uint64_t event_mask, GNUNET_TESTBED_ControllerCallback cc, void *cc_cls, GNUNET_TESTBED_TestMaster test_master, void *test_master_cls)
Convenience method for running a testbed with a single call.
struct ActiveContext * ac
Active context; NULL if this peer is not an active peer.
struct GNUNET_TESTBED_Peer * peer
The testbed peer this context belongs to.
void GNUNET_DHT_get_stop(struct GNUNET_DHT_GetHandle *get_handle)
Stop async DHT-get.
Definition: dht_api.c:1150
static uint64_t outgoing_bandwidth
Total number of messages sent by peer.
struct Context * ctx
The linked peer context.
static unsigned int n_gets
Number of DHT GETs made.
uint64_t event_mask
Global event mask for all testbed events.
static struct GNUNET_TESTBED_Operation * bandwidth_stats_op
Testbed Operation (to get stats).
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_DHT_PutHandle * GNUNET_DHT_put(struct GNUNET_DHT_Handle *handle, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, size_t size, const void *data, struct GNUNET_TIME_Absolute exp, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Perform a PUT operation storing data in the DHT.
Definition: dht_api.c:961
static unsigned int size
Size of the "table".
Definition: peer.c:66
struct GNUNET_DHT_Handle * GNUNET_DHT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int ht_len)
Initialize the connection with the DHT service.
Definition: dht_api.c:885
static unsigned long long n_puts
Number of DHT PUTs made.
const char * name
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:913
static struct GNUNET_TESTBED_Peer ** testbed_handles
Testbed peer handles.
static struct GNUNET_TIME_Relative timeout
The timeout for GET and PUT.
Handle to a GET request.
Definition: dht_api.c:78
static int in_shutdown
Are we shutting down.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration.
static void start_profiling(void)
Connect to DHT services of active peers.
The identity of the host (wraps the signing key of the peer).
Handle to a PUT request.
Definition: dht_api.c:43
static char * hosts_file
Name of the file with the hosts to run the test over.
configuration data
Definition: configuration.c:83
Block for testing.
uint16_t nrefs
The number of peers currently doing GET on our data.
#define MESSAGE(...)
struct GNUNET_DHT_GetHandle * GNUNET_DHT_get_start(struct GNUNET_DHT_Handle *handle, enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, const void *xquery, size_t xquery_size, GNUNET_DHT_GetIterator iter, void *iter_cls)
Perform an asynchronous GET operation on the DHT identified.
Definition: dht_api.c:1062
struct ActiveContext * get_ac
The active context used for our DHT GET.
static struct CadetPeer * peers
Operation to get peer ids.
struct GNUNET_DHT_GetHandle * dht_get
The get handle.
#define GNUNET_log(kind,...)
static void do_shutdown(void *cls)
Shutdown task.
Entry in list of pending tasks.
Definition: scheduler.c:131
static int peers_started
Counter to keep track of peers added to peer_context lists.
static void cancel_get(void *cls)
Task to cancel DHT GET.
static unsigned long long n_puts_ok
Number of DHT PUTs succeeded.
int main(int argc, char *const *argv)
Main function.
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
static struct GNUNET_TIME_Relative delay_stats
The delay between rounds for collecting statistics.
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:367
static double average_get_path_length
Average number of hops taken to do get.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *config)
Main function that will be run by the scheduler.
struct GNUNET_SCHEDULER_Task * delay_task
Delay task.
struct GNUNET_TESTBED_Operation * op
Testbed operation acting on this peer.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_uint(char shortName, const char *name, const char *argumentHelp, const char *description, unsigned int *val)
Allow user to specify an unsigned int.
struct GNUNET_DHT_PutHandle * dht_put
The put handle.
A peer controlled by the testing framework.
struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_peer_manage_service(void *op_cls, struct GNUNET_TESTBED_Peer *peer, const char *service_name, GNUNET_TESTBED_OperationCompletionCallback cb, void *cb_cls, unsigned int start)
Start or stop given service at a peer.
static unsigned int n_gets_fail
Number of DHT GETs succeeded.
uint32_t data
The data value.
static struct ActiveContext * a_ac
Array of active peers.
static unsigned int total_get_path_length
Total get path length across all peers.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
static enum @11 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
#define gettext_noop(String)
Definition: gettext.h:69
static void test_run(void *cls, struct GNUNET_TESTBED_RunHandle *h, unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers, unsigned int links_succeeded, unsigned int links_failed)
Signature of a main function for a testcase.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956