From 93287c8fecfc7fce37f0d9dfb1dc5b1bd7a9f7b3 Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Wed, 22 May 2013 12:19:53 +0000 Subject: changes --- .../gnunet-daemon-experimentation.c | 146 +++++++++++++++++---- 1 file changed, 123 insertions(+), 23 deletions(-) (limited to 'src/experimentation/gnunet-daemon-experimentation.c') diff --git a/src/experimentation/gnunet-daemon-experimentation.c b/src/experimentation/gnunet-daemon-experimentation.c index 8a6fba4b2..0f39b926f 100644 --- a/src/experimentation/gnunet-daemon-experimentation.c +++ b/src/experimentation/gnunet-daemon-experimentation.c @@ -26,16 +26,18 @@ */ #include "platform.h" #include "gnunet_getopt_lib.h" -#include "gnunet_container_lib.h" -#include "gnunet_program_lib.h" +#include "gnunet_util_lib.h" #include "gnunet_core_service.h" +#include "gnunet_statistics_service.h" -#define EXP_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) +#define EXP_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) static struct GNUNET_CORE_Handle *ch; static struct GNUNET_PeerIdentity me; +static struct GNUNET_STATISTICS_Handle *stats; + /** * A experimentation node */ @@ -44,6 +46,14 @@ struct Node struct GNUNET_PeerIdentity id; GNUNET_SCHEDULER_TaskIdentifier timeout_task; + + struct GNUNET_CORE_TransmitHandle *cth; +}; + + +struct Experimentation_Request +{ + struct GNUNET_MessageHeader msg; }; /** @@ -64,6 +74,31 @@ struct GNUNET_CONTAINER_MultiHashMap *nodes_active; struct GNUNET_CONTAINER_MultiHashMap *nodes_inactive; +static void update_stats (struct GNUNET_CONTAINER_MultiHashMap *m) +{ + GNUNET_assert (NULL != m); + GNUNET_assert (NULL != stats); + + if (m == nodes_active) + { + GNUNET_STATISTICS_set (stats, "# nodes active", + GNUNET_CONTAINER_multihashmap_size(m), GNUNET_NO); + } + else if (m == nodes_inactive) + { + GNUNET_STATISTICS_set (stats, "# nodes inactive", + GNUNET_CONTAINER_multihashmap_size(m), GNUNET_NO); + } + else if (m == nodes_requested) + { + GNUNET_STATISTICS_set (stats, "# nodes requested", + GNUNET_CONTAINER_multihashmap_size(m), GNUNET_NO); + } + else + GNUNET_break (0); + +} + static int cleanup_nodes (void *cls, const struct GNUNET_HashCode * key, @@ -78,6 +113,12 @@ cleanup_nodes (void *cls, GNUNET_SCHEDULER_cancel (n->timeout_task); n->timeout_task = GNUNET_SCHEDULER_NO_TASK; } + if (NULL != n->cth) + { + GNUNET_CORE_notify_transmit_ready_cancel (n->cth); + n->cth = NULL; + } + GNUNET_CONTAINER_multihashmap_remove (cur, key, value); GNUNET_free (value); @@ -105,6 +146,7 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_CONTAINER_multihashmap_iterate (nodes_requested, &cleanup_nodes, nodes_requested); + update_stats (nodes_requested); GNUNET_CONTAINER_multihashmap_destroy (nodes_requested); nodes_requested = NULL; } @@ -114,6 +156,7 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_CONTAINER_multihashmap_iterate (nodes_active, &cleanup_nodes, nodes_active); + update_stats (nodes_active); GNUNET_CONTAINER_multihashmap_destroy (nodes_active); nodes_active = NULL; } @@ -123,9 +166,16 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_CONTAINER_multihashmap_iterate (nodes_inactive, &cleanup_nodes, nodes_inactive); + update_stats (nodes_inactive); GNUNET_CONTAINER_multihashmap_destroy (nodes_inactive); nodes_inactive = NULL; } + + if (NULL != stats) + { + GNUNET_STATISTICS_destroy (stats, GNUNET_NO); + stats = NULL; + } } static int is_me (const struct GNUNET_PeerIdentity *id) @@ -149,18 +199,74 @@ remove_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct Node *n = cls; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Removing request for peer %s due to timeout\n"), + GNUNET_i2s (&n->id)); + if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (nodes_requested, &n->id.hashPubKey)) GNUNET_break (0); else { GNUNET_CONTAINER_multihashmap_remove (nodes_requested, &n->id.hashPubKey, n); + update_stats (nodes_requested); GNUNET_CONTAINER_multihashmap_put (nodes_inactive, &n->id.hashPubKey, n, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); + update_stats (nodes_inactive); n->timeout_task = GNUNET_SCHEDULER_NO_TASK; + if (NULL != n->cth) + { + GNUNET_CORE_notify_transmit_ready_cancel (n->cth); + n->cth = NULL; + } } } +size_t send_request_cb (void *cls, size_t bufsize, void *buf) +{ + struct Node *n = cls; + struct Experimentation_Request msg; + size_t size = sizeof (msg); + + n->cth = NULL; + if (buf == NULL) + { + /* client disconnected */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected\n"); + if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task) + GNUNET_SCHEDULER_cancel (n->timeout_task); + GNUNET_SCHEDULER_add_now (&remove_request, n); + return 0; + } + GNUNET_assert (bufsize >= size); + + msg.msg.size = htons (size); + msg.msg.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_REQUEST); + memcpy (buf, &msg, size); + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Sending request to peer %s\n"), + GNUNET_i2s (&n->id)); + return size; +} + +static void send_request (const struct GNUNET_PeerIdentity *peer) +{ + struct Node *n; + size_t size; + + size = sizeof (struct Experimentation_Request); + n = GNUNET_malloc (sizeof (struct Node)); + n->id = *peer; + n->timeout_task = GNUNET_SCHEDULER_add_delayed (EXP_RESPONSE_TIMEOUT, &remove_request, n); + n->cth = GNUNET_CORE_notify_transmit_ready(ch, GNUNET_NO, 0, + GNUNET_TIME_relative_get_forever_(), + peer, size, send_request_cb, n); + + GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (nodes_requested, + &peer->hashPubKey, n, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); + + update_stats (nodes_requested); +} + /** * Method called whenever a given peer connects. * @@ -168,10 +274,8 @@ remove_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @param peer peer identity this notification is about */ void core_connect_handler (void *cls, - const struct GNUNET_PeerIdentity * peer) + const struct GNUNET_PeerIdentity *peer) { - struct Node *n; - if (GNUNET_YES == is_me(peer)) return; @@ -182,23 +286,12 @@ void core_connect_handler (void *cls, return; /* We already sent a request */ if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (nodes_active, &peer->hashPubKey)) - return; /*This peer is known as active */ + return; /* This peer is known as active */ if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (nodes_inactive, &peer->hashPubKey)) - return; /*This peer is known as inactive */ - - /* Send request */ - GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Sending request to peer %s\n"), - GNUNET_i2s (peer)); - - n = GNUNET_malloc (sizeof (struct Node)); - n->id = *peer; - n->timeout_task = GNUNET_SCHEDULER_add_delayed (EXP_RESPONSE_TIMEOUT, &remove_request, n); - - GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (nodes_requested, - &peer->hashPubKey, n, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); - + return; /* This peer is known as inactive */ + send_request (peer); } @@ -232,9 +325,12 @@ run (void *cls, char *const *args, const char *cfgfile, { GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Experimentation daemon starting ...\n")); - nodes_requested = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); - nodes_active = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); - nodes_inactive = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); + stats = GNUNET_STATISTICS_create ("experimentation", cfg); + if (NULL == stats) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to create statistics!\n")); + return; + } /* Connecting to core service to find partners */ ch = GNUNET_CORE_connect (cfg, NULL, @@ -248,6 +344,10 @@ run (void *cls, char *const *args, const char *cfgfile, return; } + nodes_requested = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); + nodes_active = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); + nodes_inactive = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, NULL); -- cgit v1.2.3