diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-09-06 11:41:42 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-09-06 11:41:42 +0000 |
commit | e268f4d047f92e5e4e1a78aabbd323c5953debcd (patch) | |
tree | 7df22c008f4c85e8814c91bf3421afd562312829 /src/ats/perf_ats.c | |
parent | 07da5a62c47fdbf91ffa99364ee117e2cf8ced5e (diff) | |
download | gnunet-e268f4d047f92e5e4e1a78aabbd323c5953debcd.tar.gz gnunet-e268f4d047f92e5e4e1a78aabbd323c5953debcd.zip |
removing tests moved to ../ats-tests
Diffstat (limited to 'src/ats/perf_ats.c')
-rw-r--r-- | src/ats/perf_ats.c | 1316 |
1 files changed, 0 insertions, 1316 deletions
diff --git a/src/ats/perf_ats.c b/src/ats/perf_ats.c deleted file mode 100644 index 2cb6a0116..000000000 --- a/src/ats/perf_ats.c +++ /dev/null | |||
@@ -1,1316 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2010-2013 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 | * @file ats/perf_ats.c | ||
22 | * @brief ats benchmark: start peers and modify preferences, monitor change over time | ||
23 | * @author Christian Grothoff | ||
24 | * @author Matthias Wachs | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testbed_service.h" | ||
29 | #include "gnunet_ats_service.h" | ||
30 | #include "gnunet_core_service.h" | ||
31 | |||
32 | #define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) | ||
33 | #define BENCHMARK_DURATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
34 | #define TESTNAME_PREFIX "perf_ats_" | ||
35 | #define DEFAULT_SLAVES_NUM 3 | ||
36 | #define DEFAULT_MASTERS_NUM 1 | ||
37 | |||
38 | #define TEST_MESSAGE_TYPE_PING 12345 | ||
39 | #define TEST_MESSAGE_TYPE_PONG 12346 | ||
40 | #define TEST_MESSAGE_SIZE 1000 | ||
41 | #define TEST_MESSAGE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) | ||
42 | |||
43 | |||
44 | /** | ||
45 | * Information we track for a peer in the testbed. | ||
46 | */ | ||
47 | struct BenchmarkPeer | ||
48 | { | ||
49 | /** | ||
50 | * Handle with testbed. | ||
51 | */ | ||
52 | struct GNUNET_TESTBED_Peer *peer; | ||
53 | |||
54 | /** | ||
55 | * Unique identifier | ||
56 | */ | ||
57 | int no; | ||
58 | |||
59 | /** | ||
60 | * master: GNUNET_YES/NO | ||
61 | */ | ||
62 | int master; | ||
63 | |||
64 | /** | ||
65 | * Peer ID | ||
66 | */ | ||
67 | struct GNUNET_PeerIdentity id; | ||
68 | |||
69 | /** | ||
70 | * Core handle | ||
71 | */ | ||
72 | struct GNUNET_CORE_Handle *ch; | ||
73 | |||
74 | /** | ||
75 | * Testbed operation to connect to ATS performance service | ||
76 | */ | ||
77 | struct GNUNET_TESTBED_Operation *ats_perf_op; | ||
78 | |||
79 | /** | ||
80 | * Testbed operation to get peer information | ||
81 | */ | ||
82 | struct GNUNET_TESTBED_Operation *info_op; | ||
83 | |||
84 | /** | ||
85 | * Testbed operation to connect to core | ||
86 | */ | ||
87 | struct GNUNET_TESTBED_Operation *core_op; | ||
88 | |||
89 | /** | ||
90 | * ATS performance handle | ||
91 | */ | ||
92 | struct GNUNET_ATS_PerformanceHandle *p_handle; | ||
93 | |||
94 | /** | ||
95 | * Testbed connecect operation | ||
96 | */ | ||
97 | struct ConnectOperation *connect_ops; | ||
98 | |||
99 | /** | ||
100 | * ATS Measurement Partner | ||
101 | */ | ||
102 | struct BenchmarkPeer *destination; | ||
103 | |||
104 | GNUNET_SCHEDULER_TaskIdentifier ats_task; | ||
105 | |||
106 | /* Message exchange */ | ||
107 | |||
108 | /** | ||
109 | * Core transmit handle | ||
110 | */ | ||
111 | struct GNUNET_CORE_TransmitHandle *cth; | ||
112 | |||
113 | /** | ||
114 | * DLL for pending messages: head | ||
115 | */ | ||
116 | struct PendingMessages *p_head; | ||
117 | |||
118 | /** | ||
119 | * DLL for pending messages: tail | ||
120 | */ | ||
121 | struct PendingMessages *p_tail; | ||
122 | |||
123 | /** | ||
124 | * Bit-mask for next partner selection | ||
125 | */ | ||
126 | uint32_t send_mask; | ||
127 | |||
128 | /** | ||
129 | * Current message for partner? | ||
130 | */ | ||
131 | int partner_msg; | ||
132 | |||
133 | /** | ||
134 | * Number of core connections | ||
135 | */ | ||
136 | int core_connections; | ||
137 | |||
138 | /** | ||
139 | * Number of slave connections | ||
140 | */ | ||
141 | int slave_connections; | ||
142 | |||
143 | /** | ||
144 | * Statistics | ||
145 | */ | ||
146 | unsigned int messages_sent; | ||
147 | unsigned int messages_sent_partner; | ||
148 | unsigned int messages_received; | ||
149 | }; | ||
150 | |||
151 | |||
152 | static int c_master_peers; | ||
153 | |||
154 | /** | ||
155 | * Array of master peers | ||
156 | * Preferences to be set for | ||
157 | */ | ||
158 | static struct BenchmarkPeer *bp_master; | ||
159 | |||
160 | static int c_slave_peers; | ||
161 | |||
162 | /** | ||
163 | * Array of slave peers | ||
164 | * Peer used for measurements | ||
165 | */ | ||
166 | static struct BenchmarkPeer *bp_slaves; | ||
167 | |||
168 | |||
169 | struct BenchmarkState | ||
170 | { | ||
171 | /* Are we connected to ATS service of all peers: GNUNET_YES/NO */ | ||
172 | int connected_ATS_service; | ||
173 | |||
174 | /* Are we connected to CORE service of all peers: GNUNET_YES/NO */ | ||
175 | int connected_CORE_service; | ||
176 | |||
177 | /* Are we connected to all peers: GNUNET_YES/NO */ | ||
178 | int connected_PEERS; | ||
179 | |||
180 | /* Are we connected to all slave peers on CORE level: GNUNET_YES/NO */ | ||
181 | int connected_CORE; | ||
182 | |||
183 | /* Are we connected to CORE service of all peers: GNUNET_YES/NO */ | ||
184 | int benchmarking; | ||
185 | |||
186 | int *core_connections; | ||
187 | |||
188 | uint32_t partner_map; | ||
189 | }; | ||
190 | |||
191 | static struct BenchmarkState state; | ||
192 | |||
193 | /** | ||
194 | * Shutdown task | ||
195 | */ | ||
196 | static GNUNET_SCHEDULER_TaskIdentifier shutdown_task; | ||
197 | |||
198 | static int result; | ||
199 | static char *solver; | ||
200 | static char *preference; | ||
201 | |||
202 | /** | ||
203 | * Pending Responses | ||
204 | */ | ||
205 | struct PendingMessages | ||
206 | { | ||
207 | struct PendingMessages *prev; | ||
208 | struct PendingMessages *next; | ||
209 | struct GNUNET_PeerIdentity target; | ||
210 | }; | ||
211 | |||
212 | |||
213 | /** | ||
214 | * Information we track for a peer in the testbed. | ||
215 | */ | ||
216 | struct ConnectOperation | ||
217 | { | ||
218 | struct BenchmarkPeer *master; | ||
219 | |||
220 | struct BenchmarkPeer *slave; | ||
221 | /** | ||
222 | * Testbed operation to connect peers | ||
223 | */ | ||
224 | struct GNUNET_TESTBED_Operation *connect_op; | ||
225 | |||
226 | }; | ||
227 | |||
228 | |||
229 | static void | ||
230 | core_connect_completion_cb (void *cls, | ||
231 | struct GNUNET_TESTBED_Operation *op, | ||
232 | void *ca_result, | ||
233 | const char *emsg ); | ||
234 | |||
235 | |||
236 | static void evaluate () | ||
237 | { | ||
238 | int c_p; | ||
239 | struct BenchmarkPeer *bp; | ||
240 | int total_out; | ||
241 | int partner_out; | ||
242 | |||
243 | for (c_p = 0; c_p < c_master_peers; c_p++) | ||
244 | { | ||
245 | bp = &bp_master[c_p]; | ||
246 | total_out = (bp->messages_sent * TEST_MESSAGE_SIZE) / 10240; | ||
247 | partner_out = (bp->messages_sent_partner * TEST_MESSAGE_SIZE) / 10240; | ||
248 | fprintf (stderr, _("Peer %u: Out total: %u KiB/s, out partner %u KiB/s\n"), | ||
249 | bp->no, | ||
250 | total_out, partner_out | ||
251 | /*partner_out / (total_out / 100)*/); | ||
252 | } | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | * Shutdown nicely | ||
257 | * | ||
258 | * @param cls NULL | ||
259 | * @param tc the task context | ||
260 | */ | ||
261 | static void | ||
262 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
263 | { | ||
264 | int c_p; | ||
265 | int c_op; | ||
266 | struct PendingMessages *cur; | ||
267 | struct PendingMessages *next; | ||
268 | |||
269 | shutdown_task = GNUNET_SCHEDULER_NO_TASK; | ||
270 | |||
271 | state.benchmarking = GNUNET_NO; | ||
272 | |||
273 | evaluate (); | ||
274 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Benchmarking done\n")); | ||
275 | |||
276 | for (c_p = 0; c_p < c_master_peers; c_p++) | ||
277 | { | ||
278 | next = bp_master[c_p].p_head; | ||
279 | for (cur = next; cur != NULL; cur = next ) | ||
280 | { | ||
281 | next = cur->next; | ||
282 | GNUNET_CONTAINER_DLL_remove (bp_master[c_p].p_head, bp_master[c_p].p_tail, cur); | ||
283 | GNUNET_free (cur); | ||
284 | } | ||
285 | |||
286 | if (GNUNET_SCHEDULER_NO_TASK != bp_master[c_p].ats_task) | ||
287 | { | ||
288 | GNUNET_SCHEDULER_cancel (bp_master[c_p].ats_task); | ||
289 | bp_master[c_p].ats_task = GNUNET_SCHEDULER_NO_TASK; | ||
290 | } | ||
291 | |||
292 | if (NULL != bp_master[c_p].cth) | ||
293 | { | ||
294 | GNUNET_CORE_notify_transmit_ready_cancel(bp_master[c_p].cth); | ||
295 | bp_master[c_p].cth = NULL; | ||
296 | } | ||
297 | |||
298 | if (NULL != bp_master[c_p].ats_perf_op) | ||
299 | { | ||
300 | GNUNET_TESTBED_operation_done (bp_master[c_p].ats_perf_op); | ||
301 | bp_master[c_p].ats_perf_op = NULL; | ||
302 | } | ||
303 | |||
304 | if (NULL != bp_master[c_p].core_op) | ||
305 | { | ||
306 | GNUNET_TESTBED_operation_done (bp_master[c_p].core_op); | ||
307 | bp_master[c_p].core_op = NULL; | ||
308 | } | ||
309 | |||
310 | if (NULL != bp_master[c_p].info_op) | ||
311 | { | ||
312 | GNUNET_break (0); | ||
313 | GNUNET_TESTBED_operation_done (bp_master[c_p].info_op); | ||
314 | bp_master[c_p].info_op = NULL; | ||
315 | } | ||
316 | |||
317 | for (c_op = 0; c_op < c_slave_peers; c_op++) | ||
318 | { | ||
319 | if (NULL != bp_master[c_p].connect_ops[c_op].connect_op) | ||
320 | { | ||
321 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Failed to connect peer 0 and %u\n"), c_p); | ||
322 | GNUNET_TESTBED_operation_done (bp_master[c_p].connect_ops[c_op].connect_op); | ||
323 | bp_master[c_p].connect_ops[c_op].connect_op = NULL; | ||
324 | result = 1; | ||
325 | } | ||
326 | } | ||
327 | GNUNET_free (bp_master[c_p].connect_ops); | ||
328 | } | ||
329 | |||
330 | for (c_p = 0; c_p < c_slave_peers; c_p++) | ||
331 | { | ||
332 | next = bp_slaves[c_p].p_head; | ||
333 | for (cur = next; cur != NULL; cur = next ) | ||
334 | { | ||
335 | next = cur->next; | ||
336 | GNUNET_CONTAINER_DLL_remove (bp_slaves[c_p].p_head, bp_slaves[c_p].p_tail, cur); | ||
337 | GNUNET_free (cur); | ||
338 | } | ||
339 | |||
340 | if (NULL != bp_slaves[c_p].cth) | ||
341 | { | ||
342 | GNUNET_CORE_notify_transmit_ready_cancel(bp_slaves[c_p].cth); | ||
343 | bp_slaves[c_p].cth = NULL; | ||
344 | } | ||
345 | |||
346 | if (NULL != bp_slaves[c_p].ats_perf_op) | ||
347 | { | ||
348 | GNUNET_TESTBED_operation_done (bp_slaves[c_p].ats_perf_op); | ||
349 | bp_slaves[c_p].ats_perf_op = NULL; | ||
350 | } | ||
351 | |||
352 | if (NULL != bp_slaves[c_p].core_op) | ||
353 | { | ||
354 | GNUNET_TESTBED_operation_done (bp_slaves[c_p].core_op); | ||
355 | bp_slaves[c_p].core_op = NULL; | ||
356 | } | ||
357 | |||
358 | if (NULL != bp_slaves[c_p].info_op) | ||
359 | { | ||
360 | GNUNET_break (0); | ||
361 | GNUNET_TESTBED_operation_done (bp_slaves[c_p].info_op); | ||
362 | bp_slaves[c_p].info_op = NULL; | ||
363 | } | ||
364 | |||
365 | } | ||
366 | |||
367 | GNUNET_SCHEDULER_shutdown(); | ||
368 | } | ||
369 | |||
370 | static struct BenchmarkPeer * | ||
371 | find_peer (const struct GNUNET_PeerIdentity * peer) | ||
372 | { | ||
373 | int c_p; | ||
374 | |||
375 | for (c_p = 0; c_p < c_master_peers; c_p++) | ||
376 | { | ||
377 | if (0 == memcmp (&bp_master[c_p].id, peer, sizeof (struct GNUNET_PeerIdentity))) | ||
378 | return &bp_master[c_p]; | ||
379 | } | ||
380 | |||
381 | for (c_p = 0; c_p < c_slave_peers; c_p++) | ||
382 | { | ||
383 | if (0 == memcmp (&bp_slaves[c_p].id, peer, sizeof (struct GNUNET_PeerIdentity))) | ||
384 | return &bp_slaves[c_p]; | ||
385 | } | ||
386 | |||
387 | return NULL; | ||
388 | } | ||
389 | |||
390 | |||
391 | static void | ||
392 | store_information (struct GNUNET_PeerIdentity *id, | ||
393 | const struct GNUNET_HELLO_Address *address, | ||
394 | int address_active, | ||
395 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, | ||
396 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, | ||
397 | const struct GNUNET_ATS_Information *ats, | ||
398 | uint32_t ats_count) | ||
399 | { | ||
400 | struct BenchmarkPeer *bp; | ||
401 | |||
402 | bp = find_peer (id); | ||
403 | |||
404 | if (NULL == bp) | ||
405 | { | ||
406 | GNUNET_break (0); | ||
407 | return; | ||
408 | } | ||
409 | } | ||
410 | |||
411 | static void | ||
412 | ats_performance_info_cb (void *cls, | ||
413 | const struct GNUNET_HELLO_Address *address, | ||
414 | int address_active, | ||
415 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, | ||
416 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, | ||
417 | const struct GNUNET_ATS_Information *ats, | ||
418 | uint32_t ats_count) | ||
419 | { | ||
420 | struct BenchmarkPeer *bp = cls; | ||
421 | int c_a; | ||
422 | char *peer_id; | ||
423 | |||
424 | peer_id = GNUNET_strdup (GNUNET_i2s (&bp->id)); | ||
425 | for (c_a = 0; c_a < ats_count; c_a++) | ||
426 | { | ||
427 | /*GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("%c %03u: %s %s %u\n"), | ||
428 | (GNUNET_YES == p->master) ? 'M' : 'S', | ||
429 | p->no, | ||
430 | GNUNET_i2s (&address->peer), | ||
431 | GNUNET_ATS_print_property_type(ntohl(ats[c_a].type)), | ||
432 | ntohl(ats[c_a].value));*/ | ||
433 | } | ||
434 | |||
435 | if ((GNUNET_YES == bp->master) && | ||
436 | (0 == memcmp (&address->peer, &bp->destination->id, | ||
437 | sizeof (struct GNUNET_PeerIdentity)))) | ||
438 | { | ||
439 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Bandwidth for master %u: %lu %lu\n", | ||
440 | bp->no, | ||
441 | (long unsigned int) ntohl(bandwidth_in.value__), | ||
442 | (long unsigned int) ntohl(bandwidth_in.value__)); | ||
443 | } | ||
444 | |||
445 | store_information (&bp->id, address, address_active, | ||
446 | bandwidth_in, bandwidth_out, | ||
447 | ats, ats_count); | ||
448 | |||
449 | GNUNET_free (peer_id); | ||
450 | } | ||
451 | |||
452 | static size_t | ||
453 | core_send_ready (void *cls, size_t size, void *buf) | ||
454 | { | ||
455 | static char msgbuf[TEST_MESSAGE_SIZE]; | ||
456 | struct BenchmarkPeer *bp = cls; | ||
457 | struct GNUNET_MessageHeader *msg; | ||
458 | |||
459 | bp->cth = NULL; | ||
460 | |||
461 | bp->messages_sent ++; | ||
462 | if (GNUNET_YES == bp->partner_msg) | ||
463 | { | ||
464 | bp->messages_sent_partner ++; | ||
465 | bp->partner_msg = GNUNET_NO; | ||
466 | } | ||
467 | |||
468 | msg = (struct GNUNET_MessageHeader *) &msgbuf; | ||
469 | memset (&msgbuf, 'a', TEST_MESSAGE_SIZE); | ||
470 | msg->type = htons (TEST_MESSAGE_TYPE_PING); | ||
471 | msg->size = htons (TEST_MESSAGE_SIZE); | ||
472 | memcpy (buf, msg, TEST_MESSAGE_SIZE); | ||
473 | return TEST_MESSAGE_SIZE; | ||
474 | } | ||
475 | |||
476 | static struct BenchmarkPeer * | ||
477 | get_next (struct BenchmarkPeer *p) | ||
478 | { | ||
479 | uint32_t b_index; | ||
480 | uint32_t index; | ||
481 | int counter; | ||
482 | |||
483 | if (0 == p->send_mask) | ||
484 | p->send_mask = (1 << c_slave_peers) - 1; /* Next round */ | ||
485 | |||
486 | GNUNET_assert (p->send_mask <= (1 << c_slave_peers) - 1); | ||
487 | counter = 0; | ||
488 | do | ||
489 | { | ||
490 | index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, c_slave_peers); | ||
491 | b_index = 1 << index; | ||
492 | counter++; | ||
493 | } | ||
494 | while ((b_index != (p->send_mask & b_index)) && (counter < c_slave_peers)); | ||
495 | if ((b_index != (p->send_mask & b_index)) && (counter == c_slave_peers)) | ||
496 | { | ||
497 | /* To many random attempts use fcfs */ | ||
498 | for (index = 0; index < c_slave_peers - 1; index ++) | ||
499 | { | ||
500 | b_index = 1 << index; | ||
501 | if (b_index == (p->send_mask & b_index)) | ||
502 | break; | ||
503 | } | ||
504 | } | ||
505 | p->send_mask ^= b_index; /* Remove bit */ | ||
506 | return &bp_slaves[index]; | ||
507 | |||
508 | } | ||
509 | |||
510 | |||
511 | static void | ||
512 | ats_pref_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
513 | { | ||
514 | static double last = 1; | ||
515 | struct BenchmarkPeer *bp = cls; | ||
516 | |||
517 | bp->ats_task = GNUNET_SCHEDULER_NO_TASK; | ||
518 | |||
519 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Set preference for master %u: %f\n", | ||
520 | bp->no, last); | ||
521 | GNUNET_ATS_performance_change_preference (bp->p_handle, &bp->destination->id, | ||
522 | GNUNET_ATS_PREFERENCE_BANDWIDTH, (double) last, | ||
523 | GNUNET_ATS_PREFERENCE_END); | ||
524 | last++; | ||
525 | bp->ats_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | ||
526 | &ats_pref_task, bp); | ||
527 | } | ||
528 | |||
529 | |||
530 | static void | ||
531 | do_benchmark () | ||
532 | { | ||
533 | int c_m; | ||
534 | struct BenchmarkPeer *s; | ||
535 | struct BenchmarkPeer *bp; | ||
536 | |||
537 | if ((state.connected_ATS_service == GNUNET_NO) || | ||
538 | (state.connected_CORE_service == GNUNET_NO) || | ||
539 | (state.connected_PEERS == GNUNET_NO) || | ||
540 | (state.connected_CORE == GNUNET_NO)) | ||
541 | return; | ||
542 | |||
543 | state.benchmarking = GNUNET_YES; | ||
544 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
545 | _("Benchmarking start\n")); | ||
546 | |||
547 | if (GNUNET_SCHEDULER_NO_TASK != shutdown_task) | ||
548 | GNUNET_SCHEDULER_cancel (shutdown_task); | ||
549 | shutdown_task = GNUNET_SCHEDULER_add_delayed (BENCHMARK_DURATION, &do_shutdown, NULL); | ||
550 | |||
551 | /* Start sending test messages */ | ||
552 | for (c_m = 0; c_m < c_master_peers; c_m ++) | ||
553 | { | ||
554 | bp = &bp_master[c_m]; | ||
555 | s = get_next (bp); | ||
556 | if (0 == memcmp(&s->id, &bp->destination->id, sizeof (struct GNUNET_PeerIdentity))) | ||
557 | bp->partner_msg = GNUNET_YES; | ||
558 | bp->cth = GNUNET_CORE_notify_transmit_ready (bp->ch, | ||
559 | GNUNET_NO, 0, GNUNET_TIME_UNIT_MINUTES, | ||
560 | &s->id, | ||
561 | TEST_MESSAGE_SIZE, &core_send_ready, bp); | ||
562 | bp->ats_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | ||
563 | &ats_pref_task, bp); | ||
564 | } | ||
565 | |||
566 | |||
567 | } | ||
568 | |||
569 | |||
570 | static void | ||
571 | connect_completion_callback (void *cls, | ||
572 | struct GNUNET_TESTBED_Operation *op, | ||
573 | const char *emsg) | ||
574 | { | ||
575 | struct ConnectOperation *cop = cls; | ||
576 | static int ops = 0 ; | ||
577 | int c; | ||
578 | if (NULL == emsg) | ||
579 | { | ||
580 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
581 | _("Connected master peer %u with peer %u\n"), cop->master->no, cop->slave->no); | ||
582 | } | ||
583 | else | ||
584 | { | ||
585 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
586 | _("Failed to connect master peer%u with peer %u\n"), cop->master->no, cop->slave->no); | ||
587 | GNUNET_break (0); | ||
588 | if (GNUNET_SCHEDULER_NO_TASK != shutdown_task) | ||
589 | GNUNET_SCHEDULER_cancel(shutdown_task); | ||
590 | shutdown_task = GNUNET_SCHEDULER_add_now (do_shutdown, NULL); | ||
591 | } | ||
592 | GNUNET_TESTBED_operation_done(op); | ||
593 | ops++; | ||
594 | for (c = 0; c < c_slave_peers; c++) | ||
595 | { | ||
596 | if (cop == &cop->master->connect_ops[c]) | ||
597 | cop->master->connect_ops[c].connect_op = NULL; | ||
598 | } | ||
599 | if (ops == c_master_peers * c_slave_peers) | ||
600 | { | ||
601 | state.connected_PEERS = GNUNET_YES; | ||
602 | GNUNET_SCHEDULER_add_now (&do_benchmark, NULL); | ||
603 | } | ||
604 | } | ||
605 | |||
606 | |||
607 | static void | ||
608 | do_connect_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
609 | { | ||
610 | int c_m; | ||
611 | int c_s; | ||
612 | struct BenchmarkPeer *bp; | ||
613 | |||
614 | if ((state.connected_ATS_service == GNUNET_NO) || | ||
615 | (state.connected_CORE_service == GNUNET_NO)) | ||
616 | { | ||
617 | return; | ||
618 | } | ||
619 | |||
620 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Connecting peers on CORE level\n")); | ||
621 | |||
622 | for (c_m = 0; c_m < c_master_peers; c_m ++) | ||
623 | { | ||
624 | bp = &bp_master[c_m]; | ||
625 | bp->connect_ops = GNUNET_malloc (c_slave_peers * sizeof (struct ConnectOperation)); | ||
626 | |||
627 | for (c_s = 0; c_s < c_slave_peers; c_s ++) | ||
628 | { | ||
629 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Connecting master peer %u with slave peer %u\n"), | ||
630 | bp->no, bp_slaves[c_s].no); | ||
631 | |||
632 | bp->connect_ops[c_s].master = bp; | ||
633 | bp->connect_ops[c_s].slave = &bp_slaves[c_s]; | ||
634 | bp->connect_ops[c_s].connect_op = GNUNET_TESTBED_overlay_connect( NULL, | ||
635 | &connect_completion_callback, | ||
636 | &bp->connect_ops[c_s], | ||
637 | bp_slaves[c_s].peer, | ||
638 | bp->peer); | ||
639 | |||
640 | if (NULL == bp->connect_ops[c_s].connect_op) | ||
641 | { | ||
642 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
643 | _("Could not connect master peer %u and slave peer %u\n"), | ||
644 | bp->no, bp_slaves[c_s].no); | ||
645 | GNUNET_break (0); | ||
646 | if (GNUNET_SCHEDULER_NO_TASK != shutdown_task) | ||
647 | GNUNET_SCHEDULER_cancel(shutdown_task); | ||
648 | shutdown_task = GNUNET_SCHEDULER_add_now (do_shutdown, NULL); | ||
649 | return; | ||
650 | } | ||
651 | } | ||
652 | } | ||
653 | } | ||
654 | |||
655 | |||
656 | /** | ||
657 | * Controller event callback | ||
658 | * | ||
659 | * @param cls NULL | ||
660 | * @param event the controller event | ||
661 | */ | ||
662 | static void | ||
663 | controller_event_cb (void *cls, | ||
664 | const struct GNUNET_TESTBED_EventInformation *event) | ||
665 | { | ||
666 | //struct BenchmarkPeer *p = cls; | ||
667 | switch (event->type) | ||
668 | { | ||
669 | case GNUNET_TESTBED_ET_CONNECT: | ||
670 | break; | ||
671 | case GNUNET_TESTBED_ET_OPERATION_FINISHED: | ||
672 | break; | ||
673 | default: | ||
674 | GNUNET_break (0); | ||
675 | result = 2; | ||
676 | GNUNET_SCHEDULER_cancel (shutdown_task); | ||
677 | shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
678 | } | ||
679 | } | ||
680 | |||
681 | /** | ||
682 | * Method called whenever a given peer connects. | ||
683 | * | ||
684 | * @param cls closure | ||
685 | * @param peer peer identity this notification is about | ||
686 | */ | ||
687 | static void | ||
688 | core_connect_cb (void *cls, const struct GNUNET_PeerIdentity * peer) | ||
689 | { | ||
690 | struct BenchmarkPeer *p = cls; | ||
691 | struct BenchmarkPeer *t; | ||
692 | char *id; | ||
693 | int c; | ||
694 | int cs; | ||
695 | |||
696 | id = GNUNET_strdup (GNUNET_i2s (&p->id)); | ||
697 | |||
698 | t = find_peer (peer); | ||
699 | if (NULL == t) | ||
700 | { | ||
701 | GNUNET_break (0); | ||
702 | return; | ||
703 | } | ||
704 | |||
705 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
706 | "%s %s connected to %s %s\n", | ||
707 | (p->master == GNUNET_YES) ? "Master": "Slave", | ||
708 | id, | ||
709 | (t->master == GNUNET_YES) ? "Master": "Slave", | ||
710 | GNUNET_i2s (peer)); | ||
711 | |||
712 | p->core_connections ++; | ||
713 | if ((GNUNET_YES == p->master) && (GNUNET_NO == t->master) && (GNUNET_NO == state.connected_CORE)) | ||
714 | { | ||
715 | p->slave_connections ++; | ||
716 | |||
717 | if (p->slave_connections == c_slave_peers) | ||
718 | { | ||
719 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
720 | "Master %u connected all slaves\n", p->no); | ||
721 | } | ||
722 | cs = GNUNET_YES; | ||
723 | for (c = 0; c < c_master_peers; c ++) | ||
724 | { | ||
725 | if (bp_master[c].slave_connections != c_slave_peers) | ||
726 | cs = GNUNET_NO; | ||
727 | } | ||
728 | if (GNUNET_YES == cs) | ||
729 | { | ||
730 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
731 | "All master peers connected all slave peers\n", id, GNUNET_i2s (peer)); | ||
732 | state.connected_CORE = GNUNET_YES; | ||
733 | GNUNET_SCHEDULER_add_now (&do_benchmark, NULL); | ||
734 | } | ||
735 | } | ||
736 | GNUNET_free (id); | ||
737 | } | ||
738 | |||
739 | |||
740 | /** | ||
741 | * Method called whenever a peer disconnects. | ||
742 | * | ||
743 | * @param cls closure | ||
744 | * @param peer peer identity this notification is about | ||
745 | */ | ||
746 | static void | ||
747 | core_disconnect_cb (void *cls, const struct GNUNET_PeerIdentity * peer) | ||
748 | { | ||
749 | struct BenchmarkPeer *p = cls; | ||
750 | struct BenchmarkPeer *t; | ||
751 | char *id; | ||
752 | |||
753 | t = find_peer (peer); | ||
754 | if (NULL == t) | ||
755 | { | ||
756 | GNUNET_break (0); | ||
757 | return; | ||
758 | } | ||
759 | |||
760 | id = GNUNET_strdup (GNUNET_i2s (&p->id)); | ||
761 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
762 | "%s disconnected from %s \n", id, GNUNET_i2s (peer)); | ||
763 | GNUNET_assert (p->core_connections > 0); | ||
764 | p->core_connections --; | ||
765 | |||
766 | if ((GNUNET_YES == state.benchmarking) && | ||
767 | ((GNUNET_YES == p->master) || (GNUNET_YES == t->master))) | ||
768 | { | ||
769 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
770 | "%s disconnected from %s while benchmarking \n", id, GNUNET_i2s (peer)); | ||
771 | } | ||
772 | |||
773 | GNUNET_free (id); | ||
774 | } | ||
775 | |||
776 | static size_t | ||
777 | core_send_echo_queued_ready (void *cls, size_t size, void *buf); | ||
778 | |||
779 | static size_t | ||
780 | core_send_echo_ready (void *cls, size_t size, void *buf) | ||
781 | { | ||
782 | static char msgbuf[TEST_MESSAGE_SIZE]; | ||
783 | struct BenchmarkPeer *bp = cls; | ||
784 | struct GNUNET_MessageHeader *msg; | ||
785 | |||
786 | bp->cth = NULL; | ||
787 | |||
788 | msg = (struct GNUNET_MessageHeader *) &msgbuf; | ||
789 | memset (&msgbuf, 'a', TEST_MESSAGE_SIZE); | ||
790 | msg->type = htons (TEST_MESSAGE_TYPE_PONG); | ||
791 | msg->size = htons (TEST_MESSAGE_SIZE); | ||
792 | memcpy (buf, msg, TEST_MESSAGE_SIZE); | ||
793 | |||
794 | /* send echo */ | ||
795 | if (NULL != bp->p_head) | ||
796 | bp->cth = GNUNET_CORE_notify_transmit_ready (bp->ch, | ||
797 | GNUNET_NO, 0, GNUNET_TIME_UNIT_MINUTES, | ||
798 | &bp->p_head->target, | ||
799 | TEST_MESSAGE_SIZE, &core_send_echo_queued_ready, bp); | ||
800 | |||
801 | return TEST_MESSAGE_SIZE; | ||
802 | } | ||
803 | |||
804 | static size_t | ||
805 | core_send_echo_queued_ready (void *cls, size_t size, void *buf) | ||
806 | { | ||
807 | struct BenchmarkPeer *bp = cls; | ||
808 | struct PendingMessages *pm; | ||
809 | GNUNET_assert (NULL != bp->p_head); | ||
810 | |||
811 | pm = bp->p_head; | ||
812 | GNUNET_CONTAINER_DLL_remove (bp->p_head, bp->p_tail, pm); | ||
813 | GNUNET_free (pm); | ||
814 | |||
815 | |||
816 | return core_send_echo_ready (cls, size, buf); | ||
817 | |||
818 | } | ||
819 | |||
820 | |||
821 | static int | ||
822 | core_handle_ping (void *cls, const struct GNUNET_PeerIdentity *other, | ||
823 | const struct GNUNET_MessageHeader *message) | ||
824 | { | ||
825 | struct BenchmarkPeer *me = cls; | ||
826 | struct BenchmarkPeer *remote; | ||
827 | struct PendingMessages *pm; | ||
828 | |||
829 | remote = find_peer (other); | ||
830 | |||
831 | if (NULL == remote) | ||
832 | { | ||
833 | GNUNET_break (0); | ||
834 | return GNUNET_SYSERR; | ||
835 | } | ||
836 | |||
837 | if (NULL != me->cth) | ||
838 | { | ||
839 | pm = GNUNET_malloc (sizeof (struct PendingMessages)); | ||
840 | pm->target = (*other); | ||
841 | GNUNET_CONTAINER_DLL_insert_tail (me->p_head, me->p_tail, pm); | ||
842 | return GNUNET_OK; | ||
843 | } | ||
844 | |||
845 | if (GNUNET_NO == remote->master) | ||
846 | { | ||
847 | GNUNET_break (0); | ||
848 | return GNUNET_OK; | ||
849 | } | ||
850 | |||
851 | me->messages_received ++; | ||
852 | /* send echo */ | ||
853 | me->cth = GNUNET_CORE_notify_transmit_ready (me->ch, | ||
854 | GNUNET_NO, 0, GNUNET_TIME_UNIT_MINUTES, | ||
855 | &remote->id, | ||
856 | TEST_MESSAGE_SIZE, &core_send_echo_ready, me); | ||
857 | return GNUNET_OK; | ||
858 | } | ||
859 | |||
860 | static int | ||
861 | core_handle_pong (void *cls, const struct GNUNET_PeerIdentity *other, | ||
862 | const struct GNUNET_MessageHeader *message) | ||
863 | { | ||
864 | struct BenchmarkPeer *me = cls; | ||
865 | struct BenchmarkPeer *remote; | ||
866 | struct BenchmarkPeer *next; | ||
867 | |||
868 | remote = find_peer (other); | ||
869 | |||
870 | if (NULL == remote) | ||
871 | { | ||
872 | GNUNET_break (0); | ||
873 | return GNUNET_SYSERR; | ||
874 | } | ||
875 | |||
876 | if (NULL != me->cth) | ||
877 | { | ||
878 | GNUNET_break (0); | ||
879 | return GNUNET_OK; | ||
880 | } | ||
881 | |||
882 | if (GNUNET_YES == remote->master) | ||
883 | { | ||
884 | GNUNET_break (0); | ||
885 | return GNUNET_OK; | ||
886 | } | ||
887 | me->messages_received ++; | ||
888 | next = get_next (me); | ||
889 | if (0 == memcmp(&remote->id, &me->destination->id, sizeof (struct GNUNET_PeerIdentity))) | ||
890 | me->partner_msg = GNUNET_YES; | ||
891 | me->cth = GNUNET_CORE_notify_transmit_ready (me->ch, | ||
892 | GNUNET_NO, 0, GNUNET_TIME_UNIT_MINUTES, | ||
893 | &next->id, | ||
894 | TEST_MESSAGE_SIZE, &core_send_ready, me); | ||
895 | |||
896 | return GNUNET_OK; | ||
897 | } | ||
898 | |||
899 | |||
900 | /** | ||
901 | * Called to open a connection to the peer's ATS performance | ||
902 | * | ||
903 | * @param cls peer context | ||
904 | * @param cfg configuration of the peer to connect to; will be available until | ||
905 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
906 | * from GNUNET_TESTBED_service_connect() | ||
907 | * @return service handle to return in 'op_result', NULL on error | ||
908 | */ | ||
909 | static void * | ||
910 | core_connect_adapter (void *cls, | ||
911 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
912 | { | ||
913 | struct BenchmarkPeer *peer = cls; | ||
914 | |||
915 | static const struct GNUNET_CORE_MessageHandler handlers[] = { | ||
916 | {&core_handle_ping, TEST_MESSAGE_TYPE_PING, 0}, | ||
917 | {&core_handle_pong, TEST_MESSAGE_TYPE_PONG, 0}, | ||
918 | {NULL, 0, 0} | ||
919 | }; | ||
920 | |||
921 | peer->ch = GNUNET_CORE_connect(cfg, peer, NULL, | ||
922 | core_connect_cb, core_disconnect_cb, | ||
923 | NULL, GNUNET_NO, NULL, GNUNET_NO, handlers); | ||
924 | if (NULL == peer->ch) | ||
925 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
926 | "Failed to create core connection \n"); | ||
927 | return peer->ch; | ||
928 | } | ||
929 | |||
930 | |||
931 | /** | ||
932 | * Callback to be called when a service connect operation is completed | ||
933 | * | ||
934 | * @param cls the callback closure from functions generating an operation | ||
935 | * @param op the operation that has been finished | ||
936 | * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() | ||
937 | * @param emsg error message in case the operation has failed; will be NULL if | ||
938 | * operation has executed successfully. | ||
939 | */ | ||
940 | static void | ||
941 | core_connect_completion_cb (void *cls, | ||
942 | struct GNUNET_TESTBED_Operation *op, | ||
943 | void *ca_result, | ||
944 | const char *emsg ) | ||
945 | { | ||
946 | static int core_done = 0; | ||
947 | if ((NULL != emsg) || (NULL == ca_result)) | ||
948 | { | ||
949 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
950 | _("Initialization failed, shutdown\n")); | ||
951 | GNUNET_break (0); | ||
952 | if (GNUNET_SCHEDULER_NO_TASK != shutdown_task) | ||
953 | GNUNET_SCHEDULER_cancel(shutdown_task); | ||
954 | shutdown_task = GNUNET_SCHEDULER_add_now (do_shutdown, NULL); | ||
955 | return; | ||
956 | } | ||
957 | core_done ++; | ||
958 | |||
959 | if (core_done == c_slave_peers + c_master_peers) | ||
960 | { | ||
961 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
962 | "Connected to all CORE services\n"); | ||
963 | state.connected_CORE_service = GNUNET_YES; | ||
964 | GNUNET_SCHEDULER_add_now (&do_connect_peers, NULL); | ||
965 | } | ||
966 | } | ||
967 | |||
968 | |||
969 | /** | ||
970 | * Called to disconnect from peer's statistics service | ||
971 | * | ||
972 | * @param cls peer context | ||
973 | * @param op_result service handle returned from the connect adapter | ||
974 | */ | ||
975 | static void | ||
976 | core_disconnect_adapter (void *cls, void *op_result) | ||
977 | { | ||
978 | struct BenchmarkPeer *peer = cls; | ||
979 | |||
980 | GNUNET_CORE_disconnect (peer->ch); | ||
981 | peer->ch = NULL; | ||
982 | } | ||
983 | |||
984 | static void | ||
985 | do_connect_core (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
986 | { | ||
987 | int c_p; | ||
988 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
989 | "Connecting to all CORE services\n"); | ||
990 | for (c_p = 0; c_p < c_master_peers; c_p++) | ||
991 | { | ||
992 | bp_master[c_p].core_op = GNUNET_TESTBED_service_connect (NULL, | ||
993 | bp_master[c_p].peer, "core", | ||
994 | core_connect_completion_cb, NULL, | ||
995 | &core_connect_adapter, | ||
996 | &core_disconnect_adapter, | ||
997 | &bp_master[c_p]); | ||
998 | |||
999 | } | ||
1000 | |||
1001 | for (c_p = 0; c_p < c_slave_peers; c_p++) | ||
1002 | { | ||
1003 | bp_slaves[c_p].core_op = GNUNET_TESTBED_service_connect (NULL, | ||
1004 | bp_slaves[c_p].peer, "core", | ||
1005 | core_connect_completion_cb, NULL, | ||
1006 | &core_connect_adapter, | ||
1007 | &core_disconnect_adapter, | ||
1008 | &bp_slaves[c_p]); | ||
1009 | } | ||
1010 | } | ||
1011 | |||
1012 | |||
1013 | |||
1014 | /** | ||
1015 | * Called to open a connection to the peer's ATS performance | ||
1016 | * | ||
1017 | * @param cls peer context | ||
1018 | * @param cfg configuration of the peer to connect to; will be available until | ||
1019 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
1020 | * from GNUNET_TESTBED_service_connect() | ||
1021 | * @return service handle to return in 'op_result', NULL on error | ||
1022 | */ | ||
1023 | static void * | ||
1024 | ats_perf_connect_adapter (void *cls, | ||
1025 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
1026 | { | ||
1027 | struct BenchmarkPeer *peer = cls; | ||
1028 | |||
1029 | peer->p_handle = GNUNET_ATS_performance_init (cfg, &ats_performance_info_cb, peer); | ||
1030 | if (NULL == peer->p_handle) | ||
1031 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create ATS performance handle \n"); | ||
1032 | return peer->p_handle; | ||
1033 | } | ||
1034 | |||
1035 | |||
1036 | /** | ||
1037 | * Called to disconnect from peer's statistics service | ||
1038 | * | ||
1039 | * @param cls peer context | ||
1040 | * @param op_result service handle returned from the connect adapter | ||
1041 | */ | ||
1042 | static void | ||
1043 | ats_perf_disconnect_adapter (void *cls, void *op_result) | ||
1044 | { | ||
1045 | struct BenchmarkPeer *peer = cls; | ||
1046 | |||
1047 | GNUNET_ATS_performance_done(peer->p_handle); | ||
1048 | peer->p_handle = NULL; | ||
1049 | } | ||
1050 | |||
1051 | |||
1052 | /** | ||
1053 | * Callback to be called when a service connect operation is completed | ||
1054 | * | ||
1055 | * @param cls the callback closure from functions generating an operation | ||
1056 | * @param op the operation that has been finished | ||
1057 | * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() | ||
1058 | * @param emsg error message in case the operation has failed; will be NULL if | ||
1059 | * operation has executed successfully. | ||
1060 | */ | ||
1061 | static void | ||
1062 | ats_connect_completion_cb (void *cls, | ||
1063 | struct GNUNET_TESTBED_Operation *op, | ||
1064 | void *ca_result, | ||
1065 | const char *emsg ) | ||
1066 | { | ||
1067 | static int op_done = 0; | ||
1068 | if ((NULL != emsg) || (NULL == ca_result)) | ||
1069 | { | ||
1070 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1071 | _("Initialization failed, shutdown\n")); | ||
1072 | GNUNET_break (0); | ||
1073 | if (GNUNET_SCHEDULER_NO_TASK != shutdown_task) | ||
1074 | GNUNET_SCHEDULER_cancel(shutdown_task); | ||
1075 | shutdown_task = GNUNET_SCHEDULER_add_now (do_shutdown, NULL); | ||
1076 | return; | ||
1077 | } | ||
1078 | |||
1079 | op_done ++; | ||
1080 | if (op_done == (c_slave_peers + c_master_peers)) | ||
1081 | { | ||
1082 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1083 | "Connected to all ATS services\n"); | ||
1084 | state.connected_ATS_service = GNUNET_YES; | ||
1085 | GNUNET_SCHEDULER_add_now (&do_connect_core, NULL); | ||
1086 | } | ||
1087 | } | ||
1088 | |||
1089 | static void | ||
1090 | do_connect_ats (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1091 | { | ||
1092 | int c_p; | ||
1093 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1094 | "Connecting to all ATS services %u\n", c_slave_peers); | ||
1095 | for (c_p = 0; c_p < c_master_peers; c_p++) | ||
1096 | { | ||
1097 | bp_master[c_p].ats_perf_op = GNUNET_TESTBED_service_connect (NULL, | ||
1098 | bp_master[c_p].peer, "ats", | ||
1099 | ats_connect_completion_cb, NULL, | ||
1100 | &ats_perf_connect_adapter, | ||
1101 | &ats_perf_disconnect_adapter, | ||
1102 | &bp_master[c_p]); | ||
1103 | |||
1104 | } | ||
1105 | |||
1106 | for (c_p = 0; c_p < c_slave_peers; c_p++) | ||
1107 | { | ||
1108 | bp_slaves[c_p].ats_perf_op = GNUNET_TESTBED_service_connect (NULL, | ||
1109 | bp_slaves[c_p].peer, "ats", | ||
1110 | ats_connect_completion_cb, NULL, | ||
1111 | &ats_perf_connect_adapter, | ||
1112 | &ats_perf_disconnect_adapter, | ||
1113 | &bp_slaves[c_p]); | ||
1114 | } | ||
1115 | |||
1116 | } | ||
1117 | |||
1118 | |||
1119 | /** | ||
1120 | * Callback to be called when the requested peer information is available | ||
1121 | * | ||
1122 | * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information() | ||
1123 | * @param op the operation this callback corresponds to | ||
1124 | * @param pinfo the result; will be NULL if the operation has failed | ||
1125 | * @param emsg error message if the operation has failed; will be NULL if the | ||
1126 | * operation is successfull | ||
1127 | */ | ||
1128 | static void | ||
1129 | peerinformation_cb (void *cb_cls, | ||
1130 | struct GNUNET_TESTBED_Operation *op, | ||
1131 | const struct GNUNET_TESTBED_PeerInformation*pinfo, | ||
1132 | const char *emsg) | ||
1133 | { | ||
1134 | struct BenchmarkPeer *p = cb_cls; | ||
1135 | static int done = 0; | ||
1136 | |||
1137 | if (pinfo->pit == GNUNET_TESTBED_PIT_IDENTITY) | ||
1138 | { | ||
1139 | p->id = *pinfo->result.id; | ||
1140 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1141 | "[%c %03u] Peers %s\n", | ||
1142 | (p->master == GNUNET_YES) ? 'M' : 'S', p->no, GNUNET_i2s (&p->id)); | ||
1143 | } | ||
1144 | else | ||
1145 | { | ||
1146 | GNUNET_assert (0); | ||
1147 | } | ||
1148 | GNUNET_TESTBED_operation_done (op); | ||
1149 | p->info_op = NULL; | ||
1150 | done++; | ||
1151 | |||
1152 | if (done == c_master_peers + c_slave_peers) | ||
1153 | { | ||
1154 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1155 | "Retrieved all peer ID, connect to ATS\n"); | ||
1156 | state.connected_CORE_service = GNUNET_YES; | ||
1157 | GNUNET_SCHEDULER_add_now (&do_connect_ats, NULL); | ||
1158 | } | ||
1159 | } | ||
1160 | |||
1161 | |||
1162 | /** | ||
1163 | * Signature of a main function for a testcase. | ||
1164 | * | ||
1165 | * @param cls closure | ||
1166 | * @param num_peers number of peers in 'peers' | ||
1167 | * @param peers_ handle to peers run in the testbed | ||
1168 | * @param links_succeeded the number of overlay link connection attempts that | ||
1169 | * succeeded | ||
1170 | * @param links_failed the number of overlay link connection attempts that | ||
1171 | * failed | ||
1172 | */ | ||
1173 | static void | ||
1174 | test_main (void *cls, unsigned int num_peers, | ||
1175 | struct GNUNET_TESTBED_Peer **peers_, | ||
1176 | unsigned int links_succeeded, | ||
1177 | unsigned int links_failed) | ||
1178 | { | ||
1179 | int c_p; | ||
1180 | |||
1181 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1182 | _("Benchmarking solver `%s' on preference `%s' with %u master and %u slave peers\n"), | ||
1183 | solver, preference, c_master_peers, c_slave_peers); | ||
1184 | |||
1185 | shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(TEST_TIMEOUT, c_master_peers + c_slave_peers), &do_shutdown, NULL); | ||
1186 | |||
1187 | GNUNET_assert (NULL == cls); | ||
1188 | GNUNET_assert (c_slave_peers + c_master_peers == num_peers); | ||
1189 | GNUNET_assert (NULL != peers_); | ||
1190 | |||
1191 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1192 | _("Initializing... \n")); | ||
1193 | |||
1194 | for (c_p = 0; c_p < c_master_peers; c_p++) | ||
1195 | { | ||
1196 | GNUNET_assert (NULL != peers_[c_p]); | ||
1197 | bp_master[c_p].no = c_p; | ||
1198 | bp_master[c_p].send_mask = (1 << c_slave_peers) - 1; | ||
1199 | bp_master[c_p].master = GNUNET_YES; | ||
1200 | bp_master[c_p].peer = peers_[c_p]; | ||
1201 | bp_master[c_p].info_op = GNUNET_TESTBED_peer_get_information (bp_master[c_p].peer, | ||
1202 | GNUNET_TESTBED_PIT_IDENTITY, | ||
1203 | &peerinformation_cb, &bp_master[c_p]); | ||
1204 | |||
1205 | /* Select ATS measurement partner */ | ||
1206 | bp_master[c_p].destination = &bp_slaves[c_p]; | ||
1207 | } | ||
1208 | |||
1209 | for (c_p = 0; c_p < c_slave_peers; c_p++) | ||
1210 | { | ||
1211 | GNUNET_assert (NULL != peers_[c_p + c_master_peers]); | ||
1212 | bp_slaves[c_p].no = c_p + c_master_peers; | ||
1213 | bp_slaves[c_p].master = GNUNET_NO; | ||
1214 | bp_slaves[c_p].peer = peers_[c_p + c_master_peers]; | ||
1215 | bp_slaves[c_p].info_op = GNUNET_TESTBED_peer_get_information (bp_slaves[c_p].peer, | ||
1216 | GNUNET_TESTBED_PIT_IDENTITY, | ||
1217 | &peerinformation_cb, &bp_slaves[c_p]); | ||
1218 | } | ||
1219 | |||
1220 | } | ||
1221 | |||
1222 | |||
1223 | int | ||
1224 | main (int argc, char *argv[]) | ||
1225 | { | ||
1226 | char *tmp; | ||
1227 | char *tmp_sep; | ||
1228 | char *test_name; | ||
1229 | char *conf_name; | ||
1230 | char *dotexe; | ||
1231 | int c; | ||
1232 | |||
1233 | result = 0; | ||
1234 | |||
1235 | /* figure out testname */ | ||
1236 | tmp = strstr (argv[0], TESTNAME_PREFIX); | ||
1237 | if (NULL == tmp) | ||
1238 | { | ||
1239 | fprintf (stderr, "Unable to parse test name `%s'\n", argv[0]); | ||
1240 | return GNUNET_SYSERR; | ||
1241 | } | ||
1242 | tmp += strlen(TESTNAME_PREFIX); | ||
1243 | solver = GNUNET_strdup (tmp); | ||
1244 | if (NULL != (dotexe = strstr (solver, ".exe")) && | ||
1245 | dotexe[4] == '\0') | ||
1246 | dotexe[0] = '\0'; | ||
1247 | tmp_sep = strchr (solver, '_'); | ||
1248 | if (NULL == tmp_sep) | ||
1249 | { | ||
1250 | fprintf (stderr, "Unable to parse test name `%s'\n", argv[0]); | ||
1251 | GNUNET_free (solver); | ||
1252 | return GNUNET_SYSERR; | ||
1253 | } | ||
1254 | tmp_sep[0] = '\0'; | ||
1255 | preference = GNUNET_strdup(tmp_sep + 1); | ||
1256 | |||
1257 | GNUNET_asprintf(&conf_name, "%s%s_%s.conf", TESTNAME_PREFIX, solver, preference); | ||
1258 | GNUNET_asprintf(&test_name, "%s%s_%s", TESTNAME_PREFIX, solver, preference); | ||
1259 | |||
1260 | for (c = 0; c < (argc -1); c++) | ||
1261 | { | ||
1262 | if (0 == strcmp(argv[c], "-s")) | ||
1263 | break; | ||
1264 | } | ||
1265 | if (c < argc-1) | ||
1266 | { | ||
1267 | if ((0L != (c_slave_peers = strtol (argv[c + 1], NULL, 10))) && (c_slave_peers >= 1)) | ||
1268 | fprintf (stderr, "Starting %u slave peers\n", c_slave_peers); | ||
1269 | else | ||
1270 | c_slave_peers = DEFAULT_SLAVES_NUM; | ||
1271 | } | ||
1272 | else | ||
1273 | c_slave_peers = DEFAULT_SLAVES_NUM; | ||
1274 | |||
1275 | for (c = 0; c < (argc -1); c++) | ||
1276 | { | ||
1277 | if (0 == strcmp(argv[c], "-m")) | ||
1278 | break; | ||
1279 | } | ||
1280 | if (c < argc-1) | ||
1281 | { | ||
1282 | if ((0L != (c_master_peers = strtol (argv[c + 1], NULL, 10))) && (c_master_peers >= 2)) | ||
1283 | fprintf (stderr, "Starting %u master peers\n", c_master_peers); | ||
1284 | else | ||
1285 | c_master_peers = DEFAULT_MASTERS_NUM; | ||
1286 | } | ||
1287 | else | ||
1288 | c_master_peers = DEFAULT_MASTERS_NUM; | ||
1289 | |||
1290 | bp_slaves = GNUNET_malloc (c_slave_peers * sizeof (struct BenchmarkPeer)); | ||
1291 | bp_master = GNUNET_malloc (c_master_peers * sizeof (struct BenchmarkPeer)); | ||
1292 | |||
1293 | state.connected_ATS_service = GNUNET_NO; | ||
1294 | state.connected_CORE_service = GNUNET_NO; | ||
1295 | state.connected_PEERS = GNUNET_NO; | ||
1296 | |||
1297 | /* Start topology */ | ||
1298 | uint64_t event_mask; | ||
1299 | event_mask = 0; | ||
1300 | event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT); | ||
1301 | event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED); | ||
1302 | (void) GNUNET_TESTBED_test_run (test_name, | ||
1303 | conf_name, c_slave_peers + c_master_peers, | ||
1304 | event_mask, &controller_event_cb, NULL, | ||
1305 | &test_main, NULL); | ||
1306 | |||
1307 | GNUNET_free (solver); | ||
1308 | GNUNET_free (preference); | ||
1309 | GNUNET_free (conf_name); | ||
1310 | GNUNET_free (test_name); | ||
1311 | GNUNET_free (bp_slaves); | ||
1312 | |||
1313 | return result; | ||
1314 | } | ||
1315 | |||
1316 | /* end of file perf_ats.c */ | ||