remove speed bumps
[oweals/gnunet.git] / src / core / core_api_monitor_peers.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009-2014, 2016 GNUnet e.V.
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20
21 /**
22  * @file core/core_api_monitor_peers.c
23  * @brief implementation of the peer_iterate function
24  * @author Christian Grothoff
25  * @author Nathan Evans
26  */
27 #include "platform.h"
28 #include "gnunet_core_service.h"
29 #include "core.h"
30
31
32 /**
33  * Handle to a CORE monitoring operation.
34  */
35 struct GNUNET_CORE_MonitorHandle
36 {
37
38   /**
39    * Our configuration.
40    */
41   const struct GNUNET_CONFIGURATION_Handle *cfg;
42
43   /**
44    * Our connection to the service.
45    */
46   struct GNUNET_MQ_Handle *mq;
47
48   /**
49    * Function called with the peer.
50    */
51   GNUNET_CORE_MonitorCallback peer_cb;
52
53   /**
54    * Closure for @e peer_cb.
55    */
56   void *peer_cb_cls;
57
58 };
59
60
61 /**
62  * Protocol error, reconnect to CORE service and notify
63  * client.
64  *
65  * @param mh monitoring session to reconnect to CORE
66  */
67 static void
68 reconnect (struct GNUNET_CORE_MonitorHandle *mh);
69
70
71 /**
72  * Generic error handler, called with the appropriate error code and
73  * the same closure specified at the creation of the message queue.
74  * Not every message queue implementation supports an error handler.
75  *
76  * @param cls closure, a `struct GNUNET_CORE_MonitorHandle *`
77  * @param error error code
78  */
79 static void
80 handle_mq_error (void *cls,
81                  enum GNUNET_MQ_Error error)
82 {
83   struct GNUNET_CORE_MonitorHandle *mh = cls;
84
85   reconnect (mh);
86 }
87
88
89 /**
90  * Receive reply from CORE service with information about a peer.
91  *
92  * @param cls our `struct  GNUNET_CORE_MonitorHandle *`
93  * @param mon_message monitor message
94  */
95 static void
96 handle_receive_info (void *cls,
97                      const struct MonitorNotifyMessage *mon_message)
98 {
99   struct GNUNET_CORE_MonitorHandle *mh = cls;
100
101   mh->peer_cb (mh->peer_cb_cls,
102                &mon_message->peer,
103                (enum GNUNET_CORE_KxState) ntohl (mon_message->state),
104                GNUNET_TIME_absolute_ntoh (mon_message->timeout));
105 }
106
107
108 /**
109  * Protocol error, reconnect to CORE service and notify
110  * client.
111  *
112  * @param mh monitoring session to reconnect to CORE
113  */
114 static void
115 reconnect (struct GNUNET_CORE_MonitorHandle *mh)
116 {
117   struct GNUNET_MQ_MessageHandler handlers[] = {
118     GNUNET_MQ_hd_fixed_size (receive_info,
119                              GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY,
120                              struct MonitorNotifyMessage,
121                              mh),
122     GNUNET_MQ_handler_end ()
123   };
124   struct GNUNET_MQ_Envelope *env;
125   struct GNUNET_MessageHeader *msg;
126
127   if (NULL != mh->mq)
128     GNUNET_MQ_destroy (mh->mq);
129   /* FIXME: use backoff? */
130   mh->mq = GNUNET_CLIENT_connect (mh->cfg,
131                                   "core",
132                                   handlers,
133                                   &handle_mq_error,
134                                   mh);
135   if (NULL == mh->mq)
136     return;
137   /* notify callback about reconnect */
138   mh->peer_cb (mh->peer_cb_cls,
139                NULL,
140                GNUNET_CORE_KX_CORE_DISCONNECT,
141                GNUNET_TIME_UNIT_FOREVER_ABS);
142   env = GNUNET_MQ_msg (msg,
143                        GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS);
144   GNUNET_MQ_send (mh->mq,
145                   env);
146 }
147
148
149 /**
150  * Monitor connectivity and KX status of all peers known to CORE.
151  * Calls @a peer_cb with the current status for each connected peer,
152  * and then once with NULL to indicate that all peers that are
153  * currently active have been handled.  After that, the iteration
154  * continues until it is cancelled.  Normal users of the CORE API are
155  * not expected to use this function.  It is different in that it
156  * truly lists all connections (including those where the KX is in
157  * progress), not just those relevant to the application.  This
158  * function is used by special applications for diagnostics.
159  *
160  * @param cfg configuration handle
161  * @param peer_cb function to call with the peer information
162  * @param peer_cb_cls closure for @a peer_cb
163  * @return NULL on error
164  */
165 struct GNUNET_CORE_MonitorHandle *
166 GNUNET_CORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
167                            GNUNET_CORE_MonitorCallback peer_cb,
168                            void *peer_cb_cls)
169 {
170   struct GNUNET_CORE_MonitorHandle *mh;
171
172   GNUNET_assert (NULL != peer_cb);
173   mh = GNUNET_new (struct GNUNET_CORE_MonitorHandle);
174   mh->cfg = cfg;
175   mh->peer_cb = peer_cb;
176   mh->peer_cb_cls = peer_cb_cls;
177   reconnect (mh);
178   if (NULL == mh->mq)
179   {
180     GNUNET_free (mh);
181     return NULL;
182   }
183   return mh;
184 }
185
186
187 /**
188  * Stop monitoring CORE activity.
189  *
190  * @param mh monitor to stop
191  */
192 void
193 GNUNET_CORE_monitor_stop (struct GNUNET_CORE_MonitorHandle *mh)
194 {
195   if (NULL != mh->mq)
196   {
197     GNUNET_MQ_destroy (mh->mq);
198     mh->mq = NULL;
199   }
200   GNUNET_free (mh);
201 }
202
203
204 /* end of core_api_monitor_peers.c */