core_api_monitor_peers.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2009-2014, 2016 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 core/core_api_monitor_peers.c
  18. * @brief implementation of the peer_iterate function
  19. * @author Christian Grothoff
  20. * @author Nathan Evans
  21. */
  22. #include "platform.h"
  23. #include "gnunet_core_service.h"
  24. #include "core.h"
  25. /**
  26. * Handle to a CORE monitoring operation.
  27. */
  28. struct GNUNET_CORE_MonitorHandle
  29. {
  30. /**
  31. * Our configuration.
  32. */
  33. const struct GNUNET_CONFIGURATION_Handle *cfg;
  34. /**
  35. * Our connection to the service.
  36. */
  37. struct GNUNET_MQ_Handle *mq;
  38. /**
  39. * Function called with the peer.
  40. */
  41. GNUNET_CORE_MonitorCallback peer_cb;
  42. /**
  43. * Closure for @e peer_cb.
  44. */
  45. void *peer_cb_cls;
  46. };
  47. /**
  48. * Protocol error, reconnect to CORE service and notify
  49. * client.
  50. *
  51. * @param mh monitoring session to reconnect to CORE
  52. */
  53. static void
  54. reconnect (struct GNUNET_CORE_MonitorHandle *mh);
  55. /**
  56. * Generic error handler, called with the appropriate error code and
  57. * the same closure specified at the creation of the message queue.
  58. * Not every message queue implementation supports an error handler.
  59. *
  60. * @param cls closure, a `struct GNUNET_CORE_MonitorHandle *`
  61. * @param error error code
  62. */
  63. static void
  64. handle_mq_error (void *cls,
  65. enum GNUNET_MQ_Error error)
  66. {
  67. struct GNUNET_CORE_MonitorHandle *mh = cls;
  68. reconnect (mh);
  69. }
  70. /**
  71. * Receive reply from CORE service with information about a peer.
  72. *
  73. * @param cls our `struct GNUNET_CORE_MonitorHandle *`
  74. * @param mon_message monitor message
  75. */
  76. static void
  77. handle_receive_info (void *cls,
  78. const struct MonitorNotifyMessage *mon_message)
  79. {
  80. struct GNUNET_CORE_MonitorHandle *mh = cls;
  81. mh->peer_cb (mh->peer_cb_cls,
  82. &mon_message->peer,
  83. (enum GNUNET_CORE_KxState) ntohl (mon_message->state),
  84. GNUNET_TIME_absolute_ntoh (mon_message->timeout));
  85. }
  86. /**
  87. * Protocol error, reconnect to CORE service and notify
  88. * client.
  89. *
  90. * @param mh monitoring session to reconnect to CORE
  91. */
  92. static void
  93. reconnect (struct GNUNET_CORE_MonitorHandle *mh)
  94. {
  95. struct GNUNET_MQ_MessageHandler handlers[] = {
  96. GNUNET_MQ_hd_fixed_size (receive_info,
  97. GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY,
  98. struct MonitorNotifyMessage,
  99. mh),
  100. GNUNET_MQ_handler_end ()
  101. };
  102. struct GNUNET_MQ_Envelope *env;
  103. struct GNUNET_MessageHeader *msg;
  104. if (NULL != mh->mq)
  105. GNUNET_MQ_destroy (mh->mq);
  106. /* FIXME: use backoff? */
  107. mh->mq = GNUNET_CLIENT_connect (mh->cfg,
  108. "core",
  109. handlers,
  110. &handle_mq_error,
  111. mh);
  112. if (NULL == mh->mq)
  113. return;
  114. /* notify callback about reconnect */
  115. if (NULL != mh->peer_cb)
  116. mh->peer_cb (mh->peer_cb_cls,
  117. NULL,
  118. GNUNET_CORE_KX_CORE_DISCONNECT,
  119. GNUNET_TIME_UNIT_FOREVER_ABS);
  120. env = GNUNET_MQ_msg (msg,
  121. GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS);
  122. GNUNET_MQ_send (mh->mq,
  123. env);
  124. }
  125. /**
  126. * Monitor connectivity and KX status of all peers known to CORE.
  127. * Calls @a peer_cb with the current status for each connected peer,
  128. * and then once with NULL to indicate that all peers that are
  129. * currently active have been handled. After that, the iteration
  130. * continues until it is cancelled. Normal users of the CORE API are
  131. * not expected to use this function. It is different in that it
  132. * truly lists all connections (including those where the KX is in
  133. * progress), not just those relevant to the application. This
  134. * function is used by special applications for diagnostics.
  135. *
  136. * @param cfg configuration handle
  137. * @param peer_cb function to call with the peer information
  138. * @param peer_cb_cls closure for @a peer_cb
  139. * @return NULL on error
  140. */
  141. struct GNUNET_CORE_MonitorHandle *
  142. GNUNET_CORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
  143. GNUNET_CORE_MonitorCallback peer_cb,
  144. void *peer_cb_cls)
  145. {
  146. struct GNUNET_CORE_MonitorHandle *mh;
  147. GNUNET_assert (NULL != peer_cb);
  148. mh = GNUNET_new (struct GNUNET_CORE_MonitorHandle);
  149. mh->cfg = cfg;
  150. reconnect (mh);
  151. mh->peer_cb = peer_cb;
  152. mh->peer_cb_cls = peer_cb_cls;
  153. if (NULL == mh->mq)
  154. {
  155. GNUNET_free (mh);
  156. return NULL;
  157. }
  158. return mh;
  159. }
  160. /**
  161. * Stop monitoring CORE activity.
  162. *
  163. * @param mh monitor to stop
  164. */
  165. void
  166. GNUNET_CORE_monitor_stop (struct GNUNET_CORE_MonitorHandle *mh)
  167. {
  168. if (NULL != mh->mq)
  169. {
  170. GNUNET_MQ_destroy (mh->mq);
  171. mh->mq = NULL;
  172. }
  173. GNUNET_free (mh);
  174. }
  175. /* end of core_api_monitor_peers.c */