core_api_monitor_peers.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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, enum GNUNET_MQ_Error error)
  65. {
  66. struct GNUNET_CORE_MonitorHandle *mh = cls;
  67. (void) error;
  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, const struct MonitorNotifyMessage *mon_message)
  78. {
  79. struct GNUNET_CORE_MonitorHandle *mh = cls;
  80. mh->peer_cb (mh->peer_cb_cls,
  81. &mon_message->peer,
  82. (enum GNUNET_CORE_KxState) ntohl (mon_message->state),
  83. GNUNET_TIME_absolute_ntoh (mon_message->timeout));
  84. }
  85. /**
  86. * Protocol error, reconnect to CORE service and notify
  87. * client.
  88. *
  89. * @param mh monitoring session to reconnect to CORE
  90. */
  91. static void
  92. reconnect (struct GNUNET_CORE_MonitorHandle *mh)
  93. {
  94. struct GNUNET_MQ_MessageHandler handlers[] =
  95. {GNUNET_MQ_hd_fixed_size (receive_info,
  96. GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY,
  97. struct MonitorNotifyMessage,
  98. mh),
  99. GNUNET_MQ_handler_end ()};
  100. struct GNUNET_MQ_Envelope *env;
  101. struct GNUNET_MessageHeader *msg;
  102. if (NULL != mh->mq)
  103. GNUNET_MQ_destroy (mh->mq);
  104. /* FIXME: use backoff? */
  105. mh->mq =
  106. GNUNET_CLIENT_connect (mh->cfg, "core", handlers, &handle_mq_error, mh);
  107. if (NULL == mh->mq)
  108. return;
  109. /* notify callback about reconnect */
  110. if (NULL != mh->peer_cb)
  111. mh->peer_cb (mh->peer_cb_cls,
  112. NULL,
  113. GNUNET_CORE_KX_CORE_DISCONNECT,
  114. GNUNET_TIME_UNIT_FOREVER_ABS);
  115. env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS);
  116. GNUNET_MQ_send (mh->mq, env);
  117. }
  118. /**
  119. * Monitor connectivity and KX status of all peers known to CORE.
  120. * Calls @a peer_cb with the current status for each connected peer,
  121. * and then once with NULL to indicate that all peers that are
  122. * currently active have been handled. After that, the iteration
  123. * continues until it is cancelled. Normal users of the CORE API are
  124. * not expected to use this function. It is different in that it
  125. * truly lists all connections (including those where the KX is in
  126. * progress), not just those relevant to the application. This
  127. * function is used by special applications for diagnostics.
  128. *
  129. * @param cfg configuration handle
  130. * @param peer_cb function to call with the peer information
  131. * @param peer_cb_cls closure for @a peer_cb
  132. * @return NULL on error
  133. */
  134. struct GNUNET_CORE_MonitorHandle *
  135. GNUNET_CORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
  136. GNUNET_CORE_MonitorCallback peer_cb,
  137. void *peer_cb_cls)
  138. {
  139. struct GNUNET_CORE_MonitorHandle *mh;
  140. GNUNET_assert (NULL != peer_cb);
  141. mh = GNUNET_new (struct GNUNET_CORE_MonitorHandle);
  142. mh->cfg = cfg;
  143. reconnect (mh);
  144. mh->peer_cb = peer_cb;
  145. mh->peer_cb_cls = peer_cb_cls;
  146. if (NULL == mh->mq)
  147. {
  148. GNUNET_free (mh);
  149. return NULL;
  150. }
  151. return mh;
  152. }
  153. /**
  154. * Stop monitoring CORE activity.
  155. *
  156. * @param mh monitor to stop
  157. */
  158. void
  159. GNUNET_CORE_monitor_stop (struct GNUNET_CORE_MonitorHandle *mh)
  160. {
  161. if (NULL != mh->mq)
  162. {
  163. GNUNET_MQ_destroy (mh->mq);
  164. mh->mq = NULL;
  165. }
  166. GNUNET_free (mh);
  167. }
  168. /* end of core_api_monitor_peers.c */