diff options
Diffstat (limited to 'src/ats-tests/ats-testing.c')
-rw-r--r-- | src/ats-tests/ats-testing.c | 975 |
1 files changed, 0 insertions, 975 deletions
diff --git a/src/ats-tests/ats-testing.c b/src/ats-tests/ats-testing.c deleted file mode 100644 index c6ba8533d..000000000 --- a/src/ats-tests/ats-testing.c +++ /dev/null | |||
@@ -1,975 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2010-2013, 2016, 2017 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /** | ||
21 | * @file ats-tests/ats-testing.c | ||
22 | * @brief ats testing library: setup topology | ||
23 | * solvers | ||
24 | * @author Christian Grothoff | ||
25 | * @author Matthias Wachs | ||
26 | */ | ||
27 | #include "ats-testing.h" | ||
28 | |||
29 | |||
30 | /** | ||
31 | * Connect peers with testbed | ||
32 | */ | ||
33 | struct TestbedConnectOperation | ||
34 | { | ||
35 | /** | ||
36 | * The benchmarking master initiating this connection | ||
37 | */ | ||
38 | struct BenchmarkPeer *master; | ||
39 | |||
40 | /** | ||
41 | * The benchmarking slave to connect to | ||
42 | */ | ||
43 | struct BenchmarkPeer *slave; | ||
44 | |||
45 | /** | ||
46 | * Testbed operation to connect peers | ||
47 | */ | ||
48 | struct GNUNET_TESTBED_Operation *connect_op; | ||
49 | }; | ||
50 | |||
51 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
52 | |||
53 | struct GNUNET_ATS_TEST_Topology *top; | ||
54 | |||
55 | |||
56 | /** | ||
57 | * Shutdown nicely | ||
58 | * | ||
59 | * @param cls NULL | ||
60 | */ | ||
61 | static void | ||
62 | do_shutdown (void *cls) | ||
63 | { | ||
64 | int c_m; | ||
65 | int c_s; | ||
66 | int c_op; | ||
67 | struct BenchmarkPeer *p; | ||
68 | |||
69 | top->state.benchmarking = GNUNET_NO; | ||
70 | |||
71 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
72 | "Benchmarking done\n"); | ||
73 | |||
74 | GNUNET_ATS_TEST_generate_traffic_stop_all (); | ||
75 | |||
76 | for (c_m = 0; c_m < top->num_masters; c_m++) | ||
77 | { | ||
78 | p = &top->mps[c_m]; | ||
79 | if (NULL != top->mps[c_m].peer_id_op) | ||
80 | { | ||
81 | GNUNET_TESTBED_operation_done (p->peer_id_op); | ||
82 | p->peer_id_op = NULL; | ||
83 | } | ||
84 | |||
85 | if (NULL != p->ats_task) | ||
86 | GNUNET_SCHEDULER_cancel (p->ats_task); | ||
87 | p->ats_task = NULL; | ||
88 | |||
89 | for (c_op = 0; c_op < p->num_partners; c_op++) | ||
90 | { | ||
91 | if ((NULL != p->core_connect_ops) && | ||
92 | (NULL != p->core_connect_ops[c_op].connect_op)) | ||
93 | { | ||
94 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
95 | "Failed to connect peer 0 and %u\n", | ||
96 | c_op); | ||
97 | GNUNET_TESTBED_operation_done (p->core_connect_ops[c_op].connect_op); | ||
98 | p->core_connect_ops[c_op].connect_op = NULL; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | if (NULL != p->ats_perf_op) | ||
103 | { | ||
104 | GNUNET_TESTBED_operation_done (p->ats_perf_op); | ||
105 | p->ats_perf_op = NULL; | ||
106 | } | ||
107 | |||
108 | if (NULL != p->comm_op) | ||
109 | { | ||
110 | GNUNET_TESTBED_operation_done (p->comm_op); | ||
111 | p->comm_op = NULL; | ||
112 | } | ||
113 | GNUNET_free (p->core_connect_ops); | ||
114 | GNUNET_free (p->partners); | ||
115 | p->partners = NULL; | ||
116 | } | ||
117 | |||
118 | for (c_s = 0; c_s < top->num_slaves; c_s++) | ||
119 | { | ||
120 | p = &top->sps[c_s]; | ||
121 | if (NULL != p->peer_id_op) | ||
122 | { | ||
123 | GNUNET_TESTBED_operation_done (p->peer_id_op); | ||
124 | p->peer_id_op = NULL; | ||
125 | } | ||
126 | if (NULL != p->ats_perf_op) | ||
127 | { | ||
128 | GNUNET_TESTBED_operation_done (p->ats_perf_op); | ||
129 | p->ats_perf_op = NULL; | ||
130 | } | ||
131 | if (NULL != p->comm_op) | ||
132 | { | ||
133 | GNUNET_TESTBED_operation_done (p->comm_op); | ||
134 | p->comm_op = NULL; | ||
135 | } | ||
136 | GNUNET_free (p->partners); | ||
137 | p->partners = NULL; | ||
138 | } | ||
139 | GNUNET_SCHEDULER_shutdown (); | ||
140 | GNUNET_free (top); | ||
141 | top = NULL; | ||
142 | } | ||
143 | |||
144 | |||
145 | static struct BenchmarkPartner * | ||
146 | find_partner (struct BenchmarkPeer *me, | ||
147 | const struct GNUNET_PeerIdentity *peer) | ||
148 | { | ||
149 | int c_m; | ||
150 | |||
151 | for (c_m = 0; c_m < me->num_partners; c_m++) | ||
152 | { | ||
153 | /* Find a partner with other as destination */ | ||
154 | if (0 == GNUNET_memcmp (peer, | ||
155 | &me->partners[c_m].dest->id)) | ||
156 | { | ||
157 | return &me->partners[c_m]; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | return NULL; | ||
162 | } | ||
163 | |||
164 | |||
165 | static struct BenchmarkPeer * | ||
166 | find_peer (const struct GNUNET_PeerIdentity *peer) | ||
167 | { | ||
168 | int c_p; | ||
169 | |||
170 | for (c_p = 0; c_p < top->num_masters; c_p++) | ||
171 | { | ||
172 | if (0 == GNUNET_memcmp (&top->mps[c_p].id, | ||
173 | peer)) | ||
174 | return &top->mps[c_p]; | ||
175 | } | ||
176 | |||
177 | for (c_p = 0; c_p < top->num_slaves; c_p++) | ||
178 | { | ||
179 | if (0 == GNUNET_memcmp (&top->sps[c_p].id, | ||
180 | peer)) | ||
181 | return &top->sps[c_p]; | ||
182 | } | ||
183 | return NULL; | ||
184 | } | ||
185 | |||
186 | |||
187 | /** | ||
188 | * Method called whenever a given peer connects. | ||
189 | * | ||
190 | * @param cls closure | ||
191 | * @param peer peer identity this notification is about | ||
192 | * @param mq queue to use to send messages to @a peer | ||
193 | * @return the `struct BenchmarkPartner` of @a peer | ||
194 | */ | ||
195 | static void * | ||
196 | comm_connect_cb (void *cls, | ||
197 | const struct GNUNET_PeerIdentity *peer, | ||
198 | struct GNUNET_MQ_Handle *mq) | ||
199 | { | ||
200 | struct BenchmarkPeer *me = cls; | ||
201 | struct BenchmarkPeer *remote; | ||
202 | struct BenchmarkPartner *p; | ||
203 | char *id; | ||
204 | int c; | ||
205 | int completed; | ||
206 | |||
207 | remote = find_peer (peer); | ||
208 | if (NULL == remote) | ||
209 | { | ||
210 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
211 | "Unknown peer connected: `%s'\n", | ||
212 | GNUNET_i2s (peer)); | ||
213 | GNUNET_break (0); | ||
214 | return NULL; | ||
215 | } | ||
216 | |||
217 | id = GNUNET_strdup (GNUNET_i2s (&me->id)); | ||
218 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
219 | "%s [%u] `%s' connected to %s [%u] %s\n", | ||
220 | (me->master == GNUNET_YES) ? "Master" : "Slave", | ||
221 | me->no, | ||
222 | id, | ||
223 | (remote->master == GNUNET_YES) ? "Master" : "Slave", | ||
224 | remote->no, | ||
225 | GNUNET_i2s (peer)); | ||
226 | |||
227 | me->core_connections++; | ||
228 | if ((GNUNET_YES == me->master) && | ||
229 | (GNUNET_NO == remote->master) && | ||
230 | (GNUNET_NO == top->state.connected_CORE)) | ||
231 | { | ||
232 | me->core_slave_connections++; | ||
233 | |||
234 | if (me->core_slave_connections == top->num_slaves) | ||
235 | { | ||
236 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
237 | "Master [%u] connected all slaves\n", | ||
238 | me->no); | ||
239 | } | ||
240 | completed = GNUNET_YES; | ||
241 | for (c = 0; c < top->num_masters; c++) | ||
242 | { | ||
243 | if (top->mps[c].core_slave_connections != top->num_slaves) | ||
244 | completed = GNUNET_NO; | ||
245 | } | ||
246 | if (GNUNET_YES == completed) | ||
247 | { | ||
248 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
249 | "All master peers connected all slave peers\n"); | ||
250 | top->state.connected_CORE = GNUNET_YES; | ||
251 | /* Notify about setup done */ | ||
252 | if (NULL != top->done_cb) | ||
253 | top->done_cb (top->done_cb_cls, | ||
254 | top->mps, | ||
255 | top->sps); | ||
256 | } | ||
257 | } | ||
258 | GNUNET_free (id); | ||
259 | p = find_partner (me, | ||
260 | peer); | ||
261 | if (NULL != p) | ||
262 | p->mq = mq; | ||
263 | return p; | ||
264 | } | ||
265 | |||
266 | |||
267 | /** | ||
268 | * @param cls this peer | ||
269 | * @param peer id of disconnecting peer | ||
270 | * @param internal_cls the `struct BenchmarkPartner` of @a peer | ||
271 | */ | ||
272 | static void | ||
273 | comm_disconnect_cb (void *cls, | ||
274 | const struct GNUNET_PeerIdentity *peer, | ||
275 | void *internal_cls) | ||
276 | { | ||
277 | struct BenchmarkPeer *me = cls; | ||
278 | struct BenchmarkPartner *p = internal_cls; | ||
279 | char *id; | ||
280 | |||
281 | if (NULL == p) | ||
282 | return; | ||
283 | |||
284 | id = GNUNET_strdup (GNUNET_i2s (&me->id)); | ||
285 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
286 | "%s disconnected from %s\n", | ||
287 | id, | ||
288 | GNUNET_i2s (peer)); | ||
289 | GNUNET_assert (me->core_connections > 0); | ||
290 | me->core_connections--; | ||
291 | |||
292 | if ((GNUNET_YES == top->state.benchmarking) && | ||
293 | ((GNUNET_YES == me->master) || | ||
294 | (GNUNET_YES == p->dest->master))) | ||
295 | { | ||
296 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
297 | "%s disconnected from %s while benchmarking\n", | ||
298 | id, | ||
299 | GNUNET_i2s (peer)); | ||
300 | } | ||
301 | GNUNET_free (id); | ||
302 | } | ||
303 | |||
304 | |||
305 | static void | ||
306 | handle_pong (void *cls, | ||
307 | const struct TestMessage *message) | ||
308 | { | ||
309 | struct BenchmarkPartner *p = cls; | ||
310 | |||
311 | GNUNET_ATS_TEST_traffic_handle_pong (p); | ||
312 | } | ||
313 | |||
314 | |||
315 | static void | ||
316 | handle_ping (void *cls, | ||
317 | const struct TestMessage *message) | ||
318 | { | ||
319 | struct BenchmarkPartner *p = cls; | ||
320 | |||
321 | GNUNET_ATS_TEST_traffic_handle_ping (p); | ||
322 | } | ||
323 | |||
324 | |||
325 | static void * | ||
326 | transport_connect_adapter (void *cls, | ||
327 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
328 | { | ||
329 | struct BenchmarkPeer *me = cls; | ||
330 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
331 | GNUNET_MQ_hd_fixed_size (ping, | ||
332 | TEST_MESSAGE_TYPE_PING, | ||
333 | struct TestMessage, | ||
334 | me), | ||
335 | GNUNET_MQ_hd_fixed_size (pong, | ||
336 | TEST_MESSAGE_TYPE_PONG, | ||
337 | struct TestMessage, | ||
338 | me), | ||
339 | GNUNET_MQ_handler_end () | ||
340 | }; | ||
341 | |||
342 | me->th = GNUNET_TRANSPORT_core_connect (cfg, | ||
343 | &me->id, | ||
344 | handlers, | ||
345 | me, | ||
346 | &comm_connect_cb, | ||
347 | &comm_disconnect_cb, | ||
348 | NULL); | ||
349 | if (NULL == me->th) | ||
350 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
351 | "Failed to create transport connection \n"); | ||
352 | return me->th; | ||
353 | } | ||
354 | |||
355 | |||
356 | static void | ||
357 | transport_disconnect_adapter (void *cls, | ||
358 | void *op_result) | ||
359 | { | ||
360 | struct BenchmarkPeer *me = cls; | ||
361 | |||
362 | GNUNET_TRANSPORT_core_disconnect (me->th); | ||
363 | me->th = NULL; | ||
364 | } | ||
365 | |||
366 | |||
367 | static void * | ||
368 | core_connect_adapter (void *cls, | ||
369 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
370 | { | ||
371 | struct BenchmarkPeer *me = cls; | ||
372 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
373 | GNUNET_MQ_hd_fixed_size (ping, | ||
374 | TEST_MESSAGE_TYPE_PING, | ||
375 | struct TestMessage, | ||
376 | me), | ||
377 | GNUNET_MQ_hd_fixed_size (pong, | ||
378 | TEST_MESSAGE_TYPE_PONG, | ||
379 | struct TestMessage, | ||
380 | me), | ||
381 | GNUNET_MQ_handler_end () | ||
382 | }; | ||
383 | |||
384 | me->ch = GNUNET_CORE_connect (cfg, | ||
385 | me, | ||
386 | NULL, | ||
387 | &comm_connect_cb, | ||
388 | &comm_disconnect_cb, | ||
389 | handlers); | ||
390 | if (NULL == me->ch) | ||
391 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
392 | "Failed to create core connection \n"); | ||
393 | return me->ch; | ||
394 | } | ||
395 | |||
396 | |||
397 | static void | ||
398 | core_disconnect_adapter (void *cls, | ||
399 | void *op_result) | ||
400 | { | ||
401 | struct BenchmarkPeer *me = cls; | ||
402 | |||
403 | GNUNET_CORE_disconnect (me->ch); | ||
404 | me->ch = NULL; | ||
405 | } | ||
406 | |||
407 | |||
408 | static void | ||
409 | connect_completion_callback (void *cls, | ||
410 | struct GNUNET_TESTBED_Operation *op, | ||
411 | const char *emsg) | ||
412 | { | ||
413 | struct TestbedConnectOperation *cop = cls; | ||
414 | static int ops = 0; | ||
415 | int c; | ||
416 | |||
417 | if (NULL == emsg) | ||
418 | { | ||
419 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
420 | _ ("Connected master [%u] with slave [%u]\n"), | ||
421 | cop->master->no, | ||
422 | cop->slave->no); | ||
423 | } | ||
424 | else | ||
425 | { | ||
426 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
427 | _ ("Failed to connect master peer [%u] with slave [%u]\n"), | ||
428 | cop->master->no, cop->slave->no); | ||
429 | GNUNET_break (0); | ||
430 | GNUNET_SCHEDULER_shutdown (); | ||
431 | } | ||
432 | GNUNET_TESTBED_operation_done (op); | ||
433 | ops++; | ||
434 | for (c = 0; c < top->num_slaves; c++) | ||
435 | { | ||
436 | if (cop == &cop->master->core_connect_ops[c]) | ||
437 | cop->master->core_connect_ops[c].connect_op = NULL; | ||
438 | } | ||
439 | if (ops == top->num_masters * top->num_slaves) | ||
440 | { | ||
441 | top->state.connected_PEERS = GNUNET_YES; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | |||
446 | static void | ||
447 | do_connect_peers (void *cls) | ||
448 | { | ||
449 | int c_m; | ||
450 | int c_s; | ||
451 | struct BenchmarkPeer *p; | ||
452 | |||
453 | if ((top->state.connected_ATS_service == GNUNET_NO) || | ||
454 | (top->state.connected_COMM_service == GNUNET_NO)) | ||
455 | return; | ||
456 | |||
457 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
458 | "Connecting peers on CORE level\n"); | ||
459 | for (c_m = 0; c_m < top->num_masters; c_m++) | ||
460 | { | ||
461 | p = &top->mps[c_m]; | ||
462 | p->core_connect_ops = GNUNET_malloc (top->num_slaves | ||
463 | * sizeof(struct | ||
464 | TestbedConnectOperation)); | ||
465 | |||
466 | for (c_s = 0; c_s < top->num_slaves; c_s++) | ||
467 | { | ||
468 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
469 | "Connecting master [%u] with slave [%u]\n", | ||
470 | p->no, | ||
471 | top->sps[c_s].no); | ||
472 | p->core_connect_ops[c_s].master = p; | ||
473 | p->core_connect_ops[c_s].slave = &top->sps[c_s]; | ||
474 | p->core_connect_ops[c_s].connect_op | ||
475 | = GNUNET_TESTBED_overlay_connect (NULL, | ||
476 | &connect_completion_callback, | ||
477 | &p->core_connect_ops[c_s], | ||
478 | top->sps[c_s].peer, | ||
479 | p->peer); | ||
480 | if (NULL == p->core_connect_ops[c_s].connect_op) | ||
481 | { | ||
482 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
483 | "Could not connect master [%u] and slave [%u]\n", | ||
484 | p->no, | ||
485 | top->sps[c_s].no); | ||
486 | GNUNET_break (0); | ||
487 | GNUNET_SCHEDULER_shutdown (); | ||
488 | return; | ||
489 | } | ||
490 | } | ||
491 | } | ||
492 | } | ||
493 | |||
494 | |||
495 | static void | ||
496 | comm_connect_completion_cb (void *cls, | ||
497 | struct GNUNET_TESTBED_Operation *op, | ||
498 | void *ca_result, | ||
499 | const char *emsg) | ||
500 | { | ||
501 | static int comm_done = 0; | ||
502 | |||
503 | if ((NULL != emsg) || (NULL == ca_result)) | ||
504 | { | ||
505 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
506 | "Initialization failed, shutdown\n"); | ||
507 | GNUNET_break (0); | ||
508 | GNUNET_SCHEDULER_shutdown (); | ||
509 | return; | ||
510 | } | ||
511 | comm_done++; | ||
512 | |||
513 | if (comm_done == top->num_slaves + top->num_masters) | ||
514 | { | ||
515 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
516 | "Connected to all %s services\n", | ||
517 | (GNUNET_YES == top->test_core) ? "CORE" : "TRANSPORT"); | ||
518 | top->state.connected_COMM_service = GNUNET_YES; | ||
519 | GNUNET_SCHEDULER_add_now (&do_connect_peers, | ||
520 | NULL); | ||
521 | } | ||
522 | } | ||
523 | |||
524 | |||
525 | static void | ||
526 | do_comm_connect (void *cls) | ||
527 | { | ||
528 | int c_s; | ||
529 | int c_m; | ||
530 | |||
531 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
532 | "Connecting to all %s services\n", | ||
533 | (GNUNET_YES == top->test_core) ? "CORE" : "TRANSPORT"); | ||
534 | for (c_m = 0; c_m < top->num_masters; c_m++) | ||
535 | { | ||
536 | if (GNUNET_YES == top->test_core) | ||
537 | top->mps[c_m].comm_op | ||
538 | = GNUNET_TESTBED_service_connect (NULL, | ||
539 | top->mps[c_m].peer, | ||
540 | "core", | ||
541 | &comm_connect_completion_cb, | ||
542 | NULL, | ||
543 | &core_connect_adapter, | ||
544 | &core_disconnect_adapter, | ||
545 | &top->mps[c_m]); | ||
546 | else | ||
547 | { | ||
548 | top->mps[c_m].comm_op | ||
549 | = GNUNET_TESTBED_service_connect (NULL, | ||
550 | top->mps[c_m].peer, | ||
551 | "transport", | ||
552 | &comm_connect_completion_cb, | ||
553 | NULL, | ||
554 | &transport_connect_adapter, | ||
555 | &transport_disconnect_adapter, | ||
556 | &top->mps[c_m]); | ||
557 | } | ||
558 | } | ||
559 | |||
560 | for (c_s = 0; c_s < top->num_slaves; c_s++) | ||
561 | { | ||
562 | if (GNUNET_YES == top->test_core) | ||
563 | top->sps[c_s].comm_op | ||
564 | = GNUNET_TESTBED_service_connect (NULL, | ||
565 | top->sps[c_s].peer, | ||
566 | "core", | ||
567 | &comm_connect_completion_cb, | ||
568 | NULL, | ||
569 | &core_connect_adapter, | ||
570 | &core_disconnect_adapter, | ||
571 | &top->sps[c_s]); | ||
572 | else | ||
573 | { | ||
574 | top->sps[c_s].comm_op | ||
575 | = GNUNET_TESTBED_service_connect (NULL, | ||
576 | top->sps[c_s].peer, | ||
577 | "transport", | ||
578 | &comm_connect_completion_cb, | ||
579 | NULL, | ||
580 | &transport_connect_adapter, | ||
581 | &transport_disconnect_adapter, | ||
582 | &top->sps[c_s]); | ||
583 | } | ||
584 | } | ||
585 | } | ||
586 | |||
587 | |||
588 | static void | ||
589 | ats_performance_info_cb (void *cls, | ||
590 | const struct GNUNET_HELLO_Address *address, | ||
591 | int address_active, | ||
592 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, | ||
593 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, | ||
594 | const struct GNUNET_ATS_Properties *ats_prop) | ||
595 | { | ||
596 | struct BenchmarkPeer *me = cls; | ||
597 | struct BenchmarkPartner *p; | ||
598 | int log; | ||
599 | char *peer_id; | ||
600 | |||
601 | if (NULL == address) | ||
602 | { | ||
603 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
604 | "Peer %u: ATS Service disconnected!\n", | ||
605 | me->no); | ||
606 | return; | ||
607 | } | ||
608 | |||
609 | p = find_partner (me, | ||
610 | &address->peer); | ||
611 | if (NULL == p) | ||
612 | { | ||
613 | /* This is not one of my partners | ||
614 | * Will happen since the peers will connect to each other due to gossiping | ||
615 | */ | ||
616 | return; | ||
617 | } | ||
618 | peer_id = GNUNET_strdup (GNUNET_i2s (&me->id)); | ||
619 | |||
620 | log = GNUNET_NO; | ||
621 | if ((p->bandwidth_in != ntohl (bandwidth_in.value__)) || | ||
622 | (p->bandwidth_out != ntohl (bandwidth_out.value__))) | ||
623 | log = GNUNET_YES; | ||
624 | p->bandwidth_in = ntohl (bandwidth_in.value__); | ||
625 | p->bandwidth_out = ntohl (bandwidth_out.value__); | ||
626 | |||
627 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
628 | "%s [%u] received ATS information: %s\n", | ||
629 | (GNUNET_YES == p->me->master) ? "Master" : "Slave", | ||
630 | p->me->no, | ||
631 | GNUNET_i2s (&p->dest->id)); | ||
632 | |||
633 | p->props.utilization_out = ats_prop->utilization_out; | ||
634 | p->props.utilization_in = ats_prop->utilization_in; | ||
635 | p->props.scope = ats_prop->scope; | ||
636 | p->props.delay = ats_prop->delay; | ||
637 | p->props.distance = ats_prop->distance; | ||
638 | |||
639 | if (GNUNET_YES == log) | ||
640 | top->ats_perf_cb (cls, address, | ||
641 | address_active, | ||
642 | bandwidth_out, | ||
643 | bandwidth_in, | ||
644 | ats_prop); | ||
645 | GNUNET_free (peer_id); | ||
646 | } | ||
647 | |||
648 | |||
649 | static void * | ||
650 | ats_perf_connect_adapter (void *cls, | ||
651 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
652 | { | ||
653 | struct BenchmarkPeer *me = cls; | ||
654 | |||
655 | me->ats_perf_handle | ||
656 | = GNUNET_ATS_performance_init (cfg, | ||
657 | &ats_performance_info_cb, | ||
658 | me); | ||
659 | if (NULL == me->ats_perf_handle) | ||
660 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
661 | "Failed to create ATS performance handle \n"); | ||
662 | return me->ats_perf_handle; | ||
663 | } | ||
664 | |||
665 | |||
666 | static void | ||
667 | ats_perf_disconnect_adapter (void *cls, | ||
668 | void *op_result) | ||
669 | { | ||
670 | struct BenchmarkPeer *me = cls; | ||
671 | |||
672 | GNUNET_ATS_performance_done (me->ats_perf_handle); | ||
673 | me->ats_perf_handle = NULL; | ||
674 | } | ||
675 | |||
676 | |||
677 | static void | ||
678 | ats_connect_completion_cb (void *cls, | ||
679 | struct GNUNET_TESTBED_Operation *op, | ||
680 | void *ca_result, | ||
681 | const char *emsg) | ||
682 | { | ||
683 | static int op_done = 0; | ||
684 | |||
685 | if ((NULL != emsg) || (NULL == ca_result)) | ||
686 | { | ||
687 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
688 | "Initialization failed, shutdown\n"); | ||
689 | GNUNET_break (0); | ||
690 | GNUNET_SCHEDULER_shutdown (); | ||
691 | return; | ||
692 | } | ||
693 | op_done++; | ||
694 | if (op_done == (top->num_masters + top->num_slaves)) | ||
695 | { | ||
696 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
697 | "Connected to all ATS services\n"); | ||
698 | top->state.connected_ATS_service = GNUNET_YES; | ||
699 | GNUNET_SCHEDULER_add_now (&do_comm_connect, | ||
700 | NULL); | ||
701 | } | ||
702 | } | ||
703 | |||
704 | |||
705 | static void | ||
706 | do_connect_ats (void *cls) | ||
707 | { | ||
708 | int c_m; | ||
709 | int c_s; | ||
710 | |||
711 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
712 | "Connecting to all ATS services\n"); | ||
713 | for (c_m = 0; c_m < top->num_masters; c_m++) | ||
714 | { | ||
715 | top->mps[c_m].ats_perf_op | ||
716 | = GNUNET_TESTBED_service_connect (NULL, | ||
717 | top->mps[c_m].peer, | ||
718 | "ats", | ||
719 | &ats_connect_completion_cb, | ||
720 | NULL, | ||
721 | &ats_perf_connect_adapter, | ||
722 | &ats_perf_disconnect_adapter, | ||
723 | &top->mps[c_m]); | ||
724 | } | ||
725 | |||
726 | for (c_s = 0; c_s < top->num_slaves; c_s++) | ||
727 | { | ||
728 | top->sps[c_s].ats_perf_op | ||
729 | = GNUNET_TESTBED_service_connect (NULL, | ||
730 | top->sps[c_s].peer, | ||
731 | "ats", | ||
732 | &ats_connect_completion_cb, | ||
733 | NULL, | ||
734 | &ats_perf_connect_adapter, | ||
735 | &ats_perf_disconnect_adapter, | ||
736 | &top->sps[c_s]); | ||
737 | } | ||
738 | } | ||
739 | |||
740 | |||
741 | static void | ||
742 | peerinformation_cb (void *cb_cls, | ||
743 | struct GNUNET_TESTBED_Operation *op, | ||
744 | const struct GNUNET_TESTBED_PeerInformation *pinfo, | ||
745 | const char *emsg) | ||
746 | { | ||
747 | struct BenchmarkPeer *p = cb_cls; | ||
748 | static int done = 0; | ||
749 | |||
750 | GNUNET_assert (pinfo->pit == GNUNET_TESTBED_PIT_IDENTITY); | ||
751 | |||
752 | p->id = *pinfo->result.id; | ||
753 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
754 | "%s [%u] has peer id `%s'\n", | ||
755 | (p->master == GNUNET_YES) ? "Master" : "Slave", | ||
756 | p->no, | ||
757 | GNUNET_i2s (&p->id)); | ||
758 | |||
759 | GNUNET_TESTBED_operation_done (op); | ||
760 | p->peer_id_op = NULL; | ||
761 | done++; | ||
762 | |||
763 | if (done == top->num_slaves + top->num_masters) | ||
764 | { | ||
765 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
766 | "Retrieved all peer ID, connect to ATS\n"); | ||
767 | GNUNET_SCHEDULER_add_now (&do_connect_ats, | ||
768 | NULL); | ||
769 | } | ||
770 | } | ||
771 | |||
772 | |||
773 | /** | ||
774 | * Signature of a main function for a testcase. | ||
775 | * | ||
776 | * @param cls closure | ||
777 | * @param h testbed handle | ||
778 | * @param num_peers number of peers in 'peers' | ||
779 | * @param peers_ handle to peers run in the testbed | ||
780 | * @param links_succeeded the number of overlay link connection attempts that | ||
781 | * succeeded | ||
782 | * @param links_failed the number of overlay link connection attempts that | ||
783 | * failed | ||
784 | */ | ||
785 | static void | ||
786 | main_run (void *cls, | ||
787 | struct GNUNET_TESTBED_RunHandle *h, | ||
788 | unsigned int num_peers, | ||
789 | struct GNUNET_TESTBED_Peer **peers_, | ||
790 | unsigned int links_succeeded, | ||
791 | unsigned int links_failed) | ||
792 | { | ||
793 | int c_m; | ||
794 | int c_s; | ||
795 | |||
796 | GNUNET_assert (NULL == cls); | ||
797 | GNUNET_assert (top->num_masters + top->num_slaves == num_peers); | ||
798 | GNUNET_assert (NULL != peers_); | ||
799 | |||
800 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | ||
801 | top); | ||
802 | |||
803 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
804 | "Setting up %u masters and %u slaves\n", | ||
805 | top->num_masters, | ||
806 | top->num_slaves); | ||
807 | |||
808 | /* Setup master peers */ | ||
809 | for (c_m = 0; c_m < top->num_masters; c_m++) | ||
810 | { | ||
811 | GNUNET_assert (NULL != peers_[c_m]); | ||
812 | top->mps[c_m].peer = peers_[c_m]; | ||
813 | top->mps[c_m].no = c_m; | ||
814 | top->mps[c_m].master = GNUNET_YES; | ||
815 | top->mps[c_m].pref_partner = &top->sps[c_m]; | ||
816 | top->mps[c_m].pref_value = TEST_ATS_PREFERENCE_DEFAULT; | ||
817 | top->mps[c_m].partners = | ||
818 | GNUNET_malloc (top->num_slaves * sizeof(struct BenchmarkPartner)); | ||
819 | top->mps[c_m].num_partners = top->num_slaves; | ||
820 | /* Initialize partners */ | ||
821 | for (c_s = 0; c_s < top->num_slaves; c_s++) | ||
822 | { | ||
823 | top->mps[c_m].partners[c_s].me = &top->mps[c_m]; | ||
824 | top->mps[c_m].partners[c_s].dest = &top->sps[c_s]; | ||
825 | } | ||
826 | /* Get configuration */ | ||
827 | top->mps[c_m].peer_id_op | ||
828 | = GNUNET_TESTBED_peer_get_information (top->mps[c_m].peer, | ||
829 | GNUNET_TESTBED_PIT_IDENTITY, | ||
830 | &peerinformation_cb, | ||
831 | &top->mps[c_m]); | ||
832 | } | ||
833 | |||
834 | /* Setup slave peers */ | ||
835 | for (c_s = 0; c_s < top->num_slaves; c_s++) | ||
836 | { | ||
837 | GNUNET_assert (NULL != peers_[c_s + top->num_masters]); | ||
838 | top->sps[c_s].peer = peers_[c_s + top->num_masters]; | ||
839 | top->sps[c_s].no = c_s + top->num_masters; | ||
840 | top->sps[c_s].master = GNUNET_NO; | ||
841 | top->sps[c_s].partners = | ||
842 | GNUNET_new_array (top->num_masters, | ||
843 | struct BenchmarkPartner); | ||
844 | top->sps[c_s].num_partners = top->num_masters; | ||
845 | /* Initialize partners */ | ||
846 | for (c_m = 0; c_m < top->num_masters; c_m++) | ||
847 | { | ||
848 | top->sps[c_s].partners[c_m].me = &top->sps[c_s]; | ||
849 | top->sps[c_s].partners[c_m].dest = &top->mps[c_m]; | ||
850 | |||
851 | /* Initialize properties */ | ||
852 | top->sps[c_s].partners[c_m].props.delay = GNUNET_TIME_UNIT_ZERO; | ||
853 | top->sps[c_s].partners[c_m].props.distance = 0; | ||
854 | top->sps[c_s].partners[c_m].props.scope = GNUNET_NT_UNSPECIFIED; | ||
855 | top->sps[c_s].partners[c_m].props.utilization_in = 0; | ||
856 | top->sps[c_s].partners[c_m].props.utilization_out = 0; | ||
857 | } | ||
858 | /* Get configuration */ | ||
859 | top->sps[c_s].peer_id_op | ||
860 | = GNUNET_TESTBED_peer_get_information (top->sps[c_s].peer, | ||
861 | GNUNET_TESTBED_PIT_IDENTITY, | ||
862 | &peerinformation_cb, | ||
863 | &top->sps[c_s]); | ||
864 | } | ||
865 | } | ||
866 | |||
867 | |||
868 | /** | ||
869 | * Controller event callback | ||
870 | * | ||
871 | * @param cls NULL | ||
872 | * @param event the controller event | ||
873 | */ | ||
874 | static void | ||
875 | controller_event_cb (void *cls, | ||
876 | const struct GNUNET_TESTBED_EventInformation *event) | ||
877 | { | ||
878 | switch (event->type) | ||
879 | { | ||
880 | case GNUNET_TESTBED_ET_CONNECT: | ||
881 | break; | ||
882 | |||
883 | case GNUNET_TESTBED_ET_OPERATION_FINISHED: | ||
884 | break; | ||
885 | |||
886 | default: | ||
887 | GNUNET_break (0); | ||
888 | GNUNET_SCHEDULER_shutdown (); | ||
889 | } | ||
890 | } | ||
891 | |||
892 | |||
893 | struct BenchmarkPeer * | ||
894 | GNUNET_ATS_TEST_get_peer (int src) | ||
895 | { | ||
896 | if (src > top->num_masters) | ||
897 | return NULL; | ||
898 | return &top->mps[src]; | ||
899 | } | ||
900 | |||
901 | |||
902 | struct BenchmarkPartner * | ||
903 | GNUNET_ATS_TEST_get_partner (int src, | ||
904 | int dest) | ||
905 | { | ||
906 | if (src > top->num_masters) | ||
907 | return NULL; | ||
908 | if (dest > top->num_slaves) | ||
909 | return NULL; | ||
910 | return &top->mps[src].partners[dest]; | ||
911 | } | ||
912 | |||
913 | |||
914 | /** | ||
915 | * Create a topology for ats testing | ||
916 | * | ||
917 | * @param name test name | ||
918 | * @param cfg_file configuration file to use for the peers | ||
919 | * @param num_slaves number of slaves | ||
920 | * @param num_masters number of masters | ||
921 | * @param test_core connect to CORE service (GNUNET_YES) or transport (GNUNET_NO) | ||
922 | * @param done_cb function to call when topology is setup | ||
923 | * @param done_cb_cls cls for callback | ||
924 | * @param log_request_cb callback to call when logging is required | ||
925 | */ | ||
926 | void | ||
927 | GNUNET_ATS_TEST_create_topology (char *name, char *cfg_file, | ||
928 | unsigned int num_slaves, | ||
929 | unsigned int num_masters, | ||
930 | int test_core, | ||
931 | GNUNET_ATS_TEST_TopologySetupDoneCallback | ||
932 | done_cb, | ||
933 | void *done_cb_cls, | ||
934 | GNUNET_ATS_AddressInformationCallback | ||
935 | log_request_cb) | ||
936 | { | ||
937 | top = GNUNET_new (struct GNUNET_ATS_TEST_Topology); | ||
938 | top->num_masters = num_masters; | ||
939 | top->num_slaves = num_slaves; | ||
940 | top->done_cb = done_cb; | ||
941 | top->done_cb_cls = done_cb_cls; | ||
942 | top->test_core = test_core; | ||
943 | top->ats_perf_cb = log_request_cb; | ||
944 | top->mps = GNUNET_new_array (num_masters, | ||
945 | struct BenchmarkPeer); | ||
946 | top->sps = GNUNET_new_array (num_slaves, | ||
947 | struct BenchmarkPeer); | ||
948 | |||
949 | /* Start topology */ | ||
950 | uint64_t event_mask; | ||
951 | event_mask = 0; | ||
952 | event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT); | ||
953 | event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED); | ||
954 | (void) GNUNET_TESTBED_test_run (name, | ||
955 | cfg_file, | ||
956 | num_slaves + num_masters, | ||
957 | event_mask, | ||
958 | &controller_event_cb, NULL, | ||
959 | &main_run, NULL); | ||
960 | } | ||
961 | |||
962 | |||
963 | /** | ||
964 | * Shutdown topology | ||
965 | */ | ||
966 | void | ||
967 | GNUNET_ATS_TEST_shutdown_topology (void) | ||
968 | { | ||
969 | if (NULL == top) | ||
970 | return; | ||
971 | GNUNET_SCHEDULER_shutdown (); | ||
972 | } | ||
973 | |||
974 | |||
975 | /* end of file ats-testing.c */ | ||