aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-01-30 10:06:33 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-01-30 10:06:33 +0000
commit105e00be9252a2e6db0dec566b2b0d9e633a31bf (patch)
tree36cbccc92d2da220cd0f1e5354b2f175a93ccbaa /src
parent8cc87399cf760b9fa3cbdb40bf71d1eb333c8434 (diff)
downloadgnunet-105e00be9252a2e6db0dec566b2b0d9e633a31bf.tar.gz
gnunet-105e00be9252a2e6db0dec566b2b0d9e633a31bf.zip
cache transport handles with peer connect notifications
Diffstat (limited to 'src')
-rw-r--r--src/testbed/gnunet-service-testbed.h27
-rw-r--r--src/testbed/gnunet-service-testbed_hc.c170
-rw-r--r--src/testbed/gnunet-service-testbed_oc.c23
3 files changed, 179 insertions, 41 deletions
diff --git a/src/testbed/gnunet-service-testbed.h b/src/testbed/gnunet-service-testbed.h
index 72ad5d15a..b7924dc59 100644
--- a/src/testbed/gnunet-service-testbed.h
+++ b/src/testbed/gnunet-service-testbed.h
@@ -814,6 +814,22 @@ typedef void (*GST_cache_callback) (void *cls, struct GNUNET_CORE_Handle *ch,
814 814
815 815
816/** 816/**
817 * Callback to notify when the target peer given to
818 * GST_cache_get_handle_transport() is connected. Note that this callback may
819 * not be called if the target peer is already connected. Use
820 * GNUNET_TRANSPORT_check_neighbour_connected() to check if the target peer is
821 * already connected or not. This callback will be called only once or never (in
822 * case the target cannot be connected).
823 *
824 * @param cls the closure given to GST_cache_get_handle_done() for this callback
825 * @param target the peer identity of the target peer. The pointer should be
826 * valid until GST_cache_get_handle_done() is called.
827 */
828typedef void (*GST_cache_peer_connect_notify) (void *cls,
829 const struct GNUNET_PeerIdentity *target);
830
831
832/**
817 * Get a transport handle with the given configuration. If the handle is already 833 * Get a transport handle with the given configuration. If the handle is already
818 * cached before, it will be retured in the given callback; the peer_id is used to lookup in the 834 * cached before, it will be retured in the given callback; the peer_id is used to lookup in the
819 * cache. If not a new operation is started to open the transport handle and 835 * cache. If not a new operation is started to open the transport handle and
@@ -824,6 +840,12 @@ typedef void (*GST_cache_callback) (void *cls, struct GNUNET_CORE_Handle *ch,
824 * created if it was not present in the cache 840 * created if it was not present in the cache
825 * @param cb the callback to notify when the transport handle is available 841 * @param cb the callback to notify when the transport handle is available
826 * @param cb_cls the closure for the above callback 842 * @param cb_cls the closure for the above callback
843 * @param target the peer identify of the peer whose connection to our TRANSPORT
844 * subsystem will be notified through the connect_notify_cb. Can be NULL
845 * @param connect_notify_cb the callback to call when the given target peer is
846 * connected. This callback will only be called once or never again (in
847 * case the target peer cannot be connected). Can be NULL
848 * @param connect_notify_cb_cls the closure for the above callback
827 * @return the handle which can be used cancel or mark that the handle is no 849 * @return the handle which can be used cancel or mark that the handle is no
828 * longer being used 850 * longer being used
829 */ 851 */
@@ -831,7 +853,10 @@ struct GSTCacheGetHandle *
831GST_cache_get_handle_transport (unsigned int peer_id, 853GST_cache_get_handle_transport (unsigned int peer_id,
832 const struct GNUNET_CONFIGURATION_Handle *cfg, 854 const struct GNUNET_CONFIGURATION_Handle *cfg,
833 GST_cache_callback cb, 855 GST_cache_callback cb,
834 void *cb_cls); 856 void *cb_cls,
857 const struct GNUNET_PeerIdentity *target,
858 GST_cache_peer_connect_notify connect_notify_cb,
859 void *connect_notify_cb_cls);
835 860
836 861
837/** 862/**
diff --git a/src/testbed/gnunet-service-testbed_hc.c b/src/testbed/gnunet-service-testbed_hc.c
index 7a7689cce..2f3586c45 100644
--- a/src/testbed/gnunet-service-testbed_hc.c
+++ b/src/testbed/gnunet-service-testbed_hc.c
@@ -34,9 +34,6 @@
34#define LOG(kind,...) \ 34#define LOG(kind,...) \
35 GNUNET_log_from (kind, "testbed-cache", __VA_ARGS__) 35 GNUNET_log_from (kind, "testbed-cache", __VA_ARGS__)
36 36
37/* #define LOG_DEBUG(...) \ */
38/* LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) */
39
40 37
41enum CacheGetType 38enum CacheGetType
42{ 39{
@@ -61,6 +58,40 @@ struct GSTCacheGetHandle
61 int notify_called; 58 int notify_called;
62}; 59};
63 60
61
62/**
63 * This context structure is used to maintain a queue of notifications to check
64 * which of them are to be notified when a peer is connected.
65 */
66struct ConnectNotifyContext
67{
68 /**
69 * The next ptr for the DLL
70 */
71 struct ConnectNotifyContext *next;
72
73 /**
74 * The prev ptr for the DLL
75 */
76 struct ConnectNotifyContext *prev;
77
78 /**
79 * The peer identity of the target peer. When this target peer is connected,
80 * call the notify callback
81 */
82 const struct GNUNET_PeerIdentity *target;
83
84 /**
85 * The notify callback to be called when the target peer is connected
86 */
87 GST_cache_peer_connect_notify cb;
88
89 /**
90 * The closure for the notify callback
91 */
92 void *cb_cls;
93};
94
64/** 95/**
65 * Cache entry 96 * Cache entry
66 */ 97 */
@@ -105,12 +136,24 @@ struct CacheEntry
105 /** 136 /**
106 * the head of the CacheGetHandle queue 137 * the head of the CacheGetHandle queue
107 */ 138 */
108 struct GSTCacheGetHandle *cghq_head; 139 struct GSTCacheGetHandle *cgh_qhead;
109 140
110 /** 141 /**
111 * the tail of the CacheGetHandle queue 142 * the tail of the CacheGetHandle queue
112 */ 143 */
113 struct GSTCacheGetHandle *cghq_tail; 144 struct GSTCacheGetHandle *cgh_qtail;
145
146 /**
147 * DLL head for the queue of notifications contexts to check which of them are to
148 * be notified when a peer is connected.
149 */
150 struct ConnectNotifyContext *nctxt_qhead;
151
152 /**
153 * DLL tail for the queue of notifications contexts to check which of them are to
154 * be notified when a peer is connected.
155 */
156 struct ConnectNotifyContext *nctxt_qtail;
114 157
115 /** 158 /**
116 * The task that calls the cache callback 159 * The task that calls the cache callback
@@ -247,12 +290,12 @@ call_cgh_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
247 290
248 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != entry->notify_task); 291 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != entry->notify_task);
249 entry->notify_task = GNUNET_SCHEDULER_NO_TASK; 292 entry->notify_task = GNUNET_SCHEDULER_NO_TASK;
250 cgh = entry->cghq_head; 293 cgh = entry->cgh_qhead;
251 GNUNET_assert (GNUNET_NO == cgh->notify_called); 294 GNUNET_assert (GNUNET_NO == cgh->notify_called);
252 GNUNET_CONTAINER_DLL_remove (entry->cghq_head, entry->cghq_tail, cgh); 295 GNUNET_CONTAINER_DLL_remove (entry->cgh_qhead, entry->cgh_qtail, cgh);
253 cgh->notify_called = GNUNET_YES; 296 cgh->notify_called = GNUNET_YES;
254 GNUNET_CONTAINER_DLL_insert_tail (entry->cghq_head, entry->cghq_tail, cgh); 297 GNUNET_CONTAINER_DLL_insert_tail (entry->cgh_qhead, entry->cgh_qtail, cgh);
255 if (GNUNET_NO == entry->cghq_head->notify_called) 298 if (GNUNET_NO == entry->cgh_qhead->notify_called)
256 entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry); 299 entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry);
257 switch (cgh->type) 300 switch (cgh->type)
258 { 301 {
@@ -262,6 +305,40 @@ call_cgh_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
262 } 305 }
263} 306}
264 307
308/**
309 * Function called to notify transport users that another
310 * peer connected to us.
311 *
312 * @param cls closure
313 * @param peer the peer that connected
314 * @param ats performance data
315 * @param ats_count number of entries in ats (excluding 0-termination)
316 */
317static void
318peer_connect_notify_cb (void *cls,
319 const struct GNUNET_PeerIdentity *peer,
320 const struct GNUNET_ATS_Information *ats,
321 uint32_t ats_count)
322{
323 struct CacheEntry *entry = cls;
324 struct ConnectNotifyContext *ctxt;
325 GST_cache_peer_connect_notify cb;
326 void *cb_cls;
327
328 while (NULL != (ctxt = entry->nctxt_qhead))
329 {
330 if (0 == memcmp (ctxt->target, peer, sizeof (struct GNUNET_PeerIdentity)))
331 break;
332 }
333 if (NULL == ctxt)
334 return;
335 cb = ctxt->cb;
336 cb_cls = ctxt->cb_cls;
337 GNUNET_CONTAINER_DLL_remove (entry->nctxt_qhead, entry->nctxt_qtail, ctxt);
338 GNUNET_free (ctxt);
339 cb (cb_cls, peer);
340}
341
265 342
266static void 343static void
267opstart_get_handle_transport (void *cls) 344opstart_get_handle_transport (void *cls)
@@ -271,9 +348,9 @@ opstart_get_handle_transport (void *cls)
271 GNUNET_assert (NULL != entry); 348 GNUNET_assert (NULL != entry);
272 LOG_DEBUG ("Opening a transport connection to peer %u\n", entry->peer_id); 349 LOG_DEBUG ("Opening a transport connection to peer %u\n", entry->peer_id);
273 entry->transport_handle = GNUNET_TRANSPORT_connect (entry->cfg, 350 entry->transport_handle = GNUNET_TRANSPORT_connect (entry->cfg,
274 NULL, NULL, 351 NULL, entry,
275 NULL,
276 NULL, 352 NULL,
353 &peer_connect_notify_cb,
277 NULL); 354 NULL);
278 if (NULL == entry->transport_handle) 355 if (NULL == entry->transport_handle)
279 { 356 {
@@ -283,7 +360,7 @@ opstart_get_handle_transport (void *cls)
283 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == entry->notify_task); 360 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == entry->notify_task);
284 if (0 == entry->demand) 361 if (0 == entry->demand)
285 return; 362 return;
286 if (GNUNET_NO == entry->cghq_head->notify_called) 363 if (GNUNET_NO == entry->cgh_qhead->notify_called)
287 entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry); 364 entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry);
288} 365}
289 366
@@ -292,7 +369,13 @@ static void
292oprelease_get_handle_transport (void *cls) 369oprelease_get_handle_transport (void *cls)
293{ 370{
294 struct CacheEntry *entry = cls; 371 struct CacheEntry *entry = cls;
295 372 struct ConnectNotifyContext *ctxt;
373
374 while (NULL != (ctxt = entry->nctxt_qhead))
375 {
376 GNUNET_CONTAINER_DLL_remove (entry->nctxt_qhead, entry->nctxt_qtail, ctxt);
377 GNUNET_free (ctxt);
378 }
296 if (NULL == entry->transport_handle) 379 if (NULL == entry->transport_handle)
297 return; 380 return;
298 GNUNET_TRANSPORT_disconnect (entry->transport_handle); 381 GNUNET_TRANSPORT_disconnect (entry->transport_handle);
@@ -303,11 +386,15 @@ oprelease_get_handle_transport (void *cls)
303static struct GSTCacheGetHandle * 386static struct GSTCacheGetHandle *
304cache_get_handle (unsigned int peer_id, 387cache_get_handle (unsigned int peer_id,
305 struct GSTCacheGetHandle *cgh, 388 struct GSTCacheGetHandle *cgh,
306 const struct GNUNET_CONFIGURATION_Handle *cfg) 389 const struct GNUNET_CONFIGURATION_Handle *cfg,
390 const struct GNUNET_PeerIdentity *target,
391 GST_cache_peer_connect_notify connect_notify_cb,
392 void *connect_notify_cb_cls)
307{ 393{
308 struct GNUNET_HashCode key; 394 struct GNUNET_HashCode key;
309 void *handle; 395 void *handle;
310 struct CacheEntry *entry; 396 struct CacheEntry *entry;
397 struct ConnectNotifyContext *ctxt;
311 398
312 GNUNET_assert (0 != cgh->type); 399 GNUNET_assert (0 != cgh->type);
313 GNUNET_CRYPTO_hash (&peer_id, sizeof (peer_id), &key); 400 GNUNET_CRYPTO_hash (&peer_id, sizeof (peer_id), &key);
@@ -332,7 +419,15 @@ cache_get_handle (unsigned int peer_id,
332 entry->cfg = GNUNET_CONFIGURATION_dup (cfg); 419 entry->cfg = GNUNET_CONFIGURATION_dup (cfg);
333 entry->demand++; 420 entry->demand++;
334 cgh->entry = entry; 421 cgh->entry = entry;
335 GNUNET_CONTAINER_DLL_insert (entry->cghq_head, entry->cghq_tail, cgh); 422 GNUNET_CONTAINER_DLL_insert (entry->cgh_qhead, entry->cgh_qtail, cgh);
423 if ((NULL != target) && (NULL != connect_notify_cb))
424 {
425 ctxt = GNUNET_malloc (sizeof (struct ConnectNotifyContext));
426 ctxt->target = target;
427 ctxt->cb = connect_notify_cb;
428 ctxt->cb_cls = connect_notify_cb_cls;
429 GNUNET_CONTAINER_DLL_insert_tail (entry->nctxt_qhead, entry->nctxt_qtail, ctxt);
430 }
336 if ((NULL != entry->transport_handle) || (NULL != entry->transport_op)) 431 if ((NULL != entry->transport_handle) || (NULL != entry->transport_op))
337 { 432 {
338 if (GNUNET_SCHEDULER_NO_TASK == entry->notify_task) 433 if (GNUNET_SCHEDULER_NO_TASK == entry->notify_task)
@@ -380,6 +475,10 @@ cache_clear_iterator (void *cls,
380 GNUNET_free_non_null (entry->hello); 475 GNUNET_free_non_null (entry->hello);
381 GNUNET_break (NULL == entry->transport_handle); 476 GNUNET_break (NULL == entry->transport_handle);
382 GNUNET_break (NULL == entry->cfg); 477 GNUNET_break (NULL == entry->cfg);
478 GNUNET_assert (NULL == entry->cgh_qhead);
479 GNUNET_assert (NULL == entry->cgh_qtail);
480 GNUNET_assert (NULL == entry->nctxt_qhead);
481 GNUNET_assert (NULL == entry->nctxt_qtail);
383 GNUNET_free (entry); 482 GNUNET_free (entry);
384 return GNUNET_YES; 483 return GNUNET_YES;
385} 484}
@@ -423,27 +522,28 @@ GST_cache_init (unsigned int size)
423void 522void
424GST_cache_get_handle_done (struct GSTCacheGetHandle *cgh) 523GST_cache_get_handle_done (struct GSTCacheGetHandle *cgh)
425{ 524{
426 GNUNET_assert (NULL != cgh->entry); 525 struct CacheEntry *entry;
427 GNUNET_assert (0 < cgh->entry->demand); 526
428 cgh->entry->demand--; 527 entry = cgh->entry;
429 if (GNUNET_SCHEDULER_NO_TASK != cgh->entry->notify_task) 528 GNUNET_assert (NULL != entry);
529 GNUNET_assert (0 < entry->demand);
530 entry->demand--;
531 if (GNUNET_SCHEDULER_NO_TASK != entry->notify_task)
430 { 532 {
431 GNUNET_SCHEDULER_cancel (cgh->entry->notify_task); 533 GNUNET_SCHEDULER_cancel (entry->notify_task);
432 cgh->entry->notify_task = GNUNET_SCHEDULER_NO_TASK; 534 entry->notify_task = GNUNET_SCHEDULER_NO_TASK;
433 } 535 }
434 GNUNET_CONTAINER_DLL_remove (cgh->entry->cghq_head, 536 GNUNET_CONTAINER_DLL_remove (entry->cgh_qhead, entry->cgh_qtail, cgh);
435 cgh->entry->cghq_tail, 537 if (0 == entry->demand)
436 cgh);
437 if (0 == cgh->entry->demand)
438 { 538 {
439 GNUNET_CONTAINER_DLL_insert_tail (lru_cache_head, lru_cache_tail, cgh->entry); 539 GNUNET_CONTAINER_DLL_insert_tail (lru_cache_head, lru_cache_tail, entry);
440 if (lru_cache_size > lru_cache_threshold_size) 540 if (lru_cache_size > lru_cache_threshold_size)
441 cache_remove (lru_cache_head); 541 cache_remove (lru_cache_head);
442 } 542 }
443 else 543 else
444 { 544 {
445 if (GNUNET_NO == cgh->entry->cghq_head->notify_called) 545 if (GNUNET_NO == entry->cgh_qhead->notify_called)
446 cgh->entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, cgh->entry); 546 entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry);
447 } 547 }
448 GNUNET_free (cgh); 548 GNUNET_free (cgh);
449} 549}
@@ -460,6 +560,12 @@ GST_cache_get_handle_done (struct GSTCacheGetHandle *cgh)
460 * created if it was not present in the cache 560 * created if it was not present in the cache
461 * @param cb the callback to notify when the transport handle is available 561 * @param cb the callback to notify when the transport handle is available
462 * @param cb_cls the closure for the above callback 562 * @param cb_cls the closure for the above callback
563 * @param target the peer identify of the peer whose connection to our TRANSPORT
564 * subsystem will be notified through the connect_notify_cb. Can be NULL
565 * @param connect_notify_cb the callback to call when the given target peer is
566 * connected. This callback will only be called once or never again (in
567 * case the target peer cannot be connected). Can be NULL
568 * @param connect_notify_cb_cls the closure for the above callback
463 * @return the handle which can be used cancel or mark that the handle is no 569 * @return the handle which can be used cancel or mark that the handle is no
464 * longer being used 570 * longer being used
465 */ 571 */
@@ -467,7 +573,10 @@ struct GSTCacheGetHandle *
467GST_cache_get_handle_transport (unsigned int peer_id, 573GST_cache_get_handle_transport (unsigned int peer_id,
468 const struct GNUNET_CONFIGURATION_Handle *cfg, 574 const struct GNUNET_CONFIGURATION_Handle *cfg,
469 GST_cache_callback cb, 575 GST_cache_callback cb,
470 void *cb_cls) 576 void *cb_cls,
577 const struct GNUNET_PeerIdentity *target,
578 GST_cache_peer_connect_notify connect_notify_cb,
579 void *connect_notify_cb_cls)
471{ 580{
472 struct GSTCacheGetHandle *cgh; 581 struct GSTCacheGetHandle *cgh;
473 582
@@ -475,7 +584,8 @@ GST_cache_get_handle_transport (unsigned int peer_id,
475 cgh->cb = cb; 584 cgh->cb = cb;
476 cgh->cb_cls = cb_cls; 585 cgh->cb_cls = cb_cls;
477 cgh->type = CGT_TRANSPORT_HANDLE; 586 cgh->type = CGT_TRANSPORT_HANDLE;
478 return cache_get_handle (peer_id, cgh, cfg); 587 return cache_get_handle (peer_id, cgh, cfg,
588 target, connect_notify_cb, connect_notify_cb_cls);
479} 589}
480 590
481 591
diff --git a/src/testbed/gnunet-service-testbed_oc.c b/src/testbed/gnunet-service-testbed_oc.c
index 75c7f4975..623b7614b 100644
--- a/src/testbed/gnunet-service-testbed_oc.c
+++ b/src/testbed/gnunet-service-testbed_oc.c
@@ -764,7 +764,8 @@ p2_transport_connect (struct OverlayConnectContext *occ)
764 GST_peer_list[occ->other_peer_id]-> 764 GST_peer_list[occ->other_peer_id]->
765 details.local.cfg, 765 details.local.cfg,
766 &p2_transport_connect_cache_callback, 766 &p2_transport_connect_cache_callback,
767 occ); 767 occ,
768 NULL, NULL, NULL);
768 return; 769 return;
769 } 770 }
770 GNUNET_asprintf (&occ->emsg, "0x%llx: Timeout while offering HELLO to %s", 771 GNUNET_asprintf (&occ->emsg, "0x%llx: Timeout while offering HELLO to %s",
@@ -1362,15 +1363,13 @@ timeout_rocc_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1362 * @param ats_count number of entries in ats (excluding 0-termination) 1363 * @param ats_count number of entries in ats (excluding 0-termination)
1363 */ 1364 */
1364static void 1365static void
1365transport_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer, 1366cache_transport_peer_connect_notify (void *cls,
1366 const struct GNUNET_ATS_Information *ats, 1367 const struct GNUNET_PeerIdentity *new_peer)
1367 uint32_t ats_count)
1368{ 1368{
1369 struct RemoteOverlayConnectCtx *rocc = cls; 1369 struct RemoteOverlayConnectCtx *rocc = cls;
1370 1370
1371 LOG_DEBUG ("0x%llx: Request Overlay connect notify\n", rocc->op_id); 1371 LOG_DEBUG ("0x%llx: Request Overlay connect notify\n", rocc->op_id);
1372 if (0 != memcmp (new_peer, &rocc->a_id, sizeof (struct GNUNET_PeerIdentity))) 1372 GNUNET_assert (0 == memcmp (new_peer, &rocc->a_id, sizeof (struct GNUNET_PeerIdentity)));
1373 return;
1374 LOG_DEBUG ("0x%llx: Peer %4s connected\n", rocc->op_id, 1373 LOG_DEBUG ("0x%llx: Peer %4s connected\n", rocc->op_id,
1375 GNUNET_i2s (&rocc->a_id)); 1374 GNUNET_i2s (&rocc->a_id));
1376 cleanup_rocc (rocc); 1375 cleanup_rocc (rocc);
@@ -1546,10 +1545,14 @@ GST_handle_remote_overlay_connect (void *cls,
1546 rocc->peer->reference_cnt++; 1545 rocc->peer->reference_cnt++;
1547 rocc->hello = GNUNET_malloc (hsize); 1546 rocc->hello = GNUNET_malloc (hsize);
1548 memcpy (rocc->hello, msg->hello, hsize); 1547 memcpy (rocc->hello, msg->hello, hsize);
1549 rocc->tcc.cgh_th = GST_cache_get_handle_transport (peer_id, 1548 rocc->tcc.cgh_th =
1550 rocc->peer->details.local.cfg, 1549 GST_cache_get_handle_transport (peer_id,
1551 &rocc_cache_get_handle_transport_cb, 1550 rocc->peer->details.local.cfg,
1552 rocc); 1551 &rocc_cache_get_handle_transport_cb,
1552 rocc,
1553 &rocc->a_id,
1554 &cache_transport_peer_connect_notify,
1555 rocc);
1553 rocc->timeout_rocc_task_id = 1556 rocc->timeout_rocc_task_id =
1554 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_rocc_task, rocc); 1557 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_rocc_task, rocc);
1555 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1558 GNUNET_SERVER_receive_done (client, GNUNET_OK);