diff options
author | Supriti Singh <supritisingh08@gmail.com> | 2014-09-05 12:36:34 +0000 |
---|---|---|
committer | Supriti Singh <supritisingh08@gmail.com> | 2014-09-05 12:36:34 +0000 |
commit | ab98625d6e8f82dc7c897c48081b0f1fef947f8d (patch) | |
tree | 5e9dadb5a3945f416310fe40ff888adab43a21b8 /src/dht | |
parent | ebb5527954a8e214324d76f0c1c181cab3c51170 (diff) | |
download | gnunet-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.am | 13 | ||||
-rw-r--r-- | src/dht/gnunet_dht_profiler.c | 12 | ||||
-rw-r--r-- | src/dht/gnunet_dht_r5n_profiler.c | 781 |
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 | ||
62 | gnunet_service_dht_SOURCES = \ | 61 | gnunet_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 = \ | |||
140 | gnunet_dht_profiler_DEPENDENCIES = \ | 139 | gnunet_dht_profiler_DEPENDENCIES = \ |
141 | libgnunetdht.la | 140 | libgnunetdht.la |
142 | 141 | ||
143 | gnunet_dht_r5n_profiler_SOURCES = \ | ||
144 | gnunet_dht_r5n_profiler.c | ||
145 | gnunet_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 | ||
150 | gnunet_dht_r5n_profiler_DEPENDENCIES = \ | ||
151 | libgnunetdht.la | ||
152 | |||
153 | if HAVE_TESTING | 142 | if HAVE_TESTING |
154 | noinst_LIBRARIES = libgnunetdhttest.a | 143 | noinst_LIBRARIES = libgnunetdhttest.a |
155 | endif | 144 | endif |
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; | |||
63 | struct ActiveContext; | 63 | struct ActiveContext; |
64 | 64 | ||
65 | /** | 65 | /** |
66 | * Context for a peer which should act maliciously. | ||
67 | */ | ||
68 | struct MaliciousContext; | ||
69 | |||
70 | /** | ||
66 | * Context to hold data of peer | 71 | * Context to hold data of peer |
67 | */ | 72 | */ |
68 | struct Context | 73 | struct 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 | */ | ||
46 | static struct GNUNET_CONFIGURATION_Handle *cfg; | ||
47 | |||
48 | /** | ||
49 | * Name of the file with the hosts to run the test over | ||
50 | */ | ||
51 | static char *hosts_file; | ||
52 | |||
53 | /** | ||
54 | * Context for a peer which actively does DHT PUT/GET | ||
55 | */ | ||
56 | struct ActiveContext; | ||
57 | |||
58 | /** | ||
59 | * Context to hold data of peer | ||
60 | */ | ||
61 | struct 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 | */ | ||
84 | struct 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 | */ | ||
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; | ||
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; | ||
192 | |||
193 | /** | ||
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 | * 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; | ||
232 | |||
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 | /** | ||
242 | * Shutdown task. Cleanup all resources and operations. | ||
243 | * | ||
244 | * @param cls NULL | ||
245 | * @param tc scheduler task context | ||
246 | */ | ||
247 | static void | ||
248 | do_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 | */ | ||
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 | |||
338 | static void | ||
339 | summarize () | ||
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 | */ | ||
369 | static void | ||
370 | cancel_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 | */ | ||
404 | static void | ||
405 | get_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 | */ | ||
448 | static void | ||
449 | delayed_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 | */ | ||
492 | static void | ||
493 | put_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 | */ | ||
512 | static void | ||
513 | delayed_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 | */ | ||
549 | static void | ||
550 | dht_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 | */ | ||
582 | static void * | ||
583 | dht_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 | */ | ||
597 | static void | ||
598 | dht_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 | */ | ||
620 | static void | ||
621 | service_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 | */ | ||
654 | static void | ||
655 | test_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 | */ | ||
718 | static void | ||
719 | run (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 | */ | ||
744 | int | ||
745 | main (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 | } | ||