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 * The local operation we create for this overlay connection
132 struct GNUNET_TESTBED_Operation *lop;
135 * Controller of peer 2; NULL if the peer is local
137 struct GNUNET_TESTBED_Controller *peer2_controller;
140 * The transport try connect context
142 struct TryConnectContext tcc;
145 * The peer identity of the first peer
147 struct GNUNET_PeerIdentity peer_identity;
150 * The peer identity of the other peer
152 struct GNUNET_PeerIdentity other_peer_identity;
155 * The id of the operation responsible for creating this context
160 * The id of the task for sending HELLO of peer 2 to peer 1 and ask peer 1 to
163 GNUNET_SCHEDULER_TaskIdentifier send_hello_task;
166 * The id of the overlay connect timeout task
168 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
171 * The id of the cleanup task
173 GNUNET_SCHEDULER_TaskIdentifier cleanup_task;
183 uint32_t other_peer_id;
189 * Context information for RequestOverlayConnect
190 * operations. RequestOverlayConnect is used when peers A, B reside on different
191 * hosts and the host controller for peer B is asked by the host controller of
192 * peer A to make peer B connect to peer A
194 struct RemoteOverlayConnectCtx
197 * the next pointer for DLL
199 struct RemoteOverlayConnectCtx *next;
202 * the prev pointer for DLL
204 struct RemoteOverlayConnectCtx *prev;
207 * The peer handle of peer B
214 struct GNUNET_MessageHeader *hello;
217 * The handle for offering HELLO
219 struct GNUNET_TRANSPORT_OfferHelloHandle *ohh;
222 * The local operation we create for this overlay connection
224 struct GNUNET_TESTBED_Operation *lop;
227 * The transport try connect context
229 struct TryConnectContext tcc;
232 * The peer identity of peer A
234 struct GNUNET_PeerIdentity a_id;
237 * Task for offering HELLO of A to B and doing try_connect
239 GNUNET_SCHEDULER_TaskIdentifier attempt_connect_task_id;
242 * Task to timeout RequestOverlayConnect
244 GNUNET_SCHEDULER_TaskIdentifier timeout_rocc_task_id;
247 * The id of the operation responsible for creating this context
254 * DLL head for OverlayConnectContext DLL - to be used to clean up during shutdown
256 static struct OverlayConnectContext *occq_head;
259 * DLL tail for OverlayConnectContext DLL
261 static struct OverlayConnectContext *occq_tail;
264 * DLL head for RequectOverlayConnectContext DLL - to be used to clean up during
267 static struct RemoteOverlayConnectCtx *roccq_head;
270 * DLL tail for RequectOverlayConnectContext DLL
272 static struct RemoteOverlayConnectCtx *roccq_tail;
276 * Cleans up ForwardedOverlayConnectContext
278 * @param focc the ForwardedOverlayConnectContext to cleanup
281 GST_cleanup_focc (struct ForwardedOverlayConnectContext *focc)
283 GNUNET_free_non_null (focc->orig_msg);
289 * Timeout task for cancelling a forwarded overlay connect connect
291 * @param cls the ForwardedOverlayConnectContext
292 * @param tc the task context from the scheduler
295 forwarded_overlay_connect_timeout (void *cls,
296 const struct GNUNET_SCHEDULER_TaskContext
299 struct ForwardedOperationContext *fopc = cls;
300 struct RegisteredHostContext *rhc;
301 struct ForwardedOverlayConnectContext *focc;
304 focc = rhc->focc_dll_head;
305 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
306 GST_cleanup_focc (focc);
307 LOG_DEBUG ("Overlay linking between peers %u and %u failed\n", focc->peer1,
309 GST_forwarded_operation_timeout (cls, tc);
310 if (NULL != rhc->focc_dll_head)
311 GST_process_next_focc (rhc);
316 * Callback to be called when forwarded overlay connection operation has a reply
317 * from the sub-controller successfull. We have to relay the reply msg back to
320 * @param cls ForwardedOperationContext
321 * @param msg the peer create success message
324 forwarded_overlay_connect_listener (void *cls,
325 const struct GNUNET_MessageHeader *msg)
327 struct ForwardedOperationContext *fopc = cls;
328 struct RegisteredHostContext *rhc;
329 struct ForwardedOverlayConnectContext *focc;
332 GST_forwarded_operation_reply_relay (cls, msg);
333 focc = rhc->focc_dll_head;
334 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
335 GST_cleanup_focc (focc);
336 if (NULL != rhc->focc_dll_head)
337 GST_process_next_focc (rhc);
342 * Processes a forwarded overlay connect context in the queue of the given RegisteredHostContext
344 * @param rhc the RegisteredHostContext
347 GST_process_next_focc (struct RegisteredHostContext *rhc)
349 struct ForwardedOperationContext *fopc;
350 struct ForwardedOverlayConnectContext *focc;
352 focc = rhc->focc_dll_head;
353 GNUNET_assert (NULL != focc);
354 GNUNET_assert (RHC_OL_CONNECT == rhc->state);
355 fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
356 GNUNET_SERVER_client_keep (rhc->client);
357 fopc->client = rhc->client;
358 fopc->operation_id = focc->operation_id;
360 fopc->type = OP_OVERLAY_CONNECT;
362 GNUNET_TESTBED_forward_operation_msg_ (rhc->gateway->controller,
363 focc->operation_id, focc->orig_msg,
364 &forwarded_overlay_connect_listener,
366 GNUNET_free (focc->orig_msg);
367 focc->orig_msg = NULL;
369 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &forwarded_overlay_connect_timeout,
371 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
376 * Cleanup overlay connect context structure
378 * @param occ the overlay connect context
381 cleanup_occ (struct OverlayConnectContext *occ)
383 if (NULL != occ->lop)
385 GNUNET_TESTBED_operation_release_ (occ->lop);
388 LOG_DEBUG ("0x%llx: Cleaning up occ\n", occ->op_id);
389 GNUNET_free_non_null (occ->emsg);
390 GNUNET_free_non_null (occ->hello);
391 GNUNET_SERVER_client_drop (occ->client);
392 if (NULL != occ->opc)
393 GNUNET_TESTBED_forward_operation_msg_cancel_ (occ->opc);
394 if (GNUNET_SCHEDULER_NO_TASK != occ->send_hello_task)
395 GNUNET_SCHEDULER_cancel (occ->send_hello_task);
396 if (GNUNET_SCHEDULER_NO_TASK != occ->cleanup_task)
397 GNUNET_SCHEDULER_cancel (occ->cleanup_task);
398 if (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task)
399 GNUNET_SCHEDULER_cancel (occ->timeout_task);
402 GNUNET_CORE_disconnect (occ->ch);
403 occ->peer->reference_cnt--;
405 if (NULL != occ->ghh)
406 GNUNET_TRANSPORT_get_hello_cancel (occ->ghh);
407 if (NULL != occ->ohh)
408 GNUNET_TRANSPORT_offer_hello_cancel (occ->ohh);
409 if (GNUNET_SCHEDULER_NO_TASK != occ->tcc.task)
410 GNUNET_SCHEDULER_cancel (occ->tcc.task);
411 if (NULL != occ->tcc.tch)
412 GNUNET_TRANSPORT_try_connect_cancel (occ->tcc.tch);
413 if (NULL != occ->p1th)
415 GNUNET_TRANSPORT_disconnect (occ->p1th);
416 occ->peer->reference_cnt--;
418 if (NULL != occ->tcc.th)
420 GNUNET_TRANSPORT_disconnect (occ->tcc.th);
421 GST_peer_list[occ->other_peer_id]->reference_cnt--;
423 if ((GNUNET_YES == occ->peer->destroy_flag) &&
424 (0 == occ->peer->reference_cnt))
425 GST_destroy_peer (occ->peer);
426 if ((NULL == occ->peer2_controller) &&
427 (GNUNET_YES == GST_peer_list[occ->other_peer_id]->destroy_flag) &&
428 (0 == GST_peer_list[occ->other_peer_id]->reference_cnt))
429 GST_destroy_peer (GST_peer_list[occ->other_peer_id]);
430 GNUNET_CONTAINER_DLL_remove (occq_head, occq_tail, occ);
431 GNUNET_assert (NULL == occ->lop);
437 * Task for cleaing up overlay connect context structure
439 * @param cls the overlay connect context
440 * @param tc the task context
443 do_cleanup_occ (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
445 struct OverlayConnectContext *occ = cls;
447 occ->cleanup_task = GNUNET_SCHEDULER_NO_TASK;
453 * Task which will be run when overlay connect request has been timed out
455 * @param cls the OverlayConnectContext
456 * @param tc the TaskContext
459 timeout_overlay_connect (void *cls,
460 const struct GNUNET_SCHEDULER_TaskContext *tc)
462 struct OverlayConnectContext *occ = cls;
464 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task);
465 occ->timeout_task = GNUNET_SCHEDULER_NO_TASK;
466 LOG (GNUNET_ERROR_TYPE_WARNING,
467 "0x%llx: Timeout while connecting peers %u and %u\n", occ->op_id,
468 occ->peer_id, occ->other_peer_id);
469 GST_send_operation_fail_msg (occ->client, occ->op_id, occ->emsg);
475 * Function called to notify transport users that another
476 * peer connected to us.
479 * @param new_peer the peer that connected
480 * @param ats performance data
481 * @param ats_count number of entries in ats (excluding 0-termination)
484 overlay_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer,
485 const struct GNUNET_ATS_Information *ats,
486 unsigned int ats_count)
488 struct OverlayConnectContext *occ = cls;
489 struct GNUNET_TESTBED_ConnectionEventMessage *msg;
491 char *other_peer_str;
493 //LOG_DEBUG ("Overlay connect notify\n");
495 memcmp (new_peer, &occ->peer_identity,
496 sizeof (struct GNUNET_PeerIdentity)))
498 new_peer_str = GNUNET_strdup (GNUNET_i2s (new_peer));
499 other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity));
501 memcmp (new_peer, &occ->other_peer_identity,
502 sizeof (struct GNUNET_PeerIdentity)))
504 /* LOG_DEBUG ("Unexpected peer %4s connected when expecting peer %4s\n", */
505 /* new_peer_str, other_peer_str); */
506 GNUNET_free (new_peer_str);
507 GNUNET_free (other_peer_str);
510 GNUNET_free (new_peer_str);
511 LOG_DEBUG ("0x%llx: Peer %4s connected to peer %4s\n", occ->op_id,
512 other_peer_str, GNUNET_i2s (&occ->peer_identity));
513 GNUNET_free (other_peer_str);
514 if (GNUNET_SCHEDULER_NO_TASK != occ->send_hello_task)
516 GNUNET_SCHEDULER_cancel (occ->send_hello_task);
517 occ->send_hello_task = GNUNET_SCHEDULER_NO_TASK;
519 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task);
520 GNUNET_SCHEDULER_cancel (occ->timeout_task);
521 occ->timeout_task = GNUNET_SCHEDULER_NO_TASK;
522 if (GNUNET_SCHEDULER_NO_TASK != occ->tcc.task)
524 GNUNET_SCHEDULER_cancel (occ->tcc.task);
525 occ->tcc.task = GNUNET_SCHEDULER_NO_TASK;
527 GNUNET_free_non_null (occ->emsg);
529 LOG_DEBUG ("0x%llx: Peers connected - Sending overlay connect success\n",
531 msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ConnectionEventMessage));
533 htons (sizeof (struct GNUNET_TESTBED_ConnectionEventMessage));
534 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONNECT_EVENT);
535 msg->event_type = htonl (GNUNET_TESTBED_ET_CONNECT);
536 msg->peer1 = htonl (occ->peer_id);
537 msg->peer2 = htonl (occ->other_peer_id);
538 msg->operation_id = GNUNET_htonll (occ->op_id);
539 GST_queue_message (occ->client, &msg->header);
540 occ->cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup_occ, occ);
546 * Task to ask transport of a peer to connect to another peer
548 * @param cls the TryConnectContext
549 * @param tc the scheduler task context
552 try_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
556 * Callback to be called with result of the try connect request.
558 * @param cls the overlay connect context
559 * @param result GNUNET_OK if message was transmitted to transport service
560 * GNUNET_SYSERR if message was not transmitted to transport service
563 try_connect_cb (void *cls, const int result)
565 struct TryConnectContext *tcc = cls;
568 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == tcc->task);
570 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
571 (GNUNET_TIME_UNIT_MILLISECONDS,
572 500 + pow (2, ++tcc->retries)),
573 &try_connect_task, tcc);
578 * Task to ask transport of a peer to connect to another peer
580 * @param cls the TryConnectContext
581 * @param tc the scheduler task context
584 try_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
586 struct TryConnectContext *tcc = cls;
588 tcc->task = GNUNET_SCHEDULER_NO_TASK;
589 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
591 GNUNET_assert (NULL == tcc->tch);
592 GNUNET_assert (NULL != tcc->pid);
593 GNUNET_assert (NULL != tcc->th);
594 LOG_DEBUG ("0x%llx: Trail %u to connect to peer %s\n", tcc->op_id,
595 tcc->retries, GNUNET_i2s (tcc->pid));
597 GNUNET_TRANSPORT_try_connect (tcc->th, tcc->pid, &try_connect_cb, tcc);
602 * Task to offer HELLO of peer 1 to peer 2 and try to make peer 2 to connect to
605 * @param cls the OverlayConnectContext
606 * @param tc the TaskContext from scheduler
609 send_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
613 * Task that is run when hello has been sent
615 * @param cls the overlay connect context
616 * @param tc the scheduler task context; if tc->reason =
617 * GNUNET_SCHEDULER_REASON_TIMEOUT then sending HELLO failed; if
618 * GNUNET_SCHEDULER_REASON_READ_READY is succeeded
621 occ_hello_sent_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
623 struct OverlayConnectContext *occ = cls;
626 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == occ->send_hello_task);
627 if (GNUNET_SCHEDULER_REASON_TIMEOUT == tc->reason)
629 GNUNET_free_non_null (occ->emsg);
630 GNUNET_asprintf (&occ->emsg,
631 "0x%llx: Timeout while offering HELLO to other peer",
633 occ->send_hello_task = GNUNET_SCHEDULER_add_now (&send_hello, occ);
636 if (GNUNET_SCHEDULER_REASON_READ_READY != tc->reason)
638 GNUNET_free_non_null (occ->emsg);
639 GNUNET_asprintf (&occ->emsg, "0x%llx: Timeout while try connect", occ->op_id);
640 occ->tcc.pid = &occ->peer_identity;
641 occ->tcc.op_id = occ->op_id;
642 occ->tcc.task = GNUNET_SCHEDULER_add_now (&try_connect_task, &occ->tcc);
647 * Task to offer HELLO of peer 1 to peer 2 and try to make peer 2 to connect to
650 * @param cls the OverlayConnectContext
651 * @param tc the TaskContext from scheduler
654 send_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
656 struct OverlayConnectContext *occ = cls;
657 char *other_peer_str;
659 occ->send_hello_task = GNUNET_SCHEDULER_NO_TASK;
660 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
662 GNUNET_assert (NULL != occ->hello);
663 other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity));
664 if (NULL != occ->peer2_controller)
666 struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg;
670 LOG_DEBUG ("0x%llx: Offering HELLO of %s (size: %u) to %s via Remote "
671 "Overlay Request\n", occ->op_id,
672 GNUNET_i2s (&occ->peer_identity), ntohs (occ->hello->size),
674 hello_size = ntohs (occ->hello->size);
676 sizeof (struct GNUNET_TESTBED_RemoteOverlayConnectMessage) + hello_size;
677 msg = GNUNET_malloc (msize);
679 htons (GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT);
680 msg->header.size = htons (msize);
681 msg->peer = htonl (occ->other_peer_id);
682 msg->operation_id = GNUNET_htonll (occ->op_id);
683 (void) memcpy (&msg->peer_identity, &occ->peer_identity,
684 sizeof (struct GNUNET_PeerIdentity));
685 memcpy (msg->hello, occ->hello, hello_size);
686 GNUNET_TESTBED_queue_message_ (occ->peer2_controller, &msg->header);
690 LOG_DEBUG ("0x%llx: Offering HELLO of %s to %s\n", occ->op_id,
691 GNUNET_i2s (&occ->peer_identity), other_peer_str);
693 GNUNET_TRANSPORT_offer_hello (occ->tcc.th, occ->hello,
694 occ_hello_sent_cb, occ);
695 if (NULL == occ->ohh)
698 occ->send_hello_task =
699 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
700 (GNUNET_TIME_UNIT_MILLISECONDS,
702 GNUNET_CRYPTO_random_u32
703 (GNUNET_CRYPTO_QUALITY_WEAK, 500)),
707 GNUNET_free (other_peer_str);
712 * Connects to the transport of the other peer if it is a local peer and
713 * schedules the send hello task
715 * @param occ the overlay connect context
718 p2_transport_connect (struct OverlayConnectContext *occ)
720 GNUNET_assert (NULL == occ->emsg);
721 GNUNET_assert (NULL != occ->hello);
722 GNUNET_assert (NULL == occ->ghh);
723 GNUNET_assert (NULL == occ->p1th);
724 if (NULL == occ->peer2_controller)
726 GST_peer_list[occ->other_peer_id]->reference_cnt++;
728 GNUNET_TRANSPORT_connect (GST_peer_list[occ->other_peer_id]->
729 details.local.cfg, &occ->other_peer_identity,
730 NULL, NULL, NULL, NULL);
731 if (NULL == occ->tcc.th)
733 GNUNET_asprintf (&occ->emsg, "0x%llx: Cannot connect to TRANSPORT of %s",
734 occ->op_id, GNUNET_i2s (&occ->other_peer_identity));
735 GNUNET_SCHEDULER_cancel (occ->timeout_task);
737 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
741 GNUNET_asprintf (&occ->emsg, "0x%llx: Timeout while offering HELLO to %s",
742 occ->op_id, GNUNET_i2s (&occ->other_peer_identity));
743 occ->send_hello_task = GNUNET_SCHEDULER_add_now (&send_hello, occ);
748 * Test for checking whether HELLO message is empty
750 * @param cls empty flag to set
751 * @param address the HELLO
752 * @param expiration expiration of the HELLO
756 test_address (void *cls, const struct GNUNET_HELLO_Address *address,
757 struct GNUNET_TIME_Absolute expiration)
767 * Function called whenever there is an update to the HELLO of peers in the
768 * OverlayConnectClosure. If we have a valid HELLO, we connect to the peer 2's
769 * transport and offer peer 1's HELLO and ask peer 2 to connect to peer 1
772 * @param hello our updated HELLO
775 hello_update_cb (void *cls, const struct GNUNET_MessageHeader *hello)
777 struct OverlayConnectContext *occ = cls;
781 msize = ntohs (hello->size);
783 (void) GNUNET_HELLO_iterate_addresses ((const struct GNUNET_HELLO_Message *)
784 hello, GNUNET_NO, &test_address,
786 if (GNUNET_YES == empty)
788 LOG_DEBUG ("0x%llx: HELLO of %s is empty\n", occ->op_id,
789 GNUNET_i2s (&occ->peer_identity));
792 LOG_DEBUG ("0x%llx: Received HELLO of %s\n", occ->op_id,
793 GNUNET_i2s (&occ->peer_identity));
794 occ->hello = GNUNET_malloc (msize);
795 GST_hello_cache_add (&occ->peer_identity, hello);
796 memcpy (occ->hello, hello, msize);
797 GNUNET_TRANSPORT_get_hello_cancel (occ->ghh);
799 GNUNET_TRANSPORT_disconnect (occ->p1th);
801 occ->peer->reference_cnt--;
802 GNUNET_free_non_null (occ->emsg);
804 p2_transport_connect (occ);
809 * Function called after GNUNET_CORE_connect has succeeded (or failed
810 * for good). Note that the private key of the peer is intentionally
811 * not exposed here; if you need it, your process should try to read
812 * the private key file directly (which should work if you are
816 * @param server handle to the server, NULL if we failed
817 * @param my_identity ID of this peer, NULL if we failed
820 core_startup_cb (void *cls, struct GNUNET_CORE_Handle *server,
821 const struct GNUNET_PeerIdentity *my_identity)
823 struct OverlayConnectContext *occ = cls;
824 const struct GNUNET_MessageHeader *hello;
826 GNUNET_free_non_null (occ->emsg);
827 (void) GNUNET_asprintf (&occ->emsg,
828 "0x%llx: Failed to connect to CORE of peer with"
829 "id: %u", occ->op_id, occ->peer_id);
830 if ((NULL == server) || (NULL == my_identity))
832 GNUNET_free (occ->emsg);
835 memcpy (&occ->peer_identity, my_identity,
836 sizeof (struct GNUNET_PeerIdentity));
837 LOG_DEBUG ("0x%llx: Acquiring HELLO of peer %s\n", occ->op_id,
838 GNUNET_i2s (&occ->peer_identity));
839 /* Lookup for HELLO in hello cache */
840 if (NULL != (hello = GST_hello_cache_lookup (&occ->peer_identity)))
842 LOG_DEBUG ("0x%llx: HELLO of peer %s found in cache\n", occ->op_id,
843 GNUNET_i2s (&occ->peer_identity));
844 occ->hello = GNUNET_copy_message (hello);
845 p2_transport_connect (occ);
848 occ->peer->reference_cnt++;
850 GNUNET_TRANSPORT_connect (occ->peer->details.local.cfg,
851 &occ->peer_identity, NULL, NULL, NULL, NULL);
852 if (NULL == occ->p1th)
854 GNUNET_asprintf (&occ->emsg,
855 "0x%llx: Cannot connect to TRANSPORT of peer %4s",
856 occ->op_id, GNUNET_i2s (&occ->peer_identity));
859 GNUNET_asprintf (&occ->emsg,
860 "0x%llx: Timeout while acquiring HELLO of peer %4s",
861 occ->op_id, GNUNET_i2s (&occ->peer_identity));
862 occ->ghh = GNUNET_TRANSPORT_get_hello (occ->p1th, &hello_update_cb, occ);
866 GNUNET_SCHEDULER_cancel (occ->timeout_task);
867 occ->timeout_task = GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
873 * Callback which will be called when overlay connect operation is started
875 * @param cls the closure from GNUNET_TESTBED_operation_create_()
878 opstart_overlay_connect (void *cls)
880 struct OverlayConnectContext *occ = cls;
882 const struct GNUNET_CORE_MessageHandler no_handlers[] = {
886 GNUNET_assert (NULL != occ->lop);
887 /* Connect to the core of 1st peer and wait for the 2nd peer to connect */
888 occ->emsg = GNUNET_strdup ("Timeout while connecting to CORE");
889 GNUNET_asprintf (&occ->emsg,
890 "0x%llx: Timeout while connecting to CORE of peer with "
891 "id: %u", occ->op_id, occ->peer_id);
892 occ->peer->reference_cnt++;
894 GNUNET_CORE_connect (occ->peer->details.local.cfg, occ, &core_startup_cb,
895 &overlay_connect_notify, NULL, NULL, GNUNET_NO, NULL,
896 GNUNET_NO, no_handlers);
897 if (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task)
898 GNUNET_SCHEDULER_cancel (occ->timeout_task);
901 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
904 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_overlay_connect, occ);
909 * Callback which will be called when overlay connect operation is released
911 * @param cls the closure from GNUNET_TESTBED_operation_create_()
914 oprelease_overlay_connect (void *cls)
916 struct OverlayConnectContext *occ = cls;
918 GNUNET_assert (NULL != occ->lop);
925 * Callback to be called when forwarded get peer config operation as part of
926 * overlay connect is successfull. Connection to Peer 1's core is made and is
927 * checked for new connection from peer 2
929 * @param cls ForwardedOperationContext
930 * @param msg the peer create success message
933 overlay_connect_get_config (void *cls, const struct GNUNET_MessageHeader *msg)
935 struct OverlayConnectContext *occ = cls;
936 const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *cmsg;
939 if (GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONFIGURATION != ntohs (msg->type))
941 GNUNET_SCHEDULER_cancel (occ->timeout_task);
943 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
946 (const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *) msg;
947 memcpy (&occ->other_peer_identity, &cmsg->peer_identity,
948 sizeof (struct GNUNET_PeerIdentity));
949 GNUNET_free_non_null (occ->emsg);
951 GNUNET_assert (NULL == occ->lop);
953 GNUNET_TESTBED_operation_create_ (occ, &opstart_overlay_connect,
954 &oprelease_overlay_connect);
955 /* This operation needs in total 2 connections (one to core and one to
957 GNUNET_TESTBED_operation_queue_insert2_ (GST_opq_openfds, occ->lop, 2);
958 GNUNET_TESTBED_operation_begin_wait_ (occ->lop);
964 * Callback which will be called to after a host registration succeeded or failed
966 * @param cls the RegisteredHostContext
967 * @param emsg the error message; NULL if host registration is successful
970 registeredhost_registration_completion (void *cls, const char *emsg)
972 struct RegisteredHostContext *rhc = cls;
973 struct GNUNET_CONFIGURATION_Handle *cfg;
974 uint32_t peer2_host_id;
976 /* if (NULL != rhc->focc_dll_head) */
977 /* TESTBED_process_next_focc (rhc); */
978 peer2_host_id = GNUNET_TESTBED_host_get_id_ (rhc->reg_host);
979 GNUNET_assert (RHC_INIT == rhc->state);
980 GNUNET_assert (NULL == rhc->sub_op);
981 if ((NULL == rhc->gateway2) || ((peer2_host_id < GST_slave_list_size) /* Check if we have the needed config */
982 && (NULL != GST_slave_list[peer2_host_id])))
984 rhc->state = RHC_LINK;
987 rhc->gateway2) ? our_config : GST_slave_list[peer2_host_id]->cfg;
989 GNUNET_TESTBED_controller_link (rhc, rhc->gateway->controller,
990 rhc->reg_host, rhc->host, cfg,
994 rhc->state = RHC_GET_CFG;
996 GNUNET_TESTBED_get_slave_config (rhc, rhc->gateway2->controller,
1002 * Iterator to match a registered host context
1004 * @param cls pointer 2 pointer of RegisteredHostContext
1005 * @param key current key code
1006 * @param value value in the hash map
1007 * @return GNUNET_YES if we should continue to
1012 reghost_match_iterator (void *cls, const struct GNUNET_HashCode *key,
1015 struct RegisteredHostContext **rh = cls;
1016 struct RegisteredHostContext *rh_val = value;
1018 if ((rh_val->host == (*rh)->host) && (rh_val->reg_host == (*rh)->reg_host))
1029 * Function to generate the hashcode corresponding to a RegisteredHostContext
1031 * @param reg_host the host which is being registered in RegisteredHostContext
1032 * @param host the host of the controller which has to connect to the above rhost
1033 * @return the hashcode
1035 static struct GNUNET_HashCode
1036 hash_hosts (struct GNUNET_TESTBED_Host *reg_host,
1037 struct GNUNET_TESTBED_Host *host)
1039 struct GNUNET_HashCode hash;
1040 uint32_t host_ids[2];
1042 host_ids[0] = GNUNET_TESTBED_host_get_id_ (reg_host);
1043 host_ids[1] = GNUNET_TESTBED_host_get_id_ (host);
1044 GNUNET_CRYPTO_hash (host_ids, sizeof (host_ids), &hash);
1050 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_OLCONNECT messages
1053 * @param client identification of the client
1054 * @param message the actual message
1057 GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
1058 const struct GNUNET_MessageHeader *message)
1060 const struct GNUNET_TESTBED_OverlayConnectMessage *msg;
1062 struct OverlayConnectContext *occ;
1063 struct GNUNET_TESTBED_Controller *peer2_controller;
1064 uint64_t operation_id;
1067 uint32_t peer2_host_id;
1069 if (sizeof (struct GNUNET_TESTBED_OverlayConnectMessage) !=
1070 ntohs (message->size))
1073 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1076 msg = (const struct GNUNET_TESTBED_OverlayConnectMessage *) message;
1077 p1 = ntohl (msg->peer1);
1078 p2 = ntohl (msg->peer2);
1079 if ((p1 >= GST_peer_list_size) || (NULL == GST_peer_list[p1]))
1082 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1085 peer = GST_peer_list[p1];
1086 peer2_host_id = ntohl (msg->peer2_host_id);
1087 operation_id = GNUNET_ntohll (msg->operation_id);
1089 ("Received overlay connect for peers %u and %u with op id: 0x%llx\n", p1,
1091 if (GNUNET_YES == peer->is_remote)
1093 struct ForwardedOperationContext *fopc;
1094 struct Route *route_to_peer2_host;
1095 struct Route *route_to_peer1_host;
1097 LOG_DEBUG ("0x%llx: Forwarding overlay connect\n", operation_id);
1098 route_to_peer2_host = NULL;
1099 route_to_peer1_host = NULL;
1100 route_to_peer2_host = GST_find_dest_route (peer2_host_id);
1101 if ((NULL != route_to_peer2_host) ||
1102 (peer2_host_id == GST_context->host_id))
1104 /* Peer 2 either below us OR with us */
1105 route_to_peer1_host =
1106 GST_find_dest_route (GST_peer_list[p1]->details.
1107 remote.remote_host_id);
1108 /* Because we get this message only if we know where peer 1 is */
1109 GNUNET_assert (NULL != route_to_peer1_host);
1110 if ((peer2_host_id == GST_context->host_id) ||
1111 (route_to_peer2_host->dest != route_to_peer1_host->dest))
1113 /* Peer2 is either with us OR peer1 and peer2 can be reached through
1114 * different gateways */
1115 struct GNUNET_HashCode hash;
1116 struct RegisteredHostContext *rhc;
1119 rhc = GNUNET_malloc (sizeof (struct RegisteredHostContext));
1120 if (NULL != route_to_peer2_host)
1121 rhc->reg_host = GST_host_list[route_to_peer2_host->dest];
1123 rhc->reg_host = GST_host_list[GST_context->host_id];
1124 rhc->host = GST_host_list[route_to_peer1_host->dest];
1125 GNUNET_assert (NULL != rhc->reg_host);
1126 GNUNET_assert (NULL != rhc->host);
1127 rhc->gateway = peer->details.remote.slave;
1130 route_to_peer2_host) ? NULL :
1131 GST_slave_list[route_to_peer2_host->dest];
1132 rhc->state = RHC_INIT;
1133 GNUNET_SERVER_client_keep (client);
1134 rhc->client = client;
1135 hash = hash_hosts (rhc->reg_host, rhc->host);
1136 skip_focc = GNUNET_NO;
1138 GNUNET_CONTAINER_multihashmap_contains (peer->details.
1139 remote.slave->reghost_map,
1142 GNUNET_CONTAINER_multihashmap_get_multiple (peer->details.remote.
1145 reghost_match_iterator,
1148 /* create and add a new registerd host context */
1149 /* add the focc to its queue */
1150 GNUNET_CONTAINER_multihashmap_put (peer->details.remote.
1151 slave->reghost_map, &hash, rhc,
1152 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1153 GNUNET_assert (NULL != GST_host_list[peer2_host_id]);
1154 GST_queue_host_registration (peer->details.remote.slave,
1155 registeredhost_registration_completion,
1156 rhc, GST_host_list[peer2_host_id]);
1160 /* rhc is now set to the existing one from the hash map by
1161 * reghost_match_iterator() */
1162 /* if queue is empty then ignore creating focc and proceed with
1163 * normal forwarding */
1164 if (RHC_OL_CONNECT == rhc->state)
1165 skip_focc = GNUNET_YES;
1167 if (GNUNET_NO == skip_focc)
1169 struct ForwardedOverlayConnectContext *focc;
1171 focc = GNUNET_malloc (sizeof (struct ForwardedOverlayConnectContext));
1174 focc->peer2_host_id = peer2_host_id;
1175 focc->orig_msg = GNUNET_copy_message (message);
1176 focc->operation_id = operation_id;
1177 GNUNET_CONTAINER_DLL_insert_tail (rhc->focc_dll_head,
1178 rhc->focc_dll_tail, focc);
1179 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1184 fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
1185 GNUNET_SERVER_client_keep (client);
1186 fopc->client = client;
1187 fopc->operation_id = operation_id;
1188 fopc->type = OP_OVERLAY_CONNECT;
1190 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
1191 slave->controller, operation_id,
1193 &GST_forwarded_operation_reply_relay,
1195 fopc->timeout_task =
1196 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &GST_forwarded_operation_timeout,
1198 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
1199 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1203 peer2_controller = NULL;
1204 if ((p2 >= GST_peer_list_size) || (NULL == GST_peer_list[p2]))
1206 if ((peer2_host_id >= GST_slave_list_size) ||
1207 (NULL == GST_slave_list[peer2_host_id]))
1209 LOG (GNUNET_ERROR_TYPE_WARNING,
1210 "0x%llx: Configuration of peer2's controller missing for connecting peers"
1211 "%u and %u\n", operation_id, p1, p2);
1212 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1215 peer2_controller = GST_slave_list[peer2_host_id]->controller;
1216 if (NULL == peer2_controller)
1218 GNUNET_break (0); /* What's going on? */
1219 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1225 if (GNUNET_YES == GST_peer_list[p2]->is_remote)
1226 peer2_controller = GST_peer_list[p2]->details.remote.slave->controller;
1228 occ = GNUNET_malloc (sizeof (struct OverlayConnectContext));
1229 GNUNET_CONTAINER_DLL_insert_tail (occq_head, occq_tail, occ);
1230 GNUNET_SERVER_client_keep (client);
1231 occ->client = client;
1233 occ->other_peer_id = p2;
1234 occ->peer = GST_peer_list[p1];
1235 occ->op_id = GNUNET_ntohll (msg->operation_id);
1236 occ->peer2_controller = peer2_controller;
1237 /* Get the identity of the second peer */
1238 if (NULL != occ->peer2_controller)
1240 struct GNUNET_TESTBED_PeerGetConfigurationMessage cmsg;
1243 htons (sizeof (struct GNUNET_TESTBED_PeerGetConfigurationMessage));
1245 htons (GNUNET_MESSAGE_TYPE_TESTBED_GET_PEER_CONFIGURATION);
1246 cmsg.peer_id = msg->peer2;
1247 cmsg.operation_id = msg->operation_id;
1249 GNUNET_TESTBED_forward_operation_msg_ (occ->peer2_controller,
1250 occ->op_id, &cmsg.header,
1251 &overlay_connect_get_config,
1253 GNUNET_asprintf (&occ->emsg,
1254 "0x%llx: Timeout while getting peer identity of peer "
1255 "with id: %u", occ->op_id, occ->other_peer_id);
1256 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == occ->timeout_task);
1258 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_overlay_connect, occ);
1259 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1262 GNUNET_TESTING_peer_get_identity (GST_peer_list[occ->other_peer_id]->
1264 &occ->other_peer_identity);
1266 GNUNET_TESTBED_operation_create_ (occ, &opstart_overlay_connect,
1267 &oprelease_overlay_connect);
1268 /* This operation needs in total 2 connections (one to core and one to
1270 GNUNET_TESTBED_operation_queue_insert2_ (GST_opq_openfds, occ->lop, 2);
1271 GNUNET_TESTBED_operation_begin_wait_ (occ->lop);
1272 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1277 * Function to cleanup RemoteOverlayConnectCtx and any associated tasks
1280 * @param rocc the RemoteOverlayConnectCtx
1283 cleanup_rocc (struct RemoteOverlayConnectCtx *rocc)
1285 LOG_DEBUG ("0x%llx: Cleaning up rocc\n", rocc->op_id);
1286 if (GNUNET_SCHEDULER_NO_TASK != rocc->attempt_connect_task_id)
1287 GNUNET_SCHEDULER_cancel (rocc->attempt_connect_task_id);
1288 if (GNUNET_SCHEDULER_NO_TASK != rocc->timeout_rocc_task_id)
1289 GNUNET_SCHEDULER_cancel (rocc->timeout_rocc_task_id);
1290 if (NULL != rocc->ohh)
1291 GNUNET_TRANSPORT_offer_hello_cancel (rocc->ohh);
1292 if (NULL != rocc->tcc.tch)
1293 GNUNET_TRANSPORT_try_connect_cancel (rocc->tcc.tch);
1294 if (GNUNET_SCHEDULER_NO_TASK != rocc->tcc.task)
1295 GNUNET_SCHEDULER_cancel (rocc->tcc.task);
1296 GNUNET_TRANSPORT_disconnect (rocc->tcc.th);
1297 rocc->peer->reference_cnt--;
1298 if ((GNUNET_YES == rocc->peer->destroy_flag) &&
1299 (0 == rocc->peer->reference_cnt))
1300 GST_destroy_peer (rocc->peer);
1301 GNUNET_free_non_null (rocc->hello);
1302 GNUNET_CONTAINER_DLL_remove (roccq_head, roccq_tail, rocc);
1308 * Task to timeout rocc and cleanit up
1310 * @param cls the RemoteOverlayConnectCtx
1311 * @param tc the TaskContext from scheduler
1314 timeout_rocc_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1316 struct RemoteOverlayConnectCtx *rocc = cls;
1318 GNUNET_assert (rocc->timeout_rocc_task_id != GNUNET_SCHEDULER_NO_TASK);
1319 rocc->timeout_rocc_task_id = GNUNET_SCHEDULER_NO_TASK;
1320 LOG_DEBUG ("0x%llx: rocc timed out\n", rocc->op_id);
1321 cleanup_rocc (rocc);
1326 * Function called to notify transport users that another
1327 * peer connected to us.
1329 * @param cls closure
1330 * @param new_peer the peer that connected
1331 * @param ats performance data
1332 * @param ats_count number of entries in ats (excluding 0-termination)
1335 transport_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer,
1336 const struct GNUNET_ATS_Information *ats,
1339 struct RemoteOverlayConnectCtx *rocc = cls;
1341 LOG_DEBUG ("0x%llx: Request Overlay connect notify\n", rocc->op_id);
1342 if (0 != memcmp (new_peer, &rocc->a_id, sizeof (struct GNUNET_PeerIdentity)))
1344 LOG_DEBUG ("0x%llx: Peer %4s connected\n", rocc->op_id,
1345 GNUNET_i2s (&rocc->a_id));
1346 cleanup_rocc (rocc);
1351 * Task to offer the HELLO message to the peer and ask it to connect to the peer
1352 * whose identity is in RemoteOverlayConnectCtx
1354 * @param cls the RemoteOverlayConnectCtx
1355 * @param tc the TaskContext from scheduler
1358 attempt_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
1362 * Task that is run when hello has been sent
1364 * @param cls the overlay connect context
1365 * @param tc the scheduler task context; if tc->reason =
1366 * GNUNET_SCHEDULER_REASON_TIMEOUT then sending HELLO failed; if
1367 * GNUNET_SCHEDULER_REASON_READ_READY is succeeded
1370 rocc_hello_sent_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1372 struct RemoteOverlayConnectCtx *rocc = cls;
1375 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == rocc->attempt_connect_task_id);
1376 LOG_DEBUG ("0x%llx: HELLO of peer %4s sent to local peer with id: %u\n",
1377 rocc->op_id, GNUNET_i2s (&rocc->a_id), rocc->peer->id);
1378 if (GNUNET_SCHEDULER_REASON_TIMEOUT == tc->reason)
1381 rocc->attempt_connect_task_id =
1382 GNUNET_SCHEDULER_add_now (&attempt_connect_task, rocc);
1385 if (GNUNET_SCHEDULER_REASON_READ_READY != tc->reason)
1387 rocc->tcc.task = GNUNET_SCHEDULER_add_now (&try_connect_task, &rocc->tcc);
1392 * Task to offer the HELLO message to the peer and ask it to connect to the peer
1393 * whose identity is in RemoteOverlayConnectCtx
1395 * @param cls the RemoteOverlayConnectCtx
1396 * @param tc the TaskContext from scheduler
1399 attempt_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1401 struct RemoteOverlayConnectCtx *rocc = cls;
1403 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != rocc->attempt_connect_task_id);
1404 rocc->attempt_connect_task_id = GNUNET_SCHEDULER_NO_TASK;
1405 LOG_DEBUG ("0x%llx: Offering HELLO of peer %4s to local peer with id: %u\n",
1406 rocc->op_id, GNUNET_i2s (&rocc->a_id), rocc->peer->id);
1408 GNUNET_TRANSPORT_offer_hello (rocc->tcc.th, rocc->hello,
1409 rocc_hello_sent_cb, rocc);
1410 if (NULL == rocc->ohh)
1411 rocc->attempt_connect_task_id =
1412 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
1413 (GNUNET_TIME_UNIT_MILLISECONDS,
1415 GNUNET_CRYPTO_random_u32
1416 (GNUNET_CRYPTO_QUALITY_WEAK, 500)),
1417 &attempt_connect_task, rocc);
1422 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_REQUESTCONNECT messages
1425 * @param client identification of the client
1426 * @param message the actual message
1429 GST_handle_remote_overlay_connect (void *cls,
1430 struct GNUNET_SERVER_Client *client,
1431 const struct GNUNET_MessageHeader *message)
1433 const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg;
1434 struct RemoteOverlayConnectCtx *rocc;
1440 msize = ntohs (message->size);
1441 if (sizeof (struct GNUNET_TESTBED_RemoteOverlayConnectMessage) >= msize)
1444 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1447 msg = (const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *) message;
1448 if ((NULL == msg->hello) ||
1449 (GNUNET_MESSAGE_TYPE_HELLO != ntohs (msg->hello->type)))
1452 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1455 hsize = ntohs (msg->hello->size);
1456 if ((sizeof (struct GNUNET_TESTBED_RemoteOverlayConnectMessage) + hsize) !=
1460 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1463 peer_id = ntohl (msg->peer);
1464 if ((peer_id >= GST_peer_list_size) ||
1465 (NULL == (peer = GST_peer_list[peer_id])))
1467 GNUNET_break_op (0);
1468 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1471 if (GNUNET_YES == peer->is_remote)
1473 struct GNUNET_MessageHeader *msg2;
1475 msg2 = GNUNET_copy_message (message);
1476 GNUNET_TESTBED_queue_message_ (peer->details.remote.slave->controller,
1478 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1481 rocc = GNUNET_malloc (sizeof (struct RemoteOverlayConnectCtx));
1482 rocc->op_id = GNUNET_ntohll (msg->operation_id);
1483 GNUNET_CONTAINER_DLL_insert_tail (roccq_head, roccq_tail, rocc);
1484 memcpy (&rocc->a_id, &msg->peer_identity,
1485 sizeof (struct GNUNET_PeerIdentity));
1486 LOG_DEBUG ("Received request for overlay connection with op_id: 0x%llx "
1487 "from local peer %u to peer %4s with hello size: %u\n",
1488 rocc->op_id, peer_id, GNUNET_i2s (&rocc->a_id), hsize);
1490 rocc->peer->reference_cnt++;
1491 rocc->tcc.op_id = rocc->op_id;
1493 GNUNET_TRANSPORT_connect (rocc->peer->details.local.cfg, NULL, rocc, NULL,
1494 &transport_connect_notify, NULL);
1495 if (NULL == rocc->tcc.th)
1499 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1502 rocc->tcc.pid = &rocc->a_id;
1503 rocc->hello = GNUNET_malloc (hsize);
1504 memcpy (rocc->hello, msg->hello, hsize);
1505 rocc->attempt_connect_task_id =
1506 GNUNET_SCHEDULER_add_now (&attempt_connect_task, rocc);
1507 rocc->timeout_rocc_task_id =
1508 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_rocc_task, rocc);
1509 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1514 * Clears all pending overlay connect contexts in queue
1519 struct OverlayConnectContext *occ;
1521 while (NULL != (occ = occq_head))
1527 * Clears all pending remote overlay connect contexts in queue
1532 struct RemoteOverlayConnectCtx *rocc;
1534 while (NULL != (rocc = roccq_head))
1535 cleanup_rocc (rocc);