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