aboutsummaryrefslogtreecommitdiff
path: root/src/testbed
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2012-07-17 22:25:44 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2012-07-17 22:25:44 +0000
commit253d546750130fc4471a7c53355b6f5d58326fc3 (patch)
treeb7c567693f7a4c2e47782d3b05538d8586942dd4 /src/testbed
parent89daff335a418fb67ce8ea4d3e1e128e96d19877 (diff)
downloadgnunet-253d546750130fc4471a7c53355b6f5d58326fc3.tar.gz
gnunet-253d546750130fc4471a7c53355b6f5d58326fc3.zip
helper reply with modified config
Diffstat (limited to 'src/testbed')
-rw-r--r--src/testbed/Makefile.am3
-rw-r--r--src/testbed/gnunet-service-testbed.c71
-rw-r--r--src/testbed/gnunet-testbed-helper.c114
-rw-r--r--src/testbed/test_testbed_api_hosts.c23
-rw-r--r--src/testbed/testbed_api.c169
-rw-r--r--src/testbed/testbed_api_hosts.c127
-rw-r--r--src/testbed/testbed_api_hosts.h111
-rw-r--r--src/testbed/testbed_helper.h21
8 files changed, 349 insertions, 290 deletions
diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am
index 80e6b9e3d..f5fbbe21d 100644
--- a/src/testbed/Makefile.am
+++ b/src/testbed/Makefile.am
@@ -33,6 +33,7 @@ gnunet_testbed_helper_SOURCES = \
33gnunet_testbed_helper_LDADD = $(XLIB) \ 33gnunet_testbed_helper_LDADD = $(XLIB) \
34 $(top_builddir)/src/util/libgnunetutil.la \ 34 $(top_builddir)/src/util/libgnunetutil.la \
35 $(top_builddir)/src/testing/libgnunettesting.la \ 35 $(top_builddir)/src/testing/libgnunettesting.la \
36 libgnunettestbed.la \
36 $(LTLIBINTL) -lz 37 $(LTLIBINTL) -lz
37gnunet_testbed_helper_DEPENDENCIES = \ 38gnunet_testbed_helper_DEPENDENCIES = \
38 gnunet-service-testbed.$(OBJEXT) 39 gnunet-service-testbed.$(OBJEXT)
@@ -70,7 +71,7 @@ check_PROGRAMS = \
70if ENABLE_TEST_RUN 71if ENABLE_TEST_RUN
71 TESTS = \ 72 TESTS = \
72 test_testbed_api_hosts \ 73 test_testbed_api_hosts \
73 test_gnunet_testbed_helper 74 #test_gnunet_testbed_helper
74endif 75endif
75 76
76test_testbed_api_hosts_SOURCES = \ 77test_testbed_api_hosts_SOURCES = \
diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c
index 3908af14a..6aafd1b60 100644
--- a/src/testbed/gnunet-service-testbed.c
+++ b/src/testbed/gnunet-service-testbed.c
@@ -167,6 +167,23 @@ struct Slave
167 167
168 168
169/** 169/**
170 * Slave startup context
171 */
172struct SlaveContext
173{
174 /**
175 * The slave corresponding to this context
176 */
177 struct Slave *slave;
178
179 /**
180 * The configuration used as a template while startup
181 */
182 struct GNUNET_CONFIGURATION_Handle *cfg;
183};
184
185
186/**
170 * States of LCFContext 187 * States of LCFContext
171 */ 188 */
172enum LCFContextState 189enum LCFContextState
@@ -703,24 +720,35 @@ slave_event_callback(void *cls,
703 720
704 721
705/** 722/**
706 * Callback for unexpected slave shutdowns 723 * Callback to signal successfull startup of the controller process
707 * 724 *
708 * @param cls closure 725 * @param cls the closure from GNUNET_TESTBED_controller_start()
709 * @param emsg error message if available; can be NULL, which does NOT mean 726 * @param cfg the configuration with which the controller has been started;
710 * that there was no error 727 * NULL if status is not GNUNET_OK
728 * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
729 * GNUNET_TESTBED_controller_stop() shouldn't be called in this case
711 */ 730 */
712static void 731static void
713slave_shutdown_handler (void *cls, const char *emsg) 732slave_status_callback (void *cls,
733 const struct GNUNET_CONFIGURATION_Handle *cfg,
734 int status)
714{ 735{
715 struct Slave *slave; 736 struct SlaveContext *sc = cls;
716 737
717 slave = (struct Slave *) cls; 738 if (GNUNET_SYSERR == status)
718 slave->controller_proc = NULL; 739 {
719 LOG (GNUNET_ERROR_TYPE_WARNING, 740 sc->slave->controller_proc = NULL;
720 "Unexpected slave shutdown\n"); 741 LOG (GNUNET_ERROR_TYPE_WARNING,
721 if (NULL != emsg) 742 "Unexpected slave shutdown\n");
722 LOG (GNUNET_ERROR_TYPE_WARNING, "Error: %s\n", emsg); 743 GNUNET_SCHEDULER_shutdown (); /* We too shutdown */
723 GNUNET_SCHEDULER_shutdown (); /* We too shutdown */ 744 return;
745 }
746 GNUNET_CONFIGURATION_destroy (sc->cfg);
747 sc->slave->controller =
748 GNUNET_TESTBED_controller_connect (cfg, host_list[sc->slave->host_id],
749 master_context->event_mask,
750 &slave_event_callback, sc->slave);
751 GNUNET_free (sc);
724} 752}
725 753
726 754
@@ -950,6 +978,7 @@ handle_link_controllers (void *cls,
950{ 978{
951 const struct GNUNET_TESTBED_ControllerLinkMessage *msg; 979 const struct GNUNET_TESTBED_ControllerLinkMessage *msg;
952 struct GNUNET_CONFIGURATION_Handle *cfg; 980 struct GNUNET_CONFIGURATION_Handle *cfg;
981 struct SlaveContext *sc;
953 struct LCFContextQueue *lcfq; 982 struct LCFContextQueue *lcfq;
954 struct Route *route; 983 struct Route *route;
955 struct Route *new_route; 984 struct Route *new_route;
@@ -1053,19 +1082,17 @@ handle_link_controllers (void *cls,
1053 slave = GNUNET_malloc (sizeof (struct Slave)); 1082 slave = GNUNET_malloc (sizeof (struct Slave));
1054 slave->host_id = delegated_host_id; 1083 slave->host_id = delegated_host_id;
1055 slave_list_add (slave); 1084 slave_list_add (slave);
1085 sc = GNUNET_malloc (sizeof (struct SlaveContext));
1086 sc->slave = slave;
1087 sc->cfg = cfg;
1056 if (1 == msg->is_subordinate) 1088 if (1 == msg->is_subordinate)
1057 { 1089 {
1058 slave->controller_proc = 1090 slave->controller_proc =
1059 GNUNET_TESTBED_controller_start (master_context->master_ip, 1091 GNUNET_TESTBED_controller_start (master_context->master_ip,
1060 host_list[delegated_host_id], 1092 host_list[slave->host_id],
1061 cfg, &slave_shutdown_handler, 1093 cfg, &slave_status_callback,
1062 slave); 1094 sc);
1063 } 1095 }
1064 slave->controller =
1065 GNUNET_TESTBED_controller_connect (cfg, host_list[delegated_host_id],
1066 master_context->event_mask,
1067 &slave_event_callback, slave);
1068 GNUNET_CONFIGURATION_destroy (cfg);
1069 new_route = GNUNET_malloc (sizeof (struct Route)); 1096 new_route = GNUNET_malloc (sizeof (struct Route));
1070 new_route->dest = delegated_host_id; 1097 new_route->dest = delegated_host_id;
1071 new_route->thru = master_context->host_id; 1098 new_route->thru = master_context->host_id;
diff --git a/src/testbed/gnunet-testbed-helper.c b/src/testbed/gnunet-testbed-helper.c
index 4c202193b..23dfeddc2 100644
--- a/src/testbed/gnunet-testbed-helper.c
+++ b/src/testbed/gnunet-testbed-helper.c
@@ -33,7 +33,9 @@
33#include "platform.h" 33#include "platform.h"
34#include "gnunet_util_lib.h" 34#include "gnunet_util_lib.h"
35#include "gnunet_testing_lib-new.h" 35#include "gnunet_testing_lib-new.h"
36#include "gnunet_testbed_service.h"
36#include "testbed_helper.h" 37#include "testbed_helper.h"
38#include "testbed_api.h"
37#include <zlib.h> 39#include <zlib.h>
38 40
39/** 41/**
@@ -48,6 +50,29 @@
48#define LOG_DEBUG(...) \ 50#define LOG_DEBUG(...) \
49 LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) 51 LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
50 52
53
54/**
55 * Context for a single write on a chunk of memory
56 */
57struct WriteContext
58{
59 /**
60 * The data to write
61 */
62 void *data;
63
64 /**
65 * The length of the data
66 */
67 size_t length;
68
69 /**
70 * The current position from where the write operation should begin
71 */
72 size_t pos;
73};
74
75
51/** 76/**
52 * Handle to the testing system 77 * Handle to the testing system
53 */ 78 */
@@ -64,6 +89,11 @@ struct GNUNET_SERVER_MessageStreamTokenizer *tokenizer;
64static struct GNUNET_DISK_FileHandle *stdin_fd; 89static struct GNUNET_DISK_FileHandle *stdin_fd;
65 90
66/** 91/**
92 * Disk handle for stdout
93 */
94static struct GNUNET_DISK_FileHandle *stdout_fd;
95
96/**
67 * The process handle to the testbed service 97 * The process handle to the testbed service
68 */ 98 */
69static struct GNUNET_OS_Process *testbed; 99static struct GNUNET_OS_Process *testbed;
@@ -84,6 +114,11 @@ static struct GNUNET_DISK_PipeHandle *pipe_out;
84static GNUNET_SCHEDULER_TaskIdentifier read_task_id; 114static GNUNET_SCHEDULER_TaskIdentifier read_task_id;
85 115
86/** 116/**
117 * Task identifier for the write task
118 */
119static GNUNET_SCHEDULER_TaskIdentifier write_task_id;
120
121/**
87 * Are we done reading messages from stdin? 122 * Are we done reading messages from stdin?
88 */ 123 */
89static int done_reading; 124static int done_reading;
@@ -109,7 +144,15 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
109 GNUNET_SCHEDULER_cancel (read_task_id); 144 GNUNET_SCHEDULER_cancel (read_task_id);
110 read_task_id = GNUNET_SCHEDULER_NO_TASK; 145 read_task_id = GNUNET_SCHEDULER_NO_TASK;
111 } 146 }
112 (void) GNUNET_DISK_file_close (stdin_fd); 147 if (GNUNET_SCHEDULER_NO_TASK != write_task_id)
148 {
149 GNUNET_SCHEDULER_cancel (write_task_id);
150 write_task_id = GNUNET_SCHEDULER_NO_TASK;
151 }
152 if (NULL != stdin_fd)
153 (void) GNUNET_DISK_file_close (stdin_fd);
154 if (NULL != stdout_fd)
155 (void) GNUNET_DISK_file_close (stdin_fd);
113 GNUNET_SERVER_mst_destroy (tokenizer); 156 GNUNET_SERVER_mst_destroy (tokenizer);
114 tokenizer = NULL; 157 tokenizer = NULL;
115 if (NULL != testbed) 158 if (NULL != testbed)
@@ -138,6 +181,41 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
138 181
139 182
140/** 183/**
184 * Task to write to the standard out
185 *
186 * @param
187 * @return
188 */
189static void
190write_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
191{
192 struct WriteContext *wc = cls;
193 ssize_t bytes_wrote;
194
195 GNUNET_assert (NULL != wc);
196 write_task_id = GNUNET_SCHEDULER_NO_TASK;
197 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
198 {
199 GNUNET_free (wc->data);
200 GNUNET_free (wc);
201 return;
202 }
203 bytes_wrote = GNUNET_DISK_file_write (stdout_fd, wc->data + wc->pos,
204 wc->length - wc->pos);
205 GNUNET_assert (GNUNET_SYSERR != bytes_wrote);
206 wc->pos += bytes_wrote;
207 if (wc->pos == wc->length)
208 {
209 GNUNET_free (wc->data);
210 GNUNET_free (wc);
211 return;
212 }
213 write_task_id = GNUNET_SCHEDULER_add_write_file
214 (GNUNET_TIME_UNIT_FOREVER_REL, stdout_fd, &write_task, wc);
215}
216
217
218/**
141 * Functions with this signature are called whenever a 219 * Functions with this signature are called whenever a
142 * complete message is received by the tokenizer. 220 * complete message is received by the tokenizer.
143 * 221 *
@@ -154,11 +232,15 @@ tokenizer_cb (void *cls, void *client,
154 const struct GNUNET_MessageHeader *message) 232 const struct GNUNET_MessageHeader *message)
155{ 233{
156 const struct GNUNET_TESTBED_HelperInit *msg; 234 const struct GNUNET_TESTBED_HelperInit *msg;
235 struct GNUNET_TESTBED_HelperReply *reply;
157 struct GNUNET_CONFIGURATION_Handle *cfg; 236 struct GNUNET_CONFIGURATION_Handle *cfg;
237 struct WriteContext *wc;
158 char *controller; 238 char *controller;
159 char *config; 239 char *config;
160 uLongf config_size; 240 char *xconfig;
161 uint16_t xconfig_size; 241 size_t config_size;
242 uLongf ul_config_size;
243 size_t xconfig_size;
162 uint16_t cname_size; 244 uint16_t cname_size;
163 245
164 if ((sizeof (struct GNUNET_TESTBED_HelperInit) >= ntohs (message->size)) || 246 if ((sizeof (struct GNUNET_TESTBED_HelperInit) >= ntohs (message->size)) ||
@@ -177,10 +259,11 @@ tokenizer_cb (void *cls, void *client,
177 "Controller name cannot be empty -- exiting\n"); 259 "Controller name cannot be empty -- exiting\n");
178 goto error; 260 goto error;
179 } 261 }
180 config_size = (uLongf) ntohs (msg->config_size); 262 ul_config_size = (uLongf) ntohs (msg->config_size);
181 config = GNUNET_malloc (config_size); 263 config = GNUNET_malloc (ul_config_size);
182 xconfig_size = ntohs (message->size) - (cname_size + 1); 264 xconfig_size = ntohs (message->size) -
183 if (Z_OK != uncompress ((Bytef *) config, &config_size, 265 (cname_size + 1 + sizeof (struct GNUNET_TESTBED_HelperInit));
266 if (Z_OK != uncompress ((Bytef *) config, &ul_config_size,
184 (const Bytef *) (controller + cname_size + 1), 267 (const Bytef *) (controller + cname_size + 1),
185 (uLongf) xconfig_size)) 268 (uLongf) xconfig_size))
186 { 269 {
@@ -190,8 +273,8 @@ tokenizer_cb (void *cls, void *client,
190 goto error; 273 goto error;
191 } 274 }
192 cfg = GNUNET_CONFIGURATION_create (); 275 cfg = GNUNET_CONFIGURATION_create ();
193 if (GNUNET_OK != GNUNET_CONFIGURATION_deserialize (cfg, config, config_size, 276 if (GNUNET_OK != GNUNET_CONFIGURATION_deserialize (cfg, config,
194 GNUNET_NO)) 277 ul_config_size, GNUNET_NO))
195 { 278 {
196 LOG (GNUNET_ERROR_TYPE_WARNING, 279 LOG (GNUNET_ERROR_TYPE_WARNING,
197 "Unable to deserialize config -- exiting\n"); 280 "Unable to deserialize config -- exiting\n");
@@ -234,6 +317,18 @@ tokenizer_cb (void *cls, void *client,
234 GNUNET_DISK_pipe_close_end (pipe_out, GNUNET_DISK_PIPE_END_WRITE); 317 GNUNET_DISK_pipe_close_end (pipe_out, GNUNET_DISK_PIPE_END_WRITE);
235 GNUNET_DISK_pipe_close_end (pipe_in, GNUNET_DISK_PIPE_END_READ); 318 GNUNET_DISK_pipe_close_end (pipe_in, GNUNET_DISK_PIPE_END_READ);
236 done_reading = GNUNET_YES; 319 done_reading = GNUNET_YES;
320 config = GNUNET_CONFIGURATION_serialize (cfg, &config_size);
321 xconfig_size = GNUNET_TESTBED_compress_config (config, config_size, &xconfig);
322 wc = GNUNET_malloc (sizeof (struct WriteContext));
323 wc->length = xconfig_size + sizeof (struct GNUNET_TESTBED_HelperReply);
324 reply = GNUNET_realloc (xconfig, wc->length);
325 memmove (&reply[1], reply, xconfig_size);
326 reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY);
327 reply->header.size = htons ((uint16_t) wc->length);
328 reply->config_size = htons ((uint16_t) config_size);
329 wc->data = reply;
330 write_task_id = GNUNET_SCHEDULER_add_write_file
331 (GNUNET_TIME_UNIT_FOREVER_REL, stdout_fd, &write_task, wc);
237 return GNUNET_OK; 332 return GNUNET_OK;
238 333
239 error: 334 error:
@@ -302,6 +397,7 @@ run (void *cls, char *const *args, const char *cfgfile,
302 LOG_DEBUG ("Starting testbed helper...\n"); 397 LOG_DEBUG ("Starting testbed helper...\n");
303 tokenizer = GNUNET_SERVER_mst_create (&tokenizer_cb, NULL); 398 tokenizer = GNUNET_SERVER_mst_create (&tokenizer_cb, NULL);
304 stdin_fd = GNUNET_DISK_get_handle_from_native (stdin); 399 stdin_fd = GNUNET_DISK_get_handle_from_native (stdin);
400 stdout_fd = GNUNET_DISK_get_handle_from_native (stdout);
305 read_task_id = 401 read_task_id =
306 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 402 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
307 stdin_fd, &read_task, NULL); 403 stdin_fd, &read_task, NULL);
diff --git a/src/testbed/test_testbed_api_hosts.c b/src/testbed/test_testbed_api_hosts.c
index 54e2461c7..ae71abc54 100644
--- a/src/testbed/test_testbed_api_hosts.c
+++ b/src/testbed/test_testbed_api_hosts.c
@@ -39,11 +39,6 @@
39static struct GNUNET_TESTBED_Host *host; 39static struct GNUNET_TESTBED_Host *host;
40 40
41/** 41/**
42 * The host helper handle
43 */
44static struct GNUNET_TESTBED_HelperHandle *helper_handle;
45
46/**
47 * Global test status 42 * Global test status
48 */ 43 */
49static int status; 44static int status;
@@ -62,27 +57,11 @@ GNUNET_SCHEDULER_TaskIdentifier shutdown_id;
62static void 57static void
63do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 58do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
64{ 59{
65 GNUNET_TESTBED_host_stop_ (helper_handle);
66 GNUNET_TESTBED_host_destroy (host); 60 GNUNET_TESTBED_host_destroy (host);
67} 61}
68 62
69 63
70/** 64/**
71 * Callback that will be called when the helper process dies. This is not called
72 * when the helper process is stoped using GNUNET_HELPER_stop()
73 *
74 * @param cls the closure from GNUNET_HELPER_start()
75 */
76static void
77exp_cb (void *cls)
78{
79 status = GNUNET_SYSERR;
80 GNUNET_SCHEDULER_cancel (shutdown_id);
81 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
82}
83
84
85/**
86 * Main run function. 65 * Main run function.
87 * 66 *
88 * @param cls NULL 67 * @param cls NULL
@@ -102,8 +81,6 @@ run (void *cls, char *const *args, const char *cfgfile,
102 GNUNET_assert (NULL != host); 81 GNUNET_assert (NULL != host);
103 GNUNET_assert (0 == GNUNET_TESTBED_host_get_id_ (host)); 82 GNUNET_assert (0 == GNUNET_TESTBED_host_get_id_ (host));
104 GNUNET_assert (host == GNUNET_TESTBED_host_lookup_by_id_ (0)); 83 GNUNET_assert (host == GNUNET_TESTBED_host_lookup_by_id_ (0));
105 helper_handle = GNUNET_TESTBED_host_run_ ("127.0.0.1", host, cfg, &exp_cb, NULL);
106 GNUNET_assert (NULL != helper_handle);
107 shutdown_id = 84 shutdown_id =
108 GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (2), &do_shutdown, NULL); 85 GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (2), &do_shutdown, NULL);
109} 86}
diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c
index aa410e010..3a42e87a8 100644
--- a/src/testbed/testbed_api.c
+++ b/src/testbed/testbed_api.c
@@ -426,76 +426,179 @@ GNUNET_TESTBED_queue_message (struct GNUNET_TESTBED_Controller *controller,
426struct GNUNET_TESTBED_ControllerProc 426struct GNUNET_TESTBED_ControllerProc
427{ 427{
428 /** 428 /**
429 * The helper handle 429 * The process handle
430 */ 430 */
431 struct GNUNET_TESTBED_HelperHandle *helper; 431 struct GNUNET_HELPER_Handle *helper;
432 432
433 /** 433 /**
434 * The controller error callback 434 * The controller error callback
435 */ 435 */
436 GNUNET_TESTBED_ControllerErrorCallback cec; 436 GNUNET_TESTBED_ControllerStatusCallback cb;
437 437
438 /** 438 /**
439 * The closure for the above callback 439 * The closure for the above callback
440 */ 440 */
441 void *cec_cls; 441 void *cls;
442
443 /**
444 * The send handle for the helper
445 */
446 struct GNUNET_HELPER_SendHandle *shandle;
447
448 /**
449 * The port number for ssh; used for helpers starting ssh
450 */
451 char *port;
452
453 /**
454 * The ssh destination string; used for helpers starting ssh
455 */
456 char *dst;
457
442}; 458};
443 459
444 460
445/** 461/**
462 * Functions with this signature are called whenever a
463 * complete message is received by the tokenizer.
464 *
465 * Do not call GNUNET_SERVER_mst_destroy in callback
466 *
467 * @param cls closure
468 * @param client identification of the client
469 * @param message the actual message
470 *
471 * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
472 */
473static int helper_mst (void *cls, void *client,
474 const struct GNUNET_MessageHeader *message)
475{
476 GNUNET_break (0);
477 return GNUNET_OK;
478}
479
480
481/**
482 * Continuation function from GNUNET_HELPER_send()
483 *
484 * @param cls closure
485 * @param result GNUNET_OK on success,
486 * GNUNET_NO if helper process died
487 * GNUNET_SYSERR during GNUNET_HELPER_stop
488 */
489static void
490clear_msg (void *cls, int result)
491{
492 GNUNET_free (cls);
493}
494
495
496/**
446 * Callback that will be called when the helper process dies. This is not called 497 * Callback that will be called when the helper process dies. This is not called
447 * when the helper process is stoped using GNUNET_HELPER_stop() 498 * when the helper process is stoped using GNUNET_HELPER_stop()
448 * 499 *
449 * @param cls the closure from GNUNET_HELPER_start() 500 * @param cls the closure from GNUNET_HELPER_start()
450 */ 501 */
451static void 502static void
452controller_exp_cb (void *cls) 503helper_exp_cb (void *cls)
453{ 504{
454 struct GNUNET_TESTBED_ControllerProc *cproc = cls; 505 struct GNUNET_TESTBED_ControllerProc *cp = cls;
455 506 GNUNET_TESTBED_ControllerStatusCallback cb;
456 if (NULL != cproc->cec) 507 void *cb_cls;
457 cproc->cec (cproc->cec_cls, NULL); /* FIXME: How to get the error message? */ 508
509 cb = cp->cb;
510 cb_cls = cp->cls;
511 GNUNET_TESTBED_controller_stop (cp);
512 if (NULL != cb)
513 cb (cb_cls, NULL, GNUNET_SYSERR);
458} 514}
459 515
460 516
461/** 517/**
462 * Starts a controller process at the host 518 * Starts a controller process at the host. FIXME: add controller start callback
519 * with the configuration with which the controller is started
463 * 520 *
464 * @param controller_ip the ip address of the controller. Will be set as TRUSTED 521 * @param controller_ip the ip address of the controller. Will be set as TRUSTED
465 * host when starting testbed controller at host 522 * host when starting testbed controller at host
466 * @param host the host where the controller has to be started; NULL for localhost 523 * @param host the host where the controller has to be started; NULL for
524 * localhost
467 * @param cfg template configuration to use for the remote controller; the 525 * @param cfg template configuration to use for the remote controller; the
468 * remote controller will be started with a slightly modified 526 * remote controller will be started with a slightly modified
469 * configuration (port numbers, unix domain sockets and service home 527 * configuration (port numbers, unix domain sockets and service home
470 * values are changed as per TESTING library on the remote host) 528 * values are changed as per TESTING library on the remote host)
471 * @param cec function called if the contoller dies unexpectedly; will not be 529 * @param cb function called when the controller is successfully started or
472 * invoked after GNUNET_TESTBED_controller_stop, if 'cec' was called, 530 * dies unexpectedly; GNUNET_TESTBED_controller_stop shouldn't be
473 * GNUNET_TESTBED_controller_stop must no longer be called; will 531 * called if cb is called with GNUNET_SYSERR as status. Will never be
474 * never be called in the same task as 'GNUNET_TESTBED_controller_start' 532 * called in the same task as 'GNUNET_TESTBED_controller_start'
475 * (synchronous errors will be signalled by returning NULL) 533 * (synchronous errors will be signalled by returning NULL)
476 * @param cec_cls closure for 'cec' 534 * @param cls closure for above callbacks
477 * @return the controller process handle, NULL on errors 535 * @return the controller process handle, NULL on errors
478 */ 536 */
479struct GNUNET_TESTBED_ControllerProc * 537struct GNUNET_TESTBED_ControllerProc *
480GNUNET_TESTBED_controller_start (const char *controller_ip, 538GNUNET_TESTBED_controller_start (const char *controller_ip,
481 struct GNUNET_TESTBED_Host *host, 539 struct GNUNET_TESTBED_Host *host,
482 const struct GNUNET_CONFIGURATION_Handle *cfg, 540 const struct GNUNET_CONFIGURATION_Handle *cfg,
483 GNUNET_TESTBED_ControllerErrorCallback cec, 541 GNUNET_TESTBED_ControllerStatusCallback cb,
484 void *cec_cls) 542 void *cls)
485{ 543{
486 struct GNUNET_TESTBED_ControllerProc *cproc; 544 struct GNUNET_TESTBED_ControllerProc *cp;
545 struct GNUNET_TESTBED_HelperInit *msg;
487 546
488 cproc = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ControllerProc)); 547 cp = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ControllerProc));
489 cproc->helper = GNUNET_TESTBED_host_run_ (controller_ip, host, cfg, 548 if ((NULL == host) || (0 == GNUNET_TESTBED_host_get_id_ (host)))
490 &controller_exp_cb, cproc); 549 {
491 if (NULL == cproc->helper) 550 char * const binary_argv[] = {
551 "gnunet-testbed-helper", NULL
552 };
553
554 cp->helper = GNUNET_HELPER_start ("gnunet-testbed-helper", binary_argv,
555 &helper_mst, &helper_exp_cb, cp);
556 }
557 else
558 {
559 char *remote_args[6 + 1];
560 unsigned int argp;
561 const char *username;
562 const char *hostname;
563
564 username = GNUNET_TESTBED_host_get_username_ (host);
565 hostname = GNUNET_TESTBED_host_get_hostname_ (host);
566 GNUNET_asprintf (&cp->port, "%u", GNUNET_TESTBED_host_get_ssh_port_ (host));
567 if (NULL == username)
568 GNUNET_asprintf (&cp->dst, "%s", hostname);
569 else
570 GNUNET_asprintf (&cp->dst, "%s@%s", hostname, username);
571 argp = 0;
572 remote_args[argp++] = "ssh";
573 remote_args[argp++] = "-p";
574 remote_args[argp++] = cp->port;
575 remote_args[argp++] = "-q";
576 remote_args[argp++] = cp->dst;
577 remote_args[argp++] = "gnunet-testbed-helper";
578 remote_args[argp++] = NULL;
579 GNUNET_assert (argp == 6 + 1);
580 cp->helper = GNUNET_HELPER_start ("ssh", remote_args,
581 &helper_mst, &helper_exp_cb, cp);
582 }
583 if (NULL == cp->helper)
584 {
585 GNUNET_free_non_null (cp->port);
586 GNUNET_free_non_null (cp->dst);
587 GNUNET_free (cp);
588 return NULL;
589 }
590 cp->cb = cb;
591 cp->cls = cls;
592 msg = GNUNET_TESTBED_create_helper_init_msg_ (controller_ip, cfg);
593 cp->shandle = GNUNET_HELPER_send (cp->helper, &msg->header, GNUNET_NO,
594 &clear_msg, msg);
595 if (NULL == cp->shandle)
492 { 596 {
493 GNUNET_free (cproc); 597 GNUNET_free (msg);
598 GNUNET_TESTBED_controller_stop (cp);
494 return NULL; 599 return NULL;
495 } 600 }
496 cproc->cec = cec; 601 return cp;
497 cproc->cec_cls = cec_cls;
498 return cproc;
499} 602}
500 603
501 604
@@ -507,10 +610,14 @@ GNUNET_TESTBED_controller_start (const char *controller_ip,
507 * @param cproc the controller process handle 610 * @param cproc the controller process handle
508 */ 611 */
509void 612void
510GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cproc) 613GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cp)
511{ 614{
512 GNUNET_TESTBED_host_stop_ (cproc->helper); 615 if (NULL != cp->shandle)
513 GNUNET_free (cproc); 616 GNUNET_HELPER_send_cancel (cp->shandle);
617 GNUNET_HELPER_stop (cp->helper);
618 GNUNET_free_non_null (cp->port);
619 GNUNET_free_non_null (cp->dst);
620 GNUNET_free (cp);
514} 621}
515 622
516 623
diff --git a/src/testbed/testbed_api_hosts.c b/src/testbed/testbed_api_hosts.c
index f88da52b8..dd08d3a50 100644
--- a/src/testbed/testbed_api_hosts.c
+++ b/src/testbed/testbed_api_hosts.c
@@ -338,133 +338,6 @@ GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host)
338 338
339 339
340/** 340/**
341 * Continuation function from GNUNET_HELPER_send()
342 *
343 * @param cls closure
344 * @param result GNUNET_OK on success,
345 * GNUNET_NO if helper process died
346 * GNUNET_SYSERR during GNUNET_HELPER_stop
347 */
348static void
349clear_msg (void *cls, int result)
350{
351 GNUNET_free (cls);
352}
353
354
355/**
356 * Callback that will be called when the helper process dies. This is not called
357 * when the helper process is stoped using GNUNET_HELPER_stop()
358 *
359 * @param cls the closure from GNUNET_HELPER_start()
360 */
361static void
362helper_exp_cb (void *cls)
363{
364 struct GNUNET_TESTBED_HelperHandle *handle = cls;
365
366 handle->is_stopped = GNUNET_YES;
367 GNUNET_TESTBED_host_stop_ (handle);
368 handle->exp_cb (handle->exp_cb_cls);
369}
370
371
372/**
373 * Run a given helper process at the given host. Communication
374 * with the helper will be via GNUnet messages on stdin/stdout.
375 * Runs the process via 'ssh' at the specified host, or locally.
376 * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API.
377 *
378 * @param controller_ip the ip address of the controller. Will be set as TRUSTED
379 * host when starting testbed controller at host
380 * @param host host to use, use "NULL" for localhost
381 * @param binary_argv binary name and command-line arguments to give to the
382 * binary
383 * @param cfg template configuration to use for the remote controller; the
384 * remote controller will be started with a slightly modified
385 * configuration (port numbers, unix domain sockets and service home
386 * values are changed as per TESTING library on the remote host)
387 * @param cb the callback to run when helper process dies; cannot be NULL
388 * @param cb_cls the closure for the above callback
389 * @return handle to terminate the command, NULL on error
390 */
391struct GNUNET_TESTBED_HelperHandle *
392GNUNET_TESTBED_host_run_ (const char *controller_ip,
393 const struct GNUNET_TESTBED_Host *host,
394 const struct GNUNET_CONFIGURATION_Handle *cfg,
395 GNUNET_HELPER_ExceptionCallback cb,
396 void *cb_cls)
397{
398 struct GNUNET_TESTBED_HelperHandle *h;
399 struct GNUNET_TESTBED_HelperInit *msg;
400
401 GNUNET_assert (NULL != cb);
402 h = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HelperHandle));
403 h->exp_cb = cb;
404 h->exp_cb_cls = cb_cls;
405 h->is_stopped = GNUNET_NO;
406 if ((NULL == host) || (0 == host->id))
407 {
408 char * const binary_argv[] = {
409 "gnunet-testbed-helper", NULL
410 };
411
412 h->helper =
413 GNUNET_HELPER_start ("gnunet-testbed-helper", binary_argv, NULL, &helper_exp_cb, h);
414 }
415 else
416 {
417 char *remote_args[6 + 1];
418 unsigned int argp;
419
420 GNUNET_asprintf (&h->port, "%d", host->port);
421 if (NULL == host->username)
422 GNUNET_asprintf (&h->dst, "%s", host->hostname);
423 else
424 GNUNET_asprintf (&h->dst, "%s@%s", host->hostname, host->username);
425 argp = 0;
426 remote_args[argp++] = "ssh";
427 remote_args[argp++] = "-p";
428 remote_args[argp++] = h->port;
429 remote_args[argp++] = "-q";
430 remote_args[argp++] = h->dst;
431 remote_args[argp++] = "gnunet-testbed-helper";
432 remote_args[argp++] = NULL;
433 GNUNET_assert (argp == 6 + 1);
434 h->helper = GNUNET_HELPER_start ("ssh", remote_args, NULL, &helper_exp_cb, h);
435 }
436 msg = GNUNET_TESTBED_create_helper_init_msg_ (controller_ip, cfg);
437 if ((NULL == h->helper) ||
438 (NULL == (h->helper_shandle = GNUNET_HELPER_send (h->helper, &msg->header, GNUNET_NO,
439 &clear_msg, msg))))
440 {
441 GNUNET_free (msg);
442 GNUNET_free_non_null (h->port);
443 GNUNET_free_non_null (h->dst);
444 GNUNET_free (h);
445 return NULL;
446 }
447 return h;
448}
449
450
451/**
452 * Stops a helper in the HelperHandle using GNUNET_HELPER_stop
453 *
454 * @param handle the handle returned from GNUNET_TESTBED_host_start_
455 */
456void
457GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle)
458{
459 if (GNUNET_YES != handle->is_stopped)
460 GNUNET_HELPER_stop (handle->helper);
461 GNUNET_free_non_null (handle->port);
462 GNUNET_free_non_null (handle->dst);
463 GNUNET_free (handle);
464}
465
466
467/**
468 * Marks a host as registered with a controller 341 * Marks a host as registered with a controller
469 * 342 *
470 * @param host the host to mark 343 * @param host the host to mark
diff --git a/src/testbed/testbed_api_hosts.h b/src/testbed/testbed_api_hosts.h
index 21e9520e2..2c89e29ac 100644
--- a/src/testbed/testbed_api_hosts.h
+++ b/src/testbed/testbed_api_hosts.h
@@ -32,48 +32,6 @@
32 32
33 33
34/** 34/**
35 * Wrapper around
36 */
37struct GNUNET_TESTBED_HelperHandle
38{
39 /**
40 * The process handle
41 */
42 struct GNUNET_HELPER_Handle *helper;
43
44 /**
45 * The send handle for the helper
46 */
47 struct GNUNET_HELPER_SendHandle *helper_shandle;
48
49 /**
50 * The port number for ssh; used for helpers starting ssh
51 */
52 char *port;
53
54 /**
55 * The ssh destination string; used for helpers starting ssh
56 */
57 char *dst;
58
59 /**
60 * The helper exception callback
61 */
62 GNUNET_HELPER_ExceptionCallback exp_cb;
63
64 /**
65 * The closure for exp_cb
66 */
67 void *exp_cb_cls;
68
69 /**
70 * Is the helper stopped?
71 */
72 int is_stopped;
73};
74
75
76/**
77 * Lookup a host by ID. 35 * Lookup a host by ID.
78 * 36 *
79 * @param id global host ID assigned to the host; 0 is 37 * @param id global host ID assigned to the host; 0 is
@@ -144,40 +102,41 @@ GNUNET_TESTBED_host_get_ssh_port_ (const struct GNUNET_TESTBED_Host *host);
144struct GNUNET_TESTBED_HelperHandle; 102struct GNUNET_TESTBED_HelperHandle;
145 103
146 104
147/** 105/* /\** */
148 * Run a given helper process at the given host. Communication 106/* * Run a given helper process at the given host. Communication */
149 * with the helper will be via GNUnet messages on stdin/stdout. 107/* * with the helper will be via GNUnet messages on stdin/stdout. */
150 * Runs the process via 'ssh' at the specified host, or locally. 108/* * Runs the process via 'ssh' at the specified host, or locally. */
151 * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API. 109/* * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API. */
152 * 110/* * */
153 * @param controller_ip the ip address of the controller. Will be set as TRUSTED 111/* * @param controller_ip the ip address of the controller. Will be set as TRUSTED */
154 * host when starting testbed controller at host 112/* * host when starting testbed controller at host */
155 * @param host host to use, use "NULL" for localhost 113/* * @param host host to use, use "NULL" for localhost */
156 * @param binary_argv binary name and command-line arguments to give to the 114/* * @param binary_argv binary name and command-line arguments to give to the */
157 * binary 115/* * binary */
158 * @param cfg template configuration to use for the remote controller; the 116/* * @param cfg template configuration to use for the remote controller; the */
159 * remote controller will be started with a slightly modified 117/* * remote controller will be started with a slightly modified */
160 * configuration (port numbers, unix domain sockets and service home 118/* * configuration (port numbers, unix domain sockets and service home */
161 * values are changed as per TESTING library on the remote host) 119/* * values are changed as per TESTING library on the remote host) */
162 * @param cb the callback to run when helper process dies; cannot be NULL 120/* * @param cb the callback to run when helper process dies; cannot be NULL */
163 * @param cb_cls the closure for the above callback 121/* * @param cb_cls the closure for the above callback */
164 * @return handle to terminate the command, NULL on error 122/* * @return handle to terminate the command, NULL on error */
165 */ 123/* *\/ */
166struct GNUNET_TESTBED_HelperHandle * 124/* struct GNUNET_TESTBED_HelperHandle * */
167GNUNET_TESTBED_host_run_ (const char *controller_ip, 125/* GNUNET_TESTBED_host_run_ (const char *controller_ip, */
168 const struct GNUNET_TESTBED_Host *host, 126/* const struct GNUNET_TESTBED_Host *host, */
169 const struct GNUNET_CONFIGURATION_Handle *cfg, 127/* const struct GNUNET_CONFIGURATION_Handle *cfg, */
170 GNUNET_HELPER_ExceptionCallback cb, 128/* GNUNET_HELPER_ExceptionCallback cb, */
171 void *cb_cls); 129/* void *cb_cls); */
172 130
173 131
174/** 132
175 * Stops a helper in the HelperHandle using GNUNET_HELPER_stop 133/* /\** */
176 * 134/* * Stops a helper in the HelperHandle using GNUNET_HELPER_stop */
177 * @param handle the handle returned from GNUNET_TESTBED_host_start_ 135/* * */
178 */ 136/* * @param handle the handle returned from GNUNET_TESTBED_host_start_ */
179void 137/* *\/ */
180GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle); 138/* void */
139/* GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle); */
181 140
182 141
183/** 142/**
diff --git a/src/testbed/testbed_helper.h b/src/testbed/testbed_helper.h
index 8780d7e98..8b3c84dde 100644
--- a/src/testbed/testbed_helper.h
+++ b/src/testbed/testbed_helper.h
@@ -52,7 +52,26 @@ struct GNUNET_TESTBED_HelperInit
52 /* Followed by NULL terminated controller hostname */ 52 /* Followed by NULL terminated controller hostname */
53 53
54 /* Followed by serialized and compressed configuration which should be 54 /* Followed by serialized and compressed configuration which should be
55 config_size long */ 55 config_size long when un-compressed */
56};
57
58/**
59 * Reply message from helper process
60 */
61struct GNUNET_TESTBED_HelperReply
62{
63 /**
64 * Type is GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY
65 */
66 struct GNUNET_MessageHeader header;
67
68 /**
69 * Size of the uncompressed configuration
70 */
71 uint16_t config_size GNUNET_PACKED;
72
73 /* Followed by compressed configuration which should be config_size long when
74 un-compressed */
56}; 75};
57 76
58#endif 77#endif