aboutsummaryrefslogtreecommitdiff
path: root/src/peerinfo
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-06-24 13:55:46 +0000
committerChristian Grothoff <christian@grothoff.org>2016-06-24 13:55:46 +0000
commit87cc7b0d43e19da65f8947950cfbcfbea95e265e (patch)
treee65a1bf0d06c407e31fb7b419b192af098e132d3 /src/peerinfo
parentad471e4ff9c4bd212cb40aa7fd72ca0b0396ac77 (diff)
downloadgnunet-87cc7b0d43e19da65f8947950cfbcfbea95e265e.tar.gz
gnunet-87cc7b0d43e19da65f8947950cfbcfbea95e265e.zip
converting peerinfo-notify to new MQ ApI
Diffstat (limited to 'src/peerinfo')
-rw-r--r--src/peerinfo/peerinfo_api_notify.c239
1 files changed, 103 insertions, 136 deletions
diff --git a/src/peerinfo/peerinfo_api_notify.c b/src/peerinfo/peerinfo_api_notify.c
index 2a80c6c1a..479d4bd86 100644
--- a/src/peerinfo/peerinfo_api_notify.c
+++ b/src/peerinfo/peerinfo_api_notify.c
@@ -40,7 +40,7 @@ struct GNUNET_PEERINFO_NotifyContext
40 /** 40 /**
41 * Our connection to the PEERINFO service. 41 * Our connection to the PEERINFO service.
42 */ 42 */
43 struct GNUNET_CLIENT_Connection *client; 43 struct GNUNET_MQ_Handle *mq;
44 44
45 /** 45 /**
46 * Function to call with information. 46 * Function to call with information.
@@ -48,17 +48,11 @@ struct GNUNET_PEERINFO_NotifyContext
48 GNUNET_PEERINFO_Processor callback; 48 GNUNET_PEERINFO_Processor callback;
49 49
50 /** 50 /**
51 * Closure for callback. 51 * Closure for @e callback.
52 */ 52 */
53 void *callback_cls; 53 void *callback_cls;
54 54
55 /** 55 /**
56 * Handle to our initial request for message transmission to
57 * the peerinfo service.
58 */
59 struct GNUNET_CLIENT_TransmitHandle *init;
60
61 /**
62 * Configuration. 56 * Configuration.
63 */ 57 */
64 const struct GNUNET_CONFIGURATION_Handle *cfg; 58 const struct GNUNET_CONFIGURATION_Handle *cfg;
@@ -71,171 +65,144 @@ struct GNUNET_PEERINFO_NotifyContext
71 /** 65 /**
72 * Include friend only HELLOs in callbacks 66 * Include friend only HELLOs in callbacks
73 */ 67 */
74
75 int include_friend_only; 68 int include_friend_only;
76}; 69};
77 70
78 71
79/** 72/**
80 * Send a request to the peerinfo service to start being 73 * Task to re-try connecting to peerinfo.
81 * notified about all changes to peer information.
82 * 74 *
83 * @param nc our context 75 * @param cls the `struct GNUNET_PEERINFO_NotifyContext *`
84 */ 76 */
85static void 77static void
86request_notifications (struct GNUNET_PEERINFO_NotifyContext *nc); 78reconnect (void *cls);
87 79
88 80
89/** 81/**
90 * Read notifications from the client handle and pass them 82 * We encountered an error, reconnect to the service.
91 * to the callback.
92 * 83 *
93 * @param nc our context 84 * @param nc context to reconnect
94 */ 85 */
95static void 86static void
96receive_notifications (struct GNUNET_PEERINFO_NotifyContext *nc); 87do_reconnect (struct GNUNET_PEERINFO_NotifyContext *nc)
88{
89 GNUNET_MQ_destroy (nc->mq);
90 nc->mq = NULL;
91 nc->task = GNUNET_SCHEDULER_add_now (&reconnect,
92 nc);
93}
97 94
98 95
99/** 96/**
100 * Task to re-try connecting to peerinfo. 97 * We got a disconnect after asking regex to do the announcement.
98 * Retry.
101 * 99 *
102 * @param cls the `struct GNUNET_PEERINFO_NotifyContext *` 100 * @param cls the `struct GNUNET_PEERINFO_NotifyContext` to retry
101 * @param error error code
103 */ 102 */
104static void 103static void
105reconnect (void *cls) 104mq_error_handler (void *cls,
105 enum GNUNET_MQ_Error error)
106{ 106{
107 struct GNUNET_PEERINFO_NotifyContext *nc = cls; 107 struct GNUNET_PEERINFO_NotifyContext *nc = cls;
108 108
109 nc->task = NULL; 109 do_reconnect (nc);
110 nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg);
111 if (NULL == nc->client)
112 {
113 /* ugh */
114 nc->task =
115 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
116 &reconnect, nc);
117 return;
118 }
119 request_notifications (nc);
120} 110}
121 111
122 112
123/** 113/**
124 * Receive a peerinfo information message, process it and 114 * Check that a peerinfo information message is well-formed.
125 * go for more.
126 * 115 *
127 * @param cls closure 116 * @param cls closure
128 * @param msg message received, NULL on timeout or fatal error 117 * @param im message received
118 * @return #GNUNET_OK if the message is well-formed
129 */ 119 */
130static void 120static int
131process_notification (void *cls, const struct GNUNET_MessageHeader *msg) 121check_notification (void *cls,
122 const struct InfoMessage *im)
132{ 123{
133 struct GNUNET_PEERINFO_NotifyContext *nc = cls; 124 uint16_t ms = ntohs (im->header.size) - sizeof (*im);
134 const struct InfoMessage *im;
135 const struct GNUNET_HELLO_Message *hello;
136 uint16_t ms;
137 125
138 if (msg == NULL) 126 if (ms >= sizeof (struct GNUNET_MessageHeader))
139 {
140 GNUNET_CLIENT_disconnect (nc->client);
141 reconnect (nc);
142 return;
143 }
144 ms = ntohs (msg->size);
145 if ((ms < sizeof (struct InfoMessage)) ||
146 (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_PEERINFO_INFO))
147 {
148 GNUNET_break (0);
149 GNUNET_CLIENT_disconnect (nc->client);
150 nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg);
151 request_notifications (nc);
152 return;
153 }
154 im = (const struct InfoMessage *) msg;
155 hello = NULL;
156 if (ms > sizeof (struct InfoMessage) + sizeof (struct GNUNET_MessageHeader))
157 { 127 {
128 const struct GNUNET_HELLO_Message *hello;
129
158 hello = (const struct GNUNET_HELLO_Message *) &im[1]; 130 hello = (const struct GNUNET_HELLO_Message *) &im[1];
159 if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello)) 131 if (ms != GNUNET_HELLO_size (hello))
160 { 132 {
161 GNUNET_break (0); 133 GNUNET_break (0);
162 GNUNET_CLIENT_disconnect (nc->client); 134 return GNUNET_SYSERR;
163 nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg);
164 request_notifications (nc);
165 return;
166 } 135 }
136 return GNUNET_OK;
167 } 137 }
168 138 if (0 != ms)
169 LOG (GNUNET_ERROR_TYPE_DEBUG, 139 {
170 "Received information about peer `%s' from peerinfo database\n", 140 GNUNET_break (0);
171 GNUNET_i2s (&im->peer)); 141 return GNUNET_SYSERR;
172 nc->callback (nc->callback_cls, &im->peer, hello, NULL); 142 }
173 receive_notifications (nc); 143 return GNUNET_OK; /* odd... */
174} 144}
175 145
176 146
177/** 147/**
178 * Read notifications from the client handle and pass them 148 * Receive a peerinfo information message, process it.
179 * to the callback.
180 * 149 *
181 * @param nc our context 150 * @param cls closure
151 * @param im message received
182 */ 152 */
183static void 153static void
184receive_notifications (struct GNUNET_PEERINFO_NotifyContext *nc) 154handle_notification (void *cls,
185{ 155 const struct InfoMessage *im)
186 GNUNET_CLIENT_receive (nc->client, &process_notification, nc,
187 GNUNET_TIME_UNIT_FOREVER_REL);
188}
189
190
191/**
192 * Transmit our init-notify request, start receiving.
193 *
194 * @param cls closure (our 'struct GNUNET_PEERINFO_NotifyContext')
195 * @param size number of bytes available in buf
196 * @param buf where the callee should write the message
197 * @return number of bytes written to buf
198 */
199static size_t
200transmit_notify_request (void *cls, size_t size, void *buf)
201{ 156{
202 struct GNUNET_PEERINFO_NotifyContext *nc = cls; 157 struct GNUNET_PEERINFO_NotifyContext *nc = cls;
203 struct NotifyMessage nm; 158 const struct GNUNET_HELLO_Message *hello;
159 uint16_t ms = ntohs (im->header.size) - sizeof (struct InfoMessage);
204 160
205 nc->init = NULL; 161 if (0 == ms)
206 if (buf == NULL) 162 return;
207 { 163 hello = (const struct GNUNET_HELLO_Message *) &im[1];
208 GNUNET_CLIENT_disconnect (nc->client); 164 LOG (GNUNET_ERROR_TYPE_DEBUG,
209 nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg); 165 "Received information about peer `%s' from peerinfo database\n",
210 request_notifications (nc); 166 GNUNET_i2s (&im->peer));
211 return 0; 167 nc->callback (nc->callback_cls,
212 } 168 &im->peer,
213 GNUNET_assert (size >= sizeof (struct NotifyMessage)); 169 hello,
214 nm.header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY); 170 NULL);
215 nm.header.size = htons (sizeof (struct NotifyMessage));
216 nm.include_friend_only = htonl (nc->include_friend_only);
217 memcpy (buf, &nm, sizeof (struct NotifyMessage));
218 receive_notifications (nc);
219 return sizeof (struct NotifyMessage);
220} 171}
221 172
222 173
223/** 174/**
224 * Send a request to the peerinfo service to start being 175 * Task to re-try connecting to peerinfo.
225 * notified about all changes to peer information.
226 * 176 *
227 * @param nc our context 177 * @param cls the `struct GNUNET_PEERINFO_NotifyContext *`
228 */ 178 */
229static void 179static void
230request_notifications (struct GNUNET_PEERINFO_NotifyContext *nc) 180reconnect (void *cls)
231{ 181{
232 GNUNET_assert (NULL == nc->init); 182 GNUNET_MQ_hd_var_size (notification,
233 nc->init = 183 GNUNET_MESSAGE_TYPE_PEERINFO_INFO,
234 GNUNET_CLIENT_notify_transmit_ready (nc->client, 184 struct InfoMessage);
235 sizeof (struct NotifyMessage), 185 struct GNUNET_PEERINFO_NotifyContext *nc = cls;
236 GNUNET_TIME_UNIT_FOREVER_REL, 186 struct GNUNET_MQ_MessageHandler handlers[] = {
237 GNUNET_YES, &transmit_notify_request, 187 make_notification_handler (nc),
238 nc); 188 GNUNET_MQ_handler_end ()
189 };
190 struct GNUNET_MQ_Envelope *env;
191 struct NotifyMessage *nm;
192
193 nc->task = NULL;
194 nc->mq = GNUNET_CLIENT_connecT (nc->cfg,
195 "peerinfo",
196 handlers,
197 &mq_error_handler,
198 nc);
199 if (NULL == nc->mq)
200 return;
201 env = GNUNET_MQ_msg (nm,
202 GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY);
203 nm->include_friend_only = htonl (nc->include_friend_only);
204 GNUNET_MQ_send (nc->mq,
205 env);
239} 206}
240 207
241 208
@@ -244,38 +211,37 @@ request_notifications (struct GNUNET_PEERINFO_NotifyContext *nc)
244 * changes. Initially calls the given function for all known 211 * changes. Initially calls the given function for all known
245 * peers and then only signals changes. 212 * peers and then only signals changes.
246 * 213 *
247 * If include_friend_only is set to GNUNET_YES peerinfo will include HELLO 214 * If @a include_friend_only is set to #GNUNET_YES peerinfo will include HELLO
248 * messages which are intended for friend to friend mode and which do not 215 * messages which are intended for friend to friend mode and which do not
249 * have to be gossiped. Otherwise these messages are skipped. 216 * have to be gossiped. Otherwise these messages are skipped.
250 * 217 *
251 * @param cfg configuration to use 218 * @param cfg configuration to use
252 * @param include_friend_only include HELLO messages for friends only 219 * @param include_friend_only include HELLO messages for friends only
253 * @param callback the method to call for each peer 220 * @param callback the method to call for each peer
254 * @param callback_cls closure for callback 221 * @param callback_cls closure for @a callback
255 * @return NULL on error 222 * @return NULL on error
256 */ 223 */
257struct GNUNET_PEERINFO_NotifyContext * 224struct GNUNET_PEERINFO_NotifyContext *
258GNUNET_PEERINFO_notify (const struct GNUNET_CONFIGURATION_Handle *cfg, 225GNUNET_PEERINFO_notify (const struct GNUNET_CONFIGURATION_Handle *cfg,
259 int include_friend_only, 226 int include_friend_only,
260 GNUNET_PEERINFO_Processor callback, void *callback_cls) 227 GNUNET_PEERINFO_Processor callback,
228 void *callback_cls)
261{ 229{
262 struct GNUNET_PEERINFO_NotifyContext *nc; 230 struct GNUNET_PEERINFO_NotifyContext *nc;
263 struct GNUNET_CLIENT_Connection *client;
264 231
265 client = GNUNET_CLIENT_connect ("peerinfo", cfg);
266 if (client == NULL)
267 {
268 LOG (GNUNET_ERROR_TYPE_WARNING, _("Could not connect to `%s' service.\n"),
269 "peerinfo");
270 return NULL;
271 }
272 nc = GNUNET_new (struct GNUNET_PEERINFO_NotifyContext); 232 nc = GNUNET_new (struct GNUNET_PEERINFO_NotifyContext);
273 nc->cfg = cfg; 233 nc->cfg = cfg;
274 nc->client = client;
275 nc->callback = callback; 234 nc->callback = callback;
276 nc->callback_cls = callback_cls; 235 nc->callback_cls = callback_cls;
277 nc->include_friend_only = include_friend_only; 236 nc->include_friend_only = include_friend_only;
278 request_notifications (nc); 237 reconnect (nc);
238 if (NULL == nc->mq)
239 {
240 LOG (GNUNET_ERROR_TYPE_WARNING,
241 "Could not connect to PEERINFO service.\n");
242 GNUNET_free (nc);
243 return NULL;
244 }
279 return nc; 245 return nc;
280} 246}
281 247
@@ -288,15 +254,16 @@ GNUNET_PEERINFO_notify (const struct GNUNET_CONFIGURATION_Handle *cfg,
288void 254void
289GNUNET_PEERINFO_notify_cancel (struct GNUNET_PEERINFO_NotifyContext *nc) 255GNUNET_PEERINFO_notify_cancel (struct GNUNET_PEERINFO_NotifyContext *nc)
290{ 256{
291 if (NULL != nc->init) 257 if (NULL != nc->mq)
292 { 258 {
293 GNUNET_CLIENT_notify_transmit_ready_cancel (nc->init); 259 GNUNET_MQ_destroy (nc->mq);
294 nc->init = NULL; 260 nc->mq = NULL;
295 } 261 }
296 if (NULL != nc->client)
297 GNUNET_CLIENT_disconnect (nc->client);
298 if (NULL != nc->task) 262 if (NULL != nc->task)
263 {
299 GNUNET_SCHEDULER_cancel (nc->task); 264 GNUNET_SCHEDULER_cancel (nc->task);
265 nc->task = NULL;
266 }
300 GNUNET_free (nc); 267 GNUNET_free (nc);
301} 268}
302 269