diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2012-03-08 14:14:01 +0000 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2012-03-08 14:14:01 +0000 |
commit | 3a60024e089a38aa32fcafece7c257672abf4608 (patch) | |
tree | a3c36e0a87766bd85e450bd1b9c8766965a34710 /src/gns/gns_api.c | |
parent | 588b14ec0ec5c59d0dad37dcc0841c1ff0b2942c (diff) | |
download | gnunet-3a60024e089a38aa32fcafece7c257672abf4608.tar.gz gnunet-3a60024e089a38aa32fcafece7c257672abf4608.zip |
-GNS service api change, replaced complicated buggy code
Diffstat (limited to 'src/gns/gns_api.c')
-rw-r--r-- | src/gns/gns_api.c | 680 |
1 files changed, 229 insertions, 451 deletions
diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c index eaae4955f..47efe5058 100644 --- a/src/gns/gns_api.c +++ b/src/gns/gns_api.c | |||
@@ -46,130 +46,54 @@ | |||
46 | #define GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT 26 | 46 | #define GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT 26 |
47 | 47 | ||
48 | /** | 48 | /** |
49 | * Entry in our list of messages to be (re-)transmitted. | 49 | * A QueueEntry. |
50 | */ | 50 | */ |
51 | struct PendingMessage | 51 | struct GNUNET_GNS_QueueEntry |
52 | { | 52 | { |
53 | /** | 53 | /** |
54 | * This is a doubly-linked list. | 54 | * DLL |
55 | */ | ||
56 | struct PendingMessage *prev; | ||
57 | |||
58 | /** | ||
59 | * This is a doubly-linked list. | ||
60 | */ | ||
61 | struct PendingMessage *next; | ||
62 | |||
63 | /** | ||
64 | * Message that is pending, allocated at the end | ||
65 | * of this struct. | ||
66 | */ | ||
67 | const struct GNUNET_MessageHeader *msg; | ||
68 | |||
69 | /** | ||
70 | * Handle to the GNS API context. | ||
71 | */ | 55 | */ |
72 | struct GNUNET_GNS_Handle *handle; | 56 | struct GNUNET_GNS_QueueEntry *next; |
73 | 57 | ||
74 | /** | ||
75 | * Continuation to call when the request has been | ||
76 | * transmitted (for the first time) to the service; can be NULL. | ||
77 | */ | ||
78 | GNUNET_SCHEDULER_Task cont; | ||
79 | |||
80 | /** | ||
81 | * Closure for 'cont'. | ||
82 | */ | ||
83 | void *cont_cls; | ||
84 | |||
85 | /** | ||
86 | * Unique ID for this request | ||
87 | */ | ||
88 | uint64_t unique_id; | ||
89 | |||
90 | /** | ||
91 | * Free the saved message once sent, set to GNUNET_YES for messages | ||
92 | * that do not receive responses; GNUNET_NO if this pending message | ||
93 | * is aliased from a 'struct GNUNET_DHT_RouteHandle' and will be freed | ||
94 | * from there. | ||
95 | */ | ||
96 | |||
97 | int free_on_send; | ||
98 | /** | ||
99 | * GNUNET_YES if this message is in our pending queue right now. | ||
100 | */ | ||
101 | int in_pending_queue; | ||
102 | |||
103 | }; | ||
104 | |||
105 | /** | ||
106 | * Handle to a Lookup request | ||
107 | */ | ||
108 | struct GNUNET_GNS_LookupHandle | ||
109 | { | ||
110 | |||
111 | /** | ||
112 | * Iterator to call on data receipt | ||
113 | */ | ||
114 | GNUNET_GNS_LookupIterator iter; | ||
115 | |||
116 | /** | 58 | /** |
117 | * Closure for the iterator callback | 59 | * DLL |
118 | */ | 60 | */ |
119 | void *iter_cls; | 61 | struct GNUNET_GNS_QueueEntry *prev; |
120 | 62 | ||
121 | /** | 63 | /* request id */ |
122 | * Main handle to this GNS api | 64 | uint32_t r_id; |
123 | */ | 65 | |
66 | /* handle to gns */ | ||
124 | struct GNUNET_GNS_Handle *gns_handle; | 67 | struct GNUNET_GNS_Handle *gns_handle; |
125 | 68 | ||
126 | /** | 69 | /* processor to call on shorten result */ |
127 | * Key that this get request is for | 70 | GNUNET_GNS_ShortenResultProcessor proc; |
128 | */ | 71 | |
129 | GNUNET_HashCode key; | 72 | /* processor closure */ |
130 | 73 | void *proc_cls; | |
131 | /** | 74 | |
132 | * Unique identifier for this request (for key collisions). | ||
133 | */ | ||
134 | uint64_t unique_id; | ||
135 | |||
136 | struct PendingMessage *message; | ||
137 | |||
138 | }; | 75 | }; |
139 | 76 | ||
140 | 77 | ||
141 | /** | 78 | /** |
142 | * Handle to a shorten request | 79 | * Entry in our list of messages to be (re-)transmitted. |
143 | */ | 80 | */ |
144 | struct GNUNET_GNS_ShortenHandle | 81 | struct PendingMessage |
145 | { | 82 | { |
146 | |||
147 | /** | ||
148 | * Processor to call on data receipt | ||
149 | */ | ||
150 | GNUNET_GNS_ShortenResultProcessor proc; | ||
151 | |||
152 | /** | 83 | /** |
153 | * Closure for the processor | 84 | * This is a doubly-linked list. |
154 | */ | ||
155 | void *proc_cls; | ||
156 | |||
157 | /** | ||
158 | * Main handle to this GNS api | ||
159 | */ | 85 | */ |
160 | struct GNUNET_GNS_Handle *gns_handle; | 86 | struct PendingMessage *prev; |
161 | 87 | ||
162 | /** | 88 | /** |
163 | * Key that this get request is for | 89 | * This is a doubly-linked list. |
164 | */ | 90 | */ |
165 | GNUNET_HashCode key; | 91 | struct PendingMessage *next; |
166 | 92 | ||
167 | /** | 93 | /** |
168 | * Unique identifier for this request (for key collisions). | 94 | * Size of the message. |
169 | */ | 95 | */ |
170 | uint64_t unique_id; | 96 | size_t size; |
171 | |||
172 | struct PendingMessage *message; | ||
173 | 97 | ||
174 | }; | 98 | }; |
175 | 99 | ||
@@ -194,40 +118,53 @@ struct GNUNET_GNS_Handle | |||
194 | * Currently pending transmission request (or NULL). | 118 | * Currently pending transmission request (or NULL). |
195 | */ | 119 | */ |
196 | struct GNUNET_CLIENT_TransmitHandle *th; | 120 | struct GNUNET_CLIENT_TransmitHandle *th; |
197 | 121 | ||
122 | uint32_t r_id; | ||
123 | |||
198 | /** | 124 | /** |
199 | * Head of linked list of messages we would like to transmit. | 125 | * Head of linked list of shorten messages we would like to transmit. |
200 | */ | 126 | */ |
201 | struct PendingMessage *pending_head; | 127 | struct PendingMessage *pending_head; |
202 | 128 | ||
203 | /** | 129 | /** |
204 | * Tail of linked list of messages we would like to transmit. | 130 | * Tail of linked list of shorten messages we would like to transmit. |
205 | */ | 131 | */ |
206 | struct PendingMessage *pending_tail; | 132 | struct PendingMessage *pending_tail; |
207 | 133 | ||
208 | /** | 134 | /** |
209 | * Hash maps containing the current outstanding unique requests. | 135 | * Head of linked list of shorten messages we would like to transmit. |
210 | */ | 136 | */ |
211 | struct GNUNET_CONTAINER_MultiHashMap *active_lookup_requests; | 137 | struct GNUNET_GNS_QueueEntry *shorten_head; |
212 | struct GNUNET_CONTAINER_MultiHashMap *active_shorten_requests; | ||
213 | |||
214 | GNUNET_SCHEDULER_TaskIdentifier reconnect_task; | ||
215 | 138 | ||
216 | /** | 139 | /** |
217 | * How quickly should we retry? Used for exponential back-off on | 140 | * Tail of linked list of shorten messages we would like to transmit. |
218 | * connect-errors. | 141 | */ |
142 | struct GNUNET_GNS_QueueEntry *shorten_tail; | ||
143 | |||
144 | /** | ||
145 | * Head of linked list of lookup messages we would like to transmit. | ||
219 | */ | 146 | */ |
220 | struct GNUNET_TIME_Relative retry_time; | 147 | struct GNUNET_GNS_QueueEntry *lookup_head; |
221 | 148 | ||
222 | /** | 149 | /** |
223 | * Generator for unique ids. | 150 | * Tail of linked list of lookup messages we would like to transmit. |
224 | */ | 151 | */ |
225 | uint64_t uid_gen; | 152 | struct GNUNET_GNS_QueueEntry *lookup_tail; |
153 | |||
154 | /** | ||
155 | * Reconnect task | ||
156 | */ | ||
157 | GNUNET_SCHEDULER_TaskIdentifier reconnect_task; | ||
226 | 158 | ||
227 | /** | 159 | /** |
228 | * Did we start our receive loop yet? | 160 | * Did we start our receive loop yet? |
229 | */ | 161 | */ |
230 | int in_receive; | 162 | int in_receive; |
163 | |||
164 | /** | ||
165 | * Reconnect necessary | ||
166 | */ | ||
167 | int reconnect; | ||
231 | }; | 168 | }; |
232 | 169 | ||
233 | /** | 170 | /** |
@@ -237,140 +174,52 @@ struct GNUNET_GNS_Handle | |||
237 | static void | 174 | static void |
238 | process_pending_messages (struct GNUNET_GNS_Handle *handle); | 175 | process_pending_messages (struct GNUNET_GNS_Handle *handle); |
239 | 176 | ||
240 | /** | ||
241 | * Try to (re)connect to the GNS service. | ||
242 | * | ||
243 | * @return GNUNET_YES on success, GNUNET_NO on failure. | ||
244 | */ | ||
245 | static int | ||
246 | try_connect (struct GNUNET_GNS_Handle *handle) | ||
247 | { | ||
248 | if (handle->client != NULL) | ||
249 | return GNUNET_OK; | ||
250 | handle->in_receive = GNUNET_NO; | ||
251 | handle->client = GNUNET_CLIENT_connect ("gns", handle->cfg); | ||
252 | if (handle->client == NULL) | ||
253 | { | ||
254 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
255 | _("Failed to connect to the GNS service!\n")); | ||
256 | return GNUNET_NO; | ||
257 | } | ||
258 | return GNUNET_YES; | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * Add the request corresponding to the given handle | ||
263 | * to the pending queue (if it is not already in there). | ||
264 | * | ||
265 | * @param cls the 'struct GNUNET_GNS_Handle*' | ||
266 | * @param key key for the request (not used) | ||
267 | * @param value the 'struct GNUNET_GNS_LookupHandle*' | ||
268 | * @return GNUNET_YES (always) | ||
269 | */ | ||
270 | static int | ||
271 | add_lookup_request_to_pending (void *cls, const GNUNET_HashCode * key, | ||
272 | void *value) | ||
273 | { | ||
274 | struct GNUNET_GNS_Handle *handle = cls; | ||
275 | struct GNUNET_GNS_LookupHandle *lh = value; | ||
276 | |||
277 | if (GNUNET_NO == lh->message->in_pending_queue) | ||
278 | { | ||
279 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
280 | "Retransmitting request related to %s to GNS %p\n", GNUNET_h2s(key), | ||
281 | handle); | ||
282 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, | ||
283 | lh->message); | ||
284 | lh->message->in_pending_queue = GNUNET_YES; | ||
285 | } | ||
286 | return GNUNET_YES; | ||
287 | } | ||
288 | |||
289 | 177 | ||
290 | /** | 178 | /** |
291 | * Add the request corresponding to the given handle | 179 | * Reconnect to GNS service. |
292 | * to the pending queue (if it is not already in there). | ||
293 | * | 180 | * |
294 | * @param cls the 'struct GNUNET_GNS_Handle*' | 181 | * @param h the handle to the namestore service |
295 | * @param key key for the request (not used) | ||
296 | * @param value the 'struct GNUNET_GNS_ShortenHandle*' | ||
297 | * @return GNUNET_YES (always) | ||
298 | */ | 182 | */ |
299 | static int | 183 | static void |
300 | add_shorten_request_to_pending (void *cls, const GNUNET_HashCode * key, | 184 | reconnect (struct GNUNET_GNS_Handle *h) |
301 | void *value) | ||
302 | { | 185 | { |
303 | struct GNUNET_GNS_Handle *handle = cls; | 186 | GNUNET_assert (NULL == h->client); |
304 | struct GNUNET_GNS_ShortenHandle *sh = value; | 187 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
305 | 188 | "Trying to connect to GNS...\n"); | |
306 | if (GNUNET_NO == sh->message->in_pending_queue) | 189 | h->client = GNUNET_CLIENT_connect ("gns", h->cfg); |
307 | { | 190 | GNUNET_assert (NULL != h->client); |
308 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
309 | "Retransmitting shorten request related to %s to GNS %p\n", | ||
310 | GNUNET_h2s(key), | ||
311 | handle); | ||
312 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, | ||
313 | sh->message); | ||
314 | sh->message->in_pending_queue = GNUNET_YES; | ||
315 | } | ||
316 | return GNUNET_YES; | ||
317 | } | 191 | } |
318 | 192 | ||
319 | |||
320 | /** | 193 | /** |
321 | * Try reconnecting to the GNS service. | 194 | * Reconnect to GNS |
322 | * | 195 | * |
323 | * @param cls GNUNET_GNS_Handle | 196 | * @param cls the handle |
324 | * @param tc scheduler context | 197 | * @param tc task context |
325 | */ | 198 | */ |
326 | static void | 199 | static void |
327 | try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 200 | reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
328 | { | 201 | { |
329 | struct GNUNET_GNS_Handle *handle = cls; | 202 | struct GNUNET_GNS_Handle *h = cls; |
330 | 203 | ||
331 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting with GNS %p\n", handle); | 204 | h->reconnect_task = GNUNET_SCHEDULER_NO_TASK; |
332 | handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; | 205 | reconnect (h); |
333 | if (handle->retry_time.rel_value < GNUNET_CONSTANTS_SERVICE_RETRY.rel_value) | ||
334 | handle->retry_time = GNUNET_CONSTANTS_SERVICE_RETRY; | ||
335 | else | ||
336 | handle->retry_time = GNUNET_TIME_relative_multiply (handle->retry_time, 2); | ||
337 | if (handle->retry_time.rel_value > GNUNET_CONSTANTS_SERVICE_TIMEOUT.rel_value) | ||
338 | handle->retry_time = GNUNET_CONSTANTS_SERVICE_TIMEOUT; | ||
339 | handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; | ||
340 | if (GNUNET_YES != try_connect (handle)) | ||
341 | { | ||
342 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNS reconnect failed(!)\n"); | ||
343 | return; | ||
344 | } | ||
345 | GNUNET_CONTAINER_multihashmap_iterate (handle->active_lookup_requests, | ||
346 | &add_lookup_request_to_pending, handle); | ||
347 | GNUNET_CONTAINER_multihashmap_iterate (handle->active_shorten_requests, | ||
348 | &add_shorten_request_to_pending, handle); | ||
349 | process_pending_messages (handle); | ||
350 | } | 206 | } |
351 | 207 | ||
352 | 208 | ||
353 | /** | 209 | /** |
354 | * Try reconnecting to the GNS service. | 210 | * Disconnect from service and then reconnect. |
355 | * | 211 | * |
356 | * @param handle handle to gns to (possibly) disconnect and reconnect | 212 | * @param h our handle |
357 | */ | 213 | */ |
358 | static void | 214 | static void |
359 | do_disconnect (struct GNUNET_GNS_Handle *handle) | 215 | force_reconnect (struct GNUNET_GNS_Handle *h) |
360 | { | 216 | { |
361 | if (handle->client == NULL) | 217 | h->reconnect = GNUNET_NO; |
362 | return; | 218 | GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); |
363 | GNUNET_assert (handle->reconnect_task == GNUNET_SCHEDULER_NO_TASK); | 219 | h->client = NULL; |
364 | if (NULL != handle->th) | 220 | h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, |
365 | GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th); | 221 | &reconnect_task, |
366 | handle->th = NULL; | 222 | h); |
367 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
368 | "Disconnecting from GNS service, will try to reconnect in %llu ms\n", | ||
369 | (unsigned long long) handle->retry_time.rel_value); | ||
370 | GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO); | ||
371 | handle->client = NULL; | ||
372 | handle->reconnect_task = | ||
373 | GNUNET_SCHEDULER_add_delayed (handle->retry_time, &try_reconnect, handle); | ||
374 | } | 223 | } |
375 | 224 | ||
376 | /** | 225 | /** |
@@ -386,7 +235,7 @@ transmit_pending (void *cls, size_t size, void *buf); | |||
386 | * @param msg the incoming message | 235 | * @param msg the incoming message |
387 | */ | 236 | */ |
388 | static void | 237 | static void |
389 | message_handler (void *cls, const struct GNUNET_MessageHeader *msg); | 238 | process_message (void *cls, const struct GNUNET_MessageHeader *msg); |
390 | 239 | ||
391 | /** | 240 | /** |
392 | * Try to send messages from list of messages to send | 241 | * Try to send messages from list of messages to send |
@@ -394,33 +243,35 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg); | |||
394 | static void | 243 | static void |
395 | process_pending_messages (struct GNUNET_GNS_Handle *handle) | 244 | process_pending_messages (struct GNUNET_GNS_Handle *handle) |
396 | { | 245 | { |
397 | struct PendingMessage *head; | 246 | struct PendingMessage *p; |
398 | 247 | ||
399 | if (handle->client == NULL) | 248 | if (handle->client == NULL) |
400 | { | 249 | { |
401 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 250 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
402 | "process_pending_messages called, but client is null, reconnecting\n"); | 251 | "process_pending_messages called, but client is null\n"); |
403 | do_disconnect (handle); | ||
404 | return; | 252 | return; |
405 | } | 253 | } |
406 | 254 | ||
407 | if (handle->th != NULL) | 255 | if (handle->th != NULL) |
408 | return; | 256 | return; |
409 | 257 | ||
410 | if (NULL == (head = handle->pending_head)) | 258 | if (NULL == (p = handle->pending_head)) |
411 | return; | 259 | return; |
412 | 260 | ||
261 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
262 | "Trying to transmit %d bytes...\n", p->size); | ||
263 | |||
413 | handle->th = | 264 | handle->th = |
414 | GNUNET_CLIENT_notify_transmit_ready (handle->client, | 265 | GNUNET_CLIENT_notify_transmit_ready (handle->client, |
415 | ntohs (head->msg->size), | 266 | p->size, |
416 | GNUNET_TIME_UNIT_FOREVER_REL, | 267 | GNUNET_TIME_UNIT_FOREVER_REL, |
417 | GNUNET_YES, &transmit_pending, | 268 | GNUNET_NO, &transmit_pending, |
418 | handle); | 269 | handle); |
419 | if (NULL != handle->th) | 270 | if (NULL != handle->th) |
420 | return; | 271 | return; |
421 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 272 | |
422 | "notify_transmit_ready returned NULL, reconnecting\n"); | 273 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
423 | do_disconnect (handle); | 274 | "notify_transmit_ready returned NULL!\n"); |
424 | } | 275 | } |
425 | 276 | ||
426 | 277 | ||
@@ -431,53 +282,45 @@ static size_t | |||
431 | transmit_pending (void *cls, size_t size, void *buf) | 282 | transmit_pending (void *cls, size_t size, void *buf) |
432 | { | 283 | { |
433 | struct GNUNET_GNS_Handle *handle = cls; | 284 | struct GNUNET_GNS_Handle *handle = cls; |
434 | struct PendingMessage *head; | 285 | struct PendingMessage *p; |
435 | size_t tsize; | 286 | size_t tsize; |
287 | char *cbuf; | ||
436 | 288 | ||
437 | handle->th = NULL; | 289 | handle->th = NULL; |
438 | 290 | ||
439 | if (buf == NULL) | 291 | if ((size == 0) || (buf == NULL)) |
440 | { | 292 | { |
441 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 293 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
442 | "Transmission to GNS service failed! Reconnecting!\n"); | 294 | "Transmission to GNS service failed!\n"); |
443 | do_disconnect (handle); | 295 | force_reconnect(handle); |
444 | return 0; | 296 | return 0; |
445 | } | 297 | } |
446 | 298 | ||
447 | if (NULL == (head = handle->pending_head)) | 299 | tsize = 0; |
300 | cbuf = buf; | ||
301 | |||
302 | if (NULL == (p = handle->pending_head)) | ||
448 | return 0; | 303 | return 0; |
449 | 304 | ||
450 | tsize = ntohs (head->msg->size); | 305 | while ((NULL != (p = handle->pending_head)) && (p->size <= size)) |
451 | |||
452 | if (size < tsize) | ||
453 | { | 306 | { |
454 | process_pending_messages (handle); | 307 | memcpy (&cbuf[tsize], &p[1], p->size); |
455 | return 0; | 308 | tsize += p->size; |
309 | size -= p->size; | ||
310 | GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail, p); | ||
311 | if (GNUNET_YES != handle->in_receive) | ||
312 | { | ||
313 | GNUNET_CLIENT_receive (handle->client, &process_message, handle, | ||
314 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
315 | handle->in_receive = GNUNET_YES; | ||
316 | } | ||
317 | GNUNET_free(p); | ||
456 | } | 318 | } |
457 | |||
458 | memcpy (buf, head->msg, tsize); | ||
459 | |||
460 | GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail, | ||
461 | head); | ||
462 | |||
463 | head->in_pending_queue = GNUNET_NO; | ||
464 | |||
465 | if (GNUNET_YES == head->free_on_send) | ||
466 | GNUNET_free (head); | ||
467 | 319 | ||
468 | process_pending_messages (handle); | ||
469 | |||
470 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 320 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
471 | "Forwarded request of %u bytes to GNS service\n", (unsigned int) tsize); | 321 | "Sending %d bytes\n", tsize); |
472 | 322 | ||
473 | if (GNUNET_NO == handle->in_receive) | 323 | process_pending_messages(handle); |
474 | { | ||
475 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
476 | "Starting to process replies from GNS\n"); | ||
477 | handle->in_receive = GNUNET_YES; | ||
478 | GNUNET_CLIENT_receive (handle->client, &message_handler, handle, | ||
479 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
480 | } | ||
481 | return tsize; | 324 | return tsize; |
482 | } | 325 | } |
483 | 326 | ||
@@ -488,49 +331,32 @@ transmit_pending (void *cls, size_t size, void *buf) | |||
488 | * @param cls the 'struct GNUNET_GNS_ClientResultMessage' | 331 | * @param cls the 'struct GNUNET_GNS_ClientResultMessage' |
489 | * @param key query of the request | 332 | * @param key query of the request |
490 | * @param value the 'struct GNUNET_GNS_LookupHandle' of a request matching the same key | 333 | * @param value the 'struct GNUNET_GNS_LookupHandle' of a request matching the same key |
491 | * @return GNUNET_YES to continue to iterate over all results, | ||
492 | * GNUNET_NO if the reply is malformed | ||
493 | */ | 334 | */ |
494 | static int | 335 | static void |
495 | process_shorten_reply (void *cls, const GNUNET_HashCode * key, void *value) | 336 | process_shorten_reply (struct GNUNET_GNS_QueueEntry *qe, |
337 | const struct GNUNET_GNS_ClientShortenResultMessage *msg) | ||
496 | { | 338 | { |
497 | const struct GNUNET_GNS_ClientShortenResultMessage *gns_msg = cls; | 339 | struct GNUNET_GNS_Handle *h = qe->gns_handle; |
498 | struct GNUNET_GNS_ShortenHandle *shorten_handle = value; | ||
499 | const char *name = (const char*)&((struct GNUNET_GNS_ClientShortenMessage *) &((shorten_handle->message)[1]))[1]; //FIXME | ||
500 | const char *short_name; | 340 | const char *short_name; |
501 | 341 | ||
502 | if (ntohs (((struct GNUNET_MessageHeader*)gns_msg)->size) < | 342 | GNUNET_CONTAINER_DLL_remove(h->shorten_head, h->shorten_tail, qe); |
343 | |||
344 | short_name = (char*)(&msg[1]); | ||
345 | |||
346 | if (ntohs (((struct GNUNET_MessageHeader*)msg)->size) < | ||
503 | sizeof (struct GNUNET_GNS_ClientShortenResultMessage)) | 347 | sizeof (struct GNUNET_GNS_ClientShortenResultMessage)) |
504 | { | 348 | { |
505 | GNUNET_break (0); | 349 | GNUNET_break (0); |
506 | do_disconnect (shorten_handle->gns_handle); | 350 | force_reconnect (h); |
507 | return GNUNET_NO; | 351 | return; |
508 | } | ||
509 | |||
510 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
511 | "Received reply for `%s' from GNS service\n", | ||
512 | name); | ||
513 | |||
514 | if (gns_msg->unique_id != shorten_handle->unique_id) | ||
515 | { | ||
516 | /* UID mismatch */ | ||
517 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
518 | "Ignoring reply for %s: UID mismatch: %llu/%llu\n", GNUNET_h2s (key), | ||
519 | gns_msg->unique_id, shorten_handle->unique_id); | ||
520 | return GNUNET_YES; | ||
521 | } | 352 | } |
522 | short_name = (char*)&gns_msg[1]; | ||
523 | 353 | ||
524 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 354 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
525 | "Giving shorten reply %s for %s to application\n", | 355 | "Received shortened reply `%s' from GNS service\n", |
526 | short_name, name); | 356 | short_name); |
527 | 357 | ||
528 | shorten_handle->proc (shorten_handle->proc_cls, name, short_name); | 358 | qe->proc(qe->proc_cls, short_name); |
529 | 359 | ||
530 | GNUNET_CLIENT_receive (shorten_handle->gns_handle->client, | ||
531 | &message_handler, shorten_handle->gns_handle, | ||
532 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
533 | return GNUNET_YES; | ||
534 | } | 360 | } |
535 | 361 | ||
536 | 362 | ||
@@ -543,48 +369,10 @@ process_shorten_reply (void *cls, const GNUNET_HashCode * key, void *value) | |||
543 | * @return GNUNET_YES to continue to iterate over all results, | 369 | * @return GNUNET_YES to continue to iterate over all results, |
544 | * GNUNET_NO if the reply is malformed | 370 | * GNUNET_NO if the reply is malformed |
545 | */ | 371 | */ |
546 | static int | 372 | static void |
547 | process_lookup_reply (void *cls, const GNUNET_HashCode * key, void *value) | 373 | process_lookup_reply (struct GNUNET_GNS_QueueEntry *qe, |
374 | const struct GNUNET_GNS_ClientLookupResultMessage *msg) | ||
548 | { | 375 | { |
549 | const struct GNUNET_GNS_ClientLookupResultMessage *gns_msg = cls; | ||
550 | struct GNUNET_GNS_LookupHandle *lookup_handle = value; | ||
551 | const char *name = (const char*) &lookup_handle[1]; | ||
552 | struct GNUNET_NAMESTORE_RecordData *rd; | ||
553 | uint32_t rd_count; | ||
554 | |||
555 | if (ntohs (((struct GNUNET_MessageHeader*)gns_msg)->size) < | ||
556 | sizeof (struct GNUNET_GNS_ClientLookupResultMessage)) | ||
557 | { | ||
558 | GNUNET_break (0); | ||
559 | do_disconnect (lookup_handle->gns_handle); | ||
560 | return GNUNET_NO; | ||
561 | } | ||
562 | |||
563 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
564 | "Received lookup reply for `%s' from GNS service %p\n", | ||
565 | name, lookup_handle->gns_handle); | ||
566 | |||
567 | if (gns_msg->unique_id != lookup_handle->unique_id) | ||
568 | { | ||
569 | /* UID mismatch */ | ||
570 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
571 | "Ignoring reply for %s: UID mismatch: %llu/%llu\n", GNUNET_h2s (key), | ||
572 | gns_msg->unique_id, lookup_handle->unique_id); | ||
573 | return GNUNET_YES; | ||
574 | } | ||
575 | |||
576 | rd_count = ntohl(gns_msg->rd_count); | ||
577 | rd = (struct GNUNET_NAMESTORE_RecordData*)&gns_msg[1]; | ||
578 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
579 | "Giving lookup reply for %s to application\n", | ||
580 | name); | ||
581 | |||
582 | lookup_handle->iter (lookup_handle->iter_cls, name, rd_count, rd); | ||
583 | |||
584 | GNUNET_CLIENT_receive (lookup_handle->gns_handle->client, &message_handler, | ||
585 | lookup_handle->gns_handle, | ||
586 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
587 | return GNUNET_YES; | ||
588 | } | 376 | } |
589 | 377 | ||
590 | /** | 378 | /** |
@@ -594,11 +382,15 @@ process_lookup_reply (void *cls, const GNUNET_HashCode * key, void *value) | |||
594 | * @param msg the incoming message | 382 | * @param msg the incoming message |
595 | */ | 383 | */ |
596 | static void | 384 | static void |
597 | message_handler (void *cls, const struct GNUNET_MessageHeader *msg) | 385 | process_message (void *cls, const struct GNUNET_MessageHeader *msg) |
598 | { | 386 | { |
599 | struct GNUNET_GNS_Handle *handle = cls; | 387 | struct GNUNET_GNS_Handle *handle = cls; |
388 | struct GNUNET_GNS_QueueEntry *qe; | ||
600 | const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg; | 389 | const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg; |
601 | const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg; | 390 | const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg; |
391 | uint16_t size; | ||
392 | uint16_t type; | ||
393 | uint32_t r_id; | ||
602 | 394 | ||
603 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 395 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
604 | "Got message\n"); | 396 | "Got message\n"); |
@@ -606,36 +398,68 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg) | |||
606 | { | 398 | { |
607 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 399 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
608 | "Error receiving data from GNS service, reconnecting\n"); | 400 | "Error receiving data from GNS service, reconnecting\n"); |
609 | do_disconnect (handle); | 401 | force_reconnect (handle); |
610 | return; | 402 | return; |
611 | } | 403 | } |
612 | 404 | ||
613 | if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT) | 405 | size = ntohs (msg->size); |
406 | type = ntohs (msg->type); | ||
407 | |||
408 | if (type == GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT) | ||
614 | { | 409 | { |
615 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 410 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
616 | "Got lookup msg\n"); | 411 | "Got lookup msg\n"); |
617 | lookup_msg = (const struct GNUNET_GNS_ClientLookupResultMessage *) msg; | 412 | lookup_msg = (const struct GNUNET_GNS_ClientLookupResultMessage *) msg; |
618 | GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_lookup_requests, | 413 | r_id = ntohl (lookup_msg->id); |
619 | &lookup_msg->key, | 414 | |
620 | &process_lookup_reply, | 415 | if (r_id > handle->r_id) |
621 | (void *) lookup_msg); | 416 | { |
417 | /** no request found */ | ||
418 | GNUNET_break_op (0); | ||
419 | GNUNET_CLIENT_receive (handle->client, &process_message, handle, | ||
420 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
421 | } | ||
422 | |||
423 | for (qe = handle->lookup_head; qe != NULL; qe = qe->next) | ||
424 | { | ||
425 | if (qe->r_id == r_id) | ||
426 | break; | ||
427 | } | ||
428 | if (qe) | ||
429 | process_lookup_reply(qe, lookup_msg); | ||
430 | |||
431 | |||
622 | } | 432 | } |
623 | else if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT) | 433 | else if (type == GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT) |
624 | { | 434 | { |
625 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 435 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
626 | "Got shorten msg\n"); | 436 | "Got shorten msg\n"); |
627 | shorten_msg = (const struct GNUNET_GNS_ClientShortenResultMessage *) msg; | 437 | shorten_msg = (struct GNUNET_GNS_ClientShortenResultMessage *) msg; |
628 | GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_shorten_requests, | 438 | |
629 | &shorten_msg->key, | 439 | r_id = ntohl (shorten_msg->id); |
630 | &process_shorten_reply, | 440 | |
631 | (void *) shorten_msg); | 441 | if (r_id > handle->r_id) |
632 | } | 442 | { |
633 | else | 443 | /** no request found */ |
634 | { | 444 | GNUNET_break_op (0); |
635 | GNUNET_break (0); | 445 | GNUNET_CLIENT_receive (handle->client, &process_message, handle, |
636 | do_disconnect (handle); | 446 | GNUNET_TIME_UNIT_FOREVER_REL); |
637 | return; | 447 | } |
448 | |||
449 | for (qe = handle->shorten_head; qe != NULL; qe = qe->next) | ||
450 | { | ||
451 | if (qe->r_id == r_id) | ||
452 | break; | ||
453 | } | ||
454 | if (qe) | ||
455 | process_shorten_reply(qe, shorten_msg); | ||
638 | } | 456 | } |
457 | |||
458 | GNUNET_CLIENT_receive (handle->client, &process_message, handle, | ||
459 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
460 | |||
461 | if (GNUNET_YES == handle->reconnect) | ||
462 | force_reconnect (handle); | ||
639 | 463 | ||
640 | } | 464 | } |
641 | 465 | ||
@@ -654,17 +478,10 @@ GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
654 | 478 | ||
655 | handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_Handle)); | 479 | handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_Handle)); |
656 | handle->cfg = cfg; | 480 | handle->cfg = cfg; |
657 | handle->uid_gen = | 481 | reconnect (handle); |
658 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); | 482 | //handle->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect_task, handle); |
659 | handle->active_lookup_requests = | 483 | handle->r_id = 0; |
660 | GNUNET_CONTAINER_multihashmap_create (5); | 484 | handle->in_receive = GNUNET_NO; |
661 | handle->active_shorten_requests = | ||
662 | GNUNET_CONTAINER_multihashmap_create (5); | ||
663 | if (GNUNET_NO == try_connect (handle)) | ||
664 | { | ||
665 | GNUNET_GNS_disconnect (handle); | ||
666 | return NULL; | ||
667 | } | ||
668 | return handle; | 485 | return handle; |
669 | } | 486 | } |
670 | 487 | ||
@@ -680,6 +497,19 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle) | |||
680 | /* disco from GNS */ | 497 | /* disco from GNS */ |
681 | } | 498 | } |
682 | 499 | ||
500 | /* | ||
501 | * Helper function to generate request ids | ||
502 | * | ||
503 | * @param h handle | ||
504 | * @return a new id | ||
505 | */ | ||
506 | static uint32_t | ||
507 | get_request_id (struct GNUNET_GNS_Handle *h) | ||
508 | { | ||
509 | uint32_t r_id = h->r_id; | ||
510 | h->r_id++; | ||
511 | return r_id; | ||
512 | } | ||
683 | 513 | ||
684 | /** | 514 | /** |
685 | * Perform an asynchronous Lookup operation on the GNS. | 515 | * Perform an asynchronous Lookup operation on the GNS. |
@@ -690,67 +520,14 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle) | |||
690 | * @param iter_cls closure for iter | 520 | * @param iter_cls closure for iter |
691 | * @return handle to stop the async get | 521 | * @return handle to stop the async get |
692 | */ | 522 | */ |
693 | struct GNUNET_GNS_LookupHandle * | 523 | struct GNUNET_GNS_QueueEntry * |
694 | GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, | 524 | GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, |
695 | const char * name, | 525 | const char * name, |
696 | enum GNUNET_GNS_RecordType type, | 526 | enum GNUNET_GNS_RecordType type, |
697 | GNUNET_GNS_LookupIterator iter, | 527 | GNUNET_GNS_LookupIterator iter, |
698 | void *iter_cls) | 528 | void *iter_cls) |
699 | { | 529 | { |
700 | /* IPC to look for local entries, start dht lookup, return lookup_handle */ | 530 | return NULL; |
701 | struct GNUNET_GNS_ClientLookupMessage *lookup_msg; | ||
702 | struct GNUNET_GNS_LookupHandle *lookup_handle; | ||
703 | GNUNET_HashCode key; | ||
704 | size_t msize; | ||
705 | struct PendingMessage *pending; | ||
706 | |||
707 | if (NULL == name) | ||
708 | { | ||
709 | return NULL; | ||
710 | } | ||
711 | |||
712 | GNUNET_CRYPTO_hash (name, strlen(name), &key); | ||
713 | |||
714 | msize = sizeof (struct GNUNET_GNS_ClientLookupMessage) + strlen(name); | ||
715 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting lookup for %s in GNS %p\n", | ||
716 | name, handle); | ||
717 | pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); | ||
718 | lookup_msg = (struct GNUNET_GNS_ClientLookupMessage *) &pending[1]; | ||
719 | pending->msg = &lookup_msg->header; | ||
720 | pending->handle = handle; | ||
721 | pending->free_on_send = GNUNET_NO; | ||
722 | lookup_msg->header.size = htons (msize); | ||
723 | lookup_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_LOOKUP); | ||
724 | lookup_msg->key = key; | ||
725 | memcpy(&lookup_msg[1], name, strlen(name)); | ||
726 | handle->uid_gen++; | ||
727 | lookup_msg->unique_id = handle->uid_gen; | ||
728 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, | ||
729 | pending); | ||
730 | pending->in_pending_queue = GNUNET_YES; | ||
731 | lookup_handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_LookupHandle)); | ||
732 | lookup_handle->iter = iter; | ||
733 | lookup_handle->iter_cls = iter_cls; | ||
734 | lookup_handle->message = pending; | ||
735 | lookup_handle->unique_id = lookup_msg->unique_id; | ||
736 | GNUNET_CONTAINER_multihashmap_put (handle->active_lookup_requests, | ||
737 | &lookup_msg->key, | ||
738 | lookup_handle, | ||
739 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
740 | process_pending_messages (handle); | ||
741 | return lookup_handle; | ||
742 | } | ||
743 | |||
744 | |||
745 | /** | ||
746 | * Stop async GNS lookup. | ||
747 | * | ||
748 | * @param lookup_handle handle to the GNS lookup operation to stop | ||
749 | */ | ||
750 | void | ||
751 | GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle) | ||
752 | { | ||
753 | /* TODO Stop gns lookups */ | ||
754 | } | 531 | } |
755 | 532 | ||
756 | 533 | ||
@@ -763,7 +540,7 @@ GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle) | |||
763 | * @param proc_cls closure for processor | 540 | * @param proc_cls closure for processor |
764 | * @return handle to the operation | 541 | * @return handle to the operation |
765 | */ | 542 | */ |
766 | struct GNUNET_GNS_ShortenHandle * | 543 | struct GNUNET_GNS_QueueEntry * |
767 | GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle, | 544 | GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle, |
768 | const char * name, | 545 | const char * name, |
769 | GNUNET_GNS_ShortenResultProcessor proc, | 546 | GNUNET_GNS_ShortenResultProcessor proc, |
@@ -771,7 +548,7 @@ GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle, | |||
771 | { | 548 | { |
772 | /* IPC to shorten gns names, return shorten_handle */ | 549 | /* IPC to shorten gns names, return shorten_handle */ |
773 | struct GNUNET_GNS_ClientShortenMessage *shorten_msg; | 550 | struct GNUNET_GNS_ClientShortenMessage *shorten_msg; |
774 | struct GNUNET_GNS_ShortenHandle *shorten_handle; | 551 | struct GNUNET_GNS_QueueEntry *qe; |
775 | size_t msize; | 552 | size_t msize; |
776 | struct PendingMessage *pending; | 553 | struct PendingMessage *pending; |
777 | 554 | ||
@@ -780,33 +557,34 @@ GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle, | |||
780 | return NULL; | 557 | return NULL; |
781 | } | 558 | } |
782 | 559 | ||
783 | msize = sizeof (struct GNUNET_GNS_ClientShortenMessage) + strlen(name) +1; | 560 | msize = sizeof (struct GNUNET_GNS_ClientShortenMessage) + strlen(name) + 1; |
784 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to shorten %s in GNS\n", name); | 561 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to shorten %s in GNS\n", name); |
562 | |||
563 | qe = GNUNET_malloc(sizeof (struct GNUNET_GNS_QueueEntry)); | ||
564 | qe->gns_handle = handle; | ||
565 | qe->proc = proc; | ||
566 | qe->proc_cls = proc_cls; | ||
567 | qe->r_id = get_request_id(handle); | ||
568 | GNUNET_CONTAINER_DLL_insert_tail(handle->shorten_head, | ||
569 | handle->shorten_tail, qe); | ||
570 | |||
785 | pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); | 571 | pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); |
786 | memset(pending, 0, (sizeof (struct PendingMessage) + msize)); | 572 | memset(pending, 0, (sizeof (struct PendingMessage) + msize)); |
573 | |||
574 | pending->size = msize; | ||
575 | |||
787 | shorten_msg = (struct GNUNET_GNS_ClientShortenMessage *) &pending[1]; | 576 | shorten_msg = (struct GNUNET_GNS_ClientShortenMessage *) &pending[1]; |
788 | pending->msg = &shorten_msg->header; | ||
789 | pending->handle = handle; | ||
790 | pending->free_on_send = GNUNET_NO; | ||
791 | shorten_msg->header.size = htons (msize); | ||
792 | shorten_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_SHORTEN); | 577 | shorten_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_SHORTEN); |
578 | shorten_msg->header.size = htons (msize); | ||
579 | shorten_msg->id = htonl(qe->r_id); | ||
580 | |||
793 | memcpy(&shorten_msg[1], name, strlen(name)); | 581 | memcpy(&shorten_msg[1], name, strlen(name)); |
794 | handle->uid_gen++; | 582 | |
795 | shorten_msg->unique_id = handle->uid_gen; | ||
796 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, | 583 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, |
797 | pending); | 584 | pending); |
798 | pending->in_pending_queue = GNUNET_YES; | 585 | |
799 | shorten_handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_ShortenHandle)); | ||
800 | shorten_handle->proc = proc; | ||
801 | shorten_handle->proc_cls = proc_cls; | ||
802 | shorten_handle->message = pending; | ||
803 | shorten_handle->unique_id = shorten_msg->unique_id; | ||
804 | GNUNET_CONTAINER_multihashmap_put (handle->active_shorten_requests, | ||
805 | &shorten_msg->key, | ||
806 | shorten_handle, | ||
807 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
808 | process_pending_messages (handle); | 586 | process_pending_messages (handle); |
809 | return shorten_handle; | 587 | return qe; |
810 | } | 588 | } |
811 | 589 | ||
812 | 590 | ||