perf_gnunet_service_fs_p2p.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2010, 2012 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 fs/perf_gnunet_service_fs_p2p.c
  18. * @brief profile P2P routing using simple publish + download operation
  19. * @author Christian Grothoff
  20. */
  21. #include "platform.h"
  22. #include "fs_test_lib.h"
  23. #include "gnunet_testbed_service.h"
  24. #define VERBOSE GNUNET_NO
  25. /**
  26. * File-size we use for testing.
  27. */
  28. #define FILESIZE (1024 * 1024 * 10)
  29. /**
  30. * How long until we give up on transmitting the message?
  31. */
  32. #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30)
  33. #define NUM_DAEMONS 2
  34. #define SEED 42
  35. static struct GNUNET_TESTBED_Peer *daemons[NUM_DAEMONS];
  36. static int ok;
  37. static struct GNUNET_TIME_Absolute start_time;
  38. static const char *progname;
  39. static struct GNUNET_TIME_Absolute start_time;
  40. /**
  41. * Master context for 'stat_run'.
  42. */
  43. struct StatMaster
  44. {
  45. struct GNUNET_STATISTICS_Handle *stat;
  46. struct GNUNET_TESTBED_Operation *op;
  47. unsigned int daemon;
  48. unsigned int value;
  49. };
  50. struct StatValues
  51. {
  52. const char *subsystem;
  53. const char *name;
  54. };
  55. /**
  56. * Statistics we print out.
  57. */
  58. static struct StatValues stats[] = {
  59. { "fs", "# queries forwarded" },
  60. { "fs", "# replies received and matched" },
  61. { "fs", "# results found locally" },
  62. { "fs", "# requests forwarded due to high load" },
  63. { "fs", "# requests done for free (low load)" },
  64. { "fs", "# requests dropped, priority insufficient" },
  65. { "fs", "# requests done for a price (normal load)" },
  66. { "fs", "# requests dropped by datastore (queue length limit)" },
  67. { "fs", "# P2P searches received" },
  68. { "fs", "# P2P searches discarded (queue length bound)" },
  69. { "fs", "# replies received for local clients" },
  70. { "fs", "# queries retransmitted to same target" },
  71. { "core", "# bytes decrypted" },
  72. { "core", "# bytes encrypted" },
  73. { "core", "# discarded CORE_SEND requests" },
  74. { "core", "# discarded CORE_SEND request bytes" },
  75. { "core", "# discarded lower priority CORE_SEND requests" },
  76. { "core", "# discarded lower priority CORE_SEND request bytes" },
  77. { "transport", "# bytes received via TCP" },
  78. { "transport", "# bytes transmitted via TCP" },
  79. { "datacache", "# bytes stored" },
  80. { NULL, NULL }
  81. };
  82. /**
  83. * Callback function to process statistic values.
  84. *
  85. * @param cls closure
  86. * @param subsystem name of subsystem that created the statistic
  87. * @param name the name of the datum
  88. * @param value the current value
  89. * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not
  90. * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
  91. */
  92. static int
  93. print_stat (void *cls, const char *subsystem, const char *name, uint64_t value,
  94. int is_persistent)
  95. {
  96. struct StatMaster *sm = cls;
  97. fprintf (stderr,
  98. "Peer %2u: %12s/%50s = %12llu\n",
  99. sm->daemon,
  100. subsystem,
  101. name,
  102. (unsigned long long) value);
  103. return GNUNET_OK;
  104. }
  105. /**
  106. * Function that gathers stats from all daemons.
  107. */
  108. static void
  109. stat_run (void *cls,
  110. struct GNUNET_TESTBED_Operation *op,
  111. void *ca_result,
  112. const char *emsg);
  113. /**
  114. * Function called when GET operation on stats is done.
  115. */
  116. static void
  117. get_done (void *cls, int success)
  118. {
  119. struct StatMaster *sm = cls;
  120. GNUNET_break (GNUNET_OK == success);
  121. sm->value++;
  122. stat_run (sm, sm->op, sm->stat, NULL);
  123. }
  124. /**
  125. * Adapter function called to establish a connection to
  126. * statistics service.
  127. *
  128. * @param cls closure
  129. * @param cfg configuration of the peer to connect to; will be available until
  130. * GNUNET_TESTBED_operation_done() is called on the operation returned
  131. * from GNUNET_TESTBED_service_connect()
  132. * @return service handle to return in 'op_result', NULL on error
  133. */
  134. static void *
  135. statistics_connect_adapter (void *cls,
  136. const struct GNUNET_CONFIGURATION_Handle *cfg)
  137. {
  138. return GNUNET_STATISTICS_create ("<driver>",
  139. cfg);
  140. }
  141. /**
  142. * Adapter function called to destroy a connection to
  143. * statistics service.
  144. *
  145. * @param cls closure
  146. * @param op_result service handle returned from the connect adapter
  147. */
  148. static void
  149. statistics_disconnect_adapter (void *cls,
  150. void *op_result)
  151. {
  152. GNUNET_STATISTICS_destroy (op_result, GNUNET_NO);
  153. }
  154. /**
  155. * Function that gathers stats from all daemons.
  156. */
  157. static void
  158. stat_run (void *cls,
  159. struct GNUNET_TESTBED_Operation *op,
  160. void *ca_result,
  161. const char *emsg)
  162. {
  163. struct StatMaster *sm = cls;
  164. if (NULL != emsg)
  165. {
  166. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  167. "Failed to statistics service: %s\n",
  168. emsg);
  169. GNUNET_SCHEDULER_shutdown ();
  170. return;
  171. }
  172. sm->stat = ca_result;
  173. if (stats[sm->value].name != NULL)
  174. {
  175. GNUNET_STATISTICS_get (sm->stat,
  176. #if 0
  177. NULL, NULL,
  178. #else
  179. stats[sm->value].subsystem, stats[sm->value].name,
  180. #endif
  181. &get_done, &print_stat,
  182. sm);
  183. return;
  184. }
  185. GNUNET_TESTBED_operation_done (sm->op);
  186. sm->value = 0;
  187. sm->daemon++;
  188. if (NUM_DAEMONS == sm->daemon)
  189. {
  190. GNUNET_free (sm);
  191. GNUNET_SCHEDULER_shutdown ();
  192. return;
  193. }
  194. sm->op =
  195. GNUNET_TESTBED_service_connect (NULL,
  196. daemons[sm->daemon],
  197. "statistics",
  198. &stat_run, sm,
  199. &statistics_connect_adapter,
  200. &statistics_disconnect_adapter,
  201. NULL);
  202. }
  203. static void
  204. do_report (void *cls)
  205. {
  206. char *fn = cls;
  207. struct GNUNET_TIME_Relative del;
  208. char *fancy;
  209. struct StatMaster *sm;
  210. if (NULL != fn)
  211. {
  212. GNUNET_DISK_directory_remove (fn);
  213. GNUNET_free (fn);
  214. }
  215. if (0 ==
  216. GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_add (start_time,
  217. TIMEOUT)).
  218. rel_value_us)
  219. {
  220. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  221. "Timeout during download, shutting down with error\n");
  222. ok = 1;
  223. GNUNET_SCHEDULER_shutdown ();
  224. return;
  225. }
  226. del = GNUNET_TIME_absolute_get_duration (start_time);
  227. if (del.rel_value_us == 0)
  228. del.rel_value_us = 1;
  229. fancy =
  230. GNUNET_STRINGS_byte_size_fancy (((unsigned long long) FILESIZE)
  231. * 1000000LL / del.rel_value_us);
  232. fprintf (stdout,
  233. "Download speed was %s/s\n",
  234. fancy);
  235. GNUNET_free (fancy);
  236. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  237. "Finished download, shutting down\n");
  238. sm = GNUNET_new (struct StatMaster);
  239. sm->op =
  240. GNUNET_TESTBED_service_connect (NULL,
  241. daemons[sm->daemon],
  242. "statistics",
  243. &stat_run, sm,
  244. &statistics_connect_adapter,
  245. &statistics_disconnect_adapter,
  246. NULL);
  247. }
  248. static void
  249. do_download (void *cls,
  250. const struct GNUNET_FS_Uri *uri,
  251. const char *fn)
  252. {
  253. int anonymity;
  254. if (NULL == uri)
  255. {
  256. GNUNET_SCHEDULER_shutdown ();
  257. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  258. "Timeout during upload attempt, shutting down with error\n");
  259. ok = 1;
  260. return;
  261. }
  262. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Downloading %llu bytes\n",
  263. (unsigned long long) FILESIZE);
  264. start_time = GNUNET_TIME_absolute_get ();
  265. if (NULL != strstr (progname, "dht"))
  266. anonymity = 0;
  267. else
  268. anonymity = 1;
  269. start_time = GNUNET_TIME_absolute_get ();
  270. GNUNET_FS_TEST_download (daemons[0],
  271. TIMEOUT,
  272. anonymity,
  273. SEED,
  274. uri,
  275. VERBOSE,
  276. &do_report,
  277. (NULL == fn) ? NULL : GNUNET_strdup (fn));
  278. }
  279. static void
  280. do_publish (void *cls,
  281. struct GNUNET_TESTBED_RunHandle *h,
  282. unsigned int num_peers,
  283. struct GNUNET_TESTBED_Peer **peers,
  284. unsigned int links_succeeded,
  285. unsigned int links_failed)
  286. {
  287. unsigned int i;
  288. int do_index;
  289. int anonymity;
  290. GNUNET_assert (NUM_DAEMONS == num_peers);
  291. for (i = 0; i < num_peers; i++)
  292. daemons[i] = peers[i];
  293. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing %llu bytes\n",
  294. (unsigned long long) FILESIZE);
  295. if (NULL != strstr (progname, "index"))
  296. do_index = GNUNET_YES;
  297. else
  298. do_index = GNUNET_NO;
  299. if (NULL != strstr (progname, "dht"))
  300. anonymity = 0;
  301. else
  302. anonymity = 1;
  303. GNUNET_FS_TEST_publish (daemons[NUM_DAEMONS - 1], TIMEOUT, anonymity,
  304. do_index, FILESIZE, SEED, VERBOSE, &do_download,
  305. NULL);
  306. }
  307. int
  308. main (int argc, char *argv[])
  309. {
  310. progname = argv[0];
  311. (void) GNUNET_TESTBED_test_run ("perf-gnunet-service-fs-p2p",
  312. "perf_gnunet_service_fs_p2p.conf",
  313. NUM_DAEMONS,
  314. 0, NULL, NULL,
  315. &do_publish, NULL);
  316. GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/");
  317. return ok;
  318. }
  319. /* end of perf_gnunet_service_fs_p2p.c */