2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors)
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
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file testbed/gnunet-service-testbed_oc.c
23 * @brief code for handling overlay connect operations
24 * @author Sree Harsha Totakura
27 #include "gnunet-service-testbed.h"
28 #include "testbed_api_operations.h"
32 * Context information for transport try connect
34 struct TryConnectContext
37 * The identity of the peer to which the transport has to attempt a connection
39 struct GNUNET_PeerIdentity *pid;
42 * The transport handle
44 struct GNUNET_TRANSPORT_Handle *th;
47 * the try connect handle
49 struct GNUNET_TRANSPORT_TryConnectHandle *tch;
54 GNUNET_SCHEDULER_TaskIdentifier task;
57 * The id of the operation which is resposible for this context
62 * The number of times we attempted to connect
70 * Context information for connecting 2 peers in overlay
72 struct OverlayConnectContext
75 * The next pointer for maintaining a DLL
77 struct OverlayConnectContext *next;
80 * The prev pointer for maintaining a DLL
82 struct OverlayConnectContext *prev;
85 * The client which has requested for overlay connection
87 struct GNUNET_SERVER_Client *client;
90 * the peer which has to connect to the other peer
95 * Transport handle of the first peer to get its HELLO
97 struct GNUNET_TRANSPORT_Handle *p1th;
100 * Core handles of the first peer; used to notify when second peer connects to it
102 struct GNUNET_CORE_Handle *ch;
105 * HELLO of the other peer
107 struct GNUNET_MessageHeader *hello;
110 * Get hello handle to acquire HELLO of first peer
112 struct GNUNET_TRANSPORT_GetHelloHandle *ghh;
115 * The handle for offering HELLO
117 struct GNUNET_TRANSPORT_OfferHelloHandle *ohh;
120 * The error message we send if this overlay connect operation has timed out
125 * Operation context for suboperations
127 struct OperationContext *opc;
130 * Controller of peer 2; NULL if the peer is local
132 struct GNUNET_TESTBED_Controller *peer2_controller;
135 * The transport try connect context
137 struct TryConnectContext tcc;
140 * The peer identity of the first peer
142 struct GNUNET_PeerIdentity peer_identity;
145 * The peer identity of the other peer
147 struct GNUNET_PeerIdentity other_peer_identity;
150 * The id of the operation responsible for creating this context
155 * The id of the task for sending HELLO of peer 2 to peer 1 and ask peer 1 to
158 GNUNET_SCHEDULER_TaskIdentifier send_hello_task;
161 * The id of the overlay connect timeout task
163 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
166 * The id of the cleanup task
168 GNUNET_SCHEDULER_TaskIdentifier cleanup_task;
178 uint32_t other_peer_id;
184 * Context information for RequestOverlayConnect
185 * operations. RequestOverlayConnect is used when peers A, B reside on different
186 * hosts and the host controller for peer B is asked by the host controller of
187 * peer A to make peer B connect to peer A
189 struct RequestOverlayConnectContext
192 * the next pointer for DLL
194 struct RequestOverlayConnectContext *next;
197 * the prev pointer for DLL
199 struct RequestOverlayConnectContext *prev;
202 * The peer handle of peer B
209 struct GNUNET_MessageHeader *hello;
212 * The handle for offering HELLO
214 struct GNUNET_TRANSPORT_OfferHelloHandle *ohh;
217 * The transport try connect context
219 struct TryConnectContext tcc;
222 * The peer identity of peer A
224 struct GNUNET_PeerIdentity a_id;
227 * Task for offering HELLO of A to B and doing try_connect
229 GNUNET_SCHEDULER_TaskIdentifier attempt_connect_task_id;
232 * Task to timeout RequestOverlayConnect
234 GNUNET_SCHEDULER_TaskIdentifier timeout_rocc_task_id;
237 * The id of the operation responsible for creating this context
244 * DLL head for OverlayConnectContext DLL - to be used to clean up during shutdown
246 static struct OverlayConnectContext *occq_head;
249 * DLL tail for OverlayConnectContext DLL
251 static struct OverlayConnectContext *occq_tail;
254 * DLL head for RequectOverlayConnectContext DLL - to be used to clean up during
257 static struct RequestOverlayConnectContext *roccq_head;
260 * DLL tail for RequectOverlayConnectContext DLL
262 static struct RequestOverlayConnectContext *roccq_tail;
266 * Cleans up ForwardedOverlayConnectContext
268 * @param focc the ForwardedOverlayConnectContext to cleanup
271 GST_cleanup_focc (struct ForwardedOverlayConnectContext *focc)
273 GNUNET_free_non_null (focc->orig_msg);
279 * Timeout task for cancelling a forwarded overlay connect connect
281 * @param cls the ForwardedOverlayConnectContext
282 * @param tc the task context from the scheduler
285 forwarded_overlay_connect_timeout (void *cls,
286 const struct GNUNET_SCHEDULER_TaskContext
289 struct ForwardedOperationContext *fopc = cls;
290 struct RegisteredHostContext *rhc;
291 struct ForwardedOverlayConnectContext *focc;
294 focc = rhc->focc_dll_head;
295 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
296 GST_cleanup_focc (focc);
297 LOG_DEBUG ("Overlay linking between peers %u and %u failed\n",
298 focc->peer1, focc->peer2);
299 GST_forwarded_operation_timeout (cls, tc);
300 if (NULL != rhc->focc_dll_head)
301 GST_process_next_focc (rhc);
306 * Callback to be called when forwarded overlay connection operation has a reply
307 * from the sub-controller successfull. We have to relay the reply msg back to
310 * @param cls ForwardedOperationContext
311 * @param msg the peer create success message
314 forwarded_overlay_connect_listener (void *cls,
315 const struct GNUNET_MessageHeader *msg)
317 struct ForwardedOperationContext *fopc = cls;
318 struct RegisteredHostContext *rhc;
319 struct ForwardedOverlayConnectContext *focc;
322 GST_forwarded_operation_reply_relay (cls, msg);
323 focc = rhc->focc_dll_head;
324 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
325 GST_cleanup_focc (focc);
326 if (NULL != rhc->focc_dll_head)
327 GST_process_next_focc (rhc);
332 * Processes a forwarded overlay connect context in the queue of the given RegisteredHostContext
334 * @param rhc the RegisteredHostContext
337 GST_process_next_focc (struct RegisteredHostContext *rhc)
339 struct ForwardedOperationContext *fopc;
340 struct ForwardedOverlayConnectContext *focc;
342 focc = rhc->focc_dll_head;
343 GNUNET_assert (NULL != focc);
344 GNUNET_assert (RHC_OL_CONNECT == rhc->state);
345 fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
346 GNUNET_SERVER_client_keep (rhc->client);
347 fopc->client = rhc->client;
348 fopc->operation_id = focc->operation_id;
350 fopc->type = OP_OVERLAY_CONNECT;
352 GNUNET_TESTBED_forward_operation_msg_ (rhc->gateway->controller,
353 focc->operation_id, focc->orig_msg,
354 &forwarded_overlay_connect_listener,
356 GNUNET_free (focc->orig_msg);
357 focc->orig_msg = NULL;
359 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &forwarded_overlay_connect_timeout,
361 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
366 * Cleanup overlay connect context structure
368 * @param occ the overlay connect context
371 cleanup_occ (struct OverlayConnectContext *occ)
373 LOG_DEBUG ("0x%llx: Cleaning up occ\n", occ->op_id);
374 GNUNET_free_non_null (occ->emsg);
375 GNUNET_free_non_null (occ->hello);
376 GNUNET_SERVER_client_drop (occ->client);
377 if (NULL != occ->opc)
378 GNUNET_TESTBED_forward_operation_msg_cancel_ (occ->opc);
379 if (GNUNET_SCHEDULER_NO_TASK != occ->send_hello_task)
380 GNUNET_SCHEDULER_cancel (occ->send_hello_task);
381 if (GNUNET_SCHEDULER_NO_TASK != occ->cleanup_task)
382 GNUNET_SCHEDULER_cancel (occ->cleanup_task);
383 if (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task)
384 GNUNET_SCHEDULER_cancel (occ->timeout_task);
387 GNUNET_CORE_disconnect (occ->ch);
388 occ->peer->reference_cnt--;
390 if (NULL != occ->ghh)
391 GNUNET_TRANSPORT_get_hello_cancel (occ->ghh);
392 if (NULL != occ->ohh)
393 GNUNET_TRANSPORT_offer_hello_cancel (occ->ohh);
394 if (GNUNET_SCHEDULER_NO_TASK != occ->tcc.task)
395 GNUNET_SCHEDULER_cancel (occ->tcc.task);
396 if (NULL != occ->tcc.tch)
397 GNUNET_TRANSPORT_try_connect_cancel (occ->tcc.tch);
398 if (NULL != occ->p1th)
400 GNUNET_TRANSPORT_disconnect (occ->p1th);
401 occ->peer->reference_cnt--;
403 if (NULL != occ->tcc.th)
405 GNUNET_TRANSPORT_disconnect (occ->tcc.th);
406 GST_peer_list[occ->other_peer_id]->reference_cnt--;
408 if ((GNUNET_YES == occ->peer->destroy_flag)
409 && (0 == occ->peer->reference_cnt))
410 GST_destroy_peer (occ->peer);
411 if ((NULL == occ->peer2_controller)
412 && (GNUNET_YES == GST_peer_list[occ->other_peer_id]->destroy_flag)
413 && (0 == GST_peer_list[occ->other_peer_id]->reference_cnt))
414 GST_destroy_peer (GST_peer_list[occ->other_peer_id]);
415 GNUNET_CONTAINER_DLL_remove (occq_head, occq_tail, occ);
421 * Task for cleaing up overlay connect context structure
423 * @param cls the overlay connect context
424 * @param tc the task context
427 do_cleanup_occ (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
429 struct OverlayConnectContext *occ = cls;
431 occ->cleanup_task = GNUNET_SCHEDULER_NO_TASK;
437 * Task which will be run when overlay connect request has been timed out
439 * @param cls the OverlayConnectContext
440 * @param tc the TaskContext
443 timeout_overlay_connect (void *cls,
444 const struct GNUNET_SCHEDULER_TaskContext *tc)
446 struct OverlayConnectContext *occ = cls;
448 occ->timeout_task = GNUNET_SCHEDULER_NO_TASK;
449 LOG (GNUNET_ERROR_TYPE_WARNING,
450 "0x%llx: Timeout while connecting peers %u and %u\n",
451 occ->op_id, occ->peer_id, occ->other_peer_id);
452 GST_send_operation_fail_msg (occ->client, occ->op_id, occ->emsg);
458 * Function called to notify transport users that another
459 * peer connected to us.
462 * @param new_peer the peer that connected
463 * @param ats performance data
464 * @param ats_count number of entries in ats (excluding 0-termination)
467 overlay_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer,
468 const struct GNUNET_ATS_Information *ats,
469 unsigned int ats_count)
471 struct OverlayConnectContext *occ = cls;
472 struct GNUNET_TESTBED_ConnectionEventMessage *msg;
474 char *other_peer_str;
476 //LOG_DEBUG ("Overlay connect notify\n");
478 memcmp (new_peer, &occ->peer_identity,
479 sizeof (struct GNUNET_PeerIdentity)))
481 new_peer_str = GNUNET_strdup (GNUNET_i2s (new_peer));
482 other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity));
484 memcmp (new_peer, &occ->other_peer_identity,
485 sizeof (struct GNUNET_PeerIdentity)))
487 /* LOG_DEBUG ("Unexpected peer %4s connected when expecting peer %4s\n", */
488 /* new_peer_str, other_peer_str); */
489 GNUNET_free (new_peer_str);
490 GNUNET_free (other_peer_str);
493 GNUNET_free (new_peer_str);
494 LOG_DEBUG ("0x%llx: Peer %4s connected to peer %4s\n", occ->op_id,
495 other_peer_str, GNUNET_i2s (&occ->peer_identity));
496 GNUNET_free (other_peer_str);
497 if (GNUNET_SCHEDULER_NO_TASK != occ->send_hello_task)
499 GNUNET_SCHEDULER_cancel (occ->send_hello_task);
500 occ->send_hello_task = GNUNET_SCHEDULER_NO_TASK;
502 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task);
503 GNUNET_SCHEDULER_cancel (occ->timeout_task);
504 occ->timeout_task = GNUNET_SCHEDULER_NO_TASK;
505 if (GNUNET_SCHEDULER_NO_TASK != occ->tcc.task)
507 GNUNET_SCHEDULER_cancel (occ->tcc.task);
508 occ->tcc.task = GNUNET_SCHEDULER_NO_TASK;
510 GNUNET_free_non_null (occ->emsg);
512 LOG_DEBUG ("0x%llx: Peers connected - Sending overlay connect success\n",
514 msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ConnectionEventMessage));
516 htons (sizeof (struct GNUNET_TESTBED_ConnectionEventMessage));
517 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEERCONEVENT);
518 msg->event_type = htonl (GNUNET_TESTBED_ET_CONNECT);
519 msg->peer1 = htonl (occ->peer_id);
520 msg->peer2 = htonl (occ->other_peer_id);
521 msg->operation_id = GNUNET_htonll (occ->op_id);
522 GST_queue_message (occ->client, &msg->header);
523 occ->cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup_occ, occ);
529 * Task to ask transport of a peer to connect to another peer
531 * @param cls the TryConnectContext
532 * @param tc the scheduler task context
535 try_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
539 * Callback to be called with result of the try connect request.
541 * @param cls the overlay connect context
542 * @param result GNUNET_OK if message was transmitted to transport service
543 * GNUNET_SYSERR if message was not transmitted to transport service
546 try_connect_cb (void *cls, const int result)
548 struct TryConnectContext *tcc = cls;
551 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == tcc->task);
552 tcc->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
553 (GNUNET_TIME_UNIT_MILLISECONDS,
554 500 + pow(2, ++tcc->retries)),
555 &try_connect_task, tcc);
560 * Task to ask transport of a peer to connect to another peer
562 * @param cls the TryConnectContext
563 * @param tc the scheduler task context
566 try_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
568 struct TryConnectContext *tcc = cls;
570 tcc->task = GNUNET_SCHEDULER_NO_TASK;
571 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
573 GNUNET_assert (NULL == tcc->tch);
574 GNUNET_assert (NULL != tcc->pid);
575 GNUNET_assert (NULL != tcc->th);
576 LOG_DEBUG ("0x%llx: Trail %u to connect to peer %s\n", tcc->op_id, tcc->retries,
577 GNUNET_i2s(tcc->pid));
578 tcc->tch = GNUNET_TRANSPORT_try_connect (tcc->th, tcc->pid, &try_connect_cb, tcc);
583 * Task to offer HELLO of peer 1 to peer 2 and try to make peer 2 to connect to
586 * @param cls the OverlayConnectContext
587 * @param tc the TaskContext from scheduler
590 send_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
594 * Task that is run when hello has been sent
596 * @param cls the overlay connect context
597 * @param tc the scheduler task context; if tc->reason =
598 * GNUNET_SCHEDULER_REASON_TIMEOUT then sending HELLO failed; if
599 * GNUNET_SCHEDULER_REASON_READ_READY is succeeded
602 occ_hello_sent_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
604 struct OverlayConnectContext *occ = cls;
607 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == occ->send_hello_task);
608 if (GNUNET_SCHEDULER_REASON_TIMEOUT == tc->reason)
610 GNUNET_free_non_null (occ->emsg);
611 GNUNET_asprintf (&occ->emsg,
612 "0x%llx: Timeout while offering HELLO to other peer",
614 occ->send_hello_task = GNUNET_SCHEDULER_add_now (&send_hello, occ);
617 if (GNUNET_SCHEDULER_REASON_READ_READY != tc->reason)
619 GNUNET_free_non_null (occ->emsg);
620 GNUNET_asprintf (&occ->emsg, "0x%llx: Timeout while try connect",
622 occ->tcc.pid = &occ->peer_identity;
623 occ->tcc.op_id = occ->op_id;
624 occ->tcc.task = GNUNET_SCHEDULER_add_now (&try_connect_task, &occ->tcc);
629 * Task to offer HELLO of peer 1 to peer 2 and try to make peer 2 to connect to
632 * @param cls the OverlayConnectContext
633 * @param tc the TaskContext from scheduler
636 send_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
638 struct OverlayConnectContext *occ = cls;
639 char *other_peer_str;
641 occ->send_hello_task = GNUNET_SCHEDULER_NO_TASK;
642 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
644 GNUNET_assert (NULL != occ->hello);
645 other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity));
646 if (NULL != occ->peer2_controller)
648 struct GNUNET_TESTBED_RequestConnectMessage *msg;
652 LOG_DEBUG ("0x%llx: Offering HELLO of %s (size: %u) to %s via Remote "
655 GNUNET_i2s (&occ->peer_identity),
656 ntohs (occ->hello->size),
658 hello_size = ntohs (occ->hello->size);
659 msize = sizeof (struct GNUNET_TESTBED_RequestConnectMessage) + hello_size;
660 msg = GNUNET_malloc (msize);
661 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_REQUESTCONNECT);
662 msg->header.size = htons (msize);
663 msg->peer = htonl (occ->other_peer_id);
664 msg->operation_id = GNUNET_htonll (occ->op_id);
665 (void) memcpy (&msg->peer_identity, &occ->peer_identity,
666 sizeof (struct GNUNET_PeerIdentity));
667 memcpy (msg->hello, occ->hello, hello_size);
668 GNUNET_TESTBED_queue_message_ (occ->peer2_controller, &msg->header);
672 LOG_DEBUG ("0x%llx: Offering HELLO of %s to %s\n",
674 GNUNET_i2s (&occ->peer_identity), other_peer_str);
675 occ->ohh = GNUNET_TRANSPORT_offer_hello (occ->tcc.th,
679 if (NULL == occ->ohh)
682 occ->send_hello_task =
683 GNUNET_SCHEDULER_add_delayed
684 (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
685 100 + GNUNET_CRYPTO_random_u32
686 (GNUNET_CRYPTO_QUALITY_WEAK, 500)),
690 GNUNET_free (other_peer_str);
695 * Connects to the transport of the other peer if it is a local peer and
696 * schedules the send hello task
698 * @param occ the overlay connect context
701 p2_transport_connect (struct OverlayConnectContext *occ)
703 GNUNET_assert (NULL == occ->emsg);
704 GNUNET_assert (NULL != occ->hello);
705 GNUNET_assert (NULL == occ->ghh);
706 GNUNET_assert (NULL == occ->p1th);
707 if (NULL == occ->peer2_controller)
709 GST_peer_list[occ->other_peer_id]->reference_cnt++;
711 GNUNET_TRANSPORT_connect (GST_peer_list[occ->other_peer_id]->details.local.cfg,
712 &occ->other_peer_identity, NULL, NULL, NULL,
714 if (NULL == occ->tcc.th)
716 GNUNET_asprintf (&occ->emsg, "0x%llx: Cannot connect to TRANSPORT of %s",
717 occ->op_id, GNUNET_i2s (&occ->other_peer_identity));
718 GNUNET_SCHEDULER_cancel (occ->timeout_task);
719 occ->timeout_task = GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
723 GNUNET_asprintf (&occ->emsg, "0x%llx: Timeout while offering HELLO to %s",
724 occ->op_id, GNUNET_i2s (&occ->other_peer_identity));
725 occ->send_hello_task = GNUNET_SCHEDULER_add_now (&send_hello, occ);
730 * Test for checking whether HELLO message is empty
732 * @param cls empty flag to set
733 * @param address the HELLO
734 * @param expiration expiration of the HELLO
738 test_address (void *cls, const struct GNUNET_HELLO_Address *address,
739 struct GNUNET_TIME_Absolute expiration)
749 * Function called whenever there is an update to the HELLO of peers in the
750 * OverlayConnectClosure. If we have a valid HELLO, we connect to the peer 2's
751 * transport and offer peer 1's HELLO and ask peer 2 to connect to peer 1
754 * @param hello our updated HELLO
757 hello_update_cb (void *cls, const struct GNUNET_MessageHeader *hello)
759 struct OverlayConnectContext *occ = cls;
763 msize = ntohs (hello->size);
765 (void) GNUNET_HELLO_iterate_addresses ((const struct GNUNET_HELLO_Message *)
766 hello, GNUNET_NO, &test_address,
768 if (GNUNET_YES == empty)
770 LOG_DEBUG ("0x%llx: HELLO of %s is empty\n",
771 occ->op_id, GNUNET_i2s (&occ->peer_identity));
774 LOG_DEBUG ("0x%llx: Received HELLO of %s\n",
775 occ->op_id, GNUNET_i2s (&occ->peer_identity));
776 occ->hello = GNUNET_malloc (msize);
777 GST_hello_cache_add (&occ->peer_identity, hello);
778 memcpy (occ->hello, hello, msize);
779 GNUNET_TRANSPORT_get_hello_cancel (occ->ghh);
781 GNUNET_TRANSPORT_disconnect (occ->p1th);
783 occ->peer->reference_cnt--;
784 GNUNET_free_non_null (occ->emsg);
786 p2_transport_connect (occ);
791 * Function called after GNUNET_CORE_connect has succeeded (or failed
792 * for good). Note that the private key of the peer is intentionally
793 * not exposed here; if you need it, your process should try to read
794 * the private key file directly (which should work if you are
798 * @param server handle to the server, NULL if we failed
799 * @param my_identity ID of this peer, NULL if we failed
802 core_startup_cb (void *cls, struct GNUNET_CORE_Handle *server,
803 const struct GNUNET_PeerIdentity *my_identity)
805 struct OverlayConnectContext *occ = cls;
806 const struct GNUNET_MessageHeader *hello;
808 GNUNET_free_non_null (occ->emsg);
809 (void) GNUNET_asprintf (&occ->emsg,
810 "0x%llx: Failed to connect to CORE of peer with"
811 "id: %u", occ->op_id, occ->peer_id);
812 if ((NULL == server) || (NULL == my_identity))
814 GNUNET_free (occ->emsg);
817 memcpy (&occ->peer_identity, my_identity,
818 sizeof (struct GNUNET_PeerIdentity));
819 LOG_DEBUG ("0x%llx: Acquiring HELLO of peer %s\n",
820 occ->op_id, GNUNET_i2s (&occ->peer_identity));
821 /* Lookup for HELLO in hello cache */
822 if (NULL != (hello = GST_hello_cache_lookup (&occ->peer_identity)))
824 LOG_DEBUG ("0x%llx: HELLO of peer %s found in cache\n",
825 occ->op_id, GNUNET_i2s (&occ->peer_identity));
826 occ->hello = GNUNET_copy_message (hello);
827 p2_transport_connect (occ);
830 occ->peer->reference_cnt++;
832 GNUNET_TRANSPORT_connect (occ->peer->details.local.cfg,
833 &occ->peer_identity, NULL, NULL, NULL, NULL);
834 if (NULL == occ->p1th)
836 GNUNET_asprintf (&occ->emsg,
837 "0x%llx: Cannot connect to TRANSPORT of peer %4s",
838 occ->op_id, GNUNET_i2s (&occ->peer_identity));
841 GNUNET_asprintf (&occ->emsg,
842 "0x%llx: Timeout while acquiring HELLO of peer %4s",
843 occ->op_id, GNUNET_i2s (&occ->peer_identity));
844 occ->ghh = GNUNET_TRANSPORT_get_hello (occ->p1th, &hello_update_cb, occ);
848 GNUNET_SCHEDULER_cancel (occ->timeout_task);
849 occ->timeout_task = GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
855 * Callback to be called when forwarded get peer config operation as part of
856 * overlay connect is successfull. Connection to Peer 1's core is made and is
857 * checked for new connection from peer 2
859 * @param cls ForwardedOperationContext
860 * @param msg the peer create success message
863 overlay_connect_get_config (void *cls, const struct GNUNET_MessageHeader *msg)
865 struct OverlayConnectContext *occ = cls;
866 const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *cmsg;
867 const struct GNUNET_CORE_MessageHandler no_handlers[] = {
872 if (GNUNET_MESSAGE_TYPE_TESTBED_PEERCONFIG != ntohs (msg->type))
874 cmsg = (const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *)
876 memcpy (&occ->other_peer_identity, &cmsg->peer_identity,
877 sizeof (struct GNUNET_PeerIdentity));
878 GNUNET_free_non_null (occ->emsg);
879 GNUNET_asprintf (&occ->emsg, "0x%llx: Timeout while connecting to CORE",
881 occ->peer->reference_cnt++;
883 GNUNET_CORE_connect (occ->peer->details.local.cfg, occ, &core_startup_cb,
884 &overlay_connect_notify, NULL, NULL, GNUNET_NO, NULL,
885 GNUNET_NO, no_handlers);
891 GNUNET_SCHEDULER_cancel (occ->timeout_task);
893 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
898 * Callback which will be called to after a host registration succeeded or failed
900 * @param cls the RegisteredHostContext
901 * @param emsg the error message; NULL if host registration is successful
904 registeredhost_registration_completion (void *cls, const char *emsg)
906 struct RegisteredHostContext *rhc = cls;
907 struct GNUNET_CONFIGURATION_Handle *cfg;
908 uint32_t peer2_host_id;
910 /* if (NULL != rhc->focc_dll_head) */
911 /* TESTBED_process_next_focc (rhc); */
912 peer2_host_id = GNUNET_TESTBED_host_get_id_ (rhc->reg_host);
913 GNUNET_assert (RHC_INIT == rhc->state);
914 GNUNET_assert (NULL == rhc->sub_op);
915 if ((NULL == rhc->gateway2)
916 || ((peer2_host_id < GST_slave_list_size) /* Check if we have the needed config */
917 && (NULL != GST_slave_list[peer2_host_id])))
919 rhc->state = RHC_LINK;
920 cfg = (NULL == rhc->gateway2) ? our_config : GST_slave_list[peer2_host_id]->cfg;
922 GNUNET_TESTBED_controller_link (rhc,
923 rhc->gateway->controller,
930 rhc->state = RHC_GET_CFG;
931 rhc->sub_op = GNUNET_TESTBED_get_slave_config (rhc,
932 rhc->gateway2->controller,
938 * Iterator to match a registered host context
940 * @param cls pointer 2 pointer of RegisteredHostContext
941 * @param key current key code
942 * @param value value in the hash map
943 * @return GNUNET_YES if we should continue to
948 reghost_match_iterator (void *cls,
949 const struct GNUNET_HashCode * key,
952 struct RegisteredHostContext **rh = cls;
953 struct RegisteredHostContext *rh_val = value;
955 if ((rh_val->host == (*rh)->host) && (rh_val->reg_host == (*rh)->reg_host))
966 * Function to generate the hashcode corresponding to a RegisteredHostContext
968 * @param reg_host the host which is being registered in RegisteredHostContext
969 * @param host the host of the controller which has to connect to the above rhost
970 * @return the hashcode
972 static struct GNUNET_HashCode
973 hash_hosts (struct GNUNET_TESTBED_Host *reg_host,
974 struct GNUNET_TESTBED_Host *host)
976 struct GNUNET_HashCode hash;
977 uint32_t host_ids[2];
979 host_ids[0] = GNUNET_TESTBED_host_get_id_ (reg_host);
980 host_ids[1] = GNUNET_TESTBED_host_get_id_ (host);
981 GNUNET_CRYPTO_hash (host_ids, sizeof (host_ids), &hash);
987 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_OLCONNECT messages
990 * @param client identification of the client
991 * @param message the actual message
994 GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
995 const struct GNUNET_MessageHeader *message)
997 const struct GNUNET_TESTBED_OverlayConnectMessage *msg;
998 const struct GNUNET_CORE_MessageHandler no_handlers[] = {
1002 struct OverlayConnectContext *occ;
1003 struct GNUNET_TESTBED_Controller *peer2_controller;
1004 uint64_t operation_id;
1007 uint32_t peer2_host_id;
1009 if (sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)
1010 != ntohs (message->size))
1013 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1016 msg = (const struct GNUNET_TESTBED_OverlayConnectMessage *) message;
1017 p1 = ntohl (msg->peer1);
1018 p2 = ntohl (msg->peer2);
1019 if ((p1 >= GST_peer_list_size) || (NULL == GST_peer_list[p1]))
1022 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1025 peer = GST_peer_list[p1];
1026 peer2_host_id = ntohl (msg->peer2_host_id);
1027 operation_id = GNUNET_ntohll (msg->operation_id);
1028 LOG_DEBUG ("Received overlay connect for peers %u and %u with op id: 0x%llx\n",
1029 p1, p2, operation_id);
1030 if (GNUNET_YES == peer->is_remote)
1032 struct ForwardedOperationContext *fopc;
1033 struct Route *route_to_peer2_host;
1034 struct Route *route_to_peer1_host;
1036 LOG_DEBUG ("0x%llx: Forwarding overlay connect\n", operation_id);
1037 route_to_peer2_host = NULL;
1038 route_to_peer1_host = NULL;
1039 route_to_peer2_host = GST_find_dest_route (peer2_host_id);
1040 if ((NULL != route_to_peer2_host)
1041 || (peer2_host_id == GST_context->host_id))
1043 /* Peer 2 either below us OR with us */
1044 route_to_peer1_host =
1046 (GST_peer_list[p1]->details.remote.remote_host_id);
1047 /* Because we get this message only if we know where peer 1 is */
1048 GNUNET_assert (NULL != route_to_peer1_host);
1049 if ((peer2_host_id == GST_context->host_id)
1050 || (route_to_peer2_host->dest != route_to_peer1_host->dest))
1052 /* Peer2 is either with us OR peer1 and peer2 can be reached through
1053 different gateways */
1054 struct GNUNET_HashCode hash;
1055 struct RegisteredHostContext *rhc;
1058 rhc = GNUNET_malloc (sizeof (struct RegisteredHostContext));
1059 if (NULL != route_to_peer2_host)
1060 rhc->reg_host = GST_host_list[route_to_peer2_host->dest];
1062 rhc->reg_host = GST_host_list[GST_context->host_id];
1063 rhc->host = GST_host_list[route_to_peer1_host->dest];
1064 GNUNET_assert (NULL != rhc->reg_host);
1065 GNUNET_assert (NULL != rhc->host);
1066 rhc->gateway = peer->details.remote.slave;
1067 rhc->gateway2 = (NULL == route_to_peer2_host) ? NULL :
1068 GST_slave_list[route_to_peer2_host->dest];
1069 rhc->state = RHC_INIT;
1070 GNUNET_SERVER_client_keep (client);
1071 rhc->client = client;
1072 hash = hash_hosts (rhc->reg_host, rhc->host);
1073 skip_focc = GNUNET_NO;
1075 GNUNET_CONTAINER_multihashmap_contains
1076 (peer->details.remote.slave->reghost_map, &hash))
1077 || (GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_get_multiple
1078 (peer->details.remote.slave->reghost_map, &hash,
1079 reghost_match_iterator, &rhc)))
1081 /* create and add a new registerd host context */
1082 /* add the focc to its queue */
1083 GNUNET_CONTAINER_multihashmap_put
1084 (peer->details.remote.slave->reghost_map,
1085 &hash, rhc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1086 GNUNET_assert (NULL != GST_host_list[peer2_host_id]);
1087 GST_queue_host_registration (peer->details.remote.slave,
1088 registeredhost_registration_completion,
1090 GST_host_list[peer2_host_id]);
1093 /* rhc is now set to the existing one from the hash map by
1094 reghost_match_iterator() */
1095 /* if queue is empty then ignore creating focc and proceed with
1096 normal forwarding */
1097 if (RHC_OL_CONNECT == rhc->state)
1098 skip_focc = GNUNET_YES;
1100 if (GNUNET_NO == skip_focc)
1102 struct ForwardedOverlayConnectContext *focc;
1104 focc = GNUNET_malloc (sizeof (struct ForwardedOverlayConnectContext));
1107 focc->peer2_host_id = peer2_host_id;
1108 focc->orig_msg = GNUNET_copy_message (message);
1109 focc->operation_id = operation_id;
1110 GNUNET_CONTAINER_DLL_insert_tail (rhc->focc_dll_head,
1113 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1118 fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
1119 GNUNET_SERVER_client_keep (client);
1120 fopc->client = client;
1121 fopc->operation_id = operation_id;
1122 fopc->type = OP_OVERLAY_CONNECT;
1124 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.slave->controller,
1125 operation_id, message,
1126 &GST_forwarded_operation_reply_relay,
1128 fopc->timeout_task =
1129 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &GST_forwarded_operation_timeout,
1131 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
1132 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1136 peer2_controller = NULL;
1137 if ((p2 >= GST_peer_list_size) || (NULL == GST_peer_list[p2]))
1139 if ((peer2_host_id >= GST_slave_list_size)
1140 || (NULL ==GST_slave_list[peer2_host_id]))
1142 LOG (GNUNET_ERROR_TYPE_WARNING,
1143 "0x%llx: Configuration of peer2's controller missing for connecting peers"
1144 "%u and %u\n", operation_id, p1, p2);
1145 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1148 peer2_controller = GST_slave_list[peer2_host_id]->controller;
1149 if (NULL == peer2_controller)
1151 GNUNET_break (0); /* What's going on? */
1152 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1158 if (GNUNET_YES == GST_peer_list[p2]->is_remote)
1159 peer2_controller = GST_peer_list[p2]->details.remote.slave->controller;
1161 occ = GNUNET_malloc (sizeof (struct OverlayConnectContext));
1162 GNUNET_CONTAINER_DLL_insert_tail (occq_head, occq_tail, occ);
1163 GNUNET_SERVER_client_keep (client);
1164 occ->client = client;
1166 occ->other_peer_id = p2;
1167 occ->peer = GST_peer_list[p1];
1168 occ->op_id = GNUNET_ntohll (msg->operation_id);
1169 occ->peer2_controller = peer2_controller;
1170 /* Get the identity of the second peer */
1171 if (NULL != occ->peer2_controller)
1173 struct GNUNET_TESTBED_PeerGetConfigurationMessage cmsg;
1176 htons (sizeof (struct GNUNET_TESTBED_PeerGetConfigurationMessage));
1177 cmsg.header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG);
1178 cmsg.peer_id = msg->peer2;
1179 cmsg.operation_id = msg->operation_id;
1181 GNUNET_TESTBED_forward_operation_msg_ (occ->peer2_controller,
1182 occ->op_id, &cmsg.header,
1183 &overlay_connect_get_config,
1185 GNUNET_asprintf (&occ->emsg,
1186 "0x%llx: Timeout while getting peer identity of peer "
1187 "with id: %u", occ->op_id, occ->other_peer_id);
1189 GNUNET_SCHEDULER_add_delayed (TIMEOUT,
1190 &timeout_overlay_connect, occ);
1191 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1194 GNUNET_TESTING_peer_get_identity (GST_peer_list[occ->other_peer_id]->details.local.peer,
1195 &occ->other_peer_identity);
1196 /* Connect to the core of 1st peer and wait for the 2nd peer to connect */
1197 occ->emsg = GNUNET_strdup ("Timeout while connecting to CORE");
1198 GNUNET_asprintf (&occ->emsg,
1199 "0x%llx: Timeout while connecting to CORE of peer with "
1200 "id: %u", occ->op_id, occ->peer_id);
1201 occ->peer->reference_cnt++;
1203 GNUNET_CORE_connect (occ->peer->details.local.cfg, occ, &core_startup_cb,
1204 &overlay_connect_notify, NULL, NULL, GNUNET_NO, NULL,
1205 GNUNET_NO, no_handlers);
1206 if (NULL == occ->ch)
1208 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
1211 GNUNET_SCHEDULER_add_delayed (TIMEOUT,
1212 &timeout_overlay_connect, occ);
1213 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1218 * Function to cleanup RequestOverlayConnectContext and any associated tasks
1221 * @param rocc the RequestOverlayConnectContext
1224 cleanup_rocc (struct RequestOverlayConnectContext *rocc)
1226 LOG_DEBUG ("0x%llx: Cleaning up rocc\n", rocc->op_id);
1227 if (GNUNET_SCHEDULER_NO_TASK != rocc->attempt_connect_task_id)
1228 GNUNET_SCHEDULER_cancel (rocc->attempt_connect_task_id);
1229 if (GNUNET_SCHEDULER_NO_TASK != rocc->timeout_rocc_task_id)
1230 GNUNET_SCHEDULER_cancel (rocc->timeout_rocc_task_id);
1231 if (NULL != rocc->ohh)
1232 GNUNET_TRANSPORT_offer_hello_cancel (rocc->ohh);
1233 if (NULL != rocc->tcc.tch)
1234 GNUNET_TRANSPORT_try_connect_cancel (rocc->tcc.tch);
1235 if (GNUNET_SCHEDULER_NO_TASK != rocc->tcc.task)
1236 GNUNET_SCHEDULER_cancel (rocc->tcc.task);
1237 GNUNET_TRANSPORT_disconnect (rocc->tcc.th);
1238 rocc->peer->reference_cnt--;
1239 if ((GNUNET_YES == rocc->peer->destroy_flag)
1240 && (0 == rocc->peer->reference_cnt))
1241 GST_destroy_peer (rocc->peer);
1242 GNUNET_free_non_null (rocc->hello);
1243 GNUNET_CONTAINER_DLL_remove (roccq_head, roccq_tail, rocc);
1249 * Task to timeout rocc and cleanit up
1251 * @param cls the RequestOverlayConnectContext
1252 * @param tc the TaskContext from scheduler
1255 timeout_rocc_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1257 struct RequestOverlayConnectContext *rocc = cls;
1259 GNUNET_assert (rocc->timeout_rocc_task_id != GNUNET_SCHEDULER_NO_TASK);
1260 rocc->timeout_rocc_task_id = GNUNET_SCHEDULER_NO_TASK;
1261 LOG_DEBUG ("0x%llx: rocc timed out\n", rocc->op_id);
1262 cleanup_rocc (rocc);
1267 * Function called to notify transport users that another
1268 * peer connected to us.
1270 * @param cls closure
1271 * @param new_peer the peer that connected
1272 * @param ats performance data
1273 * @param ats_count number of entries in ats (excluding 0-termination)
1276 transport_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer,
1277 const struct GNUNET_ATS_Information * ats,
1280 struct RequestOverlayConnectContext *rocc = cls;
1282 LOG_DEBUG ("0x%llx: Request Overlay connect notify\n", rocc->op_id);
1283 if (0 != memcmp (new_peer, &rocc->a_id, sizeof (struct GNUNET_PeerIdentity)))
1285 LOG_DEBUG ("0x%llx: Peer %4s connected\n", rocc->op_id,
1286 GNUNET_i2s (&rocc->a_id));
1287 cleanup_rocc (rocc);
1292 * Task to offer the HELLO message to the peer and ask it to connect to the peer
1293 * whose identity is in RequestOverlayConnectContext
1295 * @param cls the RequestOverlayConnectContext
1296 * @param tc the TaskContext from scheduler
1299 attempt_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
1303 * Task that is run when hello has been sent
1305 * @param cls the overlay connect context
1306 * @param tc the scheduler task context; if tc->reason =
1307 * GNUNET_SCHEDULER_REASON_TIMEOUT then sending HELLO failed; if
1308 * GNUNET_SCHEDULER_REASON_READ_READY is succeeded
1311 rocc_hello_sent_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1313 struct RequestOverlayConnectContext *rocc = cls;
1316 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == rocc->attempt_connect_task_id);
1317 LOG_DEBUG ("0x%llx: HELLO of peer %4s sent to local peer with id: %u\n",
1318 rocc->op_id, GNUNET_i2s (&rocc->a_id), rocc->peer->id);
1319 if (GNUNET_SCHEDULER_REASON_TIMEOUT == tc->reason)
1322 rocc->attempt_connect_task_id =
1323 GNUNET_SCHEDULER_add_now (&attempt_connect_task,
1327 if (GNUNET_SCHEDULER_REASON_READ_READY != tc->reason)
1329 rocc->tcc.task = GNUNET_SCHEDULER_add_now (&try_connect_task, &rocc->tcc);
1334 * Task to offer the HELLO message to the peer and ask it to connect to the peer
1335 * whose identity is in RequestOverlayConnectContext
1337 * @param cls the RequestOverlayConnectContext
1338 * @param tc the TaskContext from scheduler
1341 attempt_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1343 struct RequestOverlayConnectContext *rocc = cls;
1345 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != rocc->attempt_connect_task_id);
1346 rocc->attempt_connect_task_id = GNUNET_SCHEDULER_NO_TASK;
1347 LOG_DEBUG ("0x%llx: Offering HELLO of peer %4s to local peer with id: %u\n",
1348 rocc->op_id, GNUNET_i2s (&rocc->a_id), rocc->peer->id);
1349 rocc->ohh = GNUNET_TRANSPORT_offer_hello (rocc->tcc.th, rocc->hello,
1350 rocc_hello_sent_cb, rocc);
1351 if (NULL == rocc->ohh)
1352 rocc->attempt_connect_task_id =
1353 GNUNET_SCHEDULER_add_delayed
1354 (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
1355 100 + GNUNET_CRYPTO_random_u32
1356 (GNUNET_CRYPTO_QUALITY_WEAK, 500)),
1357 &attempt_connect_task, rocc);
1362 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_REQUESTCONNECT messages
1365 * @param client identification of the client
1366 * @param message the actual message
1369 GST_handle_overlay_request_connect (void *cls,
1370 struct GNUNET_SERVER_Client *client,
1371 const struct GNUNET_MessageHeader
1374 const struct GNUNET_TESTBED_RequestConnectMessage *msg;
1375 struct RequestOverlayConnectContext *rocc;
1381 msize = ntohs (message->size);
1382 if (sizeof (struct GNUNET_TESTBED_RequestConnectMessage) >= msize)
1385 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1388 msg = (const struct GNUNET_TESTBED_RequestConnectMessage *) message;
1389 if ((NULL == msg->hello) ||
1390 (GNUNET_MESSAGE_TYPE_HELLO != ntohs (msg->hello->type)))
1393 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1396 hsize = ntohs (msg->hello->size);
1397 if ((sizeof (struct GNUNET_TESTBED_RequestConnectMessage) + hsize) != msize)
1400 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1403 peer_id = ntohl (msg->peer);
1404 if ((peer_id >= GST_peer_list_size) || (NULL == (peer = GST_peer_list[peer_id])))
1406 GNUNET_break_op (0);
1407 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1410 if (GNUNET_YES == peer->is_remote)
1412 struct GNUNET_MessageHeader *msg2;
1414 msg2 = GNUNET_copy_message (message);
1415 GNUNET_TESTBED_queue_message_ (peer->details.remote.slave->controller,
1417 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1420 rocc = GNUNET_malloc (sizeof (struct RequestOverlayConnectContext));
1421 rocc->op_id = GNUNET_ntohll (msg->operation_id);
1422 GNUNET_CONTAINER_DLL_insert_tail (roccq_head, roccq_tail, rocc);
1423 memcpy (&rocc->a_id, &msg->peer_identity,
1424 sizeof (struct GNUNET_PeerIdentity));
1425 LOG_DEBUG ("Received request for overlay connection with op_id: 0x%llx "
1426 "from local peer %u to peer %4s with hello size: %u\n",
1429 GNUNET_i2s (&rocc->a_id),
1432 rocc->peer->reference_cnt++;
1433 rocc->tcc.op_id = rocc->op_id;
1434 rocc->tcc.th = GNUNET_TRANSPORT_connect (rocc->peer->details.local.cfg, NULL, rocc,
1435 NULL, &transport_connect_notify, NULL);
1436 if (NULL == rocc->tcc.th)
1440 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1443 rocc->tcc.pid = &rocc->a_id;
1444 rocc->hello = GNUNET_malloc (hsize);
1445 memcpy (rocc->hello, msg->hello, hsize);
1446 rocc->attempt_connect_task_id =
1447 GNUNET_SCHEDULER_add_now (&attempt_connect_task, rocc);
1448 rocc->timeout_rocc_task_id =
1449 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_rocc_task, rocc);
1450 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1455 * Clears all pending overlay connect contexts in queue
1460 struct OverlayConnectContext *occ;
1462 while (NULL != (occ = occq_head))
1468 * Clears all pending remote overlay connect contexts in queue
1473 struct RequestOverlayConnectContext *rocc;
1475 while (NULL != (rocc = roccq_head))
1476 cleanup_rocc (rocc);