2 This file is part of GNUnet.
3 (C) 2009-2014 Christian Grothoff (and other contributing authors)
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.
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.
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., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file core/core_api_monitor_peers.c
23 * @brief implementation of the peer_iterate function
24 * @author Christian Grothoff
25 * @author Nathan Evans
28 #include "gnunet_core_service.h"
33 * Handle to a CORE monitoring operation.
35 struct GNUNET_CORE_MonitorHandle
41 const struct GNUNET_CONFIGURATION_Handle *cfg;
44 * Our connection to the service.
46 struct GNUNET_CLIENT_Connection *client;
49 * Handle for transmitting a request.
51 struct GNUNET_CLIENT_TransmitHandle *th;
54 * Function called with the peer.
56 GNUNET_CORE_MonitorCallback peer_cb;
59 * Closure for @e peer_cb.
67 * Transmits the monitor request to the CORE service.
69 * Function is called to notify a client about the socket begin ready
70 * to queue more data. @a buf will be NULL and @a size zero if the
71 * socket was closed for writing in the meantime.
73 * @param cls closure, our `struct GNUNET_CORE_MonitorHandle *`
74 * @param size number of bytes available in @a buf
75 * @param buf where the callee should write the message
76 * @return number of bytes written to @a buf
79 transmit_monitor_request (void *cls,
85 * Protocol error, reconnect to CORE service and notify
88 * @param mh monitoring session to reconnect to CORE
91 reconnect (struct GNUNET_CORE_MonitorHandle *mh)
93 GNUNET_CLIENT_disconnect (mh->client);
94 /* FIXME: use backoff? */
95 mh->client = GNUNET_CLIENT_connect ("core", mh->cfg);
96 GNUNET_assert (NULL != mh->client);
98 GNUNET_CLIENT_notify_transmit_ready (mh->client,
99 sizeof (struct GNUNET_MessageHeader),
100 GNUNET_TIME_UNIT_FOREVER_REL,
102 &transmit_monitor_request, mh);
103 /* notify callback about reconnect */
104 mh->peer_cb (mh->peer_cb_cls,
106 GNUNET_CORE_KX_CORE_DISCONNECT,
107 GNUNET_TIME_UNIT_FOREVER_ABS);
112 * Receive reply from CORE service with information about a peer.
114 * @param cls our `struct GNUNET_CORE_MonitorHandle *`
115 * @param msg NULL on error or last entry
118 receive_info (void *cls,
119 const struct GNUNET_MessageHeader *msg)
121 struct GNUNET_CORE_MonitorHandle *mh = cls;
122 const struct MonitorNotifyMessage *mon_message;
130 msize = ntohs (msg->size);
131 /* Handle incorrect message type or size, disconnect and clean up */
132 if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY) ||
133 (sizeof (struct MonitorNotifyMessage) != msize))
139 mon_message = (const struct MonitorNotifyMessage *) msg;
140 GNUNET_CLIENT_receive (mh->client,
142 GNUNET_TIME_UNIT_FOREVER_REL);
143 mh->peer_cb (mh->peer_cb_cls,
145 (enum GNUNET_CORE_KxState) ntohl (mon_message->state),
146 GNUNET_TIME_absolute_ntoh (mon_message->timeout));
151 * Transmits the monitor request to the CORE service.
153 * Function is called to notify a client about the socket begin ready
154 * to queue more data. @a buf will be NULL and @a size zero if the
155 * socket was closed for writing in the meantime.
157 * @param cls closure, our `struct GNUNET_CORE_MonitorHandle *`
158 * @param size number of bytes available in @a buf
159 * @param buf where the callee should write the message
160 * @return number of bytes written to @a buf
163 transmit_monitor_request (void *cls,
167 struct GNUNET_CORE_MonitorHandle *mh = cls;
168 struct GNUNET_MessageHeader *msg;
171 msize = sizeof (struct GNUNET_MessageHeader);
172 if ((size < msize) || (NULL == buf))
177 msg = (struct GNUNET_MessageHeader *) buf;
178 msg->size = htons (msize);
179 msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS);
180 GNUNET_CLIENT_receive (mh->client,
182 GNUNET_TIME_UNIT_FOREVER_REL);
188 * Monitor connectivity and KX status of all peers known to CORE.
189 * Calls @a peer_cb with the current status for each connected peer,
190 * and then once with NULL to indicate that all peers that are
191 * currently active have been handled. After that, the iteration
192 * continues until it is cancelled. Normal users of the CORE API are
193 * not expected to use this function. It is different in that it
194 * truly lists all connections (including those where the KX is in
195 * progress), not just those relevant to the application. This
196 * function is used by special applications for diagnostics.
198 * @param cfg configuration handle
199 * @param peer_cb function to call with the peer information
200 * @param peer_cb_cls closure for @a peer_cb
201 * @return NULL on error
203 struct GNUNET_CORE_MonitorHandle *
204 GNUNET_CORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
205 GNUNET_CORE_MonitorCallback peer_cb,
208 struct GNUNET_CORE_MonitorHandle *mh;
209 struct GNUNET_CLIENT_Connection *client;
211 GNUNET_assert (NULL != peer_cb);
212 client = GNUNET_CLIENT_connect ("core", cfg);
215 mh = GNUNET_new (struct GNUNET_CORE_MonitorHandle);
218 mh->peer_cb = peer_cb;
219 mh->peer_cb_cls = peer_cb_cls;
221 GNUNET_CLIENT_notify_transmit_ready (client,
222 sizeof (struct GNUNET_MessageHeader),
223 GNUNET_TIME_UNIT_FOREVER_REL,
225 &transmit_monitor_request, mh);
231 * Stop monitoring CORE activity.
233 * @param mh monitor to stop
236 GNUNET_CORE_monitor_stop (struct GNUNET_CORE_MonitorHandle *mh)
240 GNUNET_CLIENT_notify_transmit_ready_cancel (mh->th);
243 if (NULL != mh->client)
245 GNUNET_CLIENT_disconnect (mh->client);
252 /* end of core_api_monitor_peers.c */