gnunet-service-testbed-logger.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2008--2013 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 testbed-logger/gnunet-service-testbed-logger.c
  18. * @brief service for collecting messages and writing to a file
  19. * @author Sree Harsha Totakura
  20. */
  21. #include "platform.h"
  22. #include "gnunet_util_lib.h"
  23. /**
  24. * Generic logging shorthand
  25. */
  26. #define LOG(type, ...) \
  27. GNUNET_log (type, __VA_ARGS__)
  28. /**
  29. * Debug logging shorthand
  30. */
  31. #define LOG_DEBUG(...) \
  32. LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
  33. /**
  34. * Handle for buffered writing.
  35. */
  36. struct GNUNET_BIO_WriteHandle *bio;
  37. /**
  38. * The number of connections we have
  39. */
  40. static unsigned int nconn;
  41. /**
  42. * Are we shutting down?
  43. */
  44. static int in_shutdown;
  45. /**
  46. * Check #GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG messages
  47. *
  48. * @param cls client identification of the client
  49. * @param msg the actual message
  50. * @return #GNUNET_OK (they are all always OK)
  51. */
  52. static int
  53. check_log_msg (void *cls,
  54. const struct GNUNET_MessageHeader *msg)
  55. {
  56. return GNUNET_OK;
  57. }
  58. /**
  59. * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG messages
  60. *
  61. * @param cls client identification of the client
  62. * @param msg the actual message
  63. */
  64. static void
  65. handle_log_msg (void *cls,
  66. const struct GNUNET_MessageHeader *msg)
  67. {
  68. struct GNUNET_SERVICE_Client *client = cls;
  69. uint16_t ms;
  70. ms = ntohs (msg->size) - sizeof(struct GNUNET_MessageHeader);
  71. GNUNET_BIO_write (bio,
  72. "testbed-logger-handle-log-msg",
  73. &msg[1],
  74. ms);
  75. GNUNET_SERVICE_client_continue (client);
  76. }
  77. /**
  78. * Task to clean up and shutdown nicely
  79. *
  80. * @param cls NULL
  81. */
  82. static void
  83. shutdown_task (void *cls)
  84. {
  85. in_shutdown = GNUNET_YES;
  86. if (0 != nconn)
  87. {
  88. /* Delay shutdown if there are active connections */
  89. GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
  90. NULL);
  91. return;
  92. }
  93. GNUNET_break (GNUNET_OK ==
  94. GNUNET_BIO_write_close (bio, NULL));
  95. }
  96. /**
  97. * Callback called when a client connects to the service.
  98. *
  99. * @param cls closure for the service
  100. * @param c the new client that connected to the service
  101. * @param mq the message queue used to send messages to the client
  102. * @return @a c
  103. */
  104. static void *
  105. client_connect_cb (void *cls,
  106. struct GNUNET_SERVICE_Client *c,
  107. struct GNUNET_MQ_Handle *mq)
  108. {
  109. /* FIXME: is this really what we want here? */
  110. GNUNET_SERVICE_client_persist (c);
  111. nconn++;
  112. return c;
  113. }
  114. /**
  115. * Callback called when a client disconnected from the service
  116. *
  117. * @param cls closure for the service
  118. * @param c the client that disconnected
  119. * @param internal_cls should be equal to @a c
  120. */
  121. static void
  122. client_disconnect_cb (void *cls,
  123. struct GNUNET_SERVICE_Client *c,
  124. void *internal_cls)
  125. {
  126. nconn--;
  127. if (GNUNET_YES == in_shutdown)
  128. GNUNET_SCHEDULER_shutdown ();
  129. GNUNET_assert (c == internal_cls);
  130. }
  131. /**
  132. * Testbed setup
  133. *
  134. * @param cls closure
  135. * @param cfg configuration to use
  136. * @param service the initialized service
  137. */
  138. static void
  139. logger_run (void *cls,
  140. const struct GNUNET_CONFIGURATION_Handle *cfg,
  141. struct GNUNET_SERVICE_Handle *service)
  142. {
  143. char *dir;
  144. char *fn;
  145. char *hname;
  146. size_t hname_len;
  147. pid_t pid;
  148. if (GNUNET_OK !=
  149. GNUNET_CONFIGURATION_get_value_filename (cfg,
  150. "TESTBED-LOGGER",
  151. "DIR",
  152. &dir))
  153. {
  154. GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
  155. "TESTBED-LOGGER",
  156. "DIR");
  157. GNUNET_SCHEDULER_shutdown ();
  158. return;
  159. }
  160. pid = getpid ();
  161. hname_len = GNUNET_OS_get_hostname_max_length ();
  162. hname = GNUNET_malloc (hname_len);
  163. if (0 != gethostname (hname,
  164. hname_len))
  165. {
  166. LOG (GNUNET_ERROR_TYPE_ERROR,
  167. "Cannot get hostname. Exiting\n");
  168. GNUNET_free (hname);
  169. GNUNET_free (dir);
  170. GNUNET_SCHEDULER_shutdown ();
  171. return;
  172. }
  173. GNUNET_asprintf (&fn,
  174. "%s/%.*s_%jd.dat",
  175. dir,
  176. hname_len,
  177. hname,
  178. (intmax_t) pid);
  179. GNUNET_free (hname);
  180. GNUNET_free (dir);
  181. if (NULL == (bio = GNUNET_BIO_write_open_file (fn)))
  182. {
  183. GNUNET_free (fn);
  184. GNUNET_SCHEDULER_shutdown ();
  185. return;
  186. }
  187. GNUNET_free (fn);
  188. GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
  189. NULL);
  190. LOG_DEBUG ("TESTBED-LOGGER startup complete\n");
  191. }
  192. /**
  193. * Define "main" method using service macro.
  194. */
  195. GNUNET_SERVICE_MAIN
  196. ("testbed-logger",
  197. GNUNET_SERVICE_OPTION_NONE,
  198. &logger_run,
  199. &client_connect_cb,
  200. &client_disconnect_cb,
  201. NULL,
  202. GNUNET_MQ_hd_var_size (log_msg,
  203. GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG,
  204. struct GNUNET_MessageHeader,
  205. NULL),
  206. GNUNET_MQ_handler_end ());
  207. /* end of gnunet-service-testbed-logger.c */