ats-testing.c 27 KB

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