aboutsummaryrefslogtreecommitdiff
path: root/src/testbed
diff options
context:
space:
mode:
authort3sserakt <t3ss@posteo.de>2021-06-30 13:04:40 +0200
committert3sserakt <t3ss@posteo.de>2021-06-30 13:04:40 +0200
commit13dbe5418c1e61bb3c433efa7c2dc412e08b356d (patch)
treeba53f0f1bb3f365a41c079aa3190fb98caf9d1b6 /src/testbed
parent3ae831780b5681764a7d0505fa94f3fdaa43e1d8 (diff)
downloadgnunet-13dbe5418c1e61bb3c433efa7c2dc412e08b356d.tar.gz
gnunet-13dbe5418c1e61bb3c433efa7c2dc412e08b356d.zip
- starting testbed with netjail
Diffstat (limited to 'src/testbed')
-rw-r--r--src/testbed/Makefile.am12
-rwxr-xr-xsrc/testbed/netjail_core.sh107
-rwxr-xr-xsrc/testbed/netjail_exec.sh19
-rwxr-xr-xsrc/testbed/netjail_start.sh52
-rwxr-xr-xsrc/testbed/netjail_stop.sh26
-rw-r--r--src/testbed/test_testbed_api_cmd_netjail.c94
-rw-r--r--src/testbed/testbed_api_cmd_netjail_start.c193
-rw-r--r--src/testbed/testbed_api_cmd_netjail_start_testbed.c258
-rw-r--r--src/testbed/testbed_api_cmd_netjail_stop.c197
9 files changed, 958 insertions, 0 deletions
diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am
index 5b81f7295..486c4a4f8 100644
--- a/src/testbed/Makefile.am
+++ b/src/testbed/Makefile.am
@@ -92,6 +92,9 @@ lib_LTLIBRARIES = \
92 libgnunettestbed.la 92 libgnunettestbed.la
93 93
94libgnunettestbed_la_SOURCES = \ 94libgnunettestbed_la_SOURCES = \
95 testbed_api_cmd_netjail_start.c \
96 testbed_api_cmd_netjail_start_testbed.c \
97 testbed_api_cmd_netjail_stop.c \
95 testbed_api.c testbed_api.h testbed.h \ 98 testbed_api.c testbed_api.h testbed.h \
96 testbed_api_hosts.c testbed_api_hosts.h testbed_helper.h \ 99 testbed_api_hosts.c testbed_api_hosts.h testbed_helper.h \
97 testbed_api_cmd_controller.c \ 100 testbed_api_cmd_controller.c \
@@ -131,6 +134,7 @@ generate_underlay_topology_LDADD = $(XLIB) \
131 $(LTLIBINTL) -lsqlite3 134 $(LTLIBINTL) -lsqlite3
132 135
133check_PROGRAMS = \ 136check_PROGRAMS = \
137 test_testbed_api_cmd_netjail \
134 test_testbed_api_hosts \ 138 test_testbed_api_hosts \
135 test_gnunet_helper_testbed \ 139 test_gnunet_helper_testbed \
136 test_testbed_api_controllerlink \ 140 test_testbed_api_controllerlink \
@@ -165,6 +169,7 @@ check_PROGRAMS = \
165if ENABLE_TEST_RUN 169if ENABLE_TEST_RUN
166 AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; 170 AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
167 TESTS = \ 171 TESTS = \
172 test_testbed_api_cmd_netjail \
168 test_testbed_api \ 173 test_testbed_api \
169 test_testbed_api_sd \ 174 test_testbed_api_sd \
170 test_testbed_api_operations \ 175 test_testbed_api_operations \
@@ -195,6 +200,13 @@ if ENABLE_TEST_RUN
195 $(underlay_testcases) 200 $(underlay_testcases)
196endif 201endif
197 202
203test_testbed_api_cmd_netjail_SOURCES = \
204 test_testbed_api_cmd_netjail.c
205test_testbed_api_cmd_netjail_LDADD = \
206 $(top_builddir)/src/testing/libgnunettesting.la \
207 $(top_builddir)/src/util/libgnunetutil.la \
208 libgnunettestbed.la
209
198test_testbed_api_SOURCES = \ 210test_testbed_api_SOURCES = \
199 test_testbed_api.c 211 test_testbed_api.c
200test_testbed_api_LDADD = \ 212test_testbed_api_LDADD = \
diff --git a/src/testbed/netjail_core.sh b/src/testbed/netjail_core.sh
new file mode 100755
index 000000000..d25948bc7
--- /dev/null
+++ b/src/testbed/netjail_core.sh
@@ -0,0 +1,107 @@
1#!/bin/sh
2#
3
4JAILOR=${SUDO_USER:?must run in sudo}
5
6# running with `sudo` is required to be
7# able running the actual commands as the
8# original user.
9
10export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
11
12netjail_check() {
13 NODE_COUNT=$1
14
15 FD_COUNT=$(($(ls /proc/self/fd | wc -w) - 4))
16
17 # quit if `$FD_COUNT < ($LOCAL_M * $GLOBAL_N * 2)`:
18 # the script also requires `sudo -C ($FD_COUNT + 4)`
19 # so you need 'Defaults closefrom_override' in the
20 # sudoers file.
21
22 if [ $FD_COUNT -lt $(($NODE_COUNT * 2)) ]; then
23 echo "File descriptors do not match requirements!" >&2
24 exit 1
25 fi
26}
27
28netjail_print_name() {
29 printf "%s%02x%02x" $1 $2 ${3:-0}
30}
31
32netjail_bridge() {
33 BRIDGE=$1
34
35 ip link add $BRIDGE type bridge
36 ip link set dev $BRIDGE up
37}
38
39netjail_bridge_clear() {
40 BRIDGE=$1
41
42 ip link delete $BRIDGE
43}
44
45netjail_node() {
46 NODE=$1
47
48 ip netns add $NODE
49}
50
51netjail_node_clear() {
52 NODE=$1
53
54 ip netns delete $NODE
55}
56
57netjail_node_link_bridge() {
58 NODE=$1
59 BRIDGE=$2
60 ADDRESS=$3
61 MASK=$4
62
63 LINK_IF="$NODE-$BRIDGE-0"
64 LINK_BR="$NODE-$BRIDGE-1"
65
66 ip link add $LINK_IF type veth peer name $LINK_BR
67 ip link set $LINK_IF netns $NODE
68 ip link set $LINK_BR master $BRIDGE
69
70 ip -n $NODE addr add "$ADDRESS/$MASK" dev $LINK_IF
71 ip -n $NODE link set $LINK_IF up
72 ip -n $NODE link set up dev lo
73
74 ip link set $LINK_BR up
75}
76
77netjail_node_add_nat() {
78 NODE=$1
79 ADDRESS=$2
80 MASK=$3
81
82 ip netns exec $NODE iptables -t nat -A POSTROUTING -s "$ADDRESS/$MASK" -j MASQUERADE
83}
84
85netjail_node_add_default() {
86 NODE=$1
87 ADDRESS=$2
88
89 ip -n $NODE route add default via $ADDRESS
90}
91
92netjail_node_exec() {
93 NODE=$1
94 FD_IN=$2
95 FD_OUT=$3
96 shift 3
97
98 unshare -fp --kill-child -- ip netns exec $NODE sudo -u $JAILOR -- $@ 1>& $FD_OUT 0<& $FD_IN
99}
100
101netjail_node_exec_without_fds() {
102 local NODE=$1
103 shift 3
104
105 unshare -fp --kill-child -- ip netns exec $NODE sudo -u $JAILOR -- $@
106}
107
diff --git a/src/testbed/netjail_exec.sh b/src/testbed/netjail_exec.sh
new file mode 100755
index 000000000..274a8b037
--- /dev/null
+++ b/src/testbed/netjail_exec.sh
@@ -0,0 +1,19 @@
1#!/bin/sh
2. "./netjail_core.sh"
3
4set -eu
5set -x
6
7export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
8
9LOCAL_M=$1
10M=$2
11N=$3
12
13NODE=$(netjail_print_name "N" $N $M)
14INDEX=$(($LOCAL_M * ($N - 1) + $M - 1))
15
16FD_X=$(($INDEX * 2 + 3 + 0))
17FD_Y=$(($INDEX * 2 + 3 + 1))
18
19netjail_node_exec_without_fds $NODE $@
diff --git a/src/testbed/netjail_start.sh b/src/testbed/netjail_start.sh
new file mode 100755
index 000000000..a2abca2d7
--- /dev/null
+++ b/src/testbed/netjail_start.sh
@@ -0,0 +1,52 @@
1#!/bin/sh
2. "./netjail_core.sh"
3
4set -eu
5set -x
6
7export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
8
9LOCAL_M=$1
10GLOBAL_N=$2
11
12# TODO: stunserver? ..and globally known peer?
13
14shift 2
15
16LOCAL_GROUP="192.168.15"
17GLOBAL_GROUP="92.68.150"
18
19NETWORK_NET=$(netjail_print_name "n" $GLOBAL_N $LOCAL_M)
20
21netjail_bridge $NETWORK_NET
22
23for N in $(seq $GLOBAL_N); do
24 ROUTER=$(netjail_print_name "R" $N)
25
26 netjail_node $ROUTER
27 netjail_node_link_bridge $ROUTER $NETWORK_NET "$GLOBAL_GROUP.$N" 24
28
29 ROUTER_NET=$(netjail_print_name "r" $N)
30
31 netjail_bridge $ROUTER_NET
32
33 for M in $(seq $LOCAL_M); do
34 NODE=$(netjail_print_name "N" $N $M)
35
36 netjail_node $NODE
37 netjail_node_link_bridge $NODE $ROUTER_NET "$LOCAL_GROUP.$M" 24
38 done
39
40 ROUTER_ADDR="$LOCAL_GROUP.$(($LOCAL_M+1))"
41
42 netjail_node_link_bridge $ROUTER $ROUTER_NET $ROUTER_ADDR 24
43 netjail_node_add_nat $ROUTER $ROUTER_ADDR 24
44
45 for M in $(seq $LOCAL_M); do
46 NODE=$(netjail_print_name "N" $N $M)
47
48 netjail_node_add_default $NODE $ROUTER_ADDR
49 done
50done
51
52
diff --git a/src/testbed/netjail_stop.sh b/src/testbed/netjail_stop.sh
new file mode 100755
index 000000000..4763cb107
--- /dev/null
+++ b/src/testbed/netjail_stop.sh
@@ -0,0 +1,26 @@
1#!/bin/sh
2. "./netjail_core.sh"
3
4set -eu
5set -x
6
7export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
8
9LOCAL_M=$1
10GLOBAL_N=$2
11NETWORK_NET=$(netjail_print_name "n" $GLOBAL_N $LOCAL_M)
12
13shift 2
14
15for N in $(seq $GLOBAL_N); do
16 for M in $(seq $LOCAL_M); do
17 netjail_node_clear $(netjail_print_name "N" $N $M)
18 done
19
20 netjail_bridge_clear $(netjail_print_name "r" $N)
21 netjail_node_clear $(netjail_print_name "R" $N)
22done
23
24netjail_bridge_clear $NETWORK_NET
25
26echo "Done"
diff --git a/src/testbed/test_testbed_api_cmd_netjail.c b/src/testbed/test_testbed_api_cmd_netjail.c
new file mode 100644
index 000000000..d29ebdcb4
--- /dev/null
+++ b/src/testbed/test_testbed_api_cmd_netjail.c
@@ -0,0 +1,94 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing/test_testing_api_cmd_netjail.c
23 * @brief Test case executing a script in a network name space.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_testbed_ng_service.h"
29#include "gnunet_util_lib.h"
30
31#define HELPER_TESTBED_BINARY "../testbed/gnunet-helper-testbed"
32
33static int
34tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
35{
36 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called tokenizer.\n");
37 return GNUNET_OK;
38}
39
40
41static void
42exp_cb (void *cls)
43{
44 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n");
45}
46
47
48/**
49 * Main function to run the test cases.
50 *
51 * @param cls not used.
52 *
53 */
54static void
55run (void *cls)
56{
57 char *const binary_argv[3] = {HELPER_TESTBED_BINARY, NULL};
58
59 struct GNUNET_TESTING_Command commands[] = {
60 GNUNET_TESTBED_cmd_netjail_start ("netjail-start-1",
61 "1",
62 "2"),
63 GNUNET_TESTBED_cmd_netjail_start_testbed ("netjail-exec-1",
64 binary_argv,
65 "1",
66 "2",
67 &tokenizer_cb,
68 &exp_cb),
69 GNUNET_TESTBED_cmd_netjail_stop ("netjail-stop-1",
70 "1",
71 "2"),
72 GNUNET_TESTING_cmd_end ()
73 };
74
75 GNUNET_TESTING_run (NULL,
76 commands,
77 GNUNET_TIME_UNIT_FOREVER_REL);
78}
79
80
81int
82main (int argc,
83 char *const *argv)
84{
85 int rv = 0;
86
87 GNUNET_log_setup ("test-netjail",
88 "DEBUG",
89 NULL);
90 GNUNET_SCHEDULER_run (&run,
91 NULL);
92
93 return rv;
94}
diff --git a/src/testbed/testbed_api_cmd_netjail_start.c b/src/testbed/testbed_api_cmd_netjail_start.c
new file mode 100644
index 000000000..320537a61
--- /dev/null
+++ b/src/testbed/testbed_api_cmd_netjail_start.c
@@ -0,0 +1,193 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing/testing_api_cmd_hello_world.c
23 * @brief Command to start the netjail script.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29#include "gnunet_testbed_ng_service.h"
30
31#define NETJAIL_START_SCRIPT "./netjail_start.sh"
32
33struct NetJailState
34{
35 struct GNUNET_ChildWaitHandle *cwh;
36
37 char *local_m;
38
39 char *global_n;
40
41 /**
42 * The process id of the start script.
43 */
44 struct GNUNET_OS_Process *start_proc;
45
46 unsigned int finished;
47};
48
49
50/**
51*
52*
53* @param cls closure
54* @param cmd current CMD being cleaned up.
55*/
56static void
57netjail_start_cleanup (void *cls,
58 const struct GNUNET_TESTING_Command *cmd)
59{
60 struct NetJailState *ns = cls;
61
62 if (NULL != ns->cwh)
63 {
64 GNUNET_wait_child_cancel (ns->cwh);
65 ns->cwh = NULL;
66 }
67 if (NULL != ns->start_proc)
68 {
69 GNUNET_assert (0 ==
70 GNUNET_OS_process_kill (ns->start_proc,
71 SIGKILL));
72 GNUNET_assert (GNUNET_OK ==
73 GNUNET_OS_process_wait (ns->start_proc));
74 GNUNET_OS_process_destroy (ns->start_proc);
75 ns->start_proc = NULL;
76 }
77}
78
79
80/**
81*
82*
83* @param cls closure.
84* @param[out] ret result
85* @param trait name of the trait.
86* @param index index number of the object to offer.
87* @return #GNUNET_OK on success.
88*/
89static int
90netjail_start_traits (void *cls,
91 const void **ret,
92 const char *trait,
93 unsigned int index)
94{
95 return GNUNET_OK;
96}
97
98static void
99child_completed_callback (void *cls,
100 enum GNUNET_OS_ProcessStatusType type,
101 long unsigned int exit_code)
102{
103 struct NetJailState *ns = cls;
104
105 if (0 == exit_code)
106 {
107 ns->finished = GNUNET_YES;
108 }
109 else
110 {
111 ns->finished = GNUNET_SYSERR;
112 }
113 GNUNET_OS_process_destroy (ns->start_proc);
114 ns->start_proc = NULL;
115}
116
117
118
119/**
120* Run the "hello world" CMD.
121*
122* @param cls closure.
123* @param cmd CMD being run.
124* @param is interpreter state.
125*/
126static void
127netjail_start_run (void *cls,
128 const struct GNUNET_TESTING_Command *cmd,
129 struct GNUNET_TESTING_Interpreter *is)
130{
131 struct NetJailState *ns = cls;
132 char *const script_argv[] = {NETJAIL_START_SCRIPT,
133 ns->local_m,
134 ns->global_n,
135 NULL};
136
137 ns->start_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
138 NULL,
139 NULL,
140 NULL,
141 NETJAIL_START_SCRIPT,
142 script_argv);
143
144 ns->cwh = GNUNET_wait_child (ns->start_proc,
145 &child_completed_callback,
146 ns);
147 GNUNET_break (NULL != ns->cwh);
148}
149
150static int
151netjail_start_finish (void *cls,
152 GNUNET_SCHEDULER_TaskCallback cont,
153 void *cont_cls)
154{
155 struct NetJailState *ns = cls;
156
157 if (ns->finished)
158 {
159 cont (cont_cls);
160 }
161 return ns->finished;
162}
163
164/**
165 * Create command.
166 *
167 * @param label name for command.
168 * @param binaryname to start.
169 * @return command.
170 */
171struct GNUNET_TESTING_Command
172GNUNET_TESTBED_cmd_netjail_start (const char *label,
173 char *local_m,
174 char *global_n)
175{
176 struct NetJailState *ns;
177
178 ns = GNUNET_new (struct NetJailState);
179 ns->local_m = local_m;
180 ns->global_n = global_n;
181 ns->finished = GNUNET_NO;
182
183 struct GNUNET_TESTING_Command cmd = {
184 .cls = ns,
185 .label = label,
186 .run = &netjail_start_run,
187 .finish = &netjail_start_finish,
188 .cleanup = &netjail_start_cleanup,
189 .traits = &netjail_start_traits
190 };
191
192 return cmd;
193}
diff --git a/src/testbed/testbed_api_cmd_netjail_start_testbed.c b/src/testbed/testbed_api_cmd_netjail_start_testbed.c
new file mode 100644
index 000000000..da51350a1
--- /dev/null
+++ b/src/testbed/testbed_api_cmd_netjail_start_testbed.c
@@ -0,0 +1,258 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing/testing_api_cmd_hello_world.c
23 * @brief Command to start the netjail peers.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_testbed_ng_service.h"
29#include "testbed_api.h"
30
31#define NETJAIL_EXEC_SCRIPT "./netjail_exec.sh"
32
33struct NetJailState
34{
35
36 /**
37 * The process handle
38 */
39 struct GNUNET_HELPER_Handle *helper;
40
41 GNUNET_MessageTokenizerCallback cb;
42
43 GNUNET_HELPER_ExceptionCallback exp_cb;
44
45 char *binary_name;
46
47 char *local_m;
48
49 char *global_n;
50
51 char **binary_argv;
52
53 /**
54 * The send handle for the helper
55 */
56 struct GNUNET_HELPER_SendHandle *shandle;
57
58 /**
59 * The message corresponding to send handle
60 */
61 struct GNUNET_MessageHeader *msg;
62};
63
64
65/**
66*
67*
68* @param cls closure
69* @param cmd current CMD being cleaned up.
70*/
71static void
72netjail_exec_cleanup (void *cls,
73 const struct GNUNET_TESTING_Command *cmd)
74{
75 struct NetJailState *ns = cls;
76
77 GNUNET_free (ns->binary_name);
78}
79
80
81/**
82*
83*
84* @param cls closure.
85* @param[out] ret result
86* @param trait name of the trait.
87* @param index index number of the object to offer.
88* @return #GNUNET_OK on success.
89*/
90static int
91netjail_exec_traits (void *cls,
92 const void **ret,
93 const char *trait,
94 unsigned int index)
95{
96 return GNUNET_OK;
97}
98
99
100// TODO This would be a useful macro.
101/**
102 * Function to join NULL terminated list of arguments
103 *
104 * @param argv1 the NULL terminated list of arguments. Cannot be NULL.
105 * @param argv2 the NULL terminated list of arguments. Cannot be NULL.
106 * @return the joined NULL terminated arguments
107 */
108static char **
109join_argv (const char *const *argv1, const char *const *argv2)
110{
111 char **argvj;
112 char *argv;
113 unsigned int carg = 0;
114 unsigned int cnt;
115
116 carg = 0;
117 argvj = NULL;
118 for (cnt = 0; NULL != argv1[cnt]; cnt++)
119 {
120 argv = GNUNET_strdup (argv1[cnt]);
121 GNUNET_array_append (argvj, carg, argv);
122 }
123 for (cnt = 0; NULL != argv2[cnt]; cnt++)
124 {
125 argv = GNUNET_strdup (argv2[cnt]);
126 GNUNET_array_append (argvj, carg, argv);
127 }
128 GNUNET_array_append (argvj, carg, NULL);
129 return argvj;
130}
131
132
133/**
134 * Continuation function from GNUNET_HELPER_send()
135 *
136 * @param cls closure
137 * @param result GNUNET_OK on success,
138 * GNUNET_NO if helper process died
139 * GNUNET_SYSERR during GNUNET_HELPER_stop
140 */
141static void
142clear_msg (void *cls, int result)
143{
144 struct NetJailState *ns = cls;
145
146 GNUNET_assert (NULL != ns->shandle);
147 ns->shandle = NULL;
148 GNUNET_free (ns->msg);
149 ns->msg = NULL;
150}
151
152
153/**
154* Run the "hello world" CMD.
155*
156* @param cls closure.
157* @param cmd CMD being run.
158* @param is interpreter state.
159*/
160static void
161netjail_exec_run (void *cls,
162 const struct GNUNET_TESTING_Command *cmd,
163 struct GNUNET_TESTING_Interpreter *is)
164{
165 struct NetJailState *ns = cls;
166 char **helper_argv;
167 struct GNUNET_TESTBED_HelperInit *msg;
168 struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
169 char *const script_argv[] = {NETJAIL_EXEC_SCRIPT,
170 ns->local_m,
171 "1",
172 "1",
173 NULL};
174 GNUNET_MessageTokenizerCallback cb = ns->cb;
175 GNUNET_HELPER_ExceptionCallback exp_cb = ns->exp_cb;
176
177 if ((GNUNET_YES != GNUNET_DISK_file_test ("test_testbed_api.conf")) ||
178 (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg,
179 "test_testbed_api.conf")))
180 {
181 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
182 _ (
183 "Unreadable or malformed configuration file `%s', exit ...\n"),
184 "test_testbed_api.conf");
185 }
186
187 helper_argv = join_argv ((const char **) script_argv,
188 (const char **) ns->binary_argv);
189
190 ns->helper = GNUNET_HELPER_start (GNUNET_YES,
191 NETJAIL_EXEC_SCRIPT,
192 helper_argv,
193 cb,
194 exp_cb,
195 ns);
196
197 msg = GNUNET_TESTBED_create_helper_init_msg_ ("127.0.0.1", NULL, cfg);
198 ns->msg = &msg->header;
199 ns->shandle = GNUNET_HELPER_send (ns->helper, &msg->header, GNUNET_NO,
200 &clear_msg, ns);
201 if (NULL == ns->shandle)
202 {
203 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
204 "Send handle is NULL!\n");
205 GNUNET_free (msg);
206 }
207}
208
209
210/**
211 * Create command.
212 *
213 * @param label name for command.
214 * @param binaryname to exec.
215 * @return command.
216 */
217struct GNUNET_TESTING_Command
218GNUNET_TESTBED_cmd_netjail_start_testbed (const char *label,
219 char *const binary_argv[],
220 char *local_m,
221 char *global_n,
222 GNUNET_MessageTokenizerCallback cb,
223 GNUNET_HELPER_ExceptionCallback exp_cb)
224{
225 struct NetJailState *ns;
226 unsigned int append_cnt;
227 char **argvj;
228 char *argv;
229 unsigned int carg = 0;
230
231 ns = GNUNET_new (struct NetJailState);
232 argvj = NULL;
233 for (append_cnt = 0; NULL != binary_argv[append_cnt]; append_cnt++)
234 {
235 argv = GNUNET_strdup (binary_argv[append_cnt]);
236 GNUNET_array_append (argvj,
237 carg,
238 argv);
239 }
240 GNUNET_array_append (argvj, carg, NULL);
241
242 ns->binary_argv = argvj;
243
244 ns->local_m = local_m;
245 ns->global_n = global_n;
246 ns->cb = cb;
247 ns->exp_cb = exp_cb;
248
249 struct GNUNET_TESTING_Command cmd = {
250 .cls = ns,
251 .label = label,
252 .run = &netjail_exec_run,
253 .cleanup = &netjail_exec_cleanup,
254 .traits = &netjail_exec_traits
255 };
256
257 return cmd;
258}
diff --git a/src/testbed/testbed_api_cmd_netjail_stop.c b/src/testbed/testbed_api_cmd_netjail_stop.c
new file mode 100644
index 000000000..1e6586f94
--- /dev/null
+++ b/src/testbed/testbed_api_cmd_netjail_stop.c
@@ -0,0 +1,197 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing/testing_api_cmd_hello_world.c
23 * @brief Command to stop the netjail script.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29#include "gnunet_testbed_ng_service.h"
30
31
32#define NETJAIL_STOP_SCRIPT "./netjail_stop.sh"
33
34struct GNUNET_ChildWaitHandle *cwh;
35
36struct NetJailState
37{
38 char *local_m;
39
40 char *global_n;
41
42 /**
43 * The process id of the start script.
44 */
45 struct GNUNET_OS_Process *stop_proc;
46
47 unsigned int finished;
48};
49
50
51/**
52*
53*
54* @param cls closure
55* @param cmd current CMD being cleaned up.
56*/
57static void
58netjail_stop_cleanup (void *cls,
59 const struct GNUNET_TESTING_Command *cmd)
60{
61 struct NetJailState *ns = cls;
62
63 if (NULL != cwh)
64 {
65 GNUNET_wait_child_cancel (cwh);
66 cwh = NULL;
67 }
68 if (NULL != ns->stop_proc)
69 {
70 GNUNET_assert (0 ==
71 GNUNET_OS_process_kill (ns->stop_proc,
72 SIGKILL));
73 GNUNET_assert (GNUNET_OK ==
74 GNUNET_OS_process_wait (ns->stop_proc));
75 GNUNET_OS_process_destroy (ns->stop_proc);
76 ns->stop_proc = NULL;
77 }
78}
79
80
81/**
82*
83*
84* @param cls closure.
85* @param[out] ret result
86* @param trait name of the trait.
87* @param index index number of the object to offer.
88* @return #GNUNET_OK on success.
89*/
90static int
91netjail_stop_traits (void *cls,
92 const void **ret,
93 const char *trait,
94 unsigned int index)
95{
96 return GNUNET_OK;
97}
98
99
100static void
101child_completed_callback (void *cls,
102 enum GNUNET_OS_ProcessStatusType type,
103 long unsigned int exit_code)
104{
105 struct NetJailState *ns = cls;
106
107 cwh = NULL;
108 if (0 == exit_code)
109 {
110 ns->finished = GNUNET_YES;
111 }
112 else
113 {
114 ns->finished = GNUNET_SYSERR;
115 }
116 GNUNET_OS_process_destroy (ns->stop_proc);
117 ns->stop_proc = NULL;
118}
119
120
121/**
122* Run the "hello world" CMD.
123*
124* @param cls closure.
125* @param cmd CMD being run.
126* @param is interpreter state.
127*/
128static void
129netjail_stop_run (void *cls,
130 const struct GNUNET_TESTING_Command *cmd,
131 struct GNUNET_TESTING_Interpreter *is)
132{
133 struct NetJailState *ns = cls;
134 char *const script_argv[] = {NETJAIL_STOP_SCRIPT,
135 ns->local_m,
136 ns->global_n,
137 NULL};
138
139 ns->stop_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
140 NULL,
141 NULL,
142 NULL,
143 NETJAIL_STOP_SCRIPT,
144 script_argv);
145
146 cwh = GNUNET_wait_child (ns->stop_proc,
147 &child_completed_callback,
148 ns);
149 GNUNET_break (NULL != cwh);
150
151}
152
153
154static int
155netjail_stop_finish (void *cls,
156 GNUNET_SCHEDULER_TaskCallback cont,
157 void *cont_cls)
158{
159 struct NetJailState *ns = cls;
160
161 if (ns->finished)
162 {
163 cont (cont_cls);
164 }
165 return ns->finished;
166}
167
168
169/**
170 * Create command.
171 *
172 * @param label name for command.
173 * @param binaryname to stop.
174 * @return command.
175 */
176struct GNUNET_TESTING_Command
177GNUNET_TESTBED_cmd_netjail_stop (const char *label,
178 char *local_m,
179 char *global_n)
180{
181 struct NetJailState *ns;
182
183 ns = GNUNET_new (struct NetJailState);
184 ns->local_m = local_m;
185 ns->global_n = global_n;
186
187 struct GNUNET_TESTING_Command cmd = {
188 .cls = ns,
189 .label = label,
190 .run = &netjail_stop_run,
191 .finish = &netjail_stop_finish,
192 .cleanup = &netjail_stop_cleanup,
193 .traits = &netjail_stop_traits
194 };
195
196 return cmd;
197}