gnunet-service-testbed-logger.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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. &msg[1],
  73. ms);
  74. GNUNET_SERVICE_client_continue (client);
  75. }
  76. /**
  77. * Task to clean up and shutdown nicely
  78. *
  79. * @param cls NULL
  80. */
  81. static void
  82. shutdown_task (void *cls)
  83. {
  84. in_shutdown = GNUNET_YES;
  85. if (0 != nconn)
  86. {
  87. /* Delay shutdown if there are active connections */
  88. GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
  89. NULL);
  90. return;
  91. }
  92. GNUNET_break (GNUNET_OK ==
  93. GNUNET_BIO_write_close (bio));
  94. }
  95. /**
  96. * Callback called when a client connects to the service.
  97. *
  98. * @param cls closure for the service
  99. * @param c the new client that connected to the service
  100. * @param mq the message queue used to send messages to the client
  101. * @return @a c
  102. */
  103. static void *
  104. client_connect_cb (void *cls,
  105. struct GNUNET_SERVICE_Client *c,
  106. struct GNUNET_MQ_Handle *mq)
  107. {
  108. /* FIXME: is this really what we want here? */
  109. GNUNET_SERVICE_client_persist (c);
  110. nconn++;
  111. return c;
  112. }
  113. /**
  114. * Callback called when a client disconnected from the service
  115. *
  116. * @param cls closure for the service
  117. * @param c the client that disconnected
  118. * @param internal_cls should be equal to @a c
  119. */
  120. static void
  121. client_disconnect_cb (void *cls,
  122. struct GNUNET_SERVICE_Client *c,
  123. void *internal_cls)
  124. {
  125. nconn--;
  126. if (GNUNET_YES == in_shutdown)
  127. GNUNET_SCHEDULER_shutdown ();
  128. GNUNET_assert (c == internal_cls);
  129. }
  130. /**
  131. * Testbed setup
  132. *
  133. * @param cls closure
  134. * @param cfg configuration to use
  135. * @param service the initialized service
  136. */
  137. static void
  138. logger_run (void *cls,
  139. const struct GNUNET_CONFIGURATION_Handle *cfg,
  140. struct GNUNET_SERVICE_Handle *service)
  141. {
  142. char *dir;
  143. char *fn;
  144. char *hname;
  145. size_t hname_len;
  146. pid_t pid;
  147. if (GNUNET_OK !=
  148. GNUNET_CONFIGURATION_get_value_filename (cfg,
  149. "TESTBED-LOGGER",
  150. "DIR",
  151. &dir))
  152. {
  153. GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
  154. "TESTBED-LOGGER",
  155. "DIR");
  156. GNUNET_SCHEDULER_shutdown ();
  157. return;
  158. }
  159. pid = getpid ();
  160. hname_len = GNUNET_OS_get_hostname_max_length ();
  161. hname = GNUNET_malloc (hname_len);
  162. if (0 != gethostname (hname,
  163. hname_len))
  164. {
  165. LOG (GNUNET_ERROR_TYPE_ERROR,
  166. "Cannot get hostname. Exiting\n");
  167. GNUNET_free (hname);
  168. GNUNET_free (dir);
  169. GNUNET_SCHEDULER_shutdown ();
  170. return;
  171. }
  172. GNUNET_asprintf (&fn,
  173. "%s/%.*s_%jd.dat",
  174. dir,
  175. hname_len,
  176. hname,
  177. (intmax_t) pid);
  178. GNUNET_free (hname);
  179. GNUNET_free (dir);
  180. if (NULL == (bio = GNUNET_BIO_write_open (fn)))
  181. {
  182. GNUNET_free (fn);
  183. GNUNET_SCHEDULER_shutdown ();
  184. return;
  185. }
  186. GNUNET_free (fn);
  187. GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
  188. NULL);
  189. LOG_DEBUG ("TESTBED-LOGGER startup complete\n");
  190. }
  191. /**
  192. * Define "main" method using service macro.
  193. */
  194. GNUNET_SERVICE_MAIN
  195. ("testbed-logger",
  196. GNUNET_SERVICE_OPTION_NONE,
  197. &logger_run,
  198. &client_connect_cb,
  199. &client_disconnect_cb,
  200. NULL,
  201. GNUNET_MQ_hd_var_size (log_msg,
  202. GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG,
  203. struct GNUNET_MessageHeader,
  204. NULL),
  205. GNUNET_MQ_handler_end ());
  206. /* end of gnunet-service-testbed-logger.c */