aboutsummaryrefslogtreecommitdiff
path: root/src/core/core_api_iterate_peers.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-04-11 11:49:51 +0000
committerChristian Grothoff <christian@grothoff.org>2014-04-11 11:49:51 +0000
commit24712c94e185b72c30da25ea1b3a1784bde0defa (patch)
tree1ca399a023e0cdf48dbf9b411bb4b245081a1100 /src/core/core_api_iterate_peers.c
parenta61a4e0ffd7d563f3ae4d758f06a894edee71f58 (diff)
downloadgnunet-24712c94e185b72c30da25ea1b3a1784bde0defa.tar.gz
gnunet-24712c94e185b72c30da25ea1b3a1784bde0defa.zip
towards fixing #3363: replacing old iteration API with new monitoring API for core (needs testing, gnunet-core incomplete)
Diffstat (limited to 'src/core/core_api_iterate_peers.c')
-rw-r--r--src/core/core_api_iterate_peers.c242
1 files changed, 155 insertions, 87 deletions
diff --git a/src/core/core_api_iterate_peers.c b/src/core/core_api_iterate_peers.c
index 4889e638a..425d3579c 100644
--- a/src/core/core_api_iterate_peers.c
+++ b/src/core/core_api_iterate_peers.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2009, 2010 Christian Grothoff (and other contributing authors) 3 (C) 2009-2014 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -19,7 +19,7 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file core/core_api_iterate_peers.c 22 * @file core/core_api_monitor_peers.c
23 * @brief implementation of the peer_iterate function 23 * @brief implementation of the peer_iterate function
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Nathan Evans 25 * @author Nathan Evans
@@ -29,15 +29,23 @@
29#include "core.h" 29#include "core.h"
30 30
31 31
32struct GNUNET_CORE_RequestContext 32/**
33 * Handle to a CORE monitoring operation.
34 */
35struct GNUNET_CORE_MonitorHandle
33{ 36{
37
38 /**
39 * Our configuration.
40 */
41 const struct GNUNET_CONFIGURATION_Handle *cfg;
42
34 /** 43 /**
35 * Our connection to the service. 44 * Our connection to the service.
36 */ 45 */
37 struct GNUNET_CLIENT_Connection *client; 46 struct GNUNET_CLIENT_Connection *client;
38 47
39 /** 48 /**
40
41 * Handle for transmitting a request. 49 * Handle for transmitting a request.
42 */ 50 */
43 struct GNUNET_CLIENT_TransmitHandle *th; 51 struct GNUNET_CLIENT_TransmitHandle *th;
@@ -45,140 +53,200 @@ struct GNUNET_CORE_RequestContext
45 /** 53 /**
46 * Function called with the peer. 54 * Function called with the peer.
47 */ 55 */
48 GNUNET_CORE_ConnectEventHandler peer_cb; 56 GNUNET_CORE_MonitorCallback peer_cb;
49 57
50 /** 58 /**
51 * Peer to check for. 59 * Closure for @e peer_cb.
52 */ 60 */
53 struct GNUNET_PeerIdentity *peer; 61 void *peer_cb_cls;
54
55 /**
56 * Closure for peer_cb.
57 */
58 void *cb_cls;
59 62
60}; 63};
61 64
62 65
63/** 66/**
64 * Receive reply from core service with information about a peer. 67 * Transmits the monitor request to the CORE service.
68 *
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.
72 *
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
77 */
78static size_t
79transmit_monitor_request (void *cls,
80 size_t size,
81 void *buf);
82
83
84/**
85 * Protocol error, reconnect to CORE service and notify
86 * client.
87 *
88 * @param mh monitoring session to reconnect to CORE
89 */
90static void
91reconnect (struct GNUNET_CORE_MonitorHandle *mh)
92{
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);
97 mh->th =
98 GNUNET_CLIENT_notify_transmit_ready (mh->client,
99 sizeof (struct GNUNET_MessageHeader),
100 GNUNET_TIME_UNIT_FOREVER_REL,
101 GNUNET_YES,
102 &transmit_monitor_request, mh);
103 /* notify callback about reconnect */
104 mh->peer_cb (mh->peer_cb_cls,
105 NULL,
106 GNUNET_CORE_KX_CORE_DISCONNECT,
107 GNUNET_TIME_UNIT_FOREVER_ABS);
108}
109
110
111/**
112 * Receive reply from CORE service with information about a peer.
65 * 113 *
66 * @param cls our 'struct GNUNET_CORE_RequestContext *' 114 * @param cls our `struct GNUNET_CORE_MonitorHandle *`
67 * @param msg NULL on error or last entry 115 * @param msg NULL on error or last entry
68 */ 116 */
69static void 117static void
70receive_info (void *cls, const struct GNUNET_MessageHeader *msg) 118receive_info (void *cls,
119 const struct GNUNET_MessageHeader *msg)
71{ 120{
72 struct GNUNET_CORE_RequestContext *request_context = cls; 121 struct GNUNET_CORE_MonitorHandle *mh = cls;
73 const struct ConnectNotifyMessage *connect_message; 122 const struct MonitorNotifyMessage *mon_message;
74 uint16_t msize; 123 uint16_t msize;
75 124
76 /* Handle last message or error case, disconnect and clean up */ 125 if (NULL == msg)
77 if ((msg == NULL) ||
78 ((ntohs (msg->type) == GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END) &&
79 (ntohs (msg->size) == sizeof (struct GNUNET_MessageHeader))))
80 { 126 {
81 if (request_context->peer_cb != NULL) 127 reconnect (mh);
82 request_context->peer_cb (request_context->cb_cls, NULL);
83 GNUNET_CLIENT_disconnect (request_context->client);
84 GNUNET_free (request_context);
85 return; 128 return;
86 } 129 }
87
88 msize = ntohs (msg->size); 130 msize = ntohs (msg->size);
89 /* Handle incorrect message type or size, disconnect and clean up */ 131 /* Handle incorrect message type or size, disconnect and clean up */
90 if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT) || 132 if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY) ||
91 (msize < sizeof (struct ConnectNotifyMessage))) 133 (sizeof (struct MonitorNotifyMessage) != msize))
92 { 134 {
93 GNUNET_break (0); 135 GNUNET_break (0);
94 if (request_context->peer_cb != NULL) 136 reconnect (mh);
95 request_context->peer_cb (request_context->cb_cls, NULL);
96 GNUNET_CLIENT_disconnect (request_context->client);
97 GNUNET_free (request_context);
98 return; 137 return;
99 } 138 }
100 connect_message = (const struct ConnectNotifyMessage *) msg; 139 mon_message = (const struct MonitorNotifyMessage *) msg;
101 if (msize != sizeof (struct ConnectNotifyMessage)) 140 GNUNET_CLIENT_receive (mh->client,
102 { 141 &receive_info, mh,
103 GNUNET_break (0); 142 GNUNET_TIME_UNIT_FOREVER_REL);
104 if (request_context->peer_cb != NULL) 143 mh->peer_cb (mh->peer_cb_cls,
105 request_context->peer_cb (request_context->cb_cls, NULL); 144 &mon_message->peer,
106 GNUNET_CLIENT_disconnect (request_context->client); 145 (enum GNUNET_CORE_KxState) ntohl (mon_message->state),
107 GNUNET_free (request_context); 146 GNUNET_TIME_absolute_ntoh (mon_message->timeout));
108 return;
109 }
110 /* Normal case */
111 if (request_context->peer_cb != NULL)
112 request_context->peer_cb (request_context->cb_cls, &connect_message->peer);
113 GNUNET_CLIENT_receive (request_context->client, &receive_info,
114 request_context, GNUNET_TIME_UNIT_FOREVER_REL);
115} 147}
116 148
117 149
118/** 150/**
119 * Function called to notify a client about the socket 151 * Transmits the monitor request to the CORE service.
120 * begin ready to queue more data. "buf" will be
121 * NULL and "size" zero if the socket was closed for
122 * writing in the meantime.
123 * 152 *
124 * @param cls closure, always NULL 153 * Function is called to notify a client about the socket begin ready
125 * @param size number of bytes available in buf 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.
156 *
157 * @param cls closure, our `struct GNUNET_CORE_MonitorHandle *`
158 * @param size number of bytes available in @a buf
126 * @param buf where the callee should write the message 159 * @param buf where the callee should write the message
127 * @return number of bytes written to buf 160 * @return number of bytes written to @a buf
128 */ 161 */
129static size_t 162static size_t
130transmit_request (void *cls, size_t size, void *buf) 163transmit_monitor_request (void *cls,
164 size_t size,
165 void *buf)
131{ 166{
167 struct GNUNET_CORE_MonitorHandle *mh = cls;
132 struct GNUNET_MessageHeader *msg; 168 struct GNUNET_MessageHeader *msg;
133 int msize; 169 int msize;
134 170
135 msize = sizeof (struct GNUNET_MessageHeader); 171 msize = sizeof (struct GNUNET_MessageHeader);
136 if ((size < msize) || (buf == NULL)) 172 if ((size < msize) || (NULL == buf))
173 {
174 reconnect (mh);
137 return 0; 175 return 0;
176 }
138 msg = (struct GNUNET_MessageHeader *) buf; 177 msg = (struct GNUNET_MessageHeader *) buf;
139 msg->size = htons (msize); 178 msg->size = htons (msize);
140 msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS); 179 msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS);
141 180 GNUNET_CLIENT_receive (mh->client,
181 &receive_info, mh,
182 GNUNET_TIME_UNIT_FOREVER_REL);
142 return msize; 183 return msize;
143} 184}
144 185
145 186
146/** 187/**
147 * Iterate over all currently connected peers. 188 * Monitor connectivity and KX status of all peers known to CORE.
148 * Calls peer_cb with each connected peer, and then 189 * Calls @a peer_cb with the current status for each connected peer,
149 * once with NULL to indicate that all peers have 190 * and then once with NULL to indicate that all peers that are
150 * been handled. 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.
151 * 197 *
152 * @param cfg configuration to use 198 * @param cfg configuration handle
153 * @param peer_cb function to call with the peer information 199 * @param peer_cb function to call with the peer information
154 * @param cb_cls closure for @a peer_cb 200 * @param peer_cb_cls closure for @a peer_cb
155 * @return #GNUNET_OK if iterating, #GNUNET_SYSERR on error 201 * @return NULL on error
156 */ 202 */
157int 203struct GNUNET_CORE_MonitorHandle *
158GNUNET_CORE_iterate_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, 204GNUNET_CORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
159 GNUNET_CORE_ConnectEventHandler peer_cb, 205 GNUNET_CORE_MonitorCallback peer_cb,
160 void *cb_cls) 206 void *peer_cb_cls)
161{ 207{
162 struct GNUNET_CORE_RequestContext *request_context; 208 struct GNUNET_CORE_MonitorHandle *mh;
163 struct GNUNET_CLIENT_Connection *client; 209 struct GNUNET_CLIENT_Connection *client;
164 210
211 GNUNET_assert (NULL != peer_cb);
165 client = GNUNET_CLIENT_connect ("core", cfg); 212 client = GNUNET_CLIENT_connect ("core", cfg);
166 if (client == NULL) 213 if (NULL == client)
167 return GNUNET_SYSERR; 214 return NULL;
168 request_context = GNUNET_new (struct GNUNET_CORE_RequestContext); 215 mh = GNUNET_new (struct GNUNET_CORE_MonitorHandle);
169 request_context->client = client; 216 mh->cfg = cfg;
170 request_context->peer_cb = peer_cb; 217 mh->client = client;
171 request_context->cb_cls = cb_cls; 218 mh->peer_cb = peer_cb;
172 219 mh->peer_cb_cls = peer_cb_cls;
173 request_context->th = 220 mh->th =
174 GNUNET_CLIENT_notify_transmit_ready (client, 221 GNUNET_CLIENT_notify_transmit_ready (client,
175 sizeof (struct GNUNET_MessageHeader), 222 sizeof (struct GNUNET_MessageHeader),
176 GNUNET_TIME_UNIT_FOREVER_REL, 223 GNUNET_TIME_UNIT_FOREVER_REL,
177 GNUNET_YES, &transmit_request, NULL); 224 GNUNET_YES,
178 225 &transmit_monitor_request, mh);
179 GNUNET_CLIENT_receive (client, &receive_info, request_context, 226 return mh;
180 GNUNET_TIME_UNIT_FOREVER_REL);
181 return GNUNET_OK;
182} 227}
183 228
184/* end of core_api_iterate_peers.c */ 229
230/**
231 * Stop monitoring CORE activity.
232 *
233 * @param mh monitor to stop
234 */
235void
236GNUNET_CORE_monitor_stop (struct GNUNET_CORE_MonitorHandle *mh)
237{
238 if (NULL != mh->th)
239 {
240 GNUNET_CLIENT_notify_transmit_ready_cancel (mh->th);
241 mh->th = NULL;
242 }
243 if (NULL != mh->client)
244 {
245 GNUNET_CLIENT_disconnect (mh->client);
246 mh->client = NULL;
247 }
248 GNUNET_free (mh);
249}
250
251
252/* end of core_api_monitor_peers.c */