diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-06-24 13:55:46 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-06-24 13:55:46 +0000 |
commit | 87cc7b0d43e19da65f8947950cfbcfbea95e265e (patch) | |
tree | e65a1bf0d06c407e31fb7b419b192af098e132d3 /src/peerinfo | |
parent | ad471e4ff9c4bd212cb40aa7fd72ca0b0396ac77 (diff) | |
download | gnunet-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.c | 239 |
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 | */ |
85 | static void | 77 | static void |
86 | request_notifications (struct GNUNET_PEERINFO_NotifyContext *nc); | 78 | reconnect (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 | */ |
95 | static void | 86 | static void |
96 | receive_notifications (struct GNUNET_PEERINFO_NotifyContext *nc); | 87 | do_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 | */ |
104 | static void | 103 | static void |
105 | reconnect (void *cls) | 104 | mq_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 | */ |
130 | static void | 120 | static int |
131 | process_notification (void *cls, const struct GNUNET_MessageHeader *msg) | 121 | check_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 | */ |
183 | static void | 153 | static void |
184 | receive_notifications (struct GNUNET_PEERINFO_NotifyContext *nc) | 154 | handle_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 | */ | ||
199 | static size_t | ||
200 | transmit_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 | */ |
229 | static void | 179 | static void |
230 | request_notifications (struct GNUNET_PEERINFO_NotifyContext *nc) | 180 | reconnect (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 | */ |
257 | struct GNUNET_PEERINFO_NotifyContext * | 224 | struct GNUNET_PEERINFO_NotifyContext * |
258 | GNUNET_PEERINFO_notify (const struct GNUNET_CONFIGURATION_Handle *cfg, | 225 | GNUNET_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, | |||
288 | void | 254 | void |
289 | GNUNET_PEERINFO_notify_cancel (struct GNUNET_PEERINFO_NotifyContext *nc) | 255 | GNUNET_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 | ||