diff options
Diffstat (limited to 'src/testbed')
-rw-r--r-- | src/testbed/Makefile.am | 8 | ||||
-rw-r--r-- | src/testbed/gnunet-service-testbed.c | 8 | ||||
-rw-r--r-- | src/testbed/test_testbed_api.c | 10 | ||||
-rw-r--r-- | src/testbed/test_testbed_api_2peers_1controller.c | 10 | ||||
-rw-r--r-- | src/testbed/test_testbed_api_3peers_3controllers.c | 8 | ||||
-rw-r--r-- | src/testbed/test_testbed_api_controllerlink.c | 12 | ||||
-rw-r--r-- | src/testbed/test_testbed_api_hosts.c | 19 | ||||
-rw-r--r-- | src/testbed/testbed.h | 14 | ||||
-rw-r--r-- | src/testbed/testbed_api.c | 428 | ||||
-rw-r--r-- | src/testbed/testbed_api_hosts.c | 589 | ||||
-rw-r--r-- | src/testbed/testbed_api_hosts.h | 17 | ||||
-rw-r--r-- | src/testbed/testbed_api_testbed.c | 7 |
12 files changed, 616 insertions, 514 deletions
diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am index 53a90c325..1253f6d0e 100644 --- a/src/testbed/Makefile.am +++ b/src/testbed/Makefile.am | |||
@@ -136,12 +136,12 @@ if ENABLE_TEST_RUN | |||
136 | TESTS = \ | 136 | TESTS = \ |
137 | test_testbed_api \ | 137 | test_testbed_api \ |
138 | test_testbed_api_sd \ | 138 | test_testbed_api_sd \ |
139 | test_testbed_api_hosts \ | ||
140 | test_testbed_api_2peers_1controller \ | ||
141 | test_testbed_api_3peers_3controllers \ | ||
142 | test_testbed_api_operations \ | 139 | test_testbed_api_operations \ |
140 | test_testbed_api_hosts \ | ||
143 | test_gnunet_helper_testbed \ | 141 | test_gnunet_helper_testbed \ |
142 | test_testbed_api_2peers_1controller \ | ||
144 | test_testbed_api_controllerlink \ | 143 | test_testbed_api_controllerlink \ |
144 | test_testbed_api_3peers_3controllers \ | ||
145 | test_testbed_api_testbed_run \ | 145 | test_testbed_api_testbed_run \ |
146 | test_testbed_api_test \ | 146 | test_testbed_api_test \ |
147 | test_testbed_api_topology \ | 147 | test_testbed_api_topology \ |
@@ -150,9 +150,9 @@ if ENABLE_TEST_RUN | |||
150 | test_testbed_api_testbed_run_topologyline \ | 150 | test_testbed_api_testbed_run_topologyline \ |
151 | test_testbed_api_testbed_run_topologyclique \ | 151 | test_testbed_api_testbed_run_topologyclique \ |
152 | test_testbed_api_testbed_run_topologyring \ | 152 | test_testbed_api_testbed_run_topologyring \ |
153 | test_testbed_api_testbed_run_topologysmallworldring \ | ||
154 | test_testbed_api_testbed_run_topology2dtorus \ | 153 | test_testbed_api_testbed_run_topology2dtorus \ |
155 | test_testbed_api_testbed_run_topologysmallworld \ | 154 | test_testbed_api_testbed_run_topologysmallworld \ |
155 | test_testbed_api_testbed_run_topologysmallworldring \ | ||
156 | test_testbed_api_testbed_run_topologyfromfile \ | 156 | test_testbed_api_testbed_run_topologyfromfile \ |
157 | test_testbed_api_testbed_run_topologyscalefree | 157 | test_testbed_api_testbed_run_topologyscalefree |
158 | endif | 158 | endif |
diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index cb8c4a5f5..059423e96 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2012 Christian Grothoff (and other contributing authors) | 3 | (C) 2008--2013 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -945,7 +945,8 @@ handle_init (void *cls, struct GNUNET_SERVER_Client *client, | |||
945 | hostname); | 945 | hostname); |
946 | host = | 946 | host = |
947 | GNUNET_TESTBED_host_create_with_id (GST_context->host_id, | 947 | GNUNET_TESTBED_host_create_with_id (GST_context->host_id, |
948 | GST_context->master_ip, NULL, 0); | 948 | GST_context->master_ip, NULL, |
949 | our_config, 0); | ||
949 | host_list_add (host); | 950 | host_list_add (host); |
950 | LOG_DEBUG ("Created master context with host ID: %u\n", GST_context->host_id); | 951 | LOG_DEBUG ("Created master context with host ID: %u\n", GST_context->host_id); |
951 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 952 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
@@ -1004,9 +1005,10 @@ handle_add_host (void *cls, struct GNUNET_SERVER_Client *client, | |||
1004 | username = NULL; | 1005 | username = NULL; |
1005 | } | 1006 | } |
1006 | LOG_DEBUG ("-------ssh port: %u\n", ntohs (msg->ssh_port)); | 1007 | LOG_DEBUG ("-------ssh port: %u\n", ntohs (msg->ssh_port)); |
1008 | /* FIXME: should use configuration from ADDHOST message */ | ||
1007 | host = | 1009 | host = |
1008 | GNUNET_TESTBED_host_create_with_id (host_id, hostname, username, | 1010 | GNUNET_TESTBED_host_create_with_id (host_id, hostname, username, |
1009 | ntohs (msg->ssh_port)); | 1011 | our_config, ntohs (msg->ssh_port)); |
1010 | GNUNET_assert (NULL != host); | 1012 | GNUNET_assert (NULL != host); |
1011 | reply_size = sizeof (struct GNUNET_TESTBED_HostConfirmedMessage); | 1013 | reply_size = sizeof (struct GNUNET_TESTBED_HostConfirmedMessage); |
1012 | if (GNUNET_OK != host_list_add (host)) | 1014 | if (GNUNET_OK != host_list_add (host)) |
diff --git a/src/testbed/test_testbed_api.c b/src/testbed/test_testbed_api.c index fabe956ca..2927c3798 100644 --- a/src/testbed/test_testbed_api.c +++ b/src/testbed/test_testbed_api.c | |||
@@ -407,7 +407,7 @@ registration_comp (void *cls, const char *emsg) | |||
407 | * GNUNET_TESTBED_controller_stop() shouldn't be called in this case | 407 | * GNUNET_TESTBED_controller_stop() shouldn't be called in this case |
408 | */ | 408 | */ |
409 | static void | 409 | static void |
410 | status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, int status) | 410 | status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg_, int status) |
411 | { | 411 | { |
412 | uint64_t event_mask; | 412 | uint64_t event_mask; |
413 | 413 | ||
@@ -423,10 +423,10 @@ status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, int status) | |||
423 | event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT); | 423 | event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT); |
424 | event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED); | 424 | event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED); |
425 | controller = | 425 | controller = |
426 | GNUNET_TESTBED_controller_connect (cfg, host, event_mask, &controller_cb, | 426 | GNUNET_TESTBED_controller_connect (cfg_, host, event_mask, &controller_cb, |
427 | NULL); | 427 | NULL); |
428 | FAIL_TEST (NULL != controller, return); | 428 | FAIL_TEST (NULL != controller, return); |
429 | neighbour = GNUNET_TESTBED_host_create ("localhost", NULL, 0); | 429 | neighbour = GNUNET_TESTBED_host_create ("localhost", NULL, cfg, 0); |
430 | FAIL_TEST (NULL != neighbour, return); | 430 | FAIL_TEST (NULL != neighbour, return); |
431 | reg_handle = | 431 | reg_handle = |
432 | GNUNET_TESTBED_register_host (controller, neighbour, ®istration_comp, | 432 | GNUNET_TESTBED_register_host (controller, neighbour, ®istration_comp, |
@@ -448,9 +448,9 @@ static void | |||
448 | run (void *cls, char *const *args, const char *cfgfile, | 448 | run (void *cls, char *const *args, const char *cfgfile, |
449 | const struct GNUNET_CONFIGURATION_Handle *config) | 449 | const struct GNUNET_CONFIGURATION_Handle *config) |
450 | { | 450 | { |
451 | host = GNUNET_TESTBED_host_create (NULL, NULL, 0); | ||
452 | FAIL_TEST (NULL != host, return); | ||
453 | cfg = GNUNET_CONFIGURATION_dup (config); | 451 | cfg = GNUNET_CONFIGURATION_dup (config); |
452 | host = GNUNET_TESTBED_host_create (NULL, NULL, cfg, 0); | ||
453 | FAIL_TEST (NULL != host, return); | ||
454 | cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb, | 454 | cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb, |
455 | NULL); | 455 | NULL); |
456 | abort_task = | 456 | abort_task = |
diff --git a/src/testbed/test_testbed_api_2peers_1controller.c b/src/testbed/test_testbed_api_2peers_1controller.c index 3b033cfac..581a1c1f5 100644 --- a/src/testbed/test_testbed_api_2peers_1controller.c +++ b/src/testbed/test_testbed_api_2peers_1controller.c | |||
@@ -454,7 +454,7 @@ registration_comp (void *cls, const char *emsg) | |||
454 | * GNUNET_TESTBED_controller_stop() shouldn't be called in this case | 454 | * GNUNET_TESTBED_controller_stop() shouldn't be called in this case |
455 | */ | 455 | */ |
456 | static void | 456 | static void |
457 | status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, int status) | 457 | status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg_, int status) |
458 | { | 458 | { |
459 | uint64_t event_mask; | 459 | uint64_t event_mask; |
460 | 460 | ||
@@ -469,10 +469,10 @@ status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, int status) | |||
469 | event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT); | 469 | event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT); |
470 | event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED); | 470 | event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED); |
471 | controller = | 471 | controller = |
472 | GNUNET_TESTBED_controller_connect (cfg, host, event_mask, &controller_cb, | 472 | GNUNET_TESTBED_controller_connect (cfg_, host, event_mask, &controller_cb, |
473 | NULL); | 473 | NULL); |
474 | FAIL_TEST (NULL != controller); | 474 | FAIL_TEST (NULL != controller); |
475 | neighbour = GNUNET_TESTBED_host_create ("localhost", NULL, 0); | 475 | neighbour = GNUNET_TESTBED_host_create ("localhost", NULL, cfg, 0); |
476 | FAIL_TEST (NULL != neighbour); | 476 | FAIL_TEST (NULL != neighbour); |
477 | reg_handle = | 477 | reg_handle = |
478 | GNUNET_TESTBED_register_host (controller, neighbour, ®istration_comp, | 478 | GNUNET_TESTBED_register_host (controller, neighbour, ®istration_comp, |
@@ -494,9 +494,9 @@ static void | |||
494 | run (void *cls, char *const *args, const char *cfgfile, | 494 | run (void *cls, char *const *args, const char *cfgfile, |
495 | const struct GNUNET_CONFIGURATION_Handle *config) | 495 | const struct GNUNET_CONFIGURATION_Handle *config) |
496 | { | 496 | { |
497 | host = GNUNET_TESTBED_host_create (NULL, NULL, 0); | ||
498 | FAIL_TEST (NULL != host); | ||
499 | cfg = GNUNET_CONFIGURATION_dup (config); | 497 | cfg = GNUNET_CONFIGURATION_dup (config); |
498 | host = GNUNET_TESTBED_host_create (NULL, NULL, cfg, 0); | ||
499 | FAIL_TEST (NULL != host); | ||
500 | cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb, | 500 | cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb, |
501 | NULL); | 501 | NULL); |
502 | abort_task = | 502 | abort_task = |
diff --git a/src/testbed/test_testbed_api_3peers_3controllers.c b/src/testbed/test_testbed_api_3peers_3controllers.c index 47ad81021..526386f01 100644 --- a/src/testbed/test_testbed_api_3peers_3controllers.c +++ b/src/testbed/test_testbed_api_3peers_3controllers.c | |||
@@ -736,7 +736,7 @@ registration_comp (void *cls, const char *emsg) | |||
736 | reg_handle = NULL; | 736 | reg_handle = NULL; |
737 | if (cls == neighbour1) | 737 | if (cls == neighbour1) |
738 | { | 738 | { |
739 | neighbour2 = GNUNET_TESTBED_host_create ("127.0.0.1", NULL, 0); | 739 | neighbour2 = GNUNET_TESTBED_host_create ("127.0.0.1", NULL, cfg, 0); |
740 | if (NULL == neighbour2) | 740 | if (NULL == neighbour2) |
741 | { | 741 | { |
742 | GNUNET_break (0); | 742 | GNUNET_break (0); |
@@ -812,7 +812,7 @@ status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config, | |||
812 | return; | 812 | return; |
813 | } | 813 | } |
814 | result = CONTROLLER1_UP; | 814 | result = CONTROLLER1_UP; |
815 | neighbour1 = GNUNET_TESTBED_host_create ("127.0.0.1", NULL, 0); | 815 | neighbour1 = GNUNET_TESTBED_host_create ("127.0.0.1", NULL, cfg, 0); |
816 | if (NULL == neighbour1) | 816 | if (NULL == neighbour1) |
817 | { | 817 | { |
818 | GNUNET_break (0); | 818 | GNUNET_break (0); |
@@ -881,7 +881,8 @@ static void | |||
881 | run (void *cls, char *const *args, const char *cfgfile, | 881 | run (void *cls, char *const *args, const char *cfgfile, |
882 | const struct GNUNET_CONFIGURATION_Handle *config) | 882 | const struct GNUNET_CONFIGURATION_Handle *config) |
883 | { | 883 | { |
884 | host = GNUNET_TESTBED_host_create (NULL, NULL, 0); | 884 | cfg = GNUNET_CONFIGURATION_dup (config); |
885 | host = GNUNET_TESTBED_host_create (NULL, NULL, cfg, 0); | ||
885 | if (NULL == host) | 886 | if (NULL == host) |
886 | { | 887 | { |
887 | GNUNET_break (0); | 888 | GNUNET_break (0); |
@@ -902,7 +903,6 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
902 | result = SKIP; | 903 | result = SKIP; |
903 | return; | 904 | return; |
904 | } | 905 | } |
905 | cfg = GNUNET_CONFIGURATION_dup (config); | ||
906 | abort_task = | 906 | abort_task = |
907 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | 907 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply |
908 | (GNUNET_TIME_UNIT_MINUTES, 3), &do_abort, | 908 | (GNUNET_TIME_UNIT_MINUTES, 3), &do_abort, |
diff --git a/src/testbed/test_testbed_api_controllerlink.c b/src/testbed/test_testbed_api_controllerlink.c index f0ce4daa5..c10451703 100644 --- a/src/testbed/test_testbed_api_controllerlink.c +++ b/src/testbed/test_testbed_api_controllerlink.c | |||
@@ -484,7 +484,7 @@ controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event) | |||
484 | FAIL_TEST (event->details.peer_start.peer == master_peer); | 484 | FAIL_TEST (event->details.peer_start.peer == master_peer); |
485 | GNUNET_TESTBED_operation_done (op); | 485 | GNUNET_TESTBED_operation_done (op); |
486 | result = MASTER_PEER_START_SUCCESS; | 486 | result = MASTER_PEER_START_SUCCESS; |
487 | slave = GNUNET_TESTBED_host_create_with_id (1, "127.0.0.1", NULL, 0); | 487 | slave = GNUNET_TESTBED_host_create_with_id (1, "127.0.0.1", NULL, cfg, 0); |
488 | FAIL_TEST (NULL != slave); | 488 | FAIL_TEST (NULL != slave); |
489 | rh = GNUNET_TESTBED_register_host (mc, slave, ®istration_cont, NULL); | 489 | rh = GNUNET_TESTBED_register_host (mc, slave, ®istration_cont, NULL); |
490 | FAIL_TEST (NULL != rh); | 490 | FAIL_TEST (NULL != rh); |
@@ -548,7 +548,7 @@ controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event) | |||
548 | GNUNET_TESTBED_operation_done (op); | 548 | GNUNET_TESTBED_operation_done (op); |
549 | op = NULL; | 549 | op = NULL; |
550 | result = SLAVE2_PEER_DESTROY_SUCCESS; | 550 | result = SLAVE2_PEER_DESTROY_SUCCESS; |
551 | slave3 = GNUNET_TESTBED_host_create_with_id (3, "127.0.0.1", NULL, 0); | 551 | slave3 = GNUNET_TESTBED_host_create_with_id (3, "127.0.0.1", NULL, cfg, 0); |
552 | rh = GNUNET_TESTBED_register_host (mc, slave3, ®istration_cont, NULL); | 552 | rh = GNUNET_TESTBED_register_host (mc, slave3, ®istration_cont, NULL); |
553 | break; | 553 | break; |
554 | case SLAVE3_REGISTERED: | 554 | case SLAVE3_REGISTERED: |
@@ -607,7 +607,7 @@ registration_cont (void *cls, const char *emsg) | |||
607 | FAIL_TEST (NULL == emsg); | 607 | FAIL_TEST (NULL == emsg); |
608 | FAIL_TEST (NULL != mc); | 608 | FAIL_TEST (NULL != mc); |
609 | result = SLAVE1_REGISTERED; | 609 | result = SLAVE1_REGISTERED; |
610 | slave2 = GNUNET_TESTBED_host_create_with_id (2, "127.0.0.1", NULL, 0); | 610 | slave2 = GNUNET_TESTBED_host_create_with_id (2, "127.0.0.1", NULL, cfg, 0); |
611 | FAIL_TEST (NULL != slave2); | 611 | FAIL_TEST (NULL != slave2); |
612 | rh = GNUNET_TESTBED_register_host (mc, slave2, ®istration_cont, NULL); | 612 | rh = GNUNET_TESTBED_register_host (mc, slave2, ®istration_cont, NULL); |
613 | FAIL_TEST (NULL != rh); | 613 | FAIL_TEST (NULL != rh); |
@@ -717,7 +717,8 @@ static void | |||
717 | run (void *cls, char *const *args, const char *cfgfile, | 717 | run (void *cls, char *const *args, const char *cfgfile, |
718 | const struct GNUNET_CONFIGURATION_Handle *config) | 718 | const struct GNUNET_CONFIGURATION_Handle *config) |
719 | { | 719 | { |
720 | host = GNUNET_TESTBED_host_create (NULL, NULL, 0); | 720 | cfg = GNUNET_CONFIGURATION_dup (config); |
721 | host = GNUNET_TESTBED_host_create (NULL, NULL, cfg, 0); | ||
721 | FAIL_TEST (NULL != host); | 722 | FAIL_TEST (NULL != host); |
722 | if (NULL == | 723 | if (NULL == |
723 | (hc_handle = | 724 | (hc_handle = |
@@ -725,6 +726,8 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
725 | NULL))) | 726 | NULL))) |
726 | { | 727 | { |
727 | GNUNET_TESTBED_host_destroy (host); | 728 | GNUNET_TESTBED_host_destroy (host); |
729 | GNUNET_CONFIGURATION_destroy (cfg); | ||
730 | cfg = NULL; | ||
728 | host = NULL; | 731 | host = NULL; |
729 | (void) PRINTF ("%s", | 732 | (void) PRINTF ("%s", |
730 | "Unable to run the test as this system is not configured " | 733 | "Unable to run the test as this system is not configured " |
@@ -733,7 +736,6 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
733 | result = SKIP; | 736 | result = SKIP; |
734 | return; | 737 | return; |
735 | } | 738 | } |
736 | cfg = GNUNET_CONFIGURATION_dup (config); | ||
737 | abort_task = | 739 | abort_task = |
738 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | 740 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply |
739 | (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort, | 741 | (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort, |
diff --git a/src/testbed/test_testbed_api_hosts.c b/src/testbed/test_testbed_api_hosts.c index 51284eaab..85677b2b8 100644 --- a/src/testbed/test_testbed_api_hosts.c +++ b/src/testbed/test_testbed_api_hosts.c | |||
@@ -34,6 +34,11 @@ | |||
34 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec) | 34 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec) |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * configuration handle to use as template configuration while creating hosts | ||
38 | */ | ||
39 | static struct GNUNET_CONFIGURATION_Handle *cfg; | ||
40 | |||
41 | /** | ||
37 | * Host we are creating and using | 42 | * Host we are creating and using |
38 | */ | 43 | */ |
39 | static struct GNUNET_TESTBED_Host *host; | 44 | static struct GNUNET_TESTBED_Host *host; |
@@ -74,6 +79,11 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
74 | num_hosts--; | 79 | num_hosts--; |
75 | } | 80 | } |
76 | GNUNET_free (hosts); | 81 | GNUNET_free (hosts); |
82 | if (NULL != cfg) | ||
83 | { | ||
84 | GNUNET_CONFIGURATION_destroy (cfg); | ||
85 | cfg = NULL; | ||
86 | } | ||
77 | } | 87 | } |
78 | 88 | ||
79 | 89 | ||
@@ -87,18 +97,19 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
87 | */ | 97 | */ |
88 | static void | 98 | static void |
89 | run (void *cls, char *const *args, const char *cfgfile, | 99 | run (void *cls, char *const *args, const char *cfgfile, |
90 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 100 | const struct GNUNET_CONFIGURATION_Handle *config) |
91 | { | 101 | { |
92 | host = GNUNET_TESTBED_host_create ("localhost", NULL, 0); | 102 | cfg = GNUNET_CONFIGURATION_dup (config); |
103 | host = GNUNET_TESTBED_host_create ("localhost", NULL, cfg, 0); | ||
93 | GNUNET_assert (NULL != host); | 104 | GNUNET_assert (NULL != host); |
94 | GNUNET_assert (0 != GNUNET_TESTBED_host_get_id_ (host)); | 105 | GNUNET_assert (0 != GNUNET_TESTBED_host_get_id_ (host)); |
95 | GNUNET_TESTBED_host_destroy (host); | 106 | GNUNET_TESTBED_host_destroy (host); |
96 | host = GNUNET_TESTBED_host_create (NULL, NULL, 0); | 107 | host = GNUNET_TESTBED_host_create (NULL, NULL, cfg, 0); |
97 | GNUNET_assert (NULL != host); | 108 | GNUNET_assert (NULL != host); |
98 | GNUNET_assert (0 == GNUNET_TESTBED_host_get_id_ (host)); | 109 | GNUNET_assert (0 == GNUNET_TESTBED_host_get_id_ (host)); |
99 | GNUNET_assert (host == GNUNET_TESTBED_host_lookup_by_id_ (0)); | 110 | GNUNET_assert (host == GNUNET_TESTBED_host_lookup_by_id_ (0)); |
100 | hosts = NULL; | 111 | hosts = NULL; |
101 | num_hosts = GNUNET_TESTBED_hosts_load_from_file ("sample_hosts.txt", &hosts); | 112 | num_hosts = GNUNET_TESTBED_hosts_load_from_file ("sample_hosts.txt", cfg, &hosts); |
102 | GNUNET_assert (15 == num_hosts); | 113 | GNUNET_assert (15 == num_hosts); |
103 | GNUNET_assert (NULL != hosts); | 114 | GNUNET_assert (NULL != hosts); |
104 | status = GNUNET_YES; | 115 | status = GNUNET_YES; |
diff --git a/src/testbed/testbed.h b/src/testbed/testbed.h index 180464bd7..880a44864 100644 --- a/src/testbed/testbed.h +++ b/src/testbed/testbed.h | |||
@@ -87,9 +87,19 @@ struct GNUNET_TESTBED_AddHostMessage | |||
87 | */ | 87 | */ |
88 | uint16_t user_name_length GNUNET_PACKED; | 88 | uint16_t user_name_length GNUNET_PACKED; |
89 | 89 | ||
90 | /* followed by 0-terminated user name */ | 90 | /** |
91 | * Number of bytes in the host name (excluding 0-termination) that follows the | ||
92 | * user name; cannot be 0 | ||
93 | */ | ||
94 | uint16_t hostname_length GNUNET_PACKED; | ||
95 | |||
96 | /* followed by non 0-terminated user name */ | ||
97 | |||
98 | /* followed by non 0-terminated host name */ | ||
91 | 99 | ||
92 | /* followed by 0-terminated host name */ | 100 | /* followed by gzip compressed configuration to start or connect to a |
101 | controller on this host. While starting the controller this configration | ||
102 | is used as a template */ | ||
93 | 103 | ||
94 | }; | 104 | }; |
95 | 105 | ||
diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c index ad77003fc..eba4544eb 100644 --- a/src/testbed/testbed_api.c +++ b/src/testbed/testbed_api.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | (C) 2008--2012 Christian Grothoff (and other contributing authors) | 3 | (C) 2008--2013 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -69,54 +69,6 @@ | |||
69 | 69 | ||
70 | 70 | ||
71 | /** | 71 | /** |
72 | * Handle for controller process | ||
73 | */ | ||
74 | struct GNUNET_TESTBED_ControllerProc | ||
75 | { | ||
76 | /** | ||
77 | * The process handle | ||
78 | */ | ||
79 | struct GNUNET_HELPER_Handle *helper; | ||
80 | |||
81 | /** | ||
82 | * The arguments used to start the helper | ||
83 | */ | ||
84 | char **helper_argv; | ||
85 | |||
86 | /** | ||
87 | * The host where the helper is run | ||
88 | */ | ||
89 | struct GNUNET_TESTBED_Host *host; | ||
90 | |||
91 | /** | ||
92 | * The controller error callback | ||
93 | */ | ||
94 | GNUNET_TESTBED_ControllerStatusCallback cb; | ||
95 | |||
96 | /** | ||
97 | * The closure for the above callback | ||
98 | */ | ||
99 | void *cls; | ||
100 | |||
101 | /** | ||
102 | * The send handle for the helper | ||
103 | */ | ||
104 | struct GNUNET_HELPER_SendHandle *shandle; | ||
105 | |||
106 | /** | ||
107 | * The message corresponding to send handle | ||
108 | */ | ||
109 | struct GNUNET_MessageHeader *msg; | ||
110 | |||
111 | /** | ||
112 | * The configuration of the running testbed service | ||
113 | */ | ||
114 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
115 | |||
116 | }; | ||
117 | |||
118 | |||
119 | /** | ||
120 | * The message queue for sending messages to the controller service | 72 | * The message queue for sending messages to the controller service |
121 | */ | 73 | */ |
122 | struct MessageQueue | 74 | struct MessageQueue |
@@ -1131,98 +1083,6 @@ GNUNET_TESTBED_forward_operation_msg_cancel_ (struct OperationContext *opc) | |||
1131 | 1083 | ||
1132 | 1084 | ||
1133 | /** | 1085 | /** |
1134 | * Functions with this signature are called whenever a | ||
1135 | * complete message is received by the tokenizer. | ||
1136 | * | ||
1137 | * Do not call GNUNET_SERVER_mst_destroy in callback | ||
1138 | * | ||
1139 | * @param cls closure | ||
1140 | * @param client identification of the client | ||
1141 | * @param message the actual message | ||
1142 | * | ||
1143 | * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing | ||
1144 | */ | ||
1145 | static int | ||
1146 | helper_mst (void *cls, void *client, const struct GNUNET_MessageHeader *message) | ||
1147 | { | ||
1148 | struct GNUNET_TESTBED_ControllerProc *cp = cls; | ||
1149 | const struct GNUNET_TESTBED_HelperReply *msg; | ||
1150 | const char *hostname; | ||
1151 | char *config; | ||
1152 | uLongf config_size; | ||
1153 | uLongf xconfig_size; | ||
1154 | |||
1155 | msg = (const struct GNUNET_TESTBED_HelperReply *) message; | ||
1156 | GNUNET_assert (sizeof (struct GNUNET_TESTBED_HelperReply) < | ||
1157 | ntohs (msg->header.size)); | ||
1158 | GNUNET_assert (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY == | ||
1159 | ntohs (msg->header.type)); | ||
1160 | config_size = (uLongf) ntohs (msg->config_size); | ||
1161 | xconfig_size = | ||
1162 | (uLongf) (ntohs (msg->header.size) - | ||
1163 | sizeof (struct GNUNET_TESTBED_HelperReply)); | ||
1164 | config = GNUNET_malloc (config_size); | ||
1165 | GNUNET_assert (Z_OK == | ||
1166 | uncompress ((Bytef *) config, &config_size, | ||
1167 | (const Bytef *) &msg[1], xconfig_size)); | ||
1168 | GNUNET_assert (NULL == cp->cfg); | ||
1169 | cp->cfg = GNUNET_CONFIGURATION_create (); | ||
1170 | GNUNET_assert (GNUNET_CONFIGURATION_deserialize | ||
1171 | (cp->cfg, config, config_size, GNUNET_NO)); | ||
1172 | GNUNET_free (config); | ||
1173 | if ((NULL == cp->host) || | ||
1174 | (NULL == (hostname = GNUNET_TESTBED_host_get_hostname (cp->host)))) | ||
1175 | hostname = "localhost"; | ||
1176 | /* Change the hostname so that we can connect to it */ | ||
1177 | GNUNET_CONFIGURATION_set_value_string (cp->cfg, "testbed", "hostname", | ||
1178 | hostname); | ||
1179 | cp->cb (cp->cls, cp->cfg, GNUNET_OK); | ||
1180 | return GNUNET_OK; | ||
1181 | } | ||
1182 | |||
1183 | |||
1184 | /** | ||
1185 | * Continuation function from GNUNET_HELPER_send() | ||
1186 | * | ||
1187 | * @param cls closure | ||
1188 | * @param result GNUNET_OK on success, | ||
1189 | * GNUNET_NO if helper process died | ||
1190 | * GNUNET_SYSERR during GNUNET_HELPER_stop | ||
1191 | */ | ||
1192 | static void | ||
1193 | clear_msg (void *cls, int result) | ||
1194 | { | ||
1195 | struct GNUNET_TESTBED_ControllerProc *cp = cls; | ||
1196 | |||
1197 | GNUNET_assert (NULL != cp->shandle); | ||
1198 | cp->shandle = NULL; | ||
1199 | GNUNET_free (cp->msg); | ||
1200 | } | ||
1201 | |||
1202 | |||
1203 | /** | ||
1204 | * Callback that will be called when the helper process dies. This is not called | ||
1205 | * when the helper process is stoped using GNUNET_HELPER_stop() | ||
1206 | * | ||
1207 | * @param cls the closure from GNUNET_HELPER_start() | ||
1208 | */ | ||
1209 | static void | ||
1210 | helper_exp_cb (void *cls) | ||
1211 | { | ||
1212 | struct GNUNET_TESTBED_ControllerProc *cp = cls; | ||
1213 | GNUNET_TESTBED_ControllerStatusCallback cb; | ||
1214 | void *cb_cls; | ||
1215 | |||
1216 | cb = cp->cb; | ||
1217 | cb_cls = cp->cls; | ||
1218 | cp->helper = NULL; | ||
1219 | GNUNET_TESTBED_controller_stop (cp); | ||
1220 | if (NULL != cb) | ||
1221 | cb (cb_cls, NULL, GNUNET_SYSERR); | ||
1222 | } | ||
1223 | |||
1224 | |||
1225 | /** | ||
1226 | * Function to call to start a link-controllers type operation once all queues | 1086 | * Function to call to start a link-controllers type operation once all queues |
1227 | * the operation is part of declare that the operation can be activated. | 1087 | * the operation is part of declare that the operation can be activated. |
1228 | * | 1088 | * |
@@ -1322,290 +1182,6 @@ oprelease_get_slave_config (void *cls) | |||
1322 | 1182 | ||
1323 | 1183 | ||
1324 | /** | 1184 | /** |
1325 | * Function to copy NULL terminated list of arguments | ||
1326 | * | ||
1327 | * @param argv the NULL terminated list of arguments. Cannot be NULL. | ||
1328 | * @return the copied NULL terminated arguments | ||
1329 | */ | ||
1330 | static char ** | ||
1331 | copy_argv (const char *const *argv) | ||
1332 | { | ||
1333 | char **argv_dup; | ||
1334 | unsigned int argp; | ||
1335 | |||
1336 | GNUNET_assert (NULL != argv); | ||
1337 | for (argp = 0; NULL != argv[argp]; argp++) ; | ||
1338 | argv_dup = GNUNET_malloc (sizeof (char *) * (argp + 1)); | ||
1339 | for (argp = 0; NULL != argv[argp]; argp++) | ||
1340 | argv_dup[argp] = strdup (argv[argp]); | ||
1341 | return argv_dup; | ||
1342 | } | ||
1343 | |||
1344 | |||
1345 | /** | ||
1346 | * Function to join NULL terminated list of arguments | ||
1347 | * | ||
1348 | * @param argv1 the NULL terminated list of arguments. Cannot be NULL. | ||
1349 | * @param argv2 the NULL terminated list of arguments. Cannot be NULL. | ||
1350 | * @return the joined NULL terminated arguments | ||
1351 | */ | ||
1352 | static char ** | ||
1353 | join_argv (const char *const *argv1, const char *const *argv2) | ||
1354 | { | ||
1355 | char **argvj; | ||
1356 | char *argv; | ||
1357 | unsigned int carg; | ||
1358 | unsigned int cnt; | ||
1359 | |||
1360 | carg = 0; | ||
1361 | argvj = NULL; | ||
1362 | for (cnt = 0; NULL != argv1[cnt]; cnt++) | ||
1363 | { | ||
1364 | argv = GNUNET_strdup (argv1[cnt]); | ||
1365 | GNUNET_array_append (argvj, carg, argv); | ||
1366 | } | ||
1367 | for (cnt = 0; NULL != argv2[cnt]; cnt++) | ||
1368 | { | ||
1369 | argv = GNUNET_strdup (argv2[cnt]); | ||
1370 | GNUNET_array_append (argvj, carg, argv); | ||
1371 | } | ||
1372 | GNUNET_array_append (argvj, carg, NULL); | ||
1373 | return argvj; | ||
1374 | } | ||
1375 | |||
1376 | |||
1377 | /** | ||
1378 | * Frees the given NULL terminated arguments | ||
1379 | * | ||
1380 | * @param argv the NULL terminated list of arguments | ||
1381 | */ | ||
1382 | static void | ||
1383 | free_argv (char **argv) | ||
1384 | { | ||
1385 | unsigned int argp; | ||
1386 | |||
1387 | for (argp = 0; NULL != argv[argp]; argp++) | ||
1388 | GNUNET_free (argv[argp]); | ||
1389 | GNUNET_free (argv); | ||
1390 | } | ||
1391 | |||
1392 | |||
1393 | /** | ||
1394 | * Generates arguments for opening a remote shell. Builds up the arguments | ||
1395 | * from the environment variable GNUNET_TESTBED_RSH_CMD. The variable | ||
1396 | * should not mention `-p' (port) option and destination address as these will | ||
1397 | * be set locally in the function from its parameteres. If the environmental | ||
1398 | * variable is not found then it defaults to `ssh -o BatchMode=yes -o | ||
1399 | * NoHostAuthenticationForLocalhost=yes' | ||
1400 | * | ||
1401 | * @param port the destination port number | ||
1402 | * @param dst the destination address | ||
1403 | * @return NULL terminated list of arguments | ||
1404 | */ | ||
1405 | static char ** | ||
1406 | gen_rsh_args (const char *port, const char *dst) | ||
1407 | { | ||
1408 | static const char *default_ssh_args[] = { | ||
1409 | "ssh", | ||
1410 | "-o", | ||
1411 | "BatchMode=yes", | ||
1412 | "-o", | ||
1413 | "NoHostAuthenticationForLocalhost=yes", | ||
1414 | NULL | ||
1415 | }; | ||
1416 | char **ssh_args; | ||
1417 | char *ssh_cmd; | ||
1418 | char *ssh_cmd_cp; | ||
1419 | char *arg; | ||
1420 | unsigned int cnt; | ||
1421 | |||
1422 | ssh_args = NULL; | ||
1423 | if (NULL != (ssh_cmd = getenv ("GNUNET_TESTBED_RSH_CMD"))) | ||
1424 | { | ||
1425 | ssh_cmd = GNUNET_strdup (ssh_cmd); | ||
1426 | ssh_cmd_cp = ssh_cmd; | ||
1427 | for (cnt = 0; NULL != (arg = strtok (ssh_cmd, " ")); ssh_cmd = NULL) | ||
1428 | GNUNET_array_append (ssh_args, cnt, GNUNET_strdup (arg)); | ||
1429 | GNUNET_free (ssh_cmd_cp); | ||
1430 | } | ||
1431 | else | ||
1432 | { | ||
1433 | ssh_args = copy_argv (default_ssh_args); | ||
1434 | cnt = (sizeof (default_ssh_args)) / (sizeof (const char *)); | ||
1435 | GNUNET_array_grow (ssh_args, cnt, cnt - 1); | ||
1436 | } | ||
1437 | GNUNET_array_append (ssh_args, cnt, GNUNET_strdup ("-p")); | ||
1438 | GNUNET_array_append (ssh_args, cnt, GNUNET_strdup (port)); | ||
1439 | GNUNET_array_append (ssh_args, cnt, GNUNET_strdup (dst)); | ||
1440 | GNUNET_array_append (ssh_args, cnt, NULL); | ||
1441 | return ssh_args; | ||
1442 | } | ||
1443 | |||
1444 | |||
1445 | /** | ||
1446 | * Generates the arguments needed for executing the given binary in a remote | ||
1447 | * shell. Builds the arguments from the environmental variable | ||
1448 | * GNUNET_TETSBED_RSH_CMD_SUFFIX. If the environmental variable is not found, | ||
1449 | * only the given binary name will be present in the returned arguments | ||
1450 | * | ||
1451 | * @param helper_binary_path the path of the binary to execute | ||
1452 | * @return NULL-terminated args | ||
1453 | */ | ||
1454 | static char ** | ||
1455 | gen_rsh_suffix_args (const char *helper_binary_path) | ||
1456 | { | ||
1457 | char **rshell_args; | ||
1458 | char *rshell_cmd; | ||
1459 | char *rshell_cmd_cp; | ||
1460 | char *arg; | ||
1461 | unsigned int cnt; | ||
1462 | |||
1463 | rshell_args = NULL; | ||
1464 | cnt = 0; | ||
1465 | if (NULL != (rshell_cmd = getenv ("GNUNET_TESTBED_RSH_CMD_SUFFIX"))) | ||
1466 | { | ||
1467 | rshell_cmd = GNUNET_strdup (rshell_cmd); | ||
1468 | rshell_cmd_cp = rshell_cmd; | ||
1469 | for (; NULL != (arg = strtok (rshell_cmd, " ")); rshell_cmd = NULL) | ||
1470 | GNUNET_array_append (rshell_args, cnt, GNUNET_strdup (arg)); | ||
1471 | GNUNET_free (rshell_cmd_cp); | ||
1472 | } | ||
1473 | GNUNET_array_append (rshell_args, cnt, GNUNET_strdup (helper_binary_path)); | ||
1474 | GNUNET_array_append (rshell_args, cnt, NULL); | ||
1475 | return rshell_args; | ||
1476 | } | ||
1477 | |||
1478 | |||
1479 | /** | ||
1480 | * Starts a controller process at the given host | ||
1481 | * | ||
1482 | * @param trusted_ip the ip address of the controller which will be set as TRUSTED | ||
1483 | * HOST(all connections form this ip are permitted by the testbed) when | ||
1484 | * starting testbed controller at host. This can either be a single ip | ||
1485 | * address or a network address in CIDR notation. | ||
1486 | * @param host the host where the controller has to be started; NULL for | ||
1487 | * localhost | ||
1488 | * @param cfg template configuration to use for the remote controller; the | ||
1489 | * remote controller will be started with a slightly modified | ||
1490 | * configuration (port numbers, unix domain sockets and service home | ||
1491 | * values are changed as per TESTING library on the remote host) | ||
1492 | * @param cb function called when the controller is successfully started or | ||
1493 | * dies unexpectedly; GNUNET_TESTBED_controller_stop shouldn't be | ||
1494 | * called if cb is called with GNUNET_SYSERR as status. Will never be | ||
1495 | * called in the same task as 'GNUNET_TESTBED_controller_start' | ||
1496 | * (synchronous errors will be signalled by returning NULL). This | ||
1497 | * parameter cannot be NULL. | ||
1498 | * @param cls closure for above callbacks | ||
1499 | * @return the controller process handle, NULL on errors | ||
1500 | */ | ||
1501 | struct GNUNET_TESTBED_ControllerProc * | ||
1502 | GNUNET_TESTBED_controller_start (const char *trusted_ip, | ||
1503 | struct GNUNET_TESTBED_Host *host, | ||
1504 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
1505 | GNUNET_TESTBED_ControllerStatusCallback cb, | ||
1506 | void *cls) | ||
1507 | { | ||
1508 | struct GNUNET_TESTBED_ControllerProc *cp; | ||
1509 | struct GNUNET_TESTBED_HelperInit *msg; | ||
1510 | const char *hostname; | ||
1511 | |||
1512 | static char *const binary_argv[] = { | ||
1513 | HELPER_TESTBED_BINARY, NULL | ||
1514 | }; | ||
1515 | |||
1516 | hostname = NULL; | ||
1517 | cp = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ControllerProc)); | ||
1518 | if ((NULL == host) || (0 == GNUNET_TESTBED_host_get_id_ (host))) | ||
1519 | { | ||
1520 | cp->helper = | ||
1521 | GNUNET_HELPER_start (GNUNET_YES, HELPER_TESTBED_BINARY, binary_argv, | ||
1522 | &helper_mst, &helper_exp_cb, cp); | ||
1523 | } | ||
1524 | else | ||
1525 | { | ||
1526 | char *helper_binary_path; | ||
1527 | char **ssh_args; | ||
1528 | char **rshell_args; | ||
1529 | const char *username; | ||
1530 | char *port; | ||
1531 | char *dst; | ||
1532 | |||
1533 | username = GNUNET_TESTBED_host_get_username_ (host); | ||
1534 | hostname = GNUNET_TESTBED_host_get_hostname (host); | ||
1535 | GNUNET_asprintf (&port, "%u", GNUNET_TESTBED_host_get_ssh_port_ (host)); | ||
1536 | if (NULL == username) | ||
1537 | GNUNET_asprintf (&dst, "%s", hostname); | ||
1538 | else | ||
1539 | GNUNET_asprintf (&dst, "%s@%s", username, hostname); | ||
1540 | LOG_DEBUG ("Starting SSH to destination %s\n", dst); | ||
1541 | |||
1542 | if (GNUNET_OK != | ||
1543 | GNUNET_CONFIGURATION_get_value_string (cfg, "testbed", | ||
1544 | "HELPER_BINARY_PATH", | ||
1545 | &helper_binary_path)) | ||
1546 | helper_binary_path = | ||
1547 | GNUNET_OS_get_libexec_binary_path (HELPER_TESTBED_BINARY); | ||
1548 | ssh_args = gen_rsh_args (port, dst); | ||
1549 | rshell_args = gen_rsh_suffix_args (helper_binary_path); | ||
1550 | cp->helper_argv = | ||
1551 | join_argv ((const char **) ssh_args, (const char **) rshell_args); | ||
1552 | free_argv (ssh_args); | ||
1553 | free_argv (rshell_args); | ||
1554 | GNUNET_free (port); | ||
1555 | GNUNET_free (dst); | ||
1556 | cp->helper = | ||
1557 | GNUNET_HELPER_start (GNUNET_NO, "ssh", cp->helper_argv, &helper_mst, | ||
1558 | &helper_exp_cb, cp); | ||
1559 | GNUNET_free (helper_binary_path); | ||
1560 | } | ||
1561 | if (NULL == cp->helper) | ||
1562 | { | ||
1563 | if (NULL != cp->helper_argv) | ||
1564 | free_argv (cp->helper_argv); | ||
1565 | GNUNET_free (cp); | ||
1566 | return NULL; | ||
1567 | } | ||
1568 | cp->host = host; | ||
1569 | cp->cb = cb; | ||
1570 | cp->cls = cls; | ||
1571 | msg = GNUNET_TESTBED_create_helper_init_msg_ (trusted_ip, hostname, cfg); | ||
1572 | cp->msg = &msg->header; | ||
1573 | cp->shandle = | ||
1574 | GNUNET_HELPER_send (cp->helper, &msg->header, GNUNET_NO, &clear_msg, cp); | ||
1575 | if (NULL == cp->shandle) | ||
1576 | { | ||
1577 | GNUNET_free (msg); | ||
1578 | GNUNET_TESTBED_controller_stop (cp); | ||
1579 | return NULL; | ||
1580 | } | ||
1581 | return cp; | ||
1582 | } | ||
1583 | |||
1584 | |||
1585 | /** | ||
1586 | * Stop the controller process (also will terminate all peers and controllers | ||
1587 | * dependent on this controller). This function blocks until the testbed has | ||
1588 | * been fully terminated (!). The controller status cb from | ||
1589 | * GNUNET_TESTBED_controller_start() will not be called. | ||
1590 | * | ||
1591 | * @param cproc the controller process handle | ||
1592 | */ | ||
1593 | void | ||
1594 | GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cproc) | ||
1595 | { | ||
1596 | if (NULL != cproc->shandle) | ||
1597 | GNUNET_HELPER_send_cancel (cproc->shandle); | ||
1598 | if (NULL != cproc->helper) | ||
1599 | GNUNET_HELPER_soft_stop (cproc->helper); | ||
1600 | if (NULL != cproc->cfg) | ||
1601 | GNUNET_CONFIGURATION_destroy (cproc->cfg); | ||
1602 | if (NULL != cproc->helper_argv) | ||
1603 | free_argv (cproc->helper_argv); | ||
1604 | GNUNET_free (cproc); | ||
1605 | } | ||
1606 | |||
1607 | |||
1608 | /** | ||
1609 | * Start a controller process using the given configuration at the | 1185 | * Start a controller process using the given configuration at the |
1610 | * given host. | 1186 | * given host. |
1611 | * | 1187 | * |
@@ -1672,7 +1248,7 @@ GNUNET_TESTBED_controller_connect (const struct GNUNET_CONFIGURATION_Handle | |||
1672 | } | 1248 | } |
1673 | if (NULL == host) | 1249 | if (NULL == host) |
1674 | { | 1250 | { |
1675 | host = GNUNET_TESTBED_host_create_by_id_ (0); | 1251 | host = GNUNET_TESTBED_host_create_by_id_ (0, controller->cfg); |
1676 | if (NULL == host) /* If the above host create fails */ | 1252 | if (NULL == host) /* If the above host create fails */ |
1677 | { | 1253 | { |
1678 | LOG (GNUNET_ERROR_TYPE_WARNING, | 1254 | LOG (GNUNET_ERROR_TYPE_WARNING, |
diff --git a/src/testbed/testbed_api_hosts.c b/src/testbed/testbed_api_hosts.c index 1fb69e30b..d979d575b 100644 --- a/src/testbed/testbed_api_hosts.c +++ b/src/testbed/testbed_api_hosts.c | |||
@@ -36,6 +36,8 @@ | |||
36 | #include "testbed_api_operations.h" | 36 | #include "testbed_api_operations.h" |
37 | #include "testbed_api_sd.h" | 37 | #include "testbed_api_sd.h" |
38 | 38 | ||
39 | #include <zlib.h> | ||
40 | |||
39 | /** | 41 | /** |
40 | * Generic logging shorthand | 42 | * Generic logging shorthand |
41 | */ | 43 | */ |
@@ -43,6 +45,12 @@ | |||
43 | GNUNET_log_from (kind, "testbed-api-hosts", __VA_ARGS__); | 45 | GNUNET_log_from (kind, "testbed-api-hosts", __VA_ARGS__); |
44 | 46 | ||
45 | /** | 47 | /** |
48 | * Debug logging shorthand | ||
49 | */ | ||
50 | #define LOG_DEBUG(...) \ | ||
51 | LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__); | ||
52 | |||
53 | /** | ||
46 | * Number of extra elements we create space for when we grow host list | 54 | * Number of extra elements we create space for when we grow host list |
47 | */ | 55 | */ |
48 | #define HOST_LIST_GROW_STEP 10 | 56 | #define HOST_LIST_GROW_STEP 10 |
@@ -121,6 +129,13 @@ struct GNUNET_TESTBED_Host | |||
121 | const char *username; | 129 | const char *username; |
122 | 130 | ||
123 | /** | 131 | /** |
132 | * the configuration to use as a template while starting a controller on this | ||
133 | * host. Operation queue size specific to a host are also read from this | ||
134 | * configuration handle | ||
135 | */ | ||
136 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
137 | |||
138 | /** | ||
124 | * The head for the list of controllers where this host is registered | 139 | * The head for the list of controllers where this host is registered |
125 | */ | 140 | */ |
126 | struct RegisteredController *rc_head; | 141 | struct RegisteredController *rc_head; |
@@ -146,7 +161,7 @@ struct GNUNET_TESTBED_Host | |||
146 | * Handle for SD calculations amount parallel overlay connect operation finish | 161 | * Handle for SD calculations amount parallel overlay connect operation finish |
147 | * times | 162 | * times |
148 | */ | 163 | */ |
149 | struct SDHandle *poc_sd; | 164 | struct SDHandle *poc_sd; |
150 | 165 | ||
151 | /** | 166 | /** |
152 | * The number of parallel overlay connects we do currently | 167 | * The number of parallel overlay connects we do currently |
@@ -159,6 +174,11 @@ struct GNUNET_TESTBED_Host | |||
159 | unsigned int tslots_filled; | 174 | unsigned int tslots_filled; |
160 | 175 | ||
161 | /** | 176 | /** |
177 | * Is a controller started on this host? | ||
178 | */ | ||
179 | int controller_started; | ||
180 | |||
181 | /** | ||
162 | * Global ID we use to refer to a host on the network | 182 | * Global ID we use to refer to a host on the network |
163 | */ | 183 | */ |
164 | uint32_t id; | 184 | uint32_t id; |
@@ -205,12 +225,17 @@ GNUNET_TESTBED_host_lookup_by_id_ (uint32_t id) | |||
205 | * | 225 | * |
206 | * @param id global host ID assigned to the host; 0 is | 226 | * @param id global host ID assigned to the host; 0 is |
207 | * reserved to always mean 'localhost' | 227 | * reserved to always mean 'localhost' |
228 | * @param cfg the configuration to use as a template while starting a controller | ||
229 | * on this host. Operation queue sizes specific to a host are also | ||
230 | * read from this configuration handle | ||
208 | * @return handle to the host, NULL on error | 231 | * @return handle to the host, NULL on error |
209 | */ | 232 | */ |
210 | struct GNUNET_TESTBED_Host * | 233 | struct GNUNET_TESTBED_Host * |
211 | GNUNET_TESTBED_host_create_by_id_ (uint32_t id) | 234 | GNUNET_TESTBED_host_create_by_id_ (uint32_t id, |
235 | const struct GNUNET_CONFIGURATION_Handle | ||
236 | *cfg) | ||
212 | { | 237 | { |
213 | return GNUNET_TESTBED_host_create_with_id (id, NULL, NULL, 0); | 238 | return GNUNET_TESTBED_host_create_with_id (id, NULL, NULL, cfg, 0); |
214 | } | 239 | } |
215 | 240 | ||
216 | 241 | ||
@@ -268,18 +293,50 @@ GNUNET_TESTBED_host_get_ssh_port_ (const struct GNUNET_TESTBED_Host * host) | |||
268 | 293 | ||
269 | 294 | ||
270 | /** | 295 | /** |
296 | * Check whether a controller is already started on the given host | ||
297 | * | ||
298 | * @param host the handle to the host | ||
299 | * @return GNUNET_YES if the controller is already started; GNUNET_NO if not | ||
300 | */ | ||
301 | int | ||
302 | GNUNET_TESTBED_host_controller_started (const struct GNUNET_TESTBED_Host *host) | ||
303 | { | ||
304 | return host->controller_started; | ||
305 | } | ||
306 | |||
307 | |||
308 | /** | ||
309 | * Obtain the host's configuration template | ||
310 | * | ||
311 | * @param host handle to the host | ||
312 | * @return the host's configuration template | ||
313 | */ | ||
314 | const struct GNUNET_CONFIGURATION_Handle * | ||
315 | GNUNET_TESTBED_host_get_cfg_ (const struct GNUNET_TESTBED_Host *host) | ||
316 | { | ||
317 | return host->cfg; | ||
318 | } | ||
319 | |||
320 | |||
321 | /** | ||
271 | * Create a host to run peers and controllers on. | 322 | * Create a host to run peers and controllers on. |
272 | * | 323 | * |
273 | * @param id global host ID assigned to the host; 0 is | 324 | * @param id global host ID assigned to the host; 0 is |
274 | * reserved to always mean 'localhost' | 325 | * reserved to always mean 'localhost' |
275 | * @param hostname name of the host, use "NULL" for localhost | 326 | * @param hostname name of the host, use "NULL" for localhost |
276 | * @param username username to use for the login; may be NULL | 327 | * @param username username to use for the login; may be NULL |
328 | * @param cfg the configuration to use as a template while starting a controller | ||
329 | * on this host. Operation queue sizes specific to a host are also | ||
330 | * read from this configuration handle | ||
277 | * @param port port number to use for ssh; use 0 to let ssh decide | 331 | * @param port port number to use for ssh; use 0 to let ssh decide |
278 | * @return handle to the host, NULL on error | 332 | * @return handle to the host, NULL on error |
279 | */ | 333 | */ |
280 | struct GNUNET_TESTBED_Host * | 334 | struct GNUNET_TESTBED_Host * |
281 | GNUNET_TESTBED_host_create_with_id (uint32_t id, const char *hostname, | 335 | GNUNET_TESTBED_host_create_with_id (uint32_t id, const char *hostname, |
282 | const char *username, uint16_t port) | 336 | const char *username, |
337 | const struct GNUNET_CONFIGURATION_Handle | ||
338 | *cfg, | ||
339 | uint16_t port) | ||
283 | { | 340 | { |
284 | struct GNUNET_TESTBED_Host *host; | 341 | struct GNUNET_TESTBED_Host *host; |
285 | unsigned int new_size; | 342 | unsigned int new_size; |
@@ -293,7 +350,8 @@ GNUNET_TESTBED_host_create_with_id (uint32_t id, const char *hostname, | |||
293 | host->hostname = (NULL != hostname) ? GNUNET_strdup (hostname) : NULL; | 350 | host->hostname = (NULL != hostname) ? GNUNET_strdup (hostname) : NULL; |
294 | host->username = (NULL != username) ? GNUNET_strdup (username) : NULL; | 351 | host->username = (NULL != username) ? GNUNET_strdup (username) : NULL; |
295 | host->id = id; | 352 | host->id = id; |
296 | host->port = (0 == port) ? 22 : port; | 353 | host->port = (0 == port) ? 22 : port; |
354 | host->cfg = GNUNET_CONFIGURATION_dup (cfg); | ||
297 | host->opq_parallel_overlay_connect_operations = | 355 | host->opq_parallel_overlay_connect_operations = |
298 | GNUNET_TESTBED_operation_queue_create_ (0); | 356 | GNUNET_TESTBED_operation_queue_create_ (0); |
299 | GNUNET_TESTBED_set_num_parallel_overlay_connects_ (host, 1); | 357 | GNUNET_TESTBED_set_num_parallel_overlay_connects_ (host, 1); |
@@ -315,19 +373,24 @@ GNUNET_TESTBED_host_create_with_id (uint32_t id, const char *hostname, | |||
315 | * | 373 | * |
316 | * @param hostname name of the host, use "NULL" for localhost | 374 | * @param hostname name of the host, use "NULL" for localhost |
317 | * @param username username to use for the login; may be NULL | 375 | * @param username username to use for the login; may be NULL |
376 | * @param cfg the configuration to use as a template while starting a controller | ||
377 | * on this host. Operation queue sizes specific to a host are also | ||
378 | * read from this configuration handle | ||
318 | * @param port port number to use for ssh; use 0 to let ssh decide | 379 | * @param port port number to use for ssh; use 0 to let ssh decide |
319 | * @return handle to the host, NULL on error | 380 | * @return handle to the host, NULL on error |
320 | */ | 381 | */ |
321 | struct GNUNET_TESTBED_Host * | 382 | struct GNUNET_TESTBED_Host * |
322 | GNUNET_TESTBED_host_create (const char *hostname, const char *username, | 383 | GNUNET_TESTBED_host_create (const char *hostname, const char *username, |
384 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
323 | uint16_t port) | 385 | uint16_t port) |
324 | { | 386 | { |
325 | static uint32_t uid_generator; | 387 | static uint32_t uid_generator; |
326 | 388 | ||
327 | if (NULL == hostname) | 389 | if (NULL == hostname) |
328 | return GNUNET_TESTBED_host_create_with_id (0, hostname, username, port); | 390 | return GNUNET_TESTBED_host_create_with_id (0, hostname, username, |
391 | cfg, port); | ||
329 | return GNUNET_TESTBED_host_create_with_id (++uid_generator, hostname, | 392 | return GNUNET_TESTBED_host_create_with_id (++uid_generator, hostname, |
330 | username, port); | 393 | username, cfg, port); |
331 | } | 394 | } |
332 | 395 | ||
333 | 396 | ||
@@ -335,12 +398,17 @@ GNUNET_TESTBED_host_create (const char *hostname, const char *username, | |||
335 | * Load a set of hosts from a configuration file. | 398 | * Load a set of hosts from a configuration file. |
336 | * | 399 | * |
337 | * @param filename file with the host specification | 400 | * @param filename file with the host specification |
401 | * @param cfg the configuration to use as a template while starting a controller | ||
402 | * on any of the loaded hosts. Operation queue sizes specific to a host | ||
403 | * are also read from this configuration handle | ||
338 | * @param hosts set to the hosts found in the file; caller must free this if | 404 | * @param hosts set to the hosts found in the file; caller must free this if |
339 | * number of hosts returned is greater than 0 | 405 | * number of hosts returned is greater than 0 |
340 | * @return number of hosts returned in 'hosts', 0 on error | 406 | * @return number of hosts returned in 'hosts', 0 on error |
341 | */ | 407 | */ |
342 | unsigned int | 408 | unsigned int |
343 | GNUNET_TESTBED_hosts_load_from_file (const char *filename, | 409 | GNUNET_TESTBED_hosts_load_from_file (const char *filename, |
410 | const struct GNUNET_CONFIGURATION_Handle | ||
411 | *cfg, | ||
344 | struct GNUNET_TESTBED_Host ***hosts) | 412 | struct GNUNET_TESTBED_Host ***hosts) |
345 | { | 413 | { |
346 | //struct GNUNET_TESTBED_Host **host_array; | 414 | //struct GNUNET_TESTBED_Host **host_array; |
@@ -399,9 +467,10 @@ GNUNET_TESTBED_hosts_load_from_file (const char *filename, | |||
399 | /* We store hosts in a static list; hence we only require the starting | 467 | /* We store hosts in a static list; hence we only require the starting |
400 | * host pointer in that list to access the newly created list of hosts */ | 468 | * host pointer in that list to access the newly created list of hosts */ |
401 | if (NULL == starting_host) | 469 | if (NULL == starting_host) |
402 | starting_host = GNUNET_TESTBED_host_create (hostname, username, port); | 470 | starting_host = GNUNET_TESTBED_host_create (hostname, username, cfg, |
471 | port); | ||
403 | else | 472 | else |
404 | (void) GNUNET_TESTBED_host_create (hostname, username, port); | 473 | (void) GNUNET_TESTBED_host_create (hostname, username, cfg, port); |
405 | count++; | 474 | count++; |
406 | } | 475 | } |
407 | else | 476 | else |
@@ -449,6 +518,7 @@ GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host) | |||
449 | (host->opq_parallel_overlay_connect_operations); | 518 | (host->opq_parallel_overlay_connect_operations); |
450 | GNUNET_TESTBED_SD_destroy_ (host->poc_sd); | 519 | GNUNET_TESTBED_SD_destroy_ (host->poc_sd); |
451 | GNUNET_free_non_null (host->tslots); | 520 | GNUNET_free_non_null (host->tslots); |
521 | GNUNET_CONFIGURATION_destroy (host->cfg); | ||
452 | GNUNET_free (host); | 522 | GNUNET_free (host); |
453 | while (host_list_size >= HOST_LIST_GROW_STEP) | 523 | while (host_list_size >= HOST_LIST_GROW_STEP) |
454 | { | 524 | { |
@@ -521,6 +591,437 @@ GNUNET_TESTBED_is_host_registered_ (const struct GNUNET_TESTBED_Host *host, | |||
521 | 591 | ||
522 | 592 | ||
523 | /** | 593 | /** |
594 | * Handle for controller process | ||
595 | */ | ||
596 | struct GNUNET_TESTBED_ControllerProc | ||
597 | { | ||
598 | /** | ||
599 | * The process handle | ||
600 | */ | ||
601 | struct GNUNET_HELPER_Handle *helper; | ||
602 | |||
603 | /** | ||
604 | * The arguments used to start the helper | ||
605 | */ | ||
606 | char **helper_argv; | ||
607 | |||
608 | /** | ||
609 | * The host where the helper is run | ||
610 | */ | ||
611 | struct GNUNET_TESTBED_Host *host; | ||
612 | |||
613 | /** | ||
614 | * The controller error callback | ||
615 | */ | ||
616 | GNUNET_TESTBED_ControllerStatusCallback cb; | ||
617 | |||
618 | /** | ||
619 | * The closure for the above callback | ||
620 | */ | ||
621 | void *cls; | ||
622 | |||
623 | /** | ||
624 | * The send handle for the helper | ||
625 | */ | ||
626 | struct GNUNET_HELPER_SendHandle *shandle; | ||
627 | |||
628 | /** | ||
629 | * The message corresponding to send handle | ||
630 | */ | ||
631 | struct GNUNET_MessageHeader *msg; | ||
632 | |||
633 | /** | ||
634 | * The configuration of the running testbed service | ||
635 | */ | ||
636 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
637 | |||
638 | }; | ||
639 | |||
640 | |||
641 | /** | ||
642 | * Function to copy NULL terminated list of arguments | ||
643 | * | ||
644 | * @param argv the NULL terminated list of arguments. Cannot be NULL. | ||
645 | * @return the copied NULL terminated arguments | ||
646 | */ | ||
647 | static char ** | ||
648 | copy_argv (const char *const *argv) | ||
649 | { | ||
650 | char **argv_dup; | ||
651 | unsigned int argp; | ||
652 | |||
653 | GNUNET_assert (NULL != argv); | ||
654 | for (argp = 0; NULL != argv[argp]; argp++) ; | ||
655 | argv_dup = GNUNET_malloc (sizeof (char *) * (argp + 1)); | ||
656 | for (argp = 0; NULL != argv[argp]; argp++) | ||
657 | argv_dup[argp] = strdup (argv[argp]); | ||
658 | return argv_dup; | ||
659 | } | ||
660 | |||
661 | |||
662 | /** | ||
663 | * Function to join NULL terminated list of arguments | ||
664 | * | ||
665 | * @param argv1 the NULL terminated list of arguments. Cannot be NULL. | ||
666 | * @param argv2 the NULL terminated list of arguments. Cannot be NULL. | ||
667 | * @return the joined NULL terminated arguments | ||
668 | */ | ||
669 | static char ** | ||
670 | join_argv (const char *const *argv1, const char *const *argv2) | ||
671 | { | ||
672 | char **argvj; | ||
673 | char *argv; | ||
674 | unsigned int carg; | ||
675 | unsigned int cnt; | ||
676 | |||
677 | carg = 0; | ||
678 | argvj = NULL; | ||
679 | for (cnt = 0; NULL != argv1[cnt]; cnt++) | ||
680 | { | ||
681 | argv = GNUNET_strdup (argv1[cnt]); | ||
682 | GNUNET_array_append (argvj, carg, argv); | ||
683 | } | ||
684 | for (cnt = 0; NULL != argv2[cnt]; cnt++) | ||
685 | { | ||
686 | argv = GNUNET_strdup (argv2[cnt]); | ||
687 | GNUNET_array_append (argvj, carg, argv); | ||
688 | } | ||
689 | GNUNET_array_append (argvj, carg, NULL); | ||
690 | return argvj; | ||
691 | } | ||
692 | |||
693 | |||
694 | /** | ||
695 | * Frees the given NULL terminated arguments | ||
696 | * | ||
697 | * @param argv the NULL terminated list of arguments | ||
698 | */ | ||
699 | static void | ||
700 | free_argv (char **argv) | ||
701 | { | ||
702 | unsigned int argp; | ||
703 | |||
704 | for (argp = 0; NULL != argv[argp]; argp++) | ||
705 | GNUNET_free (argv[argp]); | ||
706 | GNUNET_free (argv); | ||
707 | } | ||
708 | |||
709 | |||
710 | /** | ||
711 | * Generates arguments for opening a remote shell. Builds up the arguments | ||
712 | * from the environment variable GNUNET_TESTBED_RSH_CMD. The variable | ||
713 | * should not mention `-p' (port) option and destination address as these will | ||
714 | * be set locally in the function from its parameteres. If the environmental | ||
715 | * variable is not found then it defaults to `ssh -o BatchMode=yes -o | ||
716 | * NoHostAuthenticationForLocalhost=yes' | ||
717 | * | ||
718 | * @param port the destination port number | ||
719 | * @param dst the destination address | ||
720 | * @return NULL terminated list of arguments | ||
721 | */ | ||
722 | static char ** | ||
723 | gen_rsh_args (const char *port, const char *dst) | ||
724 | { | ||
725 | static const char *default_ssh_args[] = { | ||
726 | "ssh", | ||
727 | "-o", | ||
728 | "BatchMode=yes", | ||
729 | "-o", | ||
730 | "NoHostAuthenticationForLocalhost=yes", | ||
731 | NULL | ||
732 | }; | ||
733 | char **ssh_args; | ||
734 | char *ssh_cmd; | ||
735 | char *ssh_cmd_cp; | ||
736 | char *arg; | ||
737 | unsigned int cnt; | ||
738 | |||
739 | ssh_args = NULL; | ||
740 | if (NULL != (ssh_cmd = getenv ("GNUNET_TESTBED_RSH_CMD"))) | ||
741 | { | ||
742 | ssh_cmd = GNUNET_strdup (ssh_cmd); | ||
743 | ssh_cmd_cp = ssh_cmd; | ||
744 | for (cnt = 0; NULL != (arg = strtok (ssh_cmd, " ")); ssh_cmd = NULL) | ||
745 | GNUNET_array_append (ssh_args, cnt, GNUNET_strdup (arg)); | ||
746 | GNUNET_free (ssh_cmd_cp); | ||
747 | } | ||
748 | else | ||
749 | { | ||
750 | ssh_args = copy_argv (default_ssh_args); | ||
751 | cnt = (sizeof (default_ssh_args)) / (sizeof (const char *)); | ||
752 | GNUNET_array_grow (ssh_args, cnt, cnt - 1); | ||
753 | } | ||
754 | GNUNET_array_append (ssh_args, cnt, GNUNET_strdup ("-p")); | ||
755 | GNUNET_array_append (ssh_args, cnt, GNUNET_strdup (port)); | ||
756 | GNUNET_array_append (ssh_args, cnt, GNUNET_strdup (dst)); | ||
757 | GNUNET_array_append (ssh_args, cnt, NULL); | ||
758 | return ssh_args; | ||
759 | } | ||
760 | |||
761 | |||
762 | /** | ||
763 | * Generates the arguments needed for executing the given binary in a remote | ||
764 | * shell. Builds the arguments from the environmental variable | ||
765 | * GNUNET_TETSBED_RSH_CMD_SUFFIX. If the environmental variable is not found, | ||
766 | * only the given binary name will be present in the returned arguments | ||
767 | * | ||
768 | * @param append_args the arguments to append after generating the suffix | ||
769 | * arguments. Can be NULL; if not must be NULL terminated 'char *' array | ||
770 | * @return NULL-terminated args | ||
771 | */ | ||
772 | static char ** | ||
773 | gen_rsh_suffix_args (const char * const *append_args) | ||
774 | { | ||
775 | char **rshell_args; | ||
776 | char *rshell_cmd; | ||
777 | char *rshell_cmd_cp; | ||
778 | char *arg; | ||
779 | unsigned int cnt; | ||
780 | unsigned int append_cnt; | ||
781 | |||
782 | rshell_args = NULL; | ||
783 | cnt = 0; | ||
784 | if (NULL != (rshell_cmd = getenv ("GNUNET_TESTBED_RSH_CMD_SUFFIX"))) | ||
785 | { | ||
786 | rshell_cmd = GNUNET_strdup (rshell_cmd); | ||
787 | rshell_cmd_cp = rshell_cmd; | ||
788 | for (; NULL != (arg = strtok (rshell_cmd, " ")); rshell_cmd = NULL) | ||
789 | GNUNET_array_append (rshell_args, cnt, GNUNET_strdup (arg)); | ||
790 | GNUNET_free (rshell_cmd_cp); | ||
791 | } | ||
792 | if (NULL != append_args) | ||
793 | { | ||
794 | for (append_cnt = 0; NULL != append_args[append_cnt]; append_cnt++) | ||
795 | GNUNET_array_append (rshell_args, cnt, GNUNET_strdup (append_args[append_cnt])); | ||
796 | } | ||
797 | GNUNET_array_append (rshell_args, cnt, NULL); | ||
798 | return rshell_args; | ||
799 | } | ||
800 | |||
801 | |||
802 | /** | ||
803 | * Functions with this signature are called whenever a | ||
804 | * complete message is received by the tokenizer. | ||
805 | * | ||
806 | * Do not call GNUNET_SERVER_mst_destroy in callback | ||
807 | * | ||
808 | * @param cls closure | ||
809 | * @param client identification of the client | ||
810 | * @param message the actual message | ||
811 | * | ||
812 | * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing | ||
813 | */ | ||
814 | static int | ||
815 | helper_mst (void *cls, void *client, const struct GNUNET_MessageHeader *message) | ||
816 | { | ||
817 | struct GNUNET_TESTBED_ControllerProc *cp = cls; | ||
818 | const struct GNUNET_TESTBED_HelperReply *msg; | ||
819 | const char *hostname; | ||
820 | char *config; | ||
821 | uLongf config_size; | ||
822 | uLongf xconfig_size; | ||
823 | |||
824 | msg = (const struct GNUNET_TESTBED_HelperReply *) message; | ||
825 | GNUNET_assert (sizeof (struct GNUNET_TESTBED_HelperReply) < | ||
826 | ntohs (msg->header.size)); | ||
827 | GNUNET_assert (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY == | ||
828 | ntohs (msg->header.type)); | ||
829 | config_size = (uLongf) ntohs (msg->config_size); | ||
830 | xconfig_size = | ||
831 | (uLongf) (ntohs (msg->header.size) - | ||
832 | sizeof (struct GNUNET_TESTBED_HelperReply)); | ||
833 | config = GNUNET_malloc (config_size); | ||
834 | GNUNET_assert (Z_OK == | ||
835 | uncompress ((Bytef *) config, &config_size, | ||
836 | (const Bytef *) &msg[1], xconfig_size)); | ||
837 | GNUNET_assert (NULL == cp->cfg); | ||
838 | cp->cfg = GNUNET_CONFIGURATION_create (); | ||
839 | GNUNET_assert (GNUNET_CONFIGURATION_deserialize | ||
840 | (cp->cfg, config, config_size, GNUNET_NO)); | ||
841 | GNUNET_free (config); | ||
842 | if ((NULL == cp->host) || | ||
843 | (NULL == (hostname = GNUNET_TESTBED_host_get_hostname (cp->host)))) | ||
844 | hostname = "localhost"; | ||
845 | /* Change the hostname so that we can connect to it */ | ||
846 | GNUNET_CONFIGURATION_set_value_string (cp->cfg, "testbed", "hostname", | ||
847 | hostname); | ||
848 | cp->cb (cp->cls, cp->cfg, GNUNET_OK); | ||
849 | return GNUNET_OK; | ||
850 | } | ||
851 | |||
852 | |||
853 | /** | ||
854 | * Continuation function from GNUNET_HELPER_send() | ||
855 | * | ||
856 | * @param cls closure | ||
857 | * @param result GNUNET_OK on success, | ||
858 | * GNUNET_NO if helper process died | ||
859 | * GNUNET_SYSERR during GNUNET_HELPER_stop | ||
860 | */ | ||
861 | static void | ||
862 | clear_msg (void *cls, int result) | ||
863 | { | ||
864 | struct GNUNET_TESTBED_ControllerProc *cp = cls; | ||
865 | |||
866 | GNUNET_assert (NULL != cp->shandle); | ||
867 | cp->shandle = NULL; | ||
868 | GNUNET_free (cp->msg); | ||
869 | } | ||
870 | |||
871 | |||
872 | /** | ||
873 | * Callback that will be called when the helper process dies. This is not called | ||
874 | * when the helper process is stoped using GNUNET_HELPER_stop() | ||
875 | * | ||
876 | * @param cls the closure from GNUNET_HELPER_start() | ||
877 | */ | ||
878 | static void | ||
879 | helper_exp_cb (void *cls) | ||
880 | { | ||
881 | struct GNUNET_TESTBED_ControllerProc *cp = cls; | ||
882 | GNUNET_TESTBED_ControllerStatusCallback cb; | ||
883 | void *cb_cls; | ||
884 | |||
885 | cb = cp->cb; | ||
886 | cb_cls = cp->cls; | ||
887 | cp->helper = NULL; | ||
888 | GNUNET_TESTBED_controller_stop (cp); | ||
889 | if (NULL != cb) | ||
890 | cb (cb_cls, NULL, GNUNET_SYSERR); | ||
891 | } | ||
892 | |||
893 | |||
894 | /** | ||
895 | * Starts a controller process at the given host | ||
896 | * | ||
897 | * @param trusted_ip the ip address of the controller which will be set as TRUSTED | ||
898 | * HOST(all connections form this ip are permitted by the testbed) when | ||
899 | * starting testbed controller at host. This can either be a single ip | ||
900 | * address or a network address in CIDR notation. | ||
901 | * @param host the host where the controller has to be started; NULL for | ||
902 | * localhost | ||
903 | * @param cfg template configuration to use for the remote controller; the | ||
904 | * remote controller will be started with a slightly modified | ||
905 | * configuration (port numbers, unix domain sockets and service home | ||
906 | * values are changed as per TESTING library on the remote host) | ||
907 | * @param cb function called when the controller is successfully started or | ||
908 | * dies unexpectedly; GNUNET_TESTBED_controller_stop shouldn't be | ||
909 | * called if cb is called with GNUNET_SYSERR as status. Will never be | ||
910 | * called in the same task as 'GNUNET_TESTBED_controller_start' | ||
911 | * (synchronous errors will be signalled by returning NULL). This | ||
912 | * parameter cannot be NULL. | ||
913 | * @param cls closure for above callbacks | ||
914 | * @return the controller process handle, NULL on errors | ||
915 | */ | ||
916 | struct GNUNET_TESTBED_ControllerProc * | ||
917 | GNUNET_TESTBED_controller_start (const char *trusted_ip, | ||
918 | struct GNUNET_TESTBED_Host *host, | ||
919 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
920 | GNUNET_TESTBED_ControllerStatusCallback cb, | ||
921 | void *cls) | ||
922 | { | ||
923 | struct GNUNET_TESTBED_ControllerProc *cp; | ||
924 | struct GNUNET_TESTBED_HelperInit *msg; | ||
925 | const char *hostname; | ||
926 | |||
927 | static char *const binary_argv[] = { | ||
928 | HELPER_TESTBED_BINARY, NULL | ||
929 | }; | ||
930 | |||
931 | hostname = NULL; | ||
932 | cp = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ControllerProc)); | ||
933 | if ((NULL == host) || (0 == GNUNET_TESTBED_host_get_id_ (host))) | ||
934 | { | ||
935 | cp->helper = | ||
936 | GNUNET_HELPER_start (GNUNET_YES, HELPER_TESTBED_BINARY, binary_argv, | ||
937 | &helper_mst, &helper_exp_cb, cp); | ||
938 | } | ||
939 | else | ||
940 | { | ||
941 | char *helper_binary_path_args[2]; | ||
942 | char **rsh_args; | ||
943 | char **rsh_suffix_args; | ||
944 | const char *username; | ||
945 | char *port; | ||
946 | char *dst; | ||
947 | |||
948 | username = GNUNET_TESTBED_host_get_username_ (host); | ||
949 | hostname = GNUNET_TESTBED_host_get_hostname (host); | ||
950 | GNUNET_asprintf (&port, "%u", GNUNET_TESTBED_host_get_ssh_port_ (host)); | ||
951 | if (NULL == username) | ||
952 | GNUNET_asprintf (&dst, "%s", hostname); | ||
953 | else | ||
954 | GNUNET_asprintf (&dst, "%s@%s", username, hostname); | ||
955 | LOG_DEBUG ("Starting SSH to destination %s\n", dst); | ||
956 | |||
957 | if (GNUNET_OK != | ||
958 | GNUNET_CONFIGURATION_get_value_string (cfg, "testbed", | ||
959 | "HELPER_BINARY_PATH", | ||
960 | &helper_binary_path_args[0])) | ||
961 | helper_binary_path_args[0] = | ||
962 | GNUNET_OS_get_libexec_binary_path (HELPER_TESTBED_BINARY); | ||
963 | helper_binary_path_args[1] = NULL; | ||
964 | rsh_args = gen_rsh_args (port, dst); | ||
965 | rsh_suffix_args = gen_rsh_suffix_args ((const char **) helper_binary_path_args); | ||
966 | cp->helper_argv = | ||
967 | join_argv ((const char **) rsh_args, (const char **) rsh_suffix_args); | ||
968 | free_argv (rsh_args); | ||
969 | free_argv (rsh_suffix_args); | ||
970 | GNUNET_free (port); | ||
971 | GNUNET_free (dst); | ||
972 | cp->helper = | ||
973 | GNUNET_HELPER_start (GNUNET_NO, cp->helper_argv[0], cp->helper_argv, &helper_mst, | ||
974 | &helper_exp_cb, cp); | ||
975 | GNUNET_free (helper_binary_path_args[0]); | ||
976 | } | ||
977 | if (NULL == cp->helper) | ||
978 | { | ||
979 | if (NULL != cp->helper_argv) | ||
980 | free_argv (cp->helper_argv); | ||
981 | GNUNET_free (cp); | ||
982 | return NULL; | ||
983 | } | ||
984 | cp->host = host; | ||
985 | cp->cb = cb; | ||
986 | cp->cls = cls; | ||
987 | msg = GNUNET_TESTBED_create_helper_init_msg_ (trusted_ip, hostname, cfg); | ||
988 | cp->msg = &msg->header; | ||
989 | cp->shandle = | ||
990 | GNUNET_HELPER_send (cp->helper, &msg->header, GNUNET_NO, &clear_msg, cp); | ||
991 | if (NULL == cp->shandle) | ||
992 | { | ||
993 | GNUNET_free (msg); | ||
994 | GNUNET_TESTBED_controller_stop (cp); | ||
995 | return NULL; | ||
996 | } | ||
997 | return cp; | ||
998 | } | ||
999 | |||
1000 | |||
1001 | /** | ||
1002 | * Stop the controller process (also will terminate all peers and controllers | ||
1003 | * dependent on this controller). This function blocks until the testbed has | ||
1004 | * been fully terminated (!). The controller status cb from | ||
1005 | * GNUNET_TESTBED_controller_start() will not be called. | ||
1006 | * | ||
1007 | * @param cproc the controller process handle | ||
1008 | */ | ||
1009 | void | ||
1010 | GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cproc) | ||
1011 | { | ||
1012 | if (NULL != cproc->shandle) | ||
1013 | GNUNET_HELPER_send_cancel (cproc->shandle); | ||
1014 | if (NULL != cproc->helper) | ||
1015 | GNUNET_HELPER_soft_stop (cproc->helper); | ||
1016 | if (NULL != cproc->cfg) | ||
1017 | GNUNET_CONFIGURATION_destroy (cproc->cfg); | ||
1018 | if (NULL != cproc->helper_argv) | ||
1019 | free_argv (cproc->helper_argv); | ||
1020 | GNUNET_free (cproc); | ||
1021 | } | ||
1022 | |||
1023 | |||
1024 | /** | ||
524 | * The handle for whether a host is habitable or not | 1025 | * The handle for whether a host is habitable or not |
525 | */ | 1026 | */ |
526 | struct GNUNET_TESTBED_HostHabitableCheckHandle | 1027 | struct GNUNET_TESTBED_HostHabitableCheckHandle |
@@ -551,19 +1052,9 @@ struct GNUNET_TESTBED_HostHabitableCheckHandle | |||
551 | struct GNUNET_OS_Process *auxp; | 1052 | struct GNUNET_OS_Process *auxp; |
552 | 1053 | ||
553 | /** | 1054 | /** |
554 | * The SSH destination address string | 1055 | * The arguments used to start the helper |
555 | */ | ||
556 | char *ssh_addr; | ||
557 | |||
558 | /** | ||
559 | * The destination port string | ||
560 | */ | 1056 | */ |
561 | char *portstr; | 1057 | char **helper_argv; |
562 | |||
563 | /** | ||
564 | * The path for hte testbed helper binary | ||
565 | */ | ||
566 | char *helper_binary_path; | ||
567 | 1058 | ||
568 | /** | 1059 | /** |
569 | * Task id for the habitability check task | 1060 | * Task id for the habitability check task |
@@ -616,9 +1107,6 @@ habitability_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
616 | ret = (0 != code) ? GNUNET_NO : GNUNET_YES; | 1107 | ret = (0 != code) ? GNUNET_NO : GNUNET_YES; |
617 | 1108 | ||
618 | call_cb: | 1109 | call_cb: |
619 | GNUNET_free (h->ssh_addr); | ||
620 | GNUNET_free (h->portstr); | ||
621 | GNUNET_free (h->helper_binary_path); | ||
622 | if (NULL != h->auxp) | 1110 | if (NULL != h->auxp) |
623 | GNUNET_OS_process_destroy (h->auxp); | 1111 | GNUNET_OS_process_destroy (h->auxp); |
624 | cb = h->cb; | 1112 | cb = h->cb; |
@@ -649,9 +1137,12 @@ GNUNET_TESTBED_is_host_habitable (const struct GNUNET_TESTBED_Host *host, | |||
649 | void *cb_cls) | 1137 | void *cb_cls) |
650 | { | 1138 | { |
651 | struct GNUNET_TESTBED_HostHabitableCheckHandle *h; | 1139 | struct GNUNET_TESTBED_HostHabitableCheckHandle *h; |
652 | char *remote_args[11]; | 1140 | char **rsh_args; |
1141 | char **rsh_suffix_args; | ||
1142 | char *stat_args[3]; | ||
653 | const char *hostname; | 1143 | const char *hostname; |
654 | unsigned int argp; | 1144 | char *port; |
1145 | char *dst; | ||
655 | 1146 | ||
656 | h = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HostHabitableCheckHandle)); | 1147 | h = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HostHabitableCheckHandle)); |
657 | h->cb = cb; | 1148 | h->cb = cb; |
@@ -659,38 +1150,34 @@ GNUNET_TESTBED_is_host_habitable (const struct GNUNET_TESTBED_Host *host, | |||
659 | h->host = host; | 1150 | h->host = host; |
660 | hostname = (NULL == host->hostname) ? "127.0.0.1" : host->hostname; | 1151 | hostname = (NULL == host->hostname) ? "127.0.0.1" : host->hostname; |
661 | if (NULL == host->username) | 1152 | if (NULL == host->username) |
662 | h->ssh_addr = GNUNET_strdup (hostname); | 1153 | dst = GNUNET_strdup (hostname); |
663 | else | 1154 | else |
664 | GNUNET_asprintf (&h->ssh_addr, "%s@%s", host->username, hostname); | 1155 | GNUNET_asprintf (&dst, "%s@%s", host->username, hostname); |
665 | if (GNUNET_OK != | 1156 | if (GNUNET_OK != |
666 | GNUNET_CONFIGURATION_get_value_string (config, "testbed", | 1157 | GNUNET_CONFIGURATION_get_value_string (config, "testbed", |
667 | "HELPER_BINARY_PATH", | 1158 | "HELPER_BINARY_PATH", |
668 | &h->helper_binary_path)) | 1159 | &stat_args[1])) |
669 | h->helper_binary_path = | 1160 | stat_args[1] = |
670 | GNUNET_OS_get_libexec_binary_path (HELPER_TESTBED_BINARY); | 1161 | GNUNET_OS_get_libexec_binary_path (HELPER_TESTBED_BINARY); |
671 | argp = 0; | 1162 | GNUNET_asprintf (&port, "%u", host->port); |
672 | remote_args[argp++] = "ssh"; | 1163 | rsh_args = gen_rsh_args (port, dst); |
673 | GNUNET_asprintf (&h->portstr, "%u", host->port); | 1164 | GNUNET_free (port); |
674 | remote_args[argp++] = "-p"; | 1165 | GNUNET_free (dst); |
675 | remote_args[argp++] = h->portstr; | 1166 | port = NULL; |
676 | remote_args[argp++] = "-o"; | 1167 | dst = NULL; |
677 | remote_args[argp++] = "BatchMode=yes"; | 1168 | stat_args[0] = "stat"; |
678 | remote_args[argp++] = "-o"; | 1169 | stat_args[2] = NULL; |
679 | remote_args[argp++] = "NoHostAuthenticationForLocalhost=yes"; | 1170 | rsh_suffix_args = gen_rsh_suffix_args ((const char **) stat_args); |
680 | remote_args[argp++] = h->ssh_addr; | 1171 | h->helper_argv = join_argv ((const char **) rsh_args, |
681 | remote_args[argp++] = "stat"; | 1172 | (const char **) rsh_suffix_args); |
682 | remote_args[argp++] = h->helper_binary_path; | 1173 | GNUNET_free (rsh_suffix_args); |
683 | remote_args[argp++] = NULL; | 1174 | GNUNET_free (rsh_args); |
684 | GNUNET_assert (argp == 11); | ||
685 | h->auxp = | 1175 | h->auxp = |
686 | GNUNET_OS_start_process_vap (GNUNET_NO, GNUNET_OS_INHERIT_STD_ERR, NULL, | 1176 | GNUNET_OS_start_process_vap (GNUNET_NO, GNUNET_OS_INHERIT_STD_ERR, NULL, |
687 | NULL, "ssh", remote_args); | 1177 | NULL, h->helper_argv[0], h->helper_argv); |
688 | if (NULL == h->auxp) | 1178 | if (NULL == h->auxp) |
689 | { | 1179 | { |
690 | GNUNET_break (0); /* Cannot exec SSH? */ | 1180 | GNUNET_break (0); /* Cannot exec SSH? */ |
691 | GNUNET_free (h->ssh_addr); | ||
692 | GNUNET_free (h->portstr); | ||
693 | GNUNET_free (h->helper_binary_path); | ||
694 | GNUNET_free (h); | 1181 | GNUNET_free (h); |
695 | return NULL; | 1182 | return NULL; |
696 | } | 1183 | } |
@@ -715,9 +1202,7 @@ GNUNET_TESTBED_is_host_habitable_cancel (struct | |||
715 | (void) GNUNET_OS_process_kill (handle->auxp, SIGTERM); | 1202 | (void) GNUNET_OS_process_kill (handle->auxp, SIGTERM); |
716 | (void) GNUNET_OS_process_wait (handle->auxp); | 1203 | (void) GNUNET_OS_process_wait (handle->auxp); |
717 | GNUNET_OS_process_destroy (handle->auxp); | 1204 | GNUNET_OS_process_destroy (handle->auxp); |
718 | GNUNET_free (handle->ssh_addr); | 1205 | free_argv (handle->helper_argv); |
719 | GNUNET_free (handle->portstr); | ||
720 | GNUNET_free (handle->helper_binary_path); | ||
721 | GNUNET_free (handle); | 1206 | GNUNET_free (handle); |
722 | } | 1207 | } |
723 | 1208 | ||
diff --git a/src/testbed/testbed_api_hosts.h b/src/testbed/testbed_api_hosts.h index 69d18bcbf..2d25fd596 100644 --- a/src/testbed/testbed_api_hosts.h +++ b/src/testbed/testbed_api_hosts.h | |||
@@ -49,10 +49,15 @@ GNUNET_TESTBED_host_lookup_by_id_ (uint32_t id); | |||
49 | * | 49 | * |
50 | * @param id global host ID assigned to the host; 0 is | 50 | * @param id global host ID assigned to the host; 0 is |
51 | * reserved to always mean 'localhost' | 51 | * reserved to always mean 'localhost' |
52 | * @param cfg the configuration to use as a template while starting a controller | ||
53 | * on this host. Operation queue sizes specific to a host are also | ||
54 | * read from this configuration handle | ||
52 | * @return handle to the host, NULL on error | 55 | * @return handle to the host, NULL on error |
53 | */ | 56 | */ |
54 | struct GNUNET_TESTBED_Host * | 57 | struct GNUNET_TESTBED_Host * |
55 | GNUNET_TESTBED_host_create_by_id_ (uint32_t id); | 58 | GNUNET_TESTBED_host_create_by_id_ (uint32_t id, |
59 | const struct GNUNET_CONFIGURATION_Handle | ||
60 | *cfg); | ||
56 | 61 | ||
57 | 62 | ||
58 | /** | 63 | /** |
@@ -87,6 +92,16 @@ GNUNET_TESTBED_host_get_ssh_port_ (const struct GNUNET_TESTBED_Host *host); | |||
87 | 92 | ||
88 | 93 | ||
89 | /** | 94 | /** |
95 | * Obtain the host's configuration template | ||
96 | * | ||
97 | * @param host handle to the host | ||
98 | * @return the host's configuration template | ||
99 | */ | ||
100 | const struct GNUNET_CONFIGURATION_Handle * | ||
101 | GNUNET_TESTBED_host_get_cfg_ (const struct GNUNET_TESTBED_Host *host); | ||
102 | |||
103 | |||
104 | /** | ||
90 | * Marks a host as registered with a controller | 105 | * Marks a host as registered with a controller |
91 | * | 106 | * |
92 | * @param host the host to mark | 107 | * @param host the host to mark |
diff --git a/src/testbed/testbed_api_testbed.c b/src/testbed/testbed_api_testbed.c index a2f60c8cc..d57c3bf4c 100644 --- a/src/testbed/testbed_api_testbed.c +++ b/src/testbed/testbed_api_testbed.c | |||
@@ -1049,10 +1049,12 @@ GNUNET_TESTBED_run (const char *host_filename, | |||
1049 | 1049 | ||
1050 | GNUNET_assert (num_peers > 0); | 1050 | GNUNET_assert (num_peers > 0); |
1051 | rc = GNUNET_malloc (sizeof (struct RunContext)); | 1051 | rc = GNUNET_malloc (sizeof (struct RunContext)); |
1052 | rc->cfg = GNUNET_CONFIGURATION_dup (cfg); | ||
1052 | if (NULL != host_filename) | 1053 | if (NULL != host_filename) |
1053 | { | 1054 | { |
1054 | rc->num_hosts = | 1055 | rc->num_hosts = |
1055 | GNUNET_TESTBED_hosts_load_from_file (host_filename, &rc->hosts); | 1056 | GNUNET_TESTBED_hosts_load_from_file (host_filename, rc->cfg, |
1057 | &rc->hosts); | ||
1056 | if (0 == rc->num_hosts) | 1058 | if (0 == rc->num_hosts) |
1057 | { | 1059 | { |
1058 | LOG (GNUNET_ERROR_TYPE_WARNING, | 1060 | LOG (GNUNET_ERROR_TYPE_WARNING, |
@@ -1061,8 +1063,7 @@ GNUNET_TESTBED_run (const char *host_filename, | |||
1061 | } | 1063 | } |
1062 | } | 1064 | } |
1063 | else | 1065 | else |
1064 | rc->h = GNUNET_TESTBED_host_create (NULL, NULL, 0); | 1066 | rc->h = GNUNET_TESTBED_host_create (NULL, NULL, rc->cfg, 0); |
1065 | rc->cfg = GNUNET_CONFIGURATION_dup (cfg); | ||
1066 | rc->num_peers = num_peers; | 1067 | rc->num_peers = num_peers; |
1067 | rc->event_mask = event_mask; | 1068 | rc->event_mask = event_mask; |
1068 | rc->cc = cc; | 1069 | rc->cc = cc; |