diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2014-01-21 15:22:09 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2014-01-21 15:22:09 +0000 |
commit | 1f3f45c08b82899a5350633dc6f1030216a1e150 (patch) | |
tree | 1536f4ed581eed1139eb8a81663038c548dea038 /src/ats-tests/ats-testing.c | |
parent | 42d205bed7f300dbc9fa4e97bb88b35321552a89 (diff) | |
download | gnunet-1f3f45c08b82899a5350633dc6f1030216a1e150.tar.gz gnunet-1f3f45c08b82899a5350633dc6f1030216a1e150.zip |
initial preliminary commit for ats testing lib and simulator tool
Diffstat (limited to 'src/ats-tests/ats-testing.c')
-rw-r--r-- | src/ats-tests/ats-testing.c | 814 |
1 files changed, 814 insertions, 0 deletions
diff --git a/src/ats-tests/ats-testing.c b/src/ats-tests/ats-testing.c new file mode 100644 index 000000000..5289c4ae7 --- /dev/null +++ b/src/ats-tests/ats-testing.c | |||
@@ -0,0 +1,814 @@ | |||
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 | #include "ats-testing.h" | ||
32 | |||
33 | |||
34 | |||
35 | |||
36 | static struct GNUNET_ATS_TEST_Topology *top; | ||
37 | |||
38 | /** | ||
39 | * Shutdown nicely | ||
40 | * | ||
41 | * @param cls NULL | ||
42 | * @param tc the task context | ||
43 | */ | ||
44 | static void | ||
45 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
46 | { | ||
47 | int c_m; | ||
48 | int c_s; | ||
49 | int c_op; | ||
50 | struct BenchmarkPeer *p; | ||
51 | /* | ||
52 | if (GNUNET_YES == logging) | ||
53 | perf_logging_stop(); | ||
54 | */ | ||
55 | top->shutdown_task = GNUNET_SCHEDULER_NO_TASK; | ||
56 | /* | ||
57 | if (GNUNET_SCHEDULER_NO_TASK != progress_task) | ||
58 | { | ||
59 | fprintf (stderr, "0\n"); | ||
60 | GNUNET_SCHEDULER_cancel (progress_task); | ||
61 | } | ||
62 | progress_task = GNUNET_SCHEDULER_NO_TASK; | ||
63 | */ | ||
64 | //evaluate (); | ||
65 | |||
66 | top->state.benchmarking = GNUNET_NO; | ||
67 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Benchmarking done\n")); | ||
68 | |||
69 | for (c_m = 0; c_m < top->num_masters; c_m++) | ||
70 | { | ||
71 | p = &top->mps[c_m]; | ||
72 | if (NULL != top->mps[c_m].peer_id_op) | ||
73 | { | ||
74 | GNUNET_TESTBED_operation_done (p->peer_id_op); | ||
75 | p->peer_id_op = NULL; | ||
76 | } | ||
77 | |||
78 | if (GNUNET_SCHEDULER_NO_TASK != p->ats_task) | ||
79 | GNUNET_SCHEDULER_cancel (p->ats_task); | ||
80 | p->ats_task = GNUNET_SCHEDULER_NO_TASK; | ||
81 | |||
82 | for (c_op = 0; c_op < p->num_partners; c_op++) | ||
83 | { | ||
84 | if (NULL != p->partners[c_op].cth) | ||
85 | { | ||
86 | GNUNET_CORE_notify_transmit_ready_cancel (p->partners[c_op].cth); | ||
87 | p->partners[c_op].cth = NULL; | ||
88 | } | ||
89 | if (NULL != p->partners[c_op].tth) | ||
90 | { | ||
91 | GNUNET_TRANSPORT_notify_transmit_ready_cancel (p->partners[c_op].tth); | ||
92 | p->partners[c_op].tth = NULL; | ||
93 | } | ||
94 | if ( (NULL != p->core_connect_ops) && | ||
95 | (NULL != p->core_connect_ops[c_op].connect_op) ) | ||
96 | { | ||
97 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
98 | _("Failed to connect peer 0 and %u\n"), c_op); | ||
99 | GNUNET_TESTBED_operation_done ( | ||
100 | p->core_connect_ops[c_op].connect_op); | ||
101 | p->core_connect_ops[c_op].connect_op = NULL; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | if (NULL != p->ats_perf_op) | ||
106 | { | ||
107 | GNUNET_TESTBED_operation_done (p->ats_perf_op); | ||
108 | p->ats_perf_op = NULL; | ||
109 | } | ||
110 | |||
111 | if (NULL != p->comm_op) | ||
112 | { | ||
113 | GNUNET_TESTBED_operation_done (p->comm_op); | ||
114 | p->comm_op = NULL; | ||
115 | } | ||
116 | GNUNET_free_non_null (p->core_connect_ops); | ||
117 | GNUNET_free(p->partners); | ||
118 | p->partners = NULL; | ||
119 | } | ||
120 | |||
121 | for (c_s = 0; c_s < top->num_slaves; c_s++) | ||
122 | { | ||
123 | p = &top->sps[c_s]; | ||
124 | if (NULL != p->peer_id_op) | ||
125 | { | ||
126 | GNUNET_TESTBED_operation_done (p->peer_id_op); | ||
127 | p->peer_id_op = NULL; | ||
128 | } | ||
129 | |||
130 | for (c_op = 0; c_op < p->num_partners; c_op++) | ||
131 | { | ||
132 | if (NULL != p->partners[c_op].cth) | ||
133 | { | ||
134 | GNUNET_CORE_notify_transmit_ready_cancel (p->partners[c_op].cth); | ||
135 | p->partners[c_op].cth = NULL; | ||
136 | } | ||
137 | if (NULL != p->partners[c_op].tth) | ||
138 | { | ||
139 | GNUNET_TRANSPORT_notify_transmit_ready_cancel (p->partners[c_op].tth); | ||
140 | p->partners[c_op].tth = NULL; | ||
141 | } | ||
142 | } | ||
143 | if (NULL != p->ats_perf_op) | ||
144 | { | ||
145 | GNUNET_TESTBED_operation_done (p->ats_perf_op); | ||
146 | p->ats_perf_op = NULL; | ||
147 | } | ||
148 | if (NULL != p->comm_op) | ||
149 | { | ||
150 | GNUNET_TESTBED_operation_done (p->comm_op); | ||
151 | p->comm_op = NULL; | ||
152 | } | ||
153 | GNUNET_free(p->partners); | ||
154 | p->partners = NULL; | ||
155 | } | ||
156 | |||
157 | GNUNET_SCHEDULER_shutdown (); | ||
158 | } | ||
159 | |||
160 | static struct BenchmarkPartner * | ||
161 | find_partner (struct BenchmarkPeer *me, const struct GNUNET_PeerIdentity * peer) | ||
162 | { | ||
163 | int c_m; | ||
164 | GNUNET_assert (NULL != me); | ||
165 | GNUNET_assert (NULL != peer); | ||
166 | |||
167 | for (c_m = 0; c_m < me->num_partners; c_m++) | ||
168 | { | ||
169 | /* Find a partner with other as destination */ | ||
170 | if (0 == memcmp (peer, &me->partners[c_m].dest->id, | ||
171 | sizeof(struct GNUNET_PeerIdentity))) | ||
172 | { | ||
173 | return &me->partners[c_m]; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | return NULL; | ||
178 | } | ||
179 | |||
180 | |||
181 | static struct BenchmarkPeer * | ||
182 | find_peer (const struct GNUNET_PeerIdentity * peer) | ||
183 | { | ||
184 | int c_p; | ||
185 | |||
186 | for (c_p = 0; c_p < top->num_masters; c_p++) | ||
187 | { | ||
188 | if (0 == memcmp (&top->mps[c_p].id, peer, sizeof(struct GNUNET_PeerIdentity))) | ||
189 | return &top->mps[c_p]; | ||
190 | } | ||
191 | |||
192 | for (c_p = 0; c_p < top->num_slaves; c_p++) | ||
193 | { | ||
194 | if (0 == memcmp (&top->sps[c_p].id, peer, sizeof(struct GNUNET_PeerIdentity))) | ||
195 | return &top->sps[c_p]; | ||
196 | } | ||
197 | return NULL ; | ||
198 | } | ||
199 | |||
200 | |||
201 | /** | ||
202 | * Method called whenever a given peer connects. | ||
203 | * | ||
204 | * @param cls closure | ||
205 | * @param peer peer identity this notification is about | ||
206 | */ | ||
207 | static void | ||
208 | comm_connect_cb (void *cls, const struct GNUNET_PeerIdentity * peer) | ||
209 | { | ||
210 | struct BenchmarkPeer *me = cls; | ||
211 | struct BenchmarkPeer *remote; | ||
212 | char *id; | ||
213 | int c; | ||
214 | int completed; | ||
215 | |||
216 | remote = find_peer (peer); | ||
217 | if (NULL == remote) | ||
218 | { | ||
219 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Unknown peer connected: `%s'\n", GNUNET_i2s (peer)); | ||
220 | GNUNET_break(0); | ||
221 | return; | ||
222 | } | ||
223 | |||
224 | id = GNUNET_strdup (GNUNET_i2s (&me->id)); | ||
225 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s [%u] `%s' connected to %s [%u] %s\n", | ||
226 | (me->master == GNUNET_YES) ? "Master": "Slave", me->no, id, | ||
227 | (remote->master == GNUNET_YES) ? "Master": "Slave", remote->no, | ||
228 | GNUNET_i2s (peer)); | ||
229 | |||
230 | me->core_connections++; | ||
231 | if ((GNUNET_YES == me->master) && (GNUNET_NO == remote->master) | ||
232 | && (GNUNET_NO == top->state.connected_CORE)) | ||
233 | { | ||
234 | me->core_slave_connections++; | ||
235 | |||
236 | if (me->core_slave_connections == top->num_slaves) | ||
237 | { | ||
238 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Master [%u] connected all slaves\n", | ||
239 | me->no); | ||
240 | } | ||
241 | completed = GNUNET_YES; | ||
242 | for (c = 0; c < top->num_masters; c++) | ||
243 | { | ||
244 | if (top->mps[c].core_slave_connections != top->num_slaves) | ||
245 | completed = GNUNET_NO; | ||
246 | } | ||
247 | if (GNUNET_YES == completed) | ||
248 | { | ||
249 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
250 | "All master peers connected all slave peers\n", id, | ||
251 | GNUNET_i2s (peer)); | ||
252 | top->state.connected_CORE = GNUNET_YES; | ||
253 | GNUNET_break (0); | ||
254 | //GNUNET_SCHEDULER_add_now (&do_benchmark, NULL ); | ||
255 | } | ||
256 | } | ||
257 | GNUNET_free(id); | ||
258 | } | ||
259 | |||
260 | static void | ||
261 | comm_disconnect_cb (void *cls, const struct GNUNET_PeerIdentity * peer) | ||
262 | { | ||
263 | struct BenchmarkPeer *me = cls; | ||
264 | struct BenchmarkPartner *p; | ||
265 | char *id; | ||
266 | |||
267 | if (NULL == (p = find_partner (me, peer))) | ||
268 | return; | ||
269 | |||
270 | id = GNUNET_strdup (GNUNET_i2s (&me->id)); | ||
271 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s disconnected from %s \n", id, | ||
272 | GNUNET_i2s (peer)); | ||
273 | GNUNET_assert(me->core_connections > 0); | ||
274 | me->core_connections--; | ||
275 | |||
276 | if ((GNUNET_YES == top->state.benchmarking) | ||
277 | && ((GNUNET_YES == me->master) || (GNUNET_YES == p->dest->master))) | ||
278 | { | ||
279 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
280 | "%s disconnected from %s while benchmarking \n", id, GNUNET_i2s (peer)); | ||
281 | if (NULL != p->tth) | ||
282 | { | ||
283 | GNUNET_TRANSPORT_notify_transmit_ready_cancel (p->tth); | ||
284 | p->tth = NULL; | ||
285 | } | ||
286 | if (NULL != p->cth) | ||
287 | { | ||
288 | GNUNET_CORE_notify_transmit_ready_cancel (p->cth); | ||
289 | p->cth = NULL; | ||
290 | } | ||
291 | } | ||
292 | GNUNET_free(id); | ||
293 | } | ||
294 | |||
295 | |||
296 | static void * | ||
297 | core_connect_adapter (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
298 | { | ||
299 | struct BenchmarkPeer *me = cls; | ||
300 | |||
301 | me->ch = GNUNET_CORE_connect (cfg, me, NULL, comm_connect_cb, | ||
302 | comm_disconnect_cb, NULL, GNUNET_NO, NULL, GNUNET_NO, top->handlers); | ||
303 | if (NULL == me->ch) | ||
304 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to create core connection \n"); | ||
305 | return me->ch; | ||
306 | } | ||
307 | |||
308 | static void | ||
309 | core_disconnect_adapter (void *cls, void *op_result) | ||
310 | { | ||
311 | struct BenchmarkPeer *me = cls; | ||
312 | |||
313 | GNUNET_CORE_disconnect (me->ch); | ||
314 | me->ch = NULL; | ||
315 | } | ||
316 | |||
317 | |||
318 | static void * | ||
319 | transport_connect_adapter (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
320 | { | ||
321 | struct BenchmarkPeer *me = cls; | ||
322 | |||
323 | me->th = GNUNET_TRANSPORT_connect (cfg, &me->id, me, top->transport_recv_cb, | ||
324 | &comm_connect_cb, &comm_disconnect_cb); | ||
325 | if (NULL == me->th) | ||
326 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to create transport connection \n"); | ||
327 | return me->th; | ||
328 | } | ||
329 | |||
330 | static void | ||
331 | transport_disconnect_adapter (void *cls, void *op_result) | ||
332 | { | ||
333 | struct BenchmarkPeer *me = cls; | ||
334 | |||
335 | GNUNET_TRANSPORT_disconnect (me->th); | ||
336 | me->th = NULL; | ||
337 | } | ||
338 | |||
339 | |||
340 | static void | ||
341 | connect_completion_callback (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
342 | const char *emsg) | ||
343 | { | ||
344 | struct TestbedConnectOperation *cop = cls; | ||
345 | static int ops = 0; | ||
346 | int c; | ||
347 | if (NULL == emsg) | ||
348 | { | ||
349 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
350 | _("Connected master [%u] with slave [%u]\n"), cop->master->no, | ||
351 | cop->slave->no); | ||
352 | } | ||
353 | else | ||
354 | { | ||
355 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
356 | _("Failed to connect master peer [%u] with slave [%u]\n"), | ||
357 | cop->master->no, cop->slave->no); | ||
358 | GNUNET_break(0); | ||
359 | if (GNUNET_SCHEDULER_NO_TASK != top->shutdown_task) | ||
360 | GNUNET_SCHEDULER_cancel (top->shutdown_task); | ||
361 | top->shutdown_task = GNUNET_SCHEDULER_add_now (do_shutdown, NULL ); | ||
362 | } | ||
363 | GNUNET_TESTBED_operation_done (op); | ||
364 | ops++; | ||
365 | for (c = 0; c < top->num_slaves; c++) | ||
366 | { | ||
367 | if (cop == &cop->master->core_connect_ops[c]) | ||
368 | cop->master->core_connect_ops[c].connect_op = NULL; | ||
369 | } | ||
370 | if (ops == top->num_masters * top->num_slaves) | ||
371 | { | ||
372 | top->state.connected_PEERS = GNUNET_YES; | ||
373 | GNUNET_break (0); | ||
374 | //GNUNET_SCHEDULER_add_now (&do_benchmark, NULL ); | ||
375 | } | ||
376 | } | ||
377 | |||
378 | static void | ||
379 | do_connect_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
380 | { | ||
381 | int c_m; | ||
382 | int c_s; | ||
383 | struct BenchmarkPeer *p; | ||
384 | |||
385 | if ((top->state.connected_ATS_service == GNUNET_NO) || | ||
386 | (top->state.connected_COMM_service == GNUNET_NO)) | ||
387 | return; | ||
388 | |||
389 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Connecting peers on CORE level\n")); | ||
390 | |||
391 | for (c_m = 0; c_m < top->num_masters; c_m++) | ||
392 | { | ||
393 | p = &top->mps[c_m]; | ||
394 | p->core_connect_ops = GNUNET_malloc (top->num_slaves * | ||
395 | sizeof (struct TestbedConnectOperation)); | ||
396 | |||
397 | for (c_s = 0; c_s < top->num_slaves; c_s++) | ||
398 | { | ||
399 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
400 | _("Connecting master [%u] with slave [%u]\n"), p->no, top->sps[c_s].no); | ||
401 | p->core_connect_ops[c_s].master = p; | ||
402 | p->core_connect_ops[c_s].slave = &top->sps[c_s]; | ||
403 | p->core_connect_ops[c_s].connect_op = GNUNET_TESTBED_overlay_connect ( | ||
404 | NULL, &connect_completion_callback, &p->core_connect_ops[c_s], | ||
405 | top->sps[c_s].peer, p->peer); | ||
406 | if (NULL == p->core_connect_ops[c_s].connect_op) | ||
407 | { | ||
408 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
409 | _("Could not connect master [%u] and slave [%u]\n"), p->no, | ||
410 | top->sps[c_s].no); | ||
411 | GNUNET_break(0); | ||
412 | if (GNUNET_SCHEDULER_NO_TASK != top->shutdown_task) | ||
413 | GNUNET_SCHEDULER_cancel (top->shutdown_task); | ||
414 | top->shutdown_task = GNUNET_SCHEDULER_add_now (do_shutdown, NULL ); | ||
415 | return; | ||
416 | } | ||
417 | } | ||
418 | } | ||
419 | } | ||
420 | |||
421 | |||
422 | static void | ||
423 | comm_connect_completion_cb (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
424 | void *ca_result, const char *emsg) | ||
425 | { | ||
426 | static int comm_done = 0; | ||
427 | if ((NULL != emsg) || (NULL == ca_result)) | ||
428 | { | ||
429 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Initialization failed, shutdown\n")); | ||
430 | GNUNET_break(0); | ||
431 | if (GNUNET_SCHEDULER_NO_TASK != top->shutdown_task) | ||
432 | GNUNET_SCHEDULER_cancel (top->shutdown_task); | ||
433 | top->shutdown_task = GNUNET_SCHEDULER_add_now (do_shutdown, NULL ); | ||
434 | return; | ||
435 | } | ||
436 | comm_done++; | ||
437 | |||
438 | if (comm_done == top->num_slaves + top->num_masters) | ||
439 | { | ||
440 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Connected to all %s services\n", | ||
441 | (GNUNET_YES == top->test_core) ? "CORE" : "TRANSPORT"); | ||
442 | top->state.connected_COMM_service = GNUNET_YES; | ||
443 | GNUNET_break (0); | ||
444 | GNUNET_SCHEDULER_add_now (&do_connect_peers, NULL ); | ||
445 | } | ||
446 | } | ||
447 | |||
448 | static void | ||
449 | do_comm_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
450 | { | ||
451 | int c_s; | ||
452 | int c_m; | ||
453 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Connecting to all %s services\n", | ||
454 | (GNUNET_YES == top->test_core) ? "CORE" : "TRANSPORT"); | ||
455 | for (c_m = 0; c_m < top->num_masters; c_m++) | ||
456 | { | ||
457 | if (GNUNET_YES == top->test_core) | ||
458 | top->mps[c_m].comm_op = GNUNET_TESTBED_service_connect (NULL, top->mps[c_m].peer, | ||
459 | "core", &comm_connect_completion_cb, NULL, &core_connect_adapter, | ||
460 | &core_disconnect_adapter, &top->mps[c_m]); | ||
461 | else | ||
462 | { | ||
463 | top->mps[c_m].comm_op = GNUNET_TESTBED_service_connect (NULL, top->mps[c_m].peer, | ||
464 | "transport", &comm_connect_completion_cb, NULL, &transport_connect_adapter, | ||
465 | &transport_disconnect_adapter, &top->mps[c_m]); | ||
466 | } | ||
467 | } | ||
468 | |||
469 | for (c_s = 0; c_s < top->num_slaves; c_s++) | ||
470 | { | ||
471 | if (GNUNET_YES == top->test_core) | ||
472 | top->sps[c_s].comm_op = GNUNET_TESTBED_service_connect (NULL, top->sps[c_s].peer, | ||
473 | "core", &comm_connect_completion_cb, NULL, &core_connect_adapter, | ||
474 | &core_disconnect_adapter, &top->sps[c_s]); | ||
475 | else | ||
476 | { | ||
477 | top->sps[c_s].comm_op = GNUNET_TESTBED_service_connect (NULL, top->sps[c_s].peer, | ||
478 | "transport", &comm_connect_completion_cb, NULL, &transport_connect_adapter, | ||
479 | &transport_disconnect_adapter, &top->sps[c_s]); | ||
480 | } | ||
481 | } | ||
482 | } | ||
483 | |||
484 | |||
485 | |||
486 | static void | ||
487 | ats_performance_info_cb (void *cls, const struct GNUNET_HELLO_Address *address, | ||
488 | int address_active, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, | ||
489 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, | ||
490 | const struct GNUNET_ATS_Information *ats, uint32_t ats_count) | ||
491 | { | ||
492 | struct BenchmarkPeer *me = cls; | ||
493 | struct BenchmarkPartner *p; | ||
494 | int c_a; | ||
495 | int log; | ||
496 | char *peer_id; | ||
497 | |||
498 | p = find_partner (me, &address->peer); | ||
499 | if (NULL == p) | ||
500 | { | ||
501 | /* This is not one of my partners | ||
502 | * Will happen since the peers will connect to each other due to gossiping | ||
503 | */ | ||
504 | return; | ||
505 | } | ||
506 | peer_id = GNUNET_strdup (GNUNET_i2s (&me->id)); | ||
507 | |||
508 | log = GNUNET_NO; | ||
509 | if ((p->bandwidth_in != ntohl (bandwidth_in.value__)) || | ||
510 | (p->bandwidth_out != ntohl (bandwidth_out.value__))) | ||
511 | log = GNUNET_YES; | ||
512 | p->bandwidth_in = ntohl (bandwidth_in.value__); | ||
513 | p->bandwidth_out = ntohl (bandwidth_out.value__); | ||
514 | |||
515 | for (c_a = 0; c_a < ats_count; c_a++) | ||
516 | { | ||
517 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s [%u] received ATS information: %s %s %u\n", | ||
518 | (GNUNET_YES == p->me->master) ? "Master" : "Slave", | ||
519 | p->me->no, | ||
520 | GNUNET_i2s (&p->dest->id), | ||
521 | GNUNET_ATS_print_property_type(ntohl(ats[c_a].type)), | ||
522 | ntohl(ats[c_a].value)); | ||
523 | switch (ntohl (ats[c_a].type )) | ||
524 | { | ||
525 | case GNUNET_ATS_ARRAY_TERMINATOR: | ||
526 | break; | ||
527 | case GNUNET_ATS_UTILIZATION_OUT: | ||
528 | if (p->ats_utilization_up != ntohl (ats[c_a].value)) | ||
529 | log = GNUNET_YES; | ||
530 | p->ats_utilization_up = ntohl (ats[c_a].value); | ||
531 | |||
532 | break; | ||
533 | case GNUNET_ATS_UTILIZATION_IN: | ||
534 | if (p->ats_utilization_down != ntohl (ats[c_a].value)) | ||
535 | log = GNUNET_YES; | ||
536 | p->ats_utilization_down = ntohl (ats[c_a].value); | ||
537 | break; | ||
538 | case GNUNET_ATS_NETWORK_TYPE: | ||
539 | if (p->ats_network_type != ntohl (ats[c_a].value)) | ||
540 | log = GNUNET_YES; | ||
541 | p->ats_network_type = ntohl (ats[c_a].value); | ||
542 | break; | ||
543 | case GNUNET_ATS_QUALITY_NET_DELAY: | ||
544 | if (p->ats_delay != ntohl (ats[c_a].value)) | ||
545 | log = GNUNET_YES; | ||
546 | p->ats_delay = ntohl (ats[c_a].value); | ||
547 | break; | ||
548 | case GNUNET_ATS_QUALITY_NET_DISTANCE: | ||
549 | if (p->ats_distance != ntohl (ats[c_a].value)) | ||
550 | log = GNUNET_YES; | ||
551 | p->ats_distance = ntohl (ats[c_a].value); | ||
552 | GNUNET_break (0); | ||
553 | break; | ||
554 | case GNUNET_ATS_COST_WAN: | ||
555 | if (p->ats_cost_wan != ntohl (ats[c_a].value)) | ||
556 | log = GNUNET_YES; | ||
557 | p->ats_cost_wan = ntohl (ats[c_a].value); | ||
558 | break; | ||
559 | case GNUNET_ATS_COST_LAN: | ||
560 | if (p->ats_cost_lan != ntohl (ats[c_a].value)) | ||
561 | log = GNUNET_YES; | ||
562 | p->ats_cost_lan = ntohl (ats[c_a].value); | ||
563 | break; | ||
564 | case GNUNET_ATS_COST_WLAN: | ||
565 | if (p->ats_cost_wlan != ntohl (ats[c_a].value)) | ||
566 | log = GNUNET_YES; | ||
567 | p->ats_cost_wlan = ntohl (ats[c_a].value); | ||
568 | break; | ||
569 | default: | ||
570 | break; | ||
571 | } | ||
572 | } | ||
573 | if ((GNUNET_YES == top->logging) && (GNUNET_YES == log)) | ||
574 | { | ||
575 | // collect_log_now(); | ||
576 | } | ||
577 | GNUNET_free(peer_id); | ||
578 | } | ||
579 | |||
580 | |||
581 | static void * | ||
582 | ats_perf_connect_adapter (void *cls, | ||
583 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
584 | { | ||
585 | struct BenchmarkPeer *me = cls; | ||
586 | |||
587 | me->ats_perf_handle = GNUNET_ATS_performance_init (cfg, | ||
588 | &ats_performance_info_cb, me); | ||
589 | if (NULL == me->ats_perf_handle) | ||
590 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
591 | "Failed to create ATS performance handle \n"); | ||
592 | return me->ats_perf_handle; | ||
593 | } | ||
594 | |||
595 | static void | ||
596 | ats_perf_disconnect_adapter (void *cls, void *op_result) | ||
597 | { | ||
598 | struct BenchmarkPeer *me = cls; | ||
599 | |||
600 | GNUNET_ATS_performance_done (me->ats_perf_handle); | ||
601 | me->ats_perf_handle = NULL; | ||
602 | } | ||
603 | |||
604 | static void | ||
605 | ats_connect_completion_cb (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
606 | void *ca_result, const char *emsg) | ||
607 | { | ||
608 | static int op_done = 0; | ||
609 | |||
610 | if ((NULL != emsg) || (NULL == ca_result)) | ||
611 | { | ||
612 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Initialization failed, shutdown\n")); | ||
613 | GNUNET_break(0); | ||
614 | if (GNUNET_SCHEDULER_NO_TASK != top->shutdown_task) | ||
615 | GNUNET_SCHEDULER_cancel (top->shutdown_task); | ||
616 | top->shutdown_task = GNUNET_SCHEDULER_add_now (do_shutdown, NULL ); | ||
617 | return; | ||
618 | } | ||
619 | op_done++; | ||
620 | if (op_done == (top->num_masters + top->num_slaves)) | ||
621 | { | ||
622 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Connected to all ATS services\n"); | ||
623 | top->state.connected_ATS_service = GNUNET_YES; | ||
624 | GNUNET_SCHEDULER_add_now (&do_comm_connect, NULL ); | ||
625 | } | ||
626 | } | ||
627 | |||
628 | |||
629 | static void | ||
630 | do_connect_ats (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
631 | { | ||
632 | int c_m; | ||
633 | int c_s; | ||
634 | |||
635 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Connecting to all ATS services\n"); | ||
636 | for (c_m = 0; c_m < top->num_masters; c_m++) | ||
637 | { | ||
638 | top->mps[c_m].ats_perf_op = GNUNET_TESTBED_service_connect (NULL, | ||
639 | top->mps[c_m].peer, | ||
640 | "ats", ats_connect_completion_cb, NULL, | ||
641 | &ats_perf_connect_adapter, | ||
642 | &ats_perf_disconnect_adapter, &top->mps[c_m]); | ||
643 | } | ||
644 | |||
645 | for (c_s = 0; c_s < top->num_slaves; c_s++) | ||
646 | { | ||
647 | top->sps[c_s].ats_perf_op = GNUNET_TESTBED_service_connect (NULL, top->sps[c_s].peer, | ||
648 | "ats", ats_connect_completion_cb, NULL, &ats_perf_connect_adapter, | ||
649 | &ats_perf_disconnect_adapter, &top->sps[c_s]); | ||
650 | } | ||
651 | } | ||
652 | |||
653 | |||
654 | |||
655 | static void | ||
656 | peerinformation_cb (void *cb_cls, struct GNUNET_TESTBED_Operation *op, | ||
657 | const struct GNUNET_TESTBED_PeerInformation*pinfo, const char *emsg) | ||
658 | { | ||
659 | struct BenchmarkPeer *p = cb_cls; | ||
660 | static int done = 0; | ||
661 | |||
662 | GNUNET_assert(pinfo->pit == GNUNET_TESTBED_PIT_IDENTITY); | ||
663 | |||
664 | p->id = *pinfo->result.id; | ||
665 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "%s [%u] has peer id `%s'\n", | ||
666 | (p->master == GNUNET_YES) ? "Master" : "Slave", p->no, | ||
667 | GNUNET_i2s (&p->id)); | ||
668 | |||
669 | GNUNET_TESTBED_operation_done (op); | ||
670 | p->peer_id_op = NULL; | ||
671 | done++; | ||
672 | |||
673 | if (done == top->num_slaves + top->num_masters) | ||
674 | { | ||
675 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
676 | "Retrieved all peer ID, connect to ATS\n"); | ||
677 | GNUNET_SCHEDULER_add_now (&do_connect_ats, NULL ); | ||
678 | } | ||
679 | } | ||
680 | |||
681 | /** | ||
682 | * Signature of a main function for a testcase. | ||
683 | * | ||
684 | * @param cls closure | ||
685 | * @param num_peers number of peers in 'peers' | ||
686 | * @param peers_ handle to peers run in the testbed | ||
687 | * @param links_succeeded the number of overlay link connection attempts that | ||
688 | * succeeded | ||
689 | * @param links_failed the number of overlay link connection attempts that | ||
690 | * failed | ||
691 | */ | ||
692 | static void | ||
693 | main_run (void *cls, struct GNUNET_TESTBED_RunHandle *h, | ||
694 | unsigned int num_peers, | ||
695 | struct GNUNET_TESTBED_Peer **peers_, | ||
696 | unsigned int links_succeeded, | ||
697 | unsigned int links_failed) | ||
698 | { | ||
699 | int c_m; | ||
700 | int c_s; | ||
701 | GNUNET_assert(NULL == cls); | ||
702 | GNUNET_assert(top->num_masters + top->num_slaves == num_peers); | ||
703 | GNUNET_assert(NULL != peers_); | ||
704 | |||
705 | top->shutdown_task = GNUNET_SCHEDULER_add_delayed ( | ||
706 | GNUNET_TIME_relative_multiply (TEST_TIMEOUT, top->num_masters + top->num_slaves), | ||
707 | &do_shutdown, top ); | ||
708 | |||
709 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Setting up %u masters and %u slaves\n", | ||
710 | top->num_masters, top->num_slaves); | ||
711 | |||
712 | /* Setup master peers */ | ||
713 | for (c_m = 0; c_m < top->num_masters; c_m++) | ||
714 | { | ||
715 | GNUNET_assert(NULL != peers_[c_m]); | ||
716 | top->mps[c_m].peer = peers_[c_m]; | ||
717 | top->mps[c_m].no = c_m; | ||
718 | top->mps[c_m].master = GNUNET_YES; | ||
719 | top->mps[c_m].pref_partner = &top->sps[c_m]; | ||
720 | top->mps[c_m].pref_value = TEST_ATS_PREFRENCE_START; | ||
721 | top->mps[c_m].partners = | ||
722 | GNUNET_malloc (top->num_slaves * sizeof (struct BenchmarkPartner)); | ||
723 | top->mps[c_m].num_partners = top->num_slaves; | ||
724 | /* Initialize partners */ | ||
725 | for (c_s = 0; c_s < top->num_slaves; c_s++) | ||
726 | { | ||
727 | top->mps[c_m].partners[c_s].me = &top->mps[c_m]; | ||
728 | top->mps[c_m].partners[c_s].dest = &top->sps[c_s]; | ||
729 | } | ||
730 | /* Get configuration */ | ||
731 | top->mps[c_m].peer_id_op = GNUNET_TESTBED_peer_get_information (top->mps[c_m].peer, | ||
732 | GNUNET_TESTBED_PIT_IDENTITY, &peerinformation_cb, &top->mps[c_m]); | ||
733 | } | ||
734 | |||
735 | /* Setup slave peers */ | ||
736 | for (c_s = 0; c_s < top->num_slaves; c_s++) | ||
737 | { | ||
738 | GNUNET_assert(NULL != peers_[c_s + top->num_masters]); | ||
739 | top->sps[c_s].peer = peers_[c_s + top->num_masters]; | ||
740 | top->sps[c_s].no = c_s + top->num_masters; | ||
741 | top->sps[c_s].master = GNUNET_NO; | ||
742 | top->sps[c_s].partners = | ||
743 | GNUNET_malloc (top->num_masters * sizeof (struct BenchmarkPartner)); | ||
744 | top->sps[c_s].num_partners = top->num_masters; | ||
745 | /* Initialize partners */ | ||
746 | for (c_m = 0; c_m < top->num_masters; c_m++) | ||
747 | { | ||
748 | top->sps[c_s].partners[c_m].me = &top->sps[c_s]; | ||
749 | top->sps[c_s].partners[c_m].dest = &top->mps[c_m]; | ||
750 | } | ||
751 | /* Get configuration */ | ||
752 | top->sps[c_s].peer_id_op = GNUNET_TESTBED_peer_get_information (top->sps[c_s].peer, | ||
753 | GNUNET_TESTBED_PIT_IDENTITY, &peerinformation_cb, &top->sps[c_s]); | ||
754 | } | ||
755 | } | ||
756 | |||
757 | /** | ||
758 | * Controller event callback | ||
759 | * | ||
760 | * @param cls NULL | ||
761 | * @param event the controller event | ||
762 | */ | ||
763 | static void | ||
764 | controller_event_cb (void *cls, | ||
765 | const struct GNUNET_TESTBED_EventInformation *event) | ||
766 | { | ||
767 | struct GNUNET_ATS_TEST_Topology *top = cls; | ||
768 | switch (event->type) | ||
769 | { | ||
770 | case GNUNET_TESTBED_ET_CONNECT: | ||
771 | break; | ||
772 | case GNUNET_TESTBED_ET_OPERATION_FINISHED: | ||
773 | break; | ||
774 | default: | ||
775 | GNUNET_break(0); | ||
776 | GNUNET_SCHEDULER_cancel (top->shutdown_task); | ||
777 | top->shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL ); | ||
778 | } | ||
779 | } | ||
780 | |||
781 | struct GNUNET_ATS_TEST_Topology * | ||
782 | GNUNET_ATS_TEST_create_topology (char *name, char *cfg_file, | ||
783 | unsigned int num_slaves, | ||
784 | unsigned int num_masters, | ||
785 | struct GNUNET_CORE_MessageHandler *handlers, | ||
786 | GNUNET_TRANSPORT_ReceiveCallback transport_recv_cb) | ||
787 | { | ||
788 | top = GNUNET_new (struct GNUNET_ATS_TEST_Topology); | ||
789 | top->num_masters = num_masters; | ||
790 | top->num_slaves = num_slaves; | ||
791 | top->handlers = handlers; | ||
792 | |||
793 | top->mps = GNUNET_malloc (num_masters * sizeof (struct BenchmarkPeer)); | ||
794 | top->sps = GNUNET_malloc (num_slaves * sizeof (struct BenchmarkPeer)); | ||
795 | |||
796 | /* Start topology */ | ||
797 | uint64_t event_mask; | ||
798 | event_mask = 0; | ||
799 | event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT); | ||
800 | event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED); | ||
801 | (void) GNUNET_TESTBED_test_run (name, cfg_file, | ||
802 | num_slaves + num_masters, event_mask, &controller_event_cb, NULL, | ||
803 | &main_run, NULL); | ||
804 | |||
805 | return NULL; | ||
806 | } | ||
807 | |||
808 | void | ||
809 | GNUNET_ATS_TEST_destroy_topology (struct GNUNET_ATS_TEST_Topology *top) | ||
810 | { | ||
811 | |||
812 | } | ||
813 | |||
814 | /* end of file perf_ats.c */ | ||