[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r27264 - gnunet/src/experimentation
From: |
gnunet |
Subject: |
[GNUnet-SVN] r27264 - gnunet/src/experimentation |
Date: |
Thu, 23 May 2013 13:19:19 +0200 |
Author: wachs
Date: 2013-05-23 13:19:19 +0200 (Thu, 23 May 2013)
New Revision: 27264
Added:
gnunet/src/experimentation/gnunet-daemon-experimentation.h
gnunet/src/experimentation/gnunet-daemon-experimentation_nodes.c
Modified:
gnunet/src/experimentation/Makefile.am
gnunet/src/experimentation/gnunet-daemon-experimentation.c
gnunet/src/experimentation/test_experimentation_clique.c
Log:
split up code to multiple files
Modified: gnunet/src/experimentation/Makefile.am
===================================================================
--- gnunet/src/experimentation/Makefile.am 2013-05-23 10:45:49 UTC (rev
27263)
+++ gnunet/src/experimentation/Makefile.am 2013-05-23 11:19:19 UTC (rev
27264)
@@ -28,7 +28,7 @@
gnunet-daemon-experimentation
gnunet_daemon_experimentation_SOURCES = \
- gnunet-daemon-experimentation.c
+ gnunet-daemon-experimentation.c gnunet-daemon-experimentation_nodes.c
gnunet_daemon_experimentation_LDADD = \
$(top_builddir)/src/core/libgnunetcore.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
Modified: gnunet/src/experimentation/gnunet-daemon-experimentation.c
===================================================================
--- gnunet/src/experimentation/gnunet-daemon-experimentation.c 2013-05-23
10:45:49 UTC (rev 27263)
+++ gnunet/src/experimentation/gnunet-daemon-experimentation.c 2013-05-23
11:19:19 UTC (rev 27264)
@@ -29,462 +29,29 @@
#include "gnunet_util_lib.h"
#include "gnunet_core_service.h"
#include "gnunet_statistics_service.h"
+#include "gnunet-daemon-experimentation.h"
-#define EXP_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 2)
+#define EXP_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 10)
-static struct GNUNET_CORE_Handle *ch;
-static struct GNUNET_PeerIdentity me;
-
static struct GNUNET_STATISTICS_Handle *stats;
/**
- * A experimentation node
- */
-struct Node
-{
- struct GNUNET_PeerIdentity id;
-
- GNUNET_SCHEDULER_TaskIdentifier timeout_task;
-
- struct GNUNET_CORE_TransmitHandle *cth;
-};
-
-
-struct Experimentation_Request
-{
- struct GNUNET_MessageHeader msg;
-};
-
-struct Experimentation_Response
-{
- struct GNUNET_MessageHeader msg;
-};
-
-
-/**
- * Nodes with a pending request
- */
-
-struct GNUNET_CONTAINER_MultiHashMap *nodes_requested;
-
-/**
- * Active experimentation nodes
- */
-struct GNUNET_CONTAINER_MultiHashMap *nodes_active;
-
-/**
- * Inactive experimentation nodes
- * To be excluded from future requests
- */
-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,
- void *value)
-{
- struct Node *n;
- struct GNUNET_CONTAINER_MultiHashMap *cur = cls;
-
- n = value;
- if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task)
- {
- 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);
- return GNUNET_OK;
-}
-
-/**
* Task run during shutdown.
*
* @param cls unused
* @param tc unused
*/
static void
-cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Experimentation daemon shutting down
...\n"));
- if (NULL != ch)
- {
- GNUNET_CORE_disconnect (ch);
- ch = NULL;
- }
-
- if (NULL != nodes_requested)
- {
- GNUNET_CONTAINER_multihashmap_iterate (nodes_requested,
-
&cleanup_nodes,
-
nodes_requested);
- update_stats (nodes_requested);
- GNUNET_CONTAINER_multihashmap_destroy (nodes_requested);
- nodes_requested = NULL;
- }
-
- if (NULL != nodes_active)
- {
- GNUNET_CONTAINER_multihashmap_iterate (nodes_active,
-
&cleanup_nodes,
-
nodes_active);
- update_stats (nodes_active);
- GNUNET_CONTAINER_multihashmap_destroy (nodes_active);
- nodes_active = NULL;
- }
-
- if (NULL != nodes_inactive)
- {
- 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;
- }
+ GNUNET_EXPERIMENTATION_nodes_stop();
}
-static int is_me (const struct GNUNET_PeerIdentity *id)
-{
- if (0 == memcmp (&me, id, sizeof (me)))
- return GNUNET_YES;
- else
- return GNUNET_NO;
-}
-static void
-core_startup_handler (void *cls,
-
struct GNUNET_CORE_Handle * server,
- const struct GNUNET_PeerIdentity *my_identity)
-{
- me = *my_identity;
-}
-static void
-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);
-}
-
-size_t send_response_cb (void *cls, size_t bufsize, void *buf)
-{
- struct Node *n = cls;
- struct Experimentation_Response msg;
- size_t size = sizeof (msg);
-
- n->cth = NULL;
- if (buf == NULL)
- {
- /* client disconnected */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected\n");
- return 0;
- }
- GNUNET_assert (bufsize >= size);
-
- msg.msg.size = htons (size);
- msg.msg.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_RESPONSE);
- memcpy (buf, &msg, size);
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Sending response to peer %s\n"),
- GNUNET_i2s (&n->id));
- return size;
-}
-
-
-static void handle_request (const struct GNUNET_PeerIdentity *peer)
-{
- struct Node *n;
-
- if (NULL != (n = GNUNET_CONTAINER_multihashmap_get (nodes_active,
&peer->hashPubKey)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
- "REQUEST", "active", GNUNET_i2s (peer));
- }
- else if (NULL != (n = GNUNET_CONTAINER_multihashmap_get
(nodes_requested, &peer->hashPubKey)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
- "REQUEST", "requested", GNUNET_i2s
(peer));
- GNUNET_CONTAINER_multihashmap_remove (nodes_requested,
&peer->hashPubKey, n);
- if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task)
- {
- 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;
- }
- update_stats (nodes_requested);
- GNUNET_CONTAINER_multihashmap_put (nodes_active,
- &peer->hashPubKey, n,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
- update_stats (nodes_active);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Added peer `%s'
active node \n"),
- GNUNET_i2s (peer));
- }
- else if (NULL != (n = GNUNET_CONTAINER_multihashmap_get
(nodes_inactive, &peer->hashPubKey)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
- "REQUEST", "inactive", GNUNET_i2s
(peer));
- GNUNET_CONTAINER_multihashmap_remove (nodes_inactive,
&peer->hashPubKey, n);
- update_stats (nodes_inactive);
- GNUNET_CONTAINER_multihashmap_put (nodes_active,
- &peer->hashPubKey, n,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
- update_stats (nodes_active);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Added peer `%s'
active node \n"),
- GNUNET_i2s (peer));
- }
- else
- {
- /* Create new node */
- n = GNUNET_malloc (sizeof (struct Node));
- n->id = *peer;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
- "REQUEST", "new", GNUNET_i2s (peer));
- GNUNET_CONTAINER_multihashmap_put (nodes_active,
- &peer->hashPubKey, n,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
- update_stats (nodes_active);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Added peer `%s'
active node \n"),
- GNUNET_i2s (peer));
- }
-
- n->cth = GNUNET_CORE_notify_transmit_ready(ch, GNUNET_NO, 0,
-
GNUNET_TIME_relative_get_forever_(),
- peer, sizeof
(struct Experimentation_Response),
-
send_response_cb, n);
-}
-
-static void handle_response (const struct GNUNET_PeerIdentity *peer)
-{
- struct Node *n;
-
- if (NULL != (n = GNUNET_CONTAINER_multihashmap_get (nodes_active,
&peer->hashPubKey)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
- "RESPONSE", "active", GNUNET_i2s
(peer));
- }
- else if (NULL != (n = GNUNET_CONTAINER_multihashmap_get
(nodes_requested, &peer->hashPubKey)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
- "RESPONSE", "requested", GNUNET_i2s
(peer));
- GNUNET_CONTAINER_multihashmap_remove (nodes_requested,
&peer->hashPubKey, n);
- if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task)
- {
- 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;
- }
- update_stats (nodes_requested);
- GNUNET_CONTAINER_multihashmap_put (nodes_active,
- &peer->hashPubKey, n,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
- update_stats (nodes_active);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Added peer `%s'
active node \n"),
- GNUNET_i2s (peer));
- }
- else if (NULL != (n = GNUNET_CONTAINER_multihashmap_get
(nodes_inactive, &peer->hashPubKey)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
peer `%s'\n"),
- "RESPONSE", "inactive", GNUNET_i2s
(peer));
- GNUNET_CONTAINER_multihashmap_remove (nodes_inactive,
&peer->hashPubKey, n);
- update_stats (nodes_inactive);
- GNUNET_CONTAINER_multihashmap_put (nodes_active,
- &peer->hashPubKey, n,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
- update_stats (nodes_active);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Added peer `%s'
active node \n"),
- GNUNET_i2s (peer));
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
- "RESPONSE", "unknown", GNUNET_i2s
(peer));
- }
-}
-
/**
- * Method called whenever a given peer connects.
- *
- * @param cls closure
- * @param peer peer identity this notification is about
- */
-void core_connect_handler (void *cls,
- const struct GNUNET_PeerIdentity *peer)
-{
- if (GNUNET_YES == is_me(peer))
- return;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Connected to peer %s\n"),
- GNUNET_i2s (peer));
-
- if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains
(nodes_requested, &peer->hashPubKey))
- return; /* We already sent a request */
-
- if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (nodes_active,
&peer->hashPubKey))
- 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 (peer);
-
-}
-
-
-/**
- * Method called whenever a given peer disconnects.
- *
- * @param cls closure
- * @param peer peer identity this notification is about
- */
-void core_disconnect_handler (void *cls,
- const struct GNUNET_PeerIdentity * peer)
-{
- if (GNUNET_YES == is_me(peer))
- return;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Disconnected from peer %s\n"),
- GNUNET_i2s (peer));
-
-}
-
-
-static int
-core_receive_handler (void *cls,
-
const struct GNUNET_PeerIdentity *other,
-
const struct GNUNET_MessageHeader *message)
-{
- if (ntohs (message->size) < sizeof (struct GNUNET_MessageHeader))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
-
- switch (ntohs (message->type)) {
- case GNUNET_MESSAGE_TYPE_EXPERIMENTATION_REQUEST:
- handle_request (other);
- break;
- case GNUNET_MESSAGE_TYPE_EXPERIMENTATION_RESPONSE:
- handle_response (other);
- break;
- default:
- break;
- }
-
- return GNUNET_OK;
-}
-
-
-
-/**
* The main function for the experimentation daemon.
*
* @param argc number of arguments from the command line
@@ -503,24 +70,9 @@
return;
}
- /* Connecting to core service to find partners */
- ch = GNUNET_CORE_connect (cfg, NULL,
-
&core_startup_handler,
-
&core_connect_handler,
-
&core_disconnect_handler,
-
&core_receive_handler,
-
GNUNET_NO, NULL, GNUNET_NO, NULL);
- if (NULL == ch)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Failed to
connect to CORE service!\n"));
- return;
- }
+ GNUNET_EXPERIMENTATION_nodes_start (cfg);
- 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,
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
NULL);
}
Added: gnunet/src/experimentation/gnunet-daemon-experimentation.h
===================================================================
--- gnunet/src/experimentation/gnunet-daemon-experimentation.h
(rev 0)
+++ gnunet/src/experimentation/gnunet-daemon-experimentation.h 2013-05-23
11:19:19 UTC (rev 27264)
@@ -0,0 +1,70 @@
+/*
+ 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 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 experimentation/gnunet-daemon-experimentation.c
+ * @brief experimentation daemon
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_getopt_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)
+/**
+ * A experimentation node
+ */
+struct Node
+{
+ struct GNUNET_PeerIdentity id;
+
+ GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+
+ struct GNUNET_CORE_TransmitHandle *cth;
+};
+
+
+struct Experimentation_Request
+{
+ struct GNUNET_MessageHeader msg;
+};
+
+struct Experimentation_Response
+{
+ struct GNUNET_MessageHeader msg;
+};
+
+
+/**
+ * The main function for the experimentation daemon.
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ */
+void
+GNUNET_EXPERIMENTATION_nodes_start (const struct GNUNET_CONFIGURATION_Handle
*cfg);
+
+void
+GNUNET_EXPERIMENTATION_nodes_stop ();
+
+/* end of gnunet-daemon-experimentation.c */
Added: gnunet/src/experimentation/gnunet-daemon-experimentation_nodes.c
===================================================================
--- gnunet/src/experimentation/gnunet-daemon-experimentation_nodes.c
(rev 0)
+++ gnunet/src/experimentation/gnunet-daemon-experimentation_nodes.c
2013-05-23 11:19:19 UTC (rev 27264)
@@ -0,0 +1,495 @@
+/*
+ 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 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 experimentation/gnunet-daemon-experimentation.c
+ * @brief experimentation daemon
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_getopt_lib.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_core_service.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet-daemon-experimentation.h"
+
+#define EXP_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 10)
+
+static struct GNUNET_CORE_Handle *ch;
+
+static struct GNUNET_PeerIdentity me;
+
+static struct GNUNET_STATISTICS_Handle *stats;
+
+/**
+ * Nodes with a pending request
+ */
+
+struct GNUNET_CONTAINER_MultiHashMap *nodes_requested;
+
+/**
+ * Active experimentation nodes
+ */
+struct GNUNET_CONTAINER_MultiHashMap *nodes_active;
+
+/**
+ * Inactive experimentation nodes
+ * To be excluded from future requests
+ */
+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,
+ void *value)
+{
+ struct Node *n;
+ struct GNUNET_CONTAINER_MultiHashMap *cur = cls;
+
+ n = value;
+ if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task)
+ {
+ 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);
+ return GNUNET_OK;
+}
+
+
+static int is_me (const struct GNUNET_PeerIdentity *id)
+{
+ if (0 == memcmp (&me, id, sizeof (me)))
+ return GNUNET_YES;
+ else
+ return GNUNET_NO;
+}
+
+static void
+core_startup_handler (void *cls,
+
struct GNUNET_CORE_Handle * server,
+ const struct GNUNET_PeerIdentity *my_identity)
+{
+ me = *my_identity;
+}
+
+static void
+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_YES == GNUNET_CONTAINER_multihashmap_contains
(nodes_requested, &n->id.hashPubKey))
+ {
+ 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);
+}
+
+size_t send_response_cb (void *cls, size_t bufsize, void *buf)
+{
+ struct Node *n = cls;
+ struct Experimentation_Response msg;
+ size_t size = sizeof (msg);
+
+ n->cth = NULL;
+ if (buf == NULL)
+ {
+ /* client disconnected */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected\n");
+ return 0;
+ }
+ GNUNET_assert (bufsize >= size);
+
+ msg.msg.size = htons (size);
+ msg.msg.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_RESPONSE);
+ memcpy (buf, &msg, size);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Sending response to peer %s\n"),
+ GNUNET_i2s (&n->id));
+ return size;
+}
+
+
+static void handle_request (const struct GNUNET_PeerIdentity *peer)
+{
+ struct Node *n;
+
+ if (NULL != (n = GNUNET_CONTAINER_multihashmap_get (nodes_active,
&peer->hashPubKey)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
+ "REQUEST", "active", GNUNET_i2s (peer));
+ }
+ else if (NULL != (n = GNUNET_CONTAINER_multihashmap_get
(nodes_requested, &peer->hashPubKey)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
+ "REQUEST", "requested", GNUNET_i2s
(peer));
+ GNUNET_CONTAINER_multihashmap_remove (nodes_requested,
&peer->hashPubKey, n);
+ if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task)
+ {
+ 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;
+ }
+ update_stats (nodes_requested);
+ GNUNET_CONTAINER_multihashmap_put (nodes_active,
+ &peer->hashPubKey, n,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ update_stats (nodes_active);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Added peer `%s'
active node \n"),
+ GNUNET_i2s (peer));
+ }
+ else if (NULL != (n = GNUNET_CONTAINER_multihashmap_get
(nodes_inactive, &peer->hashPubKey)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
+ "REQUEST", "inactive", GNUNET_i2s
(peer));
+ GNUNET_CONTAINER_multihashmap_remove (nodes_inactive,
&peer->hashPubKey, n);
+ update_stats (nodes_inactive);
+ GNUNET_CONTAINER_multihashmap_put (nodes_active,
+ &peer->hashPubKey, n,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ update_stats (nodes_active);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Added peer `%s'
active node \n"),
+ GNUNET_i2s (peer));
+ }
+ else
+ {
+ /* Create new node */
+ n = GNUNET_malloc (sizeof (struct Node));
+ n->id = *peer;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
+ "REQUEST", "new", GNUNET_i2s (peer));
+ GNUNET_CONTAINER_multihashmap_put (nodes_active,
+ &peer->hashPubKey, n,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ update_stats (nodes_active);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Added peer `%s'
active node \n"),
+ GNUNET_i2s (peer));
+ }
+
+ n->cth = GNUNET_CORE_notify_transmit_ready (ch, GNUNET_NO, 0,
+
GNUNET_TIME_relative_get_forever_(),
+ peer, sizeof
(struct Experimentation_Response),
+
send_response_cb, n);
+}
+
+static void handle_response (const struct GNUNET_PeerIdentity *peer)
+{
+ struct Node *n;
+
+ if (NULL != (n = GNUNET_CONTAINER_multihashmap_get (nodes_active,
&peer->hashPubKey)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
+ "RESPONSE", "active", GNUNET_i2s
(peer));
+ }
+ else if (NULL != (n = GNUNET_CONTAINER_multihashmap_get
(nodes_requested, &peer->hashPubKey)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
+ "RESPONSE", "requested", GNUNET_i2s
(peer));
+ GNUNET_CONTAINER_multihashmap_remove (nodes_requested,
&peer->hashPubKey, n);
+ if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task)
+ {
+ 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;
+ }
+ update_stats (nodes_requested);
+ GNUNET_CONTAINER_multihashmap_put (nodes_active,
+ &peer->hashPubKey, n,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ update_stats (nodes_active);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Added peer `%s'
active node \n"),
+ GNUNET_i2s (peer));
+ }
+ else if (NULL != (n = GNUNET_CONTAINER_multihashmap_get
(nodes_inactive, &peer->hashPubKey)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
peer `%s'\n"),
+ "RESPONSE", "inactive", GNUNET_i2s
(peer));
+ GNUNET_CONTAINER_multihashmap_remove (nodes_inactive,
&peer->hashPubKey, n);
+ update_stats (nodes_inactive);
+ GNUNET_CONTAINER_multihashmap_put (nodes_active,
+ &peer->hashPubKey, n,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ update_stats (nodes_active);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Added peer `%s'
active node \n"),
+ GNUNET_i2s (peer));
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from
%s peer `%s'\n"),
+ "RESPONSE", "unknown", GNUNET_i2s
(peer));
+ }
+}
+
+/**
+ * Method called whenever a given peer connects.
+ *
+ * @param cls closure
+ * @param peer peer identity this notification is about
+ */
+void core_connect_handler (void *cls,
+ const struct GNUNET_PeerIdentity *peer)
+{
+ if (GNUNET_YES == is_me(peer))
+ return;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Connected to peer %s\n"),
+ GNUNET_i2s (peer));
+
+ if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains
(nodes_requested, &peer->hashPubKey))
+ return; /* We already sent a request */
+
+ if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (nodes_active,
&peer->hashPubKey))
+ 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 (peer);
+
+}
+
+
+/**
+ * Method called whenever a given peer disconnects.
+ *
+ * @param cls closure
+ * @param peer peer identity this notification is about
+ */
+void core_disconnect_handler (void *cls,
+ const struct GNUNET_PeerIdentity * peer)
+{
+ if (GNUNET_YES == is_me(peer))
+ return;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Disconnected from peer %s\n"),
+ GNUNET_i2s (peer));
+
+}
+
+
+static int
+core_receive_handler (void *cls,
+
const struct GNUNET_PeerIdentity *other,
+
const struct GNUNET_MessageHeader *message)
+{
+ if (ntohs (message->size) < sizeof (struct GNUNET_MessageHeader))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+
+ switch (ntohs (message->type)) {
+ case GNUNET_MESSAGE_TYPE_EXPERIMENTATION_REQUEST:
+ handle_request (other);
+ break;
+ case GNUNET_MESSAGE_TYPE_EXPERIMENTATION_RESPONSE:
+ handle_response (other);
+ break;
+ default:
+ break;
+ }
+
+ return GNUNET_OK;
+}
+
+
+
+/**
+ * The main function for the experimentation daemon.
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ */
+void
+GNUNET_EXPERIMENTATION_nodes_start (const struct GNUNET_CONFIGURATION_Handle
*cfg)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Experimentation daemon starting
...\n"));
+
+ stats = GNUNET_STATISTICS_create ("experimentation", cfg);
+ if (NULL == stats)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to create
statistics!\n"));
+ return;
+ }
+
+ /* Connecting to core service to find partners */
+ ch = GNUNET_CORE_connect (cfg, NULL,
+
&core_startup_handler,
+
&core_connect_handler,
+
&core_disconnect_handler,
+
&core_receive_handler,
+
GNUNET_NO, NULL, GNUNET_NO, NULL);
+ if (NULL == ch)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Failed to
connect to CORE service!\n"));
+ 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);
+}
+
+
+void
+GNUNET_EXPERIMENTATION_nodes_stop ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Experimentation daemon shutting down
...\n"));
+ if (NULL != ch)
+ {
+ GNUNET_CORE_disconnect (ch);
+ ch = NULL;
+ }
+
+ if (NULL != nodes_requested)
+ {
+ GNUNET_CONTAINER_multihashmap_iterate (nodes_requested,
+
&cleanup_nodes,
+
nodes_requested);
+ update_stats (nodes_requested);
+ GNUNET_CONTAINER_multihashmap_destroy (nodes_requested);
+ nodes_requested = NULL;
+ }
+
+ if (NULL != nodes_active)
+ {
+ GNUNET_CONTAINER_multihashmap_iterate (nodes_active,
+
&cleanup_nodes,
+
nodes_active);
+ update_stats (nodes_active);
+ GNUNET_CONTAINER_multihashmap_destroy (nodes_active);
+ nodes_active = NULL;
+ }
+
+ if (NULL != nodes_inactive)
+ {
+ 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;
+ }
+}
+
+/* end of gnunet-daemon-experimentation.c */
Modified: gnunet/src/experimentation/test_experimentation_clique.c
===================================================================
--- gnunet/src/experimentation/test_experimentation_clique.c 2013-05-23
10:45:49 UTC (rev 27263)
+++ gnunet/src/experimentation/test_experimentation_clique.c 2013-05-23
11:19:19 UTC (rev 27264)
@@ -33,8 +33,10 @@
/**
* Number of peers we want to start
*/
-#define NUM_PEERS 5
+#define NUM_PEERS 10
+#define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
(5 * NUM_PEERS) + 20)
+
/**
* Array of peers
*/
@@ -79,8 +81,13 @@
* Handle to the statistics service
*/
struct GNUNET_STATISTICS_Handle *sh;
+
+ unsigned int active_nodes;
+ unsigned int requested_nodes;
+ unsigned int inactive_nodes;
};
+
struct ExperimentationPeer ph[NUM_PEERS];
/**
@@ -128,8 +135,11 @@
{
result = GNUNET_OK;
GNUNET_log (GNUNET_ERROR_TYPE_INFO, "All %u peers connected \n",
NUM_PEERS);
-
- //GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+ if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
+ {
+ GNUNET_SCHEDULER_cancel (shutdown_task);
+ }
+ shutdown_task = GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, do_shutdown,
NULL);
}
break;
case GNUNET_TESTBED_ET_OPERATION_FINISHED:
@@ -142,7 +152,35 @@
}
}
+static void
+check_end ()
+{
+ static int last_value = 0;
+ unsigned int peer;
+ unsigned int total_active = 0;
+ unsigned int total_inactive = 0;
+ unsigned int total_requested = 0;
+ for (peer = 0; peer < NUM_PEERS; peer++)
+ {
+ total_active += ph[peer].active_nodes;
+ total_requested += ph[peer].requested_nodes;
+ total_inactive += ph[peer].inactive_nodes;
+ }
+ if (last_value < total_active)
+ fprintf (stderr, ".");
+
+ if ((total_active == (NUM_PEERS * (NUM_PEERS -1))) &&
+ (total_requested == 0) && (total_inactive == 0))
+ {
+ fprintf (stderr, "\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "All %u peers
active in a clique\n", NUM_PEERS);
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+ }
+}
+
+
+
/**
* Callback function to process statistic values.
*
@@ -157,7 +195,22 @@
stat_iterator (void *cls, const char *subsystem, const char *name,
uint64_t value, int is_persistent)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "STATS `%s' %s %llu\n", subsystem,
name, value);
+ struct ExperimentationPeer *peer = cls;
+
+ if (0 == strcmp (name, "# nodes active"))
+ {
+ peer->active_nodes = value;
+ }
+ if (0 == strcmp (name, "# nodes inactive"))
+ {
+ peer->inactive_nodes = value;
+ }
+ if (0 == strcmp (name, "# nodes requested"))
+ {
+ peer->requested_nodes = value;
+ }
+ check_end ();
+
return GNUNET_OK;
}
@@ -286,10 +339,7 @@
/* NUM_PEERS, */
GNUNET_TESTBED_TOPOLOGY_OPTION_END);
GNUNET_assert (NULL != op);
- shutdown_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 20),
- do_shutdown, NULL);
+ shutdown_task = GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, do_shutdown,
NULL);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r27264 - gnunet/src/experimentation,
gnunet <=