diff options
-rw-r--r-- | src/testbed/gnunet-service-testbed_oc.c | 692 |
1 files changed, 431 insertions, 261 deletions
diff --git a/src/testbed/gnunet-service-testbed_oc.c b/src/testbed/gnunet-service-testbed_oc.c index d27c2bbf7..7913b0f49 100644 --- a/src/testbed/gnunet-service-testbed_oc.c +++ b/src/testbed/gnunet-service-testbed_oc.c | |||
@@ -80,6 +80,82 @@ struct TryConnectContext | |||
80 | 80 | ||
81 | 81 | ||
82 | /** | 82 | /** |
83 | * Types for context information we create for overlay connect requests | ||
84 | */ | ||
85 | enum OverlayConnectContextType | ||
86 | { | ||
87 | /** | ||
88 | * This type is used if the overlay connection is local i.e. the connection | ||
89 | * has to be made between local peers | ||
90 | */ | ||
91 | OCC_TYPE_LOCAL, | ||
92 | |||
93 | /** | ||
94 | * Type to be used when the first peer is local and the other peer is on a slave | ||
95 | * controller started by us | ||
96 | */ | ||
97 | OCC_TYPE_REMOTE_SLAVE, | ||
98 | |||
99 | /** | ||
100 | * Type to be used when the first peer is local and the other peer is on a | ||
101 | * controller which is not started by us. | ||
102 | */ | ||
103 | OCC_TYPE_REMOTE_LATERAL | ||
104 | }; | ||
105 | |||
106 | |||
107 | /** | ||
108 | * Context data for operations on second peer in local overlay connection | ||
109 | * contexts | ||
110 | */ | ||
111 | struct LocalPeer2Context | ||
112 | { | ||
113 | /** | ||
114 | * The handle for offering the HELLO of the first peer to the second | ||
115 | * peer. | ||
116 | */ | ||
117 | struct GNUNET_TRANSPORT_OfferHelloHandle *ohh; | ||
118 | |||
119 | /** | ||
120 | * The transport TryConnectContext | ||
121 | */ | ||
122 | struct TryConnectContext tcc; | ||
123 | }; | ||
124 | |||
125 | |||
126 | /** | ||
127 | * Context data for operations on second peer in remote overlay connection | ||
128 | * contexts | ||
129 | */ | ||
130 | struct RemotePeer2Context | ||
131 | { | ||
132 | /** | ||
133 | * Controller of peer 2; If OCC_TYPE_REMOTE_LATERAL is the type of overlay | ||
134 | * connection then this can be NULL until the connection to the controller is | ||
135 | * established | ||
136 | */ | ||
137 | struct GNUNET_TESTBED_Controller *p2c; | ||
138 | |||
139 | /** | ||
140 | * Operation context for the suboperation we start to get the identity of the | ||
141 | * second peer | ||
142 | */ | ||
143 | struct OperationContext *opc; | ||
144 | |||
145 | /** | ||
146 | * Notification handle acquire to connect to a remote controller. Only used | ||
147 | * if the type of overlay connection is OCC_TYPE_REMOTE_LATERAL. | ||
148 | */ | ||
149 | struct NeighbourConnectNotification *ncn; | ||
150 | |||
151 | /** | ||
152 | * The neighbour handle. Only used if the type of overlay connection is | ||
153 | * OCC_TYPE_REMOTE_LATERAL. | ||
154 | */ | ||
155 | struct Neighbour *p2n; | ||
156 | }; | ||
157 | |||
158 | /** | ||
83 | * Context information for connecting 2 peers in overlay. | 159 | * Context information for connecting 2 peers in overlay. |
84 | */ | 160 | */ |
85 | struct OverlayConnectContext | 161 | struct OverlayConnectContext |
@@ -133,37 +209,26 @@ struct OverlayConnectContext | |||
133 | struct GNUNET_TRANSPORT_GetHelloHandle *ghh; | 209 | struct GNUNET_TRANSPORT_GetHelloHandle *ghh; |
134 | 210 | ||
135 | /** | 211 | /** |
136 | * The handle for offering the HELLO of the first peer to the second | ||
137 | * peer. This is only used if the second peer is a local peer. | ||
138 | */ | ||
139 | struct GNUNET_TRANSPORT_OfferHelloHandle *ohh; | ||
140 | |||
141 | /** | ||
142 | * The error message we send if this overlay connect operation has timed out | 212 | * The error message we send if this overlay connect operation has timed out |
143 | */ | 213 | */ |
144 | char *emsg; | 214 | char *emsg; |
145 | 215 | ||
146 | /** | 216 | /** |
147 | * Operation context for the suboperation we start to get the identity of the | 217 | * Context information for operations on the second peer |
148 | * second peer if it is a remote peer | ||
149 | */ | 218 | */ |
150 | struct OperationContext *opc; | 219 | union { |
151 | 220 | ||
152 | /** | 221 | /** |
153 | * Controller of peer 2; NULL if the peer is a local peer or until the | 222 | * Context information to be used if the second peer is local |
154 | * connection to the controller is established | 223 | */ |
155 | */ | 224 | struct LocalPeer2Context local; |
156 | struct GNUNET_TESTBED_Controller *p2c; | ||
157 | |||
158 | struct NeighbourConnectNotification *p2_ncn; | ||
159 | 225 | ||
160 | struct Neighbour *p2n; | 226 | /** |
227 | * Context information to be used if the second peer is remote | ||
228 | */ | ||
229 | struct RemotePeer2Context remote; | ||
161 | 230 | ||
162 | /** | 231 | } p2ctx; |
163 | * The transport TryConnectContext. This will be NULL if the second peer is a | ||
164 | * remote peer | ||
165 | */ | ||
166 | struct TryConnectContext tcc; | ||
167 | 232 | ||
168 | /** | 233 | /** |
169 | * The peer identity of the first peer | 234 | * The peer identity of the first peer |
@@ -197,10 +262,14 @@ struct OverlayConnectContext | |||
197 | GNUNET_SCHEDULER_TaskIdentifier cleanup_task; | 262 | GNUNET_SCHEDULER_TaskIdentifier cleanup_task; |
198 | 263 | ||
199 | /** | 264 | /** |
265 | * The type of this context information | ||
266 | */ | ||
267 | enum OverlayConnectContextType type; | ||
268 | |||
269 | /** | ||
200 | * The id of the second peer which is has to connect to the first peer | 270 | * The id of the second peer which is has to connect to the first peer |
201 | */ | 271 | */ |
202 | uint32_t other_peer_id; | 272 | uint32_t other_peer_id; |
203 | |||
204 | }; | 273 | }; |
205 | 274 | ||
206 | 275 | ||
@@ -388,6 +457,51 @@ GST_process_next_focc (struct RegisteredHostContext *rhc) | |||
388 | 457 | ||
389 | 458 | ||
390 | /** | 459 | /** |
460 | * Cleans up any used handles in local peer2 context | ||
461 | * | ||
462 | * @param lp2c the local peer2 context information | ||
463 | */ | ||
464 | static void | ||
465 | cleanup_occ_lp2c (struct LocalPeer2Context *lp2c) | ||
466 | { | ||
467 | if (NULL != lp2c->ohh) | ||
468 | GNUNET_TRANSPORT_offer_hello_cancel (lp2c->ohh); | ||
469 | if (NULL != lp2c->tcc.cgh_th) | ||
470 | GST_cache_get_handle_done (lp2c->tcc.cgh_th); | ||
471 | if (NULL != lp2c->tcc.tch) | ||
472 | GNUNET_TRANSPORT_try_connect_cancel (lp2c->tcc.tch); | ||
473 | if (GNUNET_SCHEDULER_NO_TASK != lp2c->tcc.task) | ||
474 | GNUNET_SCHEDULER_cancel (lp2c->tcc.task); | ||
475 | } | ||
476 | |||
477 | |||
478 | /** | ||
479 | * Cleans up any used handles in remote peer2 context. Relinquishes the | ||
480 | * remote controller connection if it has been established on-demand. | ||
481 | * | ||
482 | * @param rp2c the remote peer2 context information | ||
483 | */ | ||
484 | static void | ||
485 | cleanup_occ_rp2c (struct RemotePeer2Context *rp2c) | ||
486 | { | ||
487 | if (NULL != rp2c->opc) | ||
488 | GNUNET_TESTBED_forward_operation_msg_cancel_ (rp2c->opc); | ||
489 | if (NULL != rp2c->ncn) | ||
490 | GST_neighbour_get_connection_cancel (rp2c->ncn); | ||
491 | if ( (NULL != rp2c->p2c) && (NULL != rp2c->p2n) ) | ||
492 | GST_neighbour_release_connection (rp2c->p2n); | ||
493 | |||
494 | } | ||
495 | |||
496 | /** | ||
497 | * Condition for checking if given peer is ready to be destroyed | ||
498 | * | ||
499 | * @param peer the peer to check | ||
500 | */ | ||
501 | #define PEER_EXPIRED(peer) \ | ||
502 | ( (GNUNET_YES == peer->destroy_flag) && (0 == peer->reference_cnt) ) | ||
503 | |||
504 | /** | ||
391 | * Cleanup overlay connect context structure | 505 | * Cleanup overlay connect context structure |
392 | * | 506 | * |
393 | * @param occ the overlay connect context | 507 | * @param occ the overlay connect context |
@@ -395,14 +509,12 @@ GST_process_next_focc (struct RegisteredHostContext *rhc) | |||
395 | static void | 509 | static void |
396 | cleanup_occ (struct OverlayConnectContext *occ) | 510 | cleanup_occ (struct OverlayConnectContext *occ) |
397 | { | 511 | { |
398 | struct Peer *other_peer; | 512 | struct Peer *peer2; |
399 | 513 | ||
400 | LOG_DEBUG ("0x%llx: Cleaning up occ\n", occ->op_id); | 514 | LOG_DEBUG ("0x%llx: Cleaning up occ\n", occ->op_id); |
401 | GNUNET_free_non_null (occ->emsg); | 515 | GNUNET_free_non_null (occ->emsg); |
402 | GNUNET_free_non_null (occ->hello); | 516 | GNUNET_free_non_null (occ->hello); |
403 | GNUNET_SERVER_client_drop (occ->client); | 517 | GNUNET_SERVER_client_drop (occ->client); |
404 | if (NULL != occ->opc) | ||
405 | GNUNET_TESTBED_forward_operation_msg_cancel_ (occ->opc); | ||
406 | if (GNUNET_SCHEDULER_NO_TASK != occ->send_hello_task) | 518 | if (GNUNET_SCHEDULER_NO_TASK != occ->send_hello_task) |
407 | GNUNET_SCHEDULER_cancel (occ->send_hello_task); | 519 | GNUNET_SCHEDULER_cancel (occ->send_hello_task); |
408 | if (GNUNET_SCHEDULER_NO_TASK != occ->cleanup_task) | 520 | if (GNUNET_SCHEDULER_NO_TASK != occ->cleanup_task) |
@@ -413,38 +525,27 @@ cleanup_occ (struct OverlayConnectContext *occ) | |||
413 | GST_cache_get_handle_done (occ->cgh_ch); | 525 | GST_cache_get_handle_done (occ->cgh_ch); |
414 | if (NULL != occ->ghh) | 526 | if (NULL != occ->ghh) |
415 | GNUNET_TRANSPORT_get_hello_cancel (occ->ghh); | 527 | GNUNET_TRANSPORT_get_hello_cancel (occ->ghh); |
416 | if (NULL != occ->ohh) | ||
417 | GNUNET_TRANSPORT_offer_hello_cancel (occ->ohh); | ||
418 | if (GNUNET_SCHEDULER_NO_TASK != occ->tcc.task) | ||
419 | GNUNET_SCHEDULER_cancel (occ->tcc.task); | ||
420 | if (NULL != occ->tcc.tch) | ||
421 | GNUNET_TRANSPORT_try_connect_cancel (occ->tcc.tch); | ||
422 | if (NULL != occ->cgh_p1th) | 528 | if (NULL != occ->cgh_p1th) |
423 | GST_cache_get_handle_done (occ->cgh_p1th); | 529 | GST_cache_get_handle_done (occ->cgh_p1th); |
424 | if (NULL != occ->tcc.cgh_th) | ||
425 | GST_cache_get_handle_done (occ->tcc.cgh_th); | ||
426 | if (NULL != occ->p2n) | ||
427 | { | ||
428 | if (NULL != occ->p2_ncn) | ||
429 | GST_neighbour_get_connection_cancel (occ->p2_ncn); | ||
430 | if (NULL != occ->p2c) | ||
431 | GST_neighbour_release_connection (occ->p2n); | ||
432 | } | ||
433 | GNUNET_assert (NULL != GST_peer_list); | 530 | GNUNET_assert (NULL != GST_peer_list); |
434 | GNUNET_assert (occ->peer->reference_cnt > 0); | 531 | GNUNET_assert (occ->peer->reference_cnt > 0); |
435 | occ->peer->reference_cnt--; | 532 | occ->peer->reference_cnt--; |
436 | if ( (GNUNET_YES == occ->peer->destroy_flag) && | 533 | if (PEER_EXPIRED (occ->peer)) |
437 | (0 == occ->peer->reference_cnt) ) | ||
438 | GST_destroy_peer (occ->peer); | 534 | GST_destroy_peer (occ->peer); |
439 | if ( (occ->other_peer_id < GST_peer_list_size) | 535 | switch (occ->type) |
440 | && (NULL != (other_peer = GST_peer_list[occ->other_peer_id])) | ||
441 | && (GNUNET_YES != other_peer->is_remote) ) | ||
442 | { | 536 | { |
443 | GNUNET_assert (other_peer->reference_cnt > 0); | 537 | case OCC_TYPE_LOCAL: |
444 | other_peer->reference_cnt--; | 538 | peer2 = GST_peer_list[occ->other_peer_id]; |
445 | if ( (GNUNET_YES == other_peer->destroy_flag) && | 539 | GNUNET_assert (peer2->reference_cnt > 0); |
446 | (0 == other_peer->reference_cnt) ) | 540 | peer2->reference_cnt--; |
447 | GST_destroy_peer (other_peer); | 541 | if (PEER_EXPIRED (peer2)) |
542 | GST_destroy_peer (peer2); | ||
543 | cleanup_occ_lp2c (&occ->p2ctx.local); | ||
544 | break; | ||
545 | case OCC_TYPE_REMOTE_SLAVE: | ||
546 | case OCC_TYPE_REMOTE_LATERAL: | ||
547 | cleanup_occ_rp2c (&occ->p2ctx.remote); | ||
548 | break; | ||
448 | } | 549 | } |
449 | GNUNET_CONTAINER_DLL_remove (occq_head, occq_tail, occ); | 550 | GNUNET_CONTAINER_DLL_remove (occq_head, occq_tail, occ); |
450 | GNUNET_free (occ); | 551 | GNUNET_free (occ); |
@@ -519,10 +620,11 @@ static void | |||
519 | overlay_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer) | 620 | overlay_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer) |
520 | { | 621 | { |
521 | struct OverlayConnectContext *occ = cls; | 622 | struct OverlayConnectContext *occ = cls; |
623 | struct LocalPeer2Context *lp2c; | ||
522 | char *new_peer_str; | 624 | char *new_peer_str; |
523 | char *other_peer_str; | 625 | char *other_peer_str; |
524 | 626 | ||
525 | //LOG_DEBUG ("Overlay connect notify\n"); | 627 | LOG_DEBUG ("Overlay connect notify\n"); |
526 | if (0 == | 628 | if (0 == |
527 | memcmp (new_peer, &occ->peer_identity, | 629 | memcmp (new_peer, &occ->peer_identity, |
528 | sizeof (struct GNUNET_PeerIdentity))) | 630 | sizeof (struct GNUNET_PeerIdentity))) |
@@ -533,8 +635,8 @@ overlay_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer) | |||
533 | memcmp (new_peer, &occ->other_peer_identity, | 635 | memcmp (new_peer, &occ->other_peer_identity, |
534 | sizeof (struct GNUNET_PeerIdentity))) | 636 | sizeof (struct GNUNET_PeerIdentity))) |
535 | { | 637 | { |
536 | /* LOG_DEBUG ("Unexpected peer %4s connected when expecting peer %4s\n", */ | 638 | LOG_DEBUG ("Unexpected peer %4s connected when expecting peer %4s\n", |
537 | /* new_peer_str, other_peer_str); */ | 639 | new_peer_str, other_peer_str); |
538 | GNUNET_free (new_peer_str); | 640 | GNUNET_free (new_peer_str); |
539 | GNUNET_free (other_peer_str); | 641 | GNUNET_free (other_peer_str); |
540 | return; | 642 | return; |
@@ -551,16 +653,19 @@ overlay_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer) | |||
551 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task); | 653 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task); |
552 | GNUNET_SCHEDULER_cancel (occ->timeout_task); | 654 | GNUNET_SCHEDULER_cancel (occ->timeout_task); |
553 | occ->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 655 | occ->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
554 | if (GNUNET_SCHEDULER_NO_TASK != occ->tcc.task) | 656 | if (OCC_TYPE_LOCAL == occ->type) |
555 | { | 657 | { |
556 | GNUNET_SCHEDULER_cancel (occ->tcc.task); | 658 | lp2c = &occ->p2ctx.local; |
557 | occ->tcc.task = GNUNET_SCHEDULER_NO_TASK; | 659 | if (GNUNET_SCHEDULER_NO_TASK != lp2c->tcc.task) |
660 | { | ||
661 | GNUNET_SCHEDULER_cancel (lp2c->tcc.task); | ||
662 | lp2c->tcc.task = GNUNET_SCHEDULER_NO_TASK; | ||
663 | } | ||
558 | } | 664 | } |
559 | GNUNET_free_non_null (occ->emsg); | 665 | GNUNET_free_non_null (occ->emsg); |
560 | occ->emsg = NULL; | 666 | occ->emsg = NULL; |
561 | send_overlay_connect_success_msg (occ); | 667 | send_overlay_connect_success_msg (occ); |
562 | occ->cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup_occ, occ); | 668 | occ->cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup_occ, occ); |
563 | //cleanup_occ (occ); | ||
564 | } | 669 | } |
565 | 670 | ||
566 | 671 | ||
@@ -644,8 +749,11 @@ static void | |||
644 | occ_hello_sent_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 749 | occ_hello_sent_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
645 | { | 750 | { |
646 | struct OverlayConnectContext *occ = cls; | 751 | struct OverlayConnectContext *occ = cls; |
752 | struct LocalPeer2Context *lp2c; | ||
647 | 753 | ||
648 | occ->ohh = NULL; | 754 | GNUNET_assert (OCC_TYPE_LOCAL == occ->type); |
755 | lp2c = &occ->p2ctx.local; | ||
756 | lp2c->ohh = NULL; | ||
649 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == occ->send_hello_task); | 757 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == occ->send_hello_task); |
650 | if (GNUNET_SCHEDULER_REASON_TIMEOUT == tc->reason) | 758 | if (GNUNET_SCHEDULER_REASON_TIMEOUT == tc->reason) |
651 | { | 759 | { |
@@ -663,15 +771,55 @@ occ_hello_sent_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
663 | "0x%llx: Timeout during TRANSPORT_try_connect() " | 771 | "0x%llx: Timeout during TRANSPORT_try_connect() " |
664 | "at peer %4s", occ->op_id, | 772 | "at peer %4s", occ->op_id, |
665 | GNUNET_i2s(&occ->peer_identity)); | 773 | GNUNET_i2s(&occ->peer_identity)); |
666 | occ->tcc.pid = &occ->peer_identity; | 774 | lp2c->tcc.pid = &occ->peer_identity; |
667 | occ->tcc.op_id = occ->op_id; | 775 | lp2c->tcc.op_id = occ->op_id; |
668 | occ->tcc.task = GNUNET_SCHEDULER_add_now (&try_connect_task, &occ->tcc); | 776 | lp2c->tcc.task = GNUNET_SCHEDULER_add_now (&try_connect_task, &lp2c->tcc); |
669 | } | 777 | } |
670 | 778 | ||
671 | 779 | ||
672 | /** | 780 | /** |
673 | * Task to offer HELLO of peer 1 to peer 2 and try to make peer 2 to connect to | 781 | * Sends the HELLO of peer1 to peer2's controller through remote overlay connect |
674 | * peer 1. | 782 | * request. |
783 | * | ||
784 | * @param occ the overlay connect context. Its type must be either | ||
785 | * OCC_TYPE_REMOTE_SLAVE or OCC_TYPE_REMOTE_LATERAL | ||
786 | */ | ||
787 | void | ||
788 | send_hello_thru_rocc (struct OverlayConnectContext *occ) | ||
789 | { | ||
790 | struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg; | ||
791 | char *other_peer_str; | ||
792 | uint16_t msize; | ||
793 | uint16_t hello_size; | ||
794 | |||
795 | GNUNET_assert (OCC_TYPE_LOCAL != occ->type); | ||
796 | GNUNET_assert (NULL != occ->hello); | ||
797 | other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity)); | ||
798 | LOG_DEBUG ("0x%llx: Offering HELLO of %s (size: %u) to %s via Remote " | ||
799 | "Overlay Request\n", occ->op_id, | ||
800 | GNUNET_i2s (&occ->peer_identity), ntohs (occ->hello->size), | ||
801 | other_peer_str); | ||
802 | GNUNET_free (other_peer_str); | ||
803 | hello_size = ntohs (occ->hello->size); | ||
804 | msize = | ||
805 | sizeof (struct GNUNET_TESTBED_RemoteOverlayConnectMessage) + hello_size; | ||
806 | msg = GNUNET_malloc (msize); | ||
807 | msg->header.type = | ||
808 | htons (GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT); | ||
809 | msg->header.size = htons (msize); | ||
810 | msg->peer = htonl (occ->other_peer_id); | ||
811 | msg->operation_id = GNUNET_htonll (occ->op_id); | ||
812 | (void) memcpy (&msg->peer_identity, &occ->peer_identity, | ||
813 | sizeof (struct GNUNET_PeerIdentity)); | ||
814 | memcpy (msg->hello, occ->hello, hello_size); | ||
815 | GNUNET_TESTBED_queue_message_ (occ->p2ctx.remote.p2c, &msg->header); | ||
816 | } | ||
817 | |||
818 | |||
819 | /** | ||
820 | * Task to offer HELLO of peer 1 to peer 2. If peer2 is local it is offered | ||
821 | * using its TRANSPORT connection; if remote the HELLO is sent remotely by using | ||
822 | * send_hello_thru_rocc() | ||
675 | * | 823 | * |
676 | * @param cls the OverlayConnectContext | 824 | * @param cls the OverlayConnectContext |
677 | * @param tc the TaskContext from scheduler | 825 | * @param tc the TaskContext from scheduler |
@@ -680,57 +828,37 @@ static void | |||
680 | send_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 828 | send_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
681 | { | 829 | { |
682 | struct OverlayConnectContext *occ = cls; | 830 | struct OverlayConnectContext *occ = cls; |
831 | struct LocalPeer2Context *lp2c; | ||
683 | char *other_peer_str; | 832 | char *other_peer_str; |
684 | 833 | ||
685 | occ->send_hello_task = GNUNET_SCHEDULER_NO_TASK; | 834 | occ->send_hello_task = GNUNET_SCHEDULER_NO_TASK; |
686 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 835 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
687 | return; | 836 | return; |
688 | GNUNET_assert (NULL != occ->hello); | 837 | GNUNET_assert (NULL != occ->hello); |
689 | other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity)); | 838 | if (OCC_TYPE_LOCAL != occ->type) |
690 | if (NULL != occ->p2c) | ||
691 | { | 839 | { |
692 | struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg; | 840 | send_hello_thru_rocc (occ); |
693 | uint16_t msize; | 841 | return; |
694 | uint16_t hello_size; | ||
695 | |||
696 | LOG_DEBUG ("0x%llx: Offering HELLO of %s (size: %u) to %s via Remote " | ||
697 | "Overlay Request\n", occ->op_id, | ||
698 | GNUNET_i2s (&occ->peer_identity), ntohs (occ->hello->size), | ||
699 | other_peer_str); | ||
700 | hello_size = ntohs (occ->hello->size); | ||
701 | msize = | ||
702 | sizeof (struct GNUNET_TESTBED_RemoteOverlayConnectMessage) + hello_size; | ||
703 | msg = GNUNET_malloc (msize); | ||
704 | msg->header.type = | ||
705 | htons (GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT); | ||
706 | msg->header.size = htons (msize); | ||
707 | msg->peer = htonl (occ->other_peer_id); | ||
708 | msg->operation_id = GNUNET_htonll (occ->op_id); | ||
709 | (void) memcpy (&msg->peer_identity, &occ->peer_identity, | ||
710 | sizeof (struct GNUNET_PeerIdentity)); | ||
711 | memcpy (msg->hello, occ->hello, hello_size); | ||
712 | GNUNET_TESTBED_queue_message_ (occ->p2c, &msg->header); | ||
713 | } | 842 | } |
714 | else | 843 | lp2c = &occ->p2ctx.local; |
844 | other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity)); | ||
845 | LOG_DEBUG ("0x%llx: Offering HELLO of %s to %s\n", occ->op_id, | ||
846 | GNUNET_i2s (&occ->peer_identity), other_peer_str); | ||
847 | GNUNET_free (other_peer_str); | ||
848 | lp2c->ohh = | ||
849 | GNUNET_TRANSPORT_offer_hello (lp2c->tcc.th_, occ->hello, | ||
850 | occ_hello_sent_cb, occ); | ||
851 | if (NULL == lp2c->ohh) | ||
715 | { | 852 | { |
716 | LOG_DEBUG ("0x%llx: Offering HELLO of %s to %s\n", occ->op_id, | 853 | GNUNET_break (0); |
717 | GNUNET_i2s (&occ->peer_identity), other_peer_str); | 854 | occ->send_hello_task = |
718 | occ->ohh = | 855 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply |
719 | GNUNET_TRANSPORT_offer_hello (occ->tcc.th_, occ->hello, | 856 | (GNUNET_TIME_UNIT_MILLISECONDS, |
720 | occ_hello_sent_cb, occ); | 857 | 100 + |
721 | if (NULL == occ->ohh) | 858 | GNUNET_CRYPTO_random_u32 |
722 | { | 859 | (GNUNET_CRYPTO_QUALITY_WEAK, 500)), |
723 | GNUNET_break (0); | 860 | &send_hello, occ); |
724 | occ->send_hello_task = | ||
725 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | ||
726 | (GNUNET_TIME_UNIT_MILLISECONDS, | ||
727 | 100 + | ||
728 | GNUNET_CRYPTO_random_u32 | ||
729 | (GNUNET_CRYPTO_QUALITY_WEAK, 500)), | ||
730 | &send_hello, occ); | ||
731 | } | ||
732 | } | 861 | } |
733 | GNUNET_free (other_peer_str); | ||
734 | } | 862 | } |
735 | 863 | ||
736 | 864 | ||
@@ -749,6 +877,7 @@ p2_transport_connect_cache_callback (void *cls, struct GNUNET_CORE_Handle *ch, | |||
749 | { | 877 | { |
750 | struct OverlayConnectContext *occ = cls; | 878 | struct OverlayConnectContext *occ = cls; |
751 | 879 | ||
880 | GNUNET_assert (OCC_TYPE_LOCAL == occ->type); | ||
752 | if (NULL == th) | 881 | if (NULL == th) |
753 | { | 882 | { |
754 | GNUNET_asprintf (&occ->emsg, "0x%llx: Cannot connect to TRANSPORT of %s", | 883 | GNUNET_asprintf (&occ->emsg, "0x%llx: Cannot connect to TRANSPORT of %s", |
@@ -758,7 +887,7 @@ p2_transport_connect_cache_callback (void *cls, struct GNUNET_CORE_Handle *ch, | |||
758 | GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ); | 887 | GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ); |
759 | return; | 888 | return; |
760 | } | 889 | } |
761 | occ->tcc.th_ = th; | 890 | occ->p2ctx.local.tcc.th_ = th; |
762 | GNUNET_asprintf (&occ->emsg, "0x%llx: Timeout while offering HELLO to %s", | 891 | GNUNET_asprintf (&occ->emsg, "0x%llx: Timeout while offering HELLO to %s", |
763 | occ->op_id, GNUNET_i2s (&occ->other_peer_identity)); | 892 | occ->op_id, GNUNET_i2s (&occ->other_peer_identity)); |
764 | occ->send_hello_task = GNUNET_SCHEDULER_add_now (&send_hello, occ); | 893 | occ->send_hello_task = GNUNET_SCHEDULER_add_now (&send_hello, occ); |
@@ -774,18 +903,19 @@ p2_transport_connect_cache_callback (void *cls, struct GNUNET_CORE_Handle *ch, | |||
774 | static void | 903 | static void |
775 | p2_transport_connect (struct OverlayConnectContext *occ) | 904 | p2_transport_connect (struct OverlayConnectContext *occ) |
776 | { | 905 | { |
906 | struct Peer *peer2; | ||
907 | |||
777 | GNUNET_assert (NULL == occ->emsg); | 908 | GNUNET_assert (NULL == occ->emsg); |
778 | GNUNET_assert (NULL != occ->hello); | 909 | GNUNET_assert (NULL != occ->hello); |
779 | GNUNET_assert (NULL == occ->ghh); | 910 | GNUNET_assert (NULL == occ->ghh); |
780 | GNUNET_assert (NULL == occ->p1th_); | 911 | GNUNET_assert (NULL == occ->p1th_); |
781 | GNUNET_assert (NULL == occ->cgh_p1th); | 912 | GNUNET_assert (NULL == occ->cgh_p1th); |
782 | if (NULL == occ->p2c) | 913 | if (OCC_TYPE_LOCAL == occ->type) |
783 | { | 914 | { |
784 | GNUNET_assert (NULL != GST_peer_list[occ->other_peer_id]); | 915 | GNUNET_assert (NULL != (peer2 = GST_peer_list[occ->other_peer_id])); |
785 | occ->tcc.cgh_th = | 916 | occ->p2ctx.local.tcc.cgh_th = |
786 | GST_cache_get_handle_transport (occ->other_peer_id, | 917 | GST_cache_get_handle_transport (occ->other_peer_id, |
787 | GST_peer_list[occ->other_peer_id] | 918 | peer2->details.local.cfg, |
788 | ->details.local.cfg, | ||
789 | &p2_transport_connect_cache_callback, | 919 | &p2_transport_connect_cache_callback, |
790 | occ, NULL, NULL, NULL); | 920 | occ, NULL, NULL, NULL); |
791 | return; | 921 | return; |
@@ -913,15 +1043,14 @@ occ_cache_get_handle_core_cb (void *cls, struct GNUNET_CORE_Handle *ch, | |||
913 | GNUNET_free_non_null (occ->emsg); | 1043 | GNUNET_free_non_null (occ->emsg); |
914 | if ((NULL == ch) || (NULL == my_identity)) | 1044 | if ((NULL == ch) || (NULL == my_identity)) |
915 | { | 1045 | { |
916 | (void) GNUNET_asprintf (&occ->emsg, | 1046 | GNUNET_asprintf (&occ->emsg, |
917 | "0x%llx: Failed to connect to CORE of peer with " | 1047 | "0x%llx: Failed to connect to CORE of peer with " |
918 | "id: %u", occ->op_id, occ->peer->id); | 1048 | "id: %u", occ->op_id, occ->peer->id); |
919 | GNUNET_SCHEDULER_cancel (occ->timeout_task); | 1049 | GNUNET_SCHEDULER_cancel (occ->timeout_task); |
920 | occ->timeout_task = | 1050 | occ->timeout_task = |
921 | GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ); | 1051 | GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ); |
922 | return; | 1052 | return; |
923 | } | 1053 | } |
924 | //occ->ch_ = ch; | ||
925 | occ->emsg = NULL; | 1054 | occ->emsg = NULL; |
926 | if (GNUNET_YES == | 1055 | if (GNUNET_YES == |
927 | GNUNET_CORE_is_peer_connected_sync (ch, &occ->other_peer_identity)) | 1056 | GNUNET_CORE_is_peer_connected_sync (ch, &occ->other_peer_identity)) |
@@ -969,9 +1098,12 @@ static void | |||
969 | overlay_connect_get_config (void *cls, const struct GNUNET_MessageHeader *msg) | 1098 | overlay_connect_get_config (void *cls, const struct GNUNET_MessageHeader *msg) |
970 | { | 1099 | { |
971 | struct OverlayConnectContext *occ = cls; | 1100 | struct OverlayConnectContext *occ = cls; |
1101 | struct RemotePeer2Context *rp2c; | ||
972 | const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *cmsg; | 1102 | const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *cmsg; |
973 | 1103 | ||
974 | occ->opc = NULL; | 1104 | GNUNET_assert (OCC_TYPE_LOCAL != occ->type); |
1105 | rp2c = &occ->p2ctx.remote; | ||
1106 | rp2c->opc = NULL; | ||
975 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task); | 1107 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task); |
976 | if (GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONFIGURATION != ntohs (msg->type)) | 1108 | if (GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONFIGURATION != ntohs (msg->type)) |
977 | { | 1109 | { |
@@ -1081,22 +1213,167 @@ hash_hosts (struct GNUNET_TESTBED_Host *reg_host, | |||
1081 | return hash; | 1213 | return hash; |
1082 | } | 1214 | } |
1083 | 1215 | ||
1216 | |||
1217 | /** | ||
1218 | * Forwards the overlay connect request to a slave controller. Before | ||
1219 | * forwarding, any hosts which are needed to be known by the slave controller to | ||
1220 | * execute the overlay connect request are registered at slave. | ||
1221 | * | ||
1222 | * @param msg the overlay connect request message to be forwarded | ||
1223 | * @param client the client to which the status of the forwarded request has to | ||
1224 | * be notified | ||
1225 | */ | ||
1226 | static void | ||
1227 | forward_overlay_connect (const struct GNUNET_TESTBED_OverlayConnectMessage *msg, | ||
1228 | struct GNUNET_SERVER_Client *client) | ||
1229 | { | ||
1230 | struct ForwardedOperationContext *fopc; | ||
1231 | struct Route *route_to_peer2_host; | ||
1232 | struct Route *route_to_peer1_host; | ||
1233 | struct Peer *peer; | ||
1234 | uint64_t op_id; | ||
1235 | uint32_t peer2_host_id; | ||
1236 | uint32_t p1; | ||
1237 | uint32_t p2; | ||
1238 | |||
1239 | p1 = ntohl (msg->peer1); | ||
1240 | p2 = ntohl (msg->peer2); | ||
1241 | op_id = GNUNET_ntohll (msg->operation_id); | ||
1242 | peer2_host_id = ntohl (msg->peer2_host_id); | ||
1243 | GNUNET_assert (p1 < GST_peer_list_size); | ||
1244 | GNUNET_assert (NULL != (peer = GST_peer_list[p1])); | ||
1245 | GNUNET_assert (GNUNET_YES == peer->is_remote); | ||
1246 | LOG_DEBUG ("0x%llx: Forwarding overlay connect\n", op_id); | ||
1247 | route_to_peer2_host = NULL; | ||
1248 | route_to_peer1_host = NULL; | ||
1249 | route_to_peer2_host = GST_find_dest_route (peer2_host_id); | ||
1250 | if ((NULL != route_to_peer2_host) || | ||
1251 | (peer2_host_id == GST_context->host_id)) | ||
1252 | { | ||
1253 | /* Peer 2 either below us OR with us */ | ||
1254 | route_to_peer1_host = | ||
1255 | GST_find_dest_route (GST_peer_list[p1]->details. | ||
1256 | remote.remote_host_id); | ||
1257 | /* Because we get this message only if we know where peer 1 is */ | ||
1258 | GNUNET_assert (NULL != route_to_peer1_host); | ||
1259 | if ((peer2_host_id == GST_context->host_id) || | ||
1260 | (route_to_peer2_host->dest != route_to_peer1_host->dest)) | ||
1261 | { | ||
1262 | /* Peer2 is either with us OR peer1 and peer2 can be reached through | ||
1263 | * different gateways */ | ||
1264 | struct GNUNET_HashCode hash; | ||
1265 | struct RegisteredHostContext *rhc; | ||
1266 | int skip_focc; | ||
1267 | |||
1268 | rhc = GNUNET_malloc (sizeof (struct RegisteredHostContext)); | ||
1269 | rhc->type = CLOSURE_TYPE_RHC; | ||
1270 | if (NULL != route_to_peer2_host) | ||
1271 | rhc->reg_host = GST_host_list[route_to_peer2_host->dest]; | ||
1272 | else | ||
1273 | rhc->reg_host = GST_host_list[GST_context->host_id]; | ||
1274 | rhc->host = GST_host_list[route_to_peer1_host->dest]; | ||
1275 | GNUNET_assert (NULL != rhc->reg_host); | ||
1276 | GNUNET_assert (NULL != rhc->host); | ||
1277 | rhc->gateway = peer->details.remote.slave; | ||
1278 | rhc->gateway2 = | ||
1279 | (NULL == | ||
1280 | route_to_peer2_host) ? NULL : | ||
1281 | GST_slave_list[route_to_peer2_host->dest]; | ||
1282 | rhc->state = RHC_INIT; | ||
1283 | GNUNET_SERVER_client_keep (client); | ||
1284 | rhc->client = client; | ||
1285 | hash = hash_hosts (rhc->reg_host, rhc->host); | ||
1286 | skip_focc = GNUNET_NO; | ||
1287 | if ((GNUNET_NO == | ||
1288 | GNUNET_CONTAINER_multihashmap_contains (peer->details. | ||
1289 | remote.slave->reghost_map, | ||
1290 | &hash)) || | ||
1291 | (GNUNET_SYSERR != | ||
1292 | GNUNET_CONTAINER_multihashmap_get_multiple (peer->details.remote. | ||
1293 | slave->reghost_map, | ||
1294 | &hash, | ||
1295 | reghost_match_iterator, | ||
1296 | &rhc))) | ||
1297 | { | ||
1298 | /* create and add a new registerd host context */ | ||
1299 | /* add the focc to its queue */ | ||
1300 | GNUNET_CONTAINER_multihashmap_put (peer->details.remote. | ||
1301 | slave->reghost_map, &hash, rhc, | ||
1302 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
1303 | GNUNET_assert (NULL != GST_host_list[peer2_host_id]); | ||
1304 | GST_queue_host_registration (peer->details.remote.slave, | ||
1305 | registeredhost_registration_completion, | ||
1306 | rhc, GST_host_list[peer2_host_id]); | ||
1307 | } | ||
1308 | else | ||
1309 | { | ||
1310 | /* rhc is now set to the existing one from the hash map by | ||
1311 | * reghost_match_iterator() */ | ||
1312 | /* if queue is empty then ignore creating focc and proceed with | ||
1313 | * normal forwarding */ | ||
1314 | if (RHC_OL_CONNECT == rhc->state) | ||
1315 | skip_focc = GNUNET_YES; | ||
1316 | } | ||
1317 | if (GNUNET_NO == skip_focc) | ||
1318 | { | ||
1319 | struct ForwardedOverlayConnectContext *focc; | ||
1320 | |||
1321 | focc = GNUNET_malloc (sizeof (struct ForwardedOverlayConnectContext)); | ||
1322 | focc->peer1 = p1; | ||
1323 | focc->peer2 = p2; | ||
1324 | focc->peer2_host_id = peer2_host_id; | ||
1325 | focc->orig_msg = GNUNET_copy_message (&msg->header); | ||
1326 | focc->operation_id = op_id; | ||
1327 | GNUNET_CONTAINER_DLL_insert_tail (rhc->focc_dll_head, | ||
1328 | rhc->focc_dll_tail, focc); | ||
1329 | return; | ||
1330 | } | ||
1331 | } | ||
1332 | } | ||
1333 | fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext)); | ||
1334 | GNUNET_SERVER_client_keep (client); | ||
1335 | fopc->client = client; | ||
1336 | fopc->operation_id = op_id; | ||
1337 | fopc->type = OP_OVERLAY_CONNECT; | ||
1338 | fopc->opc = | ||
1339 | GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote. | ||
1340 | slave->controller, op_id, | ||
1341 | &msg->header, | ||
1342 | &GST_forwarded_operation_reply_relay, | ||
1343 | fopc); | ||
1344 | fopc->timeout_task = | ||
1345 | GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, | ||
1346 | fopc); | ||
1347 | GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); | ||
1348 | } | ||
1349 | |||
1350 | |||
1351 | /** | ||
1352 | * Callback called when a connection to the controller of peer2 has been | ||
1353 | * established | ||
1354 | * | ||
1355 | * @param cls the overlay connect contexts | ||
1356 | * @param c handle to the controller connection | ||
1357 | */ | ||
1084 | static void | 1358 | static void |
1085 | p2_controller_connect_cb (void *cls, struct GNUNET_TESTBED_Controller *c) | 1359 | p2_controller_connect_cb (void *cls, struct GNUNET_TESTBED_Controller *c) |
1086 | { | 1360 | { |
1087 | struct OverlayConnectContext *occ = cls; | 1361 | struct OverlayConnectContext *occ = cls; |
1362 | struct RemotePeer2Context *rp2c; | ||
1088 | struct GNUNET_TESTBED_PeerGetConfigurationMessage cmsg; | 1363 | struct GNUNET_TESTBED_PeerGetConfigurationMessage cmsg; |
1089 | 1364 | ||
1090 | occ->p2_ncn = NULL; | 1365 | GNUNET_assert (OCC_TYPE_LOCAL != occ->type); |
1091 | occ->p2c = c; | 1366 | rp2c = &occ->p2ctx.remote; |
1367 | rp2c->ncn = NULL; | ||
1368 | rp2c->p2c = c; | ||
1092 | cmsg.header.size = | 1369 | cmsg.header.size = |
1093 | htons (sizeof (struct GNUNET_TESTBED_PeerGetConfigurationMessage)); | 1370 | htons (sizeof (struct GNUNET_TESTBED_PeerGetConfigurationMessage)); |
1094 | cmsg.header.type = | 1371 | cmsg.header.type = |
1095 | htons (GNUNET_MESSAGE_TYPE_TESTBED_GET_PEER_CONFIGURATION); | 1372 | htons (GNUNET_MESSAGE_TYPE_TESTBED_GET_PEER_CONFIGURATION); |
1096 | cmsg.peer_id = htonl (occ->other_peer_id); | 1373 | cmsg.peer_id = htonl (occ->other_peer_id); |
1097 | cmsg.operation_id = GNUNET_htonll (occ->op_id); | 1374 | cmsg.operation_id = GNUNET_htonll (occ->op_id); |
1098 | occ->opc = | 1375 | rp2c->opc = |
1099 | GNUNET_TESTBED_forward_operation_msg_ (occ->p2c, | 1376 | GNUNET_TESTBED_forward_operation_msg_ (rp2c->p2c, |
1100 | occ->op_id, &cmsg.header, | 1377 | occ->op_id, &cmsg.header, |
1101 | &overlay_connect_get_config, | 1378 | &overlay_connect_get_config, |
1102 | occ); | 1379 | occ); |
@@ -1120,8 +1397,9 @@ GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client, | |||
1120 | { | 1397 | { |
1121 | const struct GNUNET_TESTBED_OverlayConnectMessage *msg; | 1398 | const struct GNUNET_TESTBED_OverlayConnectMessage *msg; |
1122 | struct Peer *peer; | 1399 | struct Peer *peer; |
1400 | struct Peer *peer2; | ||
1123 | struct OverlayConnectContext *occ; | 1401 | struct OverlayConnectContext *occ; |
1124 | struct GNUNET_TESTBED_Controller *p2c; | 1402 | struct Neighbour *p2n; |
1125 | uint64_t operation_id; | 1403 | uint64_t operation_id; |
1126 | uint32_t p1; | 1404 | uint32_t p1; |
1127 | uint32_t p2; | 1405 | uint32_t p2; |
@@ -1144,127 +1422,20 @@ GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client, | |||
1144 | return; | 1422 | return; |
1145 | } | 1423 | } |
1146 | peer = GST_peer_list[p1]; | 1424 | peer = GST_peer_list[p1]; |
1147 | peer2_host_id = ntohl (msg->peer2_host_id); | ||
1148 | operation_id = GNUNET_ntohll (msg->operation_id); | 1425 | operation_id = GNUNET_ntohll (msg->operation_id); |
1149 | LOG_DEBUG | 1426 | LOG_DEBUG |
1150 | ("Received overlay connect for peers %u and %u with op id: 0x%llx\n", p1, | 1427 | ("Received overlay connect for peers %u and %u with op id: 0x%llx\n", p1, |
1151 | p2, operation_id); | 1428 | p2, operation_id); |
1152 | if (GNUNET_YES == peer->is_remote) | 1429 | if (GNUNET_YES == peer->is_remote) |
1153 | { | 1430 | { |
1154 | struct ForwardedOperationContext *fopc; | 1431 | forward_overlay_connect (msg, client); |
1155 | struct Route *route_to_peer2_host; | ||
1156 | struct Route *route_to_peer1_host; | ||
1157 | |||
1158 | LOG_DEBUG ("0x%llx: Forwarding overlay connect\n", operation_id); | ||
1159 | route_to_peer2_host = NULL; | ||
1160 | route_to_peer1_host = NULL; | ||
1161 | route_to_peer2_host = GST_find_dest_route (peer2_host_id); | ||
1162 | if ((NULL != route_to_peer2_host) || | ||
1163 | (peer2_host_id == GST_context->host_id)) | ||
1164 | { | ||
1165 | /* Peer 2 either below us OR with us */ | ||
1166 | route_to_peer1_host = | ||
1167 | GST_find_dest_route (GST_peer_list[p1]->details. | ||
1168 | remote.remote_host_id); | ||
1169 | /* Because we get this message only if we know where peer 1 is */ | ||
1170 | GNUNET_assert (NULL != route_to_peer1_host); | ||
1171 | if ((peer2_host_id == GST_context->host_id) || | ||
1172 | (route_to_peer2_host->dest != route_to_peer1_host->dest)) | ||
1173 | { | ||
1174 | /* Peer2 is either with us OR peer1 and peer2 can be reached through | ||
1175 | * different gateways */ | ||
1176 | struct GNUNET_HashCode hash; | ||
1177 | struct RegisteredHostContext *rhc; | ||
1178 | int skip_focc; | ||
1179 | |||
1180 | rhc = GNUNET_malloc (sizeof (struct RegisteredHostContext)); | ||
1181 | rhc->type = CLOSURE_TYPE_RHC; | ||
1182 | if (NULL != route_to_peer2_host) | ||
1183 | rhc->reg_host = GST_host_list[route_to_peer2_host->dest]; | ||
1184 | else | ||
1185 | rhc->reg_host = GST_host_list[GST_context->host_id]; | ||
1186 | rhc->host = GST_host_list[route_to_peer1_host->dest]; | ||
1187 | GNUNET_assert (NULL != rhc->reg_host); | ||
1188 | GNUNET_assert (NULL != rhc->host); | ||
1189 | rhc->gateway = peer->details.remote.slave; | ||
1190 | rhc->gateway2 = | ||
1191 | (NULL == | ||
1192 | route_to_peer2_host) ? NULL : | ||
1193 | GST_slave_list[route_to_peer2_host->dest]; | ||
1194 | rhc->state = RHC_INIT; | ||
1195 | GNUNET_SERVER_client_keep (client); | ||
1196 | rhc->client = client; | ||
1197 | hash = hash_hosts (rhc->reg_host, rhc->host); | ||
1198 | skip_focc = GNUNET_NO; | ||
1199 | if ((GNUNET_NO == | ||
1200 | GNUNET_CONTAINER_multihashmap_contains (peer->details. | ||
1201 | remote.slave->reghost_map, | ||
1202 | &hash)) || | ||
1203 | (GNUNET_SYSERR != | ||
1204 | GNUNET_CONTAINER_multihashmap_get_multiple (peer->details.remote. | ||
1205 | slave->reghost_map, | ||
1206 | &hash, | ||
1207 | reghost_match_iterator, | ||
1208 | &rhc))) | ||
1209 | { | ||
1210 | /* create and add a new registerd host context */ | ||
1211 | /* add the focc to its queue */ | ||
1212 | GNUNET_CONTAINER_multihashmap_put (peer->details.remote. | ||
1213 | slave->reghost_map, &hash, rhc, | ||
1214 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
1215 | GNUNET_assert (NULL != GST_host_list[peer2_host_id]); | ||
1216 | GST_queue_host_registration (peer->details.remote.slave, | ||
1217 | registeredhost_registration_completion, | ||
1218 | rhc, GST_host_list[peer2_host_id]); | ||
1219 | } | ||
1220 | else | ||
1221 | { | ||
1222 | /* rhc is now set to the existing one from the hash map by | ||
1223 | * reghost_match_iterator() */ | ||
1224 | /* if queue is empty then ignore creating focc and proceed with | ||
1225 | * normal forwarding */ | ||
1226 | if (RHC_OL_CONNECT == rhc->state) | ||
1227 | skip_focc = GNUNET_YES; | ||
1228 | } | ||
1229 | if (GNUNET_NO == skip_focc) | ||
1230 | { | ||
1231 | struct ForwardedOverlayConnectContext *focc; | ||
1232 | |||
1233 | focc = GNUNET_malloc (sizeof (struct ForwardedOverlayConnectContext)); | ||
1234 | focc->peer1 = p1; | ||
1235 | focc->peer2 = p2; | ||
1236 | focc->peer2_host_id = peer2_host_id; | ||
1237 | focc->orig_msg = GNUNET_copy_message (message); | ||
1238 | focc->operation_id = operation_id; | ||
1239 | GNUNET_CONTAINER_DLL_insert_tail (rhc->focc_dll_head, | ||
1240 | rhc->focc_dll_tail, focc); | ||
1241 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1242 | return; | ||
1243 | } | ||
1244 | } | ||
1245 | } | ||
1246 | fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext)); | ||
1247 | GNUNET_SERVER_client_keep (client); | ||
1248 | fopc->client = client; | ||
1249 | fopc->operation_id = operation_id; | ||
1250 | fopc->type = OP_OVERLAY_CONNECT; | ||
1251 | fopc->opc = | ||
1252 | GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote. | ||
1253 | slave->controller, operation_id, | ||
1254 | message, | ||
1255 | &GST_forwarded_operation_reply_relay, | ||
1256 | fopc); | ||
1257 | fopc->timeout_task = | ||
1258 | GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, | ||
1259 | fopc); | ||
1260 | GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); | ||
1261 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1432 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
1262 | return; | 1433 | return; |
1263 | } | 1434 | } |
1264 | |||
1265 | struct Neighbour *p2n; | ||
1266 | p2n = NULL; | 1435 | p2n = NULL; |
1267 | p2c = NULL; | 1436 | occ = GNUNET_malloc (sizeof (struct OverlayConnectContext)); |
1437 | occ->type = OCC_TYPE_LOCAL; | ||
1438 | peer2_host_id = ntohl (msg->peer2_host_id); | ||
1268 | if ((p2 >= GST_peer_list_size) || (NULL == GST_peer_list[p2])) | 1439 | if ((p2 >= GST_peer_list_size) || (NULL == GST_peer_list[p2])) |
1269 | { | 1440 | { |
1270 | if (NULL == (p2n = GST_get_neighbour (peer2_host_id))) | 1441 | if (NULL == (p2n = GST_get_neighbour (peer2_host_id))) |
@@ -1274,15 +1445,17 @@ GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client, | |||
1274 | "0x%llx: Peer %u's host not in our neighbours list\n", | 1445 | "0x%llx: Peer %u's host not in our neighbours list\n", |
1275 | operation_id, p2); | 1446 | operation_id, p2); |
1276 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1447 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
1448 | GNUNET_free (occ); | ||
1277 | return; | 1449 | return; |
1278 | } | 1450 | } |
1451 | occ->type = OCC_TYPE_REMOTE_LATERAL; | ||
1452 | occ->p2ctx.remote.p2n = p2n; | ||
1279 | } | 1453 | } |
1280 | else | 1454 | else if (GNUNET_YES == GST_peer_list[p2]->is_remote) |
1281 | { | 1455 | { |
1282 | if (GNUNET_YES == GST_peer_list[p2]->is_remote) | 1456 | occ->type = OCC_TYPE_REMOTE_SLAVE; |
1283 | p2c = GST_peer_list[p2]->details.remote.slave->controller; | 1457 | occ->p2ctx.remote.p2c = GST_peer_list[p2]->details.remote.slave->controller; |
1284 | } | 1458 | } |
1285 | occ = GNUNET_malloc (sizeof (struct OverlayConnectContext)); | ||
1286 | GNUNET_CONTAINER_DLL_insert_tail (occq_head, occq_tail, occ); | 1459 | GNUNET_CONTAINER_DLL_insert_tail (occq_head, occq_tail, occ); |
1287 | GNUNET_SERVER_client_keep (client); | 1460 | GNUNET_SERVER_client_keep (client); |
1288 | occ->client = client; | 1461 | occ->client = client; |
@@ -1290,39 +1463,36 @@ GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client, | |||
1290 | GST_peer_list[p1]->reference_cnt++; | 1463 | GST_peer_list[p1]->reference_cnt++; |
1291 | occ->peer = GST_peer_list[p1]; | 1464 | occ->peer = GST_peer_list[p1]; |
1292 | occ->op_id = operation_id; | 1465 | occ->op_id = operation_id; |
1293 | occ->p2n = p2n; | ||
1294 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == occ->timeout_task); | 1466 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == occ->timeout_task); |
1295 | occ->timeout_task = | 1467 | occ->timeout_task = |
1296 | GNUNET_SCHEDULER_add_delayed (GST_timeout, &timeout_overlay_connect, occ); | 1468 | GNUNET_SCHEDULER_add_delayed (GST_timeout, &timeout_overlay_connect, occ); |
1297 | /* Get the identity of the second peer */ | 1469 | switch (occ->type) |
1298 | if (NULL != p2n) | ||
1299 | { | 1470 | { |
1471 | case OCC_TYPE_REMOTE_LATERAL: | ||
1300 | GNUNET_asprintf (&occ->emsg, | 1472 | GNUNET_asprintf (&occ->emsg, |
1301 | "0x%llx: Timeout while acquiring connection to peer %u's " | 1473 | "0x%llx: Timeout while acquiring connection to peer %u's " |
1302 | "host: %u\n", occ->op_id, occ->other_peer_id, peer2_host_id); | 1474 | "host: %u\n", occ->op_id, occ->other_peer_id, peer2_host_id); |
1303 | occ->p2_ncn = GST_neighbour_get_connection (p2n, &p2_controller_connect_cb, | 1475 | occ->p2ctx.remote.ncn = |
1304 | occ); | 1476 | GST_neighbour_get_connection (p2n, &p2_controller_connect_cb, occ); |
1305 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1477 | break; |
1306 | return; | 1478 | case OCC_TYPE_REMOTE_SLAVE: |
1307 | } | 1479 | p2_controller_connect_cb (occ, occ->p2ctx.remote.p2c); |
1308 | if (NULL != p2c) | 1480 | break; |
1309 | { | 1481 | case OCC_TYPE_LOCAL: |
1310 | p2_controller_connect_cb (occ, p2c); | 1482 | peer2 = GST_peer_list[occ->other_peer_id]; |
1311 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1483 | peer2->reference_cnt++; |
1312 | return; | 1484 | GNUNET_TESTING_peer_get_identity (peer2->details.local.peer, |
1485 | &occ->other_peer_identity); | ||
1486 | GNUNET_asprintf (&occ->emsg, | ||
1487 | "0x%llx: Timeout while connecting to CORE of peer with " | ||
1488 | "id: %u", occ->op_id, occ->peer->id); | ||
1489 | occ->cgh_ch = | ||
1490 | GST_cache_get_handle_core (occ->peer->id, occ->peer->details.local.cfg, | ||
1491 | occ_cache_get_handle_core_cb, occ, | ||
1492 | &occ->other_peer_identity, | ||
1493 | &overlay_connect_notify, occ); | ||
1494 | break; | ||
1313 | } | 1495 | } |
1314 | GST_peer_list[occ->other_peer_id]->reference_cnt++; | ||
1315 | GNUNET_TESTING_peer_get_identity (GST_peer_list[occ->other_peer_id]-> | ||
1316 | details.local.peer, | ||
1317 | &occ->other_peer_identity); | ||
1318 | GNUNET_asprintf (&occ->emsg, | ||
1319 | "0x%llx: Timeout while connecting to CORE of peer with " | ||
1320 | "id: %u", occ->op_id, occ->peer->id); | ||
1321 | occ->cgh_ch = | ||
1322 | GST_cache_get_handle_core (occ->peer->id, occ->peer->details.local.cfg, | ||
1323 | occ_cache_get_handle_core_cb, occ, | ||
1324 | &occ->other_peer_identity, | ||
1325 | &overlay_connect_notify, occ); | ||
1326 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1496 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
1327 | } | 1497 | } |
1328 | 1498 | ||