test_psyc.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. /*
  2. * This file is part of GNUnet
  3. * (C) 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 psyc/test_psyc.c
  22. * @brief Tests for the PSYC API.
  23. * @author Gabor X Toth
  24. * @author Christian Grothoff
  25. */
  26. #include <inttypes.h>
  27. #include "platform.h"
  28. #include "gnunet_crypto_lib.h"
  29. #include "gnunet_common.h"
  30. #include "gnunet_util_lib.h"
  31. #include "gnunet_testing_lib.h"
  32. #include "gnunet_env_lib.h"
  33. #include "gnunet_psyc_util_lib.h"
  34. #include "gnunet_psyc_service.h"
  35. #include "gnunet_core_service.h"
  36. #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
  37. /**
  38. * Return value from 'main'.
  39. */
  40. int res;
  41. const struct GNUNET_CONFIGURATION_Handle *cfg;
  42. struct GNUNET_CORE_Handle *core;
  43. struct GNUNET_PeerIdentity this_peer;
  44. /**
  45. * Handle for task for timeout termination.
  46. */
  47. GNUNET_SCHEDULER_TaskIdentifier end_badly_task;
  48. struct GNUNET_PSYC_Master *mst;
  49. struct GNUNET_PSYC_Slave *slv;
  50. struct GNUNET_PSYC_Channel *mst_chn, *slv_chn;
  51. struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key;
  52. struct GNUNET_CRYPTO_EcdsaPrivateKey *slave_key;
  53. struct GNUNET_CRYPTO_EddsaPublicKey channel_pub_key;
  54. struct GNUNET_CRYPTO_EcdsaPublicKey slave_pub_key;
  55. struct TransmitClosure
  56. {
  57. struct GNUNET_PSYC_MasterTransmitHandle *mst_tmit;
  58. struct GNUNET_PSYC_SlaveTransmitHandle *slv_tmit;
  59. struct GNUNET_ENV_Environment *env;
  60. struct GNUNET_ENV_Modifier *mod;
  61. char *data[16];
  62. const char *mod_value;
  63. size_t mod_value_size;
  64. uint8_t data_delay[16];
  65. uint8_t data_count;
  66. uint8_t paused;
  67. uint8_t n;
  68. };
  69. struct TransmitClosure *tmit;
  70. uint8_t join_req_count;
  71. enum
  72. {
  73. TEST_NONE = 0,
  74. TEST_MASTER_START = 1,
  75. TEST_SLAVE_JOIN = 2,
  76. TEST_SLAVE_TRANSMIT = 3,
  77. TEST_MASTER_TRANSMIT = 4,
  78. TEST_MASTER_HISTORY_REPLAY_LATEST = 5,
  79. TEST_SLAVE_HISTORY_REPLAY_LATEST = 6,
  80. TEST_MASTER_HISTORY_REPLAY = 7,
  81. TEST_SLAVE_HISTORY_REPLAY = 8,
  82. TEST_MASTER_STATE_GET = 9,
  83. TEST_SLAVE_STATE_GET = 10,
  84. TEST_MASTER_STATE_GET_PREFIX = 11,
  85. TEST_SLAVE_STATE_GET_PREFIX = 12,
  86. } test;
  87. void
  88. master_transmit ();
  89. void master_stopped (void *cls)
  90. {
  91. if (NULL != tmit)
  92. {
  93. GNUNET_ENV_environment_destroy (tmit->env);
  94. GNUNET_free (tmit);
  95. tmit = NULL;
  96. }
  97. GNUNET_SCHEDULER_shutdown ();
  98. }
  99. void slave_parted (void *cls)
  100. {
  101. if (NULL != mst)
  102. {
  103. GNUNET_PSYC_master_stop (mst, GNUNET_NO, &master_stopped, NULL);
  104. mst = NULL;
  105. }
  106. else
  107. master_stopped (NULL);
  108. }
  109. /**
  110. * Clean up all resources used.
  111. */
  112. void
  113. cleanup ()
  114. {
  115. if (NULL != core)
  116. {
  117. GNUNET_CORE_disconnect (core);
  118. core = NULL;
  119. }
  120. if (NULL != slv)
  121. {
  122. GNUNET_PSYC_slave_part (slv, GNUNET_NO, &slave_parted, NULL);
  123. slv = NULL;
  124. }
  125. else
  126. slave_parted (NULL);
  127. }
  128. /**
  129. * Terminate the test case (failure).
  130. *
  131. * @param cls NULL
  132. * @param tc scheduler context
  133. */
  134. void
  135. end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  136. {
  137. res = 1;
  138. cleanup ();
  139. GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Test FAILED.\n");
  140. }
  141. /**
  142. * Terminate the test case (success).
  143. *
  144. * @param cls NULL
  145. * @param tc scheduler context
  146. */
  147. void
  148. end_normally (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  149. {
  150. res = 0;
  151. cleanup ();
  152. GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Test PASSED.\n");
  153. }
  154. /**
  155. * Finish the test case (successfully).
  156. */
  157. void
  158. end ()
  159. {
  160. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending tests.\n");
  161. if (end_badly_task != GNUNET_SCHEDULER_NO_TASK)
  162. {
  163. GNUNET_SCHEDULER_cancel (end_badly_task);
  164. end_badly_task = GNUNET_SCHEDULER_NO_TASK;
  165. }
  166. GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
  167. &end_normally, NULL);
  168. }
  169. void
  170. state_get_var (void *cls, const char *name, const void *value, size_t value_size)
  171. {
  172. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  173. "Got state var: %s\n%.*s\n", name, value_size, value);
  174. }
  175. /*** Slave state_get_prefix() ***/
  176. void
  177. slave_state_get_prefix_result (void *cls, int64_t result, const char *err_msg)
  178. {
  179. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  180. "slave_state_get_prefix:\t%" PRId64 " (%s)\n", result, err_msg);
  181. // FIXME: GNUNET_assert (2 == result);
  182. end ();
  183. }
  184. void
  185. slave_state_get_prefix ()
  186. {
  187. test = TEST_SLAVE_STATE_GET_PREFIX;
  188. GNUNET_PSYC_channel_state_get_prefix (slv_chn, "_foo", &state_get_var,
  189. &slave_state_get_prefix_result, NULL);
  190. }
  191. /*** Master state_get_prefix() ***/
  192. void
  193. master_state_get_prefix_result (void *cls, int64_t result, const char *err_msg)
  194. {
  195. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  196. "master_state_get_prefix:\t%" PRId64 " (%s)\n", result, err_msg);
  197. // FIXME: GNUNET_assert (2 == result);
  198. slave_state_get_prefix ();
  199. }
  200. void
  201. master_state_get_prefix ()
  202. {
  203. test = TEST_MASTER_STATE_GET_PREFIX;
  204. GNUNET_PSYC_channel_state_get_prefix (mst_chn, "_foo", &state_get_var,
  205. &master_state_get_prefix_result, NULL);
  206. }
  207. /*** Slave state_get() ***/
  208. void
  209. slave_state_get_result (void *cls, int64_t result, const char *err_msg)
  210. {
  211. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  212. "slave_state_get:\t%" PRId64 " (%s)\n", result, err_msg);
  213. // FIXME: GNUNET_assert (2 == result);
  214. master_state_get_prefix ();
  215. }
  216. void
  217. slave_state_get ()
  218. {
  219. test = TEST_SLAVE_STATE_GET;
  220. GNUNET_PSYC_channel_state_get (slv_chn, "_foo_bar_baz", &state_get_var,
  221. &slave_state_get_result, NULL);
  222. }
  223. /*** Master state_get() ***/
  224. void
  225. master_state_get_result (void *cls, int64_t result, const char *err_msg)
  226. {
  227. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  228. "master_state_get:\t%" PRId64 " (%s)\n", result, err_msg);
  229. // FIXME: GNUNET_assert (1 == result);
  230. slave_state_get ();
  231. }
  232. void
  233. master_state_get ()
  234. {
  235. test = TEST_MASTER_STATE_GET;
  236. GNUNET_PSYC_channel_state_get (mst_chn, "_foo_bar_baz", &state_get_var,
  237. &master_state_get_result, NULL);
  238. }
  239. /*** Slave history_replay() ***/
  240. void
  241. slave_history_replay_result (void *cls, int64_t result, const char *err_msg)
  242. {
  243. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  244. "slave_history_replay:\t%" PRId64 " (%s)\n", result, err_msg);
  245. GNUNET_assert (9 == result);
  246. master_state_get ();
  247. }
  248. void
  249. slave_history_replay ()
  250. {
  251. test = TEST_SLAVE_HISTORY_REPLAY;
  252. GNUNET_PSYC_channel_history_replay (slv_chn, 1, 1,
  253. &slave_history_replay_result,
  254. NULL);
  255. }
  256. /*** Master history_replay() ***/
  257. void
  258. master_history_replay_result (void *cls, int64_t result, const char *err_msg)
  259. {
  260. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  261. "master_history_replay:\t%" PRId64 " (%s)\n", result, err_msg);
  262. GNUNET_assert (9 == result);
  263. slave_history_replay ();
  264. }
  265. void
  266. master_history_replay ()
  267. {
  268. test = TEST_MASTER_HISTORY_REPLAY;
  269. GNUNET_PSYC_channel_history_replay (mst_chn, 1, 1,
  270. &master_history_replay_result,
  271. NULL);
  272. }
  273. /*** Slave history_replay_latest() ***/
  274. void
  275. slave_history_replay_latest_result (void *cls, int64_t result, const char *err_msg)
  276. {
  277. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  278. "slave_history_replay_latest:\t%" PRId64 " (%s)\n", result, err_msg);
  279. GNUNET_assert (9 == result);
  280. master_history_replay ();
  281. }
  282. void
  283. slave_history_replay_latest ()
  284. {
  285. test = TEST_SLAVE_HISTORY_REPLAY_LATEST;
  286. GNUNET_PSYC_channel_history_replay_latest (slv_chn, 1,
  287. &slave_history_replay_latest_result,
  288. NULL);
  289. }
  290. /*** Master history_replay_latest() ***/
  291. void
  292. master_history_replay_latest_result (void *cls, int64_t result, const char *err_msg)
  293. {
  294. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  295. "master_history_replay_latest:\t%" PRId64 " (%s)\n", result, err_msg);
  296. GNUNET_assert (9 == result);
  297. slave_history_replay_latest ();
  298. }
  299. void
  300. master_history_replay_latest ()
  301. {
  302. test = TEST_MASTER_HISTORY_REPLAY_LATEST;
  303. GNUNET_PSYC_channel_history_replay_latest (mst_chn, 1,
  304. &master_history_replay_latest_result,
  305. NULL);
  306. }
  307. void
  308. master_message_cb (void *cls, uint64_t message_id, uint32_t flags,
  309. const struct GNUNET_PSYC_MessageHeader *msg)
  310. {
  311. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  312. "Test #%d: Master got PSYC message fragment of size %u "
  313. "belonging to message ID %" PRIu64 " with flags %x\n",
  314. test, ntohs (msg->header.size), message_id, flags);
  315. // FIXME
  316. }
  317. void
  318. master_message_part_cb (void *cls, uint64_t message_id,
  319. uint64_t data_offset, uint32_t flags,
  320. const struct GNUNET_MessageHeader *msg)
  321. {
  322. if (NULL == msg)
  323. {
  324. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  325. "Error while receiving message %" PRIu64 "\n", message_id);
  326. return;
  327. }
  328. uint16_t type = ntohs (msg->type);
  329. uint16_t size = ntohs (msg->size);
  330. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  331. "Test #%d: Master got message part of type %u and size %u "
  332. "belonging to message ID %" PRIu64 " with flags %x\n",
  333. test, type, size, message_id, flags);
  334. switch (test)
  335. {
  336. case TEST_SLAVE_TRANSMIT:
  337. if (GNUNET_PSYC_MESSAGE_REQUEST != flags)
  338. {
  339. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  340. "Unexpected request flags: %x" PRIu32 "\n", flags);
  341. GNUNET_assert (0);
  342. return;
  343. }
  344. // FIXME: check rest of message
  345. if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END == type)
  346. master_transmit ();
  347. break;
  348. case TEST_MASTER_TRANSMIT:
  349. break;
  350. case TEST_MASTER_HISTORY_REPLAY:
  351. case TEST_MASTER_HISTORY_REPLAY_LATEST:
  352. if (GNUNET_PSYC_MESSAGE_HISTORIC != flags)
  353. {
  354. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  355. "Test #%d: Unexpected flags for historic message: %x" PRIu32 "\n",
  356. flags);
  357. GNUNET_assert (0);
  358. return;
  359. }
  360. break;
  361. default:
  362. GNUNET_assert (0);
  363. }
  364. }
  365. void
  366. slave_message_cb (void *cls, uint64_t message_id, uint32_t flags,
  367. const struct GNUNET_PSYC_MessageHeader *msg)
  368. {
  369. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  370. "Test #%d: Slave got PSYC message fragment of size %u "
  371. "belonging to message ID %" PRIu64 " with flags %x\n",
  372. test, ntohs (msg->header.size), message_id, flags);
  373. // FIXME
  374. }
  375. void
  376. slave_message_part_cb (void *cls, uint64_t message_id,
  377. uint64_t data_offset, uint32_t flags,
  378. const struct GNUNET_MessageHeader *msg)
  379. {
  380. if (NULL == msg)
  381. {
  382. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  383. "Error while receiving message " PRIu64 "\n", message_id);
  384. return;
  385. }
  386. uint16_t type = ntohs (msg->type);
  387. uint16_t size = ntohs (msg->size);
  388. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  389. "Test #%d: Slave got message part of type %u and size %u "
  390. "belonging to message ID %" PRIu64 " with flags %x\n",
  391. test, type, size, message_id, flags);
  392. switch (test)
  393. {
  394. case TEST_MASTER_TRANSMIT:
  395. if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END == type)
  396. master_history_replay_latest ();
  397. break;
  398. case TEST_SLAVE_HISTORY_REPLAY:
  399. case TEST_SLAVE_HISTORY_REPLAY_LATEST:
  400. if (GNUNET_PSYC_MESSAGE_HISTORIC != flags)
  401. {
  402. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  403. "Test #%d: Unexpected flags for historic message: %x" PRIu32 "\n",
  404. flags);
  405. GNUNET_assert (0);
  406. return;
  407. }
  408. break;
  409. default:
  410. GNUNET_assert (0);
  411. }
  412. }
  413. void
  414. transmit_resume (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  415. {
  416. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission resumed.\n");
  417. struct TransmitClosure *tmit = cls;
  418. if (NULL != tmit->mst_tmit)
  419. GNUNET_PSYC_master_transmit_resume (tmit->mst_tmit);
  420. else
  421. GNUNET_PSYC_slave_transmit_resume (tmit->slv_tmit);
  422. }
  423. int
  424. tmit_notify_data (void *cls, uint16_t *data_size, void *data)
  425. {
  426. struct TransmitClosure *tmit = cls;
  427. if (0 == tmit->data_count)
  428. {
  429. *data_size = 0;
  430. return GNUNET_YES;
  431. }
  432. uint16_t size = strlen (tmit->data[tmit->n]);
  433. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  434. "Transmit notify data: %u bytes available, "
  435. "processing fragment %u/%u (size %u).\n",
  436. *data_size, tmit->n + 1, tmit->data_count, size);
  437. if (*data_size < size)
  438. {
  439. *data_size = 0;
  440. GNUNET_assert (0);
  441. return GNUNET_SYSERR;
  442. }
  443. if (GNUNET_YES != tmit->paused && 0 < tmit->data_delay[tmit->n])
  444. {
  445. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission paused.\n");
  446. tmit->paused = GNUNET_YES;
  447. GNUNET_SCHEDULER_add_delayed (
  448. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
  449. tmit->data_delay[tmit->n]),
  450. &transmit_resume, tmit);
  451. *data_size = 0;
  452. return GNUNET_NO;
  453. }
  454. tmit->paused = GNUNET_NO;
  455. *data_size = size;
  456. memcpy (data, tmit->data[tmit->n], size);
  457. return ++tmit->n < tmit->data_count ? GNUNET_NO : GNUNET_YES;
  458. }
  459. int
  460. tmit_notify_mod (void *cls, uint16_t *data_size, void *data, uint8_t *oper,
  461. uint32_t *full_value_size)
  462. {
  463. struct TransmitClosure *tmit = cls;
  464. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  465. "Transmit notify modifier: %lu bytes available, "
  466. "%u modifiers left to process.\n",
  467. *data_size, GNUNET_ENV_environment_get_count (tmit->env));
  468. uint16_t name_size = 0;
  469. size_t value_size = 0;
  470. const char *value = NULL;
  471. if (NULL != oper && NULL != tmit->mod)
  472. { /* New modifier */
  473. tmit->mod = tmit->mod->next;
  474. if (NULL == tmit->mod)
  475. { /* No more modifiers, continue with data */
  476. *data_size = 0;
  477. return GNUNET_YES;
  478. }
  479. GNUNET_assert (tmit->mod->value_size < UINT32_MAX);
  480. *full_value_size = tmit->mod->value_size;
  481. *oper = tmit->mod->oper;
  482. name_size = strlen (tmit->mod->name);
  483. if (name_size + 1 + tmit->mod->value_size <= *data_size)
  484. {
  485. *data_size = name_size + 1 + tmit->mod->value_size;
  486. }
  487. else
  488. {
  489. tmit->mod_value_size = tmit->mod->value_size;
  490. value_size = *data_size - name_size - 1;
  491. tmit->mod_value_size -= value_size;
  492. tmit->mod_value = tmit->mod->value + value_size;
  493. }
  494. memcpy (data, tmit->mod->name, name_size);
  495. ((char *)data)[name_size] = '\0';
  496. memcpy ((char *)data + name_size + 1, tmit->mod->value, value_size);
  497. }
  498. else if (NULL != tmit->mod_value && 0 < tmit->mod_value_size)
  499. { /* Modifier continuation */
  500. value = tmit->mod_value;
  501. if (tmit->mod_value_size <= *data_size)
  502. {
  503. value_size = tmit->mod_value_size;
  504. tmit->mod_value = NULL;
  505. }
  506. else
  507. {
  508. value_size = *data_size;
  509. tmit->mod_value += value_size;
  510. }
  511. tmit->mod_value_size -= value_size;
  512. if (*data_size < value_size)
  513. {
  514. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  515. "value larger than buffer: %u < %zu\n",
  516. *data_size, value_size);
  517. *data_size = 0;
  518. return GNUNET_NO;
  519. }
  520. *data_size = value_size;
  521. memcpy (data, value, value_size);
  522. }
  523. return GNUNET_NO;
  524. }
  525. void
  526. slave_join ();
  527. void
  528. slave_transmit ()
  529. {
  530. GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Slave sending request to master.\n");
  531. test = TEST_SLAVE_TRANSMIT;
  532. tmit = GNUNET_new (struct TransmitClosure);
  533. tmit->env = GNUNET_ENV_environment_create ();
  534. GNUNET_ENV_environment_add (tmit->env, GNUNET_ENV_OP_ASSIGN,
  535. "_abc", "abc def", 7);
  536. GNUNET_ENV_environment_add (tmit->env, GNUNET_ENV_OP_ASSIGN,
  537. "_abc_def", "abc def ghi", 11);
  538. tmit->mod = GNUNET_ENV_environment_head (tmit->env);
  539. tmit->n = 0;
  540. tmit->data[0] = "slave test";
  541. tmit->data_count = 1;
  542. tmit->slv_tmit
  543. = GNUNET_PSYC_slave_transmit (slv, "_request_test", tmit_notify_mod,
  544. tmit_notify_data, tmit,
  545. GNUNET_PSYC_SLAVE_TRANSMIT_NONE);
  546. }
  547. void
  548. slave_remove_cb (void *cls, int64_t result, const char *err_msg)
  549. {
  550. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  551. "slave_remove:\t%" PRId64 " (%s)\n", result, err_msg);
  552. slave_transmit ();
  553. }
  554. void
  555. slave_add_cb (void *cls, int64_t result, const char *err_msg)
  556. {
  557. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  558. "slave_add:\t%" PRId64 " (%s)\n", result, err_msg);
  559. struct GNUNET_PSYC_Channel *chn = cls;
  560. GNUNET_PSYC_channel_slave_remove (chn, &slave_pub_key, 2,
  561. &slave_remove_cb, chn);
  562. }
  563. void
  564. join_decision_cb (void *cls,
  565. const struct GNUNET_PSYC_JoinDecisionMessage *dcsn,
  566. int is_admitted,
  567. const struct GNUNET_PSYC_Message *join_msg)
  568. {
  569. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  570. "Slave got join decision: %d\n", is_admitted);
  571. if (GNUNET_YES != is_admitted)
  572. { /* First join request is refused, retry. */
  573. GNUNET_assert (1 == join_req_count);
  574. slave_join ();
  575. return;
  576. }
  577. struct GNUNET_PSYC_Channel *chn = GNUNET_PSYC_master_get_channel (mst);
  578. GNUNET_PSYC_channel_slave_add (chn, &slave_pub_key, 2, 2, &slave_add_cb, chn);
  579. }
  580. void
  581. join_request_cb (void *cls,
  582. const struct GNUNET_PSYC_JoinRequestMessage *req,
  583. const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
  584. const struct GNUNET_PSYC_Message *join_msg,
  585. struct GNUNET_PSYC_JoinHandle *jh)
  586. {
  587. struct GNUNET_HashCode slave_key_hash;
  588. GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash);
  589. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  590. "Got join request #%u from %s.\n",
  591. join_req_count, GNUNET_h2s (&slave_key_hash));
  592. /* Reject first request */
  593. int is_admitted = (0 < join_req_count++) ? GNUNET_YES : GNUNET_NO;
  594. GNUNET_PSYC_join_decision (jh, is_admitted, 0, NULL, NULL);
  595. }
  596. void
  597. slave_connect_cb (void *cls, int result, uint64_t max_message_id)
  598. {
  599. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  600. "Slave connected: %d, max_message_id: %" PRIu64 "\n",
  601. result, max_message_id);
  602. GNUNET_assert (TEST_SLAVE_JOIN == test);
  603. GNUNET_assert (GNUNET_OK == result || GNUNET_NO == result);
  604. }
  605. void
  606. slave_join ()
  607. {
  608. GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Joining slave.\n");
  609. test = TEST_SLAVE_JOIN;
  610. struct GNUNET_PeerIdentity origin = this_peer;
  611. struct GNUNET_ENV_Environment *env = GNUNET_ENV_environment_create ();
  612. GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN,
  613. "_foo", "bar baz", 7);
  614. GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN,
  615. "_foo_bar", "foo bar baz", 11);
  616. struct GNUNET_PSYC_Message *
  617. join_msg = GNUNET_PSYC_message_create ("_request_join", env, "some data", 9);
  618. slv = GNUNET_PSYC_slave_join (cfg, &channel_pub_key, slave_key, &origin, 0, NULL,
  619. &slave_message_cb, &slave_message_part_cb,
  620. &slave_connect_cb, &join_decision_cb, NULL,
  621. join_msg);
  622. slv_chn = GNUNET_PSYC_slave_get_channel (slv);
  623. GNUNET_ENV_environment_destroy (env);
  624. }
  625. void
  626. master_transmit ()
  627. {
  628. GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Master sending message to all.\n");
  629. test = TEST_MASTER_TRANSMIT;
  630. uint32_t i, j;
  631. char *name_max = "_test_max";
  632. uint8_t name_max_size = sizeof ("_test_max");
  633. char *val_max = GNUNET_malloc (GNUNET_PSYC_MODIFIER_MAX_PAYLOAD);
  634. for (i = 0; i < GNUNET_PSYC_MODIFIER_MAX_PAYLOAD; i++)
  635. val_max[i] = (0 == i % 10000) ? '0' + i / 10000 : '.';
  636. char *name_cont = "_test_cont";
  637. uint8_t name_cont_size = sizeof ("_test_cont");
  638. char *val_cont = GNUNET_malloc (GNUNET_PSYC_MODIFIER_MAX_PAYLOAD
  639. + GNUNET_PSYC_MOD_CONT_MAX_PAYLOAD);
  640. for (i = 0; i < GNUNET_PSYC_MODIFIER_MAX_PAYLOAD - name_cont_size; i++)
  641. val_cont[i] = (0 == i % 10000) ? '0' + i / 10000 : ':';
  642. for (j = 0; j < GNUNET_PSYC_MOD_CONT_MAX_PAYLOAD; j++, i++)
  643. val_cont[i] = (0 == j % 10000) ? '0' + j / 10000 : '!';
  644. tmit = GNUNET_new (struct TransmitClosure);
  645. tmit->env = GNUNET_ENV_environment_create ();
  646. GNUNET_ENV_environment_add (tmit->env, GNUNET_ENV_OP_ASSIGN,
  647. "_foo", "bar baz", 7);
  648. GNUNET_ENV_environment_add (tmit->env, GNUNET_ENV_OP_ASSIGN,
  649. name_max, val_max,
  650. GNUNET_PSYC_MODIFIER_MAX_PAYLOAD
  651. - name_max_size);
  652. GNUNET_ENV_environment_add (tmit->env, GNUNET_ENV_OP_ASSIGN,
  653. "_foo_bar", "foo bar baz", 11);
  654. GNUNET_ENV_environment_add (tmit->env, GNUNET_ENV_OP_ASSIGN,
  655. name_cont, val_cont,
  656. GNUNET_PSYC_MODIFIER_MAX_PAYLOAD - name_cont_size
  657. + GNUNET_PSYC_MOD_CONT_MAX_PAYLOAD);
  658. tmit->mod = GNUNET_ENV_environment_head (tmit->env);
  659. tmit->data[0] = "foo";
  660. tmit->data[1] = GNUNET_malloc (GNUNET_PSYC_DATA_MAX_PAYLOAD + 1);
  661. for (i = 0; i < GNUNET_PSYC_DATA_MAX_PAYLOAD; i++)
  662. tmit->data[1][i] = (0 == i % 10000) ? '0' + i / 10000 : '_';
  663. tmit->data[2] = "foo bar";
  664. tmit->data[3] = "foo bar baz";
  665. tmit->data_delay[1] = 3;
  666. tmit->data_count = 4;
  667. tmit->mst_tmit
  668. = GNUNET_PSYC_master_transmit (mst, "_notice_test", tmit_notify_mod,
  669. tmit_notify_data, tmit,
  670. GNUNET_PSYC_MASTER_TRANSMIT_INC_GROUP_GEN);
  671. }
  672. void
  673. master_start_cb (void *cls, int result, uint64_t max_message_id)
  674. {
  675. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  676. "Master started: %d, max_message_id: %" PRIu64 "\n",
  677. result, max_message_id);
  678. GNUNET_assert (TEST_MASTER_START == test);
  679. GNUNET_assert (GNUNET_OK == result || GNUNET_NO == result);
  680. slave_join ();
  681. }
  682. void
  683. master_start ()
  684. {
  685. GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Starting master.\n");
  686. test = TEST_MASTER_START;
  687. mst = GNUNET_PSYC_master_start (cfg, channel_key, GNUNET_PSYC_CHANNEL_PRIVATE,
  688. &master_start_cb, &join_request_cb,
  689. &master_message_cb, &master_message_part_cb,
  690. NULL);
  691. mst_chn = GNUNET_PSYC_master_get_channel (mst);
  692. }
  693. void
  694. schedule_master_start (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  695. {
  696. master_start ();
  697. }
  698. void
  699. core_connected (void *cls, const struct GNUNET_PeerIdentity *my_identity)
  700. {
  701. this_peer = *my_identity;
  702. #if DEBUG_TEST_PSYC
  703. master_start ();
  704. #else
  705. /* Allow some time for the services to initialize. */
  706. GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
  707. &schedule_master_start, NULL);
  708. #endif
  709. }
  710. /**
  711. * Main function of the test, run from scheduler.
  712. *
  713. * @param cls NULL
  714. * @param cfg configuration we use (also to connect to PSYC service)
  715. * @param peer handle to access more of the peer (not used)
  716. */
  717. void
  718. #if DEBUG_TEST_PSYC
  719. run (void *cls, char *const *args, const char *cfgfile,
  720. const struct GNUNET_CONFIGURATION_Handle *c)
  721. #else
  722. run (void *cls,
  723. const struct GNUNET_CONFIGURATION_Handle *c,
  724. struct GNUNET_TESTING_Peer *peer)
  725. #endif
  726. {
  727. cfg = c;
  728. end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
  729. channel_key = GNUNET_CRYPTO_eddsa_key_create ();
  730. slave_key = GNUNET_CRYPTO_ecdsa_key_create ();
  731. GNUNET_CRYPTO_eddsa_key_get_public (channel_key, &channel_pub_key);
  732. GNUNET_CRYPTO_ecdsa_key_get_public (slave_key, &slave_pub_key);
  733. core = GNUNET_CORE_connect (cfg, NULL, &core_connected, NULL, NULL,
  734. NULL, GNUNET_NO, NULL, GNUNET_NO, NULL);
  735. }
  736. int
  737. main (int argc, char *argv[])
  738. {
  739. res = 1;
  740. #if DEBUG_TEST_PSYC
  741. const struct GNUNET_GETOPT_CommandLineOption opts[] = {
  742. GNUNET_GETOPT_OPTION_END
  743. };
  744. if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "test-psyc",
  745. "test-psyc [options]",
  746. opts, &run, NULL))
  747. return 1;
  748. #else
  749. if (0 != GNUNET_TESTING_peer_run ("test-psyc", "test_psyc.conf", &run, NULL))
  750. return 1;
  751. #endif
  752. return res;
  753. }
  754. /* end of test_psyc.c */