aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2014-06-20 14:49:36 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2014-06-20 14:49:36 +0000
commita267473f5f05e8b9e195ed6515f65b7cc49392e2 (patch)
tree081f8ee33343df1af1fb018481b5f47aff17ad91 /src
parent43e731e418561ac45f923212dd8bba7c8d4a3cb4 (diff)
downloadgnunet-a267473f5f05e8b9e195ed6515f65b7cc49392e2.tar.gz
gnunet-a267473f5f05e8b9e195ed6515f65b7cc49392e2.zip
Add DHT profiler.
Diffstat (limited to 'src')
-rw-r--r--src/dht/Makefile.am13
-rw-r--r--src/dht/gnunet_dht_profiler.c489
2 files changed, 464 insertions, 38 deletions
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am
index fd0cf1184..f8918616f 100644
--- a/src/dht/Makefile.am
+++ b/src/dht/Makefile.am
@@ -55,7 +55,8 @@ libexec_PROGRAMS = \
55noinst_PROGRAMS = \ 55noinst_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 60
60gnunet_service_dht_SOURCES = \ 61gnunet_service_dht_SOURCES = \
61 gnunet-service-dht.c gnunet-service-dht.h \ 62 gnunet-service-dht.c gnunet-service-dht.h \
@@ -128,6 +129,16 @@ gnunet_dht_monitor_LDADD = \
128gnunet_dht_monitor_DEPENDENCIES = \ 129gnunet_dht_monitor_DEPENDENCIES = \
129 libgnunetdht.la 130 libgnunetdht.la
130 131
132gnunet_dht_profiler_SOURCES = \
133 gnunet_dht_profiler.c
134gnunet_dht_profiler_LDADD = \
135 $(top_builddir)/src/dht/libgnunetdht.la \
136 $(top_builddir)/src/core/libgnunetcore.la \
137 $(top_builddir)/src/util/libgnunetutil.la \
138 $(top_builddir)/src/testbed/libgnunettestbed.la
139gnunet_dht_profiler_DEPENDENCIES = \
140 libgnunetdht.la
141
131if HAVE_TESTING 142if HAVE_TESTING
132noinst_LIBRARIES = libgnunetdhttest.a 143noinst_LIBRARIES = libgnunetdhttest.a
133endif 144endif
diff --git a/src/dht/gnunet_dht_profiler.c b/src/dht/gnunet_dht_profiler.c
index f9fb4cfe6..9921c0aed 100644
--- a/src/dht/gnunet_dht_profiler.c
+++ b/src/dht/gnunet_dht_profiler.c
@@ -27,6 +27,13 @@
27#include "platform.h" 27#include "platform.h"
28#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
29#include "gnunet_testbed_service.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__)
30 37
31/** 38/**
32 * 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
@@ -44,61 +51,158 @@ static struct GNUNET_CONFIGURATION_Handle *cfg;
44static char *hosts_file; 51static char *hosts_file;
45 52
46/** 53/**
47 * Number of peers 54 * Context for a peer which actively does DHT PUT/GET
48 */ 55 */
49static unsigned int num_peers; 56struct ActiveContext;
50 57
51/** 58/**
52 * Context to hold data of peer 59 * Context to hold data of peer
53 */ 60 */
54struct Context 61struct Context
55{ 62{
63
64 /**
65 * The testbed peer this context belongs to
66 */
67 struct GNUNET_TESTBED_Peer *peer;
68
56 /** 69 /**
57 * Testbed operation acting on this peer 70 * Testbed operation acting on this peer
58 */ 71 */
59 struct GNUNET_TESTBED_Operation *op; 72 struct GNUNET_TESTBED_Operation *op;
60 73
61 /** 74 /**
62 * Delay task 75 * Active context; NULL if this peer is not an active peer
63 */ 76 */
64 struct GNUNET_SCHEDULER_TaskIdentifier delay_task; 77 struct ActiveContext *ac;
65}; 78};
66 79
67 80
68/** 81/**
69 * Context for the data we put into DHT 82 * Context for a peer which actively does DHT PUT/GET
70 */ 83 */
71struct DataContext 84struct ActiveContext
72{ 85{
73 /** 86 /**
74 * next ptr for the DLL 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
75 */ 98 */
76 struct Data *next; 99 void *put_data;
77 100
78 /** 101 /**
79 * prev ptr for the DLL 102 * The active context used for our DHT GET
80 */ 103 */
81 struct Data *prev; 104 struct ActiveContext *get_ac;
82 105
83 /** 106 /**
84 * The size of the data 107 * The put handle
85 */ 108 */
86 size_t size; 109 struct GNUNET_DHT_PutHandle *dht_put;
87 110
88 /** 111 /**
89 * The data follows here 112 * The get handle
113 */
114 struct GNUNET_DHT_GetHandle *dht_get;
115
116 /**
117 * The hash of the @put_data
118 */
119 struct GNUNET_HashCode hash;
120
121 /**
122 * Delay task
90 */ 123 */
124 GNUNET_SCHEDULER_TaskIdentifier delay_task;
125
126 /**
127 * The size of the 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;
91}; 135};
92 136
93 137
94/** 138/**
95 * An array of contexts. The size of this array should be equal to @a num_peers 139 * An array of contexts. The size of this array should be equal to @a num_peers
96 */ 140 */
97struct Context *a_ctx; 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;
98 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;
99 192
100/** 193/**
101 * Shutdown task. Cleanup all resources and operations 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/**
205 * Shutdown task. Cleanup all resources and operations.
102 * 206 *
103 * @param cls NULL 207 * @param cls NULL
104 * @param tc scheduler task context 208 * @param tc scheduler task context
@@ -106,20 +210,294 @@ struct Context *a_ctx;
106static void 210static void
107do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 211do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
108{ 212{
213 struct ActiveContext *ac;
109 unsigned int cnt; 214 unsigned int cnt;
110 215
111 if (NULL != a_ctx) 216 if (NULL != a_ctx)
112 { 217 {
113 for (cnt=0; cnt < num_peers, cnt++) 218 for (cnt=0; cnt < num_peers; cnt++)
114 { 219 {
115 if (NULL == a_ctx[cnt].op) 220 if (NULL != a_ctx[cnt].op)
221 GNUNET_TESTBED_operation_done (a_ctx[cnt].op);
222
223 /* Cleanup active context if this peer is an active peer */
224 ac = a_ctx[cnt].ac;
225 if (NULL == ac)
116 continue; 226 continue;
117 GNUNET_TESTBED_operation_done (a_ctx[cnt].op); 227 if (GNUNET_SCHEDULER_NO_TASK != ac->delay_task)
118 a_ctx[cnt].op = NULL; 228 GNUNET_SCHEDULER_cancel (ac->delay_task);
229 if (NULL != ac->put_data)
230 GNUNET_free (ac->put_data);
231 if (NULL != ac->dht_put)
232 GNUNET_DHT_put_cancel (ac->dht_put);
233 if (NULL != ac->dht_get)
234 GNUNET_DHT_get_stop (ac->dht_get);
119 } 235 }
120 GNUNET_free (a_ctx); 236 GNUNET_free (a_ctx);
121 a_ctx = NULL; 237 a_ctx = NULL;
122 } 238 }
239 GNUNET_free_non_null (a_ac);
240}
241
242
243static void
244summarize ()
245{
246 INFO ("# PUTS made: %u\n", n_puts);
247 INFO ("# PUTS succeeded: %u\n", n_puts_ok);
248 INFO ("# PUTS failed: %u\n", n_puts_fail);
249 INFO ("# GETS made: %u\n", n_gets);
250 INFO ("# GETS succeeded: %u\n", n_gets_ok);
251 INFO ("# GETS failed: %u\n", n_gets_fail);
252 GNUNET_SCHEDULER_shutdown ();
253}
254
255
256/**
257 * Task to cancel DHT GET.
258 *
259 * @param cls NULL
260 * @param tc scheduler task context
261 */
262static void
263cancel_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
264{
265 struct ActiveContext *ac = cls;
266
267 ac->delay_task = GNUNET_SCHEDULER_NO_TASK;
268 GNUNET_assert (NULL != ac->dht_get);
269 GNUNET_DHT_get_stop (ac->dht_get);
270 ac->dht_get = NULL;
271 n_gets_fail++;
272
273 /* If profiling is complete, summarize */
274 if (n_gets == n_gets_fail + n_gets_ok)
275 summarize ();
276}
277
278
279/**
280 * Iterator called on each result obtained for a DHT
281 * operation that expects a reply
282 *
283 * @param cls closure
284 * @param exp when will this value expire
285 * @param key key of the result
286 * @param get_path peers on reply path (or NULL if not recorded)
287 * [0] = datastore's first neighbor, [length - 1] = local peer
288 * @param get_path_length number of entries in @a get_path
289 * @param put_path peers on the PUT path (or NULL if not recorded)
290 * [0] = origin, [length - 1] = datastore
291 * @param put_path_length number of entries in @a put_path
292 * @param type type of the result
293 * @param size number of bytes in @a data
294 * @param data pointer to the result data
295 */
296static void
297get_iter (void *cls,
298 struct GNUNET_TIME_Absolute exp,
299 const struct GNUNET_HashCode *key,
300 const struct GNUNET_PeerIdentity *get_path,
301 unsigned int get_path_length,
302 const struct GNUNET_PeerIdentity *put_path,
303 unsigned int put_path_length,
304 enum GNUNET_BLOCK_Type type,
305 size_t size, const void *data)
306{
307 struct ActiveContext *ac = cls;
308 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
321 /* 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));
323 n_gets_ok++;
324 get_ac->nrefs--;
325 GNUNET_DHT_get_stop (ac->dht_get);
326 ac->dht_get = NULL;
327 GNUNET_SCHEDULER_cancel (ac->delay_task);
328 ac->delay_task = GNUNET_SCHEDULER_NO_TASK;
329
330 /* Summarize if profiling is complete */
331 if (n_gets == n_gets_fail + n_gets_ok)
332 summarize ();
333}
334
335
336/**
337 * Task to do DHT GETs
338 *
339 * @param cls the active context
340 * @param tc the scheduler task context
341 */
342static void
343delayed_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
344{
345 struct ActiveContext *ac = cls;
346 struct ActiveContext *get_ac;
347 unsigned int r;
348
349 ac->delay_task = GNUNET_SCHEDULER_NO_TASK;
350 get_ac = NULL;
351 while (1)
352 {
353 r = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, n_active);
354 get_ac = &a_ac[r];
355 if (NULL != get_ac->put_data)
356 break;
357 }
358 get_ac->nrefs++;
359 ac->get_ac = get_ac;
360 ac->dht_get = GNUNET_DHT_get_start (ac->dht,
361 GNUNET_BLOCK_TYPE_TEST,
362 &ac->hash,
363 1, /* replication level */
364 GNUNET_DHT_RO_NONE,
365 NULL, 0, /* extended query and size */
366 get_iter, ac); /* GET iterator and closure
367 */
368 n_gets++;
369
370 /* schedule the timeout task for GET */
371 ac->delay_task = GNUNET_SCHEDULER_add_delayed (timeout, &cancel_get, ac);
372}
373
374
375/**
376 * Queue up a delayed task for doing DHT GET
377 *
378 * @param cls the active context
379 * @param success #GNUNET_OK if the PUT was transmitted,
380 * #GNUNET_NO on timeout,
381 * #GNUNET_SYSERR on disconnect from service
382 * after the PUT message was transmitted
383 * (so we don't know if it was received or not)
384 */
385static void
386put_cont (void *cls, int success)
387{
388 struct ActiveContext *ac = cls;
389
390 ac->dht_put = NULL;
391 if (success)
392 n_puts_ok++;
393 else
394 n_puts_fail++;
395 ac->delay_task = GNUNET_SCHEDULER_add_delayed (delay, &delayed_get, ac);
396}
397
398
399/**
400 * Task to do DHT PUTS
401 *
402 * @param cls the active context
403 * @param tc the scheduler task context
404 */
405static void
406delayed_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
407{
408 struct ActiveContext *ac = cls;
409
410 ac->delay_task = GNUNET_SCHEDULER_NO_TASK;
411 /* Generate and DHT PUT some random data */
412 ac->put_data_size = 16; /* minimum */
413 ac->put_data_size += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
414 (63*1024));
415 ac->put_data = GNUNET_malloc (ac->put_data_size);
416 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
417 ac->put_data, ac->put_data_size);
418 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);
420 ac->dht_put = GNUNET_DHT_put (ac->dht, &ac->hash,
421 1, /* replication level */
422 GNUNET_DHT_RO_NONE,
423 GNUNET_BLOCK_TYPE_TEST,
424 ac->put_data_size,
425 ac->put_data,
426 GNUNET_TIME_UNIT_FOREVER_ABS, /* expiration time */
427 timeout, /* PUT timeout */
428 put_cont, ac); /* continuation and its closure */
429 n_puts++;
430}
431
432
433/**
434 * Connection to DHT has been established. Call the delay task.
435 *
436 * @param cls the active context
437 * @param op the operation that has been finished
438 * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter()
439 * @param emsg error message in case the operation has failed; will be NULL if
440 * operation has executed successfully.
441 */
442static void
443dht_connected (void *cls,
444 struct GNUNET_TESTBED_Operation *op,
445 void *ca_result,
446 const char *emsg)
447{
448 struct ActiveContext *ac = cls;
449 struct Context *ctx = ac->ctx;
450
451 GNUNET_assert (NULL != ctx);
452 GNUNET_assert (NULL != ctx->op);
453 GNUNET_assert (ctx->op == op);
454 ac->dht = (struct GNUNET_DHT_Handle *) ca_result;
455 if (NULL != emsg)
456 {
457 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection to DHT service failed: %s\n", emsg);
458 GNUNET_TESTBED_operation_done (ctx->op); /* Calls dht_disconnect() */
459 ctx->op = NULL;
460 return;
461 }
462 ac->delay_task = GNUNET_SCHEDULER_add_delayed (delay, &delayed_put, ac);
463}
464
465
466/**
467 * Connect to DHT service and return the DHT client handler
468 *
469 * @param cls the active context
470 * @param cfg configuration of the peer to connect to; will be available until
471 * GNUNET_TESTBED_operation_done() is called on the operation returned
472 * from GNUNET_TESTBED_service_connect()
473 * @return service handle to return in 'op_result', NULL on error
474 */
475static void *
476dht_connect (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
477{
478 n_dht++;
479 return GNUNET_DHT_connect (cfg, 10);
480}
481
482
483/**
484 * Adapter function called to destroy a connection to
485 * a service.
486 *
487 * @param cls the active context
488 * @param op_result service handle returned from the connect adapter
489 */
490static void
491dht_disconnect (void *cls, void *op_result)
492{
493 struct ActiveContext *ac = cls;
494
495 GNUNET_assert (NULL != ac->dht);
496 GNUNET_assert (ac->dht == op_result);
497 GNUNET_DHT_disconnect (ac->dht);
498 n_dht--;
499 if (0 == n_dht)
500 GNUNET_SCHEDULER_shutdown ();
123} 501}
124 502
125 503
@@ -142,10 +520,15 @@ service_started (void *cls,
142 GNUNET_assert (NULL != ctx->op); 520 GNUNET_assert (NULL != ctx->op);
143 GNUNET_TESTBED_operation_done (ctx->op); 521 GNUNET_TESTBED_operation_done (ctx->op);
144 ctx->op = NULL; 522 ctx->op = NULL;
145 if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 100) 523 if (NULL == ctx->ac)
146 >= PUT_PROBABILITY)
147 return; 524 return;
148 /* FIXME: connect to the DHT service and wait initwait before starting a PUT */ 525 /* FIXME: connect to the DHT service and wait before starting a PUT */
526 ctx->op = GNUNET_TESTBED_service_connect (ctx, ctx->peer,
527 "dht",
528 &dht_connected, ctx->ac,
529 &dht_connect,
530 &dht_disconnect,
531 ctx->ac);
149} 532}
150 533
151 534
@@ -167,16 +550,44 @@ test_run (void *cls,
167 unsigned int links_succeeded, 550 unsigned int links_succeeded,
168 unsigned int links_failed) 551 unsigned int links_failed)
169{ 552{
170 int cnt; 553 unsigned int cnt;
554 unsigned int ac_cnt;
171 555
172 if (NULL == peers) 556 if (NULL == peers)
173 { 557 {
174 /* exit */ 558 /* exit */
175 GNUNET_assert (0); 559 GNUNET_assert (0);
176 } 560 }
561 INFO ("%u peers started\n", num_peers);
177 a_ctx = GNUNET_malloc (sizeof (struct Context) * num_peers); 562 a_ctx = GNUNET_malloc (sizeof (struct Context) * num_peers);
178 for (cnt = 0; cnt < num_peers, cnt++) 563
564 /* select the peers which actively participate in profiling */
565 n_active = num_peers * PUT_PROBABILITY / 100;
566 if (0 == n_active)
567 {
568 GNUNET_SCHEDULER_shutdown ();
569 GNUNET_free (a_ctx);
570 return;
571 }
572 a_ac = GNUNET_malloc (n_active * sizeof (struct ActiveContext));
573 ac_cnt = 0;
574 for (cnt = 0; cnt < num_peers && ac_cnt < n_active; cnt++)
179 { 575 {
576 if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 100) >=
577 PUT_PROBABILITY)
578 continue;
579 a_ctx[cnt].ac = &a_ac[ac_cnt];
580 a_ac[ac_cnt].ctx = &a_ctx[cnt];
581 ac_cnt++;
582 }
583 n_active = ac_cnt;
584 a_ac = GNUNET_realloc (a_ac, n_active * sizeof (struct ActiveContext));
585 INFO ("Active peers: %u\n", n_active);
586
587 /* start DHT service on all peers */
588 for (cnt = 0; cnt < num_peers; cnt++)
589 {
590 a_ctx[cnt].peer = peers[cnt];
180 a_ctx[cnt].op = GNUNET_TESTBED_peer_manage_service (&a_ctx[cnt], 591 a_ctx[cnt].op = GNUNET_TESTBED_peer_manage_service (&a_ctx[cnt],
181 peers[cnt], 592 peers[cnt],
182 "dht", 593 "dht",
@@ -203,17 +614,16 @@ run (void *cls, char *const *args, const char *cfgfile,
203 614
204 if (0 == num_peers) 615 if (0 == num_peers)
205 { 616 {
206 LOG (GNUNET_ERROR_TYPE_ERROR, _("Exiting as the number of peers is %u\n"), 617 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Exiting as the number of peers is %u\n"),
207 num_peers); 618 num_peers);
208 return; 619 return;
209 } 620 }
210 cfg = GNUNET_CONFIGURATION_dup (config); 621 cfg = GNUNET_CONFIGURATION_dup (config);
211 event_mask = 0; 622 event_mask = 0;
212 GNUNET_TESTBED_run (hosts_file, cfg, num_peers, event_mask, NULL, 623 GNUNET_TESTBED_run (hosts_file, cfg, num_peers, event_mask, NULL,
213 NULL, &test_run, NULL); 624 NULL, &test_run, NULL);
214 abort_task = 625 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_shutdown,
215 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_abort, 626 NULL);
216 NULL);
217} 627}
218 628
219 629
@@ -225,6 +635,8 @@ run (void *cls, char *const *args, const char *cfgfile,
225int 635int
226main (int argc, char *const *argv) 636main (int argc, char *const *argv)
227{ 637{
638 int rc;
639
228 static struct GNUNET_GETOPT_CommandLineOption options[] = { 640 static struct GNUNET_GETOPT_CommandLineOption options[] = {
229 {'n', "peers", "COUNT", 641 {'n', "peers", "COUNT",
230 gettext_noop ("number of peers to start"), 642 gettext_noop ("number of peers to start"),
@@ -232,22 +644,25 @@ main (int argc, char *const *argv)
232 {'H', "hosts", "FILENAME", 644 {'H', "hosts", "FILENAME",
233 gettext_noop ("name of the file with the login information for the testbed"), 645 gettext_noop ("name of the file with the login information for the testbed"),
234 1, &GNUNET_GETOPT_set_string, &hosts_file}, 646 1, &GNUNET_GETOPT_set_string, &hosts_file},
235 {'d', "initwait", "DELAY", 647 {'d', "delay", "DELAY",
236 gettext_noop ("delay to allow DHT to stabilize after starting the peers"), 648 gettext_noop ("delay for starting DHT PUT and GET"),
237 1, &GNUNET_GETOPT_set_relative_time, &init_wait}, 649 1, &GNUNET_GETOPT_set_relative_time, &delay},
238 {'w', "wait", "DELAY", 650 {'t', "timeout", "TIMEOUT",
239 gettext_noop ("delay between rounds"), 651 gettext_noop ("timeout for DHT PUT and GET requests"),
240 1, &GNUNET_GETOPT_set_relative_time, &wait_time}, 652 1, &GNUNET_GETOPT_set_relative_time, &timeout},
241 GNUNET_GETOPT_OPTION_END 653 GNUNET_GETOPT_OPTION_END
242 }; 654 };
243 655
244 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 656 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
245 return 2; 657 return 2;
658 delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3); /* default delay */
659 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3); /* default timeout */
660 rc = 0;
246 if (GNUNET_OK != 661 if (GNUNET_OK !=
247 GNUNET_PROGRAM_run (argc, argv, "dht-profiler", 662 GNUNET_PROGRAM_run (argc, argv, "dht-profiler",
248 gettext_noop 663 gettext_noop
249 ("Measure quality and performance of the DHT service."), 664 ("Measure quality and performance of the DHT service."),
250 options, &run, NULL)) 665 options, &run, NULL))
251 ok = 1; 666 rc = 1;
252 return ok; 667 return rc;
253} 668}