2 This file is part of GNUnet.
3 Copyright (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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, 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;
172 msize = sizeof (struct GNUNET_MessageHeader);
173 if ((size < msize) || (NULL == buf))
178 msg = (struct GNUNET_MessageHeader *) buf;
179 msg->size = htons (msize);
180 msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS);
181 GNUNET_CLIENT_receive (mh->client,
183 GNUNET_TIME_UNIT_FOREVER_REL);
189 * Monitor connectivity and KX status of all peers known to CORE.
190 * Calls @a peer_cb with the current status for each connected peer,
191 * and then once with NULL to indicate that all peers that are
192 * currently active have been handled. After that, the iteration
193 * continues until it is cancelled. Normal users of the CORE API are
194 * not expected to use this function. It is different in that it
195 * truly lists all connections (including those where the KX is in
196 * progress), not just those relevant to the application. This
197 * function is used by special applications for diagnostics.
199 * @param cfg configuration handle
200 * @param peer_cb function to call with the peer information
201 * @param peer_cb_cls closure for @a peer_cb
202 * @return NULL on error
204 struct GNUNET_CORE_MonitorHandle *
205 GNUNET_CORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
206 GNUNET_CORE_MonitorCallback peer_cb,
209 struct GNUNET_CORE_MonitorHandle *mh;
210 struct GNUNET_CLIENT_Connection *client;
212 GNUNET_assert (NULL != peer_cb);
213 client = GNUNET_CLIENT_connect ("core", cfg);
216 mh = GNUNET_new (struct GNUNET_CORE_MonitorHandle);
219 mh->peer_cb = peer_cb;
220 mh->peer_cb_cls = peer_cb_cls;
222 GNUNET_CLIENT_notify_transmit_ready (client,
223 sizeof (struct GNUNET_MessageHeader),
224 GNUNET_TIME_UNIT_FOREVER_REL,
226 &transmit_monitor_request, mh);
232 * Stop monitoring CORE activity.
234 * @param mh monitor to stop
237 GNUNET_CORE_monitor_stop (struct GNUNET_CORE_MonitorHandle *mh)
241 GNUNET_CLIENT_notify_transmit_ready_cancel (mh->th);
244 if (NULL != mh->client)
246 GNUNET_CLIENT_disconnect (mh->client);
253 /* end of core_api_monitor_peers.c */