From baaedd4fdfb10fc28d9923be9e1d28663d621eca Mon Sep 17 00:00:00 2001 From: "Nathan S. Evans" Date: Wed, 12 May 2010 15:51:49 +0000 Subject: [PATCH] moving closer towards a working dv implementation --- src/dv/Makefile.am | 11 +- src/dv/dv_api.c | 7 +- src/dv/gnunet-service-dv.c | 87 ++- src/dv/plugin_transport_dv.c | 10 - src/dv/test_dv_topology.c | 752 ++++++++++++++++++++++++ src/dv/test_dv_topology.conf | 68 +++ src/dv/test_transport_api_dv.c | 386 ++++++++---- src/dv/test_transport_api_dv_peer4.conf | 111 ++++ 8 files changed, 1269 insertions(+), 163 deletions(-) create mode 100644 src/dv/test_dv_topology.c create mode 100644 src/dv/test_dv_topology.conf create mode 100644 src/dv/test_transport_api_dv_peer4.conf diff --git a/src/dv/Makefile.am b/src/dv/Makefile.am index 0dc4afb08..9d5dc1ab1 100644 --- a/src/dv/Makefile.am +++ b/src/dv/Makefile.am @@ -50,7 +50,8 @@ libgnunet_plugin_transport_dv_la_LDFLAGS = \ check_PROGRAMS = \ - test_transport_api_dv + test_transport_api_dv \ + test_dv_topology TESTS = $(check_PROGRAMS) $(check_SCRIPTS) @@ -60,6 +61,14 @@ test_transport_api_dv_LDADD = \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/util/libgnunetutil.la +test_dv_topology_SOURCES = \ + test_dv_topology.c +test_dv_topology_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la + + EXTRA_DIST = \ test_transport_api_dv_peer1.conf \ test_transport_api_dv_peer2.conf \ diff --git a/src/dv/dv_api.c b/src/dv/dv_api.c index 28bd0dcac..b7337d45c 100644 --- a/src/dv/dv_api.c +++ b/src/dv/dv_api.c @@ -345,6 +345,10 @@ void handle_message_receipt (void *cls, GNUNET_HashCode uidhash; struct SendCallbackContext *send_ctx; +#if DEBUG_DV + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "dv api receives message!\n"); +#endif + if (msg == NULL) { return; /* Connection closed? */ @@ -474,8 +478,7 @@ int GNUNET_DV_send (struct GNUNET_DV_Handle *dv_handle, send_ctx = GNUNET_malloc(sizeof(struct SendCallbackContext)); send_ctx->cont = cont; - if (cont == NULL) - fprintf(stderr, "DV_SEND called with null continuation!\n"); + send_ctx->cont_cls = cont_cls; memcpy(&send_ctx->target, target, sizeof(struct GNUNET_PeerIdentity)); diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c index dc92bfa37..3a0d4f936 100644 --- a/src/dv/gnunet-service-dv.c +++ b/src/dv/gnunet-service-dv.c @@ -724,7 +724,7 @@ void send_to_plugin(const struct GNUNET_PeerIdentity * sender, } else { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to queue message for plugin, must be one in progress already!!\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to queue message for plugin, must be one in progress already!!\n"); } } } @@ -754,7 +754,7 @@ size_t core_transmit_notify (void *cls, { /* client disconnected */ #if DEBUG_DV - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "`%s': buffer was NULL\n", "DHT"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s': buffer was NULL\n", "DHT"); #endif return 0; } @@ -778,7 +778,6 @@ size_t core_transmit_notify (void *cls, GNUNET_free(reply->send_result); GNUNET_CONTAINER_DLL_insert_after(plugin_pending_head, plugin_pending_tail, plugin_pending_tail, client_reply); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Queued client send receipt success message!\n"); if (client_handle != NULL) { if (plugin_transmit_handle == NULL) @@ -1031,7 +1030,7 @@ static int handle_dv_data_message (void *cls, { #if DEBUG_DV GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "%s: unknown sender (%d), size of extended_peers is %d!\n", "dv", ntohl(incoming->sender), GNUNET_CONTAINER_multihashmap_size (ctx.extended_neighbors)); + "%s peer %s: unknown sender (%d)!\n", "DV SERVICE", GNUNET_i2s(&my_identity), ntohl(incoming->sender), GNUNET_CONTAINER_multihashmap_size (ctx.extended_neighbors)); #endif /* unknown sender */ return GNUNET_OK; @@ -1125,7 +1124,7 @@ static int handle_dv_data_message (void *cls, */ static void neighbor_send_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) + const struct GNUNET_SCHEDULER_TaskContext *tc) { struct NeighborSendContext *send_context = cls; #if DEBUG_DV_GOSSIP_SEND @@ -1187,7 +1186,7 @@ neighbor_send_task (void *cls, #if DEBUG_DV_GOSSIP_SEND encPeerAbout = GNUNET_strdup(GNUNET_i2s(&about->identity)); encPeerTo = GNUNET_strdup(GNUNET_i2s(&to->identity)); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s: Sending info about peer %s to directly connected peer %s\n", GNUNET_i2s(&my_identity), encPeerAbout, encPeerTo); @@ -1218,12 +1217,12 @@ neighbor_send_task (void *cls, if (send_context->fast_gossip_list_head != NULL) /* If there are other peers in the fast list, schedule right away */ { - GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "DV SERVICE: still in fast send mode\n"); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV SERVICE: still in fast send mode\n"); send_context->task = GNUNET_SCHEDULER_add_now(sched, &neighbor_send_task, send_context); } else { - GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "DV SERVICE: entering slow send mode\n"); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV SERVICE: entering slow send mode\n"); send_context->task = GNUNET_SCHEDULER_add_delayed(sched, GNUNET_DV_DEFAULT_SEND_INTERVAL, &neighbor_send_task, send_context); } @@ -1329,10 +1328,6 @@ void handle_dv_send_message (void *cls, GNUNET_assert(address_len == sizeof(struct GNUNET_PeerIdentity) * 2); message_size = ntohl(send_msg->msgbuf_size); -#if 1 - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "%s: Receives %s message size %u!\n\n\n", "dv", "SEND", message_size); -#endif GNUNET_assert(ntohs(message->size) == sizeof(struct GNUNET_DV_SendMessage) + address_len + message_size); destination = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); direct = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); @@ -1356,10 +1351,10 @@ void handle_dv_send_message (void *cls, GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s: asked to send message to `%s', but address is for `%s'!", "DV SERVICE", GNUNET_i2s(&send_msg->target), (const char *)&dest_hash.encoding); } -#if 1 +#if DEBUG_DV GNUNET_CRYPTO_hash_to_enc (&destination->hashPubKey, &dest_hash); /* GNUNET_i2s won't properly work, need to hash one ourselves */ dest_hash.encoding[4] = '\0'; - GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "DV SEND called with message of size %d type %d, destination `%s' via `%s'\n", message_size, ntohs(message_buf->type), (const char *)&dest_hash.encoding, GNUNET_i2s(direct)); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV SEND called with message of size %d type %d, destination `%s' via `%s'\n", message_size, ntohs(message_buf->type), (const char *)&dest_hash.encoding, GNUNET_i2s(direct)); #endif send_context = GNUNET_malloc(sizeof(struct DV_SendContext)); @@ -1823,10 +1818,9 @@ addUpdateNeighbor (const struct GNUNET_PeerIdentity * peer, struct GNUNET_CRYPTO "%s: Already know peer %s distance %d, referrer id %d!\n", "dv", GNUNET_i2s(peer), cost, referrer_peer_id); #endif } -#if DEBUG_DV_GOSSIP +#if DEBUG_DV GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s: Size of extended_neighbors is %d\n", "dv", GNUNET_CONTAINER_multihashmap_size(ctx.extended_neighbors)); - GNUNET_CONTAINER_multihashmap_iterate(ctx.extended_neighbors, &print_neighbors, NULL); #endif GNUNET_free(neighbor_update); @@ -1999,7 +1993,6 @@ static int add_all_extended_peers (void *cls, if (memcmp(&send_context->toNeighbor->identity, &distant->identity, sizeof(struct GNUNET_PeerIdentity)) == 0) return GNUNET_YES; /* Don't gossip to a peer about itself! */ - GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "DV SERVICE: adding extended neighbor to fast send list\n"); #if SUPPORT_HIDING if (distant->hidden == GNUNET_YES) return GNUNET_YES; /* This peer should not be gossipped about (hidden) */ @@ -2016,6 +2009,55 @@ static int add_all_extended_peers (void *cls, } +/** + * Iterate over all current direct peers, add DISTANT newly connected + * peer to the fast gossip list for that peer so we get DV routing + * information out as fast as possible! + * + * @param cls the newly connected neighbor we will gossip about + * @param key the hashcode of the peer + * @param value the direct neighbor we should gossip to + * + * @return GNUNET_YES to continue iteration, GNUNET_NO otherwise + */ +static int add_distant_all_direct_neighbors (void *cls, + const GNUNET_HashCode * key, + void *value) +{ + struct DirectNeighbor *direct = (struct DirectNeighbor *)value; + struct DistantNeighbor *distant = (struct DistantNeighbor *)cls; + struct NeighborSendContext *send_context = direct->send_context; + struct FastGossipNeighborList *gossip_entry; + + if (distant == NULL) + { + return GNUNET_YES; + } + + if (memcmp(&direct->identity, &distant->identity, sizeof(struct GNUNET_PeerIdentity)) == 0) + { + return GNUNET_YES; /* Don't gossip to a peer about itself! */ + } + +#if SUPPORT_HIDING + if (distant->hidden == GNUNET_YES) + return GNUNET_YES; /* This peer should not be gossipped about (hidden) */ +#endif + gossip_entry = GNUNET_malloc(sizeof(struct FastGossipNeighborList)); + gossip_entry->about = distant; + + GNUNET_CONTAINER_DLL_insert_after(send_context->fast_gossip_list_head, + send_context->fast_gossip_list_tail, + send_context->fast_gossip_list_tail, + gossip_entry); + if (send_context->task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel(sched, send_context->task); + + send_context->task = GNUNET_SCHEDULER_add_now(sched, &neighbor_send_task, send_context); + return GNUNET_YES; +} + + /** * Iterate over all current direct peers, add newly connected peer * to the fast gossip list for that peer so we get DV routing @@ -2039,12 +2081,15 @@ static int add_all_direct_neighbors (void *cls, distant = GNUNET_CONTAINER_multihashmap_get(ctx.extended_neighbors, &to->identity.hashPubKey); if (distant == NULL) - return GNUNET_YES; + { + return GNUNET_YES; + } if (memcmp(&direct->identity, &to->identity, sizeof(struct GNUNET_PeerIdentity)) == 0) - return GNUNET_YES; /* Don't gossip to a peer about itself! */ + { + return GNUNET_YES; /* Don't gossip to a peer about itself! */ + } - GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "DV SERVICE: adding new DISTANT neighbor to fast send list\n"); #if SUPPORT_HIDING if (distant->hidden == GNUNET_YES) return GNUNET_YES; /* This peer should not be gossipped about (hidden) */ @@ -2147,7 +2192,7 @@ void handle_core_connect (void *cls, { about = GNUNET_CONTAINER_multihashmap_get(ctx.extended_neighbors, &peer->hashPubKey); if ((GNUNET_CONTAINER_multihashmap_get(ctx.direct_neighbors, &peer->hashPubKey) == NULL) && (about != NULL)) - GNUNET_CONTAINER_multihashmap_iterate(ctx.direct_neighbors, &add_all_direct_neighbors, about); + GNUNET_CONTAINER_multihashmap_iterate(ctx.direct_neighbors, &add_distant_all_direct_neighbors, about); #if DEBUG_DV GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, diff --git a/src/dv/plugin_transport_dv.c b/src/dv/plugin_transport_dv.c index 6932ce34b..a8c05d309 100644 --- a/src/dv/plugin_transport_dv.c +++ b/src/dv/plugin_transport_dv.c @@ -138,11 +138,6 @@ struct Plugin */ struct Session *sessions; - /** - * Handle for the statistics service. - */ - struct GNUNET_STATISTICS_Handle *statistics; - /** * Our server. */ @@ -243,10 +238,6 @@ dv_plugin_send (void *cls, int ret = 0; struct Plugin *plugin = cls; - /* FIXME: do we want the dv plugin to remember sent messages to call continuation once message actually goes out? - * Or do we just call the continuation once we've notified the plugin? - */ - // FIXME: does it make sense for us to use sessions? #if DEBUG_DV GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV API: Received send request from transport, calling GNUNET_DV_send\n"); #endif @@ -390,7 +381,6 @@ libgnunet_plugin_transport_dv_init (void *cls) plugin = GNUNET_malloc (sizeof (struct Plugin)); plugin->env = env; - plugin->statistics = NULL; //plugin->service = service; //plugin->server = GNUNET_SERVICE_get_server (service); diff --git a/src/dv/test_dv_topology.c b/src/dv/test_dv_topology.c new file mode 100644 index 000000000..c7f213a07 --- /dev/null +++ b/src/dv/test_dv_topology.c @@ -0,0 +1,752 @@ +/* + This file is part of GNUnet. + (C) 2009 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 2, 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 testing/test_testing_topology.c + * @brief base testcase for testing all the topologies provided + */ +#include "platform.h" +#include "gnunet_testing_lib.h" +#include "gnunet_core_service.h" + +#define VERBOSE GNUNET_YES + +/** + * How long until we fail the whole testcase? + */ +#define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600) + +/** + * How long until we give up on connecting the peers? + */ +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) + +#define DEFAULT_NUM_PEERS 4 + +#define MAX_OUTSTANDING_CONNECTIONS 300 + +static float fail_percentage = 0.05; + +static int ok; + +static unsigned long long num_peers; + +static unsigned int total_connections; + +static unsigned int failed_connections; + +static unsigned int total_server_connections; + +static unsigned int total_messages_received; + +static unsigned int expected_messages; + +static unsigned int expected_connections; + +static unsigned long long peers_left; + +static struct GNUNET_TESTING_PeerGroup *pg; + +static struct GNUNET_SCHEDULER_Handle *sched; + +const struct GNUNET_CONFIGURATION_Handle *main_cfg; + +GNUNET_SCHEDULER_TaskIdentifier die_task; + +static char *dotOutFileName; + +static FILE *dotOutFile; + +static char *topology_string; + +static int transmit_ready_scheduled; + +static int transmit_ready_failed; + +static int transmit_ready_called; + +static enum GNUNET_TESTING_Topology topology; + +static char *test_directory; + +#define MTYPE 12345 + +struct GNUNET_TestMessage +{ + /** + * Header of the message + */ + struct GNUNET_MessageHeader header; + + /** + * Unique identifier for this message. + */ + uint32_t uid; +}; + +struct TestMessageContext +{ + /* This is a linked list */ + struct TestMessageContext *next; + + /* Handle to the sending peer core */ + struct GNUNET_CORE_Handle *peer1handle; + + /* Handle to the receiving peer core */ + struct GNUNET_CORE_Handle *peer2handle; + + /* Handle to the sending peer daemon */ + struct GNUNET_TESTING_Daemon *peer1; + + /* Handle to the receiving peer daemon */ + struct GNUNET_TESTING_Daemon *peer2; + + /* Identifier for this message, so we don't disconnect other peers! */ + uint32_t uid; + + /* Task for disconnecting cores, allow task to be cancelled on shutdown */ + GNUNET_SCHEDULER_TaskIdentifier disconnect_task; + +}; + +static struct TestMessageContext *test_messages; + +static void +finish_testing () +{ + GNUNET_assert (pg != NULL); + struct TestMessageContext *pos; + struct TestMessageContext *free_pos; +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Called finish testing, stopping daemons.\n"); +#endif + int count; + count = 0; + pos = test_messages; + while (pos != NULL) + { + if (pos->peer1handle != NULL) + { + GNUNET_CORE_disconnect(pos->peer1handle); + pos->peer1handle = NULL; + } + if (pos->peer2handle != NULL) + { + GNUNET_CORE_disconnect(pos->peer2handle); + pos->peer2handle = NULL; + } + free_pos = pos; + pos = pos->next; + if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel(sched, free_pos->disconnect_task); + } + GNUNET_free(free_pos); + } +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "transmit_ready's scheduled %d, failed %d, transmit_ready's called %d\n", transmit_ready_scheduled, transmit_ready_failed, transmit_ready_called); +#endif + sleep(1); +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Calling daemons_stop\n"); +#endif + GNUNET_TESTING_daemons_stop (pg, TIMEOUT); +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "daemons_stop finished\n"); +#endif + if (dotOutFile != NULL) + { + fprintf(dotOutFile, "}"); + fclose(dotOutFile); + } + + ok = 0; +} + + +static void +disconnect_cores (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) +{ + struct TestMessageContext *pos = cls; + + /* Disconnect from the respective cores */ +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Disconnecting from peer 1 `%4s'\n", GNUNET_i2s (&pos->peer1->id)); +#endif + if (pos->peer1handle != NULL) + GNUNET_CORE_disconnect(pos->peer1handle); +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Disconnecting from peer 2 `%4s'\n", GNUNET_i2s (&pos->peer2->id)); +#endif + if (pos->peer2handle != NULL) + GNUNET_CORE_disconnect(pos->peer2handle); + /* Set handles to NULL so test case can be ended properly */ + pos->peer1handle = NULL; + pos->peer2handle = NULL; + pos->disconnect_task = GNUNET_SCHEDULER_NO_TASK; + /* Decrement total connections so new can be established */ + total_server_connections -= 2; +} + +static int +process_mtype (void *cls, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message, + struct GNUNET_TIME_Relative latency, + uint32_t distance) +{ + struct TestMessageContext *pos = cls; + struct GNUNET_TestMessage *msg = (struct GNUNET_TestMessage *)message; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received message from `%4s', type %d, distance %u.\n", GNUNET_i2s (peer), ntohs(message->type), distance); + if (pos->uid != ntohl(msg->uid)) + return GNUNET_OK; + + total_messages_received++; +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received message from `%4s', type %d, distance %u.\n", GNUNET_i2s (peer), ntohs(message->type), distance); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Total messages received %d, expected %d.\n", total_messages_received, expected_messages); +#endif + + if (total_messages_received == expected_messages) + { + GNUNET_SCHEDULER_cancel (sched, die_task); + GNUNET_SCHEDULER_add_now (sched, &finish_testing, NULL); + } + else + { + pos->disconnect_task = GNUNET_SCHEDULER_add_now(sched, &disconnect_cores, pos); + } + + return GNUNET_OK; +} + +static void +end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) +{ + char *msg = cls; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "End badly was called (%s)... stopping daemons.\n", msg); + struct TestMessageContext *pos; + struct TestMessageContext *free_pos; + + pos = test_messages; + while (pos != NULL) + { + if (pos->peer1handle != NULL) + { + GNUNET_CORE_disconnect(pos->peer1handle); + pos->peer1handle = NULL; + } + if (pos->peer2handle != NULL) + { + GNUNET_CORE_disconnect(pos->peer2handle); + pos->peer2handle = NULL; + } + free_pos = pos; + pos = pos->next; + GNUNET_free(free_pos); + } + + if (pg != NULL) + { + GNUNET_TESTING_daemons_stop (pg); + ok = 7331; /* Opposite of leet */ + } + else + ok = 401; /* Never got peers started */ + + if (dotOutFile != NULL) + { + fprintf(dotOutFile, "}"); + fclose(dotOutFile); + } +} + + + +static size_t +transmit_ready (void *cls, size_t size, void *buf) +{ + struct GNUNET_TestMessage *m; + struct TestMessageContext *pos = cls; + + GNUNET_assert (buf != NULL); + m = (struct GNUNET_TestMessage *) buf; + m->header.type = htons (MTYPE); + m->header.size = htons (sizeof (struct GNUNET_TestMessage)); + m->uid = htonl(pos->uid); + transmit_ready_called++; +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "transmit ready for peer %s\ntransmit_ready's scheduled %d, transmit_ready's called %d\n", GNUNET_i2s(&pos->peer1->id), transmit_ready_scheduled, transmit_ready_called); +#endif + return sizeof (struct GNUNET_TestMessage); +} + + +static struct GNUNET_CORE_MessageHandler no_handlers[] = { + {NULL, 0, 0} +}; + +static struct GNUNET_CORE_MessageHandler handlers[] = { + {&process_mtype, MTYPE, sizeof (struct GNUNET_TestMessage)}, + {NULL, 0, 0} +}; + +static void +init_notify_peer2 (void *cls, + struct GNUNET_CORE_Handle *server, + const struct GNUNET_PeerIdentity *my_identity, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey) +{ + struct TestMessageContext *pos = cls; + +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Core connection to `%4s' established, scheduling message send\n", + GNUNET_i2s (my_identity)); +#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++; + } +} + + +static void +init_notify_peer1 (void *cls, + struct GNUNET_CORE_Handle *server, + const struct GNUNET_PeerIdentity *my_identity, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey) +{ + struct TestMessageContext *pos = cls; + total_server_connections++; + +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Core connection to `%4s' established, setting up handles\n", + GNUNET_i2s (my_identity)); +#endif + + /* + * Connect to the receiving peer + */ + pos->peer2handle = GNUNET_CORE_connect (sched, + pos->peer2->cfg, + TIMEOUT, + pos, + &init_notify_peer2, + NULL, + NULL, + NULL, + GNUNET_YES, NULL, GNUNET_YES, handlers); + +} + + +static void +send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) +{ + struct TestMessageContext *pos = cls; + + if ((tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) || (cls == NULL)) + return; + + if (die_task == GNUNET_SCHEDULER_NO_TASK) + { + die_task = GNUNET_SCHEDULER_add_delayed (sched, + TEST_TIMEOUT, + &end_badly, "from send_test_messages (timeout)"); + } + + if (total_server_connections >= MAX_OUTSTANDING_CONNECTIONS) + { + GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1), + &send_test_messages, pos); + return; /* Otherwise we'll double schedule messages here! */ + } + + /* + * Connect to the sending peer + */ + pos->peer1handle = GNUNET_CORE_connect (sched, + pos->peer1->cfg, + TIMEOUT, + pos, + &init_notify_peer1, + NULL, + NULL, + NULL, + GNUNET_NO, NULL, GNUNET_NO, no_handlers); + + GNUNET_assert(pos->peer1handle != NULL); + + if (total_server_connections < MAX_OUTSTANDING_CONNECTIONS) + { + GNUNET_SCHEDULER_add_now (sched, + &send_test_messages, pos->next); + } + else + { + GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1), + &send_test_messages, pos->next); + } +} + + +static void +schedule_dv_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) +{ + struct TestMessageContext *pos; + struct TestMessageContext *new_message; + struct TestMessageContext *last; + struct TestMessageContext *new_list; + int i; + int other; + + if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) + return; + + pos = test_messages; + last = NULL; + while (pos != NULL) + { + last = pos; + pos = pos->next; + } + + new_list = NULL; + for (i = 0; i < num_peers; i++) + { + new_message = GNUNET_malloc(sizeof(struct TestMessageContext)); + other = i + 2; + if (other >= num_peers) + other = other - num_peers; + new_message->peer1 = GNUNET_TESTING_daemon_get(pg, i); + new_message->peer2 = GNUNET_TESTING_daemon_get(pg, other); + + new_message->uid = total_connections + i + 1; + new_message->next = new_list; +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Scheduled message between `%4s' and `%4s'\n", + new_message->peer1->shortname, new_message->peer2->shortname); +#endif + + new_list = new_message; + expected_messages++; + } + + if (dotOutFile != NULL) + { + fprintf(dotOutFile, "}"); + fclose (dotOutFile); + dotOutFile = NULL; + } + + if (last != NULL) + last->next = new_list; + else + test_messages = new_list; + + GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &send_test_messages, test_messages); +} + + +void +topology_callback (void *cls, + const struct GNUNET_PeerIdentity *first, + const struct GNUNET_PeerIdentity *second, + const struct GNUNET_CONFIGURATION_Handle *first_cfg, + const struct GNUNET_CONFIGURATION_Handle *second_cfg, + struct GNUNET_TESTING_Daemon *first_daemon, + struct GNUNET_TESTING_Daemon *second_daemon, + const char *emsg) +{ + //struct TestMessageContext *temp_context; + if (emsg == NULL) + { + total_connections++; +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connected peer %s to peer %s\n", + first_daemon->shortname, + second_daemon->shortname); +#endif + /*temp_context = GNUNET_malloc(sizeof(struct TestMessageContext)); + temp_context->peer1 = first_daemon; + temp_context->peer2 = second_daemon; + temp_context->next = test_messages; + temp_context->uid = total_connections; + temp_context->disconnect_task = GNUNET_SCHEDULER_NO_TASK; + test_messages = temp_context; + + expected_messages++;*/ + if (dotOutFile != NULL) + fprintf(dotOutFile, "\tn%s -- n%s;\n", first_daemon->shortname, second_daemon->shortname); + } +#if VERBOSE + else + { + failed_connections++; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to connect peer %s to peer %s with error :\n%s\n", + first_daemon->shortname, + second_daemon->shortname, emsg); + } +#endif + + if (total_connections == expected_connections) + { +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Created %d total connections, which is our target number! Calling send messages.\n", + total_connections); +#endif + + GNUNET_SCHEDULER_cancel (sched, die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &schedule_dv_messages, test_messages); + } + else if (total_connections + failed_connections == expected_connections) + { + if (failed_connections < (unsigned int)(fail_percentage * total_connections)) + { + GNUNET_SCHEDULER_cancel (sched, die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &schedule_dv_messages, test_messages); + } + else + { + GNUNET_SCHEDULER_cancel (sched, die_task); + die_task = GNUNET_SCHEDULER_add_now (sched, + &end_badly, "from topology_callback (too many failed connections)"); + } + } + else + { +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Have %d total connections, %d failed connections, Want %d (at least %d)\n", + total_connections, failed_connections, expected_connections, expected_connections - (unsigned int)(fail_percentage * expected_connections)); +#endif + } +} + + +static void +create_topology () +{ + expected_connections = -1; + if ((pg != NULL) && (peers_left == 0)) + { + /* create_topology will read the topology information from + the config already contained in the peer group, so should + we have create_topology called from start peers? I think + maybe this way is best so that the client can know both + when peers are started, and when they are connected. + */ + expected_connections = GNUNET_TESTING_create_topology (pg, topology); +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Have %d expected connections\n", expected_connections); +#endif + } + + GNUNET_SCHEDULER_cancel (sched, die_task); + if (expected_connections == GNUNET_SYSERR) + { + die_task = GNUNET_SCHEDULER_add_now (sched, + &end_badly, "from create topology (bad return)"); + } + die_task = GNUNET_SCHEDULER_add_delayed (sched, + TEST_TIMEOUT, + &end_badly, "from create topology (timeout)"); +} + + +static void +my_cb (void *cls, + const struct GNUNET_PeerIdentity *id, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Daemon *d, const char *emsg) +{ + GNUNET_assert (id != NULL); +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n", + (num_peers - peers_left) + 1, num_peers); +#endif + peers_left--; + if (peers_left == 0) + { +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "All %d daemons started, now creating topology!\n", + num_peers); +#endif + GNUNET_SCHEDULER_cancel (sched, die_task); + /* Set up task in case topology creation doesn't finish + * within a reasonable amount of time */ + die_task = GNUNET_SCHEDULER_add_delayed (sched, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_MINUTES, 5), + &end_badly, "from my_cb"); + create_topology (); + ok = 0; + } +} + + +static void +run (void *cls, + struct GNUNET_SCHEDULER_Handle *s, + char *const *args, + const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + unsigned long long topology_num; + sched = s; + ok = 1; + + dotOutFileName = strdup("topology.dot"); + dotOutFile = fopen (dotOutFileName, "w"); + if (dotOutFile != NULL) + { + fprintf (dotOutFile, "strict graph G {\n"); + } + +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting daemons based on config file %s\n", cfgfile); +#endif + + if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_string(cfg, "paths", "servicehome", &test_directory)) + { + ok = 404; + return; + } + + if (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "topology", + &topology_num)) + topology = topology_num; + + if (GNUNET_SYSERR == + GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", + &num_peers)) + num_peers = DEFAULT_NUM_PEERS; + + main_cfg = cfg; + + peers_left = num_peers; + + /* Set up a task to end testing if peer start fails */ + die_task = GNUNET_SCHEDULER_add_delayed (sched, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_MINUTES, 5), + &end_badly, "didn't start all daemons in reasonable amount of time!!!"); + + pg = GNUNET_TESTING_daemons_start (sched, cfg, + peers_left, + TIMEOUT, + &my_cb, NULL, + &topology_callback, NULL, NULL); + +} + +static int +check () +{ + char *binary_name; + char *config_file_name; + GNUNET_asprintf(&binary_name, "test-dv-topology", topology_string); + GNUNET_asprintf(&config_file_name, "test_dv_topology.conf", topology_string); + + int ret; + char *const argv[] = {binary_name, + "-c", + config_file_name, +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + ret = GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, + argv, binary_name, "nohelp", + options, &run, &ok); + if (ret != GNUNET_OK) + { + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "`test-dv-topology': Failed with error code %d\n", ret); + } + GNUNET_free(binary_name); + GNUNET_free(config_file_name); + return ok; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + GNUNET_log_setup ("test-dv-topology", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + ret = check (); + + /** + * Need to remove base directory, subdirectories taken care + * of by the testing framework. + */ + if (GNUNET_DISK_directory_remove (test_directory) != GNUNET_OK) + { + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Failed to remove testing directory %s\n", test_directory); + } + + return ret; +} + +/* end of test_testing_group.c */ diff --git a/src/dv/test_dv_topology.conf b/src/dv/test_dv_topology.conf new file mode 100644 index 000000000..4eeee8fe2 --- /dev/null +++ b/src/dv/test_dv_topology.conf @@ -0,0 +1,68 @@ +[PATHS] +SERVICEHOME = /tmp/test-gnunet-dv/ +DEFAULTCONFIG = test_dv_topology.conf + +[resolver] +PORT = 2564 + +[topology] +BINARY = gnunet-daemon-topology +CONFIG = $DEFAULTCONFIG +FRIENDS = $SERVICEHOME/friends +AUTOCONNECT = YES +FRIENDS-ONLY = YES + + +[transport] +PORT = 2565 +PLUGINS = tcp dv +#PREFIX = xterm -e xterm -T transport -e gdb --args +#BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/transport/.libs/gnunet-service-transport +#PREFIX = valgrind --tool=memcheck --log-file=logs%p +#DEBUG = YES + +[arm] +PORT = 2566 +DEFAULTSERVICES = topology core dv statistics + +[statistics] +PORT = 2567 + +[transport-tcp] +PORT = 2568 + +[transport-udp] +PORT = 2568 + +[peerinfo] +PORT = 2569 +#DEBUG = YES +#PREFIX = xterm -e xterm -T peerinfo -e gdb --args +#BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/peerinfo/.libs/gnunet-service-peerinfo +#PREFIX = valgrind --tool=memcheck --log-file=peerinfo%p + +[core] +PORT = 2570 +#PREFIX = xterm -e xterm -T CORE -e gdb --args +#PREFIX = valgrind --tool=memcheck --log-file=logs%p +#DEBUG = YES + +[dv] +DEBUG = NO +ALLOW_SHUTDOWN = YES +ACCEPT_FROM6 = ::1; +ACCEPT_FROM = 127.0.0.1; +BINARY = gnunet-service-dv +#BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/dv/.libs/gnunet-service-dv +#PREFIX = xterm -T dvservice -e gdb --args +#PREFIX = valgrind --log-file=dv1-%p --leak-check=full +CONFIG = $DEFAULTCONFIG +HOME = $SERVICEHOME +HOSTNAME = localhost +PORT = 2571 + +[testing] +NUM_PEERS = 6 +WEAKRANDOM = YES +TOPOLOGY = 3 +F2F = YES diff --git a/src/dv/test_transport_api_dv.c b/src/dv/test_transport_api_dv.c index 3beb23a11..50eeeb60c 100644 --- a/src/dv/test_transport_api_dv.c +++ b/src/dv/test_transport_api_dv.c @@ -55,13 +55,17 @@ #define MTYPE 12345 +static int num_wanted = 2; + +static int num_received = 0; + struct PeerContext { struct GNUNET_CONFIGURATION_Handle *cfg; struct GNUNET_TRANSPORT_Handle *th; struct GNUNET_PeerIdentity id; const char *cfg_file; - const struct GNUNET_HELLO_Message *hello; + struct GNUNET_HELLO_Message *hello; #if START_ARM pid_t arm_pid; #endif @@ -73,6 +77,8 @@ static struct PeerContext p2; static struct PeerContext p3; +static struct PeerContext p4; + static struct GNUNET_SCHEDULER_Handle *sched; static int ok; @@ -91,15 +97,38 @@ end () { /* do work here */ GNUNET_SCHEDULER_cancel (sched, die_task); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 1!\n"); - GNUNET_TRANSPORT_disconnect (p1.th); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 2!\n"); - GNUNET_TRANSPORT_disconnect (p2.th); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 3!\n"); - GNUNET_TRANSPORT_disconnect (p3.th); + + if (p1.th != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 1!\n"); + GNUNET_TRANSPORT_disconnect (p1.th); + p1.th = NULL; + } + + if (p2.th != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 2!\n"); + GNUNET_TRANSPORT_disconnect (p2.th); + p2.th = NULL; + } + + if (p3.th != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 3!\n"); + GNUNET_TRANSPORT_disconnect (p3.th); + p3.th = NULL; + } + + if (p4.th != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transport 4!\n"); + GNUNET_TRANSPORT_disconnect (p4.th); + p4.th = NULL; + } die_task = GNUNET_SCHEDULER_NO_TASK; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transports disconnected, returning success!\n"); + sleep(2); ok = 0; } @@ -155,10 +184,30 @@ end_badly () fprintf(stderr, "Ending on an unhappy note.\n"); #endif - GNUNET_TRANSPORT_disconnect (p1.th); - GNUNET_TRANSPORT_disconnect (p2.th); - GNUNET_TRANSPORT_disconnect (p3.th); + if (p1.th != NULL) + { + GNUNET_TRANSPORT_disconnect (p1.th); + p1.th = NULL; + } + if (p2.th != NULL) + { + GNUNET_TRANSPORT_disconnect (p2.th); + p2.th = NULL; + } + + if (p3.th != NULL) + { + GNUNET_TRANSPORT_disconnect (p3.th); + p3.th = NULL; + } + + if (p4.th != NULL) + { + GNUNET_TRANSPORT_disconnect (p4.th); + p4.th = NULL; + } + sleep(2); ok = 1; return; } @@ -170,17 +219,22 @@ notify_receive (void *cls, struct GNUNET_TIME_Relative latency, uint32_t distance) { - if (ntohs(message->type) != MTYPE) return; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %d from peer (%p) distance %d!\n", - ntohs(message->type), cls, distance); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %d from peer (%p) distance %d latency %u!\n", + ntohs(message->type), cls, distance, latency.value); GNUNET_assert (MTYPE == ntohs (message->type)); GNUNET_assert (sizeof (struct GNUNET_MessageHeader) == ntohs (message->size)); - end (); + num_received++; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %d of %d messages.\n", num_received, num_wanted); + + if (num_wanted == num_received) + { + end (); + } } @@ -221,6 +275,8 @@ notify_connect (void *cls, peer_num = 2; else if (cls == &p3) peer_num = 3; + else if (cls == &p4) + peer_num = 4; if (memcmp(peer, &p1.id, sizeof(struct GNUNET_PeerIdentity)) == 0) connect_num = 1; @@ -228,18 +284,31 @@ notify_connect (void *cls, connect_num = 2; else if (memcmp(peer, &p3.id, sizeof(struct GNUNET_PeerIdentity)) == 0) connect_num = 3; + else if (memcmp(peer, &p4.id, sizeof(struct GNUNET_PeerIdentity)) == 0) + connect_num = 4; + else + connect_num = -1; if ((cls == &p1) && (memcmp(peer, &p3.id, sizeof(struct GNUNET_PeerIdentity)) == 0)) { - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peer 1 notified about connection to peer 3, distance %u!\n", distance); - GNUNET_TRANSPORT_notify_transmit_ready (p1.th, &p3.id, 256, 0, TIMEOUT, ¬ify_ready, &p1); } + + if ((cls == &p4) && (memcmp(peer, &p1.id, sizeof(struct GNUNET_PeerIdentity)) == 0)) + { + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer 4 notified about connection to peer 1, distance %u!\n", distance); + + GNUNET_TRANSPORT_notify_transmit_ready (p4.th, + &p1.id, + 256, 0, TIMEOUT, ¬ify_ready, + &p4); + } + GNUNET_asprintf(&from_peer_str, "%s", GNUNET_i2s(&from_peer->id)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%d' %4s connected to peer `%d' %4s distance %d!\n", peer_num, from_peer_str, connect_num, GNUNET_i2s(peer), distance); @@ -272,37 +341,144 @@ setup_peer (struct PeerContext *p, const char *cfgname) } +static void blacklist_peer(struct GNUNET_DISK_FileHandle *file, struct PeerContext *peer) +{ + struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc; + char *buf; + size_t size; + + GNUNET_CRYPTO_hash_to_enc(&peer->id.hashPubKey, &peer_enc); + size = GNUNET_asprintf(&buf, "%s:%s\n", "tcp", (char *)&peer_enc); + GNUNET_DISK_file_write(file, buf, size); + GNUNET_free_non_null(buf); +} + static void -exchange_hello_last (void *cls, - const struct GNUNET_MessageHeader *message) +setup_blacklists (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct PeerContext *me = cls; + char *blacklist_filename; + struct GNUNET_DISK_FileHandle *file; + int i; + + for (i = 1; i <= 4; i++) + { + GNUNET_asprintf(&blacklist_filename, "/tmp/test-gnunetd-transport-peer-%d/blacklist", i); + if (blacklist_filename != NULL) + { + file = GNUNET_DISK_file_open(blacklist_filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_TRUNCATE | GNUNET_DISK_OPEN_CREATE, + GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); + GNUNET_free(blacklist_filename); + + if (file == NULL) + { + GNUNET_SCHEDULER_cancel(sched, die_task); + GNUNET_SCHEDULER_add_now(sched, &end_badly, NULL); + return; + } + switch (i) + { + case 1: + blacklist_peer(file, &p3); + blacklist_peer(file, &p4); + break; + case 2: + blacklist_peer(file, &p4); + break; + case 3: + blacklist_peer(file, &p1); + break; + case 4: + blacklist_peer(file, &p1); + blacklist_peer(file, &p2); + break; + } + } + } - GNUNET_TRANSPORT_get_hello_cancel (p3.th, &exchange_hello_last, me); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Disconnecting transports...\n"); - GNUNET_assert (message != NULL); - GNUNET_assert (GNUNET_OK == - GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) - message, &me->id)); + if (p1.th != NULL) + { + GNUNET_TRANSPORT_disconnect (p1.th); + p1.th = NULL; + } + + if (p2.th != NULL) + { + GNUNET_TRANSPORT_disconnect (p2.th); + p2.th = NULL; + } + + if (p3.th != NULL) + { + GNUNET_TRANSPORT_disconnect (p3.th); + p3.th = NULL; + } + + if (p4.th != NULL) + { + GNUNET_TRANSPORT_disconnect (p4.th); + p4.th = NULL; + } + + sleep(1); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received HELLO size %d\n", GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); + "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", p1.arm_pid, p1.cfg_file); + restart_transport(&p1); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", p2.arm_pid, p2.cfg_file); + restart_transport(&p2); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Finished exchanging HELLOs, now waiting for transmission!\n"); + "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", p3.arm_pid, p3.cfg_file); + restart_transport(&p3); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", p4.arm_pid, p4.cfg_file); + restart_transport(&p4); + + p1.th = GNUNET_TRANSPORT_connect (sched, p1.cfg, + &p1, + ¬ify_receive, + ¬ify_connect, ¬ify_disconnect); + + p2.th = GNUNET_TRANSPORT_connect (sched, p2.cfg, + &p2, + ¬ify_receive, + ¬ify_connect, ¬ify_disconnect); + + p3.th = GNUNET_TRANSPORT_connect (sched, p3.cfg, + &p3, + ¬ify_receive, + ¬ify_connect, ¬ify_disconnect); + + p4.th = GNUNET_TRANSPORT_connect (sched, p4.cfg, + &p4, + ¬ify_receive, + ¬ify_connect, ¬ify_disconnect); + GNUNET_assert(p1.th != NULL); + GNUNET_assert(p2.th != NULL); + GNUNET_assert(p3.th != NULL); + GNUNET_assert(p4.th != NULL); + + GNUNET_TRANSPORT_offer_hello (p1.th, GNUNET_HELLO_get_header(p2.hello)); + GNUNET_TRANSPORT_offer_hello (p2.th, GNUNET_HELLO_get_header(p3.hello)); + GNUNET_TRANSPORT_offer_hello (p3.th, GNUNET_HELLO_get_header(p4.hello)); } static void -exchange_hello_next (void *cls, +get_hello_fourth (void *cls, const struct GNUNET_MessageHeader *message) { struct PeerContext *me = cls; - GNUNET_TRANSPORT_get_hello_cancel (p2.th, &exchange_hello_next, me); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Exchanging HELLO with peer (%p)!\n", cls); + GNUNET_TRANSPORT_get_hello_cancel (me->th, &get_hello_fourth, me); GNUNET_assert (message != NULL); GNUNET_assert (GNUNET_OK == @@ -312,30 +488,23 @@ exchange_hello_next (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received HELLO size %d\n", GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); - GNUNET_TRANSPORT_offer_hello (p3.th, message); - - GNUNET_TRANSPORT_get_hello (p3.th, &exchange_hello_last, &p3); + me->hello = GNUNET_malloc(GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); + memcpy(me->hello, message, GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "All HELLO's received, setting up blacklists!\n"); + GNUNET_SCHEDULER_add_now(sched, &setup_blacklists, NULL); } static void -exchange_hello (void *cls, +get_hello_third (void *cls, const struct GNUNET_MessageHeader *message) { struct PeerContext *me = cls; - GNUNET_TRANSPORT_get_hello_cancel (p1.th, &exchange_hello, me); - p2.th = GNUNET_TRANSPORT_connect (sched, p2.cfg, - &p2, - ¬ify_receive, - ¬ify_connect, ¬ify_disconnect); - - GNUNET_assert(p2.th != NULL); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Exchanging HELLO with peer (%p)!\n", cls); + GNUNET_TRANSPORT_get_hello_cancel (me->th, &get_hello_third, me); GNUNET_assert (message != NULL); GNUNET_assert (GNUNET_OK == @@ -345,118 +514,57 @@ exchange_hello (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received HELLO size %d\n", GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); - GNUNET_TRANSPORT_offer_hello (p2.th, message); - GNUNET_TRANSPORT_get_hello (p2.th, &exchange_hello_next, &p2); + me->hello = GNUNET_malloc(GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); + memcpy(me->hello, message, GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); + + GNUNET_TRANSPORT_get_hello (p4.th, &get_hello_fourth, &p4); } + static void -blacklist_setup_third (void *cls, +get_hello_second (void *cls, const struct GNUNET_MessageHeader *message) { struct PeerContext *me = cls; - char *blacklist_filename; - struct GNUNET_DISK_FileHandle *file; - struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc; - char *buf; - size_t size; - GNUNET_TRANSPORT_get_hello_cancel (p3.th, &blacklist_setup_third, &p3); + GNUNET_TRANSPORT_get_hello_cancel (me->th, &get_hello_second, me); GNUNET_assert (message != NULL); GNUNET_assert (GNUNET_OK == GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) message, &me->id)); - GNUNET_asprintf(&blacklist_filename, "/tmp/test-gnunetd-transport-peer-1/blacklist"); - if (blacklist_filename != NULL) - { - file = GNUNET_DISK_file_open(blacklist_filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_TRUNCATE | GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); - GNUNET_free(blacklist_filename); - - if (file == NULL) - { - GNUNET_SCHEDULER_cancel(sched, die_task); - GNUNET_SCHEDULER_add_now(sched, &end_badly, NULL); - return; - } - GNUNET_CRYPTO_hash_to_enc(&me->id.hashPubKey, &peer_enc); - size = GNUNET_asprintf(&buf, "%s:%s\n", "tcp", (char *)&peer_enc); - GNUNET_DISK_file_write(file, buf, size); - GNUNET_free_non_null(buf); - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", cls, p1.cfg_file); - - restart_transport(&p1); + "Received HELLO size %d\n", GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); - p1.th = GNUNET_TRANSPORT_connect (sched, p1.cfg, - &p1, - ¬ify_receive, - ¬ify_connect, ¬ify_disconnect); + me->hello = GNUNET_malloc(GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); + memcpy(me->hello, message, GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); - GNUNET_TRANSPORT_get_hello (p1.th, &exchange_hello, &p1); + GNUNET_TRANSPORT_get_hello (p3.th, &get_hello_third, &p3); } + static void -blacklist_setup_first (void *cls, +get_hello_first (void *cls, const struct GNUNET_MessageHeader *message) { struct PeerContext *me = cls; - char *blacklist_filename; - struct GNUNET_DISK_FileHandle *file; - struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc; - char *buf; - size_t size; - GNUNET_TRANSPORT_get_hello_cancel (p1.th, &blacklist_setup_first, me); - sleep(2); + GNUNET_TRANSPORT_get_hello_cancel (me->th, &get_hello_first, me); GNUNET_assert (message != NULL); GNUNET_assert (GNUNET_OK == GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) message, &me->id)); - GNUNET_asprintf(&blacklist_filename, "/tmp/test-gnunetd-transport-peer-3/blacklist"); - if (blacklist_filename != NULL) - { - file = GNUNET_DISK_file_open(blacklist_filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_TRUNCATE | GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); - GNUNET_free(blacklist_filename); - - if (file == NULL) - { - GNUNET_SCHEDULER_cancel(sched, die_task); - GNUNET_SCHEDULER_add_now(sched, &end_badly, NULL); - return; - } - GNUNET_CRYPTO_hash_to_enc(&me->id.hashPubKey, &peer_enc); - size = GNUNET_asprintf(&buf, "%s:%s\n", "tcp", (char *)&peer_enc); - GNUNET_DISK_file_write(file, buf, size); - GNUNET_free_non_null(buf); - } - - GNUNET_TRANSPORT_disconnect(p1.th); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Restarting transport service (%p) with gnunet-arm -c %s -L DEBUG -k transport!\n", cls, p3.cfg_file); - restart_transport(&p3); + "Received HELLO size %d\n", GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "reconnecting to transport (%p)!\n", cls); - p3.th = GNUNET_TRANSPORT_connect (sched, p3.cfg, - &p3, - ¬ify_receive, - ¬ify_connect, ¬ify_disconnect); - if (p3.th != NULL) - GNUNET_TRANSPORT_get_hello (p3.th, &blacklist_setup_third, &p3); - else - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "reconnecting to transport (%p) failed.!\n", cls); - //GNUNET_TRANSPORT_get_hello (p1.th, &exchange_hello, &p1); -} + me->hello = GNUNET_malloc(GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); + memcpy(me->hello, message, GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message)); + GNUNET_TRANSPORT_get_hello (p2.th, &get_hello_second, &p2); +} static void run (void *cls, @@ -474,16 +582,33 @@ run (void *cls, setup_peer (&p1, "test_transport_api_dv_peer1.conf"); setup_peer (&p2, "test_transport_api_dv_peer2.conf"); setup_peer (&p3, "test_transport_api_dv_peer3.conf"); + setup_peer (&p4, "test_transport_api_dv_peer4.conf"); p1.th = GNUNET_TRANSPORT_connect (sched, p1.cfg, &p1, ¬ify_receive, ¬ify_connect, ¬ify_disconnect); + + p2.th = GNUNET_TRANSPORT_connect (sched, p2.cfg, + &p2, + ¬ify_receive, + ¬ify_connect, ¬ify_disconnect); + + p3.th = GNUNET_TRANSPORT_connect (sched, p3.cfg, + &p3, + ¬ify_receive, + ¬ify_connect, ¬ify_disconnect); + + p4.th = GNUNET_TRANSPORT_connect (sched, p4.cfg, + &p4, + ¬ify_receive, + ¬ify_connect, ¬ify_disconnect); GNUNET_assert(p1.th != NULL); - /*GNUNET_assert(p2.th != NULL); - GNUNET_assert(p3.th != NULL);*/ + GNUNET_assert(p2.th != NULL); + GNUNET_assert(p3.th != NULL); + GNUNET_assert(p4.th != NULL); - GNUNET_TRANSPORT_get_hello (p1.th, &blacklist_setup_first, &p1); + GNUNET_TRANSPORT_get_hello (p1.th, &get_hello_first, &p1); } static int @@ -510,6 +635,7 @@ check () stop_arm (&p1); stop_arm (&p2); stop_arm (&p3); + stop_arm (&p4); return ok; } @@ -533,7 +659,9 @@ main (int argc, char *argv[]) GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-1"); GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-2"); GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-3"); + GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-4"); return ret; } /* end of test_transport_api_dv.c */ + diff --git a/src/dv/test_transport_api_dv_peer4.conf b/src/dv/test_transport_api_dv_peer4.conf new file mode 100644 index 000000000..4b569f62a --- /dev/null +++ b/src/dv/test_transport_api_dv_peer4.conf @@ -0,0 +1,111 @@ +[topology] +BINARY = gnunet-daemon-topology +CONFIG = $DEFAULTCONFIG +FRIENDS = $SERVICEHOME/friends +TARGET-CONNECTION-COUNT = 16 +AUTOCONNECT = YES +FRIENDS-ONLY = NO +MINIMUM-FRIENDS = 0 + +[transport] +PLUGINS = tcp dv +DEBUG = NO +ALLOW_SHUTDOWN = YES +ACCEPT_FROM6 = ::1; +ACCEPT_FROM = 127.0.0.1; +NEIGHBOUR_LIMIT = 50 +#BINARY = /root/documents/research/gnunet/gnunet-ng/src/transport/.libs/gnunet-service-transport +BINARY = gnunet-service-transport +#BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/transport/.libs/gnunet-service-transport +CONFIG = $DEFAULTCONFIG +HOME = $SERVICEHOME +HOSTNAME = localhost +PORT = 42365 +#PREFIX = xterm -T transport1 -e gdb --args +#PREFIX = valgrind --leak-check=full +BLACKLIST_FILE = $SERVICEHOME/blacklist + +[peerinfo] +TRUST = $SERVICEHOME/data/credit/ +HOSTS = $SERVICEHOME/data/hosts/ +ALLOW_SHUTDOWN = YES +ACCEPT_FROM6 = ::1; +ACCEPT_FROM = 127.0.0.1; +BINARY = gnunet-service-peerinfo +CONFIG = $DEFAULTCONFIG +HOME = $SERVICEHOME +HOSTNAME = localhost +PORT = 42369 + +[resolver] +ALLOW_SHUTDOWN = YES +ACCEPT_FROM6 = ::1; +ACCEPT_FROM = 127.0.0.1; +BINARY = gnunet-service-resolver +CONFIG = $DEFAULTCONFIG +HOME = $SERVICEHOME +HOSTNAME = localhost +PORT = 42364 + +[core] +TOTAL_QUOTA_OUT = 3932160 +TOTAL_QUOTA_IN = 3932160 +ALLOW_SHUTDOWN = YES +ACCEPT_FROM6 = ::1; +ACCEPT_FROM = 127.0.0.1; +BINARY = gnunet-service-core +CONFIG = $DEFAULTCONFIG +HOME = $SERVICEHOME +HOSTNAME = localhost +PORT = 42092 + +[statistics] +ALLOW_SHUTDOWN = YES +ACCEPT_FROM6 = ::1; +ACCEPT_FROM = 127.0.0.1; +BINARY = gnunet-service-statistics +CONFIG = $DEFAULTCONFIG +HOME = $SERVICEHOME +HOSTNAME = localhost +PORT = 42367 + +[dv] +DEBUG = NO +ALLOW_SHUTDOWN = YES +ACCEPT_FROM6 = ::1; +ACCEPT_FROM = 127.0.0.1; +BINARY = gnunet-service-dv +BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/dv/.libs/gnunet-service-dv +#PREFIX = xterm -T dvservice4 -e gdb --args +#PREFIX = valgrind --log-file=dv4-%p --leak-check=full --show-reachable=yes +CONFIG = $DEFAULTCONFIG +HOME = $SERVICEHOME +HOSTNAME = localhost +PORT = 42370 + +[arm] +DEFAULTSERVICES = core dv statistics +ALLOW_SHUTDOWN = YES +ACCEPT_FROM6 = ::1; +ACCEPT_FROM = 127.0.0.1; +BINARY = gnunet-service-arm +CONFIG = $DEFAULTCONFIG +HOME = $SERVICEHOME +HOSTNAME = localhost +PORT = 42366 + +[transport-tcp] +ALLOW_SHUTDOWN = NO +TIMEOUT = 300000 +PORT = 42368 + +[TESTING] +WEAKRANDOM = YES + +[gnunetd] +HOSTKEY = $SERVICEHOME/.hostkey + +[PATHS] +DEFAULTCONFIG = test_transport_api_dv_peer4.conf +SERVICEHOME = /tmp/test-gnunetd-transport-peer-4/ + -- 2.25.1