helper reply with modified config
authorSree Harsha Totakura <totakura@in.tum.de>
Tue, 17 Jul 2012 22:25:44 +0000 (22:25 +0000)
committerSree Harsha Totakura <totakura@in.tum.de>
Tue, 17 Jul 2012 22:25:44 +0000 (22:25 +0000)
src/include/gnunet_protocols.h
src/include/gnunet_testbed_service.h
src/testbed/Makefile.am
src/testbed/gnunet-service-testbed.c
src/testbed/gnunet-testbed-helper.c
src/testbed/test_testbed_api_hosts.c
src/testbed/testbed_api.c
src/testbed/testbed_api_hosts.c
src/testbed/testbed_api_hosts.h
src/testbed/testbed_helper.h

index 10869eba2b32942bb4d665f40ed51c2a7acd5f0c..9039d0f1b13b989ac95b86608bbeb2471e47084f 100644 (file)
@@ -1511,6 +1511,11 @@ extern "C"
  */
 #define GNUNET_MESSAGE_TYPE_TESTBED_HELPER_INIT 495
 
+/**
+ * The reply message from gnunet-testbed-helper
+ */
+#define GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY 496
+
 
 /**
  *  Next available: 500
index a190b67a729b91cff85a6da1be6bf37a7591df28..8888d781eba6ee3e63e72101f2ac7d0276ab0cd7 100644 (file)
@@ -403,14 +403,17 @@ struct GNUNET_TESTBED_ControllerProc;
 
 
 /**
- * Function called on errors with the controller.
+ * Callback to signal successfull startup of the controller process
  *
- * @param cls closure
- * @param emsg error message if available; can be NULL, which does NOT mean
- *             that there was no error
+ * @param cls the closure from GNUNET_TESTBED_controller_start()
+ * @param cfg the configuration with which the controller has been started;
+ *          NULL if status is not GNUNET_OK
+ * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
+ *          GNUNET_TESTBED_controller_stop() shouldn't be called in this case
  */
-typedef void (*GNUNET_TESTBED_ControllerErrorCallback)(void *cls,
-                                                      const char *emsg);
+typedef void (*GNUNET_TESTBED_ControllerStatusCallback) (void *cls, 
+                                                        const struct GNUNET_CONFIGURATION_Handle *cfg,
+                                                        int status);
 
 
 /**
@@ -419,25 +422,26 @@ typedef void (*GNUNET_TESTBED_ControllerErrorCallback)(void *cls,
  *
  * @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 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 cec function called if the contoller dies unexpectedly; will not be 
- *            invoked after GNUNET_TESTBED_controller_stop, if 'cec' was called,
- *            GNUNET_TESTBED_controller_stop must no longer be called; will
- *            never be called in the same task as 'GNUNET_TESTBED_controller_start'
- *            (synchronous errors will be signalled by returning NULL)
- * @param cec_cls closure for 'cec'
+ * @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)
+ * @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_ControllerErrorCallback cec,
-                                void *cec_cls);
+                                 GNUNET_TESTBED_ControllerStatusCallback cb,
+                                void *cls);
 
 
 /**
index 80e6b9e3dc2131ccf3fa82eefff4e205d8382b51..f5fbbe21d3ab38ac439484b101c2996d9e63445b 100644 (file)
@@ -33,6 +33,7 @@ gnunet_testbed_helper_SOURCES = \
 gnunet_testbed_helper_LDADD = $(XLIB) \
  $(top_builddir)/src/util/libgnunetutil.la \
  $(top_builddir)/src/testing/libgnunettesting.la \
+ libgnunettestbed.la \
  $(LTLIBINTL) -lz
 gnunet_testbed_helper_DEPENDENCIES = \
   gnunet-service-testbed.$(OBJEXT)
@@ -70,7 +71,7 @@ check_PROGRAMS = \
 if ENABLE_TEST_RUN
  TESTS = \
   test_testbed_api_hosts \
-  test_gnunet_testbed_helper
+  #test_gnunet_testbed_helper
 endif
 
 test_testbed_api_hosts_SOURCES = \
index 3908af14a03e04d848f11395ec9f16310dea5fea..6aafd1b607f7956f36e1ccc4d35039ba48305fc8 100644 (file)
@@ -166,6 +166,23 @@ struct Slave
 };
 
 
+/**
+ * Slave startup context
+ */
+struct SlaveContext
+{
+  /**
+   * The slave corresponding to this context
+   */
+  struct Slave *slave;
+
+  /**
+   * The configuration used as a template while startup
+   */
+  struct GNUNET_CONFIGURATION_Handle *cfg;
+};
+
+
 /**
  * States of LCFContext
  */
@@ -703,24 +720,35 @@ slave_event_callback(void *cls,
 
 
 /**
- * Callback for unexpected slave shutdowns
+ * Callback to signal successfull startup of the controller process
  *
- * @param cls closure
- * @param emsg error message if available; can be NULL, which does NOT mean
- *             that there was no error
+ * @param cls the closure from GNUNET_TESTBED_controller_start()
+ * @param cfg the configuration with which the controller has been started;
+ *          NULL if status is not GNUNET_OK
+ * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
+ *          GNUNET_TESTBED_controller_stop() shouldn't be called in this case
  */
 static void 
-slave_shutdown_handler (void *cls, const char *emsg)
+slave_status_callback (void *cls, 
+                       const struct GNUNET_CONFIGURATION_Handle *cfg,
+                       int status)
 {
-  struct Slave *slave;
+  struct SlaveContext *sc = cls;
 
-  slave = (struct Slave *) cls;
-  slave->controller_proc = NULL;
-  LOG (GNUNET_ERROR_TYPE_WARNING,
-       "Unexpected slave shutdown\n");
-  if (NULL != emsg)
-    LOG (GNUNET_ERROR_TYPE_WARNING, "Error: %s\n", emsg);
-  GNUNET_SCHEDULER_shutdown ();        /* We too shutdown */
+  if (GNUNET_SYSERR == status)
+  {
+    sc->slave->controller_proc = NULL;
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "Unexpected slave shutdown\n");
+    GNUNET_SCHEDULER_shutdown ();      /* We too shutdown */
+    return;
+  }
+  GNUNET_CONFIGURATION_destroy (sc->cfg);
+  sc->slave->controller =
+    GNUNET_TESTBED_controller_connect (cfg, host_list[sc->slave->host_id],
+                                       master_context->event_mask,
+                                       &slave_event_callback, sc->slave);
+  GNUNET_free (sc);
 }
 
 
@@ -950,6 +978,7 @@ handle_link_controllers (void *cls,
 {
   const struct GNUNET_TESTBED_ControllerLinkMessage *msg;
   struct GNUNET_CONFIGURATION_Handle *cfg;
+  struct SlaveContext *sc;
   struct LCFContextQueue *lcfq;
   struct Route *route;
   struct Route *new_route;
@@ -1053,19 +1082,17 @@ handle_link_controllers (void *cls,
     slave = GNUNET_malloc (sizeof (struct Slave));
     slave->host_id = delegated_host_id;
     slave_list_add (slave);
+    sc = GNUNET_malloc (sizeof (struct SlaveContext));
+    sc->slave = slave;
+    sc->cfg = cfg;
     if (1 == msg->is_subordinate)
     {
       slave->controller_proc =
         GNUNET_TESTBED_controller_start (master_context->master_ip,
-                                        host_list[delegated_host_id],
-                                        cfg, &slave_shutdown_handler,
-                                        slave);
-    }
-    slave->controller =
-      GNUNET_TESTBED_controller_connect (cfg, host_list[delegated_host_id],
-                                         master_context->event_mask,
-                                         &slave_event_callback, slave);
-    GNUNET_CONFIGURATION_destroy (cfg);
+                                        host_list[slave->host_id],
+                                        cfg, &slave_status_callback,
+                                        sc);
+    }    
     new_route = GNUNET_malloc (sizeof (struct Route));
     new_route->dest = delegated_host_id;
     new_route->thru = master_context->host_id;
index 4c202193bb76a0ea35efc0d20a563c82b245d1a5..23dfeddc25b5142c8ab0565d865a6f523202cb31 100644 (file)
@@ -33,7 +33,9 @@
 #include "platform.h"
 #include "gnunet_util_lib.h"
 #include "gnunet_testing_lib-new.h"
+#include "gnunet_testbed_service.h"
 #include "testbed_helper.h"
+#include "testbed_api.h"
 #include <zlib.h>
 
 /**
 #define LOG_DEBUG(...)                          \
   LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
 
+
+/**
+ * Context for a single write on a chunk of memory
+ */
+struct WriteContext
+{
+  /**
+   * The data to write
+   */
+  void *data;
+
+  /**
+   * The length of the data
+   */
+  size_t length;
+
+  /**
+   * The current position from where the write operation should begin
+   */
+  size_t pos;
+};
+
+
 /**
  * Handle to the testing system
  */
@@ -63,6 +88,11 @@ struct GNUNET_SERVER_MessageStreamTokenizer *tokenizer;
  */
 static struct GNUNET_DISK_FileHandle *stdin_fd;
 
+/**
+ * Disk handle for stdout
+ */
+static struct GNUNET_DISK_FileHandle *stdout_fd;
+
 /**
  * The process handle to the testbed service
  */
@@ -83,6 +113,11 @@ static struct GNUNET_DISK_PipeHandle *pipe_out;
  */
 static GNUNET_SCHEDULER_TaskIdentifier read_task_id;
 
+/**
+ * Task identifier for the write task
+ */
+static GNUNET_SCHEDULER_TaskIdentifier write_task_id;
+
 /**
  * Are we done reading messages from stdin?
  */
@@ -109,7 +144,15 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
     GNUNET_SCHEDULER_cancel (read_task_id);
     read_task_id = GNUNET_SCHEDULER_NO_TASK;
   }
-  (void) GNUNET_DISK_file_close (stdin_fd);
+  if (GNUNET_SCHEDULER_NO_TASK != write_task_id)
+  {
+    GNUNET_SCHEDULER_cancel (write_task_id);
+    write_task_id = GNUNET_SCHEDULER_NO_TASK;
+  }
+  if (NULL != stdin_fd)
+    (void) GNUNET_DISK_file_close (stdin_fd);
+  if (NULL != stdout_fd)
+    (void) GNUNET_DISK_file_close (stdin_fd);
   GNUNET_SERVER_mst_destroy (tokenizer);  
   tokenizer = NULL;
   if (NULL != testbed)
@@ -137,6 +180,41 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 }
 
 
+/**
+ * Task to write to the standard out
+ *
+ * @param 
+ * @return 
+ */
+static void
+write_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct WriteContext *wc = cls;
+  ssize_t bytes_wrote;
+
+  GNUNET_assert (NULL != wc);
+  write_task_id = GNUNET_SCHEDULER_NO_TASK;
+  if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
+  {
+    GNUNET_free (wc->data);
+    GNUNET_free (wc);
+    return;
+  }
+  bytes_wrote = GNUNET_DISK_file_write (stdout_fd, wc->data + wc->pos,
+                                        wc->length - wc->pos);
+  GNUNET_assert (GNUNET_SYSERR != bytes_wrote);
+  wc->pos += bytes_wrote;
+  if (wc->pos == wc->length)
+  {
+    GNUNET_free (wc->data);
+    GNUNET_free (wc);
+    return;
+  }
+  write_task_id = GNUNET_SCHEDULER_add_write_file
+    (GNUNET_TIME_UNIT_FOREVER_REL, stdout_fd, &write_task, wc);
+}
+
+
 /**
  * Functions with this signature are called whenever a
  * complete message is received by the tokenizer.
@@ -154,11 +232,15 @@ tokenizer_cb (void *cls, void *client,
               const struct GNUNET_MessageHeader *message)
 {
   const struct GNUNET_TESTBED_HelperInit *msg;
+  struct GNUNET_TESTBED_HelperReply *reply;
   struct GNUNET_CONFIGURATION_Handle *cfg;
+  struct WriteContext *wc;
   char *controller;
   char *config;
-  uLongf config_size;
-  uint16_t xconfig_size;
+  char *xconfig;
+  size_t config_size;
+  uLongf ul_config_size;
+  size_t xconfig_size;
   uint16_t cname_size;
 
   if ((sizeof (struct GNUNET_TESTBED_HelperInit) >= ntohs (message->size)) ||
@@ -177,10 +259,11 @@ tokenizer_cb (void *cls, void *client,
          "Controller name cannot be empty -- exiting\n");
     goto error;
   }
-  config_size = (uLongf) ntohs (msg->config_size);
-  config = GNUNET_malloc (config_size);
-  xconfig_size = ntohs (message->size) - (cname_size + 1);
-  if (Z_OK != uncompress ((Bytef *) config, &config_size,
+  ul_config_size = (uLongf) ntohs (msg->config_size);
+  config = GNUNET_malloc (ul_config_size);
+  xconfig_size = ntohs (message->size) - 
+    (cname_size + 1 + sizeof (struct GNUNET_TESTBED_HelperInit));
+  if (Z_OK != uncompress ((Bytef *) config, &ul_config_size,
                           (const Bytef *) (controller + cname_size + 1),
                           (uLongf) xconfig_size))
   {
@@ -190,8 +273,8 @@ tokenizer_cb (void *cls, void *client,
     goto error;
   }
   cfg = GNUNET_CONFIGURATION_create ();  
-  if (GNUNET_OK != GNUNET_CONFIGURATION_deserialize (cfg, config, config_size,
-                                                     GNUNET_NO))
+  if (GNUNET_OK != GNUNET_CONFIGURATION_deserialize (cfg, config, 
+                                                     ul_config_size, GNUNET_NO))
   {
     LOG (GNUNET_ERROR_TYPE_WARNING, 
          "Unable to deserialize config -- exiting\n");
@@ -234,6 +317,18 @@ tokenizer_cb (void *cls, void *client,
   GNUNET_DISK_pipe_close_end (pipe_out, GNUNET_DISK_PIPE_END_WRITE);
   GNUNET_DISK_pipe_close_end (pipe_in, GNUNET_DISK_PIPE_END_READ);
   done_reading = GNUNET_YES;
+  config = GNUNET_CONFIGURATION_serialize (cfg, &config_size);
+  xconfig_size = GNUNET_TESTBED_compress_config (config, config_size, &xconfig);
+  wc = GNUNET_malloc (sizeof (struct WriteContext));
+  wc->length = xconfig_size + sizeof (struct GNUNET_TESTBED_HelperReply);
+  reply = GNUNET_realloc (xconfig, wc->length);
+  memmove (&reply[1], reply, xconfig_size);
+  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY);
+  reply->header.size = htons ((uint16_t) wc->length);
+  reply->config_size = htons ((uint16_t) config_size);
+  wc->data = reply;
+  write_task_id = GNUNET_SCHEDULER_add_write_file
+    (GNUNET_TIME_UNIT_FOREVER_REL, stdout_fd, &write_task, wc);       
   return GNUNET_OK;
   
  error:
@@ -302,6 +397,7 @@ run (void *cls, char *const *args, const char *cfgfile,
   LOG_DEBUG ("Starting testbed helper...\n");
   tokenizer = GNUNET_SERVER_mst_create (&tokenizer_cb, NULL);
   stdin_fd = GNUNET_DISK_get_handle_from_native (stdin);
+  stdout_fd = GNUNET_DISK_get_handle_from_native (stdout);
   read_task_id =
     GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                     stdin_fd, &read_task, NULL);
index 54e2461c7eb642fd7a8dc7ea7d93bbbac4590788..ae71abc547e18c58332ae64fc56a24a7ac74548f 100644 (file)
  */
 static struct GNUNET_TESTBED_Host *host;
 
-/**
- * The host helper handle
- */
-static struct GNUNET_TESTBED_HelperHandle *helper_handle;
-
 /**
  * Global test status
  */
@@ -62,26 +57,10 @@ GNUNET_SCHEDULER_TaskIdentifier shutdown_id;
 static void
 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  GNUNET_TESTBED_host_stop_ (helper_handle);
   GNUNET_TESTBED_host_destroy (host);
 }
 
 
-/**
- * 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 
-exp_cb (void *cls)
-{
-  status = GNUNET_SYSERR;
-  GNUNET_SCHEDULER_cancel (shutdown_id);
-  GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
-}
-
-
 /**
  * Main run function. 
  *
@@ -102,8 +81,6 @@ run (void *cls, char *const *args, const char *cfgfile,
   GNUNET_assert (NULL != host);
   GNUNET_assert (0 == GNUNET_TESTBED_host_get_id_ (host));
   GNUNET_assert (host == GNUNET_TESTBED_host_lookup_by_id_ (0));
-  helper_handle = GNUNET_TESTBED_host_run_ ("127.0.0.1", host, cfg, &exp_cb, NULL);
-  GNUNET_assert (NULL != helper_handle);
   shutdown_id = 
     GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (2), &do_shutdown, NULL);
 }
index aa410e01097954039be34983afc019a7c2c18328..3a42e87a8a145579da148861669d8fd9b7d66edf 100644 (file)
@@ -426,22 +426,73 @@ GNUNET_TESTBED_queue_message (struct GNUNET_TESTBED_Controller *controller,
 struct GNUNET_TESTBED_ControllerProc
 {
   /**
-   * The helper handle
+   * The process handle
    */
-  struct GNUNET_TESTBED_HelperHandle *helper;
+  struct GNUNET_HELPER_Handle *helper;
 
   /**
    * The controller error callback
    */
-  GNUNET_TESTBED_ControllerErrorCallback cec;
+  GNUNET_TESTBED_ControllerStatusCallback cb;
 
   /**
    * The closure for the above callback
    */
-  void *cec_cls;
+  void *cls;
+
+  /**
+   * The send handle for the helper
+   */
+  struct GNUNET_HELPER_SendHandle *shandle;
+
+  /**
+   * The port number for ssh; used for helpers starting ssh
+   */
+  char *port;
+
+  /**
+   * The ssh destination string; used for helpers starting ssh
+   */
+  char *dst;
+
 };
 
 
+/**
+ * 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)
+{
+  GNUNET_break (0);
+  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)
+{
+  GNUNET_free (cls);
+}
+
+
 /**
  * Callback that will be called when the helper process dies. This is not called
  * when the helper process is stoped using GNUNET_HELPER_stop()
@@ -449,53 +500,105 @@ struct GNUNET_TESTBED_ControllerProc
  * @param cls the closure from GNUNET_HELPER_start()
  */
 static void 
-controller_exp_cb (void *cls)
+helper_exp_cb (void *cls)
 {
-  struct GNUNET_TESTBED_ControllerProc *cproc = cls;
-
-  if (NULL != cproc->cec)
-    cproc->cec (cproc->cec_cls, NULL); /* FIXME: How to get the error message? */
+  struct GNUNET_TESTBED_ControllerProc *cp = cls;
+  GNUNET_TESTBED_ControllerStatusCallback cb;
+  void *cb_cls;
+
+  cb = cp->cb;
+  cb_cls = cp->cls;
+  GNUNET_TESTBED_controller_stop (cp);
+  if (NULL != cb)
+    cb (cb_cls, NULL, GNUNET_SYSERR);
 }
 
 
 /**
- * Starts a controller process at the host
+ * 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 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 cec function called if the contoller dies unexpectedly; will not be 
- *            invoked after GNUNET_TESTBED_controller_stop, if 'cec' was called,
- *            GNUNET_TESTBED_controller_stop must no longer be called; will
- *            never be called in the same task as 'GNUNET_TESTBED_controller_start'
- *            (synchronous errors will be signalled by returning NULL)
- * @param cec_cls closure for 'cec'
+ * @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)
+ * @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_ControllerErrorCallback cec,
-                                void *cec_cls)
+                                 GNUNET_TESTBED_ControllerStatusCallback cb,
+                                void *cls)
 {
-  struct GNUNET_TESTBED_ControllerProc *cproc;
+  struct GNUNET_TESTBED_ControllerProc *cp;
+  struct GNUNET_TESTBED_HelperInit *msg;
   
-  cproc = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ControllerProc));
-  cproc->helper = GNUNET_TESTBED_host_run_ (controller_ip, host, cfg,
-                                           &controller_exp_cb, cproc);
-  if (NULL == cproc->helper)
+  cp = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ControllerProc));
+  if ((NULL == host) || (0 == GNUNET_TESTBED_host_get_id_ (host)))
+  {
+    char * const binary_argv[] = {
+      "gnunet-testbed-helper", NULL
+    };
+
+    cp->helper = GNUNET_HELPER_start ("gnunet-testbed-helper", binary_argv, 
+                                      &helper_mst, &helper_exp_cb, cp);
+  }
+  else
+  {
+    char *remote_args[6 + 1];
+    unsigned int argp;
+    const char *username;
+    const char *hostname;
+
+    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, "%s@%s", hostname, username);
+    argp = 0;
+    remote_args[argp++] = "ssh";
+    remote_args[argp++] = "-p";
+    remote_args[argp++] = cp->port;
+    remote_args[argp++] = "-q";
+    remote_args[argp++] = cp->dst;
+    remote_args[argp++] = "gnunet-testbed-helper";
+    remote_args[argp++] = NULL;
+    GNUNET_assert (argp == 6 + 1);
+    cp->helper = GNUNET_HELPER_start ("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->cb = cb;
+  cp->cls = cls;
+  msg = GNUNET_TESTBED_create_helper_init_msg_ (controller_ip, cfg);
+  cp->shandle = GNUNET_HELPER_send (cp->helper, &msg->header, GNUNET_NO,
+                                    &clear_msg, msg);
+  if (NULL == cp->shandle)
   {
-    GNUNET_free (cproc);
+    GNUNET_free (msg);
+    GNUNET_TESTBED_controller_stop (cp);
     return NULL;
   }
-  cproc->cec = cec;
-  cproc->cec_cls = cec_cls;
-  return cproc;
+  return cp;
 }
 
 
@@ -507,10 +610,14 @@ GNUNET_TESTBED_controller_start (const char *controller_ip,
  * @param cproc the controller process handle
  */
 void
-GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cproc)
+GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cp)
 {
-  GNUNET_TESTBED_host_stop_ (cproc->helper);
-  GNUNET_free (cproc);
+  if (NULL != cp->shandle)
+    GNUNET_HELPER_send_cancel (cp->shandle);
+  GNUNET_HELPER_stop (cp->helper);
+  GNUNET_free_non_null (cp->port);
+  GNUNET_free_non_null (cp->dst);
+  GNUNET_free (cp);
 }
 
 
index f88da52b87d21d93303b93a9792f3ed5a5159908..dd08d3a5069e85f3d76e15a0ad08d656a2ee7426 100644 (file)
@@ -337,133 +337,6 @@ GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host)
 }
 
 
-/**
- * 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)
-{
-  GNUNET_free (cls);
-}
-
-
-/**
- * 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_HelperHandle *handle = cls;
-
-  handle->is_stopped = GNUNET_YES;
-  GNUNET_TESTBED_host_stop_ (handle);
-  handle->exp_cb (handle->exp_cb_cls);
-}
-
-
-/**
- * Run a given helper process at the given host.  Communication
- * with the helper will be via GNUnet messages on stdin/stdout.
- * Runs the process via 'ssh' at the specified host, or locally.
- * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API.
- * 
- * @param controller_ip the ip address of the controller. Will be set as TRUSTED
- *          host when starting testbed controller at host
- * @param host host to use, use "NULL" for localhost
- * @param binary_argv binary name and command-line arguments to give to the
- *          binary
- * @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 the callback to run when helper process dies; cannot be NULL
- * @param cb_cls the closure for the above callback
- * @return handle to terminate the command, NULL on error
- */
-struct GNUNET_TESTBED_HelperHandle *
-GNUNET_TESTBED_host_run_ (const char *controller_ip,
-                         const struct GNUNET_TESTBED_Host *host,
-                         const struct GNUNET_CONFIGURATION_Handle *cfg,
-                         GNUNET_HELPER_ExceptionCallback cb,
-                         void *cb_cls)
-{
-  struct GNUNET_TESTBED_HelperHandle *h;  
-  struct GNUNET_TESTBED_HelperInit *msg;
-
-  GNUNET_assert (NULL != cb);
-  h = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HelperHandle));
-  h->exp_cb = cb;
-  h->exp_cb_cls = cb_cls;
-  h->is_stopped = GNUNET_NO;
-  if ((NULL == host) || (0 == host->id))
-  {
-    char * const binary_argv[] = {
-      "gnunet-testbed-helper", NULL
-    };
-
-    h->helper =
-      GNUNET_HELPER_start ("gnunet-testbed-helper", binary_argv, NULL, &helper_exp_cb, h);
-  }
-  else
-  {
-    char *remote_args[6 + 1];
-    unsigned int argp;
-
-    GNUNET_asprintf (&h->port, "%d", host->port);
-    if (NULL == host->username)
-      GNUNET_asprintf (&h->dst, "%s", host->hostname);
-    else 
-      GNUNET_asprintf (&h->dst, "%s@%s", host->hostname, host->username);
-    argp = 0;
-    remote_args[argp++] = "ssh";
-    remote_args[argp++] = "-p";
-    remote_args[argp++] = h->port;
-    remote_args[argp++] = "-q";
-    remote_args[argp++] = h->dst;
-    remote_args[argp++] = "gnunet-testbed-helper";
-    remote_args[argp++] = NULL;
-    GNUNET_assert (argp == 6 + 1);
-    h->helper = GNUNET_HELPER_start ("ssh", remote_args, NULL, &helper_exp_cb, h);
-  }
-  msg = GNUNET_TESTBED_create_helper_init_msg_ (controller_ip, cfg);
-  if ((NULL == h->helper) ||
-      (NULL == (h->helper_shandle = GNUNET_HELPER_send (h->helper, &msg->header, GNUNET_NO, 
-                                                       &clear_msg, msg))))
-  {
-    GNUNET_free (msg);
-    GNUNET_free_non_null (h->port);
-    GNUNET_free_non_null (h->dst);
-    GNUNET_free (h);
-    return NULL;
-  } 
-  return h;
-}
-
-
-/**
- * Stops a helper in the HelperHandle using GNUNET_HELPER_stop
- *
- * @param handle the handle returned from GNUNET_TESTBED_host_start_
- */
-void
-GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle)
-{
-  if (GNUNET_YES != handle->is_stopped)
-    GNUNET_HELPER_stop (handle->helper);
-  GNUNET_free_non_null (handle->port);
-  GNUNET_free_non_null (handle->dst);
-  GNUNET_free (handle);
-}
-
-
 /**
  * Marks a host as registered with a controller
  *
index 21e9520e20aed3d4da5fd4a8d2e0de0d674e4fc0..2c89e29acedeb1240c874fb37459bb9b38726f5e 100644 (file)
 #include "testbed_helper.h"
 
 
-/**
- * Wrapper around
- */
-struct GNUNET_TESTBED_HelperHandle
-{
-  /**
-   * The process handle
-   */
-  struct GNUNET_HELPER_Handle *helper;
-
-  /**
-   * The send handle for the helper
-   */
-  struct GNUNET_HELPER_SendHandle *helper_shandle;
-
-  /**
-   * The port number for ssh; used for helpers starting ssh
-   */
-  char *port;
-
-  /**
-   * The ssh destination string; used for helpers starting ssh
-   */
-  char *dst;
-
-  /**
-   * The helper exception callback
-   */
-  GNUNET_HELPER_ExceptionCallback exp_cb;
-
-  /**
-   * The closure for exp_cb
-   */
-  void *exp_cb_cls;
-
-  /**
-   * Is the helper stopped?
-   */
-  int is_stopped;
-};
-
-
 /**
  * Lookup a host by ID.
  * 
@@ -144,40 +102,41 @@ GNUNET_TESTBED_host_get_ssh_port_ (const struct GNUNET_TESTBED_Host *host);
 struct GNUNET_TESTBED_HelperHandle;
 
 
-/**
- * Run a given helper process at the given host.  Communication
- * with the helper will be via GNUnet messages on stdin/stdout.
- * Runs the process via 'ssh' at the specified host, or locally.
- * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API.
- * 
- * @param controller_ip the ip address of the controller. Will be set as TRUSTED
- *          host when starting testbed controller at host
- * @param host host to use, use "NULL" for localhost
- * @param binary_argv binary name and command-line arguments to give to the
- *          binary
- * @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 the callback to run when helper process dies; cannot be NULL
- * @param cb_cls the closure for the above callback
- * @return handle to terminate the command, NULL on error
- */
-struct GNUNET_TESTBED_HelperHandle *
-GNUNET_TESTBED_host_run_ (const char *controller_ip,
-                         const struct GNUNET_TESTBED_Host *host,
-                         const struct GNUNET_CONFIGURATION_Handle *cfg,
-                         GNUNET_HELPER_ExceptionCallback cb,
-                         void *cb_cls);
-
-
-/**
- * Stops a helper in the HelperHandle using GNUNET_HELPER_stop
- *
- * @param handle the handle returned from GNUNET_TESTBED_host_start_
- */
-void
-GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle);
+/* /\** */
+/*  * Run a given helper process at the given host.  Communication */
+/*  * with the helper will be via GNUnet messages on stdin/stdout. */
+/*  * Runs the process via 'ssh' at the specified host, or locally. */
+/*  * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API. */
+/*  *  */
+/*  * @param controller_ip the ip address of the controller. Will be set as TRUSTED */
+/*  *          host when starting testbed controller at host */
+/*  * @param host host to use, use "NULL" for localhost */
+/*  * @param binary_argv binary name and command-line arguments to give to the */
+/*  *          binary */
+/*  * @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 the callback to run when helper process dies; cannot be NULL */
+/*  * @param cb_cls the closure for the above callback */
+/*  * @return handle to terminate the command, NULL on error */
+/*  *\/ */
+/* struct GNUNET_TESTBED_HelperHandle * */
+/* GNUNET_TESTBED_host_run_ (const char *controller_ip, */
+/*                       const struct GNUNET_TESTBED_Host *host, */
+/*                       const struct GNUNET_CONFIGURATION_Handle *cfg, */
+/*                       GNUNET_HELPER_ExceptionCallback cb, */
+/*                       void *cb_cls); */
+
+
+
+/* /\** */
+/*  * Stops a helper in the HelperHandle using GNUNET_HELPER_stop */
+/*  * */
+/*  * @param handle the handle returned from GNUNET_TESTBED_host_start_ */
+/*  *\/ */
+/* void */
+/* GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle); */
 
 
 /**
index 8780d7e98c582fb6ba76272abf1adb8febeca843..8b3c84ddee08c15bf497126282231421bb45515c 100644 (file)
@@ -52,7 +52,26 @@ struct GNUNET_TESTBED_HelperInit
   /* Followed by NULL terminated controller hostname */
   
   /* Followed by serialized and compressed configuration which should be
-     config_size long */
+     config_size long when un-compressed */
+};
+
+/**
+ * Reply message from helper process
+ */
+struct GNUNET_TESTBED_HelperReply
+{
+  /**
+   * Type is GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * Size of the uncompressed configuration
+   */
+  uint16_t config_size GNUNET_PACKED;
+
+  /* Followed by compressed configuration which should be config_size long when
+     un-compressed */
 };
 
 #endif