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 TESTBED_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 TESTBED_cleanup_focc (focc);
297 LOG_DEBUG ("Overlay linking between peers %u and %u failed\n",
298 focc->peer1, focc->peer2);
299 TESTBED_forwarded_operation_timeout (cls, tc);
300 if (NULL != rhc->focc_dll_head)
301 TESTBED_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 TESTBED_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 TESTBED_cleanup_focc (focc);
326 if (NULL != rhc->focc_dll_head)
327 TESTBED_process_next_focc (rhc);
332 * Processes a forwarded overlay connect context in the queue of the given RegisteredHostContext
334 * @param rhc the RegisteredHostContext
337 TESTBED_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 TESTBED_peer_list[occ->other_peer_id]->reference_cnt--;
408 if ((GNUNET_YES == occ->peer->destroy_flag)
409 && (0 == occ->peer->reference_cnt))
410 TESTBED_destroy_peer (occ->peer);
411 if ((NULL == occ->peer2_controller)
412 && (GNUNET_YES == TESTBED_peer_list[occ->other_peer_id]->destroy_flag)
413 && (0 == TESTBED_peer_list[occ->other_peer_id]->reference_cnt))
414 TESTBED_destroy_peer (TESTBED_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 TESTBED_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 TESTBED_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 TESTBED_peer_list[occ->other_peer_id]->reference_cnt++;
711 GNUNET_TRANSPORT_connect (TESTBED_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 TESTBED_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 = TESTBED_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 < TESTBED_slave_list_size) /* Check if we have the needed config */
917 && (NULL != TESTBED_slave_list[peer2_host_id])))
919 rhc->state = RHC_LINK;
920 cfg = (NULL == rhc->gateway2) ? our_config : TESTBED_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 TESTBED_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 msg = (const struct GNUNET_TESTBED_OverlayConnectMessage *) message;
1010 p1 = ntohl (msg->peer1);
1011 p2 = ntohl (msg->peer2);
1012 peer2_host_id = ntohl (msg->peer2_host_id);
1013 GNUNET_assert (p1 < TESTBED_peer_list_size);
1014 GNUNET_assert (NULL != TESTBED_peer_list[p1]);
1015 peer = TESTBED_peer_list[p1];
1016 operation_id = GNUNET_ntohll (msg->operation_id);
1017 LOG_DEBUG ("Received overlay connect for peers %u and %u with op id: 0x%llx\n",
1018 p1, p2, operation_id);
1019 if (GNUNET_YES == peer->is_remote)
1021 struct ForwardedOperationContext *fopc;
1022 struct Route *route_to_peer2_host;
1023 struct Route *route_to_peer1_host;
1025 LOG_DEBUG ("0x%llx: Forwarding overlay connect\n", operation_id);
1026 route_to_peer2_host = NULL;
1027 route_to_peer1_host = NULL;
1028 route_to_peer2_host = TESTBED_find_dest_route (peer2_host_id);
1029 if ((NULL != route_to_peer2_host)
1030 || (peer2_host_id == TESTBED_context->host_id))
1032 /* Peer 2 either below us OR with us */
1033 route_to_peer1_host =
1034 TESTBED_find_dest_route
1035 (TESTBED_peer_list[p1]->details.remote.remote_host_id);
1036 /* Because we get this message only if we know where peer 1 is */
1037 GNUNET_assert (NULL != route_to_peer1_host);
1038 if ((peer2_host_id == TESTBED_context->host_id)
1039 || (route_to_peer2_host->dest != route_to_peer1_host->dest))
1041 /* Peer2 is either with us OR peer1 and peer2 can be reached through
1042 different gateways */
1043 struct GNUNET_HashCode hash;
1044 struct RegisteredHostContext *rhc;
1047 rhc = GNUNET_malloc (sizeof (struct RegisteredHostContext));
1048 if (NULL != route_to_peer2_host)
1049 rhc->reg_host = TESTBED_host_list[route_to_peer2_host->dest];
1051 rhc->reg_host = TESTBED_host_list[TESTBED_context->host_id];
1052 rhc->host = TESTBED_host_list[route_to_peer1_host->dest];
1053 GNUNET_assert (NULL != rhc->reg_host);
1054 GNUNET_assert (NULL != rhc->host);
1055 rhc->gateway = peer->details.remote.slave;
1056 rhc->gateway2 = (NULL == route_to_peer2_host) ? NULL :
1057 TESTBED_slave_list[route_to_peer2_host->dest];
1058 rhc->state = RHC_INIT;
1059 GNUNET_SERVER_client_keep (client);
1060 rhc->client = client;
1061 hash = hash_hosts (rhc->reg_host, rhc->host);
1062 skip_focc = GNUNET_NO;
1064 GNUNET_CONTAINER_multihashmap_contains
1065 (peer->details.remote.slave->reghost_map, &hash))
1066 || (GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_get_multiple
1067 (peer->details.remote.slave->reghost_map, &hash,
1068 reghost_match_iterator, &rhc)))
1070 /* create and add a new registerd host context */
1071 /* add the focc to its queue */
1072 GNUNET_CONTAINER_multihashmap_put
1073 (peer->details.remote.slave->reghost_map,
1074 &hash, rhc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1075 GNUNET_assert (NULL != TESTBED_host_list[peer2_host_id]);
1076 TESTBED_queue_host_registration (peer->details.remote.slave,
1077 registeredhost_registration_completion,
1079 TESTBED_host_list[peer2_host_id]);
1082 /* rhc is now set to the existing one from the hash map by
1083 reghost_match_iterator() */
1084 /* if queue is empty then ignore creating focc and proceed with
1085 normal forwarding */
1086 if (RHC_OL_CONNECT == rhc->state)
1087 skip_focc = GNUNET_YES;
1089 if (GNUNET_NO == skip_focc)
1091 struct ForwardedOverlayConnectContext *focc;
1093 focc = GNUNET_malloc (sizeof (struct ForwardedOverlayConnectContext));
1096 focc->peer2_host_id = peer2_host_id;
1097 focc->orig_msg = GNUNET_copy_message (message);
1098 focc->operation_id = operation_id;
1099 GNUNET_CONTAINER_DLL_insert_tail (rhc->focc_dll_head,
1102 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1107 fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
1108 GNUNET_SERVER_client_keep (client);
1109 fopc->client = client;
1110 fopc->operation_id = operation_id;
1111 fopc->type = OP_OVERLAY_CONNECT;
1113 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.slave->controller,
1114 operation_id, message,
1115 &TESTBED_forwarded_operation_reply_relay,
1117 fopc->timeout_task =
1118 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &TESTBED_forwarded_operation_timeout,
1120 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
1121 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1125 peer2_controller = NULL;
1126 if ((p2 >= TESTBED_peer_list_size) || (NULL == TESTBED_peer_list[p2]))
1128 if ((peer2_host_id >= TESTBED_slave_list_size)
1129 || (NULL ==TESTBED_slave_list[peer2_host_id]))
1131 LOG (GNUNET_ERROR_TYPE_WARNING,
1132 "0x%llx: Configuration of peer2's controller missing for connecting peers"
1133 "%u and %u\n", operation_id, p1, p2);
1134 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1137 peer2_controller = TESTBED_slave_list[peer2_host_id]->controller;
1138 if (NULL == peer2_controller)
1140 GNUNET_break (0); /* What's going on? */
1141 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1147 if (GNUNET_YES == TESTBED_peer_list[p2]->is_remote)
1148 peer2_controller = TESTBED_peer_list[p2]->details.remote.slave->controller;
1150 occ = GNUNET_malloc (sizeof (struct OverlayConnectContext));
1151 GNUNET_CONTAINER_DLL_insert_tail (occq_head, occq_tail, occ);
1152 GNUNET_SERVER_client_keep (client);
1153 occ->client = client;
1155 occ->other_peer_id = p2;
1156 occ->peer = TESTBED_peer_list[p1];
1157 occ->op_id = GNUNET_ntohll (msg->operation_id);
1158 occ->peer2_controller = peer2_controller;
1159 /* Get the identity of the second peer */
1160 if (NULL != occ->peer2_controller)
1162 struct GNUNET_TESTBED_PeerGetConfigurationMessage cmsg;
1165 htons (sizeof (struct GNUNET_TESTBED_PeerGetConfigurationMessage));
1166 cmsg.header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG);
1167 cmsg.peer_id = msg->peer2;
1168 cmsg.operation_id = msg->operation_id;
1170 GNUNET_TESTBED_forward_operation_msg_ (occ->peer2_controller,
1171 occ->op_id, &cmsg.header,
1172 &overlay_connect_get_config,
1174 GNUNET_asprintf (&occ->emsg,
1175 "0x%llx: Timeout while getting peer identity of peer "
1176 "with id: %u", occ->op_id, occ->other_peer_id);
1178 GNUNET_SCHEDULER_add_delayed (TIMEOUT,
1179 &timeout_overlay_connect, occ);
1180 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1183 GNUNET_TESTING_peer_get_identity (TESTBED_peer_list[occ->other_peer_id]->details.local.peer,
1184 &occ->other_peer_identity);
1185 /* Connect to the core of 1st peer and wait for the 2nd peer to connect */
1186 occ->emsg = GNUNET_strdup ("Timeout while connecting to CORE");
1187 GNUNET_asprintf (&occ->emsg,
1188 "0x%llx: Timeout while connecting to CORE of peer with "
1189 "id: %u", occ->op_id, occ->peer_id);
1190 occ->peer->reference_cnt++;
1192 GNUNET_CORE_connect (occ->peer->details.local.cfg, occ, &core_startup_cb,
1193 &overlay_connect_notify, NULL, NULL, GNUNET_NO, NULL,
1194 GNUNET_NO, no_handlers);
1195 if (NULL == occ->ch)
1197 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
1200 GNUNET_SCHEDULER_add_delayed (TIMEOUT,
1201 &timeout_overlay_connect, occ);
1202 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1207 * Function to cleanup RequestOverlayConnectContext and any associated tasks
1210 * @param rocc the RequestOverlayConnectContext
1213 cleanup_rocc (struct RequestOverlayConnectContext *rocc)
1215 LOG_DEBUG ("0x%llx: Cleaning up rocc\n", rocc->op_id);
1216 if (GNUNET_SCHEDULER_NO_TASK != rocc->attempt_connect_task_id)
1217 GNUNET_SCHEDULER_cancel (rocc->attempt_connect_task_id);
1218 if (GNUNET_SCHEDULER_NO_TASK != rocc->timeout_rocc_task_id)
1219 GNUNET_SCHEDULER_cancel (rocc->timeout_rocc_task_id);
1220 if (NULL != rocc->ohh)
1221 GNUNET_TRANSPORT_offer_hello_cancel (rocc->ohh);
1222 if (NULL != rocc->tcc.tch)
1223 GNUNET_TRANSPORT_try_connect_cancel (rocc->tcc.tch);
1224 if (GNUNET_SCHEDULER_NO_TASK != rocc->tcc.task)
1225 GNUNET_SCHEDULER_cancel (rocc->tcc.task);
1226 GNUNET_TRANSPORT_disconnect (rocc->tcc.th);
1227 rocc->peer->reference_cnt--;
1228 if ((GNUNET_YES == rocc->peer->destroy_flag)
1229 && (0 == rocc->peer->reference_cnt))
1230 TESTBED_destroy_peer (rocc->peer);
1231 GNUNET_free_non_null (rocc->hello);
1232 GNUNET_CONTAINER_DLL_remove (roccq_head, roccq_tail, rocc);
1238 * Task to timeout rocc and cleanit up
1240 * @param cls the RequestOverlayConnectContext
1241 * @param tc the TaskContext from scheduler
1244 timeout_rocc_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1246 struct RequestOverlayConnectContext *rocc = cls;
1248 GNUNET_assert (rocc->timeout_rocc_task_id != GNUNET_SCHEDULER_NO_TASK);
1249 rocc->timeout_rocc_task_id = GNUNET_SCHEDULER_NO_TASK;
1250 LOG_DEBUG ("0x%llx: rocc timed out\n", rocc->op_id);
1251 cleanup_rocc (rocc);
1256 * Function called to notify transport users that another
1257 * peer connected to us.
1259 * @param cls closure
1260 * @param new_peer the peer that connected
1261 * @param ats performance data
1262 * @param ats_count number of entries in ats (excluding 0-termination)
1265 transport_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer,
1266 const struct GNUNET_ATS_Information * ats,
1269 struct RequestOverlayConnectContext *rocc = cls;
1271 LOG_DEBUG ("0x%llx: Request Overlay connect notify\n", rocc->op_id);
1272 if (0 != memcmp (new_peer, &rocc->a_id, sizeof (struct GNUNET_PeerIdentity)))
1274 LOG_DEBUG ("0x%llx: Peer %4s connected\n", rocc->op_id,
1275 GNUNET_i2s (&rocc->a_id));
1276 cleanup_rocc (rocc);
1281 * Task to offer the HELLO message to the peer and ask it to connect to the peer
1282 * whose identity is in RequestOverlayConnectContext
1284 * @param cls the RequestOverlayConnectContext
1285 * @param tc the TaskContext from scheduler
1288 attempt_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
1292 * Task that is run when hello has been sent
1294 * @param cls the overlay connect context
1295 * @param tc the scheduler task context; if tc->reason =
1296 * GNUNET_SCHEDULER_REASON_TIMEOUT then sending HELLO failed; if
1297 * GNUNET_SCHEDULER_REASON_READ_READY is succeeded
1300 rocc_hello_sent_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1302 struct RequestOverlayConnectContext *rocc = cls;
1305 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == rocc->attempt_connect_task_id);
1306 LOG_DEBUG ("0x%llx: HELLO of peer %4s sent to local peer with id: %u\n",
1307 rocc->op_id, GNUNET_i2s (&rocc->a_id), rocc->peer->id);
1308 if (GNUNET_SCHEDULER_REASON_TIMEOUT == tc->reason)
1311 rocc->attempt_connect_task_id =
1312 GNUNET_SCHEDULER_add_now (&attempt_connect_task,
1316 if (GNUNET_SCHEDULER_REASON_READ_READY != tc->reason)
1318 rocc->tcc.task = GNUNET_SCHEDULER_add_now (&try_connect_task, &rocc->tcc);
1323 * Task to offer the HELLO message to the peer and ask it to connect to the peer
1324 * whose identity is in RequestOverlayConnectContext
1326 * @param cls the RequestOverlayConnectContext
1327 * @param tc the TaskContext from scheduler
1330 attempt_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1332 struct RequestOverlayConnectContext *rocc = cls;
1334 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != rocc->attempt_connect_task_id);
1335 rocc->attempt_connect_task_id = GNUNET_SCHEDULER_NO_TASK;
1336 LOG_DEBUG ("0x%llx: Offering HELLO of peer %4s to local peer with id: %u\n",
1337 rocc->op_id, GNUNET_i2s (&rocc->a_id), rocc->peer->id);
1338 rocc->ohh = GNUNET_TRANSPORT_offer_hello (rocc->tcc.th, rocc->hello,
1339 rocc_hello_sent_cb, rocc);
1340 if (NULL == rocc->ohh)
1341 rocc->attempt_connect_task_id =
1342 GNUNET_SCHEDULER_add_delayed
1343 (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
1344 100 + GNUNET_CRYPTO_random_u32
1345 (GNUNET_CRYPTO_QUALITY_WEAK, 500)),
1346 &attempt_connect_task, rocc);
1351 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_REQUESTCONNECT messages
1354 * @param client identification of the client
1355 * @param message the actual message
1358 TESTBED_handle_overlay_request_connect (void *cls,
1359 struct GNUNET_SERVER_Client *client,
1360 const struct GNUNET_MessageHeader
1363 const struct GNUNET_TESTBED_RequestConnectMessage *msg;
1364 struct RequestOverlayConnectContext *rocc;
1370 msize = ntohs (message->size);
1371 if (sizeof (struct GNUNET_TESTBED_RequestConnectMessage) >= msize)
1374 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1377 msg = (const struct GNUNET_TESTBED_RequestConnectMessage *) message;
1378 if ((NULL == msg->hello) ||
1379 (GNUNET_MESSAGE_TYPE_HELLO != ntohs (msg->hello->type)))
1382 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1385 hsize = ntohs (msg->hello->size);
1386 if ((sizeof (struct GNUNET_TESTBED_RequestConnectMessage) + hsize) != msize)
1389 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1392 peer_id = ntohl (msg->peer);
1393 if ((peer_id >= TESTBED_peer_list_size) || (NULL == (peer = TESTBED_peer_list[peer_id])))
1395 GNUNET_break_op (0);
1396 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1399 if (GNUNET_YES == peer->is_remote)
1401 struct GNUNET_MessageHeader *msg2;
1403 msg2 = GNUNET_copy_message (message);
1404 GNUNET_TESTBED_queue_message_ (peer->details.remote.slave->controller,
1406 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1409 rocc = GNUNET_malloc (sizeof (struct RequestOverlayConnectContext));
1410 rocc->op_id = GNUNET_ntohll (msg->operation_id);
1411 GNUNET_CONTAINER_DLL_insert_tail (roccq_head, roccq_tail, rocc);
1412 memcpy (&rocc->a_id, &msg->peer_identity,
1413 sizeof (struct GNUNET_PeerIdentity));
1414 LOG_DEBUG ("Received request for overlay connection with op_id: 0x%llx "
1415 "from local peer %u to peer %4s with hello size: %u\n",
1418 GNUNET_i2s (&rocc->a_id),
1421 rocc->peer->reference_cnt++;
1422 rocc->tcc.op_id = rocc->op_id;
1423 rocc->tcc.th = GNUNET_TRANSPORT_connect (rocc->peer->details.local.cfg, NULL, rocc,
1424 NULL, &transport_connect_notify, NULL);
1425 if (NULL == rocc->tcc.th)
1429 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1432 rocc->tcc.pid = &rocc->a_id;
1433 rocc->hello = GNUNET_malloc (hsize);
1434 memcpy (rocc->hello, msg->hello, hsize);
1435 rocc->attempt_connect_task_id =
1436 GNUNET_SCHEDULER_add_now (&attempt_connect_task, rocc);
1437 rocc->timeout_rocc_task_id =
1438 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_rocc_task, rocc);
1439 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1444 * Clears all pending overlay connect contexts in queue
1447 TESTBED_free_occq ()
1449 struct OverlayConnectContext *occ;
1451 while (NULL != (occ = occq_head))
1457 * Clears all pending remote overlay connect contexts in queue
1460 TESTBED_free_roccq ()
1462 struct RequestOverlayConnectContext *rocc;
1464 while (NULL != (rocc = roccq_head))
1465 cleanup_rocc (rocc);