gnunet-dht-monitor.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. This file is part of GNUnet.
  3. (C) 2012 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. 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. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file dht/gnunet-dht-monitor.c
  19. * @brief search for data in DHT
  20. * @author Christian Grothoff
  21. * @author Bartlomiej Polot
  22. */
  23. #include "platform.h"
  24. #include "gnunet_dht_service.h"
  25. /**
  26. * The type of the query
  27. */
  28. static unsigned int block_type;
  29. /**
  30. * The key to be monitored
  31. */
  32. static char *query_key;
  33. /**
  34. * User supplied timeout value (in seconds)
  35. */
  36. static struct GNUNET_TIME_Relative timeout_request = { 60000 };
  37. /**
  38. * Be verbose
  39. */
  40. static int verbose;
  41. /**
  42. * Handle to the DHT
  43. */
  44. static struct GNUNET_DHT_Handle *dht_handle;
  45. /**
  46. * Global handle of the configuration
  47. */
  48. static const struct GNUNET_CONFIGURATION_Handle *cfg;
  49. /**
  50. * Handle for the get request
  51. */
  52. static struct GNUNET_DHT_MonitorHandle *monitor_handle;
  53. /**
  54. * Count of messages received
  55. */
  56. static unsigned int result_count;
  57. /**
  58. * Global status value
  59. */
  60. static int ret;
  61. /**
  62. * Stop monitoring request and start shutdown
  63. *
  64. * @param cls closure (unused)
  65. * @param tc Task Context
  66. */
  67. static void
  68. cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  69. {
  70. if (verbose)
  71. FPRINTF (stderr, "%s", "Cleaning up!\n");
  72. if (NULL != monitor_handle)
  73. {
  74. GNUNET_DHT_monitor_stop (monitor_handle);
  75. monitor_handle = NULL;
  76. }
  77. if (NULL != dht_handle)
  78. {
  79. GNUNET_DHT_disconnect (dht_handle);
  80. dht_handle = NULL;
  81. }
  82. }
  83. /**
  84. * Callback called on each GET request going through the DHT.
  85. *
  86. * @param cls Closure.
  87. * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
  88. * @param type The type of data in the request.
  89. * @param hop_count Hop count so far.
  90. * @param path_length number of entries in path (or 0 if not recorded).
  91. * @param path peers on the GET path (or NULL if not recorded).
  92. * @param desired_replication_level Desired replication level.
  93. * @param key Key of the requested data.
  94. */
  95. void
  96. get_callback (void *cls,
  97. enum GNUNET_DHT_RouteOption options,
  98. enum GNUNET_BLOCK_Type type,
  99. uint32_t hop_count,
  100. uint32_t desired_replication_level,
  101. unsigned int path_length,
  102. const struct GNUNET_PeerIdentity *path,
  103. const struct GNUNET_HashCode * key)
  104. {
  105. FPRINTF (stdout, "GET #%u: type %d, key `%s'\n",
  106. result_count,
  107. (int) type,
  108. GNUNET_h2s_full(key));
  109. result_count++;
  110. }
  111. /**
  112. * Callback called on each GET reply going through the DHT.
  113. *
  114. * @param cls Closure.
  115. * @param type The type of data in the result.
  116. * @param get_path Peers on GET path (or NULL if not recorded).
  117. * @param get_path_length number of entries in get_path.
  118. * @param put_path peers on the PUT path (or NULL if not recorded).
  119. * @param put_path_length number of entries in get_path.
  120. * @param exp Expiration time of the data.
  121. * @param key Key of the data.
  122. * @param data Pointer to the result data.
  123. * @param size Number of bytes in data.
  124. */
  125. void
  126. get_resp_callback (void *cls,
  127. enum GNUNET_BLOCK_Type type,
  128. const struct GNUNET_PeerIdentity *get_path,
  129. unsigned int get_path_length,
  130. const struct GNUNET_PeerIdentity *put_path,
  131. unsigned int put_path_length,
  132. struct GNUNET_TIME_Absolute exp,
  133. const struct GNUNET_HashCode * key,
  134. const void *data,
  135. size_t size)
  136. {
  137. FPRINTF (stdout,
  138. "RESPONSE #%u: type %d, key `%s', data `%.*s'\n",
  139. result_count,
  140. (int) type,
  141. GNUNET_h2s_full (key),
  142. (unsigned int) size,
  143. (char *) data);
  144. result_count++;
  145. }
  146. /**
  147. * Callback called on each PUT request going through the DHT.
  148. *
  149. * @param cls Closure.
  150. * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
  151. * @param type The type of data in the request.
  152. * @param hop_count Hop count so far.
  153. * @param path_length number of entries in path (or 0 if not recorded).
  154. * @param path peers on the PUT path (or NULL if not recorded).
  155. * @param desired_replication_level Desired replication level.
  156. * @param exp Expiration time of the data.
  157. * @param key Key under which data is to be stored.
  158. * @param data Pointer to the data carried.
  159. * @param size Number of bytes in data.
  160. */
  161. void
  162. put_callback (void *cls,
  163. enum GNUNET_DHT_RouteOption options,
  164. enum GNUNET_BLOCK_Type type,
  165. uint32_t hop_count,
  166. uint32_t desired_replication_level,
  167. unsigned int path_length,
  168. const struct GNUNET_PeerIdentity *path,
  169. struct GNUNET_TIME_Absolute exp,
  170. const struct GNUNET_HashCode * key,
  171. const void *data,
  172. size_t size)
  173. {
  174. FPRINTF (stdout,
  175. "PUT %u: type %d, key `%s', data `%.*s'\n",
  176. result_count,
  177. (int) type,
  178. GNUNET_h2s_full(key),
  179. (unsigned int) size,
  180. (char *) data);
  181. result_count++;
  182. }
  183. /**
  184. * Main function that will be run by the scheduler.
  185. *
  186. * @param cls closure
  187. * @param args remaining command-line arguments
  188. * @param cfgfile name of the configuration file used (for saving, can be NULL!)
  189. * @param c configuration
  190. */
  191. static void
  192. run (void *cls, char *const *args, const char *cfgfile,
  193. const struct GNUNET_CONFIGURATION_Handle *c)
  194. {
  195. struct GNUNET_HashCode *key;
  196. struct GNUNET_HashCode hc;
  197. cfg = c;
  198. if (NULL == (dht_handle = GNUNET_DHT_connect (cfg, 1)))
  199. {
  200. FPRINTF (stderr, "%s",
  201. _("Failed to connect to DHT service!\n"));
  202. ret = 1;
  203. return;
  204. }
  205. if (GNUNET_BLOCK_TYPE_ANY == block_type) /* Type of data not set */
  206. block_type = GNUNET_BLOCK_TYPE_TEST;
  207. if (NULL != query_key)
  208. {
  209. key = &hc;
  210. if (GNUNET_OK !=
  211. GNUNET_CRYPTO_hash_from_string (query_key, key))
  212. GNUNET_CRYPTO_hash (query_key, strlen (query_key), key);
  213. }
  214. else
  215. {
  216. key = NULL;
  217. }
  218. if (verbose)
  219. FPRINTF (stderr,
  220. "Monitoring for %s\n",
  221. GNUNET_STRINGS_relative_time_to_string (timeout_request, GNUNET_NO));
  222. GNUNET_SCHEDULER_add_delayed (timeout_request, &cleanup_task, NULL);
  223. monitor_handle = GNUNET_DHT_monitor_start (dht_handle,
  224. block_type,
  225. key,
  226. &get_callback,
  227. &get_resp_callback,
  228. &put_callback,
  229. NULL);
  230. }
  231. /**
  232. * gnunet-dht-monitor command line options
  233. */
  234. static struct GNUNET_GETOPT_CommandLineOption options[] = {
  235. {'k', "key", "KEY",
  236. gettext_noop ("the query key"),
  237. 1, &GNUNET_GETOPT_set_string, &query_key},
  238. {'t', "type", "TYPE",
  239. gettext_noop ("the type of data to look for"),
  240. 1, &GNUNET_GETOPT_set_uint, &block_type},
  241. {'T', "timeout", "TIMEOUT",
  242. gettext_noop ("how long should the monitor command run"),
  243. 1, &GNUNET_GETOPT_set_relative_time, &timeout_request},
  244. {'V', "verbose", NULL,
  245. gettext_noop ("be verbose (print progress information)"),
  246. 0, &GNUNET_GETOPT_set_one, &verbose},
  247. GNUNET_GETOPT_OPTION_END
  248. };
  249. /**
  250. * Entry point for gnunet-dht-monitor
  251. *
  252. * @param argc number of arguments from the command line
  253. * @param argv command line arguments
  254. * @return 0 ok, 1 on error
  255. */
  256. int
  257. main (int argc, char *const *argv)
  258. {
  259. if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
  260. return 2;
  261. return (GNUNET_OK ==
  262. GNUNET_PROGRAM_run (argc, argv, "gnunet-dht-monitor",
  263. gettext_noop
  264. ("Prints all packets that go through the DHT."),
  265. options, &run, NULL)) ? ret : 1;
  266. }
  267. /* end of gnunet-dht-monitor.c */