From 2d8f5e4d85f96c131948c061d2375efe9e783f87 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Thu, 31 Jan 2013 20:02:50 +0000 Subject: [PATCH] - fixes and implements caching core handles --- src/testbed/gnunet-service-testbed_hc.c | 86 +++++------ src/testbed/gnunet-service-testbed_oc.c | 196 ++++++++++-------------- 2 files changed, 116 insertions(+), 166 deletions(-) diff --git a/src/testbed/gnunet-service-testbed_hc.c b/src/testbed/gnunet-service-testbed_hc.c index 9d50ae257..6a75bbc79 100644 --- a/src/testbed/gnunet-service-testbed_hc.c +++ b/src/testbed/gnunet-service-testbed_hc.c @@ -296,25 +296,6 @@ cache_lookup (const struct GNUNET_HashCode *key) } -static struct CacheEntry * -cache_lookup_handles (const struct GNUNET_HashCode *pid, - struct GNUNET_TRANSPORT_Handle **th, - struct GNUNET_CORE_Handle **ch) -{ - struct CacheEntry *entry; - - GNUNET_assert ((NULL != th) || (NULL != ch)); - entry = cache_lookup (pid); - if (NULL == entry) - return NULL; - if ((NULL != entry->transport_handle_) && (NULL != th)) - *th = entry->transport_handle_; - if ((NULL != entry->core_handle) && (NULL != ch)) - *ch = entry->core_handle; - return entry; -} - - static void cache_remove (struct CacheEntry *entry) { @@ -418,6 +399,7 @@ call_cgh_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_CONTAINER_DLL_insert_tail (entry->cgh_qhead, entry->cgh_qtail, cgh); if (NULL != cgh2) entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry); + LOG_DEBUG ("Calling notify for handle type %u\n", cgh->type); cgh->cb (cgh->cb_cls, entry->core_handle, entry->transport_handle_, entry->peer_identity); } @@ -437,26 +419,36 @@ peer_connect_notify_cb (void *cls, { struct CacheEntry *entry = cls; struct ConnectNotifyContext *ctxt; + struct ConnectNotifyContext *ctxt2; GST_cache_peer_connect_notify cb; void *cb_cls; - for (ctxt=entry->nctxt_qhead; NULL != ctxt; ctxt=ctxt->next) + for (ctxt=entry->nctxt_qhead; NULL != ctxt;) { GNUNET_assert (NULL != ctxt->cgh); if (type != ctxt->cgh->type) + { + ctxt = ctxt->next; continue; - if (0 == memcmp (ctxt->target, peer, sizeof (struct GNUNET_PeerIdentity))) - break; + } + if (0 != memcmp (ctxt->target, peer, sizeof (struct GNUNET_PeerIdentity))) + { + ctxt = ctxt->next; + continue; + } + cb = ctxt->cb; + cb_cls = ctxt->cb_cls; + ctxt->cgh->nctxt = NULL; + ctxt2 = ctxt->next; + GNUNET_CONTAINER_DLL_remove (entry->nctxt_qhead, entry->nctxt_qtail, ctxt); + GNUNET_free (ctxt); + ctxt = ctxt2; + cb (cb_cls, peer); } if (NULL == ctxt) return; - cb = ctxt->cb; - cb_cls = ctxt->cb_cls; - ctxt->cgh->nctxt = NULL; - GNUNET_CONTAINER_DLL_remove (entry->nctxt_qhead, entry->nctxt_qtail, ctxt); - GNUNET_free (ctxt); - cb (cb_cls, peer); + } @@ -592,11 +584,6 @@ opstart_get_handle_core (void *cls) NULL, /* outbound notify */ GNUNET_NO, no_handlers); - if (NULL == entry->core_handle) - { - GNUNET_break (0); - return; - } //GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == entry->notify_task); } @@ -632,31 +619,28 @@ cache_get_handle (unsigned int peer_id, GNUNET_assert (0 != cgh->type); GNUNET_CRYPTO_hash (&peer_id, sizeof (peer_id), &key); handle = NULL; - entry = NULL; - switch (cgh->type) - { - case CGT_TRANSPORT_HANDLE: - entry = cache_lookup_handles (&key, (struct GNUNET_TRANSPORT_Handle **) - &handle, NULL); - if (NULL != handle) - LOG_DEBUG ("Found TRANSPORT handle in cache for peer %u\n", entry->peer_id); - break; - case CGT_CORE_HANDLE: - entry = cache_lookup_handles (&key, NULL, - (struct GNUNET_CORE_Handle **) &handle); - if (NULL != handle) - LOG_DEBUG ("Found CORE handle in cache for peer %u\n", entry->peer_id); - break; - } - if (NULL != handle) + entry = cache_lookup (&key); + if (NULL != entry) { - GNUNET_assert (NULL != entry); if (0 == entry->demand) { GNUNET_assert (0 < lru_cache_size); GNUNET_CONTAINER_DLL_remove (lru_cache_head, lru_cache_tail, entry); lru_cache_size--; } + switch (cgh->type) + { + case CGT_TRANSPORT_HANDLE: + handle = entry->transport_handle_; + if (NULL != handle) + LOG_DEBUG ("Found TRANSPORT handle in cache for peer %u\n", entry->peer_id); + break; + case CGT_CORE_HANDLE: + handle = entry->core_handle; + if (NULL != handle) + LOG_DEBUG ("Found CORE handle in cache for peer %u\n", entry->peer_id); + break; + } } if (NULL == entry) entry = add_entry (&key, peer_id); diff --git a/src/testbed/gnunet-service-testbed_oc.c b/src/testbed/gnunet-service-testbed_oc.c index de6e53031..ddc31e5e2 100644 --- a/src/testbed/gnunet-service-testbed_oc.c +++ b/src/testbed/gnunet-service-testbed_oc.c @@ -117,7 +117,12 @@ struct OverlayConnectContext /** * Core handles of the first peer; used to notify when second peer connects to it */ - struct GNUNET_CORE_Handle *ch; + //struct GNUNET_CORE_Handle *ch_; + + /** + * The GetCacheHandle for the p1th transport handle + */ + struct GSTCacheGetHandle *cgh_ch; /** * HELLO of the other peer @@ -144,11 +149,6 @@ struct OverlayConnectContext */ struct OperationContext *opc; - /** - * The local operation we create for this overlay connection - */ - struct GNUNET_TESTBED_Operation *lop; - /** * Controller of peer 2; NULL if the peer is local */ @@ -393,11 +393,6 @@ GST_process_next_focc (struct RegisteredHostContext *rhc) static void cleanup_occ (struct OverlayConnectContext *occ) { - if (NULL != occ->lop) - { - GNUNET_TESTBED_operation_release_ (occ->lop); - return; - } LOG_DEBUG ("0x%llx: Cleaning up occ\n", occ->op_id); GNUNET_free_non_null (occ->emsg); GNUNET_free_non_null (occ->hello); @@ -410,9 +405,9 @@ cleanup_occ (struct OverlayConnectContext *occ) GNUNET_SCHEDULER_cancel (occ->cleanup_task); if (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task) GNUNET_SCHEDULER_cancel (occ->timeout_task); - if (NULL != occ->ch) + if (NULL != occ->cgh_ch) { - GNUNET_CORE_disconnect (occ->ch); + GST_cache_get_handle_done (occ->cgh_ch); occ->peer->reference_cnt--; } if (NULL != occ->ghh) @@ -441,7 +436,6 @@ cleanup_occ (struct OverlayConnectContext *occ) (0 == GST_peer_list[occ->other_peer_id]->reference_cnt)) GST_destroy_peer (GST_peer_list[occ->other_peer_id]); GNUNET_CONTAINER_DLL_remove (occq_head, occq_tail, occ); - GNUNET_assert (NULL == occ->lop); GNUNET_free (occ); } @@ -484,22 +478,37 @@ timeout_overlay_connect (void *cls, } +static void +send_overlay_connect_success_msg (struct OverlayConnectContext *occ) +{ + struct GNUNET_TESTBED_ConnectionEventMessage *msg; + + LOG_DEBUG ("0x%llx: Peers connected - Sending overlay connect success\n", + occ->op_id); + msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ConnectionEventMessage)); + msg->header.size = + htons (sizeof (struct GNUNET_TESTBED_ConnectionEventMessage)); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONNECT_EVENT); + msg->event_type = htonl (GNUNET_TESTBED_ET_CONNECT); + msg->peer1 = htonl (occ->peer_id); + msg->peer2 = htonl (occ->other_peer_id); + msg->operation_id = GNUNET_htonll (occ->op_id); + GST_queue_message (occ->client, &msg->header); +} + + /** * Function called to notify transport users that another * peer connected to us. * * @param cls closure * @param new_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 *new_peer, - const struct GNUNET_ATS_Information *ats, - unsigned int ats_count) +overlay_connect_notify (void *cls, + const struct GNUNET_PeerIdentity *new_peer) { struct OverlayConnectContext *occ = cls; - struct GNUNET_TESTBED_ConnectionEventMessage *msg; char *new_peer_str; char *other_peer_str; @@ -537,19 +546,12 @@ overlay_connect_notify (void *cls, const struct GNUNET_PeerIdentity *new_peer, GNUNET_SCHEDULER_cancel (occ->tcc.task); occ->tcc.task = GNUNET_SCHEDULER_NO_TASK; } + GST_cache_get_handle_done (occ->cgh_ch); + occ->peer->reference_cnt--; + occ->cgh_ch = NULL; GNUNET_free_non_null (occ->emsg); occ->emsg = NULL; - LOG_DEBUG ("0x%llx: Peers connected - Sending overlay connect success\n", - occ->op_id); - msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ConnectionEventMessage)); - msg->header.size = - htons (sizeof (struct GNUNET_TESTBED_ConnectionEventMessage)); - msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONNECT_EVENT); - msg->event_type = htonl (GNUNET_TESTBED_ET_CONNECT); - msg->peer1 = htonl (occ->peer_id); - msg->peer2 = htonl (occ->other_peer_id); - msg->operation_id = GNUNET_htonll (occ->op_id); - GST_queue_message (occ->client, &msg->header); + send_overlay_connect_success_msg (occ); occ->cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup_occ, occ); //cleanup_occ (occ); } @@ -846,32 +848,41 @@ hello_update_cb (void *cls, const struct GNUNET_MessageHeader *hello) /** - * Function called after GNUNET_CORE_connect has succeeded (or failed - * for good). Note that the private key of the peer is intentionally - * not exposed here; if you need it, your process should try to read - * the private key file directly (which should work if you are - * authorized...). + * Callback from cache with needed handles set * - * @param cls closure - * @param server handle to the server, NULL if we failed - * @param my_identity ID of this peer, NULL if we failed + * @param cls the closure passed to GST_cache_get_handle_transport() + * @param ch the handle to CORE. Can be NULL if it is not requested + * @param th the handle to TRANSPORT. Can be NULL if it is not requested + * @param my_identity the identity of our peer */ -static void -core_startup_cb (void *cls, struct GNUNET_CORE_Handle *server, - const struct GNUNET_PeerIdentity *my_identity) +static void +occ_cache_get_handle_core_cb (void *cls, struct GNUNET_CORE_Handle *ch, + struct GNUNET_TRANSPORT_Handle *th, + const struct GNUNET_PeerIdentity *my_identity) { struct OverlayConnectContext *occ = cls; const struct GNUNET_MessageHeader *hello; + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task); GNUNET_free_non_null (occ->emsg); (void) GNUNET_asprintf (&occ->emsg, "0x%llx: Failed to connect to CORE of peer with" "id: %u", occ->op_id, occ->peer_id); - if ((NULL == server) || (NULL == my_identity)) + if ((NULL == ch) || (NULL == my_identity)) goto error_return; GNUNET_free (occ->emsg); - occ->ch = server; + //occ->ch_ = ch; occ->emsg = NULL; + if (GNUNET_YES == + GNUNET_CORE_is_peer_connected_sync (ch, &occ->other_peer_identity)) + { + LOG_DEBUG ("0x%llx: Target peer already connected\n", occ->op_id); + GNUNET_SCHEDULER_cancel (occ->timeout_task); + occ->timeout_task = GNUNET_SCHEDULER_NO_TASK; + send_overlay_connect_success_msg (occ); + occ->cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup_occ, occ); + return; + } memcpy (&occ->peer_identity, my_identity, sizeof (struct GNUNET_PeerIdentity)); LOG_DEBUG ("0x%llx: Acquiring HELLO of peer %s\n", occ->op_id, @@ -909,58 +920,6 @@ error_return: } -/** - * Callback which will be called when overlay connect operation is started - * - * @param cls the closure from GNUNET_TESTBED_operation_create_() - */ -static void -opstart_overlay_connect (void *cls) -{ - struct OverlayConnectContext *occ = cls; - - const struct GNUNET_CORE_MessageHandler no_handlers[] = { - {NULL, 0, 0} - }; - - GNUNET_assert (NULL != occ->lop); - /* Connect to the core of 1st peer and wait for the 2nd peer to connect */ - occ->emsg = GNUNET_strdup ("Timeout while connecting to CORE"); - GNUNET_asprintf (&occ->emsg, - "0x%llx: Timeout while connecting to CORE of peer with " - "id: %u", occ->op_id, occ->peer_id); - occ->peer->reference_cnt++; - occ->ch = - GNUNET_CORE_connect (occ->peer->details.local.cfg, occ, &core_startup_cb, - &overlay_connect_notify, NULL, NULL, GNUNET_NO, NULL, - GNUNET_NO, no_handlers); - if (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task) - GNUNET_SCHEDULER_cancel (occ->timeout_task); - if (NULL == occ->ch) - occ->timeout_task = - GNUNET_SCHEDULER_add_now (&timeout_overlay_connect, occ); - else - occ->timeout_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_overlay_connect, occ); -} - - -/** - * 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) -{ - struct OverlayConnectContext *occ = cls; - - GNUNET_assert (NULL != occ->lop); - occ->lop = NULL; - cleanup_occ (occ); -} - - /** * Callback to be called when forwarded get peer config operation as part of * overlay connect is successfull. Connection to Peer 1's core is made and is @@ -976,6 +935,7 @@ overlay_connect_get_config (void *cls, const struct GNUNET_MessageHeader *msg) const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *cmsg; occ->opc = NULL; + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != occ->timeout_task); if (GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONFIGURATION != ntohs (msg->type)) { GNUNET_SCHEDULER_cancel (occ->timeout_task); @@ -987,15 +947,17 @@ overlay_connect_get_config (void *cls, const struct GNUNET_MessageHeader *msg) memcpy (&occ->other_peer_identity, &cmsg->peer_identity, sizeof (struct GNUNET_PeerIdentity)); GNUNET_free_non_null (occ->emsg); - occ->emsg = NULL; - GNUNET_assert (NULL == occ->lop); - occ->lop = - GNUNET_TESTBED_operation_create_ (occ, &opstart_overlay_connect, - &oprelease_overlay_connect); - /* This operation needs in total 2 connections (one to core and one to - * transport) */ - GNUNET_TESTBED_operation_queue_insert2_ (GST_opq_openfds, occ->lop, 2); - GNUNET_TESTBED_operation_begin_wait_ (occ->lop); + GNUNET_asprintf (&occ->emsg, + "0x%llx: Timeout while connecting to CORE of peer with " + "id: %u", occ->op_id, occ->peer_id); + occ->peer->reference_cnt++; + occ->cgh_ch = GST_cache_get_handle_core (occ->peer_id, + occ->peer->details.local.cfg, + occ_cache_get_handle_core_cb, + occ, + &occ->other_peer_identity, + &overlay_connect_notify, + occ); return; } @@ -1274,6 +1236,9 @@ GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client, occ->peer = GST_peer_list[p1]; occ->op_id = GNUNET_ntohll (msg->operation_id); occ->peer2_controller = peer2_controller; + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == occ->timeout_task); + occ->timeout_task = + GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_overlay_connect, occ); /* Get the identity of the second peer */ if (NULL != occ->peer2_controller) { @@ -1293,22 +1258,23 @@ GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_asprintf (&occ->emsg, "0x%llx: Timeout while getting peer identity of peer " "with id: %u", occ->op_id, occ->other_peer_id); - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == occ->timeout_task); - occ->timeout_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_overlay_connect, occ); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } GNUNET_TESTING_peer_get_identity (GST_peer_list[occ->other_peer_id]-> details.local.peer, &occ->other_peer_identity); - occ->lop = - GNUNET_TESTBED_operation_create_ (occ, &opstart_overlay_connect, - &oprelease_overlay_connect); - /* This operation needs in total 2 connections (one to core and one to - * transport) */ - GNUNET_TESTBED_operation_queue_insert2_ (GST_opq_openfds, occ->lop, 2); - GNUNET_TESTBED_operation_begin_wait_ (occ->lop); + GNUNET_asprintf (&occ->emsg, + "0x%llx: Timeout while connecting to CORE of peer with " + "id: %u", occ->op_id, occ->peer_id); + occ->peer->reference_cnt++; + occ->cgh_ch = GST_cache_get_handle_core (occ->peer_id, + occ->peer->details.local.cfg, + occ_cache_get_handle_core_cb, + occ, + &occ->other_peer_identity, + &overlay_connect_notify, + occ); GNUNET_SERVER_receive_done (client, GNUNET_OK); } -- 2.25.1