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 RequestOverlayConnectContext
197 * the next pointer for DLL
199 struct RequestOverlayConnectContext *next;
202 * the prev pointer for DLL
204 struct RequestOverlayConnectContext *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 transport try connect context
224 struct TryConnectContext tcc;
227 * The peer identity of peer A
229 struct GNUNET_PeerIdentity a_id;
232 * Task for offering HELLO of A to B and doing try_connect
234 GNUNET_SCHEDULER_TaskIdentifier attempt_connect_task_id;
237 * Task to timeout RequestOverlayConnect
239 GNUNET_SCHEDULER_TaskIdentifier timeout_rocc_task_id;
242 * The id of the operation responsible for creating this context
249 * DLL head for OverlayConnectContext DLL - to be used to clean up during shutdown
251 static struct OverlayConnectContext *occq_head;
254 * DLL tail for OverlayConnectContext DLL
256 static struct OverlayConnectContext *occq_tail;
259 * DLL head for RequectOverlayConnectContext DLL - to be used to clean up during
262 static struct RequestOverlayConnectContext *roccq_head;
265 * DLL tail for RequectOverlayConnectContext DLL
267 static struct RequestOverlayConnectContext *roccq_tail;
271 * Cleans up ForwardedOverlayConnectContext
273 * @param focc the ForwardedOverlayConnectContext to cleanup
276 GST_cleanup_focc (struct ForwardedOverlayConnectContext *focc)
278 GNUNET_free_non_null (focc->orig_msg);
284 * Timeout task for cancelling a forwarded overlay connect connect
286 * @param cls the ForwardedOverlayConnectContext
287 * @param tc the task context from the scheduler
290 forwarded_overlay_connect_timeout (void *cls,
291 const struct GNUNET_SCHEDULER_TaskContext
294 struct ForwardedOperationContext *fopc = cls;
295 struct RegisteredHostContext *rhc;
296 struct ForwardedOverlayConnectContext *focc;
299 focc = rhc->focc_dll_head;
300 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
301 GST_cleanup_focc (focc);
302 LOG_DEBUG ("Overlay linking between peers %u and %u failed\n", focc->peer1,
304 GST_forwarded_operation_timeout (cls, tc);
305 if (NULL != rhc->focc_dll_head)
306 GST_process_next_focc (rhc);
311 * Callback to be called when forwarded overlay connection operation has a reply
312 * from the sub-controller successfull. We have to relay the reply msg back to
315 * @param cls ForwardedOperationContext
316 * @param msg the peer create success message
319 forwarded_overlay_connect_listener (void *cls,
320 const struct GNUNET_MessageHeader *msg)
322 struct ForwardedOperationContext *fopc = cls;
323 struct RegisteredHostContext *rhc;
324 struct ForwardedOverlayConnectContext *focc;
327 GST_forwarded_operation_reply_relay (cls, msg);
328 focc = rhc->focc_dll_head;
329 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
330 GST_cleanup_focc (focc);
331 if (NULL != rhc->focc_dll_head)
332 GST_process_next_focc (rhc);
337 * Processes a forwarded overlay connect context in the queue of the given RegisteredHostContext
339 * @param rhc the RegisteredHostContext
342 GST_process_next_focc (struct RegisteredHostContext *rhc)
344 struct ForwardedOperationContext *fopc;
345 struct ForwardedOverlayConnectContext *focc;
347 focc = rhc->focc_dll_head;
348 GNUNET_assert (NULL != focc);
349 GNUNET_assert (RHC_OL_CONNECT == rhc->state);
350 fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
351 GNUNET_SERVER_client_keep (rhc->client);
352 fopc->client = rhc->client;
353 fopc->operation_id = focc->operation_id;
355 fopc->type = OP_OVERLAY_CONNECT;
357 GNUNET_TESTBED_forward_operation_msg_ (rhc->gateway->controller,
358 focc->operation_id, focc->orig_msg,
359 &forwarded_overlay_connect_listener,
361 GNUNET_free (focc->orig_msg);
362 focc->orig_msg = NULL;
364 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &forwarded_overlay_connect_timeout,
366 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
371 * Cleanup overlay connect context structure
373 * @param occ the overlay connect context
376 cleanup_occ (struct OverlayConnectContext *occ)
378 if (NULL != occ->lop)
380 GNUNET_TESTBED_operation_release_ (occ->lop);
383 LOG_DEBUG ("0x%llx: Cleaning up occ\n", occ->op_id);
384 GNUNET_free_non_null (occ->emsg);
385 GNUNET_free_non_null (occ->hello);
386 GNUNET_SERVER_client_drop (occ->client);
387 if (NULL != occ->opc)
388 GNUNET_TESTBED_forward_operation_msg_cancel_ (occ->opc);
389 if (GNUNET_SCHEDULER_NO_TASK != occ->send_hello_task)
390 GNUNET_SCHEDULER_cancel (occ->send_hello_task);
391 if (GNUNET_SCHEDULER_NO_TASK != occ->cleanup_task)
392 GNUNET_SCHEDULER_cancel (occ->cleanup_task);
393 if (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task)
394 GNUNET_SCHEDULER_cancel (occ->timeout_task);
397 GNUNET_CORE_disconnect (occ->ch);
398 occ->peer->reference_cnt--;
400 if (NULL != occ->ghh)
401 GNUNET_TRANSPORT_get_hello_cancel (occ->ghh);
402 if (NULL != occ->ohh)
403 GNUNET_TRANSPORT_offer_hello_cancel (occ->ohh);
404 if (GNUNET_SCHEDULER_NO_TASK != occ->tcc.task)
405 GNUNET_SCHEDULER_cancel (occ->tcc.task);
406 if (NULL != occ->tcc.tch)
407 GNUNET_TRANSPORT_try_connect_cancel (occ->tcc.tch);
408 if (NULL != occ->p1th)
410 GNUNET_TRANSPORT_disconnect (occ->p1th);
411 occ->peer->reference_cnt--;
413 if (NULL != occ->tcc.th)
415 GNUNET_TRANSPORT_disconnect (occ->tcc.th);
416 GST_peer_list[occ->other_peer_id]->reference_cnt--;
418 if ((GNUNET_YES == occ->peer->destroy_flag) &&
419 (0 == occ->peer->reference_cnt))
420 GST_destroy_peer (occ->peer);
421 if ((NULL == occ->peer2_controller) &&
422 (GNUNET_YES == GST_peer_list[occ->other_peer_id]->destroy_flag) &&
423 (0 == GST_peer_list[occ->other_peer_id]->reference_cnt))
424 GST_destroy_peer (GST_peer_list[occ->other_peer_id]);
425 GNUNET_CONTAINER_DLL_remove (occq_head, occq_tail, occ);
426 GNUNET_assert (NULL == occ->lop);
432 * Task for cleaing up overlay connect context structure
434 * @param cls the overlay connect context
435 * @param tc the task context
438 do_cleanup_occ (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
440 struct OverlayConnectContext *occ = cls;
442 occ->cleanup_task = GNUNET_SCHEDULER_NO_TASK;
448 * Task which will be run when overlay connect request has been timed out
450 * @param cls the OverlayConnectContext
451 * @param tc the TaskContext
454 timeout_overlay_connect (void *cls,
455 const struct GNUNET_SCHEDULER_TaskContext *tc)
457 struct OverlayConnectContext *occ = cls;
459 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task);
460 occ->timeout_task = GNUNET_SCHEDULER_NO_TASK;
461 LOG (GNUNET_ERROR_TYPE_WARNING,
462 "0x%llx: Timeout while connecting peers %u and %u\n", occ->op_id,
463 occ->peer_id, occ->other_peer_id);
464 GST_send_operation_fail_msg (occ->client, occ->op_id, occ->emsg);
470 * Function called to notify transport users that another
471 * peer connected to us.
474 * @param new_peer the peer that connected
475 * @param ats performance data
476 * @param ats_count number of entries in ats (excluding 0-termination)
479 overlay_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer,
480 const struct GNUNET_ATS_Information *ats,
481 unsigned int ats_count)
483 struct OverlayConnectContext *occ = cls;
484 struct GNUNET_TESTBED_ConnectionEventMessage *msg;
486 char *other_peer_str;
488 //LOG_DEBUG ("Overlay connect notify\n");
490 memcmp (new_peer, &occ->peer_identity,
491 sizeof (struct GNUNET_PeerIdentity)))
493 new_peer_str = GNUNET_strdup (GNUNET_i2s (new_peer));
494 other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity));
496 memcmp (new_peer, &occ->other_peer_identity,
497 sizeof (struct GNUNET_PeerIdentity)))
499 /* LOG_DEBUG ("Unexpected peer %4s connected when expecting peer %4s\n", */
500 /* new_peer_str, other_peer_str); */
501 GNUNET_free (new_peer_str);
502 GNUNET_free (other_peer_str);
505 GNUNET_free (new_peer_str);
506 LOG_DEBUG ("0x%llx: Peer %4s connected to peer %4s\n", occ->op_id,
507 other_peer_str, GNUNET_i2s (&occ->peer_identity));
508 GNUNET_free (other_peer_str);
509 if (GNUNET_SCHEDULER_NO_TASK != occ->send_hello_task)
511 GNUNET_SCHEDULER_cancel (occ->send_hello_task);
512 occ->send_hello_task = GNUNET_SCHEDULER_NO_TASK;
514 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task);
515 GNUNET_SCHEDULER_cancel (occ->timeout_task);
516 occ->timeout_task = GNUNET_SCHEDULER_NO_TASK;
517 if (GNUNET_SCHEDULER_NO_TASK != occ->tcc.task)
519 GNUNET_SCHEDULER_cancel (occ->tcc.task);
520 occ->tcc.task = GNUNET_SCHEDULER_NO_TASK;
522 GNUNET_free_non_null (occ->emsg);
524 LOG_DEBUG ("0x%llx: Peers connected - Sending overlay connect success\n",
526 msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ConnectionEventMessage));
528 htons (sizeof (struct GNUNET_TESTBED_ConnectionEventMessage));
529 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEERCONEVENT);
530 msg->event_type = htonl (GNUNET_TESTBED_ET_CONNECT);
531 msg->peer1 = htonl (occ->peer_id);
532 msg->peer2 = htonl (occ->other_peer_id);
533 msg->operation_id = GNUNET_htonll (occ->op_id);
534 GST_queue_message (occ->client, &msg->header);
535 occ->cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup_occ, occ);
541 * Task to ask transport of a peer to connect to another peer
543 * @param cls the TryConnectContext
544 * @param tc the scheduler task context
547 try_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
551 * Callback to be called with result of the try connect request.
553 * @param cls the overlay connect context
554 * @param result GNUNET_OK if message was transmitted to transport service
555 * GNUNET_SYSERR if message was not transmitted to transport service
558 try_connect_cb (void *cls, const int result)
560 struct TryConnectContext *tcc = cls;
563 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == tcc->task);
565 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
566 (GNUNET_TIME_UNIT_MILLISECONDS,
567 500 + pow (2, ++tcc->retries)),
568 &try_connect_task, tcc);
573 * Task to ask transport of a peer to connect to another peer
575 * @param cls the TryConnectContext
576 * @param tc the scheduler task context
579 try_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
581 struct TryConnectContext *tcc = cls;
583 tcc->task = GNUNET_SCHEDULER_NO_TASK;
584 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
586 GNUNET_assert (NULL == tcc->tch);
587 GNUNET_assert (NULL != tcc->pid);
588 GNUNET_assert (NULL != tcc->th);
589 LOG_DEBUG ("0x%llx: Trail %u to connect to peer %s\n", tcc->op_id,
590 tcc->retries, GNUNET_i2s (tcc->pid));
592 GNUNET_TRANSPORT_try_connect (tcc->th, tcc->pid, &try_connect_cb, tcc);
597 * Task to offer HELLO of peer 1 to peer 2 and try to make peer 2 to connect to
600 * @param cls the OverlayConnectContext
601 * @param tc the TaskContext from scheduler
604 send_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
608 * Task that is run when hello has been sent
610 * @param cls the overlay connect context
611 * @param tc the scheduler task context; if tc->reason =
612 * GNUNET_SCHEDULER_REASON_TIMEOUT then sending HELLO failed; if
613 * GNUNET_SCHEDULER_REASON_READ_READY is succeeded
616 occ_hello_sent_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
618 struct OverlayConnectContext *occ = cls;
621 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == occ->send_hello_task);
622 if (GNUNET_SCHEDULER_REASON_TIMEOUT == tc->reason)
624 GNUNET_free_non_null (occ->emsg);
625 GNUNET_asprintf (&occ->emsg,
626 "0x%llx: Timeout while offering HELLO to other peer",
628 occ->send_hello_task = GNUNET_SCHEDULER_add_now (&send_hello, occ);
631 if (GNUNET_SCHEDULER_REASON_READ_READY != tc->reason)
633 GNUNET_free_non_null (occ->emsg);
634 GNUNET_asprintf (&occ->emsg, "0x%llx: Timeout while try connect", occ->op_id);
635 occ->tcc.pid = &occ->peer_identity;
636 occ->tcc.op_id = occ->op_id;
637 occ->tcc.task = GNUNET_SCHEDULER_add_now (&try_connect_task, &occ->tcc);
642 * Task to offer HELLO of peer 1 to peer 2 and try to make peer 2 to connect to
645 * @param cls the OverlayConnectContext
646 * @param tc the TaskContext from scheduler
649 send_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
651 struct OverlayConnectContext *occ = cls;
652 char *other_peer_str;
654 occ->send_hello_task = GNUNET_SCHEDULER_NO_TASK;
655 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
657 GNUNET_assert (NULL != occ->hello);
658 other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity));
659 if (NULL != occ->peer2_controller)
661 struct GNUNET_TESTBED_RequestConnectMessage *msg;
665 LOG_DEBUG ("0x%llx: Offering HELLO of %s (size: %u) to %s via Remote "
666 "Overlay Request\n", occ->op_id,
667 GNUNET_i2s (&occ->peer_identity), ntohs (occ->hello->size),
669 hello_size = ntohs (occ->hello->size);
670 msize = sizeof (struct GNUNET_TESTBED_RequestConnectMessage) + hello_size;
671 msg = GNUNET_malloc (msize);
672 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_REQUESTCONNECT);
673 msg->header.size = htons (msize);
674 msg->peer = htonl (occ->other_peer_id);
675 msg->operation_id = GNUNET_htonll (occ->op_id);
676 (void) memcpy (&msg->peer_identity, &occ->peer_identity,
677 sizeof (struct GNUNET_PeerIdentity));
678 memcpy (msg->hello, occ->hello, hello_size);
679 GNUNET_TESTBED_queue_message_ (occ->peer2_controller, &msg->header);
683 LOG_DEBUG ("0x%llx: Offering HELLO of %s to %s\n", occ->op_id,
684 GNUNET_i2s (&occ->peer_identity), other_peer_str);
686 GNUNET_TRANSPORT_offer_hello (occ->tcc.th, occ->hello,
687 occ_hello_sent_cb, occ);
688 if (NULL == occ->ohh)
691 occ->send_hello_task =
692 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
693 (GNUNET_TIME_UNIT_MILLISECONDS,
695 GNUNET_CRYPTO_random_u32
696 (GNUNET_CRYPTO_QUALITY_WEAK, 500)),
700 GNUNET_free (other_peer_str);
705 * Connects to the transport of the other peer if it is a local peer and
706 * schedules the send hello task
708 * @param occ the overlay connect context
711 p2_transport_connect (struct OverlayConnectContext *occ)
713 GNUNET_assert (NULL == occ->emsg);
714 GNUNET_assert (NULL != occ->hello);
715 GNUNET_assert (NULL == occ->ghh);
716 GNUNET_assert (NULL == occ->p1th);
717 if (NULL == occ->peer2_controller)
719 GST_peer_list[occ->other_peer_id]->reference_cnt++;
721 GNUNET_TRANSPORT_connect (GST_peer_list[occ->other_peer_id]->
722 details.local.cfg, &occ->other_peer_identity,
723 NULL, NULL, NULL, NULL);
724 if (NULL == occ->tcc.th)
726 GNUNET_asprintf (&occ->emsg, "0x%llx: Cannot connect to TRANSPORT of %s",
727 occ->op_id, GNUNET_i2s (&occ->other_peer_identity));
728 GNUNET_SCHEDULER_cancel (occ->timeout_task);
730 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
734 GNUNET_asprintf (&occ->emsg, "0x%llx: Timeout while offering HELLO to %s",
735 occ->op_id, GNUNET_i2s (&occ->other_peer_identity));
736 occ->send_hello_task = GNUNET_SCHEDULER_add_now (&send_hello, occ);
741 * Test for checking whether HELLO message is empty
743 * @param cls empty flag to set
744 * @param address the HELLO
745 * @param expiration expiration of the HELLO
749 test_address (void *cls, const struct GNUNET_HELLO_Address *address,
750 struct GNUNET_TIME_Absolute expiration)
760 * Function called whenever there is an update to the HELLO of peers in the
761 * OverlayConnectClosure. If we have a valid HELLO, we connect to the peer 2's
762 * transport and offer peer 1's HELLO and ask peer 2 to connect to peer 1
765 * @param hello our updated HELLO
768 hello_update_cb (void *cls, const struct GNUNET_MessageHeader *hello)
770 struct OverlayConnectContext *occ = cls;
774 msize = ntohs (hello->size);
776 (void) GNUNET_HELLO_iterate_addresses ((const struct GNUNET_HELLO_Message *)
777 hello, GNUNET_NO, &test_address,
779 if (GNUNET_YES == empty)
781 LOG_DEBUG ("0x%llx: HELLO of %s is empty\n", occ->op_id,
782 GNUNET_i2s (&occ->peer_identity));
785 LOG_DEBUG ("0x%llx: Received HELLO of %s\n", occ->op_id,
786 GNUNET_i2s (&occ->peer_identity));
787 occ->hello = GNUNET_malloc (msize);
788 GST_hello_cache_add (&occ->peer_identity, hello);
789 memcpy (occ->hello, hello, msize);
790 GNUNET_TRANSPORT_get_hello_cancel (occ->ghh);
792 GNUNET_TRANSPORT_disconnect (occ->p1th);
794 occ->peer->reference_cnt--;
795 GNUNET_free_non_null (occ->emsg);
797 p2_transport_connect (occ);
802 * Function called after GNUNET_CORE_connect has succeeded (or failed
803 * for good). Note that the private key of the peer is intentionally
804 * not exposed here; if you need it, your process should try to read
805 * the private key file directly (which should work if you are
809 * @param server handle to the server, NULL if we failed
810 * @param my_identity ID of this peer, NULL if we failed
813 core_startup_cb (void *cls, struct GNUNET_CORE_Handle *server,
814 const struct GNUNET_PeerIdentity *my_identity)
816 struct OverlayConnectContext *occ = cls;
817 const struct GNUNET_MessageHeader *hello;
819 GNUNET_free_non_null (occ->emsg);
820 (void) GNUNET_asprintf (&occ->emsg,
821 "0x%llx: Failed to connect to CORE of peer with"
822 "id: %u", occ->op_id, occ->peer_id);
823 if ((NULL == server) || (NULL == my_identity))
825 GNUNET_free (occ->emsg);
828 memcpy (&occ->peer_identity, my_identity,
829 sizeof (struct GNUNET_PeerIdentity));
830 LOG_DEBUG ("0x%llx: Acquiring HELLO of peer %s\n", occ->op_id,
831 GNUNET_i2s (&occ->peer_identity));
832 /* Lookup for HELLO in hello cache */
833 if (NULL != (hello = GST_hello_cache_lookup (&occ->peer_identity)))
835 LOG_DEBUG ("0x%llx: HELLO of peer %s found in cache\n", occ->op_id,
836 GNUNET_i2s (&occ->peer_identity));
837 occ->hello = GNUNET_copy_message (hello);
838 p2_transport_connect (occ);
841 occ->peer->reference_cnt++;
843 GNUNET_TRANSPORT_connect (occ->peer->details.local.cfg,
844 &occ->peer_identity, NULL, NULL, NULL, NULL);
845 if (NULL == occ->p1th)
847 GNUNET_asprintf (&occ->emsg,
848 "0x%llx: Cannot connect to TRANSPORT of peer %4s",
849 occ->op_id, GNUNET_i2s (&occ->peer_identity));
852 GNUNET_asprintf (&occ->emsg,
853 "0x%llx: Timeout while acquiring HELLO of peer %4s",
854 occ->op_id, GNUNET_i2s (&occ->peer_identity));
855 occ->ghh = GNUNET_TRANSPORT_get_hello (occ->p1th, &hello_update_cb, occ);
859 GNUNET_SCHEDULER_cancel (occ->timeout_task);
860 occ->timeout_task = GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
866 * Callback which will be called when overlay connect operation is started
868 * @param cls the closure from GNUNET_TESTBED_operation_create_()
871 opstart_overlay_connect (void *cls)
873 struct OverlayConnectContext *occ = cls;
875 const struct GNUNET_CORE_MessageHandler no_handlers[] = {
879 GNUNET_assert (NULL != occ->lop);
880 /* Connect to the core of 1st peer and wait for the 2nd peer to connect */
881 occ->emsg = GNUNET_strdup ("Timeout while connecting to CORE");
882 GNUNET_asprintf (&occ->emsg,
883 "0x%llx: Timeout while connecting to CORE of peer with "
884 "id: %u", occ->op_id, occ->peer_id);
885 occ->peer->reference_cnt++;
887 GNUNET_CORE_connect (occ->peer->details.local.cfg, occ, &core_startup_cb,
888 &overlay_connect_notify, NULL, NULL, GNUNET_NO, NULL,
889 GNUNET_NO, no_handlers);
890 if (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task)
891 GNUNET_SCHEDULER_cancel (occ->timeout_task);
894 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
897 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_overlay_connect, occ);
902 * Callback which will be called when overlay connect operation is released
904 * @param cls the closure from GNUNET_TESTBED_operation_create_()
907 oprelease_overlay_connect (void *cls)
909 struct OverlayConnectContext *occ = cls;
911 GNUNET_assert (NULL != occ->lop);
918 * Callback to be called when forwarded get peer config operation as part of
919 * overlay connect is successfull. Connection to Peer 1's core is made and is
920 * checked for new connection from peer 2
922 * @param cls ForwardedOperationContext
923 * @param msg the peer create success message
926 overlay_connect_get_config (void *cls, const struct GNUNET_MessageHeader *msg)
928 struct OverlayConnectContext *occ = cls;
929 const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *cmsg;
932 if (GNUNET_MESSAGE_TYPE_TESTBED_PEERCONFIG != ntohs (msg->type))
934 GNUNET_SCHEDULER_cancel (occ->timeout_task);
936 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
939 (const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *) msg;
940 memcpy (&occ->other_peer_identity, &cmsg->peer_identity,
941 sizeof (struct GNUNET_PeerIdentity));
942 GNUNET_free_non_null (occ->emsg);
944 GNUNET_assert (NULL == occ->lop);
946 GNUNET_TESTBED_operation_create_ (occ, &opstart_overlay_connect,
947 &oprelease_overlay_connect);
948 /* This operation needs in total 2 connections (one to core and one to
950 GNUNET_TESTBED_operation_queue_insert2_ (GST_opq_openfds, occ->lop, 2);
951 GNUNET_TESTBED_operation_begin_wait_ (occ->lop);
957 * Callback which will be called to after a host registration succeeded or failed
959 * @param cls the RegisteredHostContext
960 * @param emsg the error message; NULL if host registration is successful
963 registeredhost_registration_completion (void *cls, const char *emsg)
965 struct RegisteredHostContext *rhc = cls;
966 struct GNUNET_CONFIGURATION_Handle *cfg;
967 uint32_t peer2_host_id;
969 /* if (NULL != rhc->focc_dll_head) */
970 /* TESTBED_process_next_focc (rhc); */
971 peer2_host_id = GNUNET_TESTBED_host_get_id_ (rhc->reg_host);
972 GNUNET_assert (RHC_INIT == rhc->state);
973 GNUNET_assert (NULL == rhc->sub_op);
974 if ((NULL == rhc->gateway2) || ((peer2_host_id < GST_slave_list_size) /* Check if we have the needed config */
975 && (NULL != GST_slave_list[peer2_host_id])))
977 rhc->state = RHC_LINK;
980 rhc->gateway2) ? our_config : GST_slave_list[peer2_host_id]->cfg;
982 GNUNET_TESTBED_controller_link (rhc, rhc->gateway->controller,
983 rhc->reg_host, rhc->host, cfg,
987 rhc->state = RHC_GET_CFG;
989 GNUNET_TESTBED_get_slave_config (rhc, rhc->gateway2->controller,
995 * Iterator to match a registered host context
997 * @param cls pointer 2 pointer of RegisteredHostContext
998 * @param key current key code
999 * @param value value in the hash map
1000 * @return GNUNET_YES if we should continue to
1005 reghost_match_iterator (void *cls, const struct GNUNET_HashCode *key,
1008 struct RegisteredHostContext **rh = cls;
1009 struct RegisteredHostContext *rh_val = value;
1011 if ((rh_val->host == (*rh)->host) && (rh_val->reg_host == (*rh)->reg_host))
1022 * Function to generate the hashcode corresponding to a RegisteredHostContext
1024 * @param reg_host the host which is being registered in RegisteredHostContext
1025 * @param host the host of the controller which has to connect to the above rhost
1026 * @return the hashcode
1028 static struct GNUNET_HashCode
1029 hash_hosts (struct GNUNET_TESTBED_Host *reg_host,
1030 struct GNUNET_TESTBED_Host *host)
1032 struct GNUNET_HashCode hash;
1033 uint32_t host_ids[2];
1035 host_ids[0] = GNUNET_TESTBED_host_get_id_ (reg_host);
1036 host_ids[1] = GNUNET_TESTBED_host_get_id_ (host);
1037 GNUNET_CRYPTO_hash (host_ids, sizeof (host_ids), &hash);
1043 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_OLCONNECT messages
1046 * @param client identification of the client
1047 * @param message the actual message
1050 GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
1051 const struct GNUNET_MessageHeader *message)
1053 const struct GNUNET_TESTBED_OverlayConnectMessage *msg;
1055 struct OverlayConnectContext *occ;
1056 struct GNUNET_TESTBED_Controller *peer2_controller;
1057 uint64_t operation_id;
1060 uint32_t peer2_host_id;
1062 if (sizeof (struct GNUNET_TESTBED_OverlayConnectMessage) !=
1063 ntohs (message->size))
1066 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1069 msg = (const struct GNUNET_TESTBED_OverlayConnectMessage *) message;
1070 p1 = ntohl (msg->peer1);
1071 p2 = ntohl (msg->peer2);
1072 if ((p1 >= GST_peer_list_size) || (NULL == GST_peer_list[p1]))
1075 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1078 peer = GST_peer_list[p1];
1079 peer2_host_id = ntohl (msg->peer2_host_id);
1080 operation_id = GNUNET_ntohll (msg->operation_id);
1082 ("Received overlay connect for peers %u and %u with op id: 0x%llx\n", p1,
1084 if (GNUNET_YES == peer->is_remote)
1086 struct ForwardedOperationContext *fopc;
1087 struct Route *route_to_peer2_host;
1088 struct Route *route_to_peer1_host;
1090 LOG_DEBUG ("0x%llx: Forwarding overlay connect\n", operation_id);
1091 route_to_peer2_host = NULL;
1092 route_to_peer1_host = NULL;
1093 route_to_peer2_host = GST_find_dest_route (peer2_host_id);
1094 if ((NULL != route_to_peer2_host) ||
1095 (peer2_host_id == GST_context->host_id))
1097 /* Peer 2 either below us OR with us */
1098 route_to_peer1_host =
1099 GST_find_dest_route (GST_peer_list[p1]->details.
1100 remote.remote_host_id);
1101 /* Because we get this message only if we know where peer 1 is */
1102 GNUNET_assert (NULL != route_to_peer1_host);
1103 if ((peer2_host_id == GST_context->host_id) ||
1104 (route_to_peer2_host->dest != route_to_peer1_host->dest))
1106 /* Peer2 is either with us OR peer1 and peer2 can be reached through
1107 * different gateways */
1108 struct GNUNET_HashCode hash;
1109 struct RegisteredHostContext *rhc;
1112 rhc = GNUNET_malloc (sizeof (struct RegisteredHostContext));
1113 if (NULL != route_to_peer2_host)
1114 rhc->reg_host = GST_host_list[route_to_peer2_host->dest];
1116 rhc->reg_host = GST_host_list[GST_context->host_id];
1117 rhc->host = GST_host_list[route_to_peer1_host->dest];
1118 GNUNET_assert (NULL != rhc->reg_host);
1119 GNUNET_assert (NULL != rhc->host);
1120 rhc->gateway = peer->details.remote.slave;
1123 route_to_peer2_host) ? NULL :
1124 GST_slave_list[route_to_peer2_host->dest];
1125 rhc->state = RHC_INIT;
1126 GNUNET_SERVER_client_keep (client);
1127 rhc->client = client;
1128 hash = hash_hosts (rhc->reg_host, rhc->host);
1129 skip_focc = GNUNET_NO;
1131 GNUNET_CONTAINER_multihashmap_contains (peer->details.
1132 remote.slave->reghost_map,
1135 GNUNET_CONTAINER_multihashmap_get_multiple (peer->details.remote.
1138 reghost_match_iterator,
1141 /* create and add a new registerd host context */
1142 /* add the focc to its queue */
1143 GNUNET_CONTAINER_multihashmap_put (peer->details.remote.
1144 slave->reghost_map, &hash, rhc,
1145 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1146 GNUNET_assert (NULL != GST_host_list[peer2_host_id]);
1147 GST_queue_host_registration (peer->details.remote.slave,
1148 registeredhost_registration_completion,
1149 rhc, GST_host_list[peer2_host_id]);
1153 /* rhc is now set to the existing one from the hash map by
1154 * reghost_match_iterator() */
1155 /* if queue is empty then ignore creating focc and proceed with
1156 * normal forwarding */
1157 if (RHC_OL_CONNECT == rhc->state)
1158 skip_focc = GNUNET_YES;
1160 if (GNUNET_NO == skip_focc)
1162 struct ForwardedOverlayConnectContext *focc;
1164 focc = GNUNET_malloc (sizeof (struct ForwardedOverlayConnectContext));
1167 focc->peer2_host_id = peer2_host_id;
1168 focc->orig_msg = GNUNET_copy_message (message);
1169 focc->operation_id = operation_id;
1170 GNUNET_CONTAINER_DLL_insert_tail (rhc->focc_dll_head,
1171 rhc->focc_dll_tail, focc);
1172 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1177 fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
1178 GNUNET_SERVER_client_keep (client);
1179 fopc->client = client;
1180 fopc->operation_id = operation_id;
1181 fopc->type = OP_OVERLAY_CONNECT;
1183 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
1184 slave->controller, operation_id,
1186 &GST_forwarded_operation_reply_relay,
1188 fopc->timeout_task =
1189 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &GST_forwarded_operation_timeout,
1191 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
1192 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1196 peer2_controller = NULL;
1197 if ((p2 >= GST_peer_list_size) || (NULL == GST_peer_list[p2]))
1199 if ((peer2_host_id >= GST_slave_list_size) ||
1200 (NULL == GST_slave_list[peer2_host_id]))
1202 LOG (GNUNET_ERROR_TYPE_WARNING,
1203 "0x%llx: Configuration of peer2's controller missing for connecting peers"
1204 "%u and %u\n", operation_id, p1, p2);
1205 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1208 peer2_controller = GST_slave_list[peer2_host_id]->controller;
1209 if (NULL == peer2_controller)
1211 GNUNET_break (0); /* What's going on? */
1212 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1218 if (GNUNET_YES == GST_peer_list[p2]->is_remote)
1219 peer2_controller = GST_peer_list[p2]->details.remote.slave->controller;
1221 occ = GNUNET_malloc (sizeof (struct OverlayConnectContext));
1222 GNUNET_CONTAINER_DLL_insert_tail (occq_head, occq_tail, occ);
1223 GNUNET_SERVER_client_keep (client);
1224 occ->client = client;
1226 occ->other_peer_id = p2;
1227 occ->peer = GST_peer_list[p1];
1228 occ->op_id = GNUNET_ntohll (msg->operation_id);
1229 occ->peer2_controller = peer2_controller;
1230 /* Get the identity of the second peer */
1231 if (NULL != occ->peer2_controller)
1233 struct GNUNET_TESTBED_PeerGetConfigurationMessage cmsg;
1236 htons (sizeof (struct GNUNET_TESTBED_PeerGetConfigurationMessage));
1237 cmsg.header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG);
1238 cmsg.peer_id = msg->peer2;
1239 cmsg.operation_id = msg->operation_id;
1241 GNUNET_TESTBED_forward_operation_msg_ (occ->peer2_controller,
1242 occ->op_id, &cmsg.header,
1243 &overlay_connect_get_config,
1245 GNUNET_asprintf (&occ->emsg,
1246 "0x%llx: Timeout while getting peer identity of peer "
1247 "with id: %u", occ->op_id, occ->other_peer_id);
1248 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == occ->timeout_task);
1250 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_overlay_connect, occ);
1251 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1254 GNUNET_TESTING_peer_get_identity (GST_peer_list[occ->other_peer_id]->
1256 &occ->other_peer_identity);
1258 GNUNET_TESTBED_operation_create_ (occ, &opstart_overlay_connect,
1259 &oprelease_overlay_connect);
1260 /* This operation needs in total 2 connections (one to core and one to
1262 GNUNET_TESTBED_operation_queue_insert2_ (GST_opq_openfds, occ->lop, 2);
1263 GNUNET_TESTBED_operation_begin_wait_ (occ->lop);
1264 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1269 * Function to cleanup RequestOverlayConnectContext and any associated tasks
1272 * @param rocc the RequestOverlayConnectContext
1275 cleanup_rocc (struct RequestOverlayConnectContext *rocc)
1277 LOG_DEBUG ("0x%llx: Cleaning up rocc\n", rocc->op_id);
1278 if (GNUNET_SCHEDULER_NO_TASK != rocc->attempt_connect_task_id)
1279 GNUNET_SCHEDULER_cancel (rocc->attempt_connect_task_id);
1280 if (GNUNET_SCHEDULER_NO_TASK != rocc->timeout_rocc_task_id)
1281 GNUNET_SCHEDULER_cancel (rocc->timeout_rocc_task_id);
1282 if (NULL != rocc->ohh)
1283 GNUNET_TRANSPORT_offer_hello_cancel (rocc->ohh);
1284 if (NULL != rocc->tcc.tch)
1285 GNUNET_TRANSPORT_try_connect_cancel (rocc->tcc.tch);
1286 if (GNUNET_SCHEDULER_NO_TASK != rocc->tcc.task)
1287 GNUNET_SCHEDULER_cancel (rocc->tcc.task);
1288 GNUNET_TRANSPORT_disconnect (rocc->tcc.th);
1289 rocc->peer->reference_cnt--;
1290 if ((GNUNET_YES == rocc->peer->destroy_flag) &&
1291 (0 == rocc->peer->reference_cnt))
1292 GST_destroy_peer (rocc->peer);
1293 GNUNET_free_non_null (rocc->hello);
1294 GNUNET_CONTAINER_DLL_remove (roccq_head, roccq_tail, rocc);
1300 * Task to timeout rocc and cleanit up
1302 * @param cls the RequestOverlayConnectContext
1303 * @param tc the TaskContext from scheduler
1306 timeout_rocc_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1308 struct RequestOverlayConnectContext *rocc = cls;
1310 GNUNET_assert (rocc->timeout_rocc_task_id != GNUNET_SCHEDULER_NO_TASK);
1311 rocc->timeout_rocc_task_id = GNUNET_SCHEDULER_NO_TASK;
1312 LOG_DEBUG ("0x%llx: rocc timed out\n", rocc->op_id);
1313 cleanup_rocc (rocc);
1318 * Function called to notify transport users that another
1319 * peer connected to us.
1321 * @param cls closure
1322 * @param new_peer the peer that connected
1323 * @param ats performance data
1324 * @param ats_count number of entries in ats (excluding 0-termination)
1327 transport_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer,
1328 const struct GNUNET_ATS_Information *ats,
1331 struct RequestOverlayConnectContext *rocc = cls;
1333 LOG_DEBUG ("0x%llx: Request Overlay connect notify\n", rocc->op_id);
1334 if (0 != memcmp (new_peer, &rocc->a_id, sizeof (struct GNUNET_PeerIdentity)))
1336 LOG_DEBUG ("0x%llx: Peer %4s connected\n", rocc->op_id,
1337 GNUNET_i2s (&rocc->a_id));
1338 cleanup_rocc (rocc);
1343 * Task to offer the HELLO message to the peer and ask it to connect to the peer
1344 * whose identity is in RequestOverlayConnectContext
1346 * @param cls the RequestOverlayConnectContext
1347 * @param tc the TaskContext from scheduler
1350 attempt_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
1354 * Task that is run when hello has been sent
1356 * @param cls the overlay connect context
1357 * @param tc the scheduler task context; if tc->reason =
1358 * GNUNET_SCHEDULER_REASON_TIMEOUT then sending HELLO failed; if
1359 * GNUNET_SCHEDULER_REASON_READ_READY is succeeded
1362 rocc_hello_sent_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1364 struct RequestOverlayConnectContext *rocc = cls;
1367 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == rocc->attempt_connect_task_id);
1368 LOG_DEBUG ("0x%llx: HELLO of peer %4s sent to local peer with id: %u\n",
1369 rocc->op_id, GNUNET_i2s (&rocc->a_id), rocc->peer->id);
1370 if (GNUNET_SCHEDULER_REASON_TIMEOUT == tc->reason)
1373 rocc->attempt_connect_task_id =
1374 GNUNET_SCHEDULER_add_now (&attempt_connect_task, rocc);
1377 if (GNUNET_SCHEDULER_REASON_READ_READY != tc->reason)
1379 rocc->tcc.task = GNUNET_SCHEDULER_add_now (&try_connect_task, &rocc->tcc);
1384 * Task to offer the HELLO message to the peer and ask it to connect to the peer
1385 * whose identity is in RequestOverlayConnectContext
1387 * @param cls the RequestOverlayConnectContext
1388 * @param tc the TaskContext from scheduler
1391 attempt_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1393 struct RequestOverlayConnectContext *rocc = cls;
1395 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != rocc->attempt_connect_task_id);
1396 rocc->attempt_connect_task_id = GNUNET_SCHEDULER_NO_TASK;
1397 LOG_DEBUG ("0x%llx: Offering HELLO of peer %4s to local peer with id: %u\n",
1398 rocc->op_id, GNUNET_i2s (&rocc->a_id), rocc->peer->id);
1400 GNUNET_TRANSPORT_offer_hello (rocc->tcc.th, rocc->hello,
1401 rocc_hello_sent_cb, rocc);
1402 if (NULL == rocc->ohh)
1403 rocc->attempt_connect_task_id =
1404 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
1405 (GNUNET_TIME_UNIT_MILLISECONDS,
1407 GNUNET_CRYPTO_random_u32
1408 (GNUNET_CRYPTO_QUALITY_WEAK, 500)),
1409 &attempt_connect_task, rocc);
1414 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_REQUESTCONNECT messages
1417 * @param client identification of the client
1418 * @param message the actual message
1421 GST_handle_overlay_request_connect (void *cls,
1422 struct GNUNET_SERVER_Client *client,
1423 const struct GNUNET_MessageHeader *message)
1425 const struct GNUNET_TESTBED_RequestConnectMessage *msg;
1426 struct RequestOverlayConnectContext *rocc;
1432 msize = ntohs (message->size);
1433 if (sizeof (struct GNUNET_TESTBED_RequestConnectMessage) >= msize)
1436 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1439 msg = (const struct GNUNET_TESTBED_RequestConnectMessage *) message;
1440 if ((NULL == msg->hello) ||
1441 (GNUNET_MESSAGE_TYPE_HELLO != ntohs (msg->hello->type)))
1444 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1447 hsize = ntohs (msg->hello->size);
1448 if ((sizeof (struct GNUNET_TESTBED_RequestConnectMessage) + hsize) != msize)
1451 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1454 peer_id = ntohl (msg->peer);
1455 if ((peer_id >= GST_peer_list_size) ||
1456 (NULL == (peer = GST_peer_list[peer_id])))
1458 GNUNET_break_op (0);
1459 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1462 if (GNUNET_YES == peer->is_remote)
1464 struct GNUNET_MessageHeader *msg2;
1466 msg2 = GNUNET_copy_message (message);
1467 GNUNET_TESTBED_queue_message_ (peer->details.remote.slave->controller,
1469 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1472 rocc = GNUNET_malloc (sizeof (struct RequestOverlayConnectContext));
1473 rocc->op_id = GNUNET_ntohll (msg->operation_id);
1474 GNUNET_CONTAINER_DLL_insert_tail (roccq_head, roccq_tail, rocc);
1475 memcpy (&rocc->a_id, &msg->peer_identity,
1476 sizeof (struct GNUNET_PeerIdentity));
1477 LOG_DEBUG ("Received request for overlay connection with op_id: 0x%llx "
1478 "from local peer %u to peer %4s with hello size: %u\n",
1479 rocc->op_id, peer_id, GNUNET_i2s (&rocc->a_id), hsize);
1481 rocc->peer->reference_cnt++;
1482 rocc->tcc.op_id = rocc->op_id;
1484 GNUNET_TRANSPORT_connect (rocc->peer->details.local.cfg, NULL, rocc, NULL,
1485 &transport_connect_notify, NULL);
1486 if (NULL == rocc->tcc.th)
1490 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1493 rocc->tcc.pid = &rocc->a_id;
1494 rocc->hello = GNUNET_malloc (hsize);
1495 memcpy (rocc->hello, msg->hello, hsize);
1496 rocc->attempt_connect_task_id =
1497 GNUNET_SCHEDULER_add_now (&attempt_connect_task, rocc);
1498 rocc->timeout_rocc_task_id =
1499 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_rocc_task, rocc);
1500 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1505 * Clears all pending overlay connect contexts in queue
1510 struct OverlayConnectContext *occ;
1512 while (NULL != (occ = occq_head))
1518 * Clears all pending remote overlay connect contexts in queue
1523 struct RequestOverlayConnectContext *rocc;
1525 while (NULL != (rocc = roccq_head))
1526 cleanup_rocc (rocc);