diff options
Diffstat (limited to 'src/dht/gnunet_dht_r5n_profiler.c')
-rw-r--r-- | src/dht/gnunet_dht_r5n_profiler.c | 174 |
1 files changed, 143 insertions, 31 deletions
diff --git a/src/dht/gnunet_dht_r5n_profiler.c b/src/dht/gnunet_dht_r5n_profiler.c index 9921c0aed..95528b3f9 100644 --- a/src/dht/gnunet_dht_r5n_profiler.c +++ b/src/dht/gnunet_dht_r5n_profiler.c | |||
@@ -21,7 +21,7 @@ | |||
21 | /** | 21 | /** |
22 | * @file dht/gnunet_dht_profiler.c | 22 | * @file dht/gnunet_dht_profiler.c |
23 | * @brief Profiler for GNUnet DHT | 23 | * @brief Profiler for GNUnet DHT |
24 | * @author Sree Harsha Totakura <sreeharsha@totakura.in> | 24 | * @author Sree Harsha Totakura <sreeharsha@totakura.in> |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include "platform.h" | 27 | #include "platform.h" |
@@ -38,7 +38,7 @@ | |||
38 | /** | 38 | /** |
39 | * Number of peers which should perform a PUT out of 100 peers | 39 | * Number of peers which should perform a PUT out of 100 peers |
40 | */ | 40 | */ |
41 | #define PUT_PROBABILITY 50 | 41 | #define PUT_PROBABILITY 100 |
42 | 42 | ||
43 | /** | 43 | /** |
44 | * Configuration | 44 | * Configuration |
@@ -114,7 +114,7 @@ struct ActiveContext | |||
114 | struct GNUNET_DHT_GetHandle *dht_get; | 114 | struct GNUNET_DHT_GetHandle *dht_get; |
115 | 115 | ||
116 | /** | 116 | /** |
117 | * The hash of the @put_data | 117 | * The hash of the @e put_data |
118 | */ | 118 | */ |
119 | struct GNUNET_HashCode hash; | 119 | struct GNUNET_HashCode hash; |
120 | 120 | ||
@@ -124,7 +124,7 @@ struct ActiveContext | |||
124 | GNUNET_SCHEDULER_TaskIdentifier delay_task; | 124 | GNUNET_SCHEDULER_TaskIdentifier delay_task; |
125 | 125 | ||
126 | /** | 126 | /** |
127 | * The size of the put_data | 127 | * The size of the @e put_data |
128 | */ | 128 | */ |
129 | uint16_t put_data_size; | 129 | uint16_t put_data_size; |
130 | 130 | ||
@@ -200,8 +200,45 @@ static unsigned int n_gets_ok; | |||
200 | */ | 200 | */ |
201 | static unsigned int n_gets_fail; | 201 | static unsigned int n_gets_fail; |
202 | 202 | ||
203 | /** | ||
204 | * Replication degree | ||
205 | */ | ||
206 | static unsigned int replication; | ||
207 | |||
208 | /** | ||
209 | * Testbed Operation (to get stats). | ||
210 | */ | ||
211 | static struct GNUNET_TESTBED_Operation *stats_op; | ||
212 | |||
213 | /** | ||
214 | * Testbed peer handles. | ||
215 | */ | ||
216 | static struct GNUNET_TESTBED_Peer **testbed_handles; | ||
217 | |||
218 | /** | ||
219 | * Total number of messages sent by peer. | ||
220 | */ | ||
221 | static uint64_t outgoing_bandwidth; | ||
222 | |||
223 | /** | ||
224 | * Total number of messages received by peer. | ||
225 | */ | ||
226 | static uint64_t incoming_bandwidth; | ||
227 | |||
228 | /** | ||
229 | * Average number of hops taken to do put. | ||
230 | */ | ||
231 | static unsigned int average_put_path_length; | ||
203 | 232 | ||
204 | /** | 233 | /** |
234 | * Average number of hops taken to do get. | ||
235 | */ | ||
236 | static unsigned int average_get_path_length; | ||
237 | |||
238 | static unsigned int total_put_path_length; | ||
239 | |||
240 | static unsigned int total_get_path_length; | ||
241 | /** | ||
205 | * Shutdown task. Cleanup all resources and operations. | 242 | * Shutdown task. Cleanup all resources and operations. |
206 | * | 243 | * |
207 | * @param cls NULL | 244 | * @param cls NULL |
@@ -212,14 +249,14 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
212 | { | 249 | { |
213 | struct ActiveContext *ac; | 250 | struct ActiveContext *ac; |
214 | unsigned int cnt; | 251 | unsigned int cnt; |
215 | 252 | ||
216 | if (NULL != a_ctx) | 253 | if (NULL != a_ctx) |
217 | { | 254 | { |
218 | for (cnt=0; cnt < num_peers; cnt++) | 255 | for (cnt=0; cnt < num_peers; cnt++) |
219 | { | 256 | { |
220 | if (NULL != a_ctx[cnt].op) | 257 | if (NULL != a_ctx[cnt].op) |
221 | GNUNET_TESTBED_operation_done (a_ctx[cnt].op); | 258 | GNUNET_TESTBED_operation_done (a_ctx[cnt].op); |
222 | 259 | ||
223 | /* Cleanup active context if this peer is an active peer */ | 260 | /* Cleanup active context if this peer is an active peer */ |
224 | ac = a_ctx[cnt].ac; | 261 | ac = a_ctx[cnt].ac; |
225 | if (NULL == ac) | 262 | if (NULL == ac) |
@@ -236,10 +273,68 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
236 | GNUNET_free (a_ctx); | 273 | GNUNET_free (a_ctx); |
237 | a_ctx = NULL; | 274 | a_ctx = NULL; |
238 | } | 275 | } |
276 | if(NULL != stats_op) | ||
277 | GNUNET_TESTBED_operation_done (stats_op); | ||
278 | stats_op = NULL; | ||
239 | GNUNET_free_non_null (a_ac); | 279 | GNUNET_free_non_null (a_ac); |
240 | } | 280 | } |
241 | 281 | ||
242 | 282 | ||
283 | /** | ||
284 | * Stats callback. Finish the stats testbed operation and when all stats have | ||
285 | * been iterated, shutdown the test. | ||
286 | * | ||
287 | * @param cls closure | ||
288 | * @param op the operation that has been finished | ||
289 | * @param emsg error message in case the operation has failed; will be NULL if | ||
290 | * operation has executed successfully. | ||
291 | */ | ||
292 | static void | ||
293 | bandwidth_stats_cont (void *cls, | ||
294 | struct GNUNET_TESTBED_Operation *op, | ||
295 | const char *emsg) | ||
296 | { | ||
297 | INFO ("# Outgoing bandwidth: %u\n", outgoing_bandwidth); | ||
298 | INFO ("# Incoming bandwidth: %u\n", incoming_bandwidth); | ||
299 | GNUNET_SCHEDULER_shutdown (); | ||
300 | } | ||
301 | |||
302 | |||
303 | /** | ||
304 | * Process statistic values. | ||
305 | * | ||
306 | * @param cls closure | ||
307 | * @param peer the peer the statistic belong to | ||
308 | * @param subsystem name of subsystem that created the statistic | ||
309 | * @param name the name of the datum | ||
310 | * @param value the current value | ||
311 | * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not | ||
312 | * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration | ||
313 | */ | ||
314 | static int | ||
315 | bandwidth_stats_iterator (void *cls, | ||
316 | const struct GNUNET_TESTBED_Peer *peer, | ||
317 | const char *subsystem, | ||
318 | const char *name, | ||
319 | uint64_t value, | ||
320 | int is_persistent) | ||
321 | { | ||
322 | static const char *s_sent = "# Bytes transmitted to other peers"; | ||
323 | static const char *s_recv = "# Bytes received from other peers"; | ||
324 | |||
325 | if (0 == strncmp (s_sent, name, strlen (s_sent))) | ||
326 | outgoing_bandwidth = outgoing_bandwidth + value; | ||
327 | else if (0 == strncmp(s_recv, name, strlen (s_recv))) | ||
328 | incoming_bandwidth = incoming_bandwidth + value; | ||
329 | else | ||
330 | return GNUNET_OK; | ||
331 | DEBUG ("Bandwith - Out: %lu; In: %lu\n", | ||
332 | (unsigned long) outgoing_bandwidth, | ||
333 | (unsigned long) incoming_bandwidth); | ||
334 | return GNUNET_OK; | ||
335 | } | ||
336 | |||
337 | |||
243 | static void | 338 | static void |
244 | summarize () | 339 | summarize () |
245 | { | 340 | { |
@@ -249,7 +344,19 @@ summarize () | |||
249 | INFO ("# GETS made: %u\n", n_gets); | 344 | INFO ("# GETS made: %u\n", n_gets); |
250 | INFO ("# GETS succeeded: %u\n", n_gets_ok); | 345 | INFO ("# GETS succeeded: %u\n", n_gets_ok); |
251 | INFO ("# GETS failed: %u\n", n_gets_fail); | 346 | INFO ("# GETS failed: %u\n", n_gets_fail); |
252 | GNUNET_SCHEDULER_shutdown (); | 347 | INFO ("# average_put_path_length: %u\n", average_put_path_length); |
348 | INFO ("# average_get_path_length: %u\n", average_get_path_length); | ||
349 | |||
350 | if (NULL == testbed_handles) | ||
351 | { | ||
352 | INFO ("No peers found\n"); | ||
353 | return; | ||
354 | } | ||
355 | /* Collect Stats*/ | ||
356 | stats_op = GNUNET_TESTBED_get_statistics (n_active, testbed_handles, | ||
357 | "dht", NULL, | ||
358 | bandwidth_stats_iterator, | ||
359 | bandwidth_stats_cont, NULL); | ||
253 | } | 360 | } |
254 | 361 | ||
255 | 362 | ||
@@ -271,8 +378,9 @@ cancel_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
271 | n_gets_fail++; | 378 | n_gets_fail++; |
272 | 379 | ||
273 | /* If profiling is complete, summarize */ | 380 | /* If profiling is complete, summarize */ |
274 | if (n_gets == n_gets_fail + n_gets_ok) | 381 | if (n_active == n_gets_fail + n_gets_ok) |
275 | summarize (); | 382 | summarize (); |
383 | |||
276 | } | 384 | } |
277 | 385 | ||
278 | 386 | ||
@@ -293,7 +401,7 @@ cancel_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
293 | * @param size number of bytes in @a data | 401 | * @param size number of bytes in @a data |
294 | * @param data pointer to the result data | 402 | * @param data pointer to the result data |
295 | */ | 403 | */ |
296 | static void | 404 | static void |
297 | get_iter (void *cls, | 405 | get_iter (void *cls, |
298 | struct GNUNET_TIME_Absolute exp, | 406 | struct GNUNET_TIME_Absolute exp, |
299 | const struct GNUNET_HashCode *key, | 407 | const struct GNUNET_HashCode *key, |
@@ -306,18 +414,9 @@ get_iter (void *cls, | |||
306 | { | 414 | { |
307 | struct ActiveContext *ac = cls; | 415 | struct ActiveContext *ac = cls; |
308 | struct ActiveContext *get_ac = ac->get_ac; | 416 | struct ActiveContext *get_ac = ac->get_ac; |
309 | |||
310 | if (get_ac->put_data_size != size) | ||
311 | { | ||
312 | DEBUG ("Found a GET with incorrect data length (this may happen, but very unlikely)\n"); | ||
313 | return; | ||
314 | } | ||
315 | if (0 != memcmp (data, get_ac->put_data, size)) | ||
316 | { | ||
317 | DEBUG ("Found a GET with incorrect data (this may happen, but very unlikely)\n"); | ||
318 | return; | ||
319 | } | ||
320 | 417 | ||
418 | /* Check the keys of put and get match or not. */ | ||
419 | GNUNET_assert (0 == memcmp (key, &get_ac->hash, sizeof (struct GNUNET_HashCode))); | ||
321 | /* we found the data we are looking for */ | 420 | /* we found the data we are looking for */ |
322 | DEBUG ("We found a GET request; %u remaining\n", n_gets - (n_gets_fail + n_gets_ok)); | 421 | DEBUG ("We found a GET request; %u remaining\n", n_gets - (n_gets_fail + n_gets_ok)); |
323 | n_gets_ok++; | 422 | n_gets_ok++; |
@@ -326,10 +425,17 @@ get_iter (void *cls, | |||
326 | ac->dht_get = NULL; | 425 | ac->dht_get = NULL; |
327 | GNUNET_SCHEDULER_cancel (ac->delay_task); | 426 | GNUNET_SCHEDULER_cancel (ac->delay_task); |
328 | ac->delay_task = GNUNET_SCHEDULER_NO_TASK; | 427 | ac->delay_task = GNUNET_SCHEDULER_NO_TASK; |
329 | 428 | ||
429 | total_put_path_length = total_put_path_length + put_path_length; | ||
430 | total_get_path_length = total_get_path_length + get_path_length; | ||
431 | |||
330 | /* Summarize if profiling is complete */ | 432 | /* Summarize if profiling is complete */ |
331 | if (n_gets == n_gets_fail + n_gets_ok) | 433 | if (n_active == n_gets_fail + n_gets_ok) |
434 | { | ||
435 | average_put_path_length = total_put_path_length/n_active; | ||
436 | average_get_path_length = total_get_path_length/n_active; | ||
332 | summarize (); | 437 | summarize (); |
438 | } | ||
333 | } | 439 | } |
334 | 440 | ||
335 | 441 | ||
@@ -357,9 +463,10 @@ delayed_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
357 | } | 463 | } |
358 | get_ac->nrefs++; | 464 | get_ac->nrefs++; |
359 | ac->get_ac = get_ac; | 465 | ac->get_ac = get_ac; |
466 | DEBUG ("Doing a DHT GET for data of size %u\n", get_ac->put_data_size); | ||
360 | ac->dht_get = GNUNET_DHT_get_start (ac->dht, | 467 | ac->dht_get = GNUNET_DHT_get_start (ac->dht, |
361 | GNUNET_BLOCK_TYPE_TEST, | 468 | GNUNET_BLOCK_TYPE_TEST, |
362 | &ac->hash, | 469 | &get_ac->hash, |
363 | 1, /* replication level */ | 470 | 1, /* replication level */ |
364 | GNUNET_DHT_RO_NONE, | 471 | GNUNET_DHT_RO_NONE, |
365 | NULL, 0, /* extended query and size */ | 472 | NULL, 0, /* extended query and size */ |
@@ -413,12 +520,12 @@ delayed_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
413 | ac->put_data_size += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | 520 | ac->put_data_size += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, |
414 | (63*1024)); | 521 | (63*1024)); |
415 | ac->put_data = GNUNET_malloc (ac->put_data_size); | 522 | ac->put_data = GNUNET_malloc (ac->put_data_size); |
416 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, | 523 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, |
417 | ac->put_data, ac->put_data_size); | 524 | ac->put_data, ac->put_data_size); |
418 | GNUNET_CRYPTO_hash (ac->put_data, ac->put_data_size, &ac->hash); | 525 | GNUNET_CRYPTO_hash (ac->put_data, ac->put_data_size, &ac->hash); |
419 | DEBUG ("Doing a DHT PUT with data of size %u\n", ac->put_data_size); | 526 | DEBUG ("Doing a DHT PUT with data of size %u\n", ac->put_data_size); |
420 | ac->dht_put = GNUNET_DHT_put (ac->dht, &ac->hash, | 527 | ac->dht_put = GNUNET_DHT_put (ac->dht, &ac->hash, |
421 | 1, /* replication level */ | 528 | replication, |
422 | GNUNET_DHT_RO_NONE, | 529 | GNUNET_DHT_RO_NONE, |
423 | GNUNET_BLOCK_TYPE_TEST, | 530 | GNUNET_BLOCK_TYPE_TEST, |
424 | ac->put_data_size, | 531 | ac->put_data_size, |
@@ -487,7 +594,7 @@ dht_connect (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
487 | * @param cls the active context | 594 | * @param cls the active context |
488 | * @param op_result service handle returned from the connect adapter | 595 | * @param op_result service handle returned from the connect adapter |
489 | */ | 596 | */ |
490 | static void | 597 | static void |
491 | dht_disconnect (void *cls, void *op_result) | 598 | dht_disconnect (void *cls, void *op_result) |
492 | { | 599 | { |
493 | struct ActiveContext *ac = cls; | 600 | struct ActiveContext *ac = cls; |
@@ -552,7 +659,8 @@ test_run (void *cls, | |||
552 | { | 659 | { |
553 | unsigned int cnt; | 660 | unsigned int cnt; |
554 | unsigned int ac_cnt; | 661 | unsigned int ac_cnt; |
555 | 662 | ||
663 | testbed_handles = peers; | ||
556 | if (NULL == peers) | 664 | if (NULL == peers) |
557 | { | 665 | { |
558 | /* exit */ | 666 | /* exit */ |
@@ -560,7 +668,7 @@ test_run (void *cls, | |||
560 | } | 668 | } |
561 | INFO ("%u peers started\n", num_peers); | 669 | INFO ("%u peers started\n", num_peers); |
562 | a_ctx = GNUNET_malloc (sizeof (struct Context) * num_peers); | 670 | a_ctx = GNUNET_malloc (sizeof (struct Context) * num_peers); |
563 | 671 | ||
564 | /* select the peers which actively participate in profiling */ | 672 | /* select the peers which actively participate in profiling */ |
565 | n_active = num_peers * PUT_PROBABILITY / 100; | 673 | n_active = num_peers * PUT_PROBABILITY / 100; |
566 | if (0 == n_active) | 674 | if (0 == n_active) |
@@ -611,7 +719,7 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
611 | const struct GNUNET_CONFIGURATION_Handle *config) | 719 | const struct GNUNET_CONFIGURATION_Handle *config) |
612 | { | 720 | { |
613 | uint64_t event_mask; | 721 | uint64_t event_mask; |
614 | 722 | ||
615 | if (0 == num_peers) | 723 | if (0 == num_peers) |
616 | { | 724 | { |
617 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Exiting as the number of peers is %u\n"), | 725 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Exiting as the number of peers is %u\n"), |
@@ -647,6 +755,9 @@ main (int argc, char *const *argv) | |||
647 | {'d', "delay", "DELAY", | 755 | {'d', "delay", "DELAY", |
648 | gettext_noop ("delay for starting DHT PUT and GET"), | 756 | gettext_noop ("delay for starting DHT PUT and GET"), |
649 | 1, &GNUNET_GETOPT_set_relative_time, &delay}, | 757 | 1, &GNUNET_GETOPT_set_relative_time, &delay}, |
758 | {'r', "replication", "DEGREE", | ||
759 | gettext_noop ("replication degree for DHT PUTs"), | ||
760 | 1, &GNUNET_GETOPT_set_uint, &replication}, | ||
650 | {'t', "timeout", "TIMEOUT", | 761 | {'t', "timeout", "TIMEOUT", |
651 | gettext_noop ("timeout for DHT PUT and GET requests"), | 762 | gettext_noop ("timeout for DHT PUT and GET requests"), |
652 | 1, &GNUNET_GETOPT_set_relative_time, &timeout}, | 763 | 1, &GNUNET_GETOPT_set_relative_time, &timeout}, |
@@ -655,8 +766,9 @@ main (int argc, char *const *argv) | |||
655 | 766 | ||
656 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | 767 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) |
657 | return 2; | 768 | return 2; |
658 | delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3); /* default delay */ | 769 | delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30); /* default delay */ |
659 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3); /* default timeout */ | 770 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1); /* default timeout */ |
771 | replication = 1; /* default replication */ | ||
660 | rc = 0; | 772 | rc = 0; |
661 | if (GNUNET_OK != | 773 | if (GNUNET_OK != |
662 | GNUNET_PROGRAM_run (argc, argv, "dht-profiler", | 774 | GNUNET_PROGRAM_run (argc, argv, "dht-profiler", |