aboutsummaryrefslogtreecommitdiff
path: root/src/testbed/gnunet-service-testbed_oc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testbed/gnunet-service-testbed_oc.c')
-rw-r--r--src/testbed/gnunet-service-testbed_oc.c1997
1 files changed, 0 insertions, 1997 deletions
diff --git a/src/testbed/gnunet-service-testbed_oc.c b/src/testbed/gnunet-service-testbed_oc.c
deleted file mode 100644
index 54a566e89..000000000
--- a/src/testbed/gnunet-service-testbed_oc.c
+++ /dev/null
@@ -1,1997 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2008--2016 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testbed/gnunet-service-testbed_oc.c
23 * @brief code for handling overlay connect operations
24 * @author Sree Harsha Totakura
25 */
26
27#include "platform.h"
28#include "gnunet-service-testbed.h"
29#include "gnunet-service-testbed_connectionpool.h"
30#include "gnunet_transport_hello_service.h"
31
32/**
33 * Redefine LOG with a changed log component string
34 */
35#ifdef LOG
36#undef LOG
37#endif
38#define LOG(kind, ...) \
39 GNUNET_log_from (kind, "testbed-OC", __VA_ARGS__)
40
41
42/**
43 * Context information for requesting ATS to connect to a peer
44 */
45struct ConnectivitySuggestContext
46{
47 /**
48 * The transport handle obtained from cache. Do NOT close/disconnect.
49 */
50 struct GNUNET_TRANSPORT_CoreHandle *th_;
51
52 /**
53 * Configuration of the peer from cache. Do not free!
54 */
55 const struct GNUNET_CONFIGURATION_Handle *cfg;
56
57 /**
58 * The GetCacheHandle for the peer2's transport handle
59 * (used to offer the HELLO to the peer).
60 */
61 struct GST_ConnectionPool_GetHandle *cgh_p2_th;
62
63 /**
64 * The GetCacheHandle for the peer2's ATS handle.
65 */
66 struct GST_ConnectionPool_GetHandle *cgh_p2_ats;
67
68 /**
69 * The ATS handle for the connectivity suggestion.
70 */
71 struct GNUNET_ATS_ConnectivitySuggestHandle *csh;
72};
73
74
75/**
76 * Types for context information we create for overlay connect requests
77 */
78enum OverlayConnectContextType
79{
80 /**
81 * This type is used if the overlay connection is local i.e. the connection
82 * has to be made between local peers
83 */
84 OCC_TYPE_LOCAL,
85
86 /**
87 * Type to be used when the first peer is local and the other peer is on a slave
88 * controller started by us
89 */
90 OCC_TYPE_REMOTE_SLAVE,
91
92 /**
93 * Type to be used when the first peer is local and the other peer is on a
94 * controller which is not started by us.
95 */
96 OCC_TYPE_REMOTE_LATERAL
97};
98
99
100/**
101 * Context data for operations on second peer in local overlay connection
102 * contexts
103 */
104struct LocalPeer2Context
105{
106 /**
107 * The handle for offering the HELLO of the first peer to the second
108 * peer.
109 */
110 struct GNUNET_TRANSPORT_OfferHelloHandle *ohh;
111
112 /**
113 * The transport ConnectivitySuggestContext
114 */
115 struct ConnectivitySuggestContext tcc;
116};
117
118
119/**
120 * Context data for operations on second peer in remote overlay connection
121 * contexts
122 */
123struct RemotePeer2Context
124{
125 /**
126 * Controller of peer 2; If #OCC_TYPE_REMOTE_LATERAL is the type of overlay
127 * connection then this can be NULL until the connection to the controller is
128 * established
129 */
130 struct GNUNET_TESTBED_Controller *p2c;
131
132 /**
133 * Operation context for the suboperation we start to get the identity of the
134 * second peer
135 */
136 struct OperationContext *opc;
137
138 /**
139 * Notification handle acquire to connect to a remote controller. Only used
140 * if the type of overlay connection is #OCC_TYPE_REMOTE_LATERAL.
141 */
142 struct NeighbourConnectNotification *ncn;
143
144 /**
145 * The neighbour handle. Only used if the type of overlay connection is
146 * #OCC_TYPE_REMOTE_LATERAL.
147 */
148 struct Neighbour *p2n;
149};
150
151/**
152 * Context information for connecting 2 peers in overlay.
153 */
154struct OverlayConnectContext
155{
156 /**
157 * The next pointer for maintaining a DLL of all OverlayConnectContexts
158 */
159 struct OverlayConnectContext *next;
160
161 /**
162 * The prev pointer for maintaining a DLL of all OverlayConnectContexts
163 */
164 struct OverlayConnectContext *prev;
165
166 /**
167 * The client which has requested for overlay connection. This is used to send
168 * either a success of failure message
169 */
170 struct GNUNET_SERVICE_Client *client;
171
172 /**
173 * the first peer which is to expect an overlay connection from the second peer.
174 */
175 struct Peer *peer;
176
177 /**
178 * Transport handle of the first peer obtained from cache to get its HELLO. Do
179 * NOT close/disconnect.
180 */
181 struct GNUNET_TRANSPORT_CoreHandle *p1th_;
182
183 /**
184 * The #GST_ConnectionPool_GetHandle for the peer1's transport handle
185 */
186 struct GST_ConnectionPool_GetHandle *cgh_p1th;
187
188 /**
189 * The #GST_ConnectionPool_GetHandle for registering callback to notify CORE
190 * level peer connects and to get our identity.
191 */
192 struct GST_ConnectionPool_GetHandle *cgh_ch;
193
194 /**
195 * HELLO of the first peer. This should be sent to the second peer.
196 */
197 struct GNUNET_MessageHeader *hello;
198
199 /**
200 * Get GetHelloHandle to acquire a HELLO of the first peer
201 */
202 struct GNUNET_TRANSPORT_HelloGetHandle *ghh;
203
204 /**
205 * The error message we send if this overlay connect operation has timed out
206 */
207 char *emsg;
208
209 /**
210 * Context information for operations on the second peer
211 */
212 union
213 {
214 /**
215 * Context information to be used if the second peer is local
216 */
217 struct LocalPeer2Context local;
218
219 /**
220 * Context information to be used if the second peer is remote
221 */
222 struct RemotePeer2Context remote;
223 } p2ctx;
224
225 /**
226 * The peer identity of the first peer
227 */
228 struct GNUNET_PeerIdentity peer_identity;
229
230 /**
231 * The peer identity of the other peer
232 */
233 struct GNUNET_PeerIdentity other_peer_identity;
234
235 /**
236 * The id of the operation responsible for creating this context
237 */
238 uint64_t op_id;
239
240 /**
241 * The id of the task for sending HELLO of peer 2 to peer 1 and ask peer 1 to
242 * connect to peer 2
243 */
244 struct GNUNET_SCHEDULER_Task *send_hello_task;
245
246 /**
247 * The id of the overlay connect timeout task
248 */
249 struct GNUNET_SCHEDULER_Task *timeout_task;
250
251 /**
252 * The id of the cleanup task
253 */
254 struct GNUNET_SCHEDULER_Task *cleanup_task;
255
256 /**
257 * The type of this context information
258 */
259 enum OverlayConnectContextType type;
260
261 /**
262 * The id of the second peer which has to connect to the first peer
263 */
264 uint32_t other_peer_id;
265};
266
267
268/**
269 * Context information for remote overlay connect operations. Remote overlay
270 * connections are used when peers A and B reside on different hosts. In these
271 * operations the host controller for peer B is asked by the host controller of
272 * peer A to make peer B connect to peer A by sending the controller of peer B
273 * the HELLO of peer A.
274 */
275struct RemoteOverlayConnectCtx
276{
277 /**
278 * the next pointer for DLL
279 */
280 struct RemoteOverlayConnectCtx *next;
281
282 /**
283 * the prev pointer for DLL
284 */
285 struct RemoteOverlayConnectCtx *prev;
286
287 /**
288 * The peer handle of peer B
289 */
290 struct Peer *peer;
291
292 /**
293 * Peer A's HELLO
294 */
295 struct GNUNET_MessageHeader *hello;
296
297 /**
298 * The handle for offering HELLO
299 */
300 struct GNUNET_TRANSPORT_OfferHelloHandle *ohh;
301
302 /**
303 * The transport try connect context
304 */
305 struct ConnectivitySuggestContext tcc;
306
307 /**
308 * The peer identity of peer A
309 */
310 struct GNUNET_PeerIdentity a_id;
311
312 /**
313 * Task for offering HELLO of A to B and doing try_connect
314 */
315 struct GNUNET_SCHEDULER_Task *attempt_connect_task_id;
316
317 /**
318 * Task to timeout RequestOverlayConnect
319 */
320 struct GNUNET_SCHEDULER_Task *timeout_rocc_task_id;
321
322 /**
323 * The id of the operation responsible for creating this context
324 */
325 uint64_t op_id;
326};
327
328
329/**
330 * DLL head for OverlayConnectContext DLL - to be used to clean up during shutdown
331 */
332static struct OverlayConnectContext *occq_head;
333
334/**
335 * DLL tail for OverlayConnectContext DLL
336 */
337static struct OverlayConnectContext *occq_tail;
338
339/**
340 * DLL head for RequectOverlayConnectContext DLL - to be used to clean up during
341 * shutdown
342 */
343static struct RemoteOverlayConnectCtx *roccq_head;
344
345/**
346 * DLL tail for RequectOverlayConnectContext DLL
347 */
348static struct RemoteOverlayConnectCtx *roccq_tail;
349
350
351/**
352 * Cleans up ForwardedOverlayConnectContext
353 *
354 * @param focc the ForwardedOverlayConnectContext to cleanup
355 */
356void
357GST_cleanup_focc (struct ForwardedOverlayConnectContext *focc)
358{
359 struct RegisteredHostContext *rhc = focc->rhc;
360
361 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head,
362 rhc->focc_dll_tail,
363 focc);
364 GNUNET_free (focc->orig_msg);
365 GNUNET_free (focc);
366}
367
368
369/**
370 * Timeout task for cancelling a forwarded overlay connect connect
371 *
372 * @param cls the `struct ForwardedOperationContext`
373 */
374static void
375forwarded_overlay_connect_timeout (void *cls)
376{
377 struct ForwardedOperationContext *fopc = cls;
378 struct RegisteredHostContext *rhc;
379 struct ForwardedOverlayConnectContext *focc;
380
381 fopc->timeout_task = NULL;
382 rhc = fopc->cls;
383 focc = rhc->focc_dll_head;
384 LOG_DEBUG ("Overlay linking between peers %u and %u failed\n",
385 focc->peer1,
386 focc->peer2);
387 GST_cleanup_focc (focc);
388 GST_forwarded_operation_timeout (fopc);
389 if (NULL != rhc->focc_dll_head)
390 GST_process_next_focc (rhc);
391}
392
393
394/**
395 * Callback to be called when forwarded overlay connection operation has a reply
396 * from the sub-controller successful. We have to relay the reply msg back to
397 * the client
398 *
399 * @param cls ForwardedOperationContext
400 * @param msg the peer create success message
401 */
402static void
403forwarded_overlay_connect_listener (void *cls,
404 const struct GNUNET_MessageHeader *msg)
405{
406 struct ForwardedOperationContext *fopc = cls;
407 struct RegisteredHostContext *rhc;
408 struct ForwardedOverlayConnectContext *focc;
409
410 rhc = fopc->cls;
411 GST_forwarded_operation_reply_relay (cls, msg);
412 focc = rhc->focc_dll_head;
413 GST_cleanup_focc (focc);
414 if (NULL != rhc->focc_dll_head)
415 GST_process_next_focc (rhc);
416}
417
418
419/**
420 * Processes a forwarded overlay connect context in the queue of the given RegisteredHostContext
421 *
422 * @param rhc the RegisteredHostContext
423 */
424void
425GST_process_next_focc (struct RegisteredHostContext *rhc)
426{
427 struct ForwardedOperationContext *fopc;
428 struct ForwardedOverlayConnectContext *focc;
429 struct Peer *peer;
430 struct Slave *slave;
431
432 focc = rhc->focc_dll_head;
433 GNUNET_assert (NULL != focc);
434 GNUNET_assert (RHC_DONE == rhc->state);
435 GNUNET_assert (VALID_PEER_ID (focc->peer1));
436 peer = GST_peer_list[focc->peer1];
437 GNUNET_assert (GNUNET_YES == peer->is_remote);
438 GNUNET_assert (NULL != (slave = peer->details.remote.slave));
439 fopc = GNUNET_new (struct ForwardedOperationContext);
440 fopc->client = focc->client;
441 fopc->operation_id = focc->operation_id;
442 fopc->cls = rhc;
443 fopc->type = OP_OVERLAY_CONNECT;
444 fopc->opc =
445 GNUNET_TESTBED_forward_operation_msg_ (slave->controller,
446 focc->operation_id,
447 focc->orig_msg,
448 &forwarded_overlay_connect_listener,
449 fopc);
450 GNUNET_free (focc->orig_msg);
451 focc->orig_msg = NULL;
452 fopc->timeout_task = GNUNET_SCHEDULER_add_delayed (GST_timeout,
453 &
454 forwarded_overlay_connect_timeout,
455 fopc);
456 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
457 fopcq_tail,
458 fopc);
459}
460
461
462/**
463 * Cleans up any used handles in local peer2 context
464 *
465 * @param lp2c the local peer2 context information
466 */
467static void
468cleanup_occ_lp2c (struct LocalPeer2Context *lp2c)
469{
470 if (NULL != lp2c->ohh)
471 {
472 GNUNET_TRANSPORT_offer_hello_cancel (lp2c->ohh);
473 lp2c->ohh = NULL;
474 }
475 if (NULL != lp2c->tcc.cgh_p2_th)
476 {
477 GST_connection_pool_get_handle_done (lp2c->tcc.cgh_p2_th);
478 lp2c->tcc.cgh_p2_th = NULL;
479 }
480 if (NULL != lp2c->tcc.cgh_p2_ats)
481 {
482 GST_connection_pool_get_handle_done (lp2c->tcc.cgh_p2_ats);
483 lp2c->tcc.cgh_p2_ats = NULL;
484 }
485 if (NULL != lp2c->tcc.csh)
486 {
487 GNUNET_ATS_connectivity_suggest_cancel (lp2c->tcc.csh);
488 lp2c->tcc.csh = NULL;
489 }
490}
491
492
493/**
494 * Cleans up any used handles in remote peer2 context. Relinquishes the
495 * remote controller connection if it has been established on-demand.
496 *
497 * @param rp2c the remote peer2 context information
498 */
499static void
500cleanup_occ_rp2c (struct RemotePeer2Context *rp2c)
501{
502 if (NULL != rp2c->opc)
503 {
504 GNUNET_TESTBED_forward_operation_msg_cancel_ (rp2c->opc);
505 rp2c->opc = NULL;
506 }
507 if (NULL != rp2c->ncn)
508 {
509 GST_neighbour_get_connection_cancel (rp2c->ncn);
510 rp2c->ncn = NULL;
511 }
512 if ((NULL != rp2c->p2c) && (NULL != rp2c->p2n))
513 {
514 GST_neighbour_release_connection (rp2c->p2n);
515 rp2c->p2n = NULL;
516 }
517}
518
519
520/**
521 * Condition for checking if given peer is ready to be destroyed
522 *
523 * @param peer the peer to check
524 */
525#define PEER_EXPIRED(peer) \
526 ((GNUNET_YES == peer->destroy_flag) && (0 == peer->reference_cnt))
527
528/**
529 * Cleanup overlay connect context structure
530 *
531 * @param occ the overlay connect context
532 */
533static void
534cleanup_occ (struct OverlayConnectContext *occ)
535{
536 struct Peer *peer2;
537
538 LOG_DEBUG ("0x%llx: Cleaning up occ\n",
539 (unsigned long long) occ->op_id);
540 GNUNET_free (occ->emsg);
541 GNUNET_free (occ->hello);
542 if (NULL != occ->send_hello_task)
543 GNUNET_SCHEDULER_cancel (occ->send_hello_task);
544 if (NULL != occ->cleanup_task)
545 GNUNET_SCHEDULER_cancel (occ->cleanup_task);
546 if (NULL != occ->timeout_task)
547 GNUNET_SCHEDULER_cancel (occ->timeout_task);
548 if (NULL != occ->cgh_ch)
549 GST_connection_pool_get_handle_done (occ->cgh_ch);
550 if (NULL != occ->ghh)
551 GNUNET_TRANSPORT_hello_get_cancel (occ->ghh);
552 GST_connection_pool_get_handle_done (occ->cgh_p1th);
553 GNUNET_assert (NULL != GST_peer_list);
554 GNUNET_assert (occ->peer->reference_cnt > 0);
555 occ->peer->reference_cnt--;
556 if (PEER_EXPIRED (occ->peer))
557 GST_destroy_peer (occ->peer);
558 switch (occ->type)
559 {
560 case OCC_TYPE_LOCAL:
561 peer2 = GST_peer_list[occ->other_peer_id];
562 GNUNET_assert (peer2->reference_cnt > 0);
563 peer2->reference_cnt--;
564 if (PEER_EXPIRED (peer2))
565 GST_destroy_peer (peer2);
566 cleanup_occ_lp2c (&occ->p2ctx.local);
567 break;
568
569 case OCC_TYPE_REMOTE_SLAVE:
570 case OCC_TYPE_REMOTE_LATERAL:
571 cleanup_occ_rp2c (&occ->p2ctx.remote);
572 break;
573 }
574 GNUNET_CONTAINER_DLL_remove (occq_head,
575 occq_tail,
576 occ);
577 GNUNET_free (occ);
578}
579
580
581/**
582 * Task for cleaning up overlay connect context structure
583 *
584 * @param cls the overlay connect context
585 */
586static void
587do_cleanup_occ (void *cls)
588{
589 struct OverlayConnectContext *occ = cls;
590
591 occ->cleanup_task = NULL;
592 cleanup_occ (occ);
593}
594
595
596/**
597 * Task which will be run when overlay connect request has been timed out
598 *
599 * @param cls the OverlayConnectContext
600 */
601static void
602timeout_overlay_connect (void *cls)
603{
604 struct OverlayConnectContext *occ = cls;
605
606 GNUNET_assert (NULL != occ->timeout_task);
607 occ->timeout_task = NULL;
608 /* LOG (GNUNET_ERROR_TYPE_WARNING, */
609 /* "0x%llx: Timeout while connecting peers %u and %u: %s\n", occ->op_id, */
610 /* occ->peer->id, occ->other_peer_id, occ->emsg); */
611 GST_send_operation_fail_msg (occ->client,
612 occ->op_id,
613 occ->emsg);
614 cleanup_occ (occ);
615}
616
617
618/**
619 * Notify OC subsystem that @a client disconnected.
620 *
621 * @param client the client that disconnected
622 */
623void
624GST_notify_client_disconnect_oc (struct GNUNET_SERVICE_Client *client)
625{
626 struct ForwardedOperationContext *fopc;
627 struct ForwardedOperationContext *fopcn;
628 struct OverlayConnectContext *occ;
629 struct OverlayConnectContext *occn;
630
631 for (fopc = fopcq_head; NULL != fopc; fopc = fopcn)
632 {
633 fopcn = fopc->next;
634 if (fopc->client == client)
635 {
636 GNUNET_SCHEDULER_cancel (fopc->timeout_task);
637 GST_forwarded_operation_timeout (fopc);
638 }
639 }
640 for (occ = occq_head; NULL != occ; occ = occn)
641 {
642 occn = occ->next;
643 if (occ->client == client)
644 cleanup_occ (occ);
645 }
646 // FIXME: implement clean up for client_keep replacements!
647}
648
649
650/**
651 * FIXME.
652 */
653static void
654send_overlay_connect_success_msg (struct OverlayConnectContext *occ)
655{
656 struct GNUNET_MQ_Envelope *env;
657 struct GNUNET_TESTBED_ConnectionEventMessage *msg;
658
659 LOG_DEBUG ("0x%llx: Peers connected - Sending overlay connect success\n",
660 (unsigned long long) occ->op_id);
661 env = GNUNET_MQ_msg (msg,
662 GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONNECT_EVENT);
663 msg->event_type = htonl (GNUNET_TESTBED_ET_CONNECT);
664 msg->peer1 = htonl (occ->peer->id);
665 msg->peer2 = htonl (occ->other_peer_id);
666 msg->operation_id = GNUNET_htonll (occ->op_id);
667 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (occ->client),
668 env);
669}
670
671
672/**
673 * Function called to notify transport users that another
674 * peer connected to us.
675 *
676 * @param cls closure
677 * @param new_peer the peer that connected
678 */
679static void
680overlay_connect_notify (void *cls,
681 const struct GNUNET_PeerIdentity *new_peer)
682{
683 struct OverlayConnectContext *occ = cls;
684 char *new_peer_str;
685 char *other_peer_str;
686
687 LOG_DEBUG ("Overlay connect notify\n");
688 if (0 ==
689 GNUNET_memcmp (new_peer,
690 &occ->peer_identity))
691 return;
692 new_peer_str = GNUNET_strdup (GNUNET_i2s (new_peer));
693 other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity));
694 if (0 !=
695 GNUNET_memcmp (new_peer,
696 &occ->other_peer_identity))
697 {
698 LOG_DEBUG ("Unexpected peer %s connected when expecting peer %s\n",
699 new_peer_str,
700 other_peer_str);
701 GNUNET_free (new_peer_str);
702 GNUNET_free (other_peer_str);
703 return;
704 }
705 GNUNET_free (new_peer_str);
706 LOG_DEBUG ("0x%llx: Peer %s connected to peer %s\n",
707 (unsigned long long) occ->op_id,
708 other_peer_str,
709 GNUNET_i2s (&occ->peer_identity));
710 GNUNET_free (other_peer_str);
711 if (NULL != occ->send_hello_task)
712 {
713 GNUNET_SCHEDULER_cancel (occ->send_hello_task);
714 occ->send_hello_task = NULL;
715 }
716 GNUNET_assert (NULL != occ->timeout_task);
717 GNUNET_SCHEDULER_cancel (occ->timeout_task);
718 occ->timeout_task = NULL;
719 switch (occ->type)
720 {
721 case OCC_TYPE_LOCAL:
722 cleanup_occ_lp2c (&occ->p2ctx.local);
723 break;
724
725 case OCC_TYPE_REMOTE_SLAVE:
726 case OCC_TYPE_REMOTE_LATERAL:
727 cleanup_occ_rp2c (&occ->p2ctx.remote);
728 break;
729 }
730 GNUNET_free (occ->emsg);
731 occ->emsg = NULL;
732 send_overlay_connect_success_msg (occ);
733 occ->cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup_occ,
734 occ);
735}
736
737
738/**
739 * Callback from cache with needed ATS handle set
740 *
741 * @param cls a `struct OverlayConnectCtx *`
742 * @param ch the handle to CORE. Can be NULL if it is not requested
743 * @param th the handle to TRANSPORT. Can be NULL if it is not requested
744 * @param ac the handle to ATS. Can be NULL if it is not requested
745 * @param my_identity the identity of our peer
746 * @param cfg configuration of the peer
747 */
748static void
749occ_cache_get_handle_ats_occ_cb (void *cls,
750 struct GNUNET_CORE_Handle *ch,
751 struct GNUNET_TRANSPORT_CoreHandle *th,
752 struct GNUNET_ATS_ConnectivityHandle *ac,
753 const struct GNUNET_PeerIdentity *my_identity,
754 const struct GNUNET_CONFIGURATION_Handle *cfg)
755{
756 struct OverlayConnectContext *occ = cls;
757 struct LocalPeer2Context *lp2c;
758
759 GNUNET_assert (OCC_TYPE_LOCAL == occ->type);
760 GNUNET_assert (NULL != occ->timeout_task);
761 GNUNET_free (occ->emsg);
762 if (NULL == ac)
763 {
764 GNUNET_asprintf (&occ->emsg,
765 "0x%llx: Failed to connect to ATS of peer with id: %u",
766 (unsigned long long) occ->op_id,
767 occ->peer->id);
768 GNUNET_SCHEDULER_cancel (occ->timeout_task);
769 occ->timeout_task =
770 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect,
771 occ);
772 return;
773 }
774 occ->emsg = NULL;
775
776 GNUNET_asprintf (&occ->emsg,
777 "0x%llx: Timeout during GNUNET_ATS_connectivity_suggest() at peer %s",
778 (unsigned long long) occ->op_id,
779 GNUNET_i2s (&occ->other_peer_identity));
780
781 lp2c = &occ->p2ctx.local;
782 lp2c->tcc.csh =
783 GNUNET_ATS_connectivity_suggest (ac,
784 &occ->peer_identity,
785 1);
786}
787
788
789/**
790 * Callback from cache with needed ATS handle set
791 *
792 * @param cls a `struct RemoteOverlayConnectCtx *`
793 * @param ch the handle to CORE. Can be NULL if it is not requested
794 * @param th the handle to TRANSPORT. Can be NULL if it is not requested
795 * @param ac the handle to ATS. Can be NULL if it is not requested
796 * @param my_identity the identity of our peer
797 */
798static void
799occ_cache_get_handle_ats_rocc_cb (void *cls,
800 struct GNUNET_CORE_Handle *ch,
801 struct GNUNET_TRANSPORT_CoreHandle *th,
802 struct GNUNET_ATS_ConnectivityHandle *ac,
803 const struct GNUNET_PeerIdentity *my_identity,
804 const struct GNUNET_CONFIGURATION_Handle *cfg)
805{
806 struct RemoteOverlayConnectCtx *rocc = cls;
807
808 rocc->tcc.csh =
809 GNUNET_ATS_connectivity_suggest (ac,
810 &rocc->a_id,
811 1);
812}
813
814
815/**
816 * Task to offer HELLO of peer 1 to peer 2 and try to make peer 2 to connect to
817 * peer 1.
818 *
819 * @param cls the OverlayConnectContext
820 */
821static void
822send_hello (void *cls);
823
824
825/**
826 * Task that is run when hello has been sent If tc->reason =
827 * #GNUNET_SCHEDULER_REASON_TIMEOUT then sending HELLO failed; if
828 * #GNUNET_SCHEDULER_REASON_READ_READY is succeeded
829 *
830 * @param cls the overlay connect context
831 */
832static void
833occ_hello_sent_cb (void *cls)
834{
835 struct OverlayConnectContext *occ = cls;
836 struct LocalPeer2Context *lp2c;
837 struct Peer *peer2;
838
839 GNUNET_assert (OCC_TYPE_LOCAL == occ->type);
840 GNUNET_assert (NULL != occ->timeout_task);
841 lp2c = &occ->p2ctx.local;
842 lp2c->ohh = NULL;
843
844 GNUNET_assert (NULL == occ->send_hello_task);
845 GNUNET_free (occ->emsg);
846
847 GNUNET_asprintf (&occ->emsg,
848 "0x%llx: Timeout while acquiring ATS of %s from cache",
849 (unsigned long long) occ->op_id,
850 GNUNET_i2s (&occ->other_peer_identity));
851 GNUNET_assert (NULL != (peer2 = GST_peer_list[occ->other_peer_id]));
852 lp2c->tcc.cgh_p2_ats =
853 GST_connection_pool_get_handle (occ->other_peer_id,
854 peer2->details.local.cfg,
855 GST_CONNECTIONPOOL_SERVICE_ATS_CONNECTIVITY,
856 &occ_cache_get_handle_ats_occ_cb,
857 occ, NULL, NULL, NULL);
858}
859
860
861/**
862 * Sends the HELLO of peer1 to peer2's controller through remote overlay connect
863 * request.
864 *
865 * @param occ the overlay connect context. Its type must be either
866 * #OCC_TYPE_REMOTE_SLAVE or #OCC_TYPE_REMOTE_LATERAL
867 */
868static void
869send_hello_thru_rocc (struct OverlayConnectContext *occ)
870{
871 struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg;
872 char *other_peer_str;
873 uint16_t msize;
874 uint16_t hello_size;
875
876 GNUNET_assert (OCC_TYPE_LOCAL != occ->type);
877 GNUNET_assert (NULL != occ->hello);
878 other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity));
879 LOG_DEBUG (
880 "0x%llx: Offering HELLO of %s (size: %u) to %s via Remote Overlay Request\n",
881 (unsigned long long) occ->op_id,
882 GNUNET_i2s (&occ->peer_identity),
883 ntohs (occ->hello->size),
884 other_peer_str);
885 GNUNET_free (other_peer_str);
886 hello_size = ntohs (occ->hello->size);
887 msize = sizeof(struct GNUNET_TESTBED_RemoteOverlayConnectMessage)
888 + hello_size;
889 msg = GNUNET_malloc (msize);
890 msg->header.type =
891 htons (GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT);
892 msg->header.size = htons (msize);
893 msg->peer = htonl (occ->other_peer_id);
894 msg->operation_id = GNUNET_htonll (occ->op_id);
895 msg->peer_identity = occ->peer_identity;
896 GNUNET_memcpy (msg->hello,
897 occ->hello,
898 hello_size);
899 GNUNET_TESTBED_queue_message_ (occ->p2ctx.remote.p2c,
900 &msg->header);
901}
902
903
904/**
905 * Task to offer HELLO of peer 1 to peer 2. If peer2 is local it is offered
906 * using its TRANSPORT connection; if remote the HELLO is sent remotely by using
907 * send_hello_thru_rocc()
908 *
909 * @param cls the OverlayConnectContext
910 */
911static void
912send_hello (void *cls)
913{
914 struct OverlayConnectContext *occ = cls;
915 struct LocalPeer2Context *lp2c;
916 char *other_peer_str;
917
918 occ->send_hello_task = NULL;
919 GNUNET_assert (NULL != occ->timeout_task);
920 GNUNET_assert (NULL != occ->hello);
921 if (OCC_TYPE_LOCAL != occ->type)
922 {
923 send_hello_thru_rocc (occ);
924 return;
925 }
926 lp2c = &occ->p2ctx.local;
927 other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity));
928 LOG_DEBUG ("0x%llx: Offering HELLO of %s to %s\n",
929 (unsigned long long) occ->op_id,
930 GNUNET_i2s (&occ->peer_identity),
931 other_peer_str);
932 GNUNET_free (other_peer_str);
933 lp2c->ohh =
934 GNUNET_TRANSPORT_offer_hello (lp2c->tcc.cfg,
935 occ->hello,
936 &occ_hello_sent_cb,
937 occ);
938 if (NULL == lp2c->ohh)
939 {
940 GNUNET_break (0);
941 occ->send_hello_task =
942 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
943 (GNUNET_TIME_UNIT_MILLISECONDS,
944 100
945 + GNUNET_CRYPTO_random_u32
946 (GNUNET_CRYPTO_QUALITY_WEAK, 500)),
947 &send_hello, occ);
948 }
949}
950
951
952/**
953 * Callback from cache with needed handles set
954 *
955 * @param cls the closure passed to GST_cache_get_handle_transport()
956 * @param ch the handle to CORE. Can be NULL if it is not requested
957 * @param th the handle to TRANSPORT. Can be NULL if it is not requested
958 * @param ac the handle to ATS. Can be NULL if it is not requested
959 * @param ignore_ peer identity which is ignored in this callback
960 * @param cfg configuration of the peer
961 */
962static void
963p2_transport_connect_cache_callback (void *cls,
964 struct GNUNET_CORE_Handle *ch,
965 struct GNUNET_TRANSPORT_CoreHandle *th,
966 struct GNUNET_ATS_ConnectivityHandle *ac,
967 const struct GNUNET_PeerIdentity *ignore_,
968 const struct
969 GNUNET_CONFIGURATION_Handle *cfg)
970{
971 struct OverlayConnectContext *occ = cls;
972
973 GNUNET_assert (OCC_TYPE_LOCAL == occ->type);
974 if (NULL == th)
975 {
976 GNUNET_asprintf (&occ->emsg,
977 "0x%llx: Cannot connect to TRANSPORT of %s",
978 (unsigned long long) occ->op_id,
979 GNUNET_i2s (&occ->other_peer_identity));
980 GNUNET_SCHEDULER_cancel (occ->timeout_task);
981 occ->timeout_task =
982 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
983 return;
984 }
985 occ->p2ctx.local.tcc.th_ = th;
986 occ->p2ctx.local.tcc.cfg = cfg;
987 GNUNET_asprintf (&occ->emsg,
988 "0x%llx: Timeout while offering HELLO to %s",
989 (unsigned long long) occ->op_id,
990 GNUNET_i2s (&occ->other_peer_identity));
991 occ->send_hello_task = GNUNET_SCHEDULER_add_now (&send_hello, occ);
992}
993
994
995/**
996 * Connects to the transport of the other peer if it is a local peer and
997 * schedules the send hello task
998 *
999 * @param occ the overlay connect context
1000 */
1001static void
1002p2_transport_connect (struct OverlayConnectContext *occ)
1003{
1004 struct Peer *peer2;
1005
1006 /* HUH? Why to *obtain* HELLO? Seems we use this to *SEND* the
1007 HELLO! */
1008 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1009 "Connecting to transport of peer %s to obtain HELLO\n",
1010 GNUNET_i2s (&occ->other_peer_identity));
1011 GNUNET_assert (NULL == occ->emsg);
1012 GNUNET_assert (NULL != occ->hello);
1013 GNUNET_assert (NULL == occ->ghh);
1014 GNUNET_assert (NULL == occ->p1th_);
1015 GNUNET_assert (NULL == occ->cgh_p1th);
1016 if (OCC_TYPE_LOCAL == occ->type)
1017 {
1018 GNUNET_assert (NULL != (peer2 = GST_peer_list[occ->other_peer_id]));
1019 occ->p2ctx.local.tcc.cgh_p2_th =
1020 GST_connection_pool_get_handle (occ->other_peer_id,
1021 peer2->details.local.cfg,
1022 GST_CONNECTIONPOOL_SERVICE_TRANSPORT,
1023 &p2_transport_connect_cache_callback,
1024 occ, NULL, NULL, NULL);
1025 return;
1026 }
1027 GNUNET_asprintf (&occ->emsg,
1028 "0x%llx: Timeout while offering HELLO to %s",
1029 (unsigned long long) occ->op_id,
1030 GNUNET_i2s (&occ->other_peer_identity));
1031 occ->send_hello_task = GNUNET_SCHEDULER_add_now (&send_hello, occ);
1032}
1033
1034
1035/**
1036 * Test for checking whether HELLO message is empty
1037 *
1038 * @param cls empty flag to set
1039 * @param address the HELLO
1040 * @param expiration expiration of the HELLO
1041 * @return #GNUNET_OK
1042 */
1043static int
1044test_address (void *cls,
1045 const struct GNUNET_HELLO_Address *address,
1046 struct GNUNET_TIME_Absolute expiration)
1047{
1048 int *empty = cls;
1049
1050 *empty = GNUNET_NO;
1051 return GNUNET_OK;
1052}
1053
1054
1055/**
1056 * Function called whenever there is an update to the HELLO of peers in the
1057 * OverlayConnectClosure. If we have a valid HELLO, we connect to the peer 2's
1058 * transport and offer peer 1's HELLO and ask peer 2 to connect to peer 1
1059 *
1060 * @param cls closure
1061 * @param hello our updated HELLO
1062 */
1063static void
1064hello_update_cb (void *cls,
1065 const struct GNUNET_MessageHeader *hello)
1066{
1067 struct OverlayConnectContext *occ = cls;
1068 int empty;
1069 uint16_t msize;
1070
1071 msize = ntohs (hello->size);
1072 empty = GNUNET_YES;
1073 (void) GNUNET_HELLO_iterate_addresses ((const struct GNUNET_HELLO_Message *)
1074 hello, GNUNET_NO,
1075 &test_address,
1076 &empty);
1077 if (GNUNET_YES == empty)
1078 {
1079 LOG_DEBUG ("0x%llx: HELLO of %s is empty\n",
1080 (unsigned long long) occ->op_id,
1081 GNUNET_i2s (&occ->peer_identity));
1082 return;
1083 }
1084 LOG_DEBUG ("0x%llx: Received HELLO of %s\n",
1085 (unsigned long long) occ->op_id,
1086 GNUNET_i2s (&occ->peer_identity));
1087 occ->hello = GNUNET_malloc (msize);
1088 GST_cache_add_hello (occ->peer->id, hello);
1089 GNUNET_memcpy (occ->hello, hello, msize);
1090 GNUNET_TRANSPORT_hello_get_cancel (occ->ghh);
1091 occ->ghh = NULL;
1092 GST_connection_pool_get_handle_done (occ->cgh_p1th);
1093 occ->cgh_p1th = NULL;
1094 occ->p1th_ = NULL;
1095 GNUNET_free (occ->emsg);
1096 occ->emsg = NULL;
1097 p2_transport_connect (occ);
1098}
1099
1100
1101/**
1102 * Callback from cache with needed handles set
1103 *
1104 * @param cls the closure passed to GST_cache_get_handle_transport()
1105 * @param ch the handle to CORE. Can be NULL if it is not requested
1106 * @param th the handle to TRANSPORT. Can be NULL if it is not requested
1107 * @param ac the handle to ATS. Can be NULL if it is not requested
1108 * @param ignore_ peer identity which is ignored in this callback
1109 */
1110static void
1111p1_transport_connect_cache_callback (void *cls,
1112 struct GNUNET_CORE_Handle *ch,
1113 struct GNUNET_TRANSPORT_CoreHandle *th,
1114 struct GNUNET_ATS_ConnectivityHandle *ac,
1115 const struct GNUNET_PeerIdentity *ignore_,
1116 const struct
1117 GNUNET_CONFIGURATION_Handle *cfg)
1118{
1119 struct OverlayConnectContext *occ = cls;
1120
1121 GNUNET_free (occ->emsg);
1122 occ->emsg = NULL;
1123 if (NULL == th)
1124 {
1125 GNUNET_asprintf (&occ->emsg,
1126 "0x%llx: Cannot connect to TRANSPORT of %s",
1127 (unsigned long long) occ->op_id,
1128 GNUNET_i2s (&occ->peer_identity));
1129 GNUNET_SCHEDULER_cancel (occ->timeout_task);
1130 occ->timeout_task =
1131 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
1132 return;
1133 }
1134 GNUNET_assert (NULL == occ->p1th_);
1135 GNUNET_assert (NULL != occ->cgh_p1th);
1136 occ->p1th_ = th;
1137 GNUNET_asprintf (&occ->emsg,
1138 "0x%llx: Timeout while acquiring HELLO of peer %s",
1139 (unsigned long long) occ->op_id,
1140 GNUNET_i2s (&occ->peer_identity));
1141 occ->ghh = GNUNET_TRANSPORT_hello_get (cfg,
1142 GNUNET_TRANSPORT_AC_ANY,
1143 &hello_update_cb,
1144 occ);
1145}
1146
1147
1148/**
1149 * Callback from cache with needed CORE handle set
1150 *
1151 * @param cls the closure passed to GST_cache_get_handle_transport()
1152 * @param ch the handle to CORE. Can be NULL if it is not requested
1153 * @param th the handle to TRANSPORT. Can be NULL if it is not requested
1154 * @param ac the handle to ATS. Can be NULL if it is not requested
1155 * @param my_identity the identity of our peer
1156 */
1157static void
1158occ_cache_get_handle_core_cb (void *cls,
1159 struct GNUNET_CORE_Handle *ch,
1160 struct GNUNET_TRANSPORT_CoreHandle *th,
1161 struct GNUNET_ATS_ConnectivityHandle *ac,
1162 const struct GNUNET_PeerIdentity *my_identity,
1163 const struct GNUNET_CONFIGURATION_Handle *cfg)
1164{
1165 struct OverlayConnectContext *occ = cls;
1166 const struct GNUNET_MessageHeader *hello;
1167
1168 GNUNET_assert (NULL != occ->timeout_task);
1169 GNUNET_free (occ->emsg);
1170 if ((NULL == ch) || (NULL == my_identity))
1171 {
1172 GNUNET_asprintf (&occ->emsg,
1173 "0x%llx: Failed to connect to CORE of peer with "
1174 "id: %u",
1175 (unsigned long long) occ->op_id,
1176 occ->peer->id);
1177 GNUNET_SCHEDULER_cancel (occ->timeout_task);
1178 occ->timeout_task =
1179 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
1180 return;
1181 }
1182 occ->emsg = NULL;
1183 occ->peer_identity = *my_identity;
1184 if (NULL !=
1185 GNUNET_CORE_get_mq (ch,
1186 &occ->other_peer_identity))
1187 {
1188 LOG_DEBUG ("0x%llx: Target peer %s already connected\n",
1189 (unsigned long long) occ->op_id,
1190 GNUNET_i2s (&occ->other_peer_identity));
1191 LOG_DEBUG ("0x%llx: Target peer %s connected\n",
1192 (unsigned long long) occ->op_id,
1193 GNUNET_i2s (&occ->peer_identity));
1194 GNUNET_SCHEDULER_cancel (occ->timeout_task);
1195 occ->timeout_task = NULL;
1196 send_overlay_connect_success_msg (occ);
1197 occ->cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup_occ, occ);
1198 return;
1199 }
1200 LOG_DEBUG ("0x%llx: Acquiring HELLO of peer %s\n",
1201 (unsigned long long) occ->op_id,
1202 GNUNET_i2s (&occ->peer_identity));
1203 /* Lookup for HELLO in hello cache */
1204 if (NULL != (hello = GST_cache_lookup_hello (occ->peer->id)))
1205 {
1206 LOG_DEBUG ("0x%llx: HELLO of peer %s found in cache\n",
1207 (unsigned long long) occ->op_id,
1208 GNUNET_i2s (&occ->peer_identity));
1209 occ->hello = GNUNET_copy_message (hello);
1210 p2_transport_connect (occ);
1211 return;
1212 }
1213 GNUNET_asprintf (&occ->emsg,
1214 "0x%llx: Timeout while acquiring TRANSPORT of %s from cache",
1215 (unsigned long long) occ->op_id,
1216 GNUNET_i2s (&occ->peer_identity));
1217 occ->cgh_p1th =
1218 GST_connection_pool_get_handle (occ->peer->id,
1219 occ->peer->details.local.cfg,
1220 GST_CONNECTIONPOOL_SERVICE_TRANSPORT,
1221 p1_transport_connect_cache_callback,
1222 occ,
1223 NULL, NULL, NULL);
1224}
1225
1226
1227/**
1228 * Callback to be called when forwarded get peer config operation as part of
1229 * overlay connect is successful. Connection to Peer 1's core is made and is
1230 * checked for new connection from peer 2
1231 *
1232 * @param cls ForwardedOperationContext
1233 * @param msg the peer create success message
1234 */
1235static void
1236overlay_connect_get_config (void *cls,
1237 const struct GNUNET_MessageHeader *msg)
1238{
1239 struct OverlayConnectContext *occ = cls;
1240 struct RemotePeer2Context *rp2c;
1241 const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *cmsg;
1242
1243 GNUNET_assert (OCC_TYPE_LOCAL != occ->type);
1244 rp2c = &occ->p2ctx.remote;
1245 rp2c->opc = NULL;
1246 GNUNET_assert (NULL != occ->timeout_task);
1247 if (GNUNET_MESSAGE_TYPE_TESTBED_PEER_INFORMATION != ntohs (msg->type))
1248 {
1249 GNUNET_SCHEDULER_cancel (occ->timeout_task);
1250 occ->timeout_task =
1251 GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ);
1252 }
1253 cmsg =
1254 (const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *) msg;
1255 occ->other_peer_identity = cmsg->peer_identity;
1256 GNUNET_free (occ->emsg);
1257 GNUNET_asprintf (&occ->emsg,
1258 "0x%llx: Timeout while connecting to CORE of peer with "
1259 "id: %u",
1260 (unsigned long long) occ->op_id,
1261 occ->peer->id);
1262 occ->cgh_ch =
1263 GST_connection_pool_get_handle (occ->peer->id,
1264 occ->peer->details.local.cfg,
1265 GST_CONNECTIONPOOL_SERVICE_CORE,
1266 &occ_cache_get_handle_core_cb,
1267 occ,
1268 &occ->other_peer_identity,
1269 &overlay_connect_notify,
1270 occ);
1271}
1272
1273
1274/**
1275 * Callback which will be called after a host registration succeeded or failed
1276 *
1277 * @param cls the RegisteredHostContext
1278 * @param emsg the error message; NULL if host registration is successful
1279 */
1280static void
1281host_registration_comp (void *cls, const char *emsg)
1282{
1283 struct RegisteredHostContext *rhc = cls;
1284
1285 rhc->state = RHC_DONE;
1286 GST_process_next_focc (rhc);
1287}
1288
1289
1290/**
1291 * Iterator to match a registered host context
1292 *
1293 * @param cls pointer 2 pointer of RegisteredHostContext
1294 * @param key current key code
1295 * @param value value in the hash map
1296 * @return #GNUNET_YES if we should continue to
1297 * iterate,
1298 * #GNUNET_NO if not.
1299 */
1300static int
1301reghost_match_iterator (void *cls,
1302 const struct GNUNET_HashCode *key,
1303 void *value)
1304{
1305 struct RegisteredHostContext **rh = cls;
1306 struct RegisteredHostContext *rh_val = value;
1307
1308 if ((rh_val->host == (*rh)->host) && (rh_val->reg_host == (*rh)->reg_host))
1309 {
1310 GNUNET_free (*rh);
1311 *rh = rh_val;
1312 return GNUNET_NO;
1313 }
1314 return GNUNET_YES;
1315}
1316
1317
1318/**
1319 * Function to generate the hashcode corresponding to a RegisteredHostContext
1320 *
1321 * @param reg_host the host which is being registered in RegisteredHostContext
1322 * @param host the host of the controller which has to connect to the above rhost
1323 * @return the hashcode
1324 */
1325static struct GNUNET_HashCode
1326hash_hosts (struct GNUNET_TESTBED_Host *reg_host,
1327 struct GNUNET_TESTBED_Host *host)
1328{
1329 struct GNUNET_HashCode hash;
1330 uint32_t host_ids[2];
1331
1332 host_ids[0] = GNUNET_TESTBED_host_get_id_ (reg_host);
1333 host_ids[1] = GNUNET_TESTBED_host_get_id_ (host);
1334 GNUNET_CRYPTO_hash (host_ids, sizeof(host_ids), &hash);
1335 return hash;
1336}
1337
1338
1339/**
1340 * Checks if the given host is registered at the given slave.
1341 *
1342 * @param slave the slave where registration has to be checked. The check is
1343 * actually done through a locally maintained hashmap. No
1344 * communication with the slave is involved.
1345 * @param host the host to register
1346 * @return If the given host is not registered already or the registration is
1347 * pending, it returns the registration context. Any overlay connects
1348 * to be forwarded should be queued in the context so that they can be
1349 * executed when the registration is completed. If the given host is
1350 * already registered, NULL is returned.
1351 */
1352static struct RegisteredHostContext *
1353register_host (struct Slave *slave,
1354 struct GNUNET_TESTBED_Host *host)
1355{
1356 struct GNUNET_HashCode hash;
1357 struct RegisteredHostContext *rhc;
1358
1359 rhc = GNUNET_new (struct RegisteredHostContext);
1360 rhc->reg_host = host;
1361 rhc->host = GST_host_list[slave->host_id];
1362 GNUNET_assert (NULL != rhc->reg_host);
1363 GNUNET_assert (NULL != rhc->host);
1364 rhc->state = RHC_INIT;
1365 hash = hash_hosts (rhc->reg_host, rhc->host);
1366 if ((GNUNET_NO ==
1367 GNUNET_CONTAINER_multihashmap_contains (slave->reghost_map,
1368 &hash)) ||
1369 (GNUNET_SYSERR !=
1370 GNUNET_CONTAINER_multihashmap_get_multiple (slave->reghost_map,
1371 &hash,
1372 reghost_match_iterator,
1373 &rhc)))
1374 {
1375 /* create and add a new registered host context */
1376 /* add the focc to its queue */
1377 GNUNET_CONTAINER_multihashmap_put (slave->reghost_map,
1378 &hash,
1379 rhc,
1380 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1381 GST_queue_host_registration (slave,
1382 host_registration_comp,
1383 rhc,
1384 rhc->reg_host);
1385 }
1386 else
1387 {
1388 /* rhc is now set to the existing one from the hash map by
1389 * reghost_match_iterator() */
1390 /* if queue is empty then ignore creating focc and proceed with normal
1391 * forwarding */
1392 if (RHC_DONE == rhc->state)
1393 return NULL;
1394 }
1395 return rhc;
1396}
1397
1398
1399/**
1400 * Forwards the overlay connect request to a slave controller. Before
1401 * forwarding, any hosts which are needed to be known by the slave controller to
1402 * execute the overlay connect request are registered at slave.
1403 *
1404 * @param msg the overlay connect request message to be forwarded
1405 * @param client the client to which the status of the forwarded request has to
1406 * be notified
1407 */
1408static void
1409forward_overlay_connect (const struct GNUNET_TESTBED_OverlayConnectMessage *msg,
1410 struct GNUNET_SERVICE_Client *client)
1411{
1412 struct ForwardedOperationContext *fopc;
1413 struct Route *route_to_peer2_host;
1414 struct Route *route_to_peer1_host;
1415 struct Peer *peer;
1416 struct RegisteredHostContext *rhc;
1417 struct ForwardedOverlayConnectContext *focc;
1418 uint64_t op_id;
1419 uint32_t peer2_host_id;
1420 uint32_t p1;
1421 uint32_t p2;
1422
1423 p1 = ntohl (msg->peer1);
1424 p2 = ntohl (msg->peer2);
1425 op_id = GNUNET_ntohll (msg->operation_id);
1426 peer2_host_id = ntohl (msg->peer2_host_id);
1427 GNUNET_assert (VALID_PEER_ID (p1));
1428 GNUNET_assert (VALID_HOST_ID (peer2_host_id));
1429 peer = GST_peer_list[p1];
1430 GNUNET_assert (GNUNET_YES == peer->is_remote);
1431 LOG_DEBUG ("0x%llx: Forwarding overlay connect\n",
1432 (unsigned long long) op_id);
1433 route_to_peer2_host = GST_find_dest_route (peer2_host_id);
1434 route_to_peer1_host = GST_find_dest_route
1435 (peer->details.remote.remote_host_id);
1436 GNUNET_assert (NULL != route_to_peer1_host);
1437 if ((NULL != route_to_peer2_host) &&
1438 (route_to_peer1_host->dest == route_to_peer2_host->dest))
1439 goto forward;
1440 /* Peer2 is either with us OR peer1 and peer2 can be reached through
1441 different subtrees OR peer2 is on a subtree unknown to us */
1442 if (NULL != (rhc = register_host (peer->details.remote.slave,
1443 GST_host_list[peer2_host_id])))
1444 {
1445 LOG_DEBUG ("Queueing forwarding FOCC for connecting peers %u and %u\n", p1,
1446 p2);
1447 focc = GNUNET_new (struct ForwardedOverlayConnectContext);
1448 focc->rhc = rhc;
1449 focc->peer1 = p1;
1450 focc->peer2 = p2;
1451 focc->peer2_host_id = peer2_host_id;
1452 focc->orig_msg = GNUNET_copy_message (&msg->header);
1453 focc->operation_id = op_id;
1454 focc->client = client;
1455 GNUNET_CONTAINER_DLL_insert_tail (rhc->focc_dll_head,
1456 rhc->focc_dll_tail,
1457 focc);
1458 return;
1459 }
1460
1461forward:
1462 LOG_DEBUG ("Forwarding without FOCC for connecting peers %u and %u\n", p1,
1463 p2);
1464 fopc = GNUNET_new (struct ForwardedOperationContext);
1465 fopc->client = client;
1466 fopc->operation_id = op_id;
1467 fopc->type = OP_OVERLAY_CONNECT;
1468 fopc->opc =
1469 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
1470 slave->controller, op_id,
1471 &msg->header,
1472 &GST_forwarded_operation_reply_relay,
1473 fopc);
1474 fopc->timeout_task =
1475 GNUNET_SCHEDULER_add_delayed (GST_timeout,
1476 &GST_forwarded_operation_timeout,
1477 fopc);
1478 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
1479 fopcq_tail,
1480 fopc);
1481}
1482
1483
1484/**
1485 * Callback called when a connection to the controller of peer2 has been
1486 * established
1487 *
1488 * @param cls the overlay connect contexts
1489 * @param c handle to the controller connection
1490 */
1491static void
1492p2_controller_connect_cb (void *cls,
1493 struct GNUNET_TESTBED_Controller *c)
1494{
1495 struct OverlayConnectContext *occ = cls;
1496 struct RemotePeer2Context *rp2c;
1497 struct GNUNET_TESTBED_PeerGetConfigurationMessage cmsg;
1498
1499 GNUNET_assert (OCC_TYPE_LOCAL != occ->type);
1500 rp2c = &occ->p2ctx.remote;
1501 rp2c->ncn = NULL;
1502 rp2c->p2c = c;
1503 cmsg.header.size =
1504 htons (sizeof(struct GNUNET_TESTBED_PeerGetConfigurationMessage));
1505 cmsg.header.type =
1506 htons (GNUNET_MESSAGE_TYPE_TESTBED_GET_PEER_INFORMATION);
1507 cmsg.peer_id = htonl (occ->other_peer_id);
1508 cmsg.operation_id = GNUNET_htonll (occ->op_id);
1509 rp2c->opc =
1510 GNUNET_TESTBED_forward_operation_msg_ (rp2c->p2c,
1511 occ->op_id,
1512 &cmsg.header,
1513 &overlay_connect_get_config,
1514 occ);
1515 GNUNET_free (occ->emsg);
1516 GNUNET_asprintf (&occ->emsg,
1517 "0x%llx: Timeout while getting peer identity of peer "
1518 "with id: %u",
1519 (unsigned long long) occ->op_id,
1520 occ->other_peer_id);
1521}
1522
1523
1524/**
1525 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_OVERLAY_CONNECT messages
1526 *
1527 * @param cls identification of the client
1528 * @param msg the actual message
1529 */
1530void
1531handle_overlay_connect (void *cls,
1532 const struct GNUNET_TESTBED_OverlayConnectMessage *msg)
1533{
1534 struct GNUNET_SERVICE_Client *client = cls;
1535 struct Peer *peer;
1536 struct Peer *peer2;
1537 struct OverlayConnectContext *occ;
1538 struct Neighbour *p2n;
1539 uint64_t operation_id;
1540 uint32_t p1;
1541 uint32_t p2;
1542 uint32_t peer2_host_id;
1543
1544 p1 = ntohl (msg->peer1);
1545 p2 = ntohl (msg->peer2);
1546 if (p1 == p2)
1547 {
1548 GNUNET_break (0);
1549 GNUNET_SERVICE_client_drop (client);
1550 return;
1551 }
1552 if (! VALID_PEER_ID (p1))
1553 {
1554 GNUNET_break (0);
1555 GNUNET_SERVICE_client_drop (client);
1556 return;
1557 }
1558 peer = GST_peer_list[p1];
1559 operation_id = GNUNET_ntohll (msg->operation_id);
1560 LOG_DEBUG
1561 ("Received overlay connect for peers %u and %u with op id: 0x%llx\n",
1562 p1,
1563 p2,
1564 (unsigned long long) operation_id);
1565 peer2_host_id = ntohl (msg->peer2_host_id);
1566 if (GNUNET_YES == peer->is_remote)
1567 {
1568 if (! VALID_HOST_ID (peer2_host_id))
1569 {
1570 GNUNET_break (0);
1571 GNUNET_SERVICE_client_drop (client);
1572 return;
1573 }
1574 forward_overlay_connect (msg, client);
1575 GNUNET_SERVICE_client_continue (client);
1576 return;
1577 }
1578 p2n = NULL;
1579 occ = GNUNET_new (struct OverlayConnectContext);
1580 occ->type = OCC_TYPE_LOCAL;
1581 if (! VALID_PEER_ID (p2)) /* May be peer2 is on a another controller */
1582 {
1583 if (NULL == (p2n = GST_get_neighbour (peer2_host_id)))
1584 {
1585 if (! VALID_HOST_ID (peer2_host_id))
1586 {
1587 GNUNET_break (0);
1588 LOG (GNUNET_ERROR_TYPE_WARNING,
1589 "0x%llx: Peer %u's host not in our neighbours list\n",
1590 (unsigned long long) operation_id, p2);
1591 GNUNET_SERVICE_client_drop (client);
1592 GNUNET_free (occ);
1593 return;
1594 }
1595 p2n = GST_create_neighbour (GST_host_list[peer2_host_id]);
1596 }
1597 occ->type = OCC_TYPE_REMOTE_LATERAL;
1598 occ->p2ctx.remote.p2n = p2n;
1599 }
1600 else if (GNUNET_YES == GST_peer_list[p2]->is_remote)
1601 {
1602 occ->type = OCC_TYPE_REMOTE_SLAVE;
1603 occ->p2ctx.remote.p2c = GST_peer_list[p2]->details.remote.slave->controller;
1604 }
1605 GNUNET_CONTAINER_DLL_insert_tail (occq_head,
1606 occq_tail,
1607 occ);
1608 occ->client = client;
1609 occ->other_peer_id = p2;
1610 GST_peer_list[p1]->reference_cnt++;
1611 occ->peer = GST_peer_list[p1];
1612 occ->op_id = operation_id;
1613 GNUNET_assert (NULL == occ->timeout_task);
1614 occ->timeout_task =
1615 GNUNET_SCHEDULER_add_delayed (GST_timeout,
1616 &timeout_overlay_connect,
1617 occ);
1618 switch (occ->type)
1619 {
1620 case OCC_TYPE_REMOTE_LATERAL:
1621 GNUNET_asprintf (&occ->emsg,
1622 "0x%llx: Timeout while acquiring connection to peer %u's "
1623 "host: %u\n",
1624 (unsigned long long) occ->op_id,
1625 occ->other_peer_id,
1626 peer2_host_id);
1627 occ->p2ctx.remote.ncn
1628 = GST_neighbour_get_connection (p2n,
1629 &p2_controller_connect_cb,
1630 occ);
1631 break;
1632 case OCC_TYPE_REMOTE_SLAVE:
1633 p2_controller_connect_cb (occ,
1634 occ->p2ctx.remote.p2c);
1635 break;
1636 case OCC_TYPE_LOCAL:
1637 peer2 = GST_peer_list[occ->other_peer_id];
1638 peer2->reference_cnt++;
1639 GNUNET_TESTING_peer_get_identity (peer2->details.local.peer,
1640 &occ->other_peer_identity);
1641 GNUNET_asprintf (&occ->emsg,
1642 "0x%llx: Timeout while connecting to CORE of peer with "
1643 "id: %u",
1644 (unsigned long long) occ->op_id,
1645 occ->peer->id);
1646 LOG_DEBUG ("Peer %u has PID %s\n",
1647 occ->other_peer_id,
1648 GNUNET_i2s (&occ->other_peer_identity));
1649 {
1650 struct GNUNET_PeerIdentity lpid;
1651
1652 GNUNET_TESTING_peer_get_identity (peer->details.local.peer,
1653 &lpid);
1654 LOG_DEBUG ("Peer %u has PID %s\n",
1655 p1,
1656 GNUNET_i2s (&lpid));
1657 }
1658 occ->cgh_ch =
1659 GST_connection_pool_get_handle (occ->peer->id,
1660 occ->peer->details.local.cfg,
1661 GST_CONNECTIONPOOL_SERVICE_CORE,
1662 &occ_cache_get_handle_core_cb, occ,
1663 &occ->other_peer_identity,
1664 &overlay_connect_notify, occ);
1665 break;
1666 }
1667 GNUNET_SERVICE_client_continue (client);
1668}
1669
1670
1671/**
1672 * Function to cleanup RemoteOverlayConnectCtx and any associated tasks
1673 * with it
1674 *
1675 * @param rocc the RemoteOverlayConnectCtx
1676 */
1677static void
1678cleanup_rocc (struct RemoteOverlayConnectCtx *rocc)
1679{
1680 LOG_DEBUG ("0x%llx: Cleaning up rocc\n",
1681 (unsigned long long) rocc->op_id);
1682 if (NULL != rocc->attempt_connect_task_id)
1683 GNUNET_SCHEDULER_cancel (rocc->attempt_connect_task_id);
1684 if (NULL != rocc->timeout_rocc_task_id)
1685 GNUNET_SCHEDULER_cancel (rocc->timeout_rocc_task_id);
1686 if (NULL != rocc->ohh)
1687 GNUNET_TRANSPORT_offer_hello_cancel (rocc->ohh);
1688 if (NULL != rocc->tcc.csh)
1689 GNUNET_ATS_connectivity_suggest_cancel (rocc->tcc.csh);
1690 GST_connection_pool_get_handle_done (rocc->tcc.cgh_p2_th);
1691 GST_connection_pool_get_handle_done (rocc->tcc.cgh_p2_ats);
1692 GNUNET_assert (rocc->peer->reference_cnt > 0);
1693 rocc->peer->reference_cnt--;
1694 if ((GNUNET_YES == rocc->peer->destroy_flag) &&
1695 (0 == rocc->peer->reference_cnt))
1696 GST_destroy_peer (rocc->peer);
1697 GNUNET_free (rocc->hello);
1698 GNUNET_CONTAINER_DLL_remove (roccq_head,
1699 roccq_tail,
1700 rocc);
1701 GNUNET_free (rocc);
1702}
1703
1704
1705/**
1706 * Task to timeout rocc and cleanit up
1707 *
1708 * @param cls the RemoteOverlayConnectCtx
1709 */
1710static void
1711timeout_rocc_task (void *cls)
1712{
1713 struct RemoteOverlayConnectCtx *rocc = cls;
1714
1715 GNUNET_assert (rocc->timeout_rocc_task_id != NULL);
1716 rocc->timeout_rocc_task_id = NULL;
1717 LOG_DEBUG ("0x%llx: rocc timed out\n",
1718 (unsigned long long) rocc->op_id);
1719 cleanup_rocc (rocc);
1720}
1721
1722
1723/**
1724 * Function called to notify transport users that another
1725 * peer connected to us.
1726 *
1727 * @param cls the RemoteOverlayConnectContext
1728 * @param new_peer the peer that connected
1729 */
1730static void
1731cache_transport_peer_connect_notify (void *cls,
1732 const struct GNUNET_PeerIdentity *new_peer)
1733{
1734 struct RemoteOverlayConnectCtx *rocc = cls;
1735
1736 LOG_DEBUG ("0x%llx: Request Overlay connect notify\n",
1737 (unsigned long long) rocc->op_id);
1738 GNUNET_assert (0 ==
1739 memcmp (new_peer, &rocc->a_id,
1740 sizeof(struct GNUNET_PeerIdentity)));
1741 LOG_DEBUG ("0x%llx: Peer %s connected\n",
1742 (unsigned long long) rocc->op_id,
1743 GNUNET_i2s (&rocc->a_id));
1744 cleanup_rocc (rocc);
1745}
1746
1747
1748/**
1749 * Task to offer the HELLO message to the peer and ask it to connect to the peer
1750 * whose identity is in RemoteOverlayConnectCtx
1751 *
1752 * @param cls the RemoteOverlayConnectCtx
1753 */
1754static void
1755attempt_connect_task (void *cls);
1756
1757
1758/**
1759 * Task that is run when hello has been sent If tc->reason =
1760 * #GNUNET_SCHEDULER_REASON_TIMEOUT then sending HELLO failed; if
1761 * #GNUNET_SCHEDULER_REASON_READ_READY is succeeded
1762 *
1763 * @param cls the overlay connect context
1764 */
1765static void
1766rocc_hello_sent_cb (void *cls)
1767{
1768 struct RemoteOverlayConnectCtx *rocc = cls;
1769
1770 rocc->ohh = NULL;
1771 GNUNET_assert (NULL == rocc->attempt_connect_task_id);
1772 LOG_DEBUG ("0x%llx: HELLO of peer %s delivered to local peer with id: %u\n",
1773 (unsigned long long) rocc->op_id,
1774 GNUNET_i2s (&rocc->a_id),
1775 rocc->peer->id);
1776 rocc->tcc.cgh_p2_ats =
1777 GST_connection_pool_get_handle (rocc->peer->id,
1778 rocc->peer->details.local.cfg,
1779 GST_CONNECTIONPOOL_SERVICE_ATS_CONNECTIVITY,
1780 &occ_cache_get_handle_ats_rocc_cb,
1781 rocc, NULL, NULL, NULL);
1782}
1783
1784
1785/**
1786 * Task to offer the HELLO message to the peer and ask it to connect to the peer
1787 * whose identity is in RemoteOverlayConnectCtx
1788 *
1789 * @param cls the RemoteOverlayConnectCtx
1790 */
1791static void
1792attempt_connect_task (void *cls)
1793{
1794 struct RemoteOverlayConnectCtx *rocc = cls;
1795
1796 GNUNET_assert (NULL != rocc->attempt_connect_task_id);
1797 rocc->attempt_connect_task_id = NULL;
1798 LOG_DEBUG ("0x%llx: Offering HELLO of peer %s to remote peer with id: %u\n",
1799 (unsigned long long) rocc->op_id,
1800 GNUNET_i2s (&rocc->a_id),
1801 rocc->peer->id);
1802 rocc->ohh =
1803 GNUNET_TRANSPORT_offer_hello (rocc->tcc.cfg,
1804 rocc->hello,
1805 &rocc_hello_sent_cb,
1806 rocc);
1807 if (NULL == rocc->ohh)
1808 rocc->attempt_connect_task_id =
1809 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
1810 (GNUNET_TIME_UNIT_MILLISECONDS,
1811 100
1812 + GNUNET_CRYPTO_random_u32
1813 (GNUNET_CRYPTO_QUALITY_WEAK, 500)),
1814 &attempt_connect_task, rocc);
1815}
1816
1817
1818/**
1819 * Callback from cache with needed handles set
1820 *
1821 * @param cls the closure passed to GST_cache_get_handle_transport()
1822 * @param ch the handle to CORE. Can be NULL if it is not requested
1823 * @param th the handle to TRANSPORT. Can be NULL if it is not requested
1824 * @param ac the handle to ATS. Can be NULL if it is not requested
1825 * @param ignore_ peer identity which is ignored in this callback
1826 */
1827static void
1828rocc_cache_get_handle_transport_cb (void *cls,
1829 struct GNUNET_CORE_Handle *ch,
1830 struct GNUNET_TRANSPORT_CoreHandle *th,
1831 struct GNUNET_ATS_ConnectivityHandle *ac,
1832 const struct GNUNET_PeerIdentity *ignore_,
1833 const struct
1834 GNUNET_CONFIGURATION_Handle *cfg)
1835{
1836 struct RemoteOverlayConnectCtx *rocc = cls;
1837
1838 if (NULL == th)
1839 {
1840 rocc->timeout_rocc_task_id =
1841 GNUNET_SCHEDULER_add_now (&timeout_rocc_task, rocc);
1842 return;
1843 }
1844 rocc->tcc.th_ = th;
1845 rocc->tcc.cfg = cfg;
1846 if (NULL !=
1847 GNUNET_TRANSPORT_core_get_mq (rocc->tcc.th_,
1848 &rocc->a_id))
1849 {
1850 LOG_DEBUG ("0x%llx: Target peer %s already connected to local peer: %u\n",
1851 (unsigned long long) rocc->op_id,
1852 GNUNET_i2s (&rocc->a_id),
1853 rocc->peer->id);
1854 cleanup_rocc (rocc);
1855 return;
1856 }
1857 rocc->attempt_connect_task_id =
1858 GNUNET_SCHEDULER_add_now (&attempt_connect_task, rocc);
1859}
1860
1861
1862/**
1863 * Check #GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT messages
1864 *
1865 * @param cls identification of the client
1866 * @param msg the actual message
1867 * @return #GNUNET_OK if @a msg is well-formed
1868 */
1869int
1870check_remote_overlay_connect (void *cls,
1871 const struct
1872 GNUNET_TESTBED_RemoteOverlayConnectMessage *msg)
1873{
1874 uint32_t peer_id;
1875 uint16_t msize;
1876 uint16_t hsize;
1877
1878 msize = ntohs (msg->header.size);
1879 if (GNUNET_MESSAGE_TYPE_HELLO != ntohs (msg->hello->type))
1880 {
1881 GNUNET_break (0);
1882 return GNUNET_SYSERR;
1883 }
1884 hsize = ntohs (msg->hello->size);
1885 if ((sizeof(struct GNUNET_TESTBED_RemoteOverlayConnectMessage) + hsize) !=
1886 msize)
1887 {
1888 GNUNET_break (0);
1889 return GNUNET_SYSERR;
1890 }
1891 peer_id = ntohl (msg->peer);
1892 if ((peer_id >= GST_peer_list_size) ||
1893 (NULL == GST_peer_list[peer_id]))
1894 {
1895 GNUNET_break_op (0);
1896 return GNUNET_SYSERR;
1897 }
1898 return GNUNET_OK;
1899}
1900
1901
1902/**
1903 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT messages
1904 *
1905 * @param cls identification of the client
1906 * @param msg the actual message
1907 */
1908void
1909handle_remote_overlay_connect (void *cls,
1910 const struct
1911 GNUNET_TESTBED_RemoteOverlayConnectMessage *msg)
1912{
1913 struct GNUNET_SERVICE_Client *client = cls;
1914 struct RemoteOverlayConnectCtx *rocc;
1915 struct Peer *peer;
1916 struct GNUNET_PeerIdentity pid;
1917 static char pid_str[16];
1918 uint32_t peer_id;
1919 uint16_t hsize;
1920
1921 hsize = ntohs (msg->hello->size);
1922 peer_id = ntohl (msg->peer);
1923 peer = GST_peer_list[peer_id];
1924 if (GNUNET_YES == peer->is_remote)
1925 {
1926 struct GNUNET_MessageHeader *msg2;
1927
1928 msg2 = GNUNET_copy_message (&msg->header);
1929 GNUNET_TESTBED_queue_message_ (peer->details.remote.slave->controller,
1930 msg2);
1931 GNUNET_SERVICE_client_continue (client);
1932 return;
1933 }
1934 rocc = GNUNET_new (struct RemoteOverlayConnectCtx);
1935 rocc->op_id = GNUNET_ntohll (msg->operation_id);
1936 GNUNET_CONTAINER_DLL_insert_tail (roccq_head,
1937 roccq_tail,
1938 rocc);
1939 rocc->a_id = msg->peer_identity;
1940 GNUNET_TESTING_peer_get_identity (peer->details.local.peer,
1941 &pid);
1942 (void) GNUNET_strlcpy (pid_str,
1943 GNUNET_i2s (&pid),
1944 sizeof(pid_str));
1945 LOG_DEBUG (
1946 "0x%llx: Remote overlay connect %s to peer %s with hello size: %u\n",
1947 (unsigned long long) rocc->op_id,
1948 pid_str,
1949 GNUNET_i2s (&rocc->a_id),
1950 hsize);
1951 rocc->peer = peer;
1952 rocc->peer->reference_cnt++;
1953 rocc->hello = GNUNET_malloc (hsize);
1954 GNUNET_memcpy (rocc->hello,
1955 msg->hello,
1956 hsize);
1957 rocc->tcc.cgh_p2_th =
1958 GST_connection_pool_get_handle (peer_id,
1959 rocc->peer->details.local.cfg,
1960 GST_CONNECTIONPOOL_SERVICE_TRANSPORT,
1961 &rocc_cache_get_handle_transport_cb,
1962 rocc,
1963 &rocc->a_id,
1964 &cache_transport_peer_connect_notify,
1965 rocc);
1966 rocc->timeout_rocc_task_id =
1967 GNUNET_SCHEDULER_add_delayed (GST_timeout,
1968 &timeout_rocc_task,
1969 rocc);
1970 GNUNET_SERVICE_client_continue (client);
1971}
1972
1973
1974/**
1975 * Clears all pending overlay connect contexts in queue
1976 */
1977void
1978GST_free_occq ()
1979{
1980 struct OverlayConnectContext *occ;
1981
1982 while (NULL != (occ = occq_head))
1983 cleanup_occ (occ);
1984}
1985
1986
1987/**
1988 * Clears all pending remote overlay connect contexts in queue
1989 */
1990void
1991GST_free_roccq ()
1992{
1993 struct RemoteOverlayConnectCtx *rocc;
1994
1995 while (NULL != (rocc = roccq_head))
1996 cleanup_rocc (rocc);
1997}