aboutsummaryrefslogtreecommitdiff
path: root/src/testing/testing_peergroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing/testing_peergroup.c')
-rw-r--r--src/testing/testing_peergroup.c1017
1 files changed, 0 insertions, 1017 deletions
diff --git a/src/testing/testing_peergroup.c b/src/testing/testing_peergroup.c
deleted file mode 100644
index 87504ed..0000000
--- a/src/testing/testing_peergroup.c
+++ /dev/null
@@ -1,1017 +0,0 @@
-/*
- This file is part of GNUnet
- (C) 2008-2011 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 testing/testing_peergroup.c
- * @brief API implementation for easy peer group creation
- * @author Nathan Evans
- * @author Christian Grothoff
- *
- */
-#include "platform.h"
-#include "gnunet_constants.h"
-#include "gnunet_arm_service.h"
-#include "gnunet_testing_lib.h"
-#include "gnunet_core_service.h"
-#include "gnunet_disk_lib.h"
-
-/** Globals **/
-#define DEFAULT_CONNECT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
-
-#define DEFAULT_CONNECT_ATTEMPTS 2
-
-/** Struct definitions **/
-
-struct PeerGroupStartupContext
-{
- struct GNUNET_TESTING_PeerGroup *pg;
- const struct GNUNET_CONFIGURATION_Handle *cfg;
- unsigned int total;
- unsigned int peers_left;
- unsigned long long max_concurrent_connections;
-
- /**
- * Maximum attemps to connect two daemons.
- */
- unsigned long long connect_attempts;
-
- /**
- * How long to spend trying to establish all the connections?
- */
- struct GNUNET_TIME_Relative connect_timeout;
-
- unsigned long long max_concurrent_ssh;
- struct GNUNET_TIME_Absolute timeout;
- GNUNET_TESTING_NotifyConnection connect_cb;
- GNUNET_TESTING_NotifyCompletion peergroup_cb;
-
- /**
- * Closure for all peergroup callbacks.
- */
- void *cls;
-
- const struct GNUNET_TESTING_Host *hostnames;
-
- /**
- * FIXME document
- */
- enum GNUNET_TESTING_Topology topology;
-
- float topology_percentage;
-
- float topology_probability;
-
- /**
- * FIXME document
- */
- enum GNUNET_TESTING_Topology restrict_topology;
-
- /**
- * FIXME document
- */
- char *restrict_transports;
-
- /**
- * Initial connections
- */
- enum GNUNET_TESTING_Topology connect_topology;
- enum GNUNET_TESTING_TopologyOption connect_topology_option;
- double connect_topology_option_modifier;
- int verbose;
-
- struct ProgressMeter *hostkey_meter;
- struct ProgressMeter *peer_start_meter;
- struct ProgressMeter *connect_meter;
-
- /**
- * Task used to kill the peergroup.
- */
- GNUNET_SCHEDULER_TaskIdentifier die_task;
-
- char *fail_reason;
-
- /**
- * Variable used to store the number of connections we should wait for.
- */
- unsigned int expected_connections;
-
- /**
- * Time when the connecting peers was started.
- */
- struct GNUNET_TIME_Absolute connect_start_time;
-
- /**
- * The total number of connections that have been created so far.
- */
- unsigned int total_connections;
-
- /**
- * The total number of connections that have failed so far.
- */
- unsigned int failed_connections;
-
- /**
- * File handle to write out topology in dot format.
- */
- struct GNUNET_DISK_FileHandle *topology_output_file;
-};
-
-struct TopologyOutputContext
-{
- struct GNUNET_DISK_FileHandle *file;
- GNUNET_TESTING_NotifyCompletion notify_cb;
- void *notify_cb_cls;
-};
-
-/**
- * Simple struct to keep track of progress, and print a
- * percentage meter for long running tasks.
- */
-struct ProgressMeter
-{
- /**
- * Total number of tasks to complete.
- */
- unsigned int total;
-
- /**
- * Print percentage done after modnum tasks.
- */
- unsigned int modnum;
-
- /**
- * Print a . each dotnum tasks.
- */
- unsigned int dotnum;
-
- /**
- * Total number completed thus far.
- */
- unsigned int completed;
-
- /**
- * Whether or not to print.
- */
- int print;
-
- /**
- * Startup string for progress meter.
- */
- char *startup_string;
-};
-
-
-/** Utility functions **/
-
-/**
- * Create a meter to keep track of the progress of some task.
- *
- * @param total the total number of items to complete
- * @param start_string a string to prefix the meter with (if printing)
- * @param print GNUNET_YES to print the meter, GNUNET_NO to count
- * internally only
- *
- * @return the progress meter
- */
-static struct ProgressMeter *
-create_meter (unsigned int total, char *start_string, int print)
-{
- struct ProgressMeter *ret;
-
- ret = GNUNET_malloc (sizeof (struct ProgressMeter));
- ret->print = print;
- ret->total = total;
- ret->modnum = (total / 4 == 0) ? 1 : (total / 4);
- ret->dotnum = (total / 50) + 1;
- if (start_string != NULL)
- ret->startup_string = GNUNET_strdup (start_string);
- else
- ret->startup_string = GNUNET_strdup ("");
-
- return ret;
-}
-
-/**
- * Update progress meter (increment by one).
- *
- * @param meter the meter to update and print info for
- *
- * @return GNUNET_YES if called the total requested,
- * GNUNET_NO if more items expected
- */
-static int
-update_meter (struct ProgressMeter *meter)
-{
- if (meter->print == GNUNET_YES)
- {
- if (meter->completed % meter->modnum == 0)
- {
- if (meter->completed == 0)
- {
- FPRINTF (stdout, "%sProgress: [0%%", meter->startup_string);
- }
- else
- FPRINTF (stdout, "%d%%",
- (int) (((float) meter->completed / meter->total) * 100));
- }
- else if (meter->completed % meter->dotnum == 0)
- FPRINTF (stdout, "%s", ".");
-
- if (meter->completed + 1 == meter->total)
- FPRINTF (stdout, "%d%%]\n", 100);
- fflush (stdout);
- }
- meter->completed++;
-
- if (meter->completed == meter->total)
- return GNUNET_YES;
- return GNUNET_NO;
-}
-
-/**
- * Reset progress meter.
- *
- * @param meter the meter to reset
- *
- * @return GNUNET_YES if meter reset,
- * GNUNET_SYSERR on error
- */
-static int
-reset_meter (struct ProgressMeter *meter)
-{
- if (meter == NULL)
- return GNUNET_SYSERR;
-
- meter->completed = 0;
- return GNUNET_YES;
-}
-
-/**
- * Release resources for meter
- *
- * @param meter the meter to free
- */
-static void
-free_meter (struct ProgressMeter *meter)
-{
- GNUNET_free_non_null (meter->startup_string);
- GNUNET_free (meter);
-}
-
-
-/** Functions for creating, starting and connecting the peergroup **/
-
-/**
- * Check whether peers successfully shut down.
- */
-static void
-internal_shutdown_callback (void *cls, const char *emsg)
-{
- struct PeerGroupStartupContext *pg_start_ctx = cls;
-
- if (emsg != NULL)
- pg_start_ctx->peergroup_cb (pg_start_ctx->cls, emsg);
- else
- pg_start_ctx->peergroup_cb (pg_start_ctx->cls, pg_start_ctx->fail_reason);
-}
-
-/**
- * Check if the get_handle is being used, if so stop the request. Either
- * way, schedule the end_badly_cont function which actually shuts down the
- * test.
- */
-static void
-end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct PeerGroupStartupContext *pg_start_ctx = cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Failing peer group startup with error: `%s'!\n",
- pg_start_ctx->fail_reason);
-
- GNUNET_TESTING_daemons_stop (pg_start_ctx->pg,
- GNUNET_TIME_absolute_get_remaining
- (pg_start_ctx->timeout),
- &internal_shutdown_callback, pg_start_ctx);
-
- if (pg_start_ctx->hostkey_meter != NULL)
- {
- free_meter (pg_start_ctx->hostkey_meter);
- pg_start_ctx->hostkey_meter = NULL;
- }
- if (pg_start_ctx->peer_start_meter != NULL)
- {
- free_meter (pg_start_ctx->peer_start_meter);
- pg_start_ctx->peer_start_meter = NULL;
- }
- if (pg_start_ctx->connect_meter != NULL)
- {
- free_meter (pg_start_ctx->connect_meter);
- pg_start_ctx->connect_meter = NULL;
- }
-}
-
-/**
- * This function is called whenever a connection attempt is finished between two of
- * the started peers (started with GNUNET_TESTING_daemons_start). The total
- * number of times this function is called should equal the number returned
- * from the GNUNET_TESTING_connect_topology call.
- *
- * The emsg variable is NULL on success (peers connected), and non-NULL on
- * failure (peers failed to connect).
- */
-static void
-internal_topology_callback (void *cls, const struct GNUNET_PeerIdentity *first,
- const struct GNUNET_PeerIdentity *second,
- uint32_t distance,
- 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 PeerGroupStartupContext *pg_start_ctx = cls;
- char *temp_str;
- char *second_str;
- int temp;
-
-#if TIMING
- unsigned long long duration;
- unsigned long long total_duration;
- unsigned int new_connections;
- unsigned int new_failed_connections;
- double conns_per_sec_recent;
- double conns_per_sec_total;
- double failed_conns_per_sec_recent;
- double failed_conns_per_sec_total;
-#endif
-
-#if TIMING
- if (GNUNET_TIME_absolute_get_difference
- (connect_last_time,
- GNUNET_TIME_absolute_get ()).rel_value >
- GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
- CONN_UPDATE_DURATION).rel_value)
- {
- /* Get number of new connections */
- new_connections = total_connections - previous_connections;
-
- /* Get number of new FAILED connections */
- new_failed_connections = failed_connections - previous_failed_connections;
-
- /* Get duration in seconds */
- duration =
- GNUNET_TIME_absolute_get_difference (connect_last_time,
- GNUNET_TIME_absolute_get
- ()).rel_value / 1000;
- total_duration =
- GNUNET_TIME_absolute_get_difference (connect_start_time,
- GNUNET_TIME_absolute_get
- ()).rel_value / 1000;
-
- failed_conns_per_sec_recent = (double) new_failed_connections / duration;
- failed_conns_per_sec_total = (double) failed_connections / total_duration;
- conns_per_sec_recent = (double) new_connections / duration;
- conns_per_sec_total = (double) total_connections / total_duration;
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Recent: %.2f/s, Total: %.2f/s, Recent failed: %.2f/s, total failed %.2f/s\n",
- conns_per_sec_recent, CONN_UPDATE_DURATION, conns_per_sec_total,
- failed_conns_per_sec_recent, failed_conns_per_sec_total);
- connect_last_time = GNUNET_TIME_absolute_get ();
- previous_connections = total_connections;
- previous_failed_connections = failed_connections;
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "have %u total_connections, %u failed\n", total_connections,
- failed_connections);
- }
-#endif
-
-
- if (emsg == NULL)
- {
- pg_start_ctx->total_connections++;
-#if VERBOSE > 1
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "connected peer %s to peer %s, distance %u\n",
- first_daemon->shortname, second_daemon->shortname, distance);
-#endif
- if (pg_start_ctx->topology_output_file != NULL)
- {
- second_str = GNUNET_strdup (GNUNET_i2s (second));
- temp =
- GNUNET_asprintf (&temp_str, "\t\"%s\" -- \"%s\"\n",
- GNUNET_i2s (first), second_str);
- GNUNET_free (second_str);
- if (temp > 0)
- GNUNET_DISK_file_write (pg_start_ctx->topology_output_file, temp_str,
- temp);
- GNUNET_free (temp_str);
- }
- }
- else
- {
- pg_start_ctx->failed_connections++;
-#if VERBOSE
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Failed to connect peer %s to peer %s with error :\n%s\n",
- first_daemon->shortname, second_daemon->shortname, emsg);
-
- 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
- }
-
- GNUNET_assert (pg_start_ctx->connect_meter != NULL);
- if (pg_start_ctx->connect_cb != NULL)
- pg_start_ctx->connect_cb (pg_start_ctx->cls, first, second, distance,
- first_cfg, second_cfg, first_daemon,
- second_daemon, emsg);
- if (GNUNET_YES != update_meter (pg_start_ctx->connect_meter))
- {
- /* No finished yet */
- return;
- }
-#if VERBOSE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Created %d total connections, which is our target number! Starting next phase of testing.\n",
- pg_start_ctx->total_connections);
-#endif
-
-#if TIMING
- total_duration =
- GNUNET_TIME_absolute_get_difference (connect_start_time,
- GNUNET_TIME_absolute_get
- ()).rel_value / 1000;
- failed_conns_per_sec_total = (double) failed_connections / total_duration;
- conns_per_sec_total = (double) total_connections / total_duration;
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Overall connection info --- Total: %u, Total Failed %u/s\n",
- total_connections, failed_connections);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Overall connection info --- Total: %.2f/s, Total Failed %.2f/s\n",
- conns_per_sec_total, failed_conns_per_sec_total);
-#endif
-
- GNUNET_assert (pg_start_ctx->die_task != GNUNET_SCHEDULER_NO_TASK);
- GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task);
-
- /* Call final callback, signifying that the peer group has been started and connected */
- if (pg_start_ctx->peergroup_cb != NULL)
- pg_start_ctx->peergroup_cb (pg_start_ctx->cls, NULL);
-
- if (pg_start_ctx->topology_output_file != NULL)
- {
- temp = GNUNET_asprintf (&temp_str, "}\n");
- if (temp > 0)
- GNUNET_DISK_file_write (pg_start_ctx->topology_output_file, temp_str,
- temp);
- GNUNET_free (temp_str);
- GNUNET_DISK_file_close (pg_start_ctx->topology_output_file);
- }
- GNUNET_free_non_null (pg_start_ctx->fail_reason);
- if (NULL != pg_start_ctx->hostkey_meter)
- free_meter(pg_start_ctx->hostkey_meter);
- if (NULL != pg_start_ctx->peer_start_meter)
- free_meter(pg_start_ctx->peer_start_meter);
- if (NULL != pg_start_ctx->connect_meter)
- free_meter(pg_start_ctx->connect_meter);
- GNUNET_free (pg_start_ctx);
-}
-
-
-/**
- * Callback called for each started daemon.
- *
- * @param cls Clause (PG Context).
- * @param id PeerIdentidy of started daemon.
- * @param cfg Configuration used by the daemon.
- * @param d Handle for the daemon.
- * @param emsg Error message, NULL on success.
- */
-static void
-internal_peers_started_callback (void *cls,
- const struct GNUNET_PeerIdentity *id,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- struct GNUNET_TESTING_Daemon *d,
- const char *emsg)
-{
- struct PeerGroupStartupContext *pg_start_ctx = cls;
-
- if (emsg != NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Failed to start daemon with error: `%s'\n", emsg);
- return;
- }
- GNUNET_assert (id != NULL);
-
-#if VERBOSE > 1
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n",
- (pg_start_ctx->total - pg_start_ctx->peers_left) + 1,
- pg_start_ctx->total);
-#endif
-
- pg_start_ctx->peers_left--;
-
- if (NULL == pg_start_ctx->peer_start_meter)
- {
- /* Cancelled Ctrl-C or error */
- return;
- }
- if (GNUNET_YES == update_meter (pg_start_ctx->peer_start_meter))
- {
-#if VERBOSE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "All %d daemons started, now connecting peers!\n",
- pg_start_ctx->total);
-#endif
- GNUNET_assert (pg_start_ctx->die_task != GNUNET_SCHEDULER_NO_TASK);
- GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task);
-
- pg_start_ctx->expected_connections = UINT_MAX;
- // FIXME: why whould peers_left be != 0?? Or pg NULL?
- if ((pg_start_ctx->pg != NULL) && (pg_start_ctx->peers_left == 0))
- {
- pg_start_ctx->connect_start_time = GNUNET_TIME_absolute_get ();
- pg_start_ctx->expected_connections =
- GNUNET_TESTING_connect_topology (pg_start_ctx->pg,
- pg_start_ctx->connect_topology,
- pg_start_ctx->connect_topology_option,
- pg_start_ctx->connect_topology_option_modifier,
- pg_start_ctx->connect_timeout,
- pg_start_ctx->connect_attempts, NULL,
- NULL);
-
- pg_start_ctx->connect_meter =
- create_meter (pg_start_ctx->expected_connections, "Peer connection ",
- pg_start_ctx->verbose);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Have %d expected connections\n",
- pg_start_ctx->expected_connections);
- }
-
- if (pg_start_ctx->expected_connections == 0)
- {
- GNUNET_free_non_null (pg_start_ctx->fail_reason);
- pg_start_ctx->fail_reason =
- GNUNET_strdup ("from connect topology (bad return)");
- pg_start_ctx->die_task =
- GNUNET_SCHEDULER_add_now (&end_badly, pg_start_ctx);
- return;
- }
-
- GNUNET_free_non_null (pg_start_ctx->fail_reason);
- pg_start_ctx->fail_reason =
- GNUNET_strdup ("from connect topology (timeout)");
- pg_start_ctx->die_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
- (pg_start_ctx->timeout), &end_badly,
- pg_start_ctx);
- }
-}
-
-/**
- * Callback indicating that the hostkey was created for a peer.
- *
- * @param cls NULL
- * @param id the peer identity
- * @param d the daemon handle (pretty useless at this point, remove?)
- * @param emsg non-null on failure
- */
-static void
-internal_hostkey_callback (void *cls, const struct GNUNET_PeerIdentity *id,
- struct GNUNET_TESTING_Daemon *d, const char *emsg)
-{
- struct PeerGroupStartupContext *pg_start_ctx = cls;
- unsigned int create_expected_connections;
-
- if (emsg != NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Hostkey callback received error: %s\n", emsg);
- }
-
-#if VERBOSE > 1
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Hostkey (%d/%d) created for peer `%s'\n",
- pg_start_ctx->total - pg_start_ctx->peers_left + 1,
- pg_start_ctx->total, GNUNET_i2s (id));
-#endif
-
- pg_start_ctx->peers_left--;
- if (GNUNET_YES == update_meter (pg_start_ctx->hostkey_meter))
- {
- GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task);
- GNUNET_free_non_null (pg_start_ctx->fail_reason);
- /* Set up task in case topology creation doesn't finish
- * within a reasonable amount of time */
- pg_start_ctx->fail_reason = GNUNET_strdup ("from create_topology");
- pg_start_ctx->die_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
- (pg_start_ctx->timeout), &end_badly,
- pg_start_ctx);
- pg_start_ctx->peers_left = pg_start_ctx->total; /* Reset counter */
- create_expected_connections =
- GNUNET_TESTING_create_topology (pg_start_ctx->pg,
- pg_start_ctx->topology,
- pg_start_ctx->restrict_topology,
- pg_start_ctx->restrict_transports);
- if (create_expected_connections > 0)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Topology set up, have %u expected connections, now starting peers!\n",
- create_expected_connections);
- GNUNET_TESTING_daemons_continue_startup (pg_start_ctx->pg);
- }
- else
- {
- GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task);
- GNUNET_free_non_null (pg_start_ctx->fail_reason);
- pg_start_ctx->fail_reason =
- GNUNET_strdup ("from create topology (bad return)");
- pg_start_ctx->die_task =
- GNUNET_SCHEDULER_add_now (&end_badly, pg_start_ctx);
- return;
- }
-
- GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task);
- GNUNET_free_non_null (pg_start_ctx->fail_reason);
- pg_start_ctx->fail_reason =
- GNUNET_strdup ("from continue startup (timeout)");
- pg_start_ctx->die_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
- (pg_start_ctx->timeout), &end_badly,
- pg_start_ctx);
- }
-}
-
-
-/**
- * Prototype of a callback function indicating that two peers
- * are currently connected.
- *
- * @param cls closure
- * @param first peer id for first daemon
- * @param second peer id for the second daemon
- * @param emsg error message (NULL on success)
- */
-void
-write_topology_cb (void *cls, const struct GNUNET_PeerIdentity *first,
- const struct GNUNET_PeerIdentity *second, const char *emsg)
-{
- struct TopologyOutputContext *topo_ctx;
- int temp;
- char *temp_str;
- char *temp_pid2;
-
- topo_ctx = (struct TopologyOutputContext *) cls;
- GNUNET_assert (topo_ctx->file != NULL);
- if ((emsg == NULL) && (first != NULL) && (second != NULL))
- {
- GNUNET_assert (first != NULL);
- GNUNET_assert (second != NULL);
- temp_pid2 = GNUNET_strdup (GNUNET_i2s (second));
- temp =
- GNUNET_asprintf (&temp_str, "\t\"%s\" -- \"%s\"\n", GNUNET_i2s (first),
- temp_pid2);
- GNUNET_free (temp_pid2);
- GNUNET_DISK_file_write (topo_ctx->file, temp_str, temp);
- }
- else if ((emsg == NULL) && (first == NULL) && (second == NULL))
- {
- temp = GNUNET_asprintf (&temp_str, "}\n");
- GNUNET_DISK_file_write (topo_ctx->file, temp_str, temp);
- GNUNET_DISK_file_close (topo_ctx->file);
- topo_ctx->notify_cb (topo_ctx->notify_cb_cls, NULL);
- GNUNET_free (topo_ctx);
- }
- else
- {
- temp = GNUNET_asprintf (&temp_str, "}\n");
- GNUNET_DISK_file_write (topo_ctx->file, temp_str, temp);
- GNUNET_DISK_file_close (topo_ctx->file);
- topo_ctx->notify_cb (topo_ctx->notify_cb_cls, emsg);
- GNUNET_free (topo_ctx);
- }
-}
-
-/**
- * Print current topology to a graphviz readable file.
- *
- * @param pg a currently running peergroup to print to file
- * @param output_filename the file to write the topology to
- * @param notify_cb callback to call upon completion or failure
- * @param notify_cb_cls closure for notify_cb
- *
- */
-void
-GNUNET_TESTING_peergroup_topology_to_file (struct GNUNET_TESTING_PeerGroup *pg,
- const char *output_filename,
- GNUNET_TESTING_NotifyCompletion
- notify_cb, void *notify_cb_cls)
-{
- struct TopologyOutputContext *topo_ctx;
- int temp;
- char *temp_str;
-
- topo_ctx = GNUNET_malloc (sizeof (struct TopologyOutputContext));
-
- topo_ctx->notify_cb = notify_cb;
- topo_ctx->notify_cb_cls = notify_cb_cls;
- topo_ctx->file =
- GNUNET_DISK_file_open (output_filename,
- GNUNET_DISK_OPEN_READWRITE |
- GNUNET_DISK_OPEN_CREATE,
- GNUNET_DISK_PERM_USER_READ |
- GNUNET_DISK_PERM_USER_WRITE);
- if (topo_ctx->file == NULL)
- {
- notify_cb (notify_cb_cls, "Failed to open output file!");
- GNUNET_free (topo_ctx);
- return;
- }
-
- temp = GNUNET_asprintf (&temp_str, "strict graph G {\n");
- if (temp > 0)
- GNUNET_DISK_file_write (topo_ctx->file, temp_str, temp);
- GNUNET_free_non_null (temp_str);
- GNUNET_TESTING_get_topology (pg, &write_topology_cb, topo_ctx);
-}
-
-/**
- * Start a peer group with a given number of peers. Notify
- * on completion of peer startup and connection based on given
- * topological constraints. Optionally notify on each
- * established connection.
- *
- * @param cfg configuration template to use
- * @param total number of daemons to start
- * @param timeout total time allowed for peers to start
- * @param connect_cb function to call each time two daemons are connected
- * @param peergroup_cb function to call once all peers are up and connected
- * @param peergroup_cls closure for peergroup callbacks
- * @param hostnames linked list of host structs to use to start peers on
- * (NULL to run on localhost only)
- *
- * @return NULL on error, otherwise handle to control peer group
- */
-struct GNUNET_TESTING_PeerGroup *
-GNUNET_TESTING_peergroup_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
- unsigned int total,
- struct GNUNET_TIME_Relative timeout,
- GNUNET_TESTING_NotifyConnection connect_cb,
- GNUNET_TESTING_NotifyCompletion peergroup_cb,
- void *peergroup_cls,
- const struct GNUNET_TESTING_Host *hostnames)
-{
- struct PeerGroupStartupContext *pg_start_ctx;
- char *temp_str;
- int temp;
- struct GNUNET_TIME_Relative rtimeout;
-
- GNUNET_assert (total > 0);
- GNUNET_assert (cfg != NULL);
-
- pg_start_ctx = GNUNET_malloc (sizeof (struct PeerGroupStartupContext));
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "connect_attempts",
- &pg_start_ctx->connect_attempts))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n",
- "testing", "connect_attempts");
- GNUNET_free (pg_start_ctx);
- return NULL;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (cfg, "testing", "CONNECT_TIMEOUT",
- &pg_start_ctx->connect_timeout))
- {
- pg_start_ctx->connect_timeout = DEFAULT_CONNECT_TIMEOUT;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (cfg, "testing",
- "max_outstanding_connections",
- &pg_start_ctx->max_concurrent_connections))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n",
- "testing", "max_outstanding_connections");
- GNUNET_free (pg_start_ctx);
- return NULL;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (cfg, "testing",
- "max_concurrent_ssh",
- &pg_start_ctx->max_concurrent_ssh))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n",
- "testing", "max_concurrent_ssh");
- GNUNET_free (pg_start_ctx);
- return NULL;
- }
-
- if (GNUNET_SYSERR ==
- (pg_start_ctx->verbose =
- GNUNET_CONFIGURATION_get_value_yesno (cfg, "testing",
- "use_progressbars")))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n",
- "testing", "use_progressbars");
- GNUNET_free (pg_start_ctx);
- return NULL;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (cfg, "testing", "PEERGROUP_TIMEOUT",
- &rtimeout))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n",
- "testing", "PEERGROUP_TIMEOUT");
- GNUNET_free (pg_start_ctx);
- return NULL;
- }
- pg_start_ctx->timeout = GNUNET_TIME_relative_to_absolute (rtimeout);
-
-
- /* Read topology related options from the configuration file */
- temp_str = NULL;
- if ((GNUNET_YES ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "topology",
- &temp_str)) &&
- (GNUNET_NO ==
- GNUNET_TESTING_topology_get (&pg_start_ctx->topology, temp_str)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Invalid topology `%s' given for section %s option %s\n",
- temp_str, "TESTING", "TOPOLOGY");
- pg_start_ctx->topology = GNUNET_TESTING_TOPOLOGY_CLIQUE; /* Defaults to NONE, so set better default here */
- }
- GNUNET_free_non_null (temp_str);
-
- if (GNUNET_YES ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "testing",
- "topology_output_file", &temp_str))
- {
- pg_start_ctx->topology_output_file =
- GNUNET_DISK_file_open (temp_str,
- GNUNET_DISK_OPEN_READWRITE |
- GNUNET_DISK_OPEN_CREATE,
- GNUNET_DISK_PERM_USER_READ |
- GNUNET_DISK_PERM_USER_WRITE);
- if (pg_start_ctx->topology_output_file != NULL)
- {
- GNUNET_free (temp_str);
- temp = GNUNET_asprintf (&temp_str, "strict graph G {\n");
- if (temp > 0)
- GNUNET_DISK_file_write (pg_start_ctx->topology_output_file, temp_str,
- temp);
- }
- GNUNET_free (temp_str);
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "percentage",
- &temp_str))
- pg_start_ctx->topology_percentage = 0.5;
- else
- {
- pg_start_ctx->topology_percentage = atof (temp_str);
- GNUNET_free (temp_str);
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "probability",
- &temp_str))
- pg_start_ctx->topology_probability = 0.5;
- else
- {
- pg_start_ctx->topology_probability = atof (temp_str);
- GNUNET_free (temp_str);
- }
-
- if ((GNUNET_YES ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "testing",
- "connect_topology", &temp_str)) &&
- (GNUNET_NO ==
- GNUNET_TESTING_topology_get (&pg_start_ctx->connect_topology, temp_str)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Invalid connect topology `%s' given for section %s option %s\n",
- temp_str, "TESTING", "CONNECT_TOPOLOGY");
- }
- GNUNET_free_non_null (temp_str);
-
- if ((GNUNET_YES ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "testing",
- "connect_topology_option",
- &temp_str)) &&
- (GNUNET_NO ==
- GNUNET_TESTING_topology_option_get
- (&pg_start_ctx->connect_topology_option, temp_str)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Invalid connect topology option `%s' given for section %s option %s\n",
- temp_str, "TESTING", "CONNECT_TOPOLOGY_OPTION");
- pg_start_ctx->connect_topology_option = GNUNET_TESTING_TOPOLOGY_OPTION_ALL; /* Defaults to NONE, set to ALL */
- }
- GNUNET_free_non_null (temp_str);
-
- if (GNUNET_YES ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "testing",
- "connect_topology_option_modifier",
- &temp_str))
- {
- if (SSCANF
- (temp_str, "%lf", &pg_start_ctx->connect_topology_option_modifier) != 1)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _
- ("Invalid value `%s' for option `%s' in section `%s': expected float\n"),
- temp_str, "connect_topology_option_modifier", "TESTING");
- GNUNET_free (temp_str);
- GNUNET_free (pg_start_ctx);
- return NULL;
- }
- GNUNET_free (temp_str);
- }
-
- if (GNUNET_YES !=
- GNUNET_CONFIGURATION_get_value_string (cfg, "testing",
- "blacklist_transports",
- &pg_start_ctx->restrict_transports))
- pg_start_ctx->restrict_transports = NULL;
-
- pg_start_ctx->restrict_topology = GNUNET_TESTING_TOPOLOGY_NONE;
- if ((GNUNET_YES ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "testing",
- "blacklist_topology", &temp_str))
- && (GNUNET_NO ==
- GNUNET_TESTING_topology_get (&pg_start_ctx->restrict_topology,
- temp_str)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Invalid topology `%s' given for section %s option %s\n",
- temp_str, "TESTING", "BLACKLIST_TOPOLOGY");
- }
-
- GNUNET_free_non_null (temp_str);
-
- pg_start_ctx->cfg = cfg;
- pg_start_ctx->total = total;
- pg_start_ctx->peers_left = total;
- pg_start_ctx->connect_cb = connect_cb;
- pg_start_ctx->peergroup_cb = peergroup_cb;
- pg_start_ctx->cls = peergroup_cls;
- pg_start_ctx->hostnames = hostnames;
- pg_start_ctx->hostkey_meter =
- create_meter (pg_start_ctx->peers_left, "Hostkeys created ",
- pg_start_ctx->verbose);
- pg_start_ctx->peer_start_meter =
- create_meter (pg_start_ctx->peers_left, "Peers started ",
- pg_start_ctx->verbose);
- /* Make compilers happy */
- reset_meter (pg_start_ctx->peer_start_meter);
- pg_start_ctx->fail_reason =
- GNUNET_strdup
- ("didn't generate all hostkeys within allowed startup time!");
- pg_start_ctx->die_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
- (pg_start_ctx->timeout), &end_badly,
- pg_start_ctx);
-
- pg_start_ctx->pg =
- GNUNET_TESTING_daemons_start (pg_start_ctx->cfg, pg_start_ctx->peers_left,
- pg_start_ctx->max_concurrent_connections,
- pg_start_ctx->max_concurrent_ssh,
- GNUNET_TIME_absolute_get_remaining
- (pg_start_ctx->timeout),
- &internal_hostkey_callback, pg_start_ctx,
- &internal_peers_started_callback,
- pg_start_ctx, &internal_topology_callback,
- pg_start_ctx, pg_start_ctx->hostnames);
-
- return pg_start_ctx->pg;
-}
-
-/* end of testing_peergroup.c */