From: Nathan S. Evans Date: Tue, 3 Aug 2010 08:24:45 +0000 (+0000) Subject: core changes for topology iteration (get current connections) X-Git-Tag: initial-import-from-subversion-38251~20776 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=b38f97fd35c05c1279da542a99e4577b2a019096;p=oweals%2Fgnunet.git core changes for topology iteration (get current connections) --- diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 83a8d1d35..ded3d476c 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -16,7 +16,8 @@ lib_LTLIBRARIES = \ libgnunetcore_la_SOURCES = \ core_api.c core.h \ core_api_peer_get_info.c \ - core_api_peer_request.c + core_api_peer_request.c \ + core_api_iterate_peers.c libgnunetcore_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_LIBINTL) $(XLIB) diff --git a/src/core/core.h b/src/core/core.h index cd3b5d805..021aa4184 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -30,7 +30,7 @@ /** * General core debugging. */ -#define DEBUG_CORE GNUNET_YES +#define DEBUG_CORE GNUNET_NO /** * Debugging interaction core-clients. diff --git a/src/core/core_api_iterate_peers.c b/src/core/core_api_iterate_peers.c new file mode 100644 index 000000000..08cb9797c --- /dev/null +++ b/src/core/core_api_iterate_peers.c @@ -0,0 +1,171 @@ +/* + This file is part of GNUnet. + (C) 2009, 2010 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file core/core_api_iterate_peers.c + * @brief implementation of the peer_iterate function + * @author Christian Grothoff + * @author Nathan Evans + */ +#include "platform.h" +#include "gnunet_core_service.h" +#include "core.h" + + +struct GNUNET_CORE_RequestContext +{ + + /** + * Our connection to the service. + */ + struct GNUNET_CLIENT_Connection *client; + + /** + * Handle for transmitting a request. + */ + struct GNUNET_CLIENT_TransmitHandle *th; + + /** + * Function called with the peer. + */ + GNUNET_CORE_ConnectEventHandler peer_cb; + + /** + * Closure for peer_cb. + */ + void *cb_cls; + +}; + + +/** + * Receive reply from core service with information about a peer. + * + * @param cls our 'struct GNUNET_CORE_RequestContext *' + * @param msg NULL on error or last entry + */ +static void +receive_info (void *cls, + const struct GNUNET_MessageHeader *msg) +{ + struct GNUNET_CORE_RequestContext *request_context = cls; + const struct ConnectNotifyMessage *connect_message; + + + /* Handle last message or error case, disconnect and clean up */ + if ( (msg == NULL) || + ((ntohs (msg->type) == GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT) && + (ntohs (msg->size) == sizeof (struct GNUNET_MessageHeader))) ) + { + if (request_context->peer_cb != NULL) + request_context->peer_cb (request_context->cb_cls, + NULL, GNUNET_TIME_relative_get_zero(), 0); + GNUNET_CLIENT_disconnect (request_context->client, GNUNET_NO); + GNUNET_free (request_context); + return; + } + + /* Handle incorrect message type or size, disconnect and clean up */ + if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT) || + (ntohs (msg->size) != sizeof (struct ConnectNotifyMessage)) ) + { + GNUNET_break (0); + if (request_context->peer_cb != NULL) + request_context->peer_cb (request_context->cb_cls, + NULL, GNUNET_TIME_relative_get_zero(), 0); + GNUNET_CLIENT_disconnect (request_context->client, GNUNET_NO); + GNUNET_free (request_context); + return; + } + + /* Normal case */ + connect_message = (const struct ConnectNotifyMessage *) msg; + if (request_context->peer_cb != NULL) + request_context->peer_cb (request_context->cb_cls, + &connect_message->peer, + GNUNET_TIME_relative_ntoh(connect_message->latency), + ntohl (connect_message->distance)); + + GNUNET_CLIENT_receive(request_context->client, &receive_info, request_context, GNUNET_TIME_relative_get_forever()); +} + +/** + * Function called to notify a client about the socket + * begin ready to queue more data. "buf" will be + * NULL and "size" zero if the socket was closed for + * writing in the meantime. + * + * @param cls closure + * @param size number of bytes available in buf + * @param buf where the callee should write the message + * @return number of bytes written to buf + */ +static size_t +transmit_request(void *cls, + size_t size, void *buf) +{ + struct GNUNET_MessageHeader *msg; + if ((size < sizeof(struct GNUNET_MessageHeader)) || (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); +} + +/** + * Obtain statistics and/or change preferences for the given peer. + * + * @param sched scheduler to use + * @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 +GNUNET_CORE_iterate_peers (struct GNUNET_SCHEDULER_Handle *sched, + const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_CORE_ConnectEventHandler peer_cb, + void *cb_cls) +{ + struct GNUNET_CORE_RequestContext *request_context; + struct GNUNET_CLIENT_Connection *client; + + client = GNUNET_CLIENT_connect (sched, "core", cfg); + if (client == NULL) + return GNUNET_SYSERR; + 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; + + /*GNUNET_assert (GNUNET_OK == GNUNET_CLIENT_transmit_and_get_response (client, + &request_message, + GNUNET_TIME_relative_get_forever(), + GNUNET_YES, + &receive_info, + request_context));*/ + request_context->th = GNUNET_CLIENT_notify_transmit_ready(client, sizeof(struct GNUNET_MessageHeader), GNUNET_TIME_relative_get_forever(), GNUNET_YES, &transmit_request, NULL); + GNUNET_CLIENT_receive(client, &receive_info, request_context, GNUNET_TIME_relative_get_forever()); + return GNUNET_OK; +} + +/* end of core_api_iterate_peers.c */ diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c index 6921d758f..0fcc13015 100644 --- a/src/core/gnunet-service-core.c +++ b/src/core/gnunet-service-core.c @@ -865,6 +865,48 @@ handle_peer_status_change (struct Neighbour *n) GNUNET_NO); } +/** + * Handle CORE_ITERATE_PEERS request. + */ +static void +handle_client_iterate_peers (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + struct Neighbour *n; + struct ConnectNotifyMessage cnm; + struct GNUNET_MessageHeader done_msg; + struct GNUNET_SERVER_TransmitContext *tc; + + /* notify new client about existing neighbours */ + cnm.header.size = htons (sizeof (struct ConnectNotifyMessage)); + cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); + done_msg.size = htons (sizeof (struct GNUNET_MessageHeader)); + done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); + tc = GNUNET_SERVER_transmit_context_create (client); + n = neighbours; + while (n != NULL) + { + if (n->status == PEER_STATE_KEY_CONFIRMED) + { +#if DEBUG_CORE_CLIENT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending `%s' message to client.\n", "NOTIFY_CONNECT"); +#endif + cnm.distance = htonl (n->last_distance); + cnm.latency = GNUNET_TIME_relative_hton (n->last_latency); + cnm.peer = n->peer; + GNUNET_SERVER_transmit_context_append_message (tc, &cnm.header); + /*send_to_client (c, &cnm.header, GNUNET_NO);*/ + } + n = n->next; + } + + GNUNET_SERVER_transmit_context_append_message (tc, &done_msg); + GNUNET_SERVER_transmit_context_run (tc, + GNUNET_TIME_UNIT_FOREVER_REL); +} + /** * Handle CORE_INIT request. @@ -2201,6 +2243,7 @@ handle_client_send (void *cls, if (msize < sizeof (struct SendMessage) + sizeof (struct GNUNET_MessageHeader)) { + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "about to assert fail, msize is %d, should be less than %d\n", msize, sizeof (struct SendMessage) + sizeof (struct GNUNET_MessageHeader)); GNUNET_break (0); if (client != NULL) GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); @@ -2730,7 +2773,7 @@ process_hello_retry_handle_set_key (void *cls, } else { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Ignoring `%s' message due to lack of public key for peer `%4s' (failed to obtain one).\n"), "SET_KEY", GNUNET_i2s (&n->peer)); @@ -3815,6 +3858,9 @@ run (void *cls, {&handle_client_request_info, NULL, GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO, sizeof (struct RequestInfoMessage)}, + {&handle_client_iterate_peers, NULL, + GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS, + sizeof (struct GNUNET_MessageHeader)}, {&handle_client_send, NULL, GNUNET_MESSAGE_TYPE_CORE_SEND, 0}, {&handle_client_request_connect, NULL,