GNUnet 0.28.0-dev.3-17-g184ae026b
 
Loading...
Searching...
No Matches
gnunet_dht_profiler.c File Reference

Profiler for GNUnet DHT. More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_testbed_service.h"
#include "gnunet_dht_service.h"
#include "gnunet_constants.h"
Include dependency graph for gnunet_dht_profiler.c:

Go to the source code of this file.

Data Structures

struct  Context
 Context to hold data of peer. More...
 
struct  ActiveContext
 Context for a peer which actively does DHT PUT/GET. More...
 

Macros

#define MESSAGE(...)    GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, __VA_ARGS__)
 
#define DEBUG(...)    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
 

Enumerations

enum  { MODE_PUT = 0 , MODE_GET = 1 }
 Should we do a PUT (mode = 0) or GET (mode = 1);. More...
 

Functions

static void start_profiling (void)
 Connect to DHT services of active peers.
 
static void do_shutdown (void *cls)
 Shutdown task.
 
static void bandwidth_stats_cont (void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
 Stats callback.
 
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 summarize ()
 
static void cancel_get (void *cls)
 Task to cancel DHT GET.
 
static void get_iter (void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *trunc_peer, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *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 void delayed_get (void *cls)
 Task to do DHT GETs.
 
static void delayed_put (void *cls)
 Task to do DHT PUTs.
 
static void put_cont (void *cls)
 Conclude individual PUT operation, schedule the next one.
 
static void dht_connected (void *cls, struct GNUNET_TESTBED_Operation *op, void *ca_result, const char *emsg)
 Connection to DHT has been established.
 
static void * dht_connect (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
 Connect to DHT service and return the DHT client handler.
 
static void dht_disconnect (void *cls, void *op_result)
 Adapter function called to destroy a connection to a service.
 
static void service_started (void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
 Callback called when DHT service on the peer is started.
 
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.
 
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.
 
int main (int argc, char *const *argv)
 Main function.
 

Variables

static unsigned int put_probability = 100
 Number of peers which should perform a PUT out of 100 peers.
 
static const struct GNUNET_CONFIGURATION_Handlecfg
 Configuration.
 
static char * hosts_file
 Name of the file with the hosts to run the test over.
 
static struct Contexta_ctx
 An array of contexts.
 
static struct ActiveContexta_ac
 Array of active peers.
 
static struct GNUNET_TIME_Relative delay_stats
 The delay between rounds for collecting statistics.
 
static struct GNUNET_TIME_Relative delay_put
 The delay to start puts.
 
static struct GNUNET_TIME_Relative delay_get
 The delay to start puts.
 
static struct GNUNET_TIME_Relative timeout
 The timeout for GET and PUT.
 
static unsigned int num_peers
 Number of peers.
 
static unsigned int n_active
 Number of active peers.
 
static unsigned int n_dht
 Number of DHT service connections we currently have.
 
static unsigned long long n_puts
 Number of DHT PUTs made.
 
static unsigned int num_puts_per_peer = 1
 Number of DHT PUTs to be made per peer.
 
static unsigned long long n_puts_ok
 Number of DHT PUTs succeeded.
 
static unsigned int n_gets
 Number of DHT GETs made.
 
static unsigned int n_gets_ok
 Number of DHT GETs succeeded.
 
static unsigned int n_gets_fail
 Number of DHT GETs succeeded.
 
static unsigned int replication
 Replication degree.
 
static struct GNUNET_TESTBED_Operation * bandwidth_stats_op
 Testbed Operation (to get stats).
 
static struct GNUNET_TESTBED_Peer ** testbed_handles
 Testbed peer handles.
 
static uint64_t outgoing_bandwidth
 Total number of messages sent by peer.
 
static uint64_t incoming_bandwidth
 Total number of messages received by peer.
 
static double average_put_path_length
 Average number of hops taken to do put.
 
static double average_get_path_length
 Average number of hops taken to do get.
 
static unsigned int total_put_path_length
 Total put path length across all peers.
 
static unsigned int total_get_path_length
 Total get path length across all peers.
 
static int peers_started = 0
 Counter to keep track of peers added to peer_context lists.
 
static enum { ... }  mode
 Should we do a PUT (mode = 0) or GET (mode = 1);.
 
static int in_shutdown = 0
 Are we shutting down.
 

Detailed Description

Profiler for GNUnet DHT.

Author
Sree Harsha Totakura sreeh.nosp@m.arsh.nosp@m.a@tot.nosp@m.akur.nosp@m.a.in

Definition in file gnunet_dht_profiler.c.

Macro Definition Documentation

◆ MESSAGE

#define MESSAGE (   ...)     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, __VA_ARGS__)

Definition at line 34 of file gnunet_dht_profiler.c.

63{
67 struct GNUNET_TESTBED_Peer *peer;
68
72 struct GNUNET_TESTBED_Operation *op;
73
77 struct ActiveContext *ac;
78};
79
80
84struct ActiveContext
85{
89 struct Context *ctx;
90
94 struct GNUNET_DHT_Handle *dht;
95
99 struct ActiveContext *get_ac;
100
105
110
115 struct GNUNET_HashCode *hash;
116
121
125 unsigned int put_count;
126
130 uint16_t nrefs;
131};
132
133
137static struct Context *a_ctx;
138
142static struct ActiveContext *a_ac;
143
148
152static struct GNUNET_TIME_Relative delay_put;
153
157static struct GNUNET_TIME_Relative delay_get;
158
162static struct GNUNET_TIME_Relative timeout;
163
167static unsigned int num_peers;
168
172static unsigned int n_active;
173
177static unsigned int n_dht;
178
182static unsigned long long n_puts;
183
187static unsigned int num_puts_per_peer = 1;
188
192static unsigned long long n_puts_ok;
193
197static unsigned int n_gets;
198
202static unsigned int n_gets_ok;
203
207static unsigned int n_gets_fail;
208
212static unsigned int replication;
213
217static struct GNUNET_TESTBED_Operation *bandwidth_stats_op;
218
222static struct GNUNET_TESTBED_Peer **testbed_handles;
223
227static uint64_t outgoing_bandwidth;
228
232static uint64_t incoming_bandwidth;
233
237static double average_put_path_length;
238
242static double average_get_path_length;
243
247static unsigned int total_put_path_length;
248
252static unsigned int total_get_path_length;
253
257static int peers_started = 0;
258
262static enum
263{
264 MODE_PUT = 0,
265
266 MODE_GET = 1
267} mode;
268
269
273static int in_shutdown = 0;
274
275
279static void
280start_profiling (void);
281
282
288static void
289do_shutdown (void *cls)
290{
291 struct ActiveContext *ac;
292
294 if (NULL != a_ctx)
295 {
296 for (unsigned int cnt = 0; cnt < num_peers; cnt++)
297 {
298 /* Cleanup active context if this peer is an active peer */
299 ac = a_ctx[cnt].ac;
300 if (NULL != ac)
301 {
302 if (NULL != ac->delay_task)
304 if (NULL != ac->hash)
305 free (ac->hash);
306 if (NULL != ac->dht_put)
308 if (NULL != ac->dht_get)
310 }
311 /* Cleanup testbed operation handle at the last as this operation may
312 contain service connection to DHT */
313 if (NULL != a_ctx[cnt].op)
314 GNUNET_TESTBED_operation_done (a_ctx[cnt].op);
315 }
317 a_ctx = NULL;
318 }
319 // FIXME: Should we collect stats only for put/get not for other messages.
320 if (NULL != bandwidth_stats_op)
321 {
322 GNUNET_TESTBED_operation_done (bandwidth_stats_op);
323 bandwidth_stats_op = NULL;
324 }
326}
327
328
338static void
339bandwidth_stats_cont (void *cls,
340 struct GNUNET_TESTBED_Operation *op,
341 const char *emsg)
342{
343 MESSAGE ("# Outgoing (core) bandwidth: %llu bytes\n",
344 (unsigned long long) outgoing_bandwidth);
345 MESSAGE ("# Incoming (core) bandwidth: %llu bytes\n",
346 (unsigned long long) incoming_bandwidth);
347 fprintf (stderr,
348 "Benchmark done. Collect data via gnunet-statistics, then press ENTER to exit.\n");
349 (void) getchar ();
351}
352
353
365static int
366bandwidth_stats_iterator (void *cls,
367 const struct GNUNET_TESTBED_Peer *peer,
368 const char *subsystem,
369 const char *name,
370 uint64_t value,
371 int is_persistent)
372{
373 static const char *s_sent = "# bytes encrypted";
374 static const char *s_recv = "# bytes decrypted";
375
376 if (0 == strncmp (s_sent, name, strlen (s_sent)))
378 else if (0 == strncmp (s_recv, name, strlen (s_recv)))
380 return GNUNET_OK;
381}
382
383
384static void
385summarize ()
386{
387 MESSAGE ("# PUTS started: %llu\n",
388 n_puts);
389 MESSAGE ("# PUTS succeeded: %llu\n",
390 n_puts_ok);
391 MESSAGE ("# GETS made: %u\n",
392 n_gets);
393 MESSAGE ("# GETS succeeded: %u\n",
394 n_gets_ok);
395 MESSAGE ("# GETS failed: %u\n",
397 MESSAGE ("# average_put_path_length: %f\n",
399 MESSAGE ("# average_get_path_length: %f\n",
401
402 if (NULL == testbed_handles)
403 {
404 MESSAGE ("No peers found\n");
405 return;
406 }
407 /* Collect Stats*/
408 bandwidth_stats_op = GNUNET_TESTBED_get_statistics (n_active,
410 "core",
411 NULL,
414 NULL);
415}
416
417
423static void
424cancel_get (void *cls)
425{
426 struct ActiveContext *ac = cls;
427 struct Context *ctx = ac->ctx;
428
429 ac->delay_task = NULL;
430 GNUNET_assert (NULL != ac->dht_get);
432 ac->dht_get = NULL;
433 n_gets_fail++;
434 GNUNET_assert (NULL != ctx->op);
435 GNUNET_TESTBED_operation_done (ctx->op);
436 ctx->op = NULL;
437
438 /* If profiling is complete, summarize */
440 {
442 / (double) n_active;
444 / (double ) n_gets_ok;
445 summarize ();
446 }
447}
448
449
468static void
469get_iter (void *cls,
470 struct GNUNET_TIME_Absolute exp,
471 const struct GNUNET_HashCode *key,
472 const struct GNUNET_PeerIdentity *trunc_peer,
473 const struct GNUNET_DHT_PathElement *get_path,
474 unsigned int get_path_length,
475 const struct GNUNET_DHT_PathElement *put_path,
476 unsigned int put_path_length,
478 size_t size,
479 const void *data)
480{
481 struct ActiveContext *ac = cls;
482 struct ActiveContext *get_ac = ac->get_ac;
483 struct Context *ctx = ac->ctx;
484
485 /* we found the data we are looking for */
486 DEBUG ("We found a GET request; %u remaining\n",
487 n_gets - (n_gets_fail + n_gets_ok)); // FIXME: It always prints 1.
488 n_gets_ok++;
489 get_ac->nrefs--;
491 ac->dht_get = NULL;
492 if (ac->delay_task != NULL)
494 ac->delay_task = NULL;
495 GNUNET_assert (NULL != ctx->op);
496 GNUNET_TESTBED_operation_done (ctx->op);
497 ctx->op = NULL;
498
499 total_put_path_length = total_put_path_length + (double) put_path_length;
500 total_get_path_length = total_get_path_length + (double) get_path_length;
501 DEBUG ("total_put_path_length = %u,put_path \n",
503 /* Summarize if profiling is complete */
505 {
507 / (double) n_active;
509 / (double ) n_gets_ok;
510 summarize ();
511 }
512}
513
514
520static void
521delayed_get (void *cls)
522{
523 struct ActiveContext *ac = cls;
524 struct ActiveContext *get_ac;
525 unsigned int r;
526
527 ac->delay_task = NULL;
528 get_ac = NULL;
529 while (1)
530 {
532 get_ac = &a_ac[r];
533 if (NULL != get_ac->hash)
534 break;
535 }
536 get_ac->nrefs++;
537 ac->get_ac = get_ac;
539 DEBUG ("GET_REQUEST_START key %s \n",
540 GNUNET_h2s (&get_ac->hash[r]));
543 &get_ac->hash[r],
544 1, /* replication level */
546 NULL,
547 0, /* extended query and size */
548 &get_iter,
549 ac); /* GET iterator and closure */
550 n_gets++;
551
552 /* schedule the timeout task for GET */
554 &cancel_get,
555 ac);
556}
557
558
566static void
567delayed_put (void *cls);
568
569
576static void
577put_cont (void *cls)
578{
579 struct ActiveContext *ac = cls;
580
581 ac->dht_put = NULL;
582 n_puts_ok++;
584 ac);
585}
586
587
595static void
596delayed_put (void *cls)
597{
598 struct ActiveContext *ac = cls;
599 char block[65536];
600 size_t block_size;
601
602 ac->delay_task = NULL;
603 if (0 == ac->put_count)
604 {
605 struct Context *ctx = ac->ctx;
606 struct GNUNET_TESTBED_Operation *op;
607
608 GNUNET_assert (NULL != ctx);
609 op = ctx->op;
610 ctx->op = NULL;
611 GNUNET_TESTBED_operation_done (op);
612 return;
613 }
614
615
616 /* Generate and DHT PUT some random data */
617 block_size = 16; /* minimum */
618 /* make random payload, reserve 512 - 16 bytes for DHT headers */
619 block_size += GNUNET_CRYPTO_random_u32 (
621 - 512);
623 block_size);
624 ac->put_count--;
625 GNUNET_CRYPTO_hash (block,
626 block_size,
627 &ac->hash[ac->put_count]);
628 DEBUG ("PUT_REQUEST_START key %s\n",
629 GNUNET_h2s (&ac->hash[ac->put_count]));
630 ac->dht_put = GNUNET_DHT_put (ac->dht,
631 &ac->hash[ac->put_count],
635 block_size,
636 block,
637 GNUNET_TIME_UNIT_FOREVER_ABS, /* expiration time */
638 &put_cont,
639 ac); /* continuation and its closure */
640 n_puts++;
641}
642
643
653static void
654dht_connected (void *cls,
655 struct GNUNET_TESTBED_Operation *op,
656 void *ca_result,
657 const char *emsg)
658{
659 struct ActiveContext *ac = cls;
660 struct Context *ctx = ac->ctx;
661
662 GNUNET_assert (NULL != ctx); // FIXME: Fails
663 GNUNET_assert (NULL != ctx->op);
664 GNUNET_assert (ctx->op == op);
665 ac->dht = (struct GNUNET_DHT_Handle *) ca_result;
666 if (NULL != emsg)
667 {
669 "Connection to DHT service failed: %s\n",
670 emsg);
671 GNUNET_TESTBED_operation_done (ctx->op); /* Calls dht_disconnect() */
672 ctx->op = NULL;
673 return;
674 }
675 switch (mode)
676 {
677 case MODE_PUT:
678 {
679 struct GNUNET_TIME_Relative peer_delay_put;
680
681 peer_delay_put.rel_value_us =
684 ac->hash = calloc (ac->put_count,
685 sizeof(struct GNUNET_HashCode));
686 if (NULL == ac->hash)
687 {
689 "calloc");
691 return;
692 }
693 ac->delay_task = GNUNET_SCHEDULER_add_delayed (peer_delay_put,
695 ac);
696 break;
697 }
698
699 case MODE_GET:
700 {
701 struct GNUNET_TIME_Relative peer_delay_get;
702
703 peer_delay_get.rel_value_us =
706 ac->delay_task = GNUNET_SCHEDULER_add_delayed (peer_delay_get,
708 ac);
709 break;
710 }
711 }
712}
713
714
724static void *
725dht_connect (void *cls,
726 const struct GNUNET_CONFIGURATION_Handle *cfg)
727{
728 n_dht++;
729 return GNUNET_DHT_connect (cfg,
730 10);
731}
732
733
741static void
742dht_disconnect (void *cls,
743 void *op_result)
744{
745 struct ActiveContext *ac = cls;
746
747 GNUNET_assert (NULL != ac->dht);
748 GNUNET_assert (ac->dht == op_result);
750 ac->dht = NULL;
751 n_dht--;
752 if (0 != n_dht)
753 return;
754 if (GNUNET_YES == in_shutdown)
755 return;
756 switch (mode)
757 {
758 case MODE_PUT:
759 if (n_puts_ok != ((unsigned long long) n_active) * num_puts_per_peer)
760 return;
761 /* Start GETs if all PUTs have been made */
762 mode = MODE_GET;
764 return;
765
766 case MODE_GET:
767 if ((n_gets_ok + n_gets_fail) != n_active)
768 return;
769 break;
770 }
771}
772
773
777static void
779{
780 struct Context *ctx;
781
782 DEBUG ("GNUNET_TESTBED_service_connect\n");
784 for (unsigned int i = 0; i < n_active; i++)
785 {
786 struct ActiveContext *ac = &a_ac[i];
787 GNUNET_assert (NULL != (ctx = ac->ctx));
788 GNUNET_assert (NULL == ctx->op);
789 ctx->op = GNUNET_TESTBED_service_connect (ctx,
790 ctx->peer,
791 "dht",
792 &dht_connected, ac,
795 ac);
796 }
797}
798
799
808static void
809service_started (void *cls,
810 struct GNUNET_TESTBED_Operation *op,
811 const char *emsg)
812{
813 struct Context *ctx = cls;
814
815 GNUNET_assert (NULL != ctx);
816 GNUNET_assert (NULL != ctx->op);
817 GNUNET_TESTBED_operation_done (ctx->op);
818 ctx->op = NULL;
820 DEBUG ("Peers Started = %d; num_peers = %d \n",
822 num_peers);
825}
826
827
839static void
840test_run (void *cls,
841 struct GNUNET_TESTBED_RunHandle *h,
842 unsigned int num_peers,
843 struct GNUNET_TESTBED_Peer **peers,
844 unsigned int links_succeeded,
845 unsigned int links_failed)
846{
847 unsigned int ac_cnt;
848
850 if (NULL == peers)
851 {
852 /* exit */
853 GNUNET_assert (0);
854 }
855 MESSAGE ("%u peers started, %u/%u links up\n",
856 num_peers,
857 links_succeeded,
858 links_succeeded + links_failed);
860 struct Context);
861 /* select the peers which actively participate in profiling */
863 if (0 == n_active)
864 {
867 a_ctx = NULL;
868 return;
869 }
870
872 struct ActiveContext);
873 ac_cnt = 0;
874 for (unsigned int cnt = 0; cnt < num_peers && ac_cnt < n_active; cnt++)
875 {
877 continue;
878
879 a_ctx[cnt].ac = &a_ac[ac_cnt];
880 a_ac[ac_cnt].ctx = &a_ctx[cnt];
881 ac_cnt++;
882 }
883 n_active = ac_cnt;
884
885 /* start DHT service on all peers */
886 for (unsigned int cnt = 0; cnt < num_peers; cnt++)
887 {
888 a_ctx[cnt].peer = peers[cnt];
889 a_ctx[cnt].op = GNUNET_TESTBED_peer_manage_service (&a_ctx[cnt],
890 peers[cnt],
891 "dht",
893 &a_ctx[cnt],
894 1);
895 }
896}
897
898
907static void
908run (void *cls,
909 char *const *args,
910 const char *cfgfile,
912{
913 uint64_t event_mask;
914
915 if (0 == num_peers)
916 {
918 _ ("Exiting as the number of peers is %u\n"),
919 num_peers);
920 return;
921 }
922 cfg = config;
923 event_mask = 0;
924 GNUNET_TESTBED_run (hosts_file,
925 cfg,
926 num_peers,
928 NULL,
929 NULL,
930 &test_run,
931 NULL);
933 NULL);
934}
935
936
942int
943main (int argc,
944 char *const *argv)
945{
946 int rc;
949 "peers",
950 "COUNT",
951 gettext_noop ("number of peers to start"),
952 &num_peers),
954 "peer-put-count",
955 "COUNT",
957 "number of PUTs to perform per peer"),
960 "hosts",
961 "FILENAME",
963 "name of the file with the login information for the testbed"),
964 &hosts_file),
966 "delay",
967 "DELAY",
969 "delay between rounds for collecting statistics (default: 30 sec)"),
970 &delay_stats),
972 "PUT-delay",
973 "DELAY",
975 "delay to start doing PUTs (default: 1 sec)"),
976 &delay_put),
978 "GET-delay",
979 "DELAY",
981 "delay to start doing GETs (default: 5 min)"),
982 &delay_get),
984 "replication",
985 "DEGREE",
986 gettext_noop ("replication degree for DHT PUTs"),
987 &replication),
989 "random-chance",
990 "PROBABILITY",
992 "chance that a peer is selected at random for PUTs"),
995 "timeout",
996 "TIMEOUT",
998 "timeout for DHT PUT and GET requests (default: 1 min)"),
999 &timeout),
1001 };
1002
1003 /* set default delays */
1008 replication = 1; /* default replication */
1009 rc = 0;
1010 if (GNUNET_OK !=
1011 GNUNET_PROGRAM_run (argc,
1012 argv,
1013 "gnunet-dht-profiler",
1014 gettext_noop (
1015 "Measure quality and performance of the DHT service."),
1016 options,
1017 &run,
1018 NULL))
1019 rc = 1;
1020 return rc;
1021}
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
int main()
Program to simulate results from GCP_get_desirability_of_path() for various plausible inputs.
#define gettext_noop(String)
Definition gettext.h:74
static struct GNUNET_ARM_Operation * op
Current operation.
Definition gnunet-arm.c:143
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static int do_shutdown
Set to GNUNET_YES if we are shutting down.
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_FS_Handle * ctx
const struct GNUNET_CONFIGURATION_Handle * config
static char * name
Name (label) of the records to list.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
static uint64_t event_mask
Global event mask for all testbed events.
struct GNUNET_CONTAINER_MultiPeerMap * peers
Map from PIDs to struct CadetPeer entries.
static char * subsystem
Set to subsystem that we're going to get stats for (or NULL for all).
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_TEST
Block for testing.
static struct GNUNET_TESTBED_Peer ** testbed_handles
Testbed peer handles.
static unsigned long long n_puts_ok
Number of DHT PUTs succeeded.
static void get_iter(void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *trunc_peer, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *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 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.
static void dht_connected(void *cls, struct GNUNET_TESTBED_Operation *op, void *ca_result, const char *emsg)
Connection to DHT has been established.
static void * dht_connect(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to DHT service and return the DHT client handler.
static enum @52 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
static struct GNUNET_TIME_Relative delay_put
The delay to start puts.
static unsigned int n_gets_ok
Number of DHT GETs succeeded.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration.
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 double average_get_path_length
Average number of hops taken to do get.
static int in_shutdown
Are we shutting down.
static void delayed_get(void *cls)
Task to do DHT GETs.
static struct GNUNET_TESTBED_Operation * bandwidth_stats_op
Testbed Operation (to get stats).
static void delayed_put(void *cls)
Task to do DHT PUTs.
static unsigned int n_active
Number of active peers.
static char * hosts_file
Name of the file with the hosts to run the test over.
static struct GNUNET_TIME_Relative delay_get
The delay to start puts.
static unsigned int total_put_path_length
Total put path length across all peers.
static unsigned int n_dht
Number of DHT service connections we currently have.
static void summarize()
static void bandwidth_stats_cont(void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
Stats callback.
#define DEBUG(...)
static void cancel_get(void *cls)
Task to cancel DHT GET.
static unsigned int n_gets_fail
Number of DHT GETs succeeded.
static unsigned int replication
Replication degree.
static void service_started(void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
Callback called when DHT service on the peer is started.
static void start_profiling(void)
Connect to DHT services of active peers.
static struct GNUNET_TIME_Relative timeout
The timeout for GET and PUT.
static unsigned long long n_puts
Number of DHT PUTs made.
static struct GNUNET_TIME_Relative delay_stats
The delay between rounds for collecting statistics.
static struct Context * a_ctx
An array of contexts.
static unsigned int total_get_path_length
Total get path length across all peers.
static uint64_t outgoing_bandwidth
Total number of messages sent by peer.
static double average_put_path_length
Average number of hops taken to do put.
#define MESSAGE(...)
static unsigned int put_probability
Number of peers which should perform a PUT out of 100 peers.
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.
static unsigned int num_puts_per_peer
Number of DHT PUTs to be made per peer.
static void dht_disconnect(void *cls, void *op_result)
Adapter function called to destroy a connection to a service.
static struct ActiveContext * a_ac
Array of active peers.
static unsigned int num_peers
Number of peers.
static int peers_started
Counter to keep track of peers added to peer_context lists.
static uint64_t incoming_bandwidth
Total number of messages received by peer.
static unsigned int n_gets
Number of DHT GETs made.
static void put_cont(void *cls)
Conclude individual PUT operation, schedule the next one.
#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...
uint64_t GNUNET_CRYPTO_random_u64(uint64_t max)
Generate a random unsigned 64-bit value.
void GNUNET_CRYPTO_random_block(void *buffer, size_t length)
Fill block with a random values.
uint32_t GNUNET_CRYPTO_random_u32(uint32_t i)
Produce a random value.
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition dht_api.c:1149
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:1086
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:1036
void GNUNET_DHT_get_stop(struct GNUNET_DHT_GetHandle *get_handle)
Stop async DHT-get.
Definition dht_api.c:1238
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:1165
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition dht_api.c:1058
@ GNUNET_DHT_RO_NONE
Default.
@ GNUNET_DHT_RO_RECORD_ROUTE
We should keep track of the route that the message took in the P2P network.
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_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).
#define GNUNET_GETOPT_OPTION_END
Marker for the end of the list of options.
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.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:40
#define GNUNET_log(kind,...)
@ GNUNET_OK
@ GNUNET_YES
#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.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(const struct GNUNET_OS_ProjectData *pd, 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,...
Definition program.c:406
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:572
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1345
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
#define GNUNET_TIME_UNIT_SECONDS
One second.
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:486
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
Context for a peer which actively does DHT PUT/GET.
struct GNUNET_HashCode * hash
The hashes of the values stored via this activity context.
struct GNUNET_DHT_Handle * dht
Handler to the DHT service.
uint16_t nrefs
The number of peers currently doing GET on our data.
unsigned int put_count
How many puts should we still issue?
struct GNUNET_SCHEDULER_Task * delay_task
Delay task.
struct ActiveContext * get_ac
The active context used for our DHT GET.
struct GNUNET_DHT_PutHandle * dht_put
The put handle.
struct Context * ctx
The linked peer context.
struct GNUNET_DHT_GetHandle * dht_get
The get handle.
Context to hold data of peer.
struct GNUNET_TESTBED_Peer * peer
The testbed peer this context belongs to.
struct ActiveContext * ac
Active context; NULL if this peer is not an active peer.
struct GNUNET_TESTBED_Operation * op
Testbed operation acting on this peer.
Handle to a GET request.
Definition dht_api.c:79
Connection to the DHT service.
Definition dht_api.c:235
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
Handle to a PUT request.
Definition dht_api.c:43
Definition of a command line option.
A 512-bit hashcode.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition scheduler.c:141
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.

◆ DEBUG

#define DEBUG (   ...)     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)

Definition at line 37 of file gnunet_dht_profiler.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Should we do a PUT (mode = 0) or GET (mode = 1);.

Enumerator
MODE_PUT 
MODE_GET 

Definition at line 263 of file gnunet_dht_profiler.c.

264{
265 MODE_PUT = 0,
266
267 MODE_GET = 1
268} mode;

Function Documentation

◆ start_profiling()

static void start_profiling ( void  )
static

Connect to DHT services of active peers.

Definition at line 779 of file gnunet_dht_profiler.c.

780{
781 struct Context *ctx;
782
783 DEBUG ("GNUNET_TESTBED_service_connect\n");
785 for (unsigned int i = 0; i < n_active; i++)
786 {
787 struct ActiveContext *ac = &a_ac[i];
788 GNUNET_assert (NULL != (ctx = ac->ctx));
789 GNUNET_assert (NULL == ctx->op);
790 ctx->op = GNUNET_TESTBED_service_connect (ctx,
791 ctx->peer,
792 "dht",
793 &dht_connected, ac,
796 ac);
797 }
798}

References a_ac, ctx, ActiveContext::ctx, DEBUG, dht_connect(), dht_connected(), dht_disconnect(), GNUNET_assert, GNUNET_break, GNUNET_YES, in_shutdown, and n_active.

Referenced by dht_disconnect(), and service_started().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_shutdown()

static void do_shutdown ( void *  cls)
static

Shutdown task.

Cleanup all resources and operations.

Parameters
clsNULL

Definition at line 290 of file gnunet_dht_profiler.c.

291{
292 struct ActiveContext *ac;
293
295 if (NULL != a_ctx)
296 {
297 for (unsigned int cnt = 0; cnt < num_peers; cnt++)
298 {
299 /* Cleanup active context if this peer is an active peer */
300 ac = a_ctx[cnt].ac;
301 if (NULL != ac)
302 {
303 if (NULL != ac->delay_task)
305 if (NULL != ac->hash)
306 free (ac->hash);
307 if (NULL != ac->dht_put)
309 if (NULL != ac->dht_get)
311 }
312 /* Cleanup testbed operation handle at the last as this operation may
313 contain service connection to DHT */
314 if (NULL != a_ctx[cnt].op)
315 GNUNET_TESTBED_operation_done (a_ctx[cnt].op);
316 }
318 a_ctx = NULL;
319 }
320 // FIXME: Should we collect stats only for put/get not for other messages.
321 if (NULL != bandwidth_stats_op)
322 {
323 GNUNET_TESTBED_operation_done (bandwidth_stats_op);
324 bandwidth_stats_op = NULL;
325 }
327}

References a_ac, a_ctx, Context::ac, bandwidth_stats_op, ActiveContext::delay_task, ActiveContext::dht_get, ActiveContext::dht_put, GNUNET_DHT_get_stop(), GNUNET_DHT_put_cancel(), GNUNET_free, GNUNET_SCHEDULER_cancel(), GNUNET_YES, ActiveContext::hash, in_shutdown, num_peers, and op.

Here is the call graph for this function:

◆ bandwidth_stats_cont()

static void bandwidth_stats_cont ( void *  cls,
struct GNUNET_TESTBED_Operation *  op,
const char *  emsg 
)
static

Stats callback.

Finish the stats testbed operation and when all stats have been iterated, shutdown the test.

Parameters
clsclosure
opthe operation that has been finished
emsgerror message in case the operation has failed; will be NULL if operation has executed successfully.

Definition at line 340 of file gnunet_dht_profiler.c.

343{
344 MESSAGE ("# Outgoing (core) bandwidth: %llu bytes\n",
345 (unsigned long long) outgoing_bandwidth);
346 MESSAGE ("# Incoming (core) bandwidth: %llu bytes\n",
347 (unsigned long long) incoming_bandwidth);
348 fprintf (stderr,
349 "Benchmark done. Collect data via gnunet-statistics, then press ENTER to exit.\n");
350 (void) getchar ();
352}

References GNUNET_SCHEDULER_shutdown(), incoming_bandwidth, MESSAGE, and outgoing_bandwidth.

Referenced by summarize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ bandwidth_stats_iterator()

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 
)
static

Process statistic values.

Parameters
clsclosure
peerthe peer the statistic belong to
subsystemname of subsystem that created the statistic
namethe name of the datum
valuethe current value
is_persistentGNUNET_YES if the value is persistent, GNUNET_NO if not
Returns
GNUNET_OK to continue, GNUNET_SYSERR to abort iteration

Definition at line 367 of file gnunet_dht_profiler.c.

373{
374 static const char *s_sent = "# bytes encrypted";
375 static const char *s_recv = "# bytes decrypted";
376
377 if (0 == strncmp (s_sent, name, strlen (s_sent)))
379 else if (0 == strncmp (s_recv, name, strlen (s_recv)))
381 return GNUNET_OK;
382}

References GNUNET_OK, incoming_bandwidth, name, outgoing_bandwidth, and value.

Referenced by summarize().

Here is the caller graph for this function:

◆ summarize()

static void summarize ( )
static

Definition at line 386 of file gnunet_dht_profiler.c.

387{
388 MESSAGE ("# PUTS started: %llu\n",
389 n_puts);
390 MESSAGE ("# PUTS succeeded: %llu\n",
391 n_puts_ok);
392 MESSAGE ("# GETS made: %u\n",
393 n_gets);
394 MESSAGE ("# GETS succeeded: %u\n",
395 n_gets_ok);
396 MESSAGE ("# GETS failed: %u\n",
398 MESSAGE ("# average_put_path_length: %f\n",
400 MESSAGE ("# average_get_path_length: %f\n",
402
403 if (NULL == testbed_handles)
404 {
405 MESSAGE ("No peers found\n");
406 return;
407 }
408 /* Collect Stats*/
409 bandwidth_stats_op = GNUNET_TESTBED_get_statistics (n_active,
411 "core",
412 NULL,
415 NULL);
416}

References average_get_path_length, average_put_path_length, bandwidth_stats_cont(), bandwidth_stats_iterator(), bandwidth_stats_op, MESSAGE, n_active, n_gets, n_gets_fail, n_gets_ok, n_puts, n_puts_ok, and testbed_handles.

Referenced by cancel_get(), and get_iter().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cancel_get()

static void cancel_get ( void *  cls)
static

Task to cancel DHT GET.

Parameters
clsNULL

Definition at line 425 of file gnunet_dht_profiler.c.

426{
427 struct ActiveContext *ac = cls;
428 struct Context *ctx = ac->ctx;
429
430 ac->delay_task = NULL;
431 GNUNET_assert (NULL != ac->dht_get);
433 ac->dht_get = NULL;
434 n_gets_fail++;
435 GNUNET_assert (NULL != ctx->op);
436 GNUNET_TESTBED_operation_done (ctx->op);
437 ctx->op = NULL;
438
439 /* If profiling is complete, summarize */
441 {
443 / (double) n_active;
445 / (double ) n_gets_ok;
446 summarize ();
447 }
448}

References Context::ac, average_get_path_length, average_put_path_length, ctx, ActiveContext::ctx, ActiveContext::delay_task, ActiveContext::dht_get, GNUNET_assert, GNUNET_DHT_get_stop(), n_active, n_gets_fail, n_gets_ok, summarize(), total_get_path_length, and total_put_path_length.

Referenced by delayed_get().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_iter()

static void get_iter ( void *  cls,
struct GNUNET_TIME_Absolute  exp,
const struct GNUNET_HashCode key,
const struct GNUNET_PeerIdentity trunc_peer,
const struct GNUNET_DHT_PathElement get_path,
unsigned int  get_path_length,
const struct GNUNET_DHT_PathElement put_path,
unsigned int  put_path_length,
enum GNUNET_BLOCK_Type  type,
size_t  size,
const void *  data 
)
static

Iterator called on each result obtained for a DHT operation that expects a reply.

Parameters
clsclosure
expwhen will this value expire
keykey of the result
trunc_peerpeer the path was truncated at, or NULL
get_pathpeers on reply path (or NULL if not recorded) [0] = datastore's first neighbor, [length - 1] = local peer
get_path_lengthnumber of entries in get_path
put_pathpeers on the PUT path (or NULL if not recorded) [0] = origin, [length - 1] = datastore
put_path_lengthnumber of entries in put_path
typetype of the result
sizenumber of bytes in data
datapointer to the result data

Definition at line 470 of file gnunet_dht_profiler.c.

481{
482 struct ActiveContext *ac = cls;
483 struct ActiveContext *get_ac = ac->get_ac;
484 struct Context *ctx = ac->ctx;
485
486 /* we found the data we are looking for */
487 DEBUG ("We found a GET request; %u remaining\n",
488 n_gets - (n_gets_fail + n_gets_ok)); // FIXME: It always prints 1.
489 n_gets_ok++;
490 get_ac->nrefs--;
492 ac->dht_get = NULL;
493 if (ac->delay_task != NULL)
495 ac->delay_task = NULL;
496 GNUNET_assert (NULL != ctx->op);
497 GNUNET_TESTBED_operation_done (ctx->op);
498 ctx->op = NULL;
499
500 total_put_path_length = total_put_path_length + (double) put_path_length;
501 total_get_path_length = total_get_path_length + (double) get_path_length;
502 DEBUG ("total_put_path_length = %u,put_path \n",
504 /* Summarize if profiling is complete */
506 {
508 / (double) n_active;
510 / (double ) n_gets_ok;
511 summarize ();
512 }
513}

References Context::ac, average_get_path_length, average_put_path_length, ctx, ActiveContext::ctx, DEBUG, ActiveContext::delay_task, ActiveContext::dht_get, ActiveContext::get_ac, GNUNET_assert, GNUNET_DHT_get_stop(), GNUNET_SCHEDULER_cancel(), n_active, n_gets, n_gets_fail, n_gets_ok, ActiveContext::nrefs, summarize(), total_get_path_length, and total_put_path_length.

Referenced by delayed_get().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ delayed_get()

static void delayed_get ( void *  cls)
static

Task to do DHT GETs.

Parameters
clsthe active context

Definition at line 522 of file gnunet_dht_profiler.c.

523{
524 struct ActiveContext *ac = cls;
525 struct ActiveContext *get_ac;
526 unsigned int r;
527
528 ac->delay_task = NULL;
529 get_ac = NULL;
530 while (1)
531 {
533 get_ac = &a_ac[r];
534 if (NULL != get_ac->hash)
535 break;
536 }
537 get_ac->nrefs++;
538 ac->get_ac = get_ac;
540 DEBUG ("GET_REQUEST_START key %s \n",
541 GNUNET_h2s (&get_ac->hash[r]));
544 &get_ac->hash[r],
545 1, /* replication level */
547 NULL,
548 0, /* extended query and size */
549 &get_iter,
550 ac); /* GET iterator and closure */
551 n_gets++;
552
553 /* schedule the timeout task for GET */
555 &cancel_get,
556 ac);
557}

References a_ac, cancel_get(), DEBUG, ActiveContext::delay_task, ActiveContext::dht, ActiveContext::dht_get, ActiveContext::get_ac, get_iter(), GNUNET_BLOCK_TYPE_TEST, GNUNET_CRYPTO_random_u32(), GNUNET_DHT_get_start(), GNUNET_DHT_RO_NONE, GNUNET_h2s(), GNUNET_SCHEDULER_add_delayed(), ActiveContext::hash, n_active, n_gets, ActiveContext::nrefs, num_puts_per_peer, and timeout.

Referenced by dht_connected().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ delayed_put()

static void delayed_put ( void *  cls)
static

Task to do DHT PUTs.

If the "put_count" hits zero, we stop the TESTBED operation (connection to DHT) so that others PUTs have a chance.

Parameters
clsthe active context

Definition at line 597 of file gnunet_dht_profiler.c.

598{
599 struct ActiveContext *ac = cls;
600 char block[65536];
601 size_t block_size;
602
603 ac->delay_task = NULL;
604 if (0 == ac->put_count)
605 {
606 struct Context *ctx = ac->ctx;
607 struct GNUNET_TESTBED_Operation *op;
608
609 GNUNET_assert (NULL != ctx);
610 op = ctx->op;
611 ctx->op = NULL;
612 GNUNET_TESTBED_operation_done (op);
613 return;
614 }
615
616
617 /* Generate and DHT PUT some random data */
618 block_size = 16; /* minimum */
619 /* make random payload, reserve 512 - 16 bytes for DHT headers */
620 block_size += GNUNET_CRYPTO_random_u32 (
622 - 512);
624 block_size);
625 ac->put_count--;
626 GNUNET_CRYPTO_hash (block,
627 block_size,
628 &ac->hash[ac->put_count]);
629 DEBUG ("PUT_REQUEST_START key %s\n",
630 GNUNET_h2s (&ac->hash[ac->put_count]));
631 ac->dht_put = GNUNET_DHT_put (ac->dht,
632 &ac->hash[ac->put_count],
636 block_size,
637 block,
638 GNUNET_TIME_UNIT_FOREVER_ABS, /* expiration time */
639 &put_cont,
640 ac); /* continuation and its closure */
641 n_puts++;
642}

References Context::ac, ctx, ActiveContext::ctx, DEBUG, ActiveContext::delay_task, ActiveContext::dht, ActiveContext::dht_put, GNUNET_assert, GNUNET_BLOCK_TYPE_TEST, GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_random_block(), GNUNET_CRYPTO_random_u32(), GNUNET_DHT_put(), GNUNET_DHT_RO_RECORD_ROUTE, GNUNET_h2s(), GNUNET_TIME_UNIT_FOREVER_ABS, ActiveContext::hash, n_puts, op, put_cont(), ActiveContext::put_count, and replication.

Referenced by dht_connected(), and put_cont().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ put_cont()

static void put_cont ( void *  cls)
static

Conclude individual PUT operation, schedule the next one.

Parameters
clsthe active context

Definition at line 578 of file gnunet_dht_profiler.c.

579{
580 struct ActiveContext *ac = cls;
581
582 ac->dht_put = NULL;
583 n_puts_ok++;
585 ac);
586}

References ActiveContext::delay_task, delayed_put(), ActiveContext::dht_put, GNUNET_SCHEDULER_add_now(), and n_puts_ok.

Referenced by delayed_put().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dht_connected()

static void dht_connected ( void *  cls,
struct GNUNET_TESTBED_Operation *  op,
void *  ca_result,
const char *  emsg 
)
static

Connection to DHT has been established.

Call the delay task.

Parameters
clsthe active context
opthe operation that has been finished
ca_resultthe service handle returned from GNUNET_TESTBED_ConnectAdapter()
emsgerror message in case the operation has failed; will be NULL if operation has executed successfully.

Definition at line 655 of file gnunet_dht_profiler.c.

659{
660 struct ActiveContext *ac = cls;
661 struct Context *ctx = ac->ctx;
662
663 GNUNET_assert (NULL != ctx); // FIXME: Fails
664 GNUNET_assert (NULL != ctx->op);
665 GNUNET_assert (ctx->op == op);
666 ac->dht = (struct GNUNET_DHT_Handle *) ca_result;
667 if (NULL != emsg)
668 {
670 "Connection to DHT service failed: %s\n",
671 emsg);
672 GNUNET_TESTBED_operation_done (ctx->op); /* Calls dht_disconnect() */
673 ctx->op = NULL;
674 return;
675 }
676 switch (mode)
677 {
678 case MODE_PUT:
679 {
680 struct GNUNET_TIME_Relative peer_delay_put;
681
682 peer_delay_put.rel_value_us =
685 ac->hash = calloc (ac->put_count,
686 sizeof(struct GNUNET_HashCode));
687 if (NULL == ac->hash)
688 {
690 "calloc");
692 return;
693 }
694 ac->delay_task = GNUNET_SCHEDULER_add_delayed (peer_delay_put,
696 ac);
697 break;
698 }
699
700 case MODE_GET:
701 {
702 struct GNUNET_TIME_Relative peer_delay_get;
703
704 peer_delay_get.rel_value_us =
707 ac->delay_task = GNUNET_SCHEDULER_add_delayed (peer_delay_get,
709 ac);
710 break;
711 }
712 }
713}

References Context::ac, ctx, ActiveContext::ctx, delay_get, delay_put, ActiveContext::delay_task, delayed_get(), delayed_put(), ActiveContext::dht, GNUNET_assert, GNUNET_CRYPTO_random_u64(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_log_strerror, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_shutdown(), ActiveContext::hash, mode, MODE_GET, MODE_PUT, num_puts_per_peer, op, ActiveContext::put_count, and GNUNET_TIME_Relative::rel_value_us.

Referenced by start_profiling().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dht_connect()

static void * dht_connect ( void *  cls,
const struct GNUNET_CONFIGURATION_Handle cfg 
)
static

Connect to DHT service and return the DHT client handler.

Parameters
clsthe active context
cfgconfiguration of the peer to connect to; will be available until GNUNET_TESTBED_operation_done() is called on the operation returned from GNUNET_TESTBED_service_connect()
Returns
service handle to return in 'op_result', NULL on error

Definition at line 726 of file gnunet_dht_profiler.c.

728{
729 n_dht++;
730 return GNUNET_DHT_connect (cfg,
731 10);
732}

References cfg, GNUNET_DHT_connect(), and n_dht.

Referenced by start_profiling().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dht_disconnect()

static void dht_disconnect ( void *  cls,
void *  op_result 
)
static

Adapter function called to destroy a connection to a service.

Parameters
clsthe active context
op_resultservice handle returned from the connect adapter

Definition at line 743 of file gnunet_dht_profiler.c.

745{
746 struct ActiveContext *ac = cls;
747
748 GNUNET_assert (NULL != ac->dht);
749 GNUNET_assert (ac->dht == op_result);
751 ac->dht = NULL;
752 n_dht--;
753 if (0 != n_dht)
754 return;
755 if (GNUNET_YES == in_shutdown)
756 return;
757 switch (mode)
758 {
759 case MODE_PUT:
760 if (n_puts_ok != ((unsigned long long) n_active) * num_puts_per_peer)
761 return;
762 /* Start GETs if all PUTs have been made */
763 mode = MODE_GET;
765 return;
766
767 case MODE_GET:
768 if ((n_gets_ok + n_gets_fail) != n_active)
769 return;
770 break;
771 }
772}

References ActiveContext::dht, GNUNET_assert, GNUNET_DHT_disconnect(), GNUNET_YES, in_shutdown, mode, MODE_GET, MODE_PUT, n_active, n_dht, n_gets_fail, n_gets_ok, n_puts_ok, num_puts_per_peer, and start_profiling().

Referenced by start_profiling().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ service_started()

static void service_started ( void *  cls,
struct GNUNET_TESTBED_Operation *  op,
const char *  emsg 
)
static

Callback called when DHT service on the peer is started.

Parameters
clsthe context
opthe operation that has been finished
emsgerror message in case the operation has failed; will be NULL if operation has executed successfully.

Definition at line 810 of file gnunet_dht_profiler.c.

813{
814 struct Context *ctx = cls;
815
816 GNUNET_assert (NULL != ctx);
817 GNUNET_assert (NULL != ctx->op);
818 GNUNET_TESTBED_operation_done (ctx->op);
819 ctx->op = NULL;
821 DEBUG ("Peers Started = %d; num_peers = %d \n",
823 num_peers);
826}

References ctx, DEBUG, GNUNET_assert, num_peers, peers_started, and start_profiling().

Referenced by test_run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_run()

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 
)
static

Signature of a main function for a testcase.

Parameters
clsclosure
hthe run handle
num_peersnumber of peers in 'peers'
peershandle to peers run in the testbed
links_succeededthe number of overlay link connection attempts that succeeded
links_failedthe number of overlay link

Definition at line 841 of file gnunet_dht_profiler.c.

847{
848 unsigned int ac_cnt;
849
851 if (NULL == peers)
852 {
853 /* exit */
854 GNUNET_assert (0);
855 }
856 MESSAGE ("%u peers started, %u/%u links up\n",
857 num_peers,
858 links_succeeded,
859 links_succeeded + links_failed);
861 struct Context);
862 /* select the peers which actively participate in profiling */
864 if (0 == n_active)
865 {
868 a_ctx = NULL;
869 return;
870 }
871
873 struct ActiveContext);
874 ac_cnt = 0;
875 for (unsigned int cnt = 0; cnt < num_peers && ac_cnt < n_active; cnt++)
876 {
878 continue;
879
880 a_ctx[cnt].ac = &a_ac[ac_cnt];
881 a_ac[ac_cnt].ctx = &a_ctx[cnt];
882 ac_cnt++;
883 }
884 n_active = ac_cnt;
885
886 /* start DHT service on all peers */
887 for (unsigned int cnt = 0; cnt < num_peers; cnt++)
888 {
889 a_ctx[cnt].peer = peers[cnt];
890 a_ctx[cnt].op = GNUNET_TESTBED_peer_manage_service (&a_ctx[cnt],
891 peers[cnt],
892 "dht",
894 &a_ctx[cnt],
895 1);
896 }
897}

References a_ac, a_ctx, Context::ac, ActiveContext::ctx, GNUNET_assert, GNUNET_CRYPTO_random_u32(), GNUNET_free, GNUNET_new_array, GNUNET_SCHEDULER_shutdown(), MESSAGE, n_active, num_peers, Context::op, Context::peer, peers, put_probability, service_started(), and testbed_handles.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ run()

static void run ( void *  cls,
char *const *  args,
const char *  cfgfile,
const struct GNUNET_CONFIGURATION_Handle config 
)
static

Main function that will be run by the scheduler.

Parameters
clsclosure
argsremaining command-line arguments
cfgfilename of the configuration file used (for saving, can be NULL!)
configconfiguration

Definition at line 909 of file gnunet_dht_profiler.c.

913{
914 uint64_t event_mask;
915
916 if (0 == num_peers)
917 {
919 _ ("Exiting as the number of peers is %u\n"),
920 num_peers);
921 return;
922 }
923 cfg = config;
924 event_mask = 0;
925 GNUNET_TESTBED_run (hosts_file,
926 cfg,
927 num_peers,
929 NULL,
930 NULL,
931 &test_run,
932 NULL);
934 NULL);
935}

References _, cfg, config, do_shutdown, event_mask, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_SCHEDULER_add_shutdown(), hosts_file, num_peers, and test_run().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char *const *  argv 
)

Main function.

Returns
0 on success

Definition at line 944 of file gnunet_dht_profiler.c.

946{
947 int rc;
950 "peers",
951 "COUNT",
952 gettext_noop ("number of peers to start"),
953 &num_peers),
955 "peer-put-count",
956 "COUNT",
958 "number of PUTs to perform per peer"),
961 "hosts",
962 "FILENAME",
964 "name of the file with the login information for the testbed"),
965 &hosts_file),
967 "delay",
968 "DELAY",
970 "delay between rounds for collecting statistics (default: 30 sec)"),
971 &delay_stats),
973 "PUT-delay",
974 "DELAY",
976 "delay to start doing PUTs (default: 1 sec)"),
977 &delay_put),
979 "GET-delay",
980 "DELAY",
982 "delay to start doing GETs (default: 5 min)"),
983 &delay_get),
985 "replication",
986 "DEGREE",
987 gettext_noop ("replication degree for DHT PUTs"),
988 &replication),
990 "random-chance",
991 "PROBABILITY",
993 "chance that a peer is selected at random for PUTs"),
996 "timeout",
997 "TIMEOUT",
999 "timeout for DHT PUT and GET requests (default: 1 min)"),
1000 &timeout),
1002 };
1003
1004 /* set default delays */
1009 replication = 1; /* default replication */
1010 rc = 0;
1011 if (GNUNET_OK !=
1012 GNUNET_PROGRAM_run (argc,
1013 argv,
1014 "gnunet-dht-profiler",
1015 gettext_noop (
1016 "Measure quality and performance of the DHT service."),
1017 options,
1018 &run,
1019 NULL))
1020 rc = 1;
1021 return rc;
1022}

References delay_get, delay_put, delay_stats, gettext_noop, GNUNET_GETOPT_OPTION_END, GNUNET_GETOPT_option_relative_time(), GNUNET_GETOPT_option_string(), GNUNET_GETOPT_option_uint(), GNUNET_OK, GNUNET_PROGRAM_run(), GNUNET_TIME_relative_multiply(), GNUNET_TIME_UNIT_SECONDS, hosts_file, num_peers, num_puts_per_peer, options, put_probability, replication, run(), and timeout.

Here is the call graph for this function:

Variable Documentation

◆ put_probability

unsigned int put_probability = 100
static

Number of peers which should perform a PUT out of 100 peers.

Definition at line 43 of file gnunet_dht_profiler.c.

Referenced by main(), and test_run().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Configuration.

Definition at line 48 of file gnunet_dht_profiler.c.

Referenced by dht_connect(), and run().

◆ hosts_file

char* hosts_file
static

Name of the file with the hosts to run the test over.

Definition at line 53 of file gnunet_dht_profiler.c.

Referenced by main(), and run().

◆ a_ctx

struct Context* a_ctx
static

An array of contexts.

The size of this array should be equal to num_peers

Definition at line 138 of file gnunet_dht_profiler.c.

Referenced by do_shutdown(), and test_run().

◆ a_ac

struct ActiveContext* a_ac
static

Array of active peers.

Definition at line 143 of file gnunet_dht_profiler.c.

Referenced by delayed_get(), do_shutdown(), start_profiling(), and test_run().

◆ delay_stats

struct GNUNET_TIME_Relative delay_stats
static

The delay between rounds for collecting statistics.

Definition at line 148 of file gnunet_dht_profiler.c.

Referenced by main().

◆ delay_put

struct GNUNET_TIME_Relative delay_put
static

The delay to start puts.

Definition at line 153 of file gnunet_dht_profiler.c.

Referenced by dht_connected(), and main().

◆ delay_get

struct GNUNET_TIME_Relative delay_get
static

The delay to start puts.

Definition at line 158 of file gnunet_dht_profiler.c.

Referenced by dht_connected(), and main().

◆ timeout

struct GNUNET_TIME_Relative timeout
static

The timeout for GET and PUT.

Definition at line 163 of file gnunet_dht_profiler.c.

Referenced by delayed_get(), and main().

◆ num_peers

◆ n_active

unsigned int n_active
static

Number of active peers.

Definition at line 173 of file gnunet_dht_profiler.c.

Referenced by cancel_get(), delayed_get(), dht_disconnect(), get_iter(), start_profiling(), summarize(), and test_run().

◆ n_dht

unsigned int n_dht
static

Number of DHT service connections we currently have.

Definition at line 178 of file gnunet_dht_profiler.c.

Referenced by dht_connect(), and dht_disconnect().

◆ n_puts

unsigned long long n_puts
static

Number of DHT PUTs made.

Definition at line 183 of file gnunet_dht_profiler.c.

Referenced by delayed_put(), and summarize().

◆ num_puts_per_peer

unsigned int num_puts_per_peer = 1
static

Number of DHT PUTs to be made per peer.

Definition at line 188 of file gnunet_dht_profiler.c.

Referenced by delayed_get(), dht_connected(), dht_disconnect(), and main().

◆ n_puts_ok

unsigned long long n_puts_ok
static

Number of DHT PUTs succeeded.

Definition at line 193 of file gnunet_dht_profiler.c.

Referenced by dht_disconnect(), put_cont(), and summarize().

◆ n_gets

unsigned int n_gets
static

Number of DHT GETs made.

Definition at line 198 of file gnunet_dht_profiler.c.

Referenced by delayed_get(), get_iter(), and summarize().

◆ n_gets_ok

unsigned int n_gets_ok
static

Number of DHT GETs succeeded.

Definition at line 203 of file gnunet_dht_profiler.c.

Referenced by cancel_get(), dht_disconnect(), get_iter(), and summarize().

◆ n_gets_fail

unsigned int n_gets_fail
static

Number of DHT GETs succeeded.

Definition at line 208 of file gnunet_dht_profiler.c.

Referenced by cancel_get(), dht_disconnect(), get_iter(), and summarize().

◆ replication

unsigned int replication
static

Replication degree.

Definition at line 213 of file gnunet_dht_profiler.c.

Referenced by delayed_put(), and main().

◆ bandwidth_stats_op

struct GNUNET_TESTBED_Operation* bandwidth_stats_op
static

Testbed Operation (to get stats).

Definition at line 218 of file gnunet_dht_profiler.c.

Referenced by do_shutdown(), and summarize().

◆ testbed_handles

struct GNUNET_TESTBED_Peer** testbed_handles
static

Testbed peer handles.

Definition at line 223 of file gnunet_dht_profiler.c.

Referenced by summarize(), and test_run().

◆ outgoing_bandwidth

uint64_t outgoing_bandwidth
static

Total number of messages sent by peer.

Definition at line 228 of file gnunet_dht_profiler.c.

Referenced by bandwidth_stats_cont(), and bandwidth_stats_iterator().

◆ incoming_bandwidth

uint64_t incoming_bandwidth
static

Total number of messages received by peer.

Definition at line 233 of file gnunet_dht_profiler.c.

Referenced by bandwidth_stats_cont(), and bandwidth_stats_iterator().

◆ average_put_path_length

double average_put_path_length
static

Average number of hops taken to do put.

Definition at line 238 of file gnunet_dht_profiler.c.

Referenced by cancel_get(), get_iter(), and summarize().

◆ average_get_path_length

double average_get_path_length
static

Average number of hops taken to do get.

Definition at line 243 of file gnunet_dht_profiler.c.

Referenced by cancel_get(), get_iter(), and summarize().

◆ total_put_path_length

unsigned int total_put_path_length
static

Total put path length across all peers.

Definition at line 248 of file gnunet_dht_profiler.c.

Referenced by cancel_get(), and get_iter().

◆ total_get_path_length

unsigned int total_get_path_length
static

Total get path length across all peers.

Definition at line 253 of file gnunet_dht_profiler.c.

Referenced by cancel_get(), and get_iter().

◆ peers_started

int peers_started = 0
static

Counter to keep track of peers added to peer_context lists.

Definition at line 258 of file gnunet_dht_profiler.c.

Referenced by service_started().

◆ []

◆ in_shutdown

int in_shutdown = 0
static

Are we shutting down.

Definition at line 274 of file gnunet_dht_profiler.c.

Referenced by dht_disconnect(), do_shutdown(), and start_profiling().