gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r26097 - gnunet/src/testbed


From: gnunet
Subject: [GNUnet-SVN] r26097 - gnunet/src/testbed
Date: Thu, 14 Feb 2013 11:41:47 +0100

Author: harsha
Date: 2013-02-14 11:41:47 +0100 (Thu, 14 Feb 2013)
New Revision: 26097

Added:
   gnunet/src/testbed/test_testbed_api_sd.c
   gnunet/src/testbed/testbed_api_sd.c
   gnunet/src/testbed/testbed_api_sd.h
Removed:
   gnunet/src/testbed/standard_deviation.c
   gnunet/src/testbed/testbed_api.c.new
Modified:
   gnunet/src/testbed/
   gnunet/src/testbed/Makefile.am
   gnunet/src/testbed/testbed_api.c
Log:
separate SD calculations

Index: gnunet/src/testbed
===================================================================
--- gnunet/src/testbed  2013-02-14 10:34:04 UTC (rev 26096)
+++ gnunet/src/testbed  2013-02-14 10:41:47 UTC (rev 26097)

Property changes on: gnunet/src/testbed
___________________________________________________________________
Modified: svn:ignore
## -11,6 +11,7 ##
 testbed.conf
 test_testbed_api_hosts
 test_testbed_api
+test_testbed_api_sd
 test_testbed_api_2peers_1controller
 test_testbed_api_3peers_3controllers
 test_testbed_api_operations
Modified: gnunet/src/testbed/Makefile.am
===================================================================
--- gnunet/src/testbed/Makefile.am      2013-02-14 10:34:04 UTC (rev 26096)
+++ gnunet/src/testbed/Makefile.am      2013-02-14 10:41:47 UTC (rev 26097)
@@ -96,7 +96,8 @@
   testbed_api_statistics.c \
   testbed_api_testbed.c \
   testbed_api_test.c \
-  testbed_api_topology.c testbed_api_topology.h
+  testbed_api_topology.c testbed_api_topology.h \
+  testbed_api_sd.c testbed_api_sd.h
 libgnunettestbed_la_LIBADD = $(XLIB) \
  $(top_builddir)/src/core/libgnunetcore.la \
  $(top_builddir)/src/statistics/libgnunetstatistics.la \
@@ -116,6 +117,7 @@
   test_testbed_api_2peers_1controller \
   test_testbed_api_3peers_3controllers \
   test_testbed_api \
+  test_testbed_api_sd \
   test_testbed_api_operations \
   test_testbed_api_testbed_run \
   test_testbed_api_test \
@@ -135,6 +137,7 @@
 if ENABLE_TEST_RUN
  TESTS = \
   test_testbed_api \
+  test_testbed_api_sd \
   test_testbed_api_hosts \
   test_testbed_api_2peers_1controller \
   test_testbed_api_3peers_3controllers \
@@ -170,6 +173,12 @@
  $(top_builddir)/src/dht/libgnunetdht.la \
  libgnunettestbed.la
 
+test_testbed_api_sd_SOURCES = \
+ test_testbed_api_sd.c
+test_testbed_api_sd_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunettestbed.la
+
 test_testbed_api_2peers_1controller_SOURCES = \
  test_testbed_api_2peers_1controller.c
 test_testbed_api_2peers_1controller_LDADD = \

Deleted: gnunet/src/testbed/standard_deviation.c
===================================================================
--- gnunet/src/testbed/standard_deviation.c     2013-02-14 10:34:04 UTC (rev 
26096)
+++ gnunet/src/testbed/standard_deviation.c     2013-02-14 10:41:47 UTC (rev 
26097)
@@ -1,188 +0,0 @@
-/*
-      This file is part of GNUnet
-      (C) 2008--2012 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.
- */
-
-#include "platform.h"
-#include "gnunet_util_lib.h"
-
-struct SDEntry
-{
-  /**
-   * DLL next pointer
-   */
-  struct SDEntry *next;
-
-  /**
-   * DLL prev pointer
-   */
-  struct SDEntry *prev;
-
-  /**
-   * The value to store
-   */
-  unsigned int amount;
-};
-
-
-struct SDHandle
-{
-  /**
-   * DLL head for storing entries
-   */
-  struct SDEntry *head;
-
-  /**
-   * DLL tail for storing entries
-   */
-  struct SDEntry *tail;
-
-  /**
-   * Squared sum of data values
-   */
-  unsigned long long sqsum;
-
-  /**
-   * Sum of the data values
-   */
-  unsigned long sum;
-
-  /**
-   * The average of data amounts
-   */
-  float avg;
-
-  /**
-   * The variance
-   */
-  double vr;
-
-  /**
-   * Number of data values; also the length of DLL containing SDEntries
-   */
-  unsigned int cnt;
-
-  /**
-   * max number of entries we can have in the DLL
-   */
-  unsigned int max_cnt;
-};
-
-
-struct SDHandle *
-SD_init (unsigned int max_cnt)
-{
-  struct SDHandle *h;
-
-  GNUNET_assert (1 < max_cnt);
-  h = GNUNET_malloc (sizeof (struct SDHandle));
-  h->max_cnt = max_cnt;
-  return h;
-}
-
-void
-SD_destroy (struct SDHandle *h)
-{
-  struct SDEntry *entry;
-
-  while (NULL != (entry = h->head))
-  {
-    GNUNET_CONTAINER_DLL_remove (h->head, h->tail, entry);
-    GNUNET_free (entry);
-  }
-  GNUNET_free (h);
-}
-
-void
-SD_add_data (struct SDHandle *h, unsigned int amount)
-{
-  struct SDEntry *entry;
-  double sqavg;
-  double sqsum_avg;
-
-  entry = NULL;
-  if (h->cnt == h->max_cnt)
-  {
-    entry = h->head;
-    GNUNET_CONTAINER_DLL_remove (h->head, h->tail, entry);
-    h->sum -= entry->amount;
-    h->sqsum -=
-        ((unsigned long) entry->amount) * ((unsigned long) entry->amount);
-    h->cnt--;
-  }
-  GNUNET_assert (h->cnt < h->max_cnt);
-  if (NULL == entry)
-    entry = GNUNET_malloc (sizeof (struct SDEntry));
-  entry->amount = amount;
-  GNUNET_CONTAINER_DLL_insert_tail (h->head, h->tail, entry);
-  h->sum += amount;
-  h->cnt++;
-  h->avg = ((float) h->sum) / ((float) h->cnt);
-  h->sqsum += ((unsigned long) amount) * ((unsigned long) amount);
-  sqsum_avg = ((double) h->sqsum) / ((double) h->cnt);
-  sqavg = ((double) h->avg) * ((double) h->avg);
-  h->vr = sqsum_avg - sqavg;
-}
-
-
-/**
- * Returns the factor by which the given amount differs from the standard 
deviation
- *
- * @param h the SDhandle
- * @param amount the value for which the deviation is returned
- * @return the deviation from the average; GNUNET_SYSERR if the deviation 
cannot
- *           be calculated; a maximum of 4 is returned for deviations equal to
- *           or larger than 4
- */
-int
-SD_deviation_factor (struct SDHandle *h, unsigned int amount)
-{
-  double diff;
-  unsigned int n;
-
-  if (h->cnt < 2)
-    return GNUNET_SYSERR;
-  if (((float) amount) > h->avg)
-    diff = ((float) amount) - h->avg;
-  else
-    diff = h->avg - ((float) amount);
-  diff *= diff;
-  for (n = 1; n < 4; n++)
-    if (diff < (((double) (n * n)) * h->vr))
-      break;
-  return n;
-}
-
-
-int
-main ()
-{
-  struct SDHandle *h = SD_init (20);
-
-  SD_add_data (h, 40);
-  SD_add_data (h, 30);
-  SD_add_data (h, 40);
-  SD_add_data (h, 10);
-  SD_add_data (h, 30);
-  printf ("Average: %f\n", h->avg);
-  printf ("Variance: %f\n", h->vr);
-  printf ("Standard Deviation: %f\n", sqrt (h->vr));
-  printf ("Deviation factor: %d\n", SD_deviation_factor (h, 60));
-  SD_destroy (h);
-  return 0;
-}

Added: gnunet/src/testbed/test_testbed_api_sd.c
===================================================================
--- gnunet/src/testbed/test_testbed_api_sd.c                            (rev 0)
+++ gnunet/src/testbed/test_testbed_api_sd.c    2013-02-14 10:41:47 UTC (rev 
26097)
@@ -0,0 +1,108 @@
+/*
+      This file is part of GNUnet
+      (C) 2008--2012 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/testbed_api_sd.c
+ * @brief test cases for calculating standard deviation
+ * @author Sree Harsha Totakura <address@hidden> 
+ */
+
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_util_lib.h"
+#include "testbed_api_sd.h"
+
+/**
+ * Global return value
+ */
+static int ret;
+
+/**
+ * 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)
+{
+  struct SDHandle *h = GNUNET_TESTBED_SD_init_ (20);
+
+  ret = 0;
+  GNUNET_TESTBED_SD_add_data_ (h, 40);
+  if (GNUNET_SYSERR != GNUNET_TESTBED_SD_deviation_factor_ (h, 10))
+  {
+    GNUNET_break (0);
+    ret = 1;
+    goto err;
+  }
+  GNUNET_TESTBED_SD_add_data_ (h, 30); 
+  if (GNUNET_SYSERR == GNUNET_TESTBED_SD_deviation_factor_ (h, 80))
+  {
+    GNUNET_break (0);
+    ret = 1;
+    goto err;
+  }
+  GNUNET_TESTBED_SD_add_data_ (h, 40);
+  if (0 != GNUNET_TESTBED_SD_deviation_factor_ (h, 10))
+  {
+    GNUNET_break (0);
+    ret = 1;
+    goto err;
+  }
+  GNUNET_TESTBED_SD_add_data_ (h, 10);
+  GNUNET_TESTBED_SD_add_data_ (h, 30);
+  if (3 != GNUNET_TESTBED_SD_deviation_factor_ (h, 60))
+  {
+    GNUNET_break (0);
+    ret = 1;
+    goto err;
+  }
+
+ err:
+  GNUNET_TESTBED_SD_destroy_ (h);
+}
+
+
+/**
+ * Main function
+ */
+int
+main (int argc, char **argv)
+{
+  struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_OPTION_END
+  };
+  int result;
+
+  result = GNUNET_SYSERR;
+  result =
+      GNUNET_PROGRAM_run (argc, argv,
+                          "test_testbed_api_sd", "nohelp", options, &run, 
NULL);
+  if ((GNUNET_OK != result))
+    return 1;
+  return ret;
+}
+
+/* end of test_testbed_api_sd.c */

Modified: gnunet/src/testbed/testbed_api.c
===================================================================
--- gnunet/src/testbed/testbed_api.c    2013-02-14 10:34:04 UTC (rev 26096)
+++ gnunet/src/testbed/testbed_api.c    2013-02-14 10:41:47 UTC (rev 26097)
@@ -41,6 +41,7 @@
 #include "testbed_api_hosts.h"
 #include "testbed_api_peers.h"
 #include "testbed_api_operations.h"
+#include "testbed_api_sd.h"
 
 /**
  * Generic logging shorthand
@@ -248,69 +249,6 @@
 };
 
 
-struct SDEntry
-{
-  /**
-   * DLL next pointer
-   */
-  struct SDEntry *next;
-
-  /**
-   * DLL prev pointer
-   */
-  struct SDEntry *prev;
-
-  /**
-   * The value to store
-   */
-  unsigned int amount;
-};
-
-
-struct SDHandle
-{
-  /**
-   * DLL head for storing entries
-   */
-  struct SDEntry *head;
-
-  /**
-   * DLL tail for storing entries
-   */
-  struct SDEntry *tail;
-
-  /**
-   * Squared sum of data values
-   */
-  unsigned long long sqsum;
-
-  /**
-   * Sum of the data values
-   */
-  unsigned long sum;
-
-  /**
-   * The average of data amounts
-   */
-  float avg;
-
-  /**
-   * The variance
-   */
-  double vr;
-
-  /**
-   * Number of data values; also the length of DLL containing SDEntries
-   */
-  unsigned int cnt;
-
-  /**
-   * max number of entries we can have in the DLL
-   */
-  unsigned int max_cnt;
-};
-
-
 /**
  * This variable is set to the operation that has been last marked as done. It
  * is used to verify whether the state associated with an operation is valid
@@ -322,112 +260,8 @@
  */
 static const struct GNUNET_TESTBED_Operation *last_finished_operation;
 
-/**
- * Initialize standard deviation calculation handle
- *
- * @param max_cnt the maximum number of readings to keep
- * @return the initialized handle
- */
-static struct SDHandle *
-SD_init (unsigned int max_cnt)
-{
-  struct SDHandle *h;
 
-  GNUNET_assert (1 < max_cnt);
-  h = GNUNET_malloc (sizeof (struct SDHandle));
-  h->max_cnt = max_cnt;
-  return h;
-}
-
-
 /**
- * Frees the memory allocated to the SD handle
- *
- * @param h the SD handle
- */
-static void
-SD_destroy (struct SDHandle *h)
-{
-  struct SDEntry *entry;
-
-  while (NULL != (entry = h->head))
-  {
-    GNUNET_CONTAINER_DLL_remove (h->head, h->tail, entry);
-    GNUNET_free (entry);
-  }
-  GNUNET_free (h);
-}
-
-
-/**
- * Add a reading to SD
- *
- * @param h the SD handle
- * @param amount the reading value
- */
-static void
-SD_add_data (struct SDHandle *h, unsigned int amount)
-{
-  struct SDEntry *entry;
-  double sqavg;
-  double sqsum_avg;
-
-  entry = NULL;
-  if (h->cnt == h->max_cnt)
-  {
-    entry = h->head;
-    GNUNET_CONTAINER_DLL_remove (h->head, h->tail, entry);
-    h->sum -= entry->amount;
-    h->sqsum -=
-        ((unsigned long) entry->amount) * ((unsigned long) entry->amount);
-    h->cnt--;
-  }
-  GNUNET_assert (h->cnt < h->max_cnt);
-  if (NULL == entry)
-    entry = GNUNET_malloc (sizeof (struct SDEntry));
-  entry->amount = amount;
-  GNUNET_CONTAINER_DLL_insert_tail (h->head, h->tail, entry);
-  h->sum += amount;
-  h->cnt++;
-  h->avg = ((float) h->sum) / ((float) h->cnt);
-  h->sqsum += ((unsigned long) amount) * ((unsigned long) amount);
-  sqsum_avg = ((double) h->sqsum) / ((double) h->cnt);
-  sqavg = ((double) h->avg) * ((double) h->avg);
-  h->vr = sqsum_avg - sqavg;
-}
-
-
-/**
- * Returns the factor by which the given amount differs from the standard 
deviation
- *
- * @param h the SDhandle
- * @param amount the value for which the deviation is returned
-
- * @return the deviation from the average; GNUNET_SYSERR if the deviation 
cannot
- *           be calculated OR 0 if the deviation is less than the average; a
- *           maximum of 4 is returned for deviations equal to or larger than 4
- */
-static int
-SD_deviation_factor (struct SDHandle *h, unsigned int amount)
-{
-  double diff;
-  unsigned int n;
-
-  if (h->cnt < 2)
-    return GNUNET_SYSERR;
-  if (((float) amount) > h->avg)
-    diff = ((float) amount) - h->avg;
-  else
-    return 0;                   //diff = h->avg - ((float) amount);
-  diff *= diff;
-  for (n = 1; n < 4; n++)
-    if (diff < (((double) (n * n)) * h->vr))
-      break;
-  return n;
-}
-
-
-/**
  * Returns the operation context with the given id if found in the Operation
  * context queues of the controller
  *
@@ -1887,7 +1721,7 @@
   controller->opq_parallel_overlay_connect_operations =
       GNUNET_TESTBED_operation_queue_create_ (0);
   GNUNET_TESTBED_set_num_parallel_overlay_connects_ (controller, 1);
-  controller->poc_sd = SD_init (10);
+  controller->poc_sd = GNUNET_TESTBED_SD_init_ (10);
   controller_hostname = GNUNET_TESTBED_host_get_hostname (host);
   if (NULL == controller_hostname)
     controller_hostname = "127.0.0.1";
@@ -1980,7 +1814,7 @@
       (controller->opq_parallel_topology_config_operations);
   GNUNET_TESTBED_operation_queue_destroy_
       (controller->opq_parallel_overlay_connect_operations);
-  SD_destroy (controller->poc_sd);
+  GNUNET_TESTBED_SD_destroy_ (controller->poc_sd);
   GNUNET_free_non_null (controller->tslots);
   GNUNET_free (controller);
 }
@@ -2648,11 +2482,11 @@
   GNUNET_assert (nvals >= c->num_parallel_connects);
   avg = GNUNET_TIME_relative_divide (avg, nvals);
   GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value != avg.rel_value);
-  sd = SD_deviation_factor (c->poc_sd, (unsigned int) avg.rel_value);
+  sd = GNUNET_TESTBED_SD_deviation_factor_ (c->poc_sd, (unsigned int) 
avg.rel_value);
   if ( (sd <= 5) ||
        (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
                                       c->num_parallel_connects)) )
-    SD_add_data (c->poc_sd, (unsigned int) avg.rel_value);
+    GNUNET_TESTBED_SD_add_data_ (c->poc_sd, (unsigned int) avg.rel_value);
   if (GNUNET_SYSERR == sd)
   {
     GNUNET_TESTBED_set_num_parallel_overlay_connects_ (c,

Deleted: gnunet/src/testbed/testbed_api.c.new
===================================================================
--- gnunet/src/testbed/testbed_api.c.new        2013-02-14 10:34:04 UTC (rev 
26096)
+++ gnunet/src/testbed/testbed_api.c.new        2013-02-14 10:41:47 UTC (rev 
26097)
@@ -1,2222 +0,0 @@
-/*
-      This file is part of GNUnet
-      (C) 2008--2012 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/testbed_api.c
- * @brief API for accessing the GNUnet testing service.
- *        This library is supposed to make it easier to write
- *        testcases and script large-scale benchmarks.
- * @author Christian Grothoff
- * @author Sree Harsha Totakura
- */
-
-
-#include "platform.h"
-#include "gnunet_testbed_service.h"
-#include "gnunet_core_service.h"
-#include "gnunet_constants.h"
-#include "gnunet_transport_service.h"
-#include "gnunet_hello_lib.h"
-#include <zlib.h>
-
-#include "testbed.h"
-#include "testbed_api.h"
-#include "testbed_api_hosts.h"
-#include "testbed_api_peers.h"
-#include "testbed_api_operations.h"
-
-/**
- * Generic logging shorthand
- */
-#define LOG(kind, ...)                          \
-  GNUNET_log_from (kind, "testbed-api", __VA_ARGS__);
-
-/**
- * Debug logging
- */
-#define LOG_DEBUG(...)                          \
-  LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__);
-
-/**
- * Relative time seconds shorthand
- */
-#define TIME_REL_SECS(sec) \
-  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec)
-
-
-/**
- * Default server message sending retry timeout
- */
-#define TIMEOUT_REL TIME_REL_SECS(1)
-
-
-/**
- * Testbed Helper binary name
- */
-#define HELPER_TESTBED_BINARY "gnunet-helper-testbed"
-#define HELPER_TESTBED_BINARY_SSH ". ~/.bashrc; gnunet-helper-testbed"
-
-
-/**
- * Handle for controller process
- */
-struct GNUNET_TESTBED_ControllerProc
-{
-  /**
-   * The process handle
-   */
-  struct GNUNET_HELPER_Handle *helper;
-
-  /**
-   * The host where the helper is run
-   */
-  struct GNUNET_TESTBED_Host *host;
-
-  /**
-   * The controller error callback
-   */
-  GNUNET_TESTBED_ControllerStatusCallback cb;
-
-  /**
-   * The closure for the above callback
-   */
-  void *cls;
-
-  /**
-   * The send handle for the helper
-   */
-  struct GNUNET_HELPER_SendHandle *shandle;
-
-  /**
-   * The message corresponding to send handle
-   */
-  struct GNUNET_MessageHeader *msg;
-
-  /**
-   * The port number for ssh; used for helpers starting ssh
-   */
-  char *port;
-
-  /**
-   * The ssh destination string; used for helpers starting ssh
-   */
-  char *dst;
-
-  /**
-   * The configuration of the running testbed service
-   */
-  struct GNUNET_CONFIGURATION_Handle *cfg;
-
-};
-
-
-/**
- * The message queue for sending messages to the controller service
- */
-struct MessageQueue
-{
-  /**
-   * The message to be sent
-   */
-  struct GNUNET_MessageHeader *msg;
-
-  /**
-   * next pointer for DLL
-   */
-  struct MessageQueue *next;
-
-  /**
-   * prev pointer for DLL
-   */
-  struct MessageQueue *prev;
-};
-
-
-/**
- * Structure for a controller link
- */
-struct ControllerLink
-{
-  /**
-   * The next ptr for DLL
-   */
-  struct ControllerLink *next;
-
-  /**
-   * The prev ptr for DLL
-   */
-  struct ControllerLink *prev;
-
-  /**
-   * The host which will be referred in the peer start request. This is the
-   * host where the peer should be started
-   */
-  struct GNUNET_TESTBED_Host *delegated_host;
-
-  /**
-   * The host which will contacted to delegate the peer start request
-   */
-  struct GNUNET_TESTBED_Host *slave_host;
-
-  /**
-   * The configuration to be used to connect to slave host
-   */
-  const struct GNUNET_CONFIGURATION_Handle *slave_cfg;
-
-  /**
-   * GNUNET_YES if the slave should be started (and stopped) by us; GNUNET_NO
-   * if we are just allowed to use the slave via TCP/IP
-   */
-  int is_subordinate;
-};
-
-
-/**
- * handle for host registration
- */
-struct GNUNET_TESTBED_HostRegistrationHandle
-{
-  /**
-   * The host being registered
-   */
-  struct GNUNET_TESTBED_Host *host;
-
-  /**
-   * The controller at which this host is being registered
-   */
-  struct GNUNET_TESTBED_Controller *c;
-
-  /**
-   * The Registartion completion callback
-   */
-  GNUNET_TESTBED_HostRegistrationCompletion cc;
-
-  /**
-   * The closure for above callback
-   */
-  void *cc_cls;
-};
-
-
-/**
- * Context data for forwarded Operation
- */
-struct ForwardedOperationData
-{
-
-  /**
-   * The callback to call when reply is available
-   */
-  GNUNET_CLIENT_MessageHandler cc;
-
-  /**
-   * The closure for the above callback
-   */
-  void *cc_cls;
-
-};
-
-
-/**
- * Context data for get slave config operations
- */
-struct GetSlaveConfigData
-{
-  /**
-   * The operation closure
-   */
-  void *op_cls;
-
-  /**
-   * The id of the slave controller
-   */
-  uint32_t slave_id;
-
-};
-
-
-/**
- * Context data for controller link operations
- */
-struct ControllerLinkData
-{
-  /**
-   * The controller link message
-   */
-  struct GNUNET_TESTBED_ControllerLinkMessage *msg;
-
-  /**
-   * The operation closure
-   */
-  void *op_cls;
-
-};
-
-
-/**
- * Returns the operation context with the given id if found in the Operation
- * context queues of the controller
- *
- * @param c the controller whose queues are searched
- * @param id the id which has to be checked
- * @return the matching operation context; NULL if no match found
- */
-static struct OperationContext *
-find_opc (const struct GNUNET_TESTBED_Controller *c, const uint64_t id)
-{
-  struct OperationContext *opc;
-
-  for (opc = c->ocq_head; NULL != opc; opc = opc->next)
-  {
-    if (id == opc->id)
-      return opc;
-  }
-  return NULL;
-}
-
-
-/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_ADDHOSTCONFIRM message from
- * controller (testbed service)
- *
- * @param c the controller handler
- * @param msg message received
- * @return GNUNET_YES if we can continue receiving from service; GNUNET_NO if
- *           not
- */
-static int
-handle_addhostconfirm (struct GNUNET_TESTBED_Controller *c,
-                       const struct GNUNET_TESTBED_HostConfirmedMessage *msg)
-{
-  struct GNUNET_TESTBED_HostRegistrationHandle *rh;
-  char *emsg;
-  uint16_t msg_size;
-
-  rh = c->rh;
-  if (NULL == rh)
-  {
-    return GNUNET_OK;
-  }
-  if (GNUNET_TESTBED_host_get_id_ (rh->host) != ntohl (msg->host_id))
-  {
-    LOG_DEBUG ("Mismatch in host id's %u, %u of host confirm msg\n",
-               GNUNET_TESTBED_host_get_id_ (rh->host), ntohl (msg->host_id));
-    return GNUNET_OK;
-  }
-  c->rh = NULL;
-  msg_size = ntohs (msg->header.size);
-  if (sizeof (struct GNUNET_TESTBED_HostConfirmedMessage) == msg_size)
-  {
-    LOG_DEBUG ("Host %u successfully registered\n", ntohl (msg->host_id));
-    GNUNET_TESTBED_mark_host_registered_at_ (rh->host, c);
-    rh->cc (rh->cc_cls, NULL);
-    GNUNET_free (rh);
-    return GNUNET_OK;
-  }
-  /* We have an error message */
-  emsg = (char *) &msg[1];
-  if ('\0' !=
-      emsg[msg_size - sizeof (struct GNUNET_TESTBED_HostConfirmedMessage)])
-  {
-    GNUNET_break (0);
-    GNUNET_free (rh);
-    return GNUNET_NO;
-  }
-  LOG (GNUNET_ERROR_TYPE_ERROR, _("Adding host %u failed with error: %s\n"),
-       ntohl (msg->host_id), emsg);
-  rh->cc (rh->cc_cls, emsg);
-  GNUNET_free (rh);
-  return GNUNET_OK;
-}
-
-
-/**
- * Handler for forwarded operations
- *
- * @param c the controller handle
- * @param opc the opearation context
- * @param msg the message
- */
-static void
-handle_forwarded_operation_msg (struct GNUNET_TESTBED_Controller *c,
-                               struct OperationContext *opc,
-                               const struct GNUNET_MessageHeader *msg)
-{
-  struct ForwardedOperationData *fo_data;
-
-  fo_data = opc->data;
-  if (NULL != fo_data->cc)
-    fo_data->cc (fo_data->cc_cls, msg);
-  GNUNET_CONTAINER_DLL_remove (c->ocq_head, c->ocq_tail, opc);
-  GNUNET_free (fo_data);
-  GNUNET_free (opc);
-}
-
-
-/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_ADDHOSTCONFIRM message from
- * controller (testbed service)
- *
- * @param c the controller handler
- * @param msg message received
- * @return GNUNET_YES if we can continue receiving from service; GNUNET_NO if
- *           not
- */
-static int
-handle_opsuccess (struct GNUNET_TESTBED_Controller *c,
-                  const struct
-                  GNUNET_TESTBED_GenericOperationSuccessEventMessage *msg)
-{
-  struct OperationContext *opc;
-  struct GNUNET_TESTBED_EventInformation event;
-  uint64_t op_id;
-
-  op_id = GNUNET_ntohll (msg->operation_id);
-  LOG_DEBUG ("Operation %ul successful\n", op_id);
-  if (NULL == (opc = find_opc (c, op_id)))
-  {
-    LOG_DEBUG ("Operation not found\n");
-    return GNUNET_YES;
-  }
-  event.type = GNUNET_TESTBED_ET_OPERATION_FINISHED;
-  event.details.operation_finished.operation = opc->op;
-  event.details.operation_finished.op_cls = NULL;
-  event.details.operation_finished.emsg = NULL;
-  event.details.operation_finished.generic = NULL;
-  switch (opc->type)
-  {
-  case OP_FORWARDED:
-    {
-      handle_forwarded_operation_msg
-         (c, opc, (const struct GNUNET_MessageHeader *) msg);
-      return GNUNET_YES;
-    }
-    break;
-  case OP_PEER_DESTROY:
-    {
-      struct GNUNET_TESTBED_Peer *peer;
-      
-      peer = opc->data;
-      GNUNET_free (peer);
-      opc->data = NULL;
-      //PEERDESTROYDATA
-    }
-    break;
-  case OP_LINK_CONTROLLERS:
-    {
-      struct ControllerLinkData *data;
-      
-      data = opc->data;
-      GNUNET_assert (NULL != data);      
-      event.details.operation_finished.op_cls = data->op_cls;
-      GNUNET_free (data);
-      opc->data = NULL;
-    }
-    break;
-  default:
-    GNUNET_assert (0);
-  }  
-  GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
-  opc->state = OPC_STATE_FINISHED;
-  if (0 != (c->event_mask & (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED)))
-  {
-    if (NULL != c->cc)
-      c->cc (c->cc_cls, &event);
-  }
-  return GNUNET_YES;
-}
-
-
-/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_PEERCREATESUCCESS message from
- * controller (testbed service)
- *
- * @param c the controller handle
- * @param msg message received
- * @return GNUNET_YES if we can continue receiving from service; GNUNET_NO if
- *           not
- */
-static int
-handle_peer_create_success (struct GNUNET_TESTBED_Controller *c,
-                            const struct
-                            GNUNET_TESTBED_PeerCreateSuccessEventMessage *msg)
-{
-  struct OperationContext *opc;
-  struct PeerCreateData *data;
-  struct GNUNET_TESTBED_Peer *peer;
-  GNUNET_TESTBED_PeerCreateCallback cb;
-  void *cls;
-  uint64_t op_id;
-
-  GNUNET_assert (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage) 
==
-                 ntohs (msg->header.size));
-  op_id = GNUNET_ntohll (msg->operation_id);
-  if (NULL == (opc = find_opc (c, op_id)))
-  {
-    LOG_DEBUG ("Operation context for PeerCreateSuccessEvent not found\n");
-    return GNUNET_YES;
-  }
-  if (OP_FORWARDED == opc->type)
-  {
-    handle_forwarded_operation_msg (c, opc,
-                                   (const struct GNUNET_MessageHeader *) msg);
-    return GNUNET_YES;
-  }
-  GNUNET_assert (OP_PEER_CREATE == opc->type);
-  GNUNET_assert (NULL != opc->data);
-  data = opc->data;
-  GNUNET_assert (NULL != data->peer);
-  peer = data->peer;
-  GNUNET_assert (peer->unique_id == ntohl (msg->peer_id));
-  peer->state = PS_CREATED;
-  cb = data->cb;
-  cls = data->cls;
-  GNUNET_free (opc->data);
-  GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
-  opc->state = OPC_STATE_FINISHED;
-  if (NULL != cb)
-    cb (cls, peer, NULL);
-  return GNUNET_YES;
-}
-
-
-/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_PEEREVENT message from
- * controller (testbed service)
- *
- * @param c the controller handler
- * @param msg message received
- * @return GNUNET_YES if we can continue receiving from service; GNUNET_NO if
- *           not
- */
-static int
-handle_peer_event (struct GNUNET_TESTBED_Controller *c,
-                   const struct GNUNET_TESTBED_PeerEventMessage *msg)
-{
-  struct OperationContext *opc;
-  struct GNUNET_TESTBED_Peer *peer;
-  struct PeerEventData *data;
-  GNUNET_TESTBED_PeerChurnCallback pcc;
-  void *pcc_cls;
-  struct GNUNET_TESTBED_EventInformation event;
-  uint64_t op_id;
-
-  GNUNET_assert (sizeof (struct GNUNET_TESTBED_PeerEventMessage) ==
-                 ntohs (msg->header.size));
-  op_id = GNUNET_ntohll (msg->operation_id);
-  if (NULL == (opc = find_opc (c, op_id)))
-  {
-    LOG_DEBUG ("Operation not found\n");
-    return GNUNET_YES;
-  }
-  if (OP_FORWARDED == opc->type)
-  {
-    handle_forwarded_operation_msg (c, opc,
-                                   (const struct GNUNET_MessageHeader *) msg);
-    return GNUNET_YES;
-  }
-  GNUNET_assert ((OP_PEER_START == opc->type) || (OP_PEER_STOP == opc->type));
-  data = opc->data;
-  GNUNET_assert (NULL != data);
-  peer = data->peer;
-  GNUNET_assert (NULL != peer);
-  event.type = (enum GNUNET_TESTBED_EventType) ntohl (msg->event_type);
-  switch (event.type)
-  {
-  case GNUNET_TESTBED_ET_PEER_START:
-    peer->state = PS_STARTED;
-    event.details.peer_start.host = peer->host;
-    event.details.peer_start.peer = peer;
-    break;
-  case GNUNET_TESTBED_ET_PEER_STOP:
-    peer->state = PS_STOPPED;
-    event.details.peer_stop.peer = peer;
-    break;
-  default:
-    GNUNET_assert (0);          /* We should never reach this state */
-  }
-  pcc = data->pcc;
-  pcc_cls = data->pcc_cls;
-  GNUNET_free (data);
-  GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
-  opc->state = OPC_STATE_FINISHED;
-  if (0 !=
-      ((GNUNET_TESTBED_ET_PEER_START | GNUNET_TESTBED_ET_PEER_STOP) &
-       c->event_mask))
-  {
-    if (NULL != c->cc)
-      c->cc (c->cc_cls, &event);
-  }
-  if (NULL != pcc)
-    pcc (pcc_cls, NULL);
-  return GNUNET_YES;
-}
-
-
-/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_PEERCONEVENT message from
- * controller (testbed service)
- *
- * @param c the controller handler
- * @param msg message received
- * @return GNUNET_YES if we can continue receiving from service; GNUNET_NO if
- *           not
- */
-static int
-handle_peer_conevent (struct GNUNET_TESTBED_Controller *c,
-                      const struct GNUNET_TESTBED_ConnectionEventMessage *msg)
-{
-  struct OperationContext *opc;
-  struct OverlayConnectData *data;
-  GNUNET_TESTBED_OperationCompletionCallback cb;
-  void *cb_cls;
-  struct GNUNET_TESTBED_EventInformation event;
-  uint64_t op_id;
-
-  op_id = GNUNET_ntohll (msg->operation_id);
-  if (NULL == (opc = find_opc (c, op_id)))
-  {
-    LOG_DEBUG ("Operation not found\n");
-    return GNUNET_YES;
-  }
-  if (OP_FORWARDED == opc->type)
-  {
-    handle_forwarded_operation_msg (c, opc,
-                                   (const struct GNUNET_MessageHeader *) msg);
-    return GNUNET_YES;
-  }
-  GNUNET_assert (OP_OVERLAY_CONNECT == opc->type);
-  data = opc->data;
-  GNUNET_assert (NULL != data);
-  GNUNET_assert ((ntohl (msg->peer1) == data->p1->unique_id) &&
-                 (ntohl (msg->peer2) == data->p2->unique_id));
-  event.type = (enum GNUNET_TESTBED_EventType) ntohl (msg->event_type);
-  switch (event.type)
-  {
-  case GNUNET_TESTBED_ET_CONNECT:
-    event.details.peer_connect.peer1 = data->p1;
-    event.details.peer_connect.peer2 = data->p2;
-    break;
-  case GNUNET_TESTBED_ET_DISCONNECT:
-    GNUNET_assert (0);          /* FIXME: implement */
-    break;
-  default:
-    GNUNET_assert (0);          /* Should never reach here */
-    break;
-  }
-  cb = data->cb;
-  cb_cls = data->cb_cls;
-  GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
-  opc->state = OPC_STATE_FINISHED;
-  GNUNET_free (data);
-  if (0 !=
-      ((GNUNET_TESTBED_ET_CONNECT | GNUNET_TESTBED_ET_DISCONNECT) &
-       c->event_mask))
-  {
-    if (NULL != c->cc)
-      c->cc (c->cc_cls, &event);
-  }
-  if (NULL != cb)
-    cb (cb_cls, opc->op, NULL);
-  return GNUNET_YES;
-}
-
-
-/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_PEERCONFIG message from
- * controller (testbed service)
- *
- * @param c the controller handler
- * @param msg message received
- * @return GNUNET_YES if we can continue receiving from service; GNUNET_NO if
- *           not
- */
-static int
-handle_peer_config (struct GNUNET_TESTBED_Controller *c,
-                    const struct
-                    GNUNET_TESTBED_PeerConfigurationInformationMessage *msg)
-{
-  struct OperationContext *opc;
-  struct GNUNET_TESTBED_Peer *peer;
-  struct PeerInfoData *data;
-  struct GNUNET_TESTBED_PeerInformation *pinfo;
-  GNUNET_TESTBED_PeerInfoCallback cb;
-  void *cb_cls;
-  uint64_t op_id;
-
-  op_id = GNUNET_ntohll (msg->operation_id);
-  if (NULL == (opc = find_opc (c, op_id)))
-  {
-    LOG_DEBUG ("Operation not found\n");
-    return GNUNET_YES;
-  }
-  if (OP_FORWARDED == opc->type)
-  {
-    handle_forwarded_operation_msg (c, opc,
-                                   (const struct GNUNET_MessageHeader *) msg);
-    return GNUNET_YES;
-  }
-  data = opc->data;
-  GNUNET_assert (NULL != data);
-  peer = data->peer;
-  GNUNET_assert (NULL != peer);
-  GNUNET_assert (ntohl (msg->peer_id) == peer->unique_id);
-  pinfo = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerInformation));
-  pinfo->pit = data->pit;
-  cb = data->cb;
-  cb_cls = data->cb_cls;
-  GNUNET_free (data);
-  opc->data = NULL;
-  switch (pinfo->pit)
-  {
-  case GNUNET_TESTBED_PIT_IDENTITY:
-    pinfo->result.id = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
-    (void) memcpy (pinfo->result.id, &msg->peer_identity,
-                  sizeof (struct GNUNET_PeerIdentity));
-    break;
-  case GNUNET_TESTBED_PIT_CONFIGURATION:
-    pinfo->result.cfg =        /* Freed in oprelease_peer_getinfo */
-       GNUNET_TESTBED_extract_config_ (&msg->header);
-    break;
-  case GNUNET_TESTBED_PIT_GENERIC:
-    GNUNET_assert (0);          /* never reach here */
-    break;
-  }
-  opc->data = pinfo;
-  GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
-  opc->state = OPC_STATE_FINISHED;
-  if (NULL != cb)
-    cb (cb_cls, opc->op, pinfo, NULL);
-  return GNUNET_YES;
-}
-
-
-/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_OPERATIONFAILEVENT message from
- * controller (testbed service)
- *
- * @param c the controller handler
- * @param msg message received
- * @return GNUNET_YES if we can continue receiving from service; GNUNET_NO if
- *           not
- */
-static int
-handle_op_fail_event (struct GNUNET_TESTBED_Controller *c,
-                      const struct GNUNET_TESTBED_OperationFailureEventMessage
-                      *msg)
-{
-  struct OperationContext *opc;
-  const char *emsg;
-  uint64_t op_id;
-  struct GNUNET_TESTBED_EventInformation event;
-
-  op_id = GNUNET_ntohll (msg->operation_id);
-  if (NULL == (opc = find_opc (c, op_id)))
-  {
-    LOG_DEBUG ("Operation not found\n");
-    return GNUNET_YES;
-  }
-  GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
-  if (OP_FORWARDED == opc->type)
-  {
-    handle_forwarded_operation_msg (c, opc,
-                                   (const struct GNUNET_MessageHeader *) msg);
-    return GNUNET_YES;
-  }
-  opc->state = OPC_STATE_FINISHED;
-  emsg = GNUNET_TESTBED_parse_error_string_ (msg);
-  if (NULL == emsg)
-    emsg = "Unknown error";
-  if (OP_PEER_INFO == opc->type)
-  {
-    struct PeerInfoData *data;
-    data = opc->data;
-    if (NULL != data->cb)
-      data->cb (data->cb_cls, opc->op, NULL, emsg);
-    GNUNET_free (data);
-    return GNUNET_YES;  /* We do not call controller callback for peer info */
-  }
-  if ((0 != (GNUNET_TESTBED_ET_OPERATION_FINISHED & c->event_mask)) &&
-      (NULL != c->cc))
-  {
-    event.type = GNUNET_TESTBED_ET_OPERATION_FINISHED;
-    event.details.operation_finished.operation = opc->op;
-    event.details.operation_finished.op_cls = NULL;
-    event.details.operation_finished.emsg = emsg;
-    event.details.operation_finished.generic = NULL;
-    c->cc (c->cc_cls, &event);
-  }
-  switch (opc->type)
-  {
-  case OP_PEER_CREATE:
-    {
-      struct PeerCreateData *data;      
-      data = opc->data;
-      GNUNET_free (data->peer);
-      if (NULL != data->cb)
-        data->cb (data->cls, NULL, emsg);
-      GNUNET_free (data);      
-    }
-    break;
-  case OP_PEER_START:
-  case OP_PEER_STOP:
-    {
-      struct PeerEventData *data;
-      data = opc->data;
-      if (NULL != data->pcc)
-        data->pcc (data->pcc_cls, emsg);
-      GNUNET_free (data);
-    }
-    break;
-  case OP_PEER_DESTROY:
-    break;
-  case OP_PEER_INFO:
-    GNUNET_assert (0);
-  case OP_OVERLAY_CONNECT:
-    {
-      struct OverlayConnectData *data;
-      data = opc->data;
-      if (NULL != data->cb)
-        data->cb (data->cb_cls, opc->op, emsg);
-      GNUNET_free (data);
-    }
-    break;
-  case OP_FORWARDED:
-    GNUNET_assert (0);
-  case OP_LINK_CONTROLLERS:     /* No secondary callback */
-    break;
-  default:
-    GNUNET_break (0);
-  }  
-  return GNUNET_YES;
-}
-
-
-/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_SLAVECONFIG message from controller
- * (testbed service)
- *
- * @param c the controller handler
- * @param msg message received
- * @return GNUNET_YES if we can continue receiving from service; GNUNET_NO if
- *           not
- */
-static int
-handle_slave_config (struct GNUNET_TESTBED_Controller *c,
-                    const struct GNUNET_TESTBED_SlaveConfiguration * msg)
-{
-  struct OperationContext *opc;
-  void *op_cls;
-  uint64_t op_id;
-  struct GNUNET_TESTBED_EventInformation event;  
-
-  op_id = GNUNET_ntohll (msg->operation_id);
-  if (NULL == (opc = find_opc (c, op_id)))
-  {
-    LOG_DEBUG ("Operation not found\n");
-    return GNUNET_YES;
-  }
-  if (OP_GET_SLAVE_CONFIG != opc->type)
-  {
-    GNUNET_break (0);
-    return GNUNET_YES;
-  }  
-  op_cls = ((struct GetSlaveConfigData *) opc->data)->op_cls;
-  GNUNET_free (opc->data);
-  opc->data = NULL;
-  opc->state = OPC_STATE_FINISHED;
-  GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
-  if ((0 != (GNUNET_TESTBED_ET_OPERATION_FINISHED & c->event_mask)) &&
-      (NULL != c->cc))
-  {
-    opc->data = GNUNET_TESTBED_extract_config_ (&msg->header);
-    event.type = GNUNET_TESTBED_ET_OPERATION_FINISHED;   
-    event.details.operation_finished.generic = opc->data;
-    event.details.operation_finished.operation = opc->op;
-    event.details.operation_finished.op_cls = op_cls;
-    event.details.operation_finished.emsg = NULL;
-    c->cc (c->cc_cls, &event);
-  }
-  return GNUNET_YES;
-}
-
-
-/**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_NEEDCONTROLLERCONFIG message from
- * controller (testbed service)
- *
- * @param c the controller handler
- * @param msg message received
- * @return GNUNET_YES if we can continue receiving from service; GNUNET_NO if
- *           not
- */
-static int
-handle_need_controller_config (struct GNUNET_TESTBED_Controller *c,
-                               const struct 
GNUNET_TESTBED_NeedControllerConfig * msg)
-{
-  struct OperationContext *opc;
-  uint64_t op_id;
-
-  op_id = GNUNET_ntohll (msg->operation_id);
-  if (NULL == (opc = find_opc (c, op_id)))
-  {
-    LOG_DEBUG ("Operation not found\n");
-    return GNUNET_YES;
-  }  
-  /* This has to be a forwarded operation since there is no function in the
-     testbed API to create an operation context for this message type */
-  GNUNET_assert (OP_FORWARDED == opc->type);
-  handle_forwarded_operation_msg (c, opc,
-                                  (const struct GNUNET_MessageHeader *) msg);
-  return GNUNET_YES;
-}
-
-
-/**
- * Handler for messages from controller (testbed service)
- *
- * @param cls the controller handler
- * @param msg message received, NULL on timeout or fatal error
- */
-static void
-message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
-{
-  struct GNUNET_TESTBED_Controller *c = cls;
-  int status;
-  uint16_t msize;
-
-  c->in_receive = GNUNET_NO;
-  /* FIXME: Add checks for message integrity */
-  if (NULL == msg)
-  {
-    LOG_DEBUG ("Receive timed out or connection to service dropped\n");
-    return;
-  }
-  status = GNUNET_OK;
-  msize = ntohs (msg->size);
-  switch (ntohs (msg->type))
-  {
-  case GNUNET_MESSAGE_TYPE_TESTBED_ADDHOSTCONFIRM:
-    GNUNET_assert (msize >=
-                   sizeof (struct GNUNET_TESTBED_HostConfirmedMessage));
-    status =
-        handle_addhostconfirm (c,
-                               (const struct 
GNUNET_TESTBED_HostConfirmedMessage
-                                *) msg);
-    break;
-  case GNUNET_MESSAGE_TYPE_TESTBED_GENERICOPSUCCESS:
-    GNUNET_assert (msize ==
-                   sizeof (struct
-                           
GNUNET_TESTBED_GenericOperationSuccessEventMessage));
-    status =
-        handle_opsuccess (c,
-                          (const struct
-                           GNUNET_TESTBED_GenericOperationSuccessEventMessage 
*)
-                          msg);
-    break;
-  case GNUNET_MESSAGE_TYPE_TESTBED_PEERCREATESUCCESS:
-    GNUNET_assert (msize ==
-                   sizeof (struct
-                           GNUNET_TESTBED_PeerCreateSuccessEventMessage));
-    status =
-        handle_peer_create_success (c,
-                                    (const struct
-                                     
GNUNET_TESTBED_PeerCreateSuccessEventMessage
-                                     *) msg);
-    break;
-  case GNUNET_MESSAGE_TYPE_TESTBED_PEEREVENT:
-    GNUNET_assert (msize == sizeof (struct GNUNET_TESTBED_PeerEventMessage));
-    status =
-        handle_peer_event (c,
-                           (const struct GNUNET_TESTBED_PeerEventMessage *)
-                           msg);
-
-    break;
-  case GNUNET_MESSAGE_TYPE_TESTBED_PEERCONFIG:
-    GNUNET_assert (msize >=
-                   sizeof (struct
-                           
GNUNET_TESTBED_PeerConfigurationInformationMessage));
-    status =
-        handle_peer_config (c,
-                            (const struct
-                             GNUNET_TESTBED_PeerConfigurationInformationMessage
-                             *) msg);
-    break;
-  case GNUNET_MESSAGE_TYPE_TESTBED_PEERCONEVENT:
-    GNUNET_assert (msize ==
-                   sizeof (struct GNUNET_TESTBED_ConnectionEventMessage));
-    status =
-        handle_peer_conevent (c,
-                              (const struct
-                               GNUNET_TESTBED_ConnectionEventMessage *) msg);
-    break;
-  case GNUNET_MESSAGE_TYPE_TESTBED_OPERATIONFAILEVENT:
-    GNUNET_assert (msize >=
-                   sizeof (struct 
GNUNET_TESTBED_OperationFailureEventMessage));
-    status =
-        handle_op_fail_event (c,
-                              (const struct
-                               GNUNET_TESTBED_OperationFailureEventMessage *)
-                              msg);
-    break;
-  case GNUNET_MESSAGE_TYPE_TESTBED_SLAVECONFIG:
-    GNUNET_assert (msize >
-                  sizeof (struct GNUNET_TESTBED_SlaveConfiguration));
-    status = 
-       handle_slave_config (c, (const struct 
-                                GNUNET_TESTBED_SlaveConfiguration *) msg);
-    break;
-  case GNUNET_MESSAGE_TYPE_TESTBED_NEEDCONTROLLERCONFIG:
-    GNUNET_assert (msize == sizeof (struct
-                                    GNUNET_TESTBED_NeedControllerConfig));
-    status = 
-        handle_need_controller_config (c, (const struct
-                                           GNUNET_TESTBED_NeedControllerConfig
-                                           *) msg);
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-  if ((GNUNET_OK == status) && (GNUNET_NO == c->in_receive))
-  {
-    c->in_receive = GNUNET_YES;
-    GNUNET_CLIENT_receive (c->client, &message_handler, c,
-                           GNUNET_TIME_UNIT_FOREVER_REL);
-  }
-}
-
-
-/**
- * Function called to notify a client about the connection begin ready to queue
- * more data.  "buf" will be NULL and "size" zero if the connection was closed
- * for writing in the meantime.
- *
- * @param cls closure
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t
-transmit_ready_notify (void *cls, size_t size, void *buf)
-{
-  struct GNUNET_TESTBED_Controller *c = cls;
-  struct MessageQueue *mq_entry;
-
-  c->th = NULL;
-  mq_entry = c->mq_head;
-  GNUNET_assert (NULL != mq_entry);
-  if ((0 == size) && (NULL == buf))     /* Timeout */
-  {
-    LOG_DEBUG ("Message sending timed out -- retrying\n");
-    c->th =
-        GNUNET_CLIENT_notify_transmit_ready (c->client,
-                                             ntohs (mq_entry->msg->size),
-                                             TIMEOUT_REL, GNUNET_YES,
-                                             &transmit_ready_notify, c);
-    return 0;
-  }
-  GNUNET_assert (ntohs (mq_entry->msg->size) <= size);
-  size = ntohs (mq_entry->msg->size);
-  memcpy (buf, mq_entry->msg, size);
-  LOG_DEBUG ("Message of type: %u and size: %u sent\n",
-             ntohs (mq_entry->msg->type), size);
-  GNUNET_free (mq_entry->msg);
-  GNUNET_CONTAINER_DLL_remove (c->mq_head, c->mq_tail, mq_entry);
-  GNUNET_free (mq_entry);
-  mq_entry = c->mq_head;
-  if (NULL != mq_entry)
-    c->th =
-        GNUNET_CLIENT_notify_transmit_ready (c->client,
-                                             ntohs (mq_entry->msg->size),
-                                             TIMEOUT_REL, GNUNET_YES,
-                                             &transmit_ready_notify, c);
-  if (GNUNET_NO == c->in_receive)
-  {
-    c->in_receive = GNUNET_YES;
-    GNUNET_CLIENT_receive (c->client, &message_handler, c,
-                           GNUNET_TIME_UNIT_FOREVER_REL);
-  }
-  return size;
-}
-
-
-/**
- * Queues a message in send queue for sending to the service
- *
- * @param controller the handle to the controller
- * @param msg the message to queue
- */
-void
-GNUNET_TESTBED_queue_message_ (struct GNUNET_TESTBED_Controller *controller,
-                               struct GNUNET_MessageHeader *msg)
-{
-  struct MessageQueue *mq_entry;
-  uint16_t type;
-  uint16_t size;
-
-  type = ntohs (msg->type);
-  size = ntohs (msg->size);
-  GNUNET_assert ((GNUNET_MESSAGE_TYPE_TESTBED_INIT <= type) &&
-                 (GNUNET_MESSAGE_TYPE_TESTBED_MAX > type));
-  mq_entry = GNUNET_malloc (sizeof (struct MessageQueue));
-  mq_entry->msg = msg;
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Queueing message of type %u, size %u for sending\n", type,
-       ntohs (msg->size));
-  GNUNET_CONTAINER_DLL_insert_tail (controller->mq_head, controller->mq_tail,
-                                    mq_entry);
-  if (NULL == controller->th)
-    controller->th =
-        GNUNET_CLIENT_notify_transmit_ready (controller->client, size,
-                                             TIMEOUT_REL, GNUNET_YES,
-                                             &transmit_ready_notify,
-                                             controller);
-}
-
-
-/**
- * Sends the given message as an operation. The given callback is called when a
- * reply for the operation is available.  Call
- * GNUNET_TESTBED_forward_operation_msg_cancel_() to cleanup the returned
- * operation context if the cc hasn't been called
- *
- * @param controller the controller to which the message has to be sent
- * @param operation_id the operation id of the message
- * @param msg the message to send
- * @param cc the callback to call when reply is available
- * @param cc_cls the closure for the above callback
- * @return the operation context which can be used to cancel the forwarded
- *           operation
- */
-struct OperationContext *
-GNUNET_TESTBED_forward_operation_msg_ (struct GNUNET_TESTBED_Controller
-                                       *controller, uint64_t operation_id,
-                                       const struct GNUNET_MessageHeader *msg,
-                                       GNUNET_CLIENT_MessageHandler cc,
-                                       void *cc_cls)
-{
-  struct OperationContext *opc;
-  struct ForwardedOperationData *data;
-  struct GNUNET_MessageHeader *dup_msg;
-  uint16_t msize;
-
-  data = GNUNET_malloc (sizeof (struct ForwardedOperationData));
-  data->cc = cc;
-  data->cc_cls = cc_cls;
-  opc = GNUNET_malloc (sizeof (struct OperationContext));
-  opc->c = controller;
-  opc->type = OP_FORWARDED;
-  opc->data = data;
-  opc->id = operation_id;
-  msize = ntohs (msg->size);
-  dup_msg = GNUNET_malloc (msize);
-  (void) memcpy (dup_msg, msg, msize);
-  GNUNET_TESTBED_queue_message_ (opc->c, dup_msg);
-  GNUNET_CONTAINER_DLL_insert_tail (controller->ocq_head, controller->ocq_tail,
-                                    opc);
-  return opc;
-}
-
-
-/**
- * Function to cancel an operation created by simply forwarding an operation
- * message.
- *
- * @param opc the operation context from 
GNUNET_TESTBED_forward_operation_msg_()
- */
-void
-GNUNET_TESTBED_forward_operation_msg_cancel_ (struct OperationContext *opc)
-{
-  GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
-  GNUNET_free (opc->data);
-  GNUNET_free (opc);
-}
-
-
-/**
- * Functions with this signature are called whenever a
- * complete message is received by the tokenizer.
- *
- * Do not call GNUNET_SERVER_mst_destroy in callback
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message
- *
- * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
- */
-static int
-helper_mst (void *cls, void *client, const struct GNUNET_MessageHeader 
*message)
-{
-  struct GNUNET_TESTBED_ControllerProc *cp = cls;
-  const struct GNUNET_TESTBED_HelperReply *msg;
-  const char *hostname;
-  char *config;
-  uLongf config_size;
-  uLongf xconfig_size;
-
-  msg = (const struct GNUNET_TESTBED_HelperReply *) message;
-  GNUNET_assert (sizeof (struct GNUNET_TESTBED_HelperReply) <
-                 ntohs (msg->header.size));
-  GNUNET_assert (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY ==
-                 ntohs (msg->header.type));
-  config_size = (uLongf) ntohs (msg->config_size);
-  xconfig_size =
-      (uLongf) (ntohs (msg->header.size) -
-                sizeof (struct GNUNET_TESTBED_HelperReply));
-  config = GNUNET_malloc (config_size);
-  GNUNET_assert (Z_OK ==
-                 uncompress ((Bytef *) config, &config_size,
-                             (const Bytef *) &msg[1], xconfig_size));
-  GNUNET_assert (NULL == cp->cfg);
-  cp->cfg = GNUNET_CONFIGURATION_create ();
-  GNUNET_assert (GNUNET_CONFIGURATION_deserialize
-                 (cp->cfg, config, config_size, GNUNET_NO));
-  GNUNET_free (config);
-  if ((NULL == cp->host) ||
-      (NULL == (hostname = GNUNET_TESTBED_host_get_hostname_ (cp->host))))
-    hostname = "localhost";
-  /* Change the hostname so that we can connect to it */
-  GNUNET_CONFIGURATION_set_value_string (cp->cfg, "testbed", "hostname",
-                                         hostname);
-  cp->cb (cp->cls, cp->cfg, GNUNET_OK);
-  return GNUNET_OK;
-}
-
-
-/**
- * Continuation function from GNUNET_HELPER_send()
- *
- * @param cls closure
- * @param result GNUNET_OK on success,
- *               GNUNET_NO if helper process died
- *               GNUNET_SYSERR during GNUNET_HELPER_stop
- */
-static void
-clear_msg (void *cls, int result)
-{
-  struct GNUNET_TESTBED_ControllerProc *cp = cls;
-
-  GNUNET_assert (NULL != cp->shandle);
-  cp->shandle = NULL;
-  GNUNET_free (cp->msg);
-}
-
-
-/**
- * Callback that will be called when the helper process dies. This is not 
called
- * when the helper process is stoped using GNUNET_HELPER_stop()
- *
- * @param cls the closure from GNUNET_HELPER_start()
- */
-static void
-helper_exp_cb (void *cls)
-{
-  struct GNUNET_TESTBED_ControllerProc *cp = cls;
-  GNUNET_TESTBED_ControllerStatusCallback cb;
-  void *cb_cls;
-
-  cb = cp->cb;
-  cb_cls = cp->cls;
-  cp->helper = NULL;
-  GNUNET_TESTBED_controller_stop (cp);
-  if (NULL != cb)
-    cb (cb_cls, NULL, GNUNET_SYSERR);
-}
-
-
-/**
- * Function to call to start a link-controllers type operation once all queues
- * the operation is part of declare that the operation can be activated.
- *
- * @param cls the closure from GNUNET_TESTBED_operation_create_()
- */
-static void
-opstart_link_controllers (void *cls)
-{
-  struct OperationContext *opc = cls;
-  struct ControllerLinkData *data;
-  struct GNUNET_TESTBED_ControllerLinkMessage *msg;
-
-  GNUNET_assert (NULL != opc->data);
-  data = opc->data;
-  msg = data->msg;
-  data->msg = NULL;
-  opc->state = OPC_STATE_STARTED;
-  GNUNET_CONTAINER_DLL_insert_tail (opc->c->ocq_head, opc->c->ocq_tail, opc);
-  GNUNET_TESTBED_queue_message_ (opc->c, &msg->header);
-}
-
-
-/**
- * Callback which will be called when link-controllers type operation is 
released
- *
- * @param cls the closure from GNUNET_TESTBED_operation_create_()
- */
-static void
-oprelease_link_controllers (void *cls)
-{
-  struct OperationContext *opc = cls;
-  struct ControllerLinkData *data;
-
-  data = opc->data;
-  switch (opc->state)
-  {
-  case OPC_STATE_INIT:
-    GNUNET_free (data->msg);
-    break;
-  case OPC_STATE_STARTED:
-    GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
-    break;
-  case OPC_STATE_FINISHED:
-    break;
-  }
-  GNUNET_free_non_null (data);
-  GNUNET_free (opc);
-}
-
-
-/**
- * Function to be called when get slave config operation is ready
- *
- * @param cls the OperationContext of type OP_GET_SLAVE_CONFIG
- */
-static void
-opstart_get_slave_config (void *cls)
-{
-  struct OperationContext *opc = cls;
-  struct GetSlaveConfigData *data;
-  struct GNUNET_TESTBED_SlaveGetConfigurationMessage *msg;
-  uint16_t msize;
-  
-  data = opc->data;
-  msize = sizeof (struct GNUNET_TESTBED_SlaveGetConfigurationMessage);
-  msg = GNUNET_malloc (msize);
-  msg->header.size = htons (msize);
-  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GETSLAVECONFIG);
-  msg->operation_id = GNUNET_htonll (opc->id);
-  msg->slave_id = htonl (data->slave_id);
-  GNUNET_CONTAINER_DLL_insert_tail (opc->c->ocq_head, opc->c->ocq_tail, opc);
-  GNUNET_TESTBED_queue_message_ (opc->c, &msg->header);
-  opc->state = OPC_STATE_STARTED;
-}
-
-
-/**
- * Function to be called when get slave config operation is cancelled or 
finished
- *
- * @param cls the OperationContext of type OP_GET_SLAVE_CONFIG
- */
-static void
-oprelease_get_slave_config (void *cls)
-{
-  struct OperationContext *opc = cls;
-
-  switch (opc->state)
-  {
-  case OPC_STATE_INIT:
-    GNUNET_free (opc->data);
-    break;
-  case OPC_STATE_STARTED:
-    GNUNET_free (opc->data);
-    GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
-    break;
-  case OPC_STATE_FINISHED:
-    if (NULL != opc->data)
-      GNUNET_CONFIGURATION_destroy (opc->data);
-    break;
-  }
-  GNUNET_free (opc);
-}
-
-
-/**
- * Starts a controller process at the host. FIXME: add controller start 
callback
- * with the configuration with which the controller is started
- *
- * @param controller_ip the ip address of the controller. Will be set as 
TRUSTED
- *          host when starting testbed controller at host
- * @param host the host where the controller has to be started; NULL for
- *          localhost
- * @param cfg template configuration to use for the remote controller; the
- *          remote controller will be started with a slightly modified
- *          configuration (port numbers, unix domain sockets and service home
- *          values are changed as per TESTING library on the remote host)
- * @param cb function called when the controller is successfully started or
- *          dies unexpectedly; GNUNET_TESTBED_controller_stop shouldn't be
- *          called if cb is called with GNUNET_SYSERR as status. Will never be
- *          called in the same task as 'GNUNET_TESTBED_controller_start'
- *          (synchronous errors will be signalled by returning NULL). This
- *          parameter cannot be NULL.
- * @param cls closure for above callbacks
- * @return the controller process handle, NULL on errors
- */
-struct GNUNET_TESTBED_ControllerProc *
-GNUNET_TESTBED_controller_start (const char *controller_ip,
-                                 struct GNUNET_TESTBED_Host *host,
-                                 const struct GNUNET_CONFIGURATION_Handle *cfg,
-                                 GNUNET_TESTBED_ControllerStatusCallback cb,
-                                 void *cls)
-{
-  struct GNUNET_TESTBED_ControllerProc *cp;
-  struct GNUNET_TESTBED_HelperInit *msg;
-  const char *hostname;
-  static char *const binary_argv[] = {
-    HELPER_TESTBED_BINARY, NULL
-  };
-  
-  hostname = NULL;
-  cp = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ControllerProc));
-  if ((NULL == host) || (0 == GNUNET_TESTBED_host_get_id_ (host)))
-    cp->helper =
-        GNUNET_HELPER_start (GNUNET_YES, HELPER_TESTBED_BINARY, binary_argv,
-                             &helper_mst, &helper_exp_cb, cp);
-  else
-  {
-    char *remote_args[8];
-    unsigned int argp;
-    const char *username;
-
-    username = GNUNET_TESTBED_host_get_username_ (host);
-    hostname = GNUNET_TESTBED_host_get_hostname_ (host);
-    GNUNET_asprintf (&cp->port, "%u", GNUNET_TESTBED_host_get_ssh_port_ 
(host));
-    if (NULL == username)
-      GNUNET_asprintf (&cp->dst, "%s", hostname);
-    else
-      GNUNET_asprintf (&cp->dst, "address@hidden", username, hostname);
-    LOG_DEBUG ("Starting SSH to destination %s\n", cp->dst);
-    argp = 0;
-    remote_args[argp++] = "ssh";
-    remote_args[argp++] = "-p";
-    remote_args[argp++] = cp->port;
-    remote_args[argp++] = "-o";
-    remote_args[argp++] = "BatchMode=yes";
-    remote_args[argp++] = cp->dst;
-    remote_args[argp++] = HELPER_TESTBED_BINARY_SSH;
-    remote_args[argp++] = NULL;
-    GNUNET_assert (argp == 8);
-    cp->helper =
-        GNUNET_HELPER_start (GNUNET_NO, "ssh", remote_args, &helper_mst,
-                             &helper_exp_cb, cp);
-  }
-  if (NULL == cp->helper)
-  {
-    GNUNET_free_non_null (cp->port);
-    GNUNET_free_non_null (cp->dst);
-    GNUNET_free (cp);
-    return NULL;
-  }
-  cp->host = host;
-  cp->cb = cb;
-  cp->cls = cls;
-  msg = GNUNET_TESTBED_create_helper_init_msg_ (controller_ip, hostname, cfg);
-  cp->msg = &msg->header;
-  cp->shandle =
-      GNUNET_HELPER_send (cp->helper, &msg->header, GNUNET_NO, &clear_msg, cp);
-  if (NULL == cp->shandle)
-  {
-    GNUNET_free (msg);
-    GNUNET_TESTBED_controller_stop (cp);
-    return NULL;
-  }
-  return cp;
-}
-
-
-/**
- * Stop the controller process (also will terminate all peers and controllers
- * dependent on this controller).  This function blocks until the testbed has
- * been fully terminated (!). The controller status cb from
- * GNUNET_TESTBED_controller_start() will not be called.
- *
- * @param cproc the controller process handle
- */
-void
-GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cproc)
-{
-  if (NULL != cproc->shandle)
-    GNUNET_HELPER_send_cancel (cproc->shandle);
-  if (NULL != cproc->helper)
-    GNUNET_HELPER_stop (cproc->helper);
-  if (NULL != cproc->cfg)
-    GNUNET_CONFIGURATION_destroy (cproc->cfg);
-  GNUNET_free_non_null (cproc->port);
-  GNUNET_free_non_null (cproc->dst);
-  GNUNET_free (cproc);
-}
-
-
-/**
- * Start a controller process using the given configuration at the
- * given host.
- *
- * @param cfg configuration to use
- * @param host host to run the controller on; This should be the same host if
- *          the controller was previously started with
- *          GNUNET_TESTBED_controller_start; NULL for localhost
- * @param event_mask bit mask with set of events to call 'cc' for;
- *                   or-ed values of "1LL" shifted by the
- *                   respective 'enum GNUNET_TESTBED_EventType'
- *                   (i.e.  "(1LL << GNUNET_TESTBED_ET_CONNECT) | ...")
- * @param cc controller callback to invoke on events
- * @param cc_cls closure for cc
- * @return handle to the controller
- */
-struct GNUNET_TESTBED_Controller *
-GNUNET_TESTBED_controller_connect (const struct GNUNET_CONFIGURATION_Handle
-                                   *cfg, struct GNUNET_TESTBED_Host *host,
-                                   uint64_t event_mask,
-                                   GNUNET_TESTBED_ControllerCallback cc,
-                                   void *cc_cls)
-{
-  struct GNUNET_TESTBED_Controller *controller;
-  struct GNUNET_TESTBED_InitMessage *msg;
-  const char *controller_hostname;
-  unsigned long long max_parallel_operations;
-  unsigned long long max_parallel_service_connections;
-  unsigned long long max_parallel_topology_config_operations;
-
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_number (cfg, "testbed",
-                                             "MAX_PARALLEL_OPERATIONS",
-                                             &max_parallel_operations))
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_number (cfg, "testbed",
-                                             
"MAX_PARALLEL_SERVICE_CONNECTIONS",
-                                             
&max_parallel_service_connections))
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_number (cfg, "testbed",
-                                             
"MAX_PARALLEL_TOPOLOGY_CONFIG_OPERATIONS",
-                                             
&max_parallel_topology_config_operations))
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
-  controller = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Controller));
-  controller->cc = cc;
-  controller->cc_cls = cc_cls;
-  controller->event_mask = event_mask;
-  controller->cfg = GNUNET_CONFIGURATION_dup (cfg);
-  controller->client = GNUNET_CLIENT_connect ("testbed", controller->cfg);
-  if (NULL == controller->client)
-  {
-    GNUNET_TESTBED_controller_disconnect (controller);
-    return NULL;
-  }
-  if (NULL == host)
-  {
-    host = GNUNET_TESTBED_host_create_by_id_ (0);
-    if (NULL == host)           /* If the above host create fails */
-    {
-      LOG (GNUNET_ERROR_TYPE_WARNING,
-           "Treating NULL host as localhost. Multiple references to localhost "
-           "may break when localhost freed before calling disconnect \n");
-      host = GNUNET_TESTBED_host_lookup_by_id_ (0);
-    }
-    else
-    {
-      controller->aux_host = GNUNET_YES;
-    }
-  }
-  GNUNET_assert (NULL != host);
-  GNUNET_TESTBED_mark_host_registered_at_ (host, controller);
-  controller->host = host;
-  controller->opq_parallel_operations =
-      GNUNET_TESTBED_operation_queue_create_ ((unsigned int)
-                                              max_parallel_operations);
-  controller->opq_parallel_service_connections =
-      GNUNET_TESTBED_operation_queue_create_ ((unsigned int)
-                                              
max_parallel_service_connections);
-  controller->opq_parallel_topology_config_operations=
-      GNUNET_TESTBED_operation_queue_create_ ((unsigned int)
-                                              
max_parallel_service_connections);
-  controller_hostname = GNUNET_TESTBED_host_get_hostname_ (host);
-  if (NULL == controller_hostname)
-    controller_hostname = "127.0.0.1";
-  msg =
-      GNUNET_malloc (sizeof (struct GNUNET_TESTBED_InitMessage) +
-                     strlen (controller_hostname) + 1);
-  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_INIT);
-  msg->header.size =
-      htons (sizeof (struct GNUNET_TESTBED_InitMessage) +
-             strlen (controller_hostname) + 1);
-  msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (host));
-  msg->event_mask = GNUNET_htonll (controller->event_mask);
-  strcpy ((char *) &msg[1], controller_hostname);
-  GNUNET_TESTBED_queue_message_ (controller,
-                                 (struct GNUNET_MessageHeader *) msg);
-  return controller;
-}
-
-
-/**
- * Configure shared services at a controller.  Using this function,
- * you can specify that certain services (such as "resolver")
- * should not be run for each peer but instead be shared
- * across N peers on the specified host.  This function
- * must be called before any peers are created at the host.
- *
- * @param controller controller to configure
- * @param service_name name of the service to share
- * @param num_peers number of peers that should share one instance
- *        of the specified service (1 for no sharing is the default),
- *        use 0 to disable the service
- */
-void
-GNUNET_TESTBED_controller_configure_sharing (struct GNUNET_TESTBED_Controller
-                                             *controller,
-                                             const char *service_name,
-                                             uint32_t num_peers)
-{
-  struct GNUNET_TESTBED_ConfigureSharedServiceMessage *msg;
-  uint16_t service_name_size;
-  uint16_t msg_size;
-
-  service_name_size = strlen (service_name) + 1;
-  msg_size =
-      sizeof (struct GNUNET_TESTBED_ConfigureSharedServiceMessage) +
-      service_name_size;
-  msg = GNUNET_malloc (msg_size);
-  msg->header.size = htons (msg_size);
-  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_SERVICESHARE);
-  msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (controller->host));
-  msg->num_peers = htonl (num_peers);
-  memcpy (&msg[1], service_name, service_name_size);
-  GNUNET_TESTBED_queue_message_ (controller,
-                                 (struct GNUNET_MessageHeader *) msg);
-}
-
-
-/**
- * disconnects from the controller.
- *
- * @param controller handle to controller to stop
- */
-void
-GNUNET_TESTBED_controller_disconnect (struct GNUNET_TESTBED_Controller
-                                      *controller)
-{
-  struct MessageQueue *mq_entry;
-
-  if (NULL != controller->th)
-    GNUNET_CLIENT_notify_transmit_ready_cancel (controller->th);
-  /* Clear the message queue */
-  while (NULL != (mq_entry = controller->mq_head))
-  {
-    GNUNET_CONTAINER_DLL_remove (controller->mq_head, controller->mq_tail,
-                                 mq_entry);
-    GNUNET_free (mq_entry->msg);
-    GNUNET_free (mq_entry);
-  }
-  if (NULL != controller->client)
-    GNUNET_CLIENT_disconnect (controller->client);
-  GNUNET_CONFIGURATION_destroy (controller->cfg);
-  if (GNUNET_YES == controller->aux_host)
-    GNUNET_TESTBED_host_destroy (controller->host);
-  GNUNET_TESTBED_operation_queue_destroy_ 
(controller->opq_parallel_operations);
-  GNUNET_TESTBED_operation_queue_destroy_
-      (controller->opq_parallel_service_connections);
-  GNUNET_TESTBED_operation_queue_destroy_
-      (controller->opq_parallel_topology_config_operations);
-  GNUNET_free (controller);
-}
-
-
-/**
- * Register a host with the controller
- *
- * @param controller the controller handle
- * @param host the host to register
- * @param cc the completion callback to call to inform the status of
- *          registration. After calling this callback the registration handle
- *          will be invalid. Cannot be NULL.
- * @param cc_cls the closure for the cc
- * @return handle to the host registration which can be used to cancel the
- *           registration
- */
-struct GNUNET_TESTBED_HostRegistrationHandle *
-GNUNET_TESTBED_register_host (struct GNUNET_TESTBED_Controller *controller,
-                              struct GNUNET_TESTBED_Host *host,
-                              GNUNET_TESTBED_HostRegistrationCompletion cc,
-                              void *cc_cls)
-{
-  struct GNUNET_TESTBED_HostRegistrationHandle *rh;
-  struct GNUNET_TESTBED_AddHostMessage *msg;
-  const char *username;
-  const char *hostname;
-  uint16_t msg_size;
-  uint16_t user_name_length;
-
-  if (NULL != controller->rh)
-    return NULL;
-  hostname = GNUNET_TESTBED_host_get_hostname_ (host);
-  if (GNUNET_YES == GNUNET_TESTBED_is_host_registered_ (host, controller))
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING, "Host hostname: %s already registered\n",
-         (NULL == hostname) ? "localhost" : hostname);
-    return NULL;
-  }
-  rh = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HostRegistrationHandle));
-  rh->host = host;
-  rh->c = controller;
-  GNUNET_assert (NULL != cc);
-  rh->cc = cc;
-  rh->cc_cls = cc_cls;
-  controller->rh = rh;
-  username = GNUNET_TESTBED_host_get_username_ (host);
-  msg_size = (sizeof (struct GNUNET_TESTBED_AddHostMessage));
-  user_name_length = 0;
-  if (NULL != username)
-  {
-    user_name_length = strlen (username) + 1;
-    msg_size += user_name_length;
-  }
-  /* FIXME: what happens when hostname is NULL? localhost */
-  GNUNET_assert (NULL != hostname);
-  msg_size += strlen (hostname) + 1;
-  msg = GNUNET_malloc (msg_size);
-  msg->header.size = htons (msg_size);
-  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST);
-  msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (host));
-  msg->ssh_port = htons (GNUNET_TESTBED_host_get_ssh_port_ (host));
-  msg->user_name_length = htons (user_name_length);
-  if (NULL != username)
-    memcpy (&msg[1], username, user_name_length);
-  strcpy (((void *) &msg[1]) + user_name_length, hostname);
-  GNUNET_TESTBED_queue_message_ (controller,
-                                 (struct GNUNET_MessageHeader *) msg);
-  return rh;
-}
-
-
-/**
- * Cancel the pending registration. Note that if the registration message is
- * already sent to the service the cancellation has only the effect that the
- * registration completion callback for the registration is never called.
- *
- * @param handle the registration handle to cancel
- */
-void
-GNUNET_TESTBED_cancel_registration (struct 
GNUNET_TESTBED_HostRegistrationHandle
-                                    *handle)
-{
-  if (handle != handle->c->rh)
-  {
-    GNUNET_break (0);
-    return;
-  }
-  handle->c->rh = NULL;
-  GNUNET_free (handle);
-}
-
-
-/**
- * Same as the GNUNET_TESTBED_controller_link_2, however sets the operation id
- * of the generation operation to the given id
- *
- * @param op_cls the operation closure for the event which is generated to
- *          signal success or failure of this operation
- * @param operation_id the id to use for the generated operation's id
- * @param master handle to the master controller who creates the association
- * @param delegated_host requests to which host should be delegated; cannot be 
NULL
- * @param slave_host which host is used to run the slave controller; use NULL 
to
- *          make the master controller connect to the delegated host
- * @param sxcfg serialized and compressed configuration
- * @param sxcfg_size the size sxcfg
- * @param scfg_size the size of uncompressed serialized configuration
- * @param is_subordinate GNUNET_YES if the controller at delegated_host should
- *          be started by the slave controller; GNUNET_NO if the slave
- *          controller has to connect to the already started delegated
- *          controller via TCP/IP
- * @return the operation handle
- */
-static struct GNUNET_TESTBED_Operation *
-GNUNET_TESTBED_controller_link_2_with_opid (void *op_cls,
-                                            uint64_t operation_id,
-                                            struct GNUNET_TESTBED_Controller 
*master,
-                                            struct GNUNET_TESTBED_Host
-                                            * delegated_host, 
-                                            struct GNUNET_TESTBED_Host 
*slave_host,
-                                            const char *sxcfg, 
-                                            size_t sxcfg_size, 
-                                            size_t scfg_size, int 
is_subordinate)
-{
-  struct OperationContext *opc;
-  struct GNUNET_TESTBED_ControllerLinkMessage *msg;
-  struct ControllerLinkData *data;
-  uint16_t msg_size;
-
-  GNUNET_assert (GNUNET_YES ==
-                 GNUNET_TESTBED_is_host_registered_ (delegated_host, master));
-  if ((NULL != slave_host) && (0 != GNUNET_TESTBED_host_get_id_ (slave_host)))
-    GNUNET_assert (GNUNET_YES ==
-                   GNUNET_TESTBED_is_host_registered_ (slave_host, master));
-  msg_size = sxcfg_size + sizeof (struct GNUNET_TESTBED_ControllerLinkMessage);
-  msg = GNUNET_malloc (msg_size);
-  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS);
-  msg->header.size = htons (msg_size);
-  msg->delegated_host_id = htonl (GNUNET_TESTBED_host_get_id_ 
(delegated_host));
-  msg->slave_host_id =
-      htonl (GNUNET_TESTBED_host_get_id_
-             ((NULL != slave_host) ? slave_host : master->host));
-  msg->config_size = htons ((uint16_t) scfg_size);
-  msg->is_subordinate = (GNUNET_YES == is_subordinate) ? 1 : 0;
-  memcpy (&msg[1], sxcfg, sxcfg_size);
-  data = GNUNET_malloc (sizeof (struct ControllerLinkData));
-  data->msg = msg;
-  data->op_cls = op_cls;
-  opc = GNUNET_malloc (sizeof (struct OperationContext));
-  opc->c = master;
-  opc->data = data;
-  opc->type = OP_LINK_CONTROLLERS;
-  opc->id = master->operation_counter++;
-  opc->state = OPC_STATE_INIT;
-  msg->operation_id = GNUNET_htonll (opc->id);
-  opc->op =
-      GNUNET_TESTBED_operation_create_ (opc, &opstart_link_controllers,
-                                        &oprelease_link_controllers);
-  GNUNET_TESTBED_operation_queue_insert_ (master->opq_parallel_operations,
-                                          opc->op);
-  return opc->op;
-}
-
-
-/**
- * Same as the GNUNET_TESTBED_controller_link, however expects configuration in
- * serialized and compressed
- *
- * @param op_cls the operation closure for the event which is generated to
- *          signal success or failure of this operation
- * @param master handle to the master controller who creates the association
- * @param delegated_host requests to which host should be delegated; cannot be 
NULL
- * @param slave_host which host is used to run the slave controller; use NULL 
to
- *          make the master controller connect to the delegated host
- * @param sxcfg serialized and compressed configuration
- * @param sxcfg_size the size sxcfg
- * @param scfg_size the size of uncompressed serialized configuration
- * @param is_subordinate GNUNET_YES if the controller at delegated_host should
- *          be started by the slave controller; GNUNET_NO if the slave
- *          controller has to connect to the already started delegated
- *          controller via TCP/IP
- * @return the operation handle
- */
-struct GNUNET_TESTBED_Operation *
-GNUNET_TESTBED_controller_link_2 (void *op_cls,
-                                 struct GNUNET_TESTBED_Controller *master,
-                                  struct GNUNET_TESTBED_Host *delegated_host,
-                                  struct GNUNET_TESTBED_Host *slave_host,
-                                  const char *sxcfg, size_t sxcfg_size,
-                                  size_t scfg_size, int is_subordinate)
-{
-  return
-      GNUNET_TESTBED_controller_link_2_with_opid (op_cls,
-                                                  master->operation_counter++,
-                                                  master,
-                                                  delegated_host,
-                                                  slave_host,
-                                                  sxcfg, sxcfg_size,
-                                                  scfg_size, is_subordinate);
-}
-
-
-/**
- * Compresses given configuration using zlib compress
- *
- * @param config the serialized configuration
- * @param size the size of config
- * @param xconfig will be set to the compressed configuration (memory is fresly
- *          allocated)
- * @return the size of the xconfig
- */
-size_t
-GNUNET_TESTBED_compress_config_ (const char *config, size_t size,
-                                 char **xconfig)
-{
-  size_t xsize;
-
-  xsize = compressBound ((uLong) size);
-  *xconfig = GNUNET_malloc (xsize);
-  GNUNET_assert (Z_OK ==
-                 compress2 ((Bytef *) * xconfig, (uLongf *) & xsize,
-                            (const Bytef *) config, (uLongf) size,
-                            Z_BEST_SPEED));
-  return xsize;
-}
-
-
-/**
- * Same as the GNUNET_TESTBED_controller_link, however sets the operation id
- * of the generation operation to the given id
- *
- * @param op_cls the operation closure for the event which is generated to
- *          signal success or failure of this operation
- * @param operation_id the id to use for the generated operation's id
- * @param master handle to the master controller who creates the association
- * @param delegated_host requests to which host should be delegated; cannot be 
NULL
- * @param slave_host which host is used to run the slave controller; use NULL 
to
- *          make the master controller connect to the delegated host
- * @param slave_cfg configuration to use for the slave controller
- * @param is_subordinate GNUNET_YES if the controller at delegated_host should
- *          be started by the slave controller; GNUNET_NO if the slave
- *          controller has to connect to the already started delegated
- *          controller via TCP/IP
- * @return the operation handle
- */
-struct GNUNET_TESTBED_Operation *
-GNUNET_TESTBED_controller_link_with_opid (void *op_cls,
-                                          uint64_t operation_id,
-                                          struct GNUNET_TESTBED_Controller 
*master,
-                                          struct GNUNET_TESTBED_Host 
*delegated_host,
-                                          struct GNUNET_TESTBED_Host 
*slave_host,
-                                          const struct 
GNUNET_CONFIGURATION_Handle
-                                          *slave_cfg, int is_subordinate)
-{
-  struct GNUNET_TESTBED_Operation *op;
-  char *config;
-  char *cconfig;
-  size_t cc_size;
-  size_t config_size;
-
-  GNUNET_assert (GNUNET_YES ==
-                 GNUNET_TESTBED_is_host_registered_ (delegated_host, master));
-  if ((NULL != slave_host) && (0 != GNUNET_TESTBED_host_get_id_ (slave_host)))
-    GNUNET_assert (GNUNET_YES ==
-                   GNUNET_TESTBED_is_host_registered_ (slave_host, master));
-  config = GNUNET_CONFIGURATION_serialize (slave_cfg, &config_size);
-  cc_size = GNUNET_TESTBED_compress_config_ (config, config_size, &cconfig);
-  GNUNET_free (config);
-  /* Configuration doesn't fit in 1 message */
-  GNUNET_assert ((UINT16_MAX - 
-                 sizeof (struct GNUNET_TESTBED_ControllerLinkMessage)) >= 
cc_size);
-  op = GNUNET_TESTBED_controller_link_2_with_opid (op_cls, 
-                                                   master->operation_counter++,
-                                                   master, delegated_host,
-                                                   slave_host,
-                                                   (const char *) cconfig,
-                                                   cc_size, config_size,
-                                                   is_subordinate);
-  GNUNET_free (cconfig);
-  return op;
-}
-
-
-/**
- * Create a link from slave controller to delegated controller. Whenever the
- * master controller is asked to start a peer at the delegated controller the
- * request will be routed towards slave controller (if a route exists). The
- * slave controller will then route it to the delegated controller. The
- * configuration of the delegated controller is given and is used to either
- * create the delegated controller or to connect to an existing controller. 
Note
- * that while starting the delegated controller the configuration will be
- * modified to accommodate available free ports.  the 'is_subordinate' 
specifies
- * if the given delegated controller should be started and managed by the slave
- * controller, or if the delegated controller already has a master and the 
slave
- * controller connects to it as a non master controller. The success or failure
- * of this operation will be signalled through the
- * GNUNET_TESTBED_ControllerCallback() with an event of type
- * GNUNET_TESTBED_ET_OPERATION_FINISHED
- *
- * @param op_cls the operation closure for the event which is generated to
- *          signal success or failure of this operation
- * @param master handle to the master controller who creates the association
- * @param delegated_host requests to which host should be delegated; cannot be 
NULL
- * @param slave_host which host is used to run the slave controller; use NULL 
to
- *          make the master controller connect to the delegated host
- * @param slave_cfg configuration to use for the slave controller
- * @param is_subordinate GNUNET_YES if the controller at delegated_host should
- *          be started by the slave controller; GNUNET_NO if the slave
- *          controller has to connect to the already started delegated
- *          controller via TCP/IP
- * @return the operation handle
- */
-struct GNUNET_TESTBED_Operation *
-GNUNET_TESTBED_controller_link (void *op_cls,
-                               struct GNUNET_TESTBED_Controller *master,
-                                struct GNUNET_TESTBED_Host *delegated_host,
-                                struct GNUNET_TESTBED_Host *slave_host,
-                                const struct GNUNET_CONFIGURATION_Handle
-                                *slave_cfg, int is_subordinate)
-{
-  return
-      GNUNET_TESTBED_controller_link_with_opid (op_cls, 
-                                                master->operation_counter++,
-                                                master, delegated_host,
-                                                slave_host, slave_cfg,
-                                                is_subordinate);
-}
-
-
-/**
- * Function to acquire the configuration of a running slave controller. The
- * completion of the operation is signalled through the controller_cb from
- * GNUNET_TESTBED_controller_connect(). If the operation is successful the
- * handle to the configuration is available in the generic pointer of
- * operation_finished field of struct GNUNET_TESTBED_EventInformation.
- *
- * @param op_cls the closure for the operation
- * @param master the handle to master controller
- * @param slave_host the host where the slave controller is running; the handle
- *          to the slave_host should remain valid until this operation is
- *          cancelled or marked as finished
- * @return the operation handle; NULL if the slave_host is not registered at
- *           master
- */
-struct GNUNET_TESTBED_Operation *
-GNUNET_TESTBED_get_slave_config (void *op_cls,
-                                 struct GNUNET_TESTBED_Controller *master,
-                                 struct GNUNET_TESTBED_Host *slave_host)
-{
-  struct OperationContext *opc;
-  struct GetSlaveConfigData *data;
-
-  if (GNUNET_NO == GNUNET_TESTBED_is_host_registered_ (slave_host, master))
-    return NULL;
-  data = GNUNET_malloc (sizeof (struct GetSlaveConfigData));
-  data->slave_id = GNUNET_TESTBED_host_get_id_ (slave_host);
-  data->op_cls = op_cls;
-  opc = GNUNET_malloc (sizeof (struct OperationContext));
-  opc->state = OPC_STATE_INIT;
-  opc->c = master;
-  opc->id = master->operation_counter++;
-  opc->type = OP_GET_SLAVE_CONFIG;
-  opc->data = data;
-  opc->op =
-      GNUNET_TESTBED_operation_create_ (opc, &opstart_get_slave_config,
-                                        &oprelease_get_slave_config);
-  GNUNET_TESTBED_operation_queue_insert_ (master->opq_parallel_operations,
-                                         opc->op); 
-  return opc->op;
-}
-
-
-/**
- * Ask the testbed controller to write the current overlay topology to
- * a file.  Naturally, the file will only contain a snapshot as the
- * topology may evolve all the time.
- *
- * @param controller overlay controller to inspect
- * @param filename name of the file the topology should
- *        be written to.
- */
-void
-GNUNET_TESTBED_overlay_write_topology_to_file (struct GNUNET_TESTBED_Controller
-                                               *controller,
-                                               const char *filename)
-{
-  GNUNET_break (0);
-}
-
-
-/**
- * Creates a helper initialization message. This function is here because we
- * want to use this in testing
- *
- * @param cname the ip address of the controlling host
- * @param hostname the hostname of the destination this message is intended for
- * @param cfg the configuration that has to used to start the testbed service
- *          thru helper
- * @return the initialization message
- */
-struct GNUNET_TESTBED_HelperInit *
-GNUNET_TESTBED_create_helper_init_msg_ (const char *cname,
-                                       const char *hostname,
-                                        const struct 
GNUNET_CONFIGURATION_Handle
-                                        *cfg)
-{
-  struct GNUNET_TESTBED_HelperInit *msg;
-  char *config;
-  char *xconfig;
-  size_t config_size;
-  size_t xconfig_size;
-  uint16_t cname_len;
-  uint16_t hostname_len;
-  uint16_t msg_size;
-
-  config = GNUNET_CONFIGURATION_serialize (cfg, &config_size);
-  GNUNET_assert (NULL != config);
-  xconfig_size =
-      GNUNET_TESTBED_compress_config_ (config, config_size, &xconfig);
-  GNUNET_free (config);
-  cname_len = strlen (cname);
-  hostname_len = (NULL == hostname) ? 0 : strlen (hostname);
-  msg_size =
-      xconfig_size + cname_len + 1 + sizeof (struct GNUNET_TESTBED_HelperInit);
-  msg_size += hostname_len;
-  msg = GNUNET_realloc (xconfig, msg_size);
-  (void) memmove (((void *) &msg[1]) + cname_len + 1 + hostname_len,
-                 msg,
-                 xconfig_size);
-  msg->header.size = htons (msg_size);
-  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_INIT);
-  msg->cname_size = htons (cname_len);
-  msg->hostname_size = htons (hostname_len);
-  msg->config_size = htons (config_size);
-  (void) strcpy ((char *) &msg[1], cname);
-  if (0 != hostname_len)
-    (void) strncpy (((char *) &msg[1]) + cname_len + 1, hostname, 
hostname_len);
-  return msg;
-}
-
-
-/**
- * Cancel a pending operation.  Releases all resources
- * of the operation and will ensure that no event
- * is generated for the operation.  Does NOT guarantee
- * that the operation will be fully undone (or that
- * nothing ever happened).
- *
- * @param operation operation to cancel
- */
-void
-GNUNET_TESTBED_operation_cancel (struct GNUNET_TESTBED_Operation *operation)
-{
-  GNUNET_TESTBED_operation_done (operation);
-}
-
-
-/**
- * Signal that the information from an operation has been fully
- * processed.  This function MUST be called for each event
- * of type 'operation_finished' to fully remove the operation
- * from the operation queue.  After calling this function, the
- * 'op_result' becomes invalid (!).
- *
- * @param operation operation to signal completion for
- */
-void
-GNUNET_TESTBED_operation_done (struct GNUNET_TESTBED_Operation *operation)
-{
-  switch (operation->type)
-  {
-  case OP_PEER_CREATE:
-  case OP_PEER_DESTROY:
-  case OP_PEER_START:
-  case OP_PEER_STOP:
-  case OP_PEER_INFO:
-  case OP_OVERLAY_CONNECT:
-  case OP_LINK_CONTROLLERS:
-    GNUNET_TESTBED_operation_release_ (operation);
-    return;
-  default:
-    GNUNET_assert (0);
-    break;
-  }
-}
-
-
-/**
- * Generates configuration by uncompressing configuration in given message. The
- * given message should be of the following types:
- * GNUNET_MESSAGE_TYPE_TESTBED_PEERCONFIG,
- * GNUNET_MESSAGE_TYPE_TESTBED_SLAVECONFIG
- *
- * @param msg the message containing compressed configuration
- * @return handle to the parsed configuration
- */
-struct GNUNET_CONFIGURATION_Handle *
-GNUNET_TESTBED_extract_config_ (const struct GNUNET_MessageHeader *msg)
-{  
-  struct GNUNET_CONFIGURATION_Handle *cfg;
-  Bytef *data;
-  const Bytef *xdata;
-  uLong data_len;
-  uLong xdata_len;
-  int ret;
-
-  switch (ntohs (msg->type))
-  {
-  case GNUNET_MESSAGE_TYPE_TESTBED_PEERCONFIG:
-    {
-      const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *imsg;
-
-      imsg = (const struct GNUNET_TESTBED_PeerConfigurationInformationMessage 
*)
-         msg;
-      data_len = (uLong) ntohs (imsg->config_size);
-      xdata_len = ntohs (imsg->header.size)
-         - sizeof (struct GNUNET_TESTBED_PeerConfigurationInformationMessage);
-      xdata = (const Bytef *) &imsg[1];
-    }
-    break;
-  case GNUNET_MESSAGE_TYPE_TESTBED_SLAVECONFIG:
-    {
-      const struct GNUNET_TESTBED_SlaveConfiguration *imsg;
-
-      imsg = (const struct GNUNET_TESTBED_SlaveConfiguration *) msg;
-      data_len = (uLong) ntohs (imsg->config_size);
-      xdata_len =  ntohs (imsg->header.size) 
-         - sizeof (struct GNUNET_TESTBED_SlaveConfiguration);
-      xdata = (const Bytef *) &imsg[1];
-    }
-    break;
-  default:
-    GNUNET_assert (0);
-  }  
-  data = GNUNET_malloc (data_len);
-  if (Z_OK !=
-      (ret =
-       uncompress (data, &data_len, xdata, xdata_len)))
-    GNUNET_assert (0);
-  cfg = GNUNET_CONFIGURATION_create ();
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_CONFIGURATION_deserialize (cfg, (const char *) data,
-                                                   (size_t) data_len,
-                                                   GNUNET_NO));
-  GNUNET_free (data);
-  return cfg;
-}
-
-
-/**
- * Checks the integrity of the OperationFailureEventMessage and if good returns
- * the error message it contains.
- *
- * @param msg the OperationFailureEventMessage
- * @return the error message
- */
-const char *
-GNUNET_TESTBED_parse_error_string_ (const struct
-                                    GNUNET_TESTBED_OperationFailureEventMessage
-                                    *msg)
-{
-  uint16_t msize;
-  const char *emsg;
-  
-  msize = ntohs (msg->header.size);
-  if (sizeof (struct GNUNET_TESTBED_OperationFailureEventMessage) >= msize)
-    return NULL;
-  msize -= sizeof (struct GNUNET_TESTBED_OperationFailureEventMessage);
-  emsg = (const char *) &msg[1];
-  if ('\0' != emsg[msize - 1])
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
-  return emsg;
-}
-
-/* end of testbed_api.c */

Copied: gnunet/src/testbed/testbed_api_sd.c (from rev 26092, 
gnunet/src/testbed/standard_deviation.c)
===================================================================
--- gnunet/src/testbed/testbed_api_sd.c                         (rev 0)
+++ gnunet/src/testbed/testbed_api_sd.c 2013-02-14 10:41:47 UTC (rev 26097)
@@ -0,0 +1,204 @@
+/*
+      This file is part of GNUnet
+      (C) 2008--2012 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/testbed_api_sd.c
+ * @brief functions to calculate standard deviation
+ * @author Sree Harsha Totakura <address@hidden> 
+ */
+
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "testbed_api_sd.h"
+
+/**
+ * An entry to hold data which will be used to calculate SD
+ */
+struct SDEntry
+{
+  /**
+   * DLL next pointer
+   */
+  struct SDEntry *next;
+
+  /**
+   * DLL prev pointer
+   */
+  struct SDEntry *prev;
+
+  /**
+   * The value to store
+   */
+  unsigned int amount;
+};
+
+
+/**
+ * Opaque handle for calculating SD
+ */
+struct SDHandle
+{
+  /**
+   * DLL head for storing entries
+   */
+  struct SDEntry *head;
+
+  /**
+   * DLL tail for storing entries
+   */
+  struct SDEntry *tail;
+
+  /**
+   * Squared sum of data values
+   */
+  unsigned long long sqsum;
+
+  /**
+   * Sum of the data values
+   */
+  unsigned long sum;
+
+  /**
+   * The average of data amounts
+   */
+  float avg;
+
+  /**
+   * The variance
+   */
+  double vr;
+
+  /**
+   * Number of data values; also the length of DLL containing SDEntries
+   */
+  unsigned int cnt;
+
+  /**
+   * max number of entries we can have in the DLL
+   */
+  unsigned int max_cnt;
+};
+
+
+/**
+ * Initialize standard deviation calculation handle
+ *
+ * @param max_cnt the maximum number of readings to keep
+ * @return the initialized handle
+ */
+struct SDHandle *
+GNUNET_TESTBED_SD_init_ (unsigned int max_cnt)
+{
+  struct SDHandle *h;
+
+  GNUNET_assert (1 < max_cnt);
+  h = GNUNET_malloc (sizeof (struct SDHandle));
+  h->max_cnt = max_cnt;
+  return h;
+}
+
+
+/**
+ * Frees the memory allocated to the SD handle
+ *
+ * @param h the SD handle
+ */
+void
+GNUNET_TESTBED_SD_destroy_ (struct SDHandle *h)
+{
+  struct SDEntry *entry;
+
+  while (NULL != (entry = h->head))
+  {
+    GNUNET_CONTAINER_DLL_remove (h->head, h->tail, entry);
+    GNUNET_free (entry);
+  }
+  GNUNET_free (h);
+}
+
+
+/**
+ * Add a reading to SD
+ *
+ * @param h the SD handle
+ * @param amount the reading value
+ */
+void
+GNUNET_TESTBED_SD_add_data_ (struct SDHandle *h, unsigned int amount)
+{
+  struct SDEntry *entry;
+  double sqavg;
+  double sqsum_avg;
+
+  entry = NULL;
+  if (h->cnt == h->max_cnt)
+  {
+    entry = h->head;
+    GNUNET_CONTAINER_DLL_remove (h->head, h->tail, entry);
+    h->sum -= entry->amount;
+    h->sqsum -=
+        ((unsigned long) entry->amount) * ((unsigned long) entry->amount);
+    h->cnt--;
+  }
+  GNUNET_assert (h->cnt < h->max_cnt);
+  if (NULL == entry)
+    entry = GNUNET_malloc (sizeof (struct SDEntry));
+  entry->amount = amount;
+  GNUNET_CONTAINER_DLL_insert_tail (h->head, h->tail, entry);
+  h->sum += amount;
+  h->cnt++;
+  h->avg = ((float) h->sum) / ((float) h->cnt);
+  h->sqsum += ((unsigned long) amount) * ((unsigned long) amount);
+  sqsum_avg = ((double) h->sqsum) / ((double) h->cnt);
+  sqavg = ((double) h->avg) * ((double) h->avg);
+  h->vr = sqsum_avg - sqavg;
+}
+
+
+/**
+ * Returns the factor by which the given amount differs from the standard 
deviation
+ *
+ * @param h the SDhandle
+ * @param amount the value for which the deviation is returned
+
+ * @return the deviation from the average; GNUNET_SYSERR if the deviation 
cannot
+ *           be calculated OR 0 if the deviation is less than the average; a
+ *           maximum of 4 is returned for deviations equal to or larger than 4
+ */
+int
+GNUNET_TESTBED_SD_deviation_factor_ (struct SDHandle *h, unsigned int amount)
+{
+  double diff;
+  unsigned int n;
+
+  if (h->cnt < 2)
+    return GNUNET_SYSERR;
+  if (((float) amount) > h->avg)
+    diff = ((float) amount) - h->avg;
+  else
+    return 0;                   //diff = h->avg - ((float) amount);
+  diff *= diff;
+  for (n = 1; n < 4; n++)
+    if (diff < (((double) (n * n)) * h->vr))
+      break;
+  return n;
+}
+
+/* end of testbed_api_sd.c */

Added: gnunet/src/testbed/testbed_api_sd.h
===================================================================
--- gnunet/src/testbed/testbed_api_sd.h                         (rev 0)
+++ gnunet/src/testbed/testbed_api_sd.h 2013-02-14 10:41:47 UTC (rev 26097)
@@ -0,0 +1,80 @@
+/*
+      This file is part of GNUnet
+      (C) 2008--2012 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/testbed_api_sd.h
+ * @brief functions to calculate standard deviation
+ * @author Sree Harsha Totakura <address@hidden> 
+ */
+
+#ifndef TESTBED_API_SD_H
+#define TESTBED_API_SD_H
+
+
+/**
+ * Opaque handle for calculating SD
+ */
+struct SDHandle;
+
+
+/**
+ * Initialize standard deviation calculation handle
+ *
+ * @param max_cnt the maximum number of readings to keep
+ * @return the initialized handle
+ */
+struct SDHandle *
+GNUNET_TESTBED_SD_init_ (unsigned int max_cnt);
+
+
+/**
+ * Frees the memory allocated to the SD handle
+ *
+ * @param h the SD handle
+ */
+void
+GNUNET_TESTBED_SD_destroy_ (struct SDHandle *h);
+
+
+/**
+ * Add a reading to SD
+ *
+ * @param h the SD handle
+ * @param amount the reading value
+ */
+void
+GNUNET_TESTBED_SD_add_data_ (struct SDHandle *h, unsigned int amount);
+
+
+/**
+ * Returns the factor by which the given amount differs from the standard 
deviation
+ *
+ * @param h the SDhandle
+ * @param amount the value for which the deviation is returned
+
+ * @return the deviation from the average; GNUNET_SYSERR if the deviation 
cannot
+ *           be calculated OR 0 if the deviation is less than the average; a
+ *           maximum of 4 is returned for deviations equal to or larger than 4
+ */
+int
+GNUNET_TESTBED_SD_deviation_factor_ (struct SDHandle *h, unsigned int amount);
+
+#endif
+/* end of testbed_api.h */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]