aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-09-05 12:36:34 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-09-05 12:36:34 +0000
commitab98625d6e8f82dc7c897c48081b0f1fef947f8d (patch)
tree5e9dadb5a3945f416310fe40ff888adab43a21b8 /src/dht
parentebb5527954a8e214324d76f0c1c181cab3c51170 (diff)
downloadgnunet-ab98625d6e8f82dc7c897c48081b0f1fef947f8d.tar.gz
gnunet-ab98625d6e8f82dc7c897c48081b0f1fef947f8d.zip
Removing r5n profiler, using the same profiler for both x-vine and r5n
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/Makefile.am13
-rw-r--r--src/dht/gnunet_dht_profiler.c12
-rw-r--r--src/dht/gnunet_dht_r5n_profiler.c781
3 files changed, 13 insertions, 793 deletions
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am
index b9e7c5d67..f8918616f 100644
--- a/src/dht/Makefile.am
+++ b/src/dht/Makefile.am
@@ -56,8 +56,7 @@ noinst_PROGRAMS = \
56 gnunet-dht-monitor \ 56 gnunet-dht-monitor \
57 gnunet-dht-get \ 57 gnunet-dht-get \
58 gnunet-dht-put \ 58 gnunet-dht-put \
59 gnunet-dht-profiler\ 59 gnunet-dht-profiler
60 gnunet-dht-r5n-profiler
61 60
62gnunet_service_dht_SOURCES = \ 61gnunet_service_dht_SOURCES = \
63 gnunet-service-dht.c gnunet-service-dht.h \ 62 gnunet-service-dht.c gnunet-service-dht.h \
@@ -140,16 +139,6 @@ gnunet_dht_profiler_LDADD = \
140gnunet_dht_profiler_DEPENDENCIES = \ 139gnunet_dht_profiler_DEPENDENCIES = \
141 libgnunetdht.la 140 libgnunetdht.la
142 141
143gnunet_dht_r5n_profiler_SOURCES = \
144 gnunet_dht_r5n_profiler.c
145gnunet_dht_r5n_profiler_LDADD = \
146 $(top_builddir)/src/dht/libgnunetdht.la \
147 $(top_builddir)/src/core/libgnunetcore.la \
148 $(top_builddir)/src/util/libgnunetutil.la \
149 $(top_builddir)/src/testbed/libgnunettestbed.la
150gnunet_dht_r5n_profiler_DEPENDENCIES = \
151 libgnunetdht.la
152
153if HAVE_TESTING 142if HAVE_TESTING
154noinst_LIBRARIES = libgnunetdhttest.a 143noinst_LIBRARIES = libgnunetdhttest.a
155endif 144endif
diff --git a/src/dht/gnunet_dht_profiler.c b/src/dht/gnunet_dht_profiler.c
index c5475c604..27aa892fa 100644
--- a/src/dht/gnunet_dht_profiler.c
+++ b/src/dht/gnunet_dht_profiler.c
@@ -63,6 +63,11 @@ static char *hosts_file;
63struct ActiveContext; 63struct ActiveContext;
64 64
65/** 65/**
66 * Context for a peer which should act maliciously.
67 */
68struct MaliciousContext;
69
70/**
66 * Context to hold data of peer 71 * Context to hold data of peer
67 */ 72 */
68struct Context 73struct Context
@@ -82,6 +87,13 @@ struct Context
82 * Active context; NULL if this peer is not an active peer 87 * Active context; NULL if this peer is not an active peer
83 */ 88 */
84 struct ActiveContext *ac; 89 struct ActiveContext *ac;
90
91#if ENABLE_MALICIOUS
92 /**
93 * Malicious context; NULL if this peer is NOT malicious.
94 */
95 struct MaliciousContext *mc;
96#endif
85}; 97};
86 98
87 99
diff --git a/src/dht/gnunet_dht_r5n_profiler.c b/src/dht/gnunet_dht_r5n_profiler.c
deleted file mode 100644
index f5278b3a6..000000000
--- a/src/dht/gnunet_dht_r5n_profiler.c
+++ /dev/null
@@ -1,781 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2014 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file dht/gnunet_dht_profiler.c
23 * @brief Profiler for GNUnet DHT
24 * @author Sree Harsha Totakura <sreeharsha@totakura.in>
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_testbed_service.h"
30#include "gnunet_dht_service.h"
31
32#define INFO(...) \
33 GNUNET_log (GNUNET_ERROR_TYPE_INFO, __VA_ARGS__)
34
35#define DEBUG(...) \
36 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
37
38/**
39 * Number of peers which should perform a PUT out of 100 peers
40 */
41#define PUT_PROBABILITY 100
42
43/**
44 * Configuration
45 */
46static struct GNUNET_CONFIGURATION_Handle *cfg;
47
48/**
49 * Name of the file with the hosts to run the test over
50 */
51static char *hosts_file;
52
53/**
54 * Context for a peer which actively does DHT PUT/GET
55 */
56struct ActiveContext;
57
58/**
59 * Context to hold data of peer
60 */
61struct Context
62{
63
64 /**
65 * The testbed peer this context belongs to
66 */
67 struct GNUNET_TESTBED_Peer *peer;
68
69 /**
70 * Testbed operation acting on this peer
71 */
72 struct GNUNET_TESTBED_Operation *op;
73
74 /**
75 * Active context; NULL if this peer is not an active peer
76 */
77 struct ActiveContext *ac;
78};
79
80
81/**
82 * Context for a peer which actively does DHT PUT/GET
83 */
84struct ActiveContext
85{
86 /**
87 * The linked peer context
88 */
89 struct Context *ctx;
90
91 /**
92 * Handler to the DHT service
93 */
94 struct GNUNET_DHT_Handle *dht;
95
96 /**
97 * The data used for do a PUT. Will be NULL if a PUT hasn't been performed yet
98 */
99 void *put_data;
100
101 /**
102 * The active context used for our DHT GET
103 */
104 struct ActiveContext *get_ac;
105
106 /**
107 * The put handle
108 */
109 struct GNUNET_DHT_PutHandle *dht_put;
110
111 /**
112 * The get handle
113 */
114 struct GNUNET_DHT_GetHandle *dht_get;
115
116 /**
117 * The hash of the @e put_data
118 */
119 struct GNUNET_HashCode hash;
120
121 /**
122 * Delay task
123 */
124 GNUNET_SCHEDULER_TaskIdentifier delay_task;
125
126 /**
127 * The size of the @e put_data
128 */
129 uint16_t put_data_size;
130
131 /**
132 * The number of peers currently doing GET on our data
133 */
134 uint16_t nrefs;
135};
136
137
138/**
139 * An array of contexts. The size of this array should be equal to @a num_peers
140 */
141static struct Context *a_ctx;
142
143/**
144 * Array of active peers
145 */
146static struct ActiveContext *a_ac;
147
148/**
149 * The delay between starting to do PUTS and GETS
150 */
151static struct GNUNET_TIME_Relative delay;
152
153/**
154 * The timeout for GET and PUT
155 */
156static struct GNUNET_TIME_Relative timeout;
157
158/**
159 * Number of peers
160 */
161static unsigned int num_peers;
162
163/**
164 * Number of active peers
165 */
166static unsigned int n_active;
167
168/**
169 * Number of DHT service connections we currently have
170 */
171static unsigned int n_dht;
172
173/**
174 * Number of DHT PUTs made
175 */
176static unsigned int n_puts;
177
178/**
179 * Number of DHT PUTs succeeded
180 */
181static unsigned int n_puts_ok;
182
183/**
184 * Number of DHT PUTs failed
185 */
186static unsigned int n_puts_fail;
187
188/**
189 * Number of DHT GETs made
190 */
191static unsigned int n_gets;
192
193/**
194 * Number of DHT GETs succeeded
195 */
196static unsigned int n_gets_ok;
197
198/**
199 * Number of DHT GETs succeeded
200 */
201static unsigned int n_gets_fail;
202
203/**
204 * Replication degree
205 */
206static unsigned int replication;
207
208/**
209 * Testbed Operation (to get stats).
210 */
211static struct GNUNET_TESTBED_Operation *stats_op;
212
213/**
214 * Testbed peer handles.
215 */
216static struct GNUNET_TESTBED_Peer **testbed_handles;
217
218/**
219 * Total number of messages sent by peer.
220 */
221static uint64_t outgoing_bandwidth;
222
223/**
224 * Total number of messages received by peer.
225 */
226static uint64_t incoming_bandwidth;
227
228/**
229 * Average number of hops taken to do put.
230 */
231static unsigned int average_put_path_length;
232
233/**
234 * Average number of hops taken to do get.
235 */
236static unsigned int average_get_path_length;
237
238static unsigned int total_put_path_length;
239
240static unsigned int total_get_path_length;
241/**
242 * Shutdown task. Cleanup all resources and operations.
243 *
244 * @param cls NULL
245 * @param tc scheduler task context
246 */
247static void
248do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
249{
250 struct ActiveContext *ac;
251 unsigned int cnt;
252
253 if (NULL != a_ctx)
254 {
255 for (cnt=0; cnt < num_peers; cnt++)
256 {
257 if (NULL != a_ctx[cnt].op)
258 GNUNET_TESTBED_operation_done (a_ctx[cnt].op);
259
260 /* Cleanup active context if this peer is an active peer */
261 ac = a_ctx[cnt].ac;
262 if (NULL == ac)
263 continue;
264 if (GNUNET_SCHEDULER_NO_TASK != ac->delay_task)
265 GNUNET_SCHEDULER_cancel (ac->delay_task);
266 if (NULL != ac->put_data)
267 GNUNET_free (ac->put_data);
268 if (NULL != ac->dht_put)
269 GNUNET_DHT_put_cancel (ac->dht_put);
270 if (NULL != ac->dht_get)
271 GNUNET_DHT_get_stop (ac->dht_get);
272 }
273 GNUNET_free (a_ctx);
274 a_ctx = NULL;
275 }
276 if(NULL != stats_op)
277 GNUNET_TESTBED_operation_done (stats_op);
278 stats_op = NULL;
279 GNUNET_free_non_null (a_ac);
280}
281
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 */
292static void
293bandwidth_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 */
314static int
315bandwidth_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
338static void
339summarize ()
340{
341 INFO ("# PUTS made: %u\n", n_puts);
342 INFO ("# PUTS succeeded: %u\n", n_puts_ok);
343 INFO ("# PUTS failed: %u\n", n_puts_fail);
344 INFO ("# GETS made: %u\n", n_gets);
345 INFO ("# GETS succeeded: %u\n", n_gets_ok);
346 INFO ("# GETS failed: %u\n", n_gets_fail);
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);
360}
361
362
363/**
364 * Task to cancel DHT GET.
365 *
366 * @param cls NULL
367 * @param tc scheduler task context
368 */
369static void
370cancel_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
371{
372 struct ActiveContext *ac = cls;
373
374 ac->delay_task = GNUNET_SCHEDULER_NO_TASK;
375 GNUNET_assert (NULL != ac->dht_get);
376 GNUNET_DHT_get_stop (ac->dht_get);
377 ac->dht_get = NULL;
378 n_gets_fail++;
379
380 /* If profiling is complete, summarize */
381 if (n_active == n_gets_fail + n_gets_ok)
382 summarize ();
383
384}
385
386
387/**
388 * Iterator called on each result obtained for a DHT
389 * operation that expects a reply
390 *
391 * @param cls closure
392 * @param exp when will this value expire
393 * @param key key of the result
394 * @param get_path peers on reply path (or NULL if not recorded)
395 * [0] = datastore's first neighbor, [length - 1] = local peer
396 * @param get_path_length number of entries in @a get_path
397 * @param put_path peers on the PUT path (or NULL if not recorded)
398 * [0] = origin, [length - 1] = datastore
399 * @param put_path_length number of entries in @a put_path
400 * @param type type of the result
401 * @param size number of bytes in @a data
402 * @param data pointer to the result data
403 */
404static void
405get_iter (void *cls,
406 struct GNUNET_TIME_Absolute exp,
407 const struct GNUNET_HashCode *key,
408 const struct GNUNET_PeerIdentity *get_path,
409 unsigned int get_path_length,
410 const struct GNUNET_PeerIdentity *put_path,
411 unsigned int put_path_length,
412 enum GNUNET_BLOCK_Type type,
413 size_t size, const void *data)
414{
415 struct ActiveContext *ac = cls;
416 struct ActiveContext *get_ac = ac->get_ac;
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)));
420 /* we found the data we are looking for */
421 DEBUG ("We found a GET request; %u remaining\n", n_gets - (n_gets_fail + n_gets_ok));
422 n_gets_ok++;
423 get_ac->nrefs--;
424 GNUNET_DHT_get_stop (ac->dht_get);
425 ac->dht_get = NULL;
426 GNUNET_SCHEDULER_cancel (ac->delay_task);
427 ac->delay_task = GNUNET_SCHEDULER_NO_TASK;
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
432 /* Summarize if profiling is complete */
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;
437 summarize ();
438 }
439}
440
441
442/**
443 * Task to do DHT GETs
444 *
445 * @param cls the active context
446 * @param tc the scheduler task context
447 */
448static void
449delayed_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
450{
451 struct ActiveContext *ac = cls;
452 struct ActiveContext *get_ac;
453 unsigned int r;
454
455 ac->delay_task = GNUNET_SCHEDULER_NO_TASK;
456 get_ac = NULL;
457 while (1)
458 {
459 r = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, n_active);
460 get_ac = &a_ac[r];
461 if (NULL != get_ac->put_data)
462 break;
463 }
464 get_ac->nrefs++;
465 ac->get_ac = get_ac;
466 DEBUG ("Doing a DHT GET for data of size %u\n", get_ac->put_data_size);
467 ac->dht_get = GNUNET_DHT_get_start (ac->dht,
468 GNUNET_BLOCK_TYPE_TEST,
469 &get_ac->hash,
470 1, /* replication level */
471 GNUNET_DHT_RO_NONE,
472 NULL, 0, /* extended query and size */
473 get_iter, ac); /* GET iterator and closure
474 */
475 n_gets++;
476
477 /* schedule the timeout task for GET */
478 ac->delay_task = GNUNET_SCHEDULER_add_delayed (timeout, &cancel_get, ac);
479}
480
481
482/**
483 * Queue up a delayed task for doing DHT GET
484 *
485 * @param cls the active context
486 * @param success #GNUNET_OK if the PUT was transmitted,
487 * #GNUNET_NO on timeout,
488 * #GNUNET_SYSERR on disconnect from service
489 * after the PUT message was transmitted
490 * (so we don't know if it was received or not)
491 */
492static void
493put_cont (void *cls, int success)
494{
495 struct ActiveContext *ac = cls;
496
497 ac->dht_put = NULL;
498 if (success)
499 n_puts_ok++;
500 else
501 n_puts_fail++;
502 ac->delay_task = GNUNET_SCHEDULER_add_delayed (delay, &delayed_get, ac);
503}
504
505
506/**
507 * Task to do DHT PUTS
508 *
509 * @param cls the active context
510 * @param tc the scheduler task context
511 */
512static void
513delayed_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
514{
515 struct ActiveContext *ac = cls;
516
517 ac->delay_task = GNUNET_SCHEDULER_NO_TASK;
518 /* Generate and DHT PUT some random data */
519 ac->put_data_size = 16; /* minimum */
520 ac->put_data_size += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
521 (63*1024));
522 ac->put_data = GNUNET_malloc (ac->put_data_size);
523 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
524 ac->put_data, ac->put_data_size);
525 GNUNET_CRYPTO_hash (ac->put_data, ac->put_data_size, &ac->hash);
526 DEBUG ("Doing a DHT PUT with data of size %u\n", ac->put_data_size);
527 ac->dht_put = GNUNET_DHT_put (ac->dht, &ac->hash,
528 replication,
529 GNUNET_DHT_RO_NONE,
530 GNUNET_BLOCK_TYPE_TEST,
531 ac->put_data_size,
532 ac->put_data,
533 GNUNET_TIME_UNIT_FOREVER_ABS, /* expiration time */
534 timeout, /* PUT timeout */
535 put_cont, ac); /* continuation and its closure */
536 n_puts++;
537}
538
539
540/**
541 * Connection to DHT has been established. Call the delay task.
542 *
543 * @param cls the active context
544 * @param op the operation that has been finished
545 * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter()
546 * @param emsg error message in case the operation has failed; will be NULL if
547 * operation has executed successfully.
548 */
549static void
550dht_connected (void *cls,
551 struct GNUNET_TESTBED_Operation *op,
552 void *ca_result,
553 const char *emsg)
554{
555 struct ActiveContext *ac = cls;
556 struct Context *ctx = ac->ctx;
557
558 GNUNET_assert (NULL != ctx);
559 GNUNET_assert (NULL != ctx->op);
560 GNUNET_assert (ctx->op == op);
561 ac->dht = (struct GNUNET_DHT_Handle *) ca_result;
562 if (NULL != emsg)
563 {
564 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection to DHT service failed: %s\n", emsg);
565 GNUNET_TESTBED_operation_done (ctx->op); /* Calls dht_disconnect() */
566 ctx->op = NULL;
567 return;
568 }
569 ac->delay_task = GNUNET_SCHEDULER_add_delayed (delay, &delayed_put, ac);
570}
571
572
573/**
574 * Connect to DHT service and return the DHT client handler
575 *
576 * @param cls the active context
577 * @param cfg configuration of the peer to connect to; will be available until
578 * GNUNET_TESTBED_operation_done() is called on the operation returned
579 * from GNUNET_TESTBED_service_connect()
580 * @return service handle to return in 'op_result', NULL on error
581 */
582static void *
583dht_connect (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
584{
585 n_dht++;
586 return GNUNET_DHT_connect (cfg, 10);
587}
588
589
590/**
591 * Adapter function called to destroy a connection to
592 * a service.
593 *
594 * @param cls the active context
595 * @param op_result service handle returned from the connect adapter
596 */
597static void
598dht_disconnect (void *cls, void *op_result)
599{
600 struct ActiveContext *ac = cls;
601
602 GNUNET_assert (NULL != ac->dht);
603 GNUNET_assert (ac->dht == op_result);
604 GNUNET_DHT_disconnect (ac->dht);
605 ac->dht = NULL;
606 n_dht--;
607 if (0 == n_dht)
608 GNUNET_SCHEDULER_shutdown ();
609}
610
611
612/**
613 * Callback called when DHT service on the peer is started
614 *
615 * @param cls the context
616 * @param op the operation that has been finished
617 * @param emsg error message in case the operation has failed; will be NULL if
618 * operation has executed successfully.
619 */
620static void
621service_started (void *cls,
622 struct GNUNET_TESTBED_Operation *op,
623 const char *emsg)
624{
625 struct Context *ctx = cls;
626
627 GNUNET_assert (NULL != ctx);
628 GNUNET_assert (NULL != ctx->op);
629 GNUNET_TESTBED_operation_done (ctx->op);
630 ctx->op = NULL;
631 if (NULL == ctx->ac)
632 return;
633 /* FIXME: connect to the DHT service and wait before starting a PUT */
634 ctx->op = GNUNET_TESTBED_service_connect (ctx, ctx->peer,
635 "dht",
636 &dht_connected, ctx->ac,
637 &dht_connect,
638 &dht_disconnect,
639 ctx->ac);
640}
641
642
643/**
644 * Signature of a main function for a testcase.
645 *
646 * @param cls closure
647 * @param h the run handle
648 * @param num_peers number of peers in 'peers'
649 * @param peers handle to peers run in the testbed
650 * @param links_succeeded the number of overlay link connection attempts that
651 * succeeded
652 * @param links_failed the number of overlay link
653 */
654static void
655test_run (void *cls,
656 struct GNUNET_TESTBED_RunHandle *h,
657 unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers,
658 unsigned int links_succeeded,
659 unsigned int links_failed)
660{
661 unsigned int cnt;
662 unsigned int ac_cnt;
663
664 testbed_handles = peers;
665 if (NULL == peers)
666 {
667 /* exit */
668 GNUNET_assert (0);
669 }
670 INFO ("%u peers started\n", num_peers);
671 a_ctx = GNUNET_malloc (sizeof (struct Context) * num_peers);
672
673 /* select the peers which actively participate in profiling */
674 n_active = num_peers * PUT_PROBABILITY / 100;
675 if (0 == n_active)
676 {
677 GNUNET_SCHEDULER_shutdown ();
678 GNUNET_free (a_ctx);
679 return;
680 }
681 a_ac = GNUNET_malloc (n_active * sizeof (struct ActiveContext));
682 ac_cnt = 0;
683 for (cnt = 0; cnt < num_peers && ac_cnt < n_active; cnt++)
684 {
685 if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 100) >=
686 PUT_PROBABILITY)
687 continue;
688 a_ctx[cnt].ac = &a_ac[ac_cnt];
689 a_ac[ac_cnt].ctx = &a_ctx[cnt];
690 ac_cnt++;
691 }
692 n_active = ac_cnt;
693 a_ac = GNUNET_realloc (a_ac, n_active * sizeof (struct ActiveContext));
694 INFO ("Active peers: %u\n", n_active);
695
696 /* start DHT service on all peers */
697 for (cnt = 0; cnt < num_peers; cnt++)
698 {
699 a_ctx[cnt].peer = peers[cnt];
700 a_ctx[cnt].op = GNUNET_TESTBED_peer_manage_service (&a_ctx[cnt],
701 peers[cnt],
702 "dht",
703 &service_started,
704 &a_ctx[cnt],
705 1);
706 }
707}
708
709
710/**
711 * Main function that will be run by the scheduler.
712 *
713 * @param cls closure
714 * @param args remaining command-line arguments
715 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
716 * @param config configuration
717 */
718static void
719run (void *cls, char *const *args, const char *cfgfile,
720 const struct GNUNET_CONFIGURATION_Handle *config)
721{
722 uint64_t event_mask;
723
724 if (0 == num_peers)
725 {
726 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Exiting as the number of peers is %u\n"),
727 num_peers);
728 return;
729 }
730 cfg = GNUNET_CONFIGURATION_dup (config);
731 event_mask = 0;
732 GNUNET_TESTBED_run (hosts_file, cfg, num_peers, event_mask, NULL,
733 NULL, &test_run, NULL);
734 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_shutdown,
735 NULL);
736}
737
738
739/**
740 * Main function.
741 *
742 * @return 0 on success
743 */
744int
745main (int argc, char *const *argv)
746{
747 int rc;
748
749 static struct GNUNET_GETOPT_CommandLineOption options[] = {
750 {'n', "peers", "COUNT",
751 gettext_noop ("number of peers to start"),
752 1, &GNUNET_GETOPT_set_uint, &num_peers},
753 {'H', "hosts", "FILENAME",
754 gettext_noop ("name of the file with the login information for the testbed"),
755 1, &GNUNET_GETOPT_set_string, &hosts_file},
756 {'d', "delay", "DELAY",
757 gettext_noop ("delay for starting DHT PUT and GET"),
758 1, &GNUNET_GETOPT_set_relative_time, &delay},
759 {'r', "replication", "DEGREE",
760 gettext_noop ("replication degree for DHT PUTs"),
761 1, &GNUNET_GETOPT_set_uint, &replication},
762 {'t', "timeout", "TIMEOUT",
763 gettext_noop ("timeout for DHT PUT and GET requests"),
764 1, &GNUNET_GETOPT_set_relative_time, &timeout},
765 GNUNET_GETOPT_OPTION_END
766 };
767
768 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
769 return 2;
770 delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30); /* default delay */
771 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1); /* default timeout */
772 replication = 1; /* default replication */
773 rc = 0;
774 if (GNUNET_OK !=
775 GNUNET_PROGRAM_run (argc, argv, "dht-profiler",
776 gettext_noop
777 ("Measure quality and performance of the DHT service."),
778 options, &run, NULL))
779 rc = 1;
780 return rc;
781}