From 27a6cee72d7c479853acbeed0047534fd4566deb Mon Sep 17 00:00:00 2001 From: "Nathan S. Evans" Date: Wed, 16 Feb 2011 16:24:32 +0000 Subject: [PATCH] remove double connect notify, add is connected optimization for peer iterate call --- src/core/core_api.c | 16 +------ src/core/core_api_iterate_peers.c | 69 +++++++++++++++++++++++++++++-- src/core/gnunet-service-core.c | 38 ++++++++++++++--- 3 files changed, 98 insertions(+), 25 deletions(-) diff --git a/src/core/core_api.c b/src/core/core_api.c index 57bf64ad7..e9a38271b 100644 --- a/src/core/core_api.c +++ b/src/core/core_api.c @@ -1730,25 +1730,11 @@ GNUNET_CORE_peer_request_connect (struct GNUNET_CORE_Handle *h, struct GNUNET_CORE_PeerRequestHandle *ret; struct ControlMessage *cm; struct ConnectMessage *msg; - struct PeerRecord *pr; - static struct GNUNET_TRANSPORT_ATS_Information distance[2]; if (NULL != GNUNET_CONTAINER_multihashmap_get (h->peers, &peer->hashPubKey)) - { - pr = GNUNET_CONTAINER_multihashmap_get(h->peers, &peer->hashPubKey); - GNUNET_assert(pr != NULL); - distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE); - distance[0].value = htonl (1); - distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); - distance[1].value = htonl (0); + return NULL; /* Already connected, means callback should have happened already! */ - if (NULL != h->connects) - h->connects (h->cls, - &pr->peer, - &distance[0]); - return NULL; - } cm = GNUNET_malloc (sizeof (struct ControlMessage) + sizeof (struct ConnectMessage)); diff --git a/src/core/core_api_iterate_peers.c b/src/core/core_api_iterate_peers.c index fb9c01fee..8175b70c6 100644 --- a/src/core/core_api_iterate_peers.c +++ b/src/core/core_api_iterate_peers.c @@ -31,7 +31,6 @@ struct GNUNET_CORE_RequestContext { - /** * Our connection to the service. */ @@ -47,6 +46,11 @@ struct GNUNET_CORE_RequestContext */ GNUNET_CORE_ConnectEventHandler peer_cb; + /** + * Peer to check for. + */ + struct GNUNET_PeerIdentity *peer; + /** * Closure for peer_cb. */ @@ -136,21 +140,78 @@ transmit_request(void *cls, size_t size, void *buf) { struct GNUNET_MessageHeader *msg; - if ((size < sizeof(struct GNUNET_MessageHeader)) || (buf == NULL)) + struct GNUNET_PeerIdentity *peer = cls; + int msize; + + if (peer == NULL) + msize = sizeof(struct GNUNET_MessageHeader); + else + msize = sizeof(struct GNUNET_MessageHeader) + sizeof(struct GNUNET_PeerIdentity); + + if ((size < msize) || (buf == NULL)) return 0; msg = (struct GNUNET_MessageHeader *)buf; msg->size = htons (sizeof (struct GNUNET_MessageHeader)); msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS); - return sizeof(struct GNUNET_MessageHeader); + memcpy(&msg[1], peer, sizeof(struct GNUNET_PeerIdentity)); + + return msize; } /** - * Obtain statistics and/or change preferences for the given peer. + * Iterate over all currently connected peers. + * Calls peer_cb with each connected peer, and then + * once with NULL to indicate that all peers have + * been handled. * * @param cfg configuration to use + * @param peer the specific peer to check for * @param peer_cb function to call with the peer information * @param cb_cls closure for peer_cb + * + * @return GNUNET_OK if iterating, GNUNET_SYSERR on error + */ +int +GNUNET_CORE_is_peer_connected (const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_PeerIdentity *peer, + GNUNET_CORE_ConnectEventHandler peer_cb, + void *cb_cls) +{ + struct GNUNET_CORE_RequestContext *request_context; + struct GNUNET_CLIENT_Connection *client; + + client = GNUNET_CLIENT_connect ("core", cfg); + if (client == NULL) + return GNUNET_SYSERR; + GNUNET_assert(peer != NULL); + request_context = GNUNET_malloc (sizeof (struct GNUNET_CORE_RequestContext)); + request_context->client = client; + request_context->peer_cb = peer_cb; + request_context->cb_cls = cb_cls; + request_context->peer = peer; + + request_context->th = GNUNET_CLIENT_notify_transmit_ready(client, + sizeof(struct GNUNET_MessageHeader) + sizeof(struct GNUNET_PeerIdentity), + GNUNET_TIME_relative_get_forever(), + GNUNET_YES, + &transmit_request, + peer); + + GNUNET_CLIENT_receive(client, &receive_info, request_context, GNUNET_TIME_relative_get_forever()); + return GNUNET_OK; +} + +/** + * Iterate over all currently connected peers. + * Calls peer_cb with each connected peer, and then + * once with NULL to indicate that all peers have + * been handled. + * + * @param cfg configuration to use + * @param peer_cb function to call with the peer information + * @param cb_cls closure for peer_cb + * * @return GNUNET_OK if iterating, GNUNET_SYSERR on error */ int diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c index 4519991b3..81d851265 100644 --- a/src/core/gnunet-service-core.c +++ b/src/core/gnunet-service-core.c @@ -1498,10 +1498,22 @@ handle_client_iterate_peers (void *cls, { struct GNUNET_MessageHeader done_msg; struct GNUNET_SERVER_TransmitContext *tc; - + struct GNUNET_PeerIdentity *peer; + int msize; /* notify new client about existing neighbours */ + + msize = ntohs(message->size); tc = GNUNET_SERVER_transmit_context_create (client); - GNUNET_CONTAINER_multihashmap_iterate (neighbours, &queue_connect_message, tc); + if (msize == sizeof(struct GNUNET_MessageHeader)) + GNUNET_CONTAINER_multihashmap_iterate (neighbours, &queue_connect_message, tc); + else if (msize == sizeof(struct GNUNET_MessageHeader) + sizeof(struct GNUNET_PeerIdentity)) + { + peer = (struct GNUNET_PeerIdentity *)&message[1]; + GNUNET_CONTAINER_multihashmap_get_multiple(neighbours, &peer->hashPubKey, &queue_connect_message, tc); + } + else + GNUNET_break(0); + done_msg.size = htons (sizeof (struct GNUNET_MessageHeader)); done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END); GNUNET_SERVER_transmit_context_append_message (tc, &done_msg); @@ -2908,6 +2920,10 @@ notify_transport_connect_done (void *cls, } if (buf == NULL) { + GNUNET_STATISTICS_update (stats, + gettext_noop ("# connection requests timed out in transport"), + 1, + GNUNET_NO); GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Failed to connect to `%4s': transport failed to connect\n"), GNUNET_i2s (&n->peer)); @@ -2966,10 +2982,20 @@ handle_client_request_connect (void *cls, 1, GNUNET_NO); else - GNUNET_STATISTICS_update (stats, - gettext_noop ("# connection requests ignored (already trying)"), - 1, - GNUNET_NO); + { + GNUNET_TRANSPORT_notify_transmit_ready_cancel(n->th); + n->th = GNUNET_TRANSPORT_notify_transmit_ready (transport, + &cm->peer, + sizeof (struct GNUNET_MessageHeader), 0, + timeout, + ¬ify_transport_connect_done, + n); + GNUNET_break (NULL != n->th); + GNUNET_STATISTICS_update (stats, + gettext_noop ("# connection requests retried (due to repeat request connect)"), + 1, + GNUNET_NO); + } return; /* already connected, or at least trying */ } GNUNET_STATISTICS_update (stats, -- 2.25.1