test_namestore_api_monitoring.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2013, 2018 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 namestore/test_namestore_api_monitoring.c
  18. * @brief testcase for zone monitoring functionality: monitor first, then add records
  19. */
  20. #include "platform.h"
  21. #include "gnunet_namestore_service.h"
  22. #include "gnunet_testing_lib.h"
  23. #include "namestore.h"
  24. #include "gnunet_dnsparser_lib.h"
  25. #define TEST_RECORD_TYPE GNUNET_DNSPARSER_TYPE_TXT
  26. #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 100)
  27. static struct GNUNET_NAMESTORE_Handle *nsh;
  28. static struct GNUNET_SCHEDULER_Task *endbadly_task;
  29. static struct GNUNET_IDENTITY_PrivateKey privkey;
  30. static struct GNUNET_IDENTITY_PrivateKey privkey2;
  31. static struct GNUNET_NAMESTORE_ZoneMonitor *zm;
  32. static int res;
  33. static char *s_name_1;
  34. static struct GNUNET_GNSRECORD_Data *s_rd_1;
  35. static char *s_name_2;
  36. static struct GNUNET_GNSRECORD_Data *s_rd_2;
  37. static char *s_name_3;
  38. static struct GNUNET_GNSRECORD_Data *s_rd_3;
  39. struct GNUNET_NAMESTORE_QueueEntry *ns_ops[3];
  40. static void
  41. do_shutdown ()
  42. {
  43. if (NULL != zm)
  44. {
  45. GNUNET_NAMESTORE_zone_monitor_stop (zm);
  46. zm = NULL;
  47. }
  48. if (NULL != ns_ops[0])
  49. {
  50. GNUNET_NAMESTORE_cancel (ns_ops[0]);
  51. ns_ops[0] = NULL;
  52. }
  53. if (NULL != ns_ops[1])
  54. {
  55. GNUNET_NAMESTORE_cancel (ns_ops[1]);
  56. ns_ops[1] = NULL;
  57. }
  58. if (NULL != ns_ops[2])
  59. {
  60. GNUNET_NAMESTORE_cancel (ns_ops[2]);
  61. ns_ops[2] = NULL;
  62. }
  63. if (NULL != nsh)
  64. {
  65. GNUNET_NAMESTORE_disconnect (nsh);
  66. nsh = NULL;
  67. }
  68. GNUNET_free (s_name_1);
  69. GNUNET_free (s_name_2);
  70. GNUNET_free (s_name_3);
  71. if (s_rd_1 != NULL)
  72. {
  73. GNUNET_free_nz ((void *) s_rd_1->data);
  74. GNUNET_free (s_rd_1);
  75. }
  76. if (s_rd_2 != NULL)
  77. {
  78. GNUNET_free_nz ((void *) s_rd_2->data);
  79. GNUNET_free (s_rd_2);
  80. }
  81. if (s_rd_3 != NULL)
  82. {
  83. GNUNET_free_nz ((void *) s_rd_3->data);
  84. GNUNET_free (s_rd_3);
  85. }
  86. }
  87. /**
  88. * Re-establish the connection to the service.
  89. *
  90. * @param cls handle to use to re-connect.
  91. */
  92. static void
  93. endbadly (void *cls)
  94. {
  95. do_shutdown ();
  96. res = 1;
  97. }
  98. static void
  99. end (void *cls)
  100. {
  101. do_shutdown ();
  102. res = 0;
  103. }
  104. static void
  105. zone_proc (void *cls,
  106. const struct GNUNET_IDENTITY_PrivateKey *zone_key,
  107. const char *name,
  108. unsigned int rd_count,
  109. const struct GNUNET_GNSRECORD_Data *rd)
  110. {
  111. static int returned_records;
  112. static int fail = GNUNET_NO;
  113. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  114. "Comparing results name %s\n",
  115. name);
  116. if (0 != GNUNET_memcmp (zone_key,
  117. &privkey))
  118. {
  119. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  120. "Monitoring returned wrong zone key\n");
  121. GNUNET_break (0);
  122. GNUNET_SCHEDULER_cancel (endbadly_task);
  123. endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
  124. return;
  125. }
  126. if (0 == strcmp (name, s_name_1))
  127. {
  128. if (GNUNET_YES != GNUNET_GNSRECORD_records_cmp (rd, s_rd_1))
  129. {
  130. GNUNET_break (0);
  131. fail = GNUNET_YES;
  132. }
  133. }
  134. else if (0 == strcmp (name, s_name_2))
  135. {
  136. if (GNUNET_YES != GNUNET_GNSRECORD_records_cmp (rd, s_rd_2))
  137. {
  138. GNUNET_break (0);
  139. fail = GNUNET_YES;
  140. }
  141. }
  142. else
  143. {
  144. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  145. "Invalid name %s\n",
  146. name);
  147. GNUNET_break (0);
  148. fail = GNUNET_YES;
  149. }
  150. GNUNET_NAMESTORE_zone_monitor_next (zm,
  151. 1);
  152. if (2 == ++returned_records)
  153. {
  154. if (endbadly_task != NULL)
  155. {
  156. GNUNET_SCHEDULER_cancel (endbadly_task);
  157. endbadly_task = NULL;
  158. }
  159. if (GNUNET_YES == fail)
  160. GNUNET_SCHEDULER_add_now (&endbadly, NULL);
  161. else
  162. GNUNET_SCHEDULER_add_now (&end, NULL);
  163. }
  164. }
  165. static void
  166. put_cont (void *cls,
  167. int32_t success,
  168. const char *emsg)
  169. {
  170. static int c = 0;
  171. char *label = cls;
  172. if (0 == strcmp (label, s_name_1))
  173. ns_ops[0] = NULL;
  174. else if (0 == strcmp (label, s_name_2))
  175. ns_ops[1] = NULL;
  176. else if (0 == strcmp (label, s_name_3))
  177. ns_ops[2] = NULL;
  178. if (success == GNUNET_OK)
  179. {
  180. c++;
  181. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  182. "Created record %u: `%s'\n",
  183. c,
  184. label);
  185. }
  186. else
  187. {
  188. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  189. "Failed to create record `%s'\n",
  190. label);
  191. GNUNET_break (0);
  192. GNUNET_SCHEDULER_cancel (endbadly_task);
  193. endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly,
  194. NULL);
  195. }
  196. }
  197. static struct GNUNET_GNSRECORD_Data *
  198. create_record (unsigned int count)
  199. {
  200. struct GNUNET_GNSRECORD_Data *rd;
  201. rd = GNUNET_new_array (count,
  202. struct GNUNET_GNSRECORD_Data);
  203. for (unsigned int c = 0; c < count; c++)
  204. {
  205. rd[c].expiration_time = GNUNET_TIME_relative_to_absolute (
  206. GNUNET_TIME_UNIT_HOURS).abs_value_us;
  207. rd[c].record_type = TEST_RECORD_TYPE;
  208. rd[c].data_size = 50;
  209. rd[c].data = GNUNET_malloc (50);
  210. rd[c].flags = 0;
  211. memset ((char *) rd[c].data, 'a', 50);
  212. }
  213. return rd;
  214. }
  215. static void
  216. fail_cb (void *cls)
  217. {
  218. GNUNET_assert (0);
  219. }
  220. static void
  221. sync_cb (void *cls)
  222. {
  223. /* do nothing */
  224. }
  225. static void
  226. run (void *cls,
  227. const struct GNUNET_CONFIGURATION_Handle *cfg,
  228. struct GNUNET_TESTING_Peer *peer)
  229. {
  230. res = 1;
  231. privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
  232. GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key);
  233. /* Start monitoring */
  234. zm = GNUNET_NAMESTORE_zone_monitor_start (cfg,
  235. &privkey,
  236. GNUNET_YES,
  237. &fail_cb,
  238. NULL,
  239. &zone_proc,
  240. NULL,
  241. &sync_cb,
  242. NULL);
  243. if (NULL == zm)
  244. {
  245. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  246. "Failed to create zone monitor\n");
  247. GNUNET_break (0);
  248. endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
  249. return;
  250. }
  251. endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL);
  252. /* Connect to namestore */
  253. nsh = GNUNET_NAMESTORE_connect (cfg);
  254. if (NULL == nsh)
  255. {
  256. GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connect to namestore\n");
  257. GNUNET_break (0);
  258. endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
  259. return;
  260. }
  261. privkey2.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
  262. GNUNET_CRYPTO_ecdsa_key_create (&privkey2.ecdsa_key);
  263. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  264. "Created record 3\n");
  265. /* name in different zone */
  266. GNUNET_asprintf (&s_name_3, "dummy3");
  267. s_rd_3 = create_record (1);
  268. GNUNET_assert (NULL != (ns_ops[2] =
  269. GNUNET_NAMESTORE_records_store (nsh,
  270. &privkey2,
  271. s_name_3,
  272. 1,
  273. s_rd_3,
  274. &put_cont,
  275. s_name_3)));
  276. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  277. "Created record 1\n");
  278. GNUNET_asprintf (&s_name_1, "dummy1");
  279. s_rd_1 = create_record (1);
  280. GNUNET_assert (NULL != (ns_ops[0] =
  281. GNUNET_NAMESTORE_records_store (nsh,
  282. &privkey,
  283. s_name_1,
  284. 1,
  285. s_rd_1,
  286. &put_cont,
  287. s_name_1)));
  288. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n");
  289. GNUNET_asprintf (&s_name_2, "dummy2");
  290. s_rd_2 = create_record (1);
  291. GNUNET_assert (NULL != (ns_ops[1] =
  292. GNUNET_NAMESTORE_records_store (nsh,
  293. &privkey,
  294. s_name_2,
  295. 1,
  296. s_rd_2,
  297. &put_cont,
  298. s_name_2)));
  299. }
  300. #include "test_common.c"
  301. int
  302. main (int argc,
  303. char *argv[])
  304. {
  305. const char *plugin_name;
  306. char *cfg_name;
  307. SETUP_CFG (plugin_name, cfg_name);
  308. res = 1;
  309. if (0 !=
  310. GNUNET_TESTING_peer_run ("test-namestore-api-monitoring",
  311. cfg_name,
  312. &run,
  313. NULL))
  314. {
  315. res = 1;
  316. }
  317. GNUNET_DISK_purge_cfg_dir (cfg_name,
  318. "GNUNET_TEST_HOME");
  319. GNUNET_free (cfg_name);
  320. return res;
  321. }
  322. /* end of test_namestore_api_monitoring.c */