From 03b104dab570998b1f791994a8134d35b4b4dc0a Mon Sep 17 00:00:00 2001 From: "Nathan S. Evans" Date: Tue, 16 Nov 2010 15:21:20 +0000 Subject: [PATCH] Testing changes required to work with new core api. Revert GNUNET_CORE_iterate_peers call to work properly. --- src/core/Makefile.am | 3 +- src/core/core_api.c | 6 +- src/core/core_api_iterate_peers.c | 169 ++++++++++++++++++ src/core/gnunet-service-core.c | 46 +++++ src/dht/gnunet-dht-driver.c | 2 +- src/include/gnunet_core_service.h | 4 +- src/include/gnunet_protocols.h | 4 + src/testing/test_testing_data_remote.conf | 8 +- ...test_testing_data_topology_scale_free.conf | 2 +- src/testing/test_testing_topology.c | 99 ++++++++-- src/testing/testing.c | 4 +- src/testing/testing_group.c | 9 +- src/transport/plugin_transport_tcp.c | 4 +- src/transport/plugin_transport_udp.c | 7 +- src/util/scheduler.c | 2 +- 15 files changed, 333 insertions(+), 36 deletions(-) create mode 100644 src/core/core_api_iterate_peers.c diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 94db94959..0b8a34ff9 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -14,7 +14,8 @@ lib_LTLIBRARIES = \ libgnunetcore.la libgnunetcore_la_SOURCES = \ - core_api.c core.h + core_api.c core.h \ + core_api_iterate_peers.c libgnunetcore_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_LIBINTL) $(XLIB) diff --git a/src/core/core_api.c b/src/core/core_api.c index ffffbea92..0fdcacb7a 100644 --- a/src/core/core_api.c +++ b/src/core/core_api.c @@ -1432,6 +1432,9 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, if (NULL == pr) { /* attempt to send to peer that is not connected */ + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, + "Attempting to send to peer `%s' from peer `%s', but not connected!\n", + GNUNET_i2s(target), GNUNET_h2s(&handle->me.hashPubKey)); GNUNET_break (0); return NULL; } @@ -1839,6 +1842,7 @@ GNUNET_CORE_peer_change_preference_cancel (struct GNUNET_CORE_InformationRequest } +#if NEW /* ********************* GNUNET_CORE_iterate_peers *********************** */ /** @@ -1903,6 +1907,6 @@ GNUNET_CORE_iterate_peers (struct GNUNET_CORE_Handle *h, &ic); return GNUNET_OK; } - +#endif /* end of core_api.c */ diff --git a/src/core/core_api_iterate_peers.c b/src/core/core_api_iterate_peers.c new file mode 100644 index 000000000..657768363 --- /dev/null +++ b/src/core/core_api_iterate_peers.c @@ -0,0 +1,169 @@ +/* + 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, NULL); + 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, NULL); + 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, + NULL); + + 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 (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 ("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; + + 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 29f084d04..bfb17b6c8 100644 --- a/src/core/gnunet-service-core.c +++ b/src/core/gnunet-service-core.c @@ -1306,6 +1306,49 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) } +/** + * 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; + cnm.ats_count = htonl (0); + cnm.ats.type = htonl (0); + cnm.ats.value = htonl (0); + 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.peer = n->peer; + GNUNET_SERVER_transmit_context_append_message (tc, &cnm.header); + } + n = n->next; + } + GNUNET_SERVER_transmit_context_append_message (tc, &done_msg); + GNUNET_SERVER_transmit_context_run (tc, + GNUNET_TIME_UNIT_FOREVER_REL); +} + + /** * Handle REQUEST_INFO request. */ @@ -4191,6 +4234,9 @@ run (void *cls, static const struct GNUNET_SERVER_MessageHandler handlers[] = { {&handle_client_init, NULL, GNUNET_MESSAGE_TYPE_CORE_INIT, 0}, + {&handle_client_iterate_peers, NULL, + GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS, + sizeof (struct GNUNET_MessageHeader)}, {&handle_client_request_info, NULL, GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO, sizeof (struct RequestInfoMessage)}, diff --git a/src/dht/gnunet-dht-driver.c b/src/dht/gnunet-dht-driver.c index 8f1081a7a..c6666b23d 100644 --- a/src/dht/gnunet-dht-driver.c +++ b/src/dht/gnunet-dht-driver.c @@ -2758,7 +2758,7 @@ run (void *cls, buf = &data[count + 1]; } } - + GNUNET_free(data); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "dht_testing", "malicious_getters", &malicious_getters)) diff --git a/src/include/gnunet_core_service.h b/src/include/gnunet_core_service.h index abfcd1d3b..8c57b23b7 100644 --- a/src/include/gnunet_core_service.h +++ b/src/include/gnunet_core_service.h @@ -357,13 +357,13 @@ GNUNET_CORE_peer_change_preference_cancel (struct GNUNET_CORE_InformationRequest /** * Iterate over all connected peers. * - * @param h core handle + * @param cfg configuration handle * @param peer_cb function to call with the peer information * @param cb_cls closure for peer_cb * @return GNUNET_OK on success, GNUNET_SYSERR on errors */ int -GNUNET_CORE_iterate_peers (struct GNUNET_CORE_Handle *h, +GNUNET_CORE_iterate_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CORE_ConnectEventHandler peer_cb, void *cb_cls); diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 4d9fec4ca..e9eee668a 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -377,6 +377,10 @@ extern "C" */ #define GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT 77 +/** + * Request for peer iteration from CORE service. + */ +#define GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS 78 /** * Session key exchange between peers. diff --git a/src/testing/test_testing_data_remote.conf b/src/testing/test_testing_data_remote.conf index 3c28c5ece..df036c49e 100644 --- a/src/testing/test_testing_data_remote.conf +++ b/src/testing/test_testing_data_remote.conf @@ -1,6 +1,6 @@ -PATHS] +[PATHS] SERVICEHOME = /tmp/test-gnunet-testing/ -DEFAULTCONFIG = test_testing_data.conf +DEFAULTCONFIG = test_testing_data_remote.conf [resolver] PORT = 2564 @@ -16,6 +16,7 @@ PORT = 2566 DEFAULTSERVICES = [statistics] +AUTOSTART = NO PORT = 2567 [transport-tcp] @@ -29,8 +30,9 @@ PORT = 2570 [testing] CONTROL_HOST = 131.159.20.42 -HOSTS = 127.0.0.1 +HOSTFILE = remote_hosts.txt WEAKRANDOM = YES +NUM_PEERS = 2 [dht] AUTOSTART = NO diff --git a/src/testing/test_testing_data_topology_scale_free.conf b/src/testing/test_testing_data_topology_scale_free.conf index abf86e3d9..1a104b88b 100644 --- a/src/testing/test_testing_data_topology_scale_free.conf +++ b/src/testing/test_testing_data_topology_scale_free.conf @@ -40,7 +40,7 @@ PORT = 2570 #DEBUG = YES [testing] -NUM_PEERS = 500 +NUM_PEERS = 50 WEAKRANDOM = YES TOPOLOGY = SCALE_FREE F2F = YES diff --git a/src/testing/test_testing_topology.c b/src/testing/test_testing_topology.c index 36ccad6c9..f9d5fb9af 100644 --- a/src/testing/test_testing_topology.c +++ b/src/testing/test_testing_topology.c @@ -142,6 +142,12 @@ struct TestMessageContext /* Identifier for this message, so we don't disconnect other peers! */ uint32_t uid; + /* Has peer1 been notified already of a connection to peer2? */ + int peer1notified; + + /* Has the core of peer2 been connected already? */ + int peer2connected; + /* Task for disconnecting cores, allow task to be cancelled on shutdown */ GNUNET_SCHEDULER_TaskIdentifier disconnect_task; @@ -364,6 +370,7 @@ process_mtype (void *cls, #endif total_messages_received++; + #if VERBOSE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message from `%4s', type %d.\n", GNUNET_i2s (peer), @@ -491,33 +498,89 @@ init_notify_peer2 (void *cls, { struct TestMessageContext *pos = cls; + total_server_connections++; + + pos->peer2connected = GNUNET_YES; + if (pos->peer1notified == GNUNET_YES) /* Peer 1 has been notified of connection to peer 2 */ + { #if VERBOSE > 1 - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Core connection to `%4s' established, scheduling message send\n", - GNUNET_i2s (my_identity)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Scheduling message send to peer `%s' from peer `%s' (init_notify_peer2)\n", + GNUNET_i2s (my_identity), GNUNET_h2s(&pos->peer1->id.hashPubKey)); #endif - total_server_connections++; + if (NULL == GNUNET_CORE_notify_transmit_ready (pos->peer1handle, + 0, + TIMEOUT, + &pos->peer2->id, + sizeof (struct + GNUNET_TestMessage), + &transmit_ready, pos)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "RECEIVED NULL when asking core (1) for transmission to peer `%4s'\n", + GNUNET_i2s (&pos->peer2->id)); + transmit_ready_failed++; + } + else + { + transmit_ready_scheduled++; + } + } +} + +/** + * Method called whenever a given peer connects. + * + * @param cls closure + * @param peer peer identity this notification is about + * @param atsi performance data for the connection + */ +static void connect_notify_peers (void *cls, + const struct + GNUNET_PeerIdentity *peer, + const struct GNUNET_TRANSPORT_ATS_Information *atsi) +{ + struct TestMessageContext *pos = cls; - if (NULL == GNUNET_CORE_notify_transmit_ready (pos->peer1handle, - 0, - TIMEOUT, - &pos->peer2->id, - sizeof (struct - GNUNET_TestMessage), - &transmit_ready, pos)) + if (0 == memcmp(peer, &pos->peer2->id, sizeof(struct GNUNET_PeerIdentity))) { + pos->peer1notified = GNUNET_YES; +#if VERBOSE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "RECEIVED NULL when asking core (1) for transmission to peer `%4s'\n", - GNUNET_i2s (&pos->peer2->id)); - transmit_ready_failed++; + "Peer `%s' notified of connection to peer `%s'\n", + GNUNET_i2s (&pos->peer1->id), GNUNET_h2s(&peer->hashPubKey)); +#endif } else + return; + + if (pos->peer2connected == GNUNET_YES) /* Already connected and notified of connection, send message! */ { - transmit_ready_scheduled++; +#if VERBOSE > 1 + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Scheduling message send to peer `%s' from peer `%s' (init_notify_peer2)\n", + GNUNET_i2s (&pos->peer2->id), GNUNET_h2s(&pos->peer1->id.hashPubKey)); +#endif + if (NULL == GNUNET_CORE_notify_transmit_ready (pos->peer1handle, + 0, + TIMEOUT, + &pos->peer2->id, + sizeof (struct + GNUNET_TestMessage), + &transmit_ready, pos)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "RECEIVED NULL when asking core (1) for transmission to peer `%4s'\n", + GNUNET_i2s (&pos->peer2->id)); + transmit_ready_failed++; + } + else + { + transmit_ready_scheduled++; + } } } - static void init_notify_peer1 (void *cls, struct GNUNET_CORE_Handle *server, @@ -585,7 +648,7 @@ send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 1, pos, &init_notify_peer1, - NULL, NULL, + &connect_notify_peers, NULL, NULL, NULL, GNUNET_NO, NULL, GNUNET_NO, @@ -639,7 +702,7 @@ topology_callback (void *cls, #endif total_connections++; #if VERBOSE > 1 - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connected peer %s to peer %s\n", + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "connected peer %s to peer %s\n", first_daemon->shortname, second_daemon->shortname); #endif temp_context = GNUNET_malloc (sizeof (struct TestMessageContext)); diff --git a/src/testing/testing.c b/src/testing/testing.c index 84493410a..3d1a74e0e 100644 --- a/src/testing/testing.c +++ b/src/testing/testing.c @@ -1533,10 +1533,12 @@ send_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) ctx->max_connect_attempts + 1), &ctx->d2->id, &core_connect_request_cont, ctx); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, +#if DEBUG_TESTING + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending connect request to CORE of %s for peer %s\n", GNUNET_i2s (&ctx->d1->id), GNUNET_h2s (&ctx->d2->id.hashPubKey)); +#endif ctx->timeout_hello = GNUNET_TIME_relative_add (ctx->timeout_hello, GNUNET_TIME_relative_multiply diff --git a/src/testing/testing_group.c b/src/testing/testing_group.c index 9c0dbd8fa..e74d5b9ef 100644 --- a/src/testing/testing_group.c +++ b/src/testing/testing_group.c @@ -3421,12 +3421,15 @@ schedule_get_topology (void *cls, outstanding_connects); #endif topology_context->connected++; + if (GNUNET_OK != - GNUNET_CORE_iterate_peers (core_context->daemon->server, + GNUNET_CORE_iterate_peers (core_context->daemon->cfg, &internal_topology_callback, core_context)) - internal_topology_callback (core_context, NULL, NULL); - + { + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Topology iteration failed.\n"); + internal_topology_callback (core_context, NULL, NULL); + } } } diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index ba07fcb48..9ef606f68 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c @@ -2528,7 +2528,9 @@ libgnunet_plugin_transport_tcp_init (void *cls) GNUNET_SERVER_disconnect_notify (plugin->server, &disconnect_notify, plugin); - GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-tcp", "BINDTO", &plugin->bind_address); + + if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (env->cfg, "transport-tcp", "BINDTO", &plugin->bind_address)) + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Binding tcp plugin to specific address: `%s'\n", plugin->bind_address); if (plugin->behind_nat == GNUNET_NO) { diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index d95147a1a..94447bdbc 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c @@ -2293,9 +2293,10 @@ libgnunet_plugin_transport_udp_init (void *cls) plugin->service = service; - GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-udp", "BINDTO", &plugin->bind_address); - - GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-udp", "BINDTO6", &plugin->bind6_address); + if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-udp", "BINDTO", &plugin->bind_address)) + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Binding udp plugin to specific address: `%s'\n", plugin->bind_address); + if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-udp", "BINDTO6", &plugin->bind6_address)) + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Binding udp plugin to specific address: `%s'\n", plugin->bind6_address); if (plugin->behind_nat == GNUNET_NO) { diff --git a/src/util/scheduler.c b/src/util/scheduler.c index f1cfd2c36..49d491bd7 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c @@ -770,7 +770,7 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *task_cls) snprintf (lsof, sizeof (lsof), "lsof -p %d", getpid()); close (1); dup2 (2, 1); - system (lsof); + ret = system (lsof); #endif #endif abort (); -- 2.25.1