From 97c6db0188f20f05fcb657d448a213b05df76bde Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Wed, 1 Aug 2012 15:03:57 +0000 Subject: [PATCH] improved overlay connect handling --- src/testbed/gnunet-service-testbed.c | 182 ++++++++++++++++++++++----- src/testbed/testbed_api_peers.c | 78 ++++++++---- 2 files changed, 205 insertions(+), 55 deletions(-) diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index 31112ce00..169a9e6c7 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c @@ -295,50 +295,82 @@ struct Peer }; +/** + * State information for overlay connect context + */ +enum OCCState + { + /** + * Initial state + */ + OCC_STATE_INIT, + + /** + * Peer 1 has connected to peer0 + */ + OCC_STATE_PEER0_SUCCESS, + + /** + * Peer 2 has connected to peer1 + */ + OCC_STATE_PEER1_SUCCESS, + + }; + + /** * Context information for connecting 2 peers in overlay */ struct OverlayConnectContext { /** - * peer 1 + * peer 1 and peer2 */ - struct Peer *peer1; + struct Peer * peers[2]; /** - * peer 2 + * Transport handle of peers */ - struct Peer *peer2; - + struct GNUNET_TRANSPORT_Handle *peers_transport[2]; + /** - * Transport handle of peer1 + * HELLO of peers */ - struct GNUNET_TRANSPORT_Handle *peer1_transport; + struct GNUNET_MessageHeader *peers_hello[2]; /** - * Transport handle of peer2 + * Get hello handle for peers */ - struct GNUNET_TRANSPORT_Handle *peer2_transport; + struct GNUNET_TRANSPORT_GetHelloHandle *peers_ghh[2]; /** - * HELLO of peer1 + * The peer identity of peers */ - struct GNUNET_MessageHeader *peer1_hello; - + struct GNUNET_PeerIdentity peers_identity[2]; + /** - * HELLO of peer2 + * State information for determining whose HELLOs have been successfully + * exchanged */ - struct GNUNET_MessageHeader *peer2_hello; + enum OCCState state; +}; + + +/** + * Wrapper around OverlayConnectContext + */ +struct OverlayConnectContextWrapper +{ /** - * Get hello handle for peer1 + * The overlay connect context */ - struct GNUNET_TRANSPORT_GetHelloHandle *peer1_ghh; + struct OverlayConnectContext *occ; /** - * Get hello handle for peer2 + * The peer number in reference; should be 0 or 1 */ - struct GNUNET_TRANSPORT_GetHelloHandle *peer2_ghh; + unsigned int peer; }; @@ -1495,19 +1527,97 @@ handle_peer_get_config (void *cls, } +/** + * Task to be executed when HELLO has been sent + * + * @param cls overlay connect context wrapper + * @param tc the task context from scheduler + */ +static void +overlay_connect_finalize (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct OverlayConnectContextWrapper *occw = cls; + struct OverlayConnectContext *occ; + unsigned int peer; + + peer = occw->peer; + occ = occw->occ; + GNUNET_free (occw); + GNUNET_free (occ->peers_hello[peer ^ 1]); +} + + +/** + * Exchanges HELLO of peers among them + * + * @param occ the OverlayConnectContext to look into for HELLO messages + */ +static void +exchange_hellos (struct OverlayConnectContext *occ) +{ + struct OverlayConnectContextWrapper *occw; + unsigned int peer; + + GNUNET_assert (NULL != occ->peers_hello[0]); + GNUNET_assert (NULL != occ->peers_hello[1]); + LOG_DEBUG ("Exchanging hellos\n"); + for (peer = 0; peer < 2; peer++) + { + occw = GNUNET_malloc (sizeof (struct OverlayConnectContextWrapper)); + occw->occ = occ; + occw->peer = peer; + GNUNET_TRANSPORT_offer_hello (occ->peers_transport[peer], + occ->peers_hello[peer ^ 1], + &overlay_connect_finalize, occw); + } +} + /** * Function called whenever there is an update to the - * HELLO of this peer. + * HELLO of peers in the OverlayConnectClosure * * @param cls closure * @param hello our updated HELLO */ static void -hello_update_cb (void *cls, - const struct GNUNET_MessageHeader *hello) +hello_update_cb (void *cls, const struct GNUNET_MessageHeader *hello) { - GNUNET_break(0); + struct OverlayConnectContextWrapper *occw = cls; + struct OverlayConnectContext *occ; + unsigned int peer; + uint16_t msize; + + msize = ntohs (hello->size); + peer = occw->peer; + GNUNET_assert (peer <= 1); + occ = occw->occ; + occ->peers_hello[peer] = GNUNET_malloc (msize); + memcpy (occ->peers_hello[peer], hello, msize); + GNUNET_TRANSPORT_get_hello_cancel (occ->peers_ghh[peer]); + occ->peers_ghh[peer] = NULL; + if (NULL != occ->peers_hello[peer ^ 1]) + exchange_hellos (occ); +} + + +/** + * Function called to notify transport users that another + * peer connected to us. + * + * @param cls closure + * @param peer the peer that connected + * @param ats performance data + * @param ats_count number of entries in ats (excluding 0-termination) + */ +static void +overlay_connect_notify (void *cls, + const struct GNUNET_PeerIdentity * peer, + const struct GNUNET_ATS_Information * ats, + uint32_t ats_count) +{ + GNUNET_break (0); /* To be implemented */ } @@ -1525,6 +1635,8 @@ handle_overlay_connect (void *cls, { const struct GNUNET_TESTBED_OverlayConnectMessage *msg; struct OverlayConnectContext *occ; + struct OverlayConnectContextWrapper *occw; + unsigned int peer; uint32_t p1; uint32_t p2; @@ -1536,14 +1648,24 @@ handle_overlay_connect (void *cls, GNUNET_assert (p2 < peer_list_size); GNUNET_assert (NULL != peer_list[p2]); occ = GNUNET_malloc (sizeof (struct OverlayConnectContext)); - occ->peer1 = peer_list[p1]; - occ->peer2 = peer_list[p2]; - occ->peer1_transport = GNUNET_TRANSPORT_connect (occ->peer1->cfg, NULL, occ, - NULL, NULL, NULL); - occ->peer2_transport = GNUNET_TRANSPORT_connect (occ->peer2->cfg, NULL, occ, - NULL, NULL, NULL); - occ->peer1_ghh = GNUNET_TRANSPORT_get_hello (occ->peer1_transport, &hello_update_cb, occ); - occ->peer2_ghh = GNUNET_TRANSPORT_get_hello (occ->peer2_transport, &hello_update_cb, occ); + occ->state = OCC_STATE_INIT; + occ->peers[0] = peer_list[p1]; + occ->peers[1] = peer_list[p2]; + for (peer = 0; peer < 2; peer++) + { + occw = GNUNET_malloc (sizeof (struct OverlayConnectContextWrapper)); + occw->occ = occ; + occw->peer = peer; + GNUNET_TESTING_peer_get_identity (occ->peers[peer]->peer, + &occ->peers_identity[peer]); + occ->peers_transport[peer] = + GNUNET_TRANSPORT_connect (occ->peers[peer]->cfg, + &occ->peers_identity[peer], occw, NULL, + &overlay_connect_notify, NULL); + occ->peers_ghh[peer] = + GNUNET_TRANSPORT_get_hello (occ->peers_transport[peer], + &hello_update_cb, occw); + } } diff --git a/src/testbed/testbed_api_peers.c b/src/testbed/testbed_api_peers.c index 69c3aaac8..e6d709e0b 100644 --- a/src/testbed/testbed_api_peers.c +++ b/src/testbed/testbed_api_peers.c @@ -95,7 +95,7 @@ oprelease_peer_create (void *cls) /** - * Function to called when a peer destroy operation is ready + * Function called when a peer destroy operation is ready * * @param cls the closure from GNUNET_TESTBED_operation_create_() */ @@ -138,7 +138,7 @@ oprelease_peer_destroy (void *cls) /** - * Function to called when a peer start operation is ready + * Function called when a peer start operation is ready * * @param cls the closure from GNUNET_TESTBED_operation_create_() */ @@ -181,7 +181,7 @@ oprelease_peer_start (void *cls) /** - * Function to called when a peer stop operation is ready + * Function called when a peer stop operation is ready * * @param cls the closure from GNUNET_TESTBED_operation_create_() */ @@ -223,7 +223,7 @@ oprelease_peer_stop (void *cls) /** - * Function to called when a peer get information operation is ready + * Function called when a peer get information operation is ready * * @param cls the closure from GNUNET_TESTBED_operation_create_() */ @@ -286,6 +286,44 @@ oprelease_peer_getinfo (void *cls) } +/** + * Function called when a overlay connect operation is ready + * + * @param cls the closure from GNUNET_TESTBED_operation_create_() + */ +static void +opstart_overlay_connect (void *cls) +{ + struct OperationContext *opc = cls; + struct GNUNET_TESTBED_OverlayConnectMessage *msg; + struct OverlayConnectData *data; + + opc->state = OPC_STATE_STARTED; + data = opc->data; + GNUNET_assert (NULL != data); + msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)); + msg->header.size = htons (sizeof + (struct GNUNET_TESTBED_OverlayConnectMessage)); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_OLCONNECT); + msg->peer1 = htonl (data->p1->unique_id); + msg->peer2 = htonl (data->p2->unique_id); + msg->operation_id = GNUNET_htonll (opc->id); + GNUNET_CONTAINER_DLL_insert_tail (opc->c->ocq_head, opc->c->ocq_tail, opc); + GNUNET_TESTBED_queue_message_ (opc->c, &msg->header); +} + + +/** + * Callback which will be called when overlay connect operation is released + * + * @param cls the closure from GNUNET_TESTBED_operation_create_() + */ +static void +oprelease_overlay_connect (void *cls) +{ + GNUNET_break (0); +} + /** * Lookup a peer by ID. @@ -578,32 +616,22 @@ GNUNET_TESTBED_overlay_connect (void *op_cls, struct GNUNET_TESTBED_Peer *p1, struct GNUNET_TESTBED_Peer *p2) { - struct GNUNET_TESTBED_Operation *op; + struct OperationContext *opc; struct OverlayConnectData *data; - struct GNUNET_TESTBED_OverlayConnectMessage *msg; - + GNUNET_assert ((PS_STARTED == p1->state) && (PS_STARTED == p2->state)); GNUNET_assert (p1->controller == p2->controller); data = GNUNET_malloc (sizeof (struct OverlayConnectData)); data->p1 = p1; - data->p2 = p2; - op = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Operation)); - op->controller = p1->controller; - op->operation_id = op->controller->operation_counter++; - op->type = OP_OVERLAY_CONNECT; - op->data = data; - msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)); - msg->header.size = htons (sizeof (struct - GNUNET_TESTBED_OverlayConnectMessage)); - msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_OLCONNECT); - msg->peer1 = htonl (p1->unique_id); - msg->peer2 = htonl (p2->unique_id); - msg->operation_id = GNUNET_htonll (op->operation_id); - GNUNET_CONTAINER_DLL_insert_tail (op->controller->op_head, - op->controller->op_tail, op); - GNUNET_TESTBED_queue_message_ (op->controller, - (struct GNUNET_MessageHeader *) msg); - return NULL; + data->p2 = p2; + opc = GNUNET_malloc (sizeof (struct OperationContext)); + opc->data = data; + opc->c = p1->controller; + opc->id = opc->c->operation_counter++; + opc->type = OP_OVERLAY_CONNECT; + opc->op = GNUNET_TESTBED_operation_create_ (opc, &opstart_overlay_connect, + &oprelease_overlay_connect); + return opc->op; } -- 2.25.1