[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r31802 - gnunet/src/testbed
From: |
gnunet |
Subject: |
[GNUnet-SVN] r31802 - gnunet/src/testbed |
Date: |
Mon, 6 Jan 2014 17:37:21 +0100 |
Author: harsha
Date: 2014-01-06 17:37:21 +0100 (Mon, 06 Jan 2014)
New Revision: 31802
Added:
gnunet/src/testbed/generate-underlay-topology.c
Modified:
gnunet/src/testbed/
gnunet/src/testbed/Makefile.am
gnunet/src/testbed/testbed_api_topology.c
gnunet/src/testbed/testbed_api_topology.h
Log:
- underlay topology generation
Index: gnunet/src/testbed
===================================================================
--- gnunet/src/testbed 2014-01-06 05:50:58 UTC (rev 31801)
+++ gnunet/src/testbed 2014-01-06 16:37:21 UTC (rev 31802)
Property changes on: gnunet/src/testbed
___________________________________________________________________
Modified: svn:ignore
## -50,3 +50,4 ##
buildvars.py
test_testbed_api_barriers
gnunet-daemon-testbed-underlay
+generate-underlay-topology
Modified: gnunet/src/testbed/Makefile.am
===================================================================
--- gnunet/src/testbed/Makefile.am 2014-01-06 05:50:58 UTC (rev 31801)
+++ gnunet/src/testbed/Makefile.am 2014-01-06 16:37:21 UTC (rev 31802)
@@ -18,6 +18,7 @@
if HAVE_SQLITE
underlay_daemon = gnunet-daemon-testbed-underlay
+ generate_underlay = generate-underlay-topology
endif
libexec_PROGRAMS = \
@@ -30,6 +31,9 @@
bin_PROGRAMS = \
gnunet-testbed-profiler
+noinst_PROGRAMS = \
+ $(generate_underlay)
+
gnunet_service_testbed_SOURCES = \
gnunet-service-testbed.c gnunet-service-testbed.h \
gnunet-service-testbed_links.c gnunet-service-testbed_links.h \
@@ -135,6 +139,15 @@
$(GN_LIB_LDFLAGS) \
-version-info 0:0:0
+generate_underlay_topology_SOURCES = generate-underlay-topology.c
+generate_underlay_topology_LDADD = $(XLIB) \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testbed/libgnunettestbed.la \
+ $(LTLIBINTL) -lsqlite3
+generate_underlay_topology_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunettestbed.la
+
check_PROGRAMS = \
test_testbed_api_hosts \
test_testbed_logger_api \
Added: gnunet/src/testbed/generate-underlay-topology.c
===================================================================
--- gnunet/src/testbed/generate-underlay-topology.c
(rev 0)
+++ gnunet/src/testbed/generate-underlay-topology.c 2014-01-06 16:37:21 UTC
(rev 31802)
@@ -0,0 +1,241 @@
+/*
+ This file is part of GNUnet
+ (C) 2008--2014 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 testbed/generate-underlay-topology.c
+ * @brief Program to generate a database file containing given underlay
topology
+ * @author Sree Harsha Totakura <address@hidden>
+ */
+
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_testbed_service.h"
+#include "testbed_api_topology.h"
+
+#define LOG(type, ...) \
+ GNUNET_log (type, __VA_ARGS__)
+
+
+#define LOG_ERROR(...) \
+ LOG (GNUNET_ERROR_TYPE_ERROR, __VA_ARGS__)
+
+
+/**
+ * The topology to generate
+ */
+enum GNUNET_TESTBED_TopologyOption topology;
+
+/**
+ * The number of peers to include in the topology
+ */
+static int num_peers;
+
+/**
+ * program result
+ */
+static int exit_result;
+
+
+/**
+ * Functions of this type are called to process underlay link
+ *
+ * @param cls closure
+ * @param A offset of first peer
+ * @param B offset of second peer
+ * @param bandwidth the bandwidth of the link in bytes per second
+ * @param latency the latency of link in milliseconds
+ * @param loss the percentage of messages dropped on the link
+ * @return GNUNET_OK to continue processing; GNUNET_SYSERR to abort
+ */
+static int
+link_processor (void *cls,
+ unsigned int A,
+ unsigned int B,
+ unsigned int bandwidth,
+ unsigned int latency,
+ unsigned int loss)
+{
+ GNUNET_break (0);
+ return GNUNET_OK;
+}
+
+
+/**
+ * Main run function.
+ *
+ * @param cls NULL
+ * @param args arguments passed to GNUNET_PROGRAM_run
+ * @param cfgfile the path to configuration file
+ * @param cfg the configuration file handle
+ */
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *config)
+{
+ const char *dbfile;
+ const char *topology_string;
+ unsigned int arg_uint1;
+ unsigned int arg_uint2;
+ const char *arg_str1;
+ const char *value;
+ unsigned int argc;
+
+ argc = 0;
+ if (NULL == args)
+ {
+ LOG_ERROR (_("Need atleast 2 arguments\n"));
+ return;
+ }
+ if (NULL == (dbfile = args[argc++]))
+ {
+ LOG_ERROR (_("Database filename missing\n"));
+ return;
+ }
+ if (NULL == (topology_string = args[argc++]))
+ {
+ LOG_ERROR (_("Topology string missing\n"));
+ return;
+ }
+ if (GNUNET_YES != GNUNET_TESTBED_topology_get_ (&topology, topology_string))
+ {
+ LOG_ERROR (_("Invalid topology: %s\n"), topology_string);
+ return;
+ }
+ /* parse for first TOPOOPT. This can either be arg_uint1 or arg_str1 */
+ switch (topology)
+ {
+ case GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI:
+ case GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD_RING:
+ case GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD:
+ case GNUNET_TESTBED_TOPOLOGY_SCALE_FREE:
+ if (NULL == (value = args[argc++]))
+ {
+ LOG_ERROR (_("An argument is missing for given topology `%s'\n"),
+ topology_string);
+ return;
+ }
+ if (-1 == SSCANF (value, "%u", &arg_uint1))
+ {
+ LOG_ERROR (_("Invalid argument `%s' given as topology argument\n"),
+ value);
+ return;
+ }
+ break;
+ case GNUNET_TESTBED_TOPOLOGY_FROM_FILE:
+ if (NULL == (arg_str1 = args[argc++]))
+ {
+ LOG_ERROR (_("Filename argument missing for topology `%s'\n"),
+ topology_string);
+ return;
+ }
+ break;
+ default:
+ GNUNET_assert (0);
+ }
+ /* parse for second TOPOOPT. Only required for SCALE_FREE topology */
+ switch (topology)
+ {
+ case GNUNET_TESTBED_TOPOLOGY_SCALE_FREE:
+ if (NULL == (value = args[argc++]))
+ {
+ LOG_ERROR (_("Second argument for topology `%s' is missing\n"),
+ topology_string);
+ return;
+ }
+ if (-1 == SSCANF (value, "%u", &arg_uint2))
+ {
+ LOG_ERROR (_("Invalid argument `%s'; expecting unsigned int\n"), value);
+ return;
+ }
+ break;
+ default:
+ GNUNET_assert (0);
+ }
+ /* contruct topologies */
+ switch (topology)
+ {
+ case GNUNET_TESTBED_TOPOLOGY_LINE:
+ case GNUNET_TESTBED_TOPOLOGY_RING:
+ case GNUNET_TESTBED_TOPOLOGY_CLIQUE:
+ case GNUNET_TESTBED_TOPOLOGY_2D_TORUS:
+ GNUNET_TESTBED_underlay_construct_ (num_peers, link_processor, NULL,
+ topology);
+ break;
+ case GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI:
+ case GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD_RING:
+ case GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD:
+ GNUNET_TESTBED_underlay_construct_ (num_peers, link_processor, NULL,
+ topology,
+ arg_uint1);
+ break;
+ case GNUNET_TESTBED_TOPOLOGY_FROM_FILE:
+ GNUNET_TESTBED_underlay_construct_ (num_peers, link_processor, NULL,
+ topology,
+ arg_str1);
+ break;
+ case GNUNET_TESTBED_TOPOLOGY_SCALE_FREE:
+ GNUNET_TESTBED_underlay_construct_ (num_peers, link_processor, NULL,
+ topology,
+ arg_uint1,
+ arg_uint2);
+ break;
+ default:
+ GNUNET_assert (0);
+ }
+}
+
+
+/**
+ * Main
+ */
+int
+main (int argc, char *const argv[])
+{
+ struct GNUNET_GETOPT_CommandLineOption option[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+ int ret;
+
+ exit_result = GNUNET_SYSERR;
+ ret =
+ GNUNET_PROGRAM_run (argc, argv, "gnunet-underlay-topology",
+ _("Generates SQLite3 database representing a given
underlay topology.\n"
+ "Usage: gnunet-underlay-topology [OPTIONS]
db-filename TOPO [TOPOOPTS]\n"
+ "The following options are available for TOPO
followed by TOPOOPTS if applicable:\n"
+ "\t LINE\n"
+ "\t RING\n"
+ "\t RANDOM <num_rnd_links>\n"
+ "\t SMALL_WORLD <num_rnd_links>\n"
+ "\t SMALL_WORLD_RING <num_rnd_links>\n"
+ "\t CLIQUE\n"
+ "\t 2D_TORUS\n"
+ "\t SCALE_FREE <cap> <m>\n"
+ "\t FROM_FILE <filename>\n"
+ "TOPOOPTS:\n"
+ "\t num_rnd_links: The number of random links\n"
+ "\t cap: the maximum number of links a node can
have\n"
+ "\t m: the number of links a node should have
while joining the network\n"
+ "\t filename: the path of the file which contains
topology information\n"
+ "NOTE: the format of the above file is descibed
here: https://www.gnunet.org/content/topology-file-format\n"),
+ option, &run, NULL);
+ if ((GNUNET_OK != ret) || (GNUNET_OK != exit_result))
+ return 1;
+ return 0;
+}
Modified: gnunet/src/testbed/testbed_api_topology.c
===================================================================
--- gnunet/src/testbed/testbed_api_topology.c 2014-01-06 05:50:58 UTC (rev
31801)
+++ gnunet/src/testbed/testbed_api_topology.c 2014-01-06 16:37:21 UTC (rev
31802)
@@ -78,6 +78,38 @@
};
+/**
+ * Representation of an underlay link
+ */
+struct UnderlayLink
+{
+ /**
+ * position of peer A's handle in peers array
+ */
+ uint32_t A;
+
+ /**
+ * position of peer B's handle in peers array
+ */
+ uint32_t B;
+
+ /**
+ * Bandwidth of the link in bytes per second
+ */
+ uint32_t bandwidth;
+
+ /**
+ * Latency of the link in milliseconds
+ */
+ uint32_t latency;
+
+ /**
+ * Loss in the link in percentage of message dropped
+ */
+ uint32_t loss;
+};
+
+
struct RetryListEntry
{
/**
@@ -98,9 +130,9 @@
/**
- * Context information for topology operations
+ * Context information for overlay topologies
*/
-struct TopologyContext
+struct TopologyContextOverlay
{
/**
* The array of peers
@@ -138,16 +170,6 @@
struct RetryListEntry *rl_tail;
/**
- * The number of peers
- */
- unsigned int num_peers;
-
- /**
- * The size of the link array
- */
- unsigned int link_array_size;
-
- /**
* How many retries to do before we give up
*/
unsigned int retry_cnt;
@@ -175,6 +197,66 @@
/**
+ * Topology context information for underlay topologies
+ */
+struct TopologyContextUnderlay
+{
+ /**
+ * The link array
+ */
+ struct UnderlayLink *link_array;
+};
+
+
+/**
+ * Context information for topology operations
+ */
+struct TopologyContext
+{
+ /**
+ * The type of this context
+ */
+ enum {
+
+ /**
+ * Type for underlay topology
+ */
+ TOPOLOGYCONTEXT_TYPE_UNDERLAY = 0,
+
+ /**
+ * Type for overlay topology
+ */
+ TOPOLOGYCONTEXT_TYPE_OVERLAY
+
+ } type;
+
+ union {
+
+ /**
+ * Topology context information for overlay topology
+ */
+ struct TopologyContextOverlay overlay;
+
+ /**
+ * Topology context information for underlay topology
+ */
+ struct TopologyContextUnderlay underlay;
+ } u;
+
+ /**
+ * The number of peers
+ */
+ unsigned int num_peers;
+
+ /**
+ * The size of the link array
+ */
+ unsigned int link_array_size;
+
+};
+
+
+/**
* A array of names representing topologies. Should be in sync with enum
* GNUNET_TESTBED_TopologyOption
*/
@@ -222,7 +304,9 @@
"INTERNAT",
/**
- * Scale free topology. No options.
+ * Scale free topology. Followed by the maximum number of links a node can
+ * have (unsigned int); and the number of links a new node should have when
+ * it is added to the network (unsigned int)
*/
"SCALE_FREE",
@@ -262,50 +346,53 @@
{
struct OverlayLink *link = cls;
struct TopologyContext *tc;
+ struct TopologyContextOverlay *overlay;
struct RetryListEntry *retry_entry;
GNUNET_assert (op == link->op);
GNUNET_TESTBED_operation_done (op);
link->op = NULL;
tc = link->tc;
+ GNUNET_assert (TOPOLOGYCONTEXT_TYPE_OVERLAY == tc->type);
+ overlay = &tc->u.overlay;
if (NULL != emsg)
{
- tc->nfailures++;
- if (0 != tc->retry_cnt)
+ overlay->nfailures++;
+ if (0 != overlay->retry_cnt)
{
LOG (GNUNET_ERROR_TYPE_WARNING,
"Error while establishing a link: %s -- Retrying\n", emsg);
retry_entry = GNUNET_new (struct RetryListEntry);
retry_entry->link = link;
- GNUNET_CONTAINER_DLL_insert_tail (tc->rl_head, tc->rl_tail, retry_entry);
+ GNUNET_CONTAINER_DLL_insert_tail (overlay->rl_head, overlay->rl_tail,
retry_entry);
}
}
else
- tc->nsuccess++;
- tc->ncompleted++;
- if (tc->ncompleted < tc->nlinks)
+ overlay->nsuccess++;
+ overlay->ncompleted++;
+ if (overlay->ncompleted < overlay->nlinks)
return;
- if ((0 != tc->retry_cnt) && (NULL != tc->rl_head))
+ if ((0 != overlay->retry_cnt) && (NULL != overlay->rl_head))
{
- tc->retry_cnt--;
- tc->ncompleted = 0;
- tc->nlinks = 0;
- while (NULL != (retry_entry = tc->rl_head))
+ overlay->retry_cnt--;
+ overlay->ncompleted = 0;
+ overlay->nlinks = 0;
+ while (NULL != (retry_entry = overlay->rl_head))
{
link = retry_entry->link;
link->op =
- GNUNET_TESTBED_overlay_connect (tc->op_cls, &overlay_link_completed,
- link, tc->peers[link->A],
- tc->peers[link->B]);
- tc->nlinks++;
- GNUNET_CONTAINER_DLL_remove (tc->rl_head, tc->rl_tail, retry_entry);
+ GNUNET_TESTBED_overlay_connect (overlay->op_cls,
&overlay_link_completed,
+ link, overlay->peers[link->A],
+ overlay->peers[link->B]);
+ overlay->nlinks++;
+ GNUNET_CONTAINER_DLL_remove (overlay->rl_head, overlay->rl_tail,
retry_entry);
GNUNET_free (retry_entry);
}
return;
}
- if (NULL != tc->comp_cb)
+ if (NULL != overlay->comp_cb)
{
- tc->comp_cb (tc->comp_cb_cls, tc->nsuccess, tc->nfailures);
+ overlay->comp_cb (overlay->comp_cb_cls, overlay->nsuccess,
overlay->nfailures);
}
}
@@ -320,16 +407,19 @@
opstart_overlay_configure_topology (void *cls)
{
struct TopologyContext *tc = cls;
+ struct TopologyContextOverlay *overlay;
unsigned int p;
- tc->nlinks = tc->link_array_size;
+ GNUNET_assert (TOPOLOGYCONTEXT_TYPE_OVERLAY == tc->type);
+ overlay = &tc->u.overlay;
+ overlay->nlinks = tc->link_array_size;
for (p = 0; p < tc->link_array_size; p++)
{
- tc->link_array[p].op =
- GNUNET_TESTBED_overlay_connect (tc->op_cls, &overlay_link_completed,
- &tc->link_array[p],
- tc->peers[tc->link_array[p].A],
- tc->peers[tc->link_array[p].B]);
+ overlay->link_array[p].op =
+ GNUNET_TESTBED_overlay_connect (overlay->op_cls,
&overlay_link_completed,
+ &overlay->link_array[p],
+
overlay->peers[overlay->link_array[p].A],
+
overlay->peers[overlay->link_array[p].B]);
}
}
@@ -343,20 +433,23 @@
oprelease_overlay_configure_topology (void *cls)
{
struct TopologyContext *tc = cls;
+ struct TopologyContextOverlay *overlay;
struct RetryListEntry *retry_entry;
unsigned int p;
- while (NULL != (retry_entry = tc->rl_head))
+ GNUNET_assert (TOPOLOGYCONTEXT_TYPE_OVERLAY == tc->type);
+ overlay = &tc->u.overlay;
+ while (NULL != (retry_entry = overlay->rl_head))
{
- GNUNET_CONTAINER_DLL_remove (tc->rl_head, tc->rl_tail, retry_entry);
+ GNUNET_CONTAINER_DLL_remove (overlay->rl_head, overlay->rl_tail,
retry_entry);
GNUNET_free (retry_entry);
}
- if (NULL != tc->link_array)
+ if (NULL != overlay->link_array)
{
for (p = 0; p < tc->link_array_size; p++)
- if (NULL != tc->link_array[p].op)
- GNUNET_TESTBED_operation_done (tc->link_array[p].op);
- GNUNET_free (tc->link_array);
+ if (NULL != overlay->link_array[p].op)
+ GNUNET_TESTBED_operation_done (overlay->link_array[p].op);
+ GNUNET_free (overlay->link_array);
}
GNUNET_free (tc);
}
@@ -365,22 +458,47 @@
/**
* Populates the OverlayLink structure.
*
- * @param link the OverlayLink
+ * @param offset the offset of the link array to use
* @param A the peer A. Should be different from B
* @param B the peer B. Should be different from A
* @param tc the TopologyContext
* @return
*/
static void
-make_link (struct OverlayLink *link, uint32_t A, uint32_t B,
+make_link (unsigned int offset, uint32_t A, uint32_t B,
struct TopologyContext *tc)
{
GNUNET_assert (A != B);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %u to %u\n", B, A);
- link->A = A;
- link->B = B;
- link->op = NULL;
- link->tc = tc;
+ switch (tc->type)
+ {
+ case TOPOLOGYCONTEXT_TYPE_OVERLAY:
+ {
+ struct TopologyContextOverlay *overlay;
+ struct OverlayLink *olink;
+
+ overlay = &tc->u.overlay;
+ GNUNET_assert (offset < tc->link_array_size);
+ olink = &overlay->link_array[offset];
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %u to %u\n", B, A);
+ olink->A = A;
+ olink->B = B;
+ olink->op = NULL;
+ olink->tc = tc;
+ }
+ break;
+ case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
+ {
+ struct TopologyContextUnderlay *underlay;
+ struct UnderlayLink *ulink;
+
+ underlay = &tc->u.underlay;
+ GNUNET_assert (offset < tc->link_array_size);
+ ulink = &underlay->link_array[offset];
+ ulink->A = A;
+ ulink->B = B;
+ }
+ break;
+ }
}
@@ -395,10 +513,29 @@
unsigned int cnt;
tc->link_array_size = tc->num_peers - 1;
- tc->link_array =
- GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size);
- for (cnt = 0; cnt < (tc->num_peers - 1); cnt++)
- make_link (&tc->link_array[cnt], cnt, cnt + 1, tc);
+ switch (tc->type)
+ {
+ case TOPOLOGYCONTEXT_TYPE_OVERLAY:
+ {
+ struct TopologyContextOverlay *overlay;
+
+ overlay = &tc->u.overlay;
+ overlay->link_array =
+ GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size);
+ }
+ break;
+ case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
+ {
+ struct TopologyContextUnderlay *underlay;
+
+ underlay = &tc->u.underlay;
+ underlay->link_array =
+ GNUNET_malloc (sizeof (struct UnderlayLink) * tc->link_array_size);
+ }
+ break;
+ }
+ for (cnt = 0; cnt < (tc->link_array_size); cnt++)
+ make_link (cnt, cnt, cnt + 1, tc);
}
@@ -412,11 +549,30 @@
{
gen_topo_line (tc);
tc->link_array_size++;
- tc->link_array =
- GNUNET_realloc (tc->link_array,
- sizeof (struct OverlayLink) * tc->link_array_size);
- make_link (&tc->link_array[tc->link_array_size - 1], tc->num_peers - 1, 0,
- tc);
+ switch (tc->type)
+ {
+ case TOPOLOGYCONTEXT_TYPE_OVERLAY:
+ {
+ struct TopologyContextOverlay *overlay;
+
+ overlay = &tc->u.overlay;
+ overlay->link_array =
+ GNUNET_realloc (overlay->link_array, sizeof (struct OverlayLink) *
+ tc->link_array_size);
+ }
+ break;
+ case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
+ {
+ struct TopologyContextUnderlay *underlay;
+
+ underlay = &tc->u.underlay;
+ underlay->link_array =
+ GNUNET_realloc (underlay->link_array, sizeof (struct UnderlayLink) *
+ tc->link_array_size);
+ }
+ break;
+ }
+ make_link (tc->link_array_size - 1, tc->num_peers - 1, 0, tc);
}
@@ -495,20 +651,39 @@
tc->link_array_size =
GNUNET_TESTBED_2dtorus_calc_links (tc->num_peers, &rows, &rows_len);
- tc->link_array =
- GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size);
+ switch (tc->type)
+ {
+ case TOPOLOGYCONTEXT_TYPE_OVERLAY:
+ {
+ struct TopologyContextOverlay *overlay;
+
+ overlay = &tc->u.overlay;
+ overlay->link_array =
+ GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size);
+ }
+ break;
+ case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
+ {
+ struct TopologyContextUnderlay *underlay;
+
+ underlay = &tc->u.underlay;
+ underlay->link_array =
+ GNUNET_malloc (sizeof (struct UnderlayLink) * tc->link_array_size);
+ break;
+ }
+ }
cnt = 0;
offset = 0;
for (y = 0; y < rows; y++)
{
for (x = 0; x < rows_len[y] - 1; x++)
{
- make_link (&tc->link_array[cnt], offset + x, offset + x + 1, tc);
+ make_link (cnt, offset + x, offset + x + 1, tc);
cnt++;
}
if (0 == x)
break;
- make_link (&tc->link_array[cnt], offset + x, offset, tc);
+ make_link (cnt, offset + x, offset, tc);
cnt++;
offset += rows_len[y];
}
@@ -520,14 +695,13 @@
if (x >= rows_len[y + 1])
break;
GNUNET_assert (x < rows_len[y + 1]);
- make_link (&tc->link_array[cnt], offset + x, offset + rows_len[y] + x,
- tc);
+ make_link (cnt, offset + x, offset + rows_len[y] + x, tc);
offset += rows_len[y];
cnt++;
}
if (0 == offset)
break;
- make_link (&tc->link_array[cnt], offset + x, x, tc);
+ make_link (cnt, offset + x, x, tc);
cnt++;
}
GNUNET_assert (cnt == tc->link_array_size);
@@ -553,21 +727,53 @@
if (GNUNET_YES == append)
{
- GNUNET_assert ((0 < tc->link_array_size) && (NULL != tc->link_array));
index = tc->link_array_size;
tc->link_array_size += links;
- tc->link_array =
- GNUNET_realloc (tc->link_array,
- sizeof (struct OverlayLink) * tc->link_array_size);
}
else
{
- GNUNET_assert ((0 == tc->link_array_size) && (NULL == tc->link_array));
index = 0;
tc->link_array_size = links;
- tc->link_array =
- GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size);
}
+ switch (tc->type)
+ {
+ case TOPOLOGYCONTEXT_TYPE_OVERLAY:
+ {
+ struct TopologyContextOverlay *overlay;
+
+ overlay = &tc->u.overlay;
+ if (GNUNET_YES != append)
+ {
+ GNUNET_assert (NULL == overlay->link_array);
+ overlay->link_array =
+ GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size);
+ break;
+ }
+ GNUNET_assert ((0 < tc->link_array_size) && (NULL !=
overlay->link_array));
+ overlay->link_array =
+ GNUNET_realloc (overlay->link_array,
+ sizeof (struct OverlayLink) * tc->link_array_size);
+ break;
+ }
+ case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
+ {
+ struct TopologyContextUnderlay *underlay;
+
+ underlay = &tc->u.underlay;
+ if (GNUNET_YES != append)
+ {
+ GNUNET_assert (NULL == underlay->link_array);
+ underlay->link_array =
+ GNUNET_malloc (sizeof (struct UnderlayLink) * tc->link_array_size);
+ break;
+ }
+ GNUNET_assert ((0 < tc->link_array_size) && (NULL !=
underlay->link_array));
+ underlay->link_array =
+ GNUNET_realloc (underlay->link_array,
+ sizeof (struct UnderlayLink) * tc->link_array_size);
+ break;
+ }
+ }
for (cnt = 0; cnt < links; cnt++)
{
do
@@ -578,7 +784,7 @@
GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, tc->num_peers);
}
while (A_rand == B_rand);
- make_link (&tc->link_array[index + cnt], A_rand, B_rand, tc);
+ make_link (index+cnt, A_rand, B_rand, tc);
}
}
@@ -594,7 +800,7 @@
* network
*/
static void
-gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m)
+gen_topo_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m)
{
unsigned int *deg;
unsigned int *etab;
@@ -610,13 +816,32 @@
etaboff = 0;
tc->link_array_size = tc->num_peers * m;
- tc->link_array = GNUNET_malloc_large (sizeof (struct OverlayLink) *
- tc->link_array_size);
+ switch (tc->type)
+ {
+ case TOPOLOGYCONTEXT_TYPE_OVERLAY:
+ {
+ struct TopologyContextOverlay *overlay;
+
+ overlay = &tc->u.overlay;
+ overlay->link_array = GNUNET_malloc_large (sizeof (struct OverlayLink) *
+ tc->link_array_size);
+ }
+ break;
+ case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
+ {
+ struct TopologyContextUnderlay *underlay;
+
+ underlay = &tc->u.underlay;
+ underlay->link_array = GNUNET_malloc_large (sizeof (struct UnderlayLink)
*
+ tc->link_array_size);
+ }
+ break;
+ }
etab = GNUNET_malloc_large (sizeof (unsigned int) * 2 * tc->link_array_size);
deg = GNUNET_malloc (sizeof (unsigned int) * tc->num_peers);
used = GNUNET_malloc (sizeof (unsigned int) * m);
/* start by connecting peer 1 to peer 0 */
- make_link (&tc->link_array[0], 0, 1, tc);
+ make_link (0, 0, 1, tc);
deg[0]++;
deg[1]++;
etab[etaboff++] = 0;
@@ -654,7 +879,7 @@
for (cnt2 = 0; cnt2 < cnt; cnt2++)
if (random_peer == used[cnt2])
goto redo;
- make_link (&tc->link_array[links + cnt], random_peer, peer, tc);
+ make_link (links + cnt, random_peer, peer, tc);
deg[random_peer]++;
deg[peer]++;
used[cnt] = random_peer;
@@ -671,9 +896,27 @@
GNUNET_free (deg);
GNUNET_assert (links <= tc->link_array_size);
tc->link_array_size = links;
- tc->link_array =
- GNUNET_realloc (tc->link_array,
- sizeof (struct OverlayLink) * tc->link_array_size);
+ switch (tc->type)
+ {
+ case TOPOLOGYCONTEXT_TYPE_OVERLAY:
+ {
+ struct TopologyContextOverlay *overlay;
+
+ overlay = &tc->u.overlay;
+ overlay->link_array =
+ GNUNET_realloc (overlay->link_array, sizeof (struct OverlayLink) *
tc->link_array_size);
+ }
+ break;
+ case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
+ {
+ struct TopologyContextUnderlay *underlay;
+
+ underlay = &tc->u.underlay;
+ underlay->link_array =
+ GNUNET_realloc (underlay->link_array, sizeof (struct UnderlayLink) *
tc->link_array_size);
+ }
+ break;
+ }
}
@@ -798,12 +1041,31 @@
if (peer_id != other_peer_id)
{
tc->link_array_size++;
- tc->link_array =
- GNUNET_realloc (tc->link_array,
- sizeof (struct OverlayLink) * tc->link_array_size);
+ switch (tc->type)
+ {
+ case TOPOLOGYCONTEXT_TYPE_OVERLAY:
+ {
+ struct TopologyContextOverlay *overlay;
+
+ overlay = &tc->u.overlay;
+ overlay->link_array =
+ GNUNET_realloc (overlay->link_array,
+ sizeof (struct OverlayLink) *
tc->link_array_size);
+ }
+ break;
+ case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
+ {
+ struct TopologyContextUnderlay *underlay;
+
+ underlay = &tc->u.underlay;
+ underlay->link_array =
+ GNUNET_realloc (underlay->link_array,
+ sizeof (struct UnderlayLink) *
tc->link_array_size);
+ }
+ break;
+ }
offset += end - &data[offset];
- make_link (&tc->link_array[tc->link_array_size - 1], peer_id,
- other_peer_id, tc);
+ make_link (tc->link_array_size - 1, peer_id, other_peer_id, tc);
}
else
LOG (GNUNET_ERROR_TYPE_WARNING,
@@ -829,13 +1091,79 @@
{
LOG (GNUNET_ERROR_TYPE_WARNING, "Removing link data read from the file\n");
tc->link_array_size = 0;
- GNUNET_free_non_null (tc->link_array);
- tc->link_array = NULL;
+ switch (tc->type)
+ {
+ case TOPOLOGYCONTEXT_TYPE_OVERLAY:
+ {
+ struct TopologyContextOverlay *overlay;
+
+ overlay = &tc->u.overlay;
+ GNUNET_free_non_null (overlay->link_array);
+ overlay->link_array = NULL;
+ }
+ break;
+ case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
+ {
+ struct TopologyContextUnderlay *underlay;
+
+ underlay = &tc->u.underlay;
+ GNUNET_free_non_null (underlay->link_array);
+ underlay->link_array = NULL;
+ }
+ break;
+ }
}
}
/**
+ * Generates clique topology
+ *
+ * @param tc the topology context
+ */
+static void
+gen_topo_clique (struct TopologyContext *tc)
+{
+ unsigned int cnt;
+ unsigned int offset;
+ unsigned int neighbour;
+
+ tc->link_array_size = tc->num_peers * (tc->num_peers - 1);
+ switch (tc->type)
+ {
+ case TOPOLOGYCONTEXT_TYPE_OVERLAY:
+ {
+ struct TopologyContextOverlay *overlay;
+
+ overlay = &tc->u.overlay;
+ overlay->link_array = GNUNET_malloc (sizeof (struct OverlayLink) *
+ tc->link_array_size);
+ }
+ break;
+ case TOPOLOGYCONTEXT_TYPE_UNDERLAY:
+ {
+ struct TopologyContextUnderlay *underlay;
+
+ underlay = &tc->u.underlay;
+ underlay->link_array = GNUNET_malloc (sizeof (struct UnderlayLink) *
+ tc->link_array_size);
+ }
+ }
+ offset = 0;
+ for (cnt = 0; cnt < tc->num_peers; cnt++)
+ {
+ for (neighbour = 0; neighbour < tc->num_peers; neighbour++)
+ {
+ if (neighbour == cnt)
+ continue;
+ make_link (offset, cnt, neighbour, tc);
+ offset++;
+ }
+ }
+}
+
+
+/**
* Configure overall network topology to have a particular shape.
*
* @param op_cls closure argument to give with the operation event
@@ -915,21 +1243,23 @@
va_list va)
{
struct TopologyContext *tc;
+ struct TopologyContextOverlay *overlay;
struct GNUNET_TESTBED_Operation *op;
struct GNUNET_TESTBED_Controller *c;
enum GNUNET_TESTBED_TopologyOption secondary_option;
- unsigned int cnt;
if (num_peers < 2)
return NULL;
c = peers[0]->controller;
tc = GNUNET_new (struct TopologyContext);
- tc->peers = peers;
+ tc->type = TOPOLOGYCONTEXT_TYPE_OVERLAY;
+ overlay = &tc->u.overlay;
+ overlay->peers = peers;
tc->num_peers = num_peers;
- tc->op_cls = op_cls;
- tc->retry_cnt = DEFAULT_RETRY_CNT;
- tc->comp_cb = comp_cb;
- tc->comp_cb_cls = comp_cb_cls;
+ overlay->op_cls = op_cls;
+ overlay->retry_cnt = DEFAULT_RETRY_CNT;
+ overlay->comp_cb = comp_cb;
+ overlay->comp_cb_cls = comp_cb_cls;
switch (topo)
{
case GNUNET_TESTBED_TOPOLOGY_LINE:
@@ -946,28 +1276,7 @@
gen_topo_random (tc, va_arg (va, unsigned int), GNUNET_YES);
break;
case GNUNET_TESTBED_TOPOLOGY_CLIQUE:
- tc->link_array_size = num_peers * (num_peers - 1);
- tc->link_array =
- GNUNET_malloc (sizeof (struct OverlayLink) * tc->link_array_size);
- {
- unsigned int offset;
-
- offset = 0;
- for (cnt = 0; cnt < num_peers; cnt++)
- {
- unsigned int neighbour;
-
- for (neighbour = 0; neighbour < num_peers; neighbour++)
- {
- if (neighbour == cnt)
- continue;
- tc->link_array[offset].A = cnt;
- tc->link_array[offset].B = neighbour;
- tc->link_array[offset].tc = tc;
- offset++;
- }
- }
- }
+ gen_topo_clique (tc);
break;
case GNUNET_TESTBED_TOPOLOGY_2D_TORUS:
gen_topo_2dtorus (tc);
@@ -984,7 +1293,7 @@
cap = (uint16_t) va_arg (va, unsigned int);
m = (uint8_t) va_arg (va, unsigned int);
- gen_scale_free (tc, cap, m);
+ gen_topo_scale_free (tc, cap, m);
}
break;
case GNUNET_TESTBED_TOPOLOGY_FROM_FILE:
@@ -1009,14 +1318,14 @@
switch (secondary_option)
{
case GNUNET_TESTBED_TOPOLOGY_RETRY_CNT:
- tc->retry_cnt = va_arg (va, unsigned int);
+ overlay->retry_cnt = va_arg (va, unsigned int);
break;
case GNUNET_TESTBED_TOPOLOGY_OPTION_END:
break;
default:
GNUNET_break (0); /* Should not use any other option apart from
* the ones handled here */
- GNUNET_free_non_null (tc->link_array);
+ GNUNET_free_non_null (overlay->link_array);
GNUNET_free (tc);
return NULL;
}
@@ -1125,4 +1434,106 @@
return GNUNET_strdup (topology_strings[topology]);
}
+
+/**
+ * Function to construct an underlay topology
+ *
+ * @param num_peers the number of peers for which the topology should be
+ * generated
+ * @param proc the underlay link processor callback. Will be called for each
+ * underlay link generated unless a previous call to this callback
+ * returned GNUNET_SYSERR. Cannot be NULL.
+ * @param cls closure for proc
+ * @param ... variable arguments denoting the topology and its parameters.
They
+ * should start with the type of topology to generate followed by
their
+ * options.
+ * @return GNUNET_OK if underlay link generation is successful; GNUNET_SYSERR
+ * upon error in generating the underlay or if any calls to the
+ * underlay link processor returned GNUNET_SYSERR
+ */
+int
+GNUNET_TESTBED_underlay_construct_ (int num_peers,
+ underlay_link_processor proc,
+ void *cls,
+ ...)
+{
+ struct TopologyContext tc;
+ struct TopologyContextUnderlay *underlay;
+ struct UnderlayLink *ulink;
+ va_list vargs;
+ enum GNUNET_TESTBED_TopologyOption topology;
+ unsigned int cnt;
+ int ret;
+
+ GNUNET_assert (NULL != proc);
+ ret = GNUNET_OK;
+ memset (&tc, 0, sizeof (tc));
+ tc.type = TOPOLOGYCONTEXT_TYPE_UNDERLAY;
+ underlay = &tc.u.underlay;
+ va_start (vargs, cls);
+ topology = va_arg (vargs, enum GNUNET_TESTBED_TopologyOption);
+ switch (topology)
+ {
+ case GNUNET_TESTBED_TOPOLOGY_LINE:
+ gen_topo_line (&tc);
+ break;
+ case GNUNET_TESTBED_TOPOLOGY_RING:
+ gen_topo_ring (&tc);
+ break;
+ case GNUNET_TESTBED_TOPOLOGY_CLIQUE:
+ gen_topo_clique (&tc);
+ break;
+ case GNUNET_TESTBED_TOPOLOGY_2D_TORUS:
+ gen_topo_2dtorus (&tc);
+ break;
+ case GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI:
+ gen_topo_random (&tc, va_arg (vargs, unsigned int), GNUNET_NO);
+ break;
+ case GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD_RING:
+ gen_topo_ring (&tc);
+ gen_topo_random (&tc, va_arg (vargs, unsigned int), GNUNET_YES);
+ break;
+ case GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD:
+ gen_topo_2dtorus (&tc);
+ gen_topo_random (&tc, va_arg (vargs, unsigned int), GNUNET_YES);
+ break;
+ case GNUNET_TESTBED_TOPOLOGY_FROM_FILE:
+ {
+ const char *filename;
+ filename = va_arg (vargs, char *);
+ GNUNET_assert (NULL != filename);
+ gen_topo_from_file (&tc, filename);
+ }
+ break;
+ case GNUNET_TESTBED_TOPOLOGY_SCALE_FREE:
+ {
+ uint16_t cap;
+ uint8_t m;
+ cap = (uint16_t) va_arg (vargs, unsigned int);
+ m = (uint8_t) va_arg (vargs, unsigned int);
+ gen_topo_scale_free (&tc, cap, m);
+ }
+ break;
+ default:
+ GNUNET_assert (0);
+ }
+ va_end (vargs);
+ for (cnt = 0; cnt < tc.link_array_size; cnt++)
+ {
+ ulink = &underlay->link_array[cnt];
+ if (GNUNET_SYSERR == proc (cls,
+ ulink->A,
+ ulink->B,
+ ulink->bandwidth,
+ ulink->latency,
+ ulink->loss))
+ {
+ ret = GNUNET_SYSERR;
+ break;
+ }
+ }
+ GNUNET_free_non_null (underlay->link_array);
+ return ret;
+}
+
/* end of testbed_api_topology.c */
Modified: gnunet/src/testbed/testbed_api_topology.h
===================================================================
--- gnunet/src/testbed/testbed_api_topology.h 2014-01-06 05:50:58 UTC (rev
31801)
+++ gnunet/src/testbed/testbed_api_topology.h 2014-01-06 16:37:21 UTC (rev
31802)
@@ -66,5 +66,48 @@
char *
GNUNET_TESTBED_topology_to_str_ (enum GNUNET_TESTBED_TopologyOption topology);
+
+/**
+ * Functions of this type are called to process underlay link
+ *
+ * @param cls closure
+ * @param A offset of first peer
+ * @param B offset of second peer
+ * @param bandwidth the bandwidth of the link in bytes per second
+ * @param latency the latency of link in milliseconds
+ * @param loss the percentage of messages dropped on the link
+ * @return GNUNET_OK to continue processing; GNUNET_SYSERR to abort
+ */
+typedef int (*underlay_link_processor) (void *cls,
+ unsigned int A,
+ unsigned int B,
+ unsigned int bandwidth,
+ unsigned int latency,
+ unsigned int loss);
+
+
+/**
+ * Function to construct an underlay topology
+ *
+ * @param num_peers the number of peers for which the topology should be
+ * generated
+ * @param proc the underlay link processor callback. Will be called for each
+ * underlay link generated unless a previous call to this callback
+ * returned GNUNET_SYSERR. Cannot be NULL.
+ * @param cls closure for proc
+ * @param ... variable arguments denoting the topology and its parameters.
They
+ * should start with the type of topology to generate followed by
their
+ * options. These arguments should *always* end with
+ * GNUNET_TESTBED_TOPOLOGY_OPTION_END option
+ * @return GNUNET_OK if underlay link generation is successful; GNUNET_SYSERR
+ * upon error in generating the underlay or if any calls to the
+ * underlay link processor returned GNUNET_SYSERR
+ */
+int
+GNUNET_TESTBED_underlay_construct_ (int num_peers,
+ underlay_link_processor proc,
+ void *cls,
+ ...);
+
#endif
/* end of testbed_api_topology.h */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r31802 - gnunet/src/testbed,
gnunet <=