diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2014-06-20 14:49:36 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2014-06-20 14:49:36 +0000 |
commit | a267473f5f05e8b9e195ed6515f65b7cc49392e2 (patch) | |
tree | 081f8ee33343df1af1fb018481b5f47aff17ad91 /src | |
parent | 43e731e418561ac45f923212dd8bba7c8d4a3cb4 (diff) | |
download | gnunet-a267473f5f05e8b9e195ed6515f65b7cc49392e2.tar.gz gnunet-a267473f5f05e8b9e195ed6515f65b7cc49392e2.zip |
Add DHT profiler.
Diffstat (limited to 'src')
-rw-r--r-- | src/dht/Makefile.am | 13 | ||||
-rw-r--r-- | src/dht/gnunet_dht_profiler.c | 489 |
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 = \ | |||
55 | noinst_PROGRAMS = \ | 55 | 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 | 60 | ||
60 | gnunet_service_dht_SOURCES = \ | 61 | gnunet_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 = \ | |||
128 | gnunet_dht_monitor_DEPENDENCIES = \ | 129 | gnunet_dht_monitor_DEPENDENCIES = \ |
129 | libgnunetdht.la | 130 | libgnunetdht.la |
130 | 131 | ||
132 | gnunet_dht_profiler_SOURCES = \ | ||
133 | gnunet_dht_profiler.c | ||
134 | gnunet_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 | ||
139 | gnunet_dht_profiler_DEPENDENCIES = \ | ||
140 | libgnunetdht.la | ||
141 | |||
131 | if HAVE_TESTING | 142 | if HAVE_TESTING |
132 | noinst_LIBRARIES = libgnunetdhttest.a | 143 | noinst_LIBRARIES = libgnunetdhttest.a |
133 | endif | 144 | endif |
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; | |||
44 | static char *hosts_file; | 51 | static char *hosts_file; |
45 | 52 | ||
46 | /** | 53 | /** |
47 | * Number of peers | 54 | * Context for a peer which actively does DHT PUT/GET |
48 | */ | 55 | */ |
49 | static unsigned int num_peers; | 56 | struct ActiveContext; |
50 | 57 | ||
51 | /** | 58 | /** |
52 | * Context to hold data of peer | 59 | * Context to hold data of peer |
53 | */ | 60 | */ |
54 | struct Context | 61 | struct 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 | */ |
71 | struct DataContext | 84 | struct 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 | */ |
97 | struct Context *a_ctx; | 141 | static struct Context *a_ctx; |
142 | |||
143 | /** | ||
144 | * Array of active peers | ||
145 | */ | ||
146 | static struct ActiveContext *a_ac; | ||
147 | |||
148 | /** | ||
149 | * The delay between starting to do PUTS and GETS | ||
150 | */ | ||
151 | static struct GNUNET_TIME_Relative delay; | ||
152 | |||
153 | /** | ||
154 | * The timeout for GET and PUT | ||
155 | */ | ||
156 | static struct GNUNET_TIME_Relative timeout; | ||
157 | |||
158 | /** | ||
159 | * Number of peers | ||
160 | */ | ||
161 | static unsigned int num_peers; | ||
162 | |||
163 | /** | ||
164 | * Number of active peers | ||
165 | */ | ||
166 | static unsigned int n_active; | ||
167 | |||
168 | /** | ||
169 | * Number of DHT service connections we currently have | ||
170 | */ | ||
171 | static unsigned int n_dht; | ||
172 | |||
173 | /** | ||
174 | * Number of DHT PUTs made | ||
175 | */ | ||
176 | static unsigned int n_puts; | ||
177 | |||
178 | /** | ||
179 | * Number of DHT PUTs succeeded | ||
180 | */ | ||
181 | static unsigned int n_puts_ok; | ||
98 | 182 | ||
183 | /** | ||
184 | * Number of DHT PUTs failed | ||
185 | */ | ||
186 | static unsigned int n_puts_fail; | ||
187 | |||
188 | /** | ||
189 | * Number of DHT GETs made | ||
190 | */ | ||
191 | static unsigned int n_gets; | ||
99 | 192 | ||
100 | /** | 193 | /** |
101 | * Shutdown task. Cleanup all resources and operations | 194 | * Number of DHT GETs succeeded |
195 | */ | ||
196 | static unsigned int n_gets_ok; | ||
197 | |||
198 | /** | ||
199 | * Number of DHT GETs succeeded | ||
200 | */ | ||
201 | static 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; | |||
106 | static void | 210 | static void |
107 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 211 | do_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 | |||
243 | static void | ||
244 | summarize () | ||
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 | */ | ||
262 | static void | ||
263 | cancel_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 | */ | ||
296 | static void | ||
297 | get_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 | */ | ||
342 | static void | ||
343 | delayed_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 | */ | ||
385 | static void | ||
386 | put_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 | */ | ||
405 | static void | ||
406 | delayed_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 | */ | ||
442 | static void | ||
443 | dht_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 | */ | ||
475 | static void * | ||
476 | dht_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 | */ | ||
490 | static void | ||
491 | dht_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, | |||
225 | int | 635 | int |
226 | main (int argc, char *const *argv) | 636 | main (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 | } |