diff options
203 files changed, 11740 insertions, 13688 deletions
@@ -136,7 +136,10 @@ main() | |||
136 | check_libtool | 136 | check_libtool |
137 | fi | 137 | fi |
138 | pogen | 138 | pogen |
139 | install_hooks | 139 | if test -d .git |
140 | then | ||
141 | install_hooks | ||
142 | fi | ||
140 | } | 143 | } |
141 | 144 | ||
142 | main "$@" | 145 | main "$@" |
diff --git a/configure.ac b/configure.ac index 316257f97..0e338c242 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -1235,6 +1235,7 @@ src/lib/gnsrecord/Makefile | |||
1235 | src/lib/json/Makefile | 1235 | src/lib/json/Makefile |
1236 | src/lib/pq/Makefile | 1236 | src/lib/pq/Makefile |
1237 | src/lib/sq/Makefile | 1237 | src/lib/sq/Makefile |
1238 | src/lib/testing/Makefile | ||
1238 | src/plugin/Makefile | 1239 | src/plugin/Makefile |
1239 | src/plugin/block/Makefile | 1240 | src/plugin/block/Makefile |
1240 | src/plugin/datacache/Makefile | 1241 | src/plugin/datacache/Makefile |
@@ -1303,7 +1304,7 @@ src/service/setu/Makefile | |||
1303 | src/service/setu/setu.conf | 1304 | src/service/setu/setu.conf |
1304 | src/service/statistics/Makefile | 1305 | src/service/statistics/Makefile |
1305 | src/service/statistics/statistics.conf | 1306 | src/service/statistics/statistics.conf |
1306 | src/service/testing/Makefile | 1307 | src/service/testbed/Makefile |
1307 | src/service/topology/Makefile | 1308 | src/service/topology/Makefile |
1308 | src/service/transport/Makefile | 1309 | src/service/transport/Makefile |
1309 | src/service/transport/transport.conf | 1310 | src/service/transport/transport.conf |
diff --git a/debian/changelog b/debian/changelog index 2a318e11b..b8b403baf 100644 --- a/debian/changelog +++ b/debian/changelog | |||
@@ -1,3 +1,9 @@ | |||
1 | gnunet (0.21.1-2) unstable; urgency=low | ||
2 | |||
3 | * Package for GNU Taler v0.11.0 release. | ||
4 | |||
5 | -- Christian Grothoff <grothoff@gnu.org> Wed, 15 May 2024 13:50:12 +0100 | ||
6 | |||
1 | gnunet (0.21.1-1) unstable; urgency=low | 7 | gnunet (0.21.1-1) unstable; urgency=low |
2 | 8 | ||
3 | * Package for GNU Taler v0.10.0 release. | 9 | * Package for GNU Taler v0.10.0 release. |
diff --git a/meson.build b/meson.build index 3547d9cfa..16df0524e 100644 --- a/meson.build +++ b/meson.build | |||
@@ -431,6 +431,9 @@ endif | |||
431 | if cc.has_function('explicit_bzero') | 431 | if cc.has_function('explicit_bzero') |
432 | cdata.set('HAVE_EXPLICIT_BZERO', 1) | 432 | cdata.set('HAVE_EXPLICIT_BZERO', 1) |
433 | endif | 433 | endif |
434 | if cc.has_function('getaddrinfo') | ||
435 | cdata.set('HAVE_GETADDRINFO', 1) | ||
436 | endif | ||
434 | if cc.has_function('gethostbyname') | 437 | if cc.has_function('gethostbyname') |
435 | cdata.set('HAVE_GETHOSTBYNAME', 1) | 438 | cdata.set('HAVE_GETHOSTBYNAME', 1) |
436 | endif | 439 | endif |
diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 994d90952..4eb089997 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am | |||
@@ -3,9 +3,9 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/include -I$(top_builddir)/src/include | |||
3 | 3 | ||
4 | dist_pkgdata_DATA = \ | 4 | dist_pkgdata_DATA = \ |
5 | netjail/netjail_core.sh \ | 5 | netjail/netjail_core.sh \ |
6 | netjail/netjail_exec.sh \ | ||
7 | netjail/netjail_start.sh \ | 6 | netjail/netjail_start.sh \ |
8 | netjail/netjail_stop.sh \ | 7 | netjail/netjail_stop.sh \ |
8 | netjail/netjail_test_master.sh \ | ||
9 | netjail/topo.sh \ | 9 | netjail/topo.sh \ |
10 | testing-ng/block.sh | 10 | testing-ng/block.sh |
11 | 11 | ||
@@ -20,11 +20,11 @@ EXTRA_DIST = \ | |||
20 | sphinx_update.sh | 20 | sphinx_update.sh |
21 | 21 | ||
22 | install-data-hook: | 22 | install-data-hook: |
23 | chmod o+x '$(DESTDIR)$(pkgdatadir)/netjail_core.sh' | 23 | chmod +x '$(DESTDIR)$(pkgdatadir)/netjail_core.sh' |
24 | chmod o+x '$(DESTDIR)$(pkgdatadir)/netjail_start.sh' | 24 | chmod +x '$(DESTDIR)$(pkgdatadir)/netjail_start.sh' |
25 | chmod o+x '$(DESTDIR)$(pkgdatadir)/netjail_stop.sh' | 25 | chmod +x '$(DESTDIR)$(pkgdatadir)/netjail_stop.sh' |
26 | chmod o+x '$(DESTDIR)$(pkgdatadir)/netjail_exec.sh' | 26 | chmod +x '$(DESTDIR)$(pkgdatadir)/netjail_test_master.sh' |
27 | chmod o+x '$(DESTDIR)$(pkgdatadir)/topo.sh' | 27 | chmod +x '$(DESTDIR)$(pkgdatadir)/topo.sh' |
28 | chmod o+x '$(DESTDIR)$(pkgdatadir)/block.sh' | 28 | chmod +x '$(DESTDIR)$(pkgdatadir)/block.sh' |
29 | 29 | ||
30 | ## EOF | 30 | ## EOF |
diff --git a/scripts/meson.build b/scripts/meson.build index 1628bfd13..e36a90578 100644 --- a/scripts/meson.build +++ b/scripts/meson.build | |||
@@ -1,6 +1,5 @@ | |||
1 | install_data([ | 1 | install_data([ |
2 | 'netjail'/'netjail_core.sh', | 2 | 'netjail'/'netjail_core.sh', |
3 | 'netjail'/'netjail_exec.sh', | ||
4 | 'netjail'/'netjail_start.sh', | 3 | 'netjail'/'netjail_start.sh', |
5 | 'netjail'/'netjail_stop.sh', | 4 | 'netjail'/'netjail_stop.sh', |
6 | 'netjail'/'topo.sh', | 5 | 'netjail'/'topo.sh', |
@@ -25,4 +24,3 @@ foreach f : binfiles | |||
25 | output : f, | 24 | output : f, |
26 | copy: true) | 25 | copy: true) |
27 | endforeach | 26 | endforeach |
28 | |||
diff --git a/scripts/netjail/netjail_core.sh b/scripts/netjail/netjail_core.sh index b71b51451..8a039cd2f 100755 --- a/scripts/netjail/netjail_core.sh +++ b/scripts/netjail/netjail_core.sh | |||
@@ -52,7 +52,7 @@ netjail_opts() { | |||
52 | local OPT=$1 | 52 | local OPT=$1 |
53 | local DEF=$2 | 53 | local DEF=$2 |
54 | shift 2 | 54 | shift 2 |
55 | 55 | ||
56 | while [ $# -gt 0 ]; do | 56 | while [ $# -gt 0 ]; do |
57 | if [ "$1" = "$OPT" ]; then | 57 | if [ "$1" = "$OPT" ]; then |
58 | printf "$2" | 58 | printf "$2" |
@@ -61,7 +61,7 @@ netjail_opts() { | |||
61 | 61 | ||
62 | shift 1 | 62 | shift 1 |
63 | done | 63 | done |
64 | 64 | ||
65 | RESULT="$DEF" | 65 | RESULT="$DEF" |
66 | } | 66 | } |
67 | 67 | ||
@@ -100,7 +100,7 @@ netjail_bridge() { | |||
100 | 100 | ||
101 | ip link add $BRIDGE type bridge | 101 | ip link add $BRIDGE type bridge |
102 | ip link set dev $BRIDGE up | 102 | ip link set dev $BRIDGE up |
103 | 103 | ||
104 | RESULT=$BRIDGE | 104 | RESULT=$BRIDGE |
105 | } | 105 | } |
106 | 106 | ||
@@ -108,7 +108,7 @@ netjail_bridge_name() { | |||
108 | netjail_next_interface | 108 | netjail_next_interface |
109 | local NUM=$RESULT | 109 | local NUM=$RESULT |
110 | local BRIDGE=$(printf $INTERFACE_FORMAT_STRING $PREPREFIX $PREFIX $NUM) | 110 | local BRIDGE=$(printf $INTERFACE_FORMAT_STRING $PREPREFIX $PREFIX $NUM) |
111 | 111 | ||
112 | RESULT=$BRIDGE | 112 | RESULT=$BRIDGE |
113 | } | 113 | } |
114 | 114 | ||
@@ -124,7 +124,7 @@ netjail_node() { | |||
124 | local NODE=$(printf $INTERFACE_FORMAT_STRING $PREPREFIX $PREFIX $NUM) | 124 | local NODE=$(printf $INTERFACE_FORMAT_STRING $PREPREFIX $PREFIX $NUM) |
125 | 125 | ||
126 | ip netns add $NODE | 126 | ip netns add $NODE |
127 | 127 | ||
128 | RESULT=$NODE | 128 | RESULT=$NODE |
129 | } | 129 | } |
130 | 130 | ||
@@ -132,7 +132,7 @@ netjail_node_name() { | |||
132 | netjail_next_namespace | 132 | netjail_next_namespace |
133 | local NUM=$RESULT | 133 | local NUM=$RESULT |
134 | local NODE=$(printf $INTERFACE_FORMAT_STRING $PREPREFIX $PREFIX $NUM) | 134 | local NODE=$(printf $INTERFACE_FORMAT_STRING $PREPREFIX $PREFIX $NUM) |
135 | 135 | ||
136 | RESULT=$NODE | 136 | RESULT=$NODE |
137 | } | 137 | } |
138 | 138 | ||
@@ -215,21 +215,6 @@ netjail_node_exec() { | |||
215 | ip netns exec $NODE sudo -u $JAILOR -- $@ 1>& $FD_OUT 0<& $FD_IN | 215 | ip netns exec $NODE sudo -u $JAILOR -- $@ 1>& $FD_OUT 0<& $FD_IN |
216 | } | 216 | } |
217 | 217 | ||
218 | netjail_node_exec_without_fds() { | ||
219 | JAILOR=${SUDO_USER:?must run in sudo} | ||
220 | NODE=$1 | ||
221 | shift 1 | ||
222 | |||
223 | ip netns exec $NODE sudo -u $JAILOR -- $@ | ||
224 | } | ||
225 | |||
226 | netjail_node_exec_without_fds_and_sudo() { | ||
227 | NODE=$1 | ||
228 | shift 1 | ||
229 | |||
230 | ip netns exec $NODE $@ | ||
231 | } | ||
232 | |||
233 | netjail_kill() { | 218 | netjail_kill() { |
234 | local PID=$1 | 219 | local PID=$1 |
235 | local MATCH=$(ps --pid $PID | awk "{ if ( \$1 == $PID ) { print \$1 } }" | wc -l) | 220 | local MATCH=$(ps --pid $PID | awk "{ if ( \$1 == $PID ) { print \$1 } }" | wc -l) |
@@ -264,4 +249,3 @@ netjail_waitall() { | |||
264 | done | 249 | done |
265 | fi | 250 | fi |
266 | } | 251 | } |
267 | |||
diff --git a/scripts/netjail/netjail_exec.sh b/scripts/netjail/netjail_exec.sh deleted file mode 100755 index 34edf56bf..000000000 --- a/scripts/netjail/netjail_exec.sh +++ /dev/null | |||
@@ -1,15 +0,0 @@ | |||
1 | #!/bin/bash | ||
2 | . "$(dirname $0)/netjail_core.sh" | ||
3 | |||
4 | set -eu | ||
5 | set -x | ||
6 | |||
7 | export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" | ||
8 | |||
9 | M=$1 | ||
10 | N=$2 | ||
11 | |||
12 | NODE=$6 | ||
13 | |||
14 | #netjail_node_exec_without_fds_and_sudo $NODE valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --trace-children=yes $3 $4 $5 $1 $2 $7 $8 | ||
15 | netjail_node_exec_without_fds_and_sudo $NODE $3 $4 $5 $1 $2 $7 $8 | ||
diff --git a/scripts/netjail/netjail_start.sh b/scripts/netjail/netjail_start.sh index 5e1dd2b1f..1bf9d427a 100755 --- a/scripts/netjail/netjail_start.sh +++ b/scripts/netjail/netjail_start.sh | |||
@@ -8,11 +8,14 @@ set -x | |||
8 | export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" | 8 | export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" |
9 | 9 | ||
10 | filename=$1 | 10 | filename=$1 |
11 | PREFIX=$2 | 11 | PREFIX=$PPID |
12 | readfile=$3 | 12 | readfile=$2 |
13 | 13 | ||
14 | BROADCAST=0 | 14 | BROADCAST=0 |
15 | 15 | ||
16 | # FIXME: We need to test CGNAT. Therefore we have to change the address spaces. | ||
17 | # We have the backbone network with 192.168.1.X/16 for the global reachable CGN routers and 192.168.2.X/16 for global reachable GNUnet nodes. Every CGN router spans a 10.X.0.0 carrier network for the home router subnets resp. mobile devices. With them given adresses like 10.X.Y.0 with Y being the number of those systems. Home router span a subnet 10.X.Y.0 with device getting address like 10.X.Y.Z with Z being the number of those devices. | ||
18 | |||
16 | if [ $readfile -eq 0 ] | 19 | if [ $readfile -eq 0 ] |
17 | then | 20 | then |
18 | read_topology_string "$filename" | 21 | read_topology_string "$filename" |
diff --git a/scripts/netjail/netjail_stop.sh b/scripts/netjail/netjail_stop.sh index 8f6c07f50..c17a4d6ca 100755 --- a/scripts/netjail/netjail_stop.sh +++ b/scripts/netjail/netjail_stop.sh | |||
@@ -8,7 +8,7 @@ set -x | |||
8 | export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" | 8 | export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" |
9 | 9 | ||
10 | filename=$1 | 10 | filename=$1 |
11 | PREFIX=$2 | 11 | PREFIX=$PPID |
12 | readfile=$3 | 12 | readfile=$3 |
13 | 13 | ||
14 | if [ $readfile -eq 0 ] | 14 | if [ $readfile -eq 0 ] |
diff --git a/scripts/netjail/netjail_test_master.sh b/scripts/netjail/netjail_test_master.sh new file mode 100755 index 000000000..9487f3106 --- /dev/null +++ b/scripts/netjail/netjail_test_master.sh | |||
@@ -0,0 +1,18 @@ | |||
1 | #!/bin/bash | ||
2 | if ! [ -d "/run/netns" ]; | ||
3 | then | ||
4 | echo "You have to create the directory '/run/netns'." | ||
5 | exit 77 | ||
6 | fi | ||
7 | if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; | ||
8 | then | ||
9 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" != 1 ]; | ||
10 | then | ||
11 | echo -e "Error during test setup: The kernel parameter 'kernel.unprivileged_userns_clone' has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" | ||
12 | exit 77 | ||
13 | fi | ||
14 | else | ||
15 | echo -e "Error during test setup: The kernel lacks the parameter 'kernel.unprivileged_userns_clone'\n" | ||
16 | exit 77 | ||
17 | fi | ||
18 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; $*" | ||
diff --git a/src/cli/core/gnunet-core.c b/src/cli/core/gnunet-core.c index d351a2f7f..00b08eefc 100644 --- a/src/cli/core/gnunet-core.c +++ b/src/cli/core/gnunet-core.c | |||
@@ -204,14 +204,17 @@ run (void *cls, | |||
204 | if (NULL == mh) | 204 | if (NULL == mh) |
205 | { | 205 | { |
206 | fprintf (stderr, "%s", _ ("Failed to connect to CORE service!\n")); | 206 | fprintf (stderr, "%s", _ ("Failed to connect to CORE service!\n")); |
207 | GNUNET_free (keyfile); | ||
207 | return; | 208 | return; |
208 | } | 209 | } |
209 | } | 210 | } |
210 | if (! show_pid && ! show_conns && ! monitor_connections) | 211 | if (! show_pid && ! show_conns && ! monitor_connections) |
211 | { | 212 | { |
212 | fprintf (stderr, "%s", _ ("No argument given.\n")); | 213 | fprintf (stderr, "%s", _ ("No argument given.\n")); |
214 | GNUNET_free (keyfile); | ||
213 | return; | 215 | return; |
214 | } | 216 | } |
217 | GNUNET_free (keyfile); | ||
215 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); | 218 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); |
216 | } | 219 | } |
217 | 220 | ||
diff --git a/src/cli/dht/gnunet-dht-put.c b/src/cli/dht/gnunet-dht-put.c index 37e7911b5..8f8e098e4 100644 --- a/src/cli/dht/gnunet-dht-put.c +++ b/src/cli/dht/gnunet-dht-put.c | |||
@@ -233,21 +233,22 @@ main (int argc, char *const *argv) | |||
233 | &argc, &argv)) | 233 | &argc, &argv)) |
234 | return 2; | 234 | return 2; |
235 | expiration = GNUNET_TIME_UNIT_HOURS; | 235 | expiration = GNUNET_TIME_UNIT_HOURS; |
236 | return (GNUNET_OK == | 236 | ret = (GNUNET_OK == |
237 | GNUNET_PROGRAM_run ( | 237 | GNUNET_PROGRAM_run ( |
238 | argc, | 238 | argc, |
239 | argv, | 239 | argv, |
240 | "gnunet-dht-put", | 240 | "gnunet-dht-put", |
241 | gettext_noop ( | 241 | gettext_noop ( |
242 | "Issue a PUT request to the GNUnet DHT insert DATA under KEY."), | 242 | "Issue a PUT request to the GNUnet DHT insert DATA under KEY."), |
243 | options, | 243 | options, |
244 | &run, | 244 | &run, |
245 | NULL)) | 245 | NULL)) |
246 | ? ret | 246 | ? ret |
247 | : 1; | 247 | : 1; |
248 | // This is ugly, but meh. The GNUNET_STRINGS_get_utf8_args allows us to do this. | 248 | // This is ugly, but meh. The GNUNET_STRINGS_get_utf8_args allows us to do this. |
249 | u8_argv = (char*) argv; | 249 | u8_argv = (char*) argv; |
250 | GNUNET_free (u8_argv); | 250 | GNUNET_free (u8_argv); |
251 | return ret; | ||
251 | } | 252 | } |
252 | 253 | ||
253 | 254 | ||
diff --git a/src/cli/messenger/gnunet-messenger.c b/src/cli/messenger/gnunet-messenger.c index e3c10d509..6bff0b25d 100644 --- a/src/cli/messenger/gnunet-messenger.c +++ b/src/cli/messenger/gnunet-messenger.c | |||
@@ -23,11 +23,12 @@ | |||
23 | * @brief Print information about messenger groups. | 23 | * @brief Print information about messenger groups. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include "platform.h" | ||
27 | #include <stdio.h> | 26 | #include <stdio.h> |
27 | #include <unistd.h> | ||
28 | 28 | ||
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_identity_service.h" |
30 | #include "gnunet_messenger_service.h" | 30 | #include "gnunet_messenger_service.h" |
31 | #include "gnunet_util_lib.h" | ||
31 | 32 | ||
32 | const struct GNUNET_CONFIGURATION_Handle *config; | 33 | const struct GNUNET_CONFIGURATION_Handle *config; |
33 | struct GNUNET_MESSENGER_Handle *messenger; | 34 | struct GNUNET_MESSENGER_Handle *messenger; |
diff --git a/src/cli/reclaim/gnunet-reclaim.c b/src/cli/reclaim/gnunet-reclaim.c index 901dd6bf6..94bceb8da 100644 --- a/src/cli/reclaim/gnunet-reclaim.c +++ b/src/cli/reclaim/gnunet-reclaim.c | |||
@@ -53,6 +53,11 @@ static int list_credentials; | |||
53 | static char *credential_id; | 53 | static char *credential_id; |
54 | 54 | ||
55 | /** | 55 | /** |
56 | * The expected RP URI | ||
57 | */ | ||
58 | static char *ex_rp_uri; | ||
59 | |||
60 | /** | ||
56 | * Credential ID | 61 | * Credential ID |
57 | */ | 62 | */ |
58 | static struct GNUNET_RECLAIM_Identifier credential; | 63 | static struct GNUNET_RECLAIM_Identifier credential; |
@@ -155,11 +160,6 @@ static struct GNUNET_RECLAIM_TicketIterator *ticket_iterator; | |||
155 | static const struct GNUNET_CRYPTO_PrivateKey *pkey; | 160 | static const struct GNUNET_CRYPTO_PrivateKey *pkey; |
156 | 161 | ||
157 | /** | 162 | /** |
158 | * rp public key | ||
159 | */ | ||
160 | static struct GNUNET_CRYPTO_PublicKey rp_key; | ||
161 | |||
162 | /** | ||
163 | * Ticket to consume | 163 | * Ticket to consume |
164 | */ | 164 | */ |
165 | static struct GNUNET_RECLAIM_Ticket ticket; | 165 | static struct GNUNET_RECLAIM_Ticket ticket; |
@@ -234,17 +234,10 @@ ticket_issue_cb (void *cls, | |||
234 | const struct GNUNET_RECLAIM_Ticket *ticket, | 234 | const struct GNUNET_RECLAIM_Ticket *ticket, |
235 | const struct GNUNET_RECLAIM_PresentationList *presentations) | 235 | const struct GNUNET_RECLAIM_PresentationList *presentations) |
236 | { | 236 | { |
237 | char *ticket_str; | ||
238 | |||
239 | reclaim_op = NULL; | 237 | reclaim_op = NULL; |
240 | if (NULL != ticket) | 238 | if (NULL != ticket) |
241 | { | 239 | { |
242 | ticket_str = | 240 | printf ("%s\n", ticket->gns_name); |
243 | GNUNET_STRINGS_data_to_string_alloc (ticket, | ||
244 | sizeof( | ||
245 | struct GNUNET_RECLAIM_Ticket)); | ||
246 | printf ("%s\n", ticket_str); | ||
247 | GNUNET_free (ticket_str); | ||
248 | } | 241 | } |
249 | cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); | 242 | cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); |
250 | } | 243 | } |
@@ -340,24 +333,9 @@ ticket_iter_fin (void *cls) | |||
340 | 333 | ||
341 | 334 | ||
342 | static void | 335 | static void |
343 | ticket_iter (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) | 336 | ticket_iter (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket, const char* rp_uri) |
344 | { | 337 | { |
345 | char *aud; | 338 | fprintf (stdout, "Ticket: %s | RP URI: %s\n", ticket->gns_name, rp_uri); |
346 | char *ref; | ||
347 | char *tkt; | ||
348 | |||
349 | aud = | ||
350 | GNUNET_STRINGS_data_to_string_alloc (&ticket->audience, | ||
351 | sizeof(struct | ||
352 | GNUNET_CRYPTO_PublicKey)); | ||
353 | ref = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof(ticket->rnd)); | ||
354 | tkt = | ||
355 | GNUNET_STRINGS_data_to_string_alloc (ticket, | ||
356 | sizeof(struct GNUNET_RECLAIM_Ticket)); | ||
357 | fprintf (stdout, "Ticket: %s | ID: %s | Audience: %s\n", tkt, ref, aud); | ||
358 | GNUNET_free (aud); | ||
359 | GNUNET_free (ref); | ||
360 | GNUNET_free (tkt); | ||
361 | GNUNET_RECLAIM_ticket_iteration_next (ticket_iterator); | 339 | GNUNET_RECLAIM_ticket_iteration_next (ticket_iterator); |
362 | } | 340 | } |
363 | 341 | ||
@@ -447,7 +425,6 @@ iter_finished (void *cls) | |||
447 | fprintf (stdout, "No such attribute ``%s''\n", attr_str); | 425 | fprintf (stdout, "No such attribute ``%s''\n", attr_str); |
448 | break; | 426 | break; |
449 | } | 427 | } |
450 | |||
451 | attr_str = strtok (NULL, ","); | 428 | attr_str = strtok (NULL, ","); |
452 | } | 429 | } |
453 | GNUNET_free (attrs_tmp); | 430 | GNUNET_free (attrs_tmp); |
@@ -456,10 +433,15 @@ iter_finished (void *cls) | |||
456 | GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); | 433 | GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); |
457 | return; | 434 | return; |
458 | } | 435 | } |
459 | 436 | if (NULL == ex_rp_uri) | |
437 | { | ||
438 | fprintf (stdout, "No RP URI provided\n"); | ||
439 | GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); | ||
440 | return; | ||
441 | } | ||
460 | reclaim_op = GNUNET_RECLAIM_ticket_issue (reclaim_handle, | 442 | reclaim_op = GNUNET_RECLAIM_ticket_issue (reclaim_handle, |
461 | pkey, | 443 | pkey, |
462 | &rp_key, | 444 | ex_rp_uri, |
463 | attr_list, | 445 | attr_list, |
464 | &ticket_issue_cb, | 446 | &ticket_issue_cb, |
465 | NULL); | 447 | NULL); |
@@ -467,9 +449,15 @@ iter_finished (void *cls) | |||
467 | } | 449 | } |
468 | if (consume_ticket) | 450 | if (consume_ticket) |
469 | { | 451 | { |
452 | if (NULL == ex_rp_uri) | ||
453 | { | ||
454 | fprintf (stderr, "Expected an RP URI to consume ticket\n"); | ||
455 | GNUNET_SCHEDULER_add_now(&do_cleanup, NULL); | ||
456 | return; | ||
457 | } | ||
470 | reclaim_op = GNUNET_RECLAIM_ticket_consume (reclaim_handle, | 458 | reclaim_op = GNUNET_RECLAIM_ticket_consume (reclaim_handle, |
471 | pkey, | ||
472 | &ticket, | 459 | &ticket, |
460 | ex_rp_uri, | ||
473 | &process_attrs, | 461 | &process_attrs, |
474 | NULL); | 462 | NULL); |
475 | timeout = GNUNET_SCHEDULER_add_delayed ( | 463 | timeout = GNUNET_SCHEDULER_add_delayed ( |
@@ -767,19 +755,8 @@ start_process () | |||
767 | return; | 755 | return; |
768 | } | 756 | } |
769 | 757 | ||
770 | if ((NULL != rp) && | ||
771 | (GNUNET_OK != | ||
772 | GNUNET_CRYPTO_public_key_from_string (rp, &rp_key)) ) | ||
773 | { | ||
774 | fprintf (stderr, "%s is not a public key!\n", rp); | ||
775 | cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); | ||
776 | return; | ||
777 | } | ||
778 | if (NULL != consume_ticket) | 758 | if (NULL != consume_ticket) |
779 | GNUNET_STRINGS_string_to_data (consume_ticket, | 759 | memcpy (ticket.gns_name, consume_ticket, strlen (consume_ticket) + 1); |
780 | strlen (consume_ticket), | ||
781 | &ticket, | ||
782 | sizeof(struct GNUNET_RECLAIM_Ticket)); | ||
783 | if (NULL != revoke_ticket) | 760 | if (NULL != revoke_ticket) |
784 | GNUNET_STRINGS_string_to_data (revoke_ticket, | 761 | GNUNET_STRINGS_string_to_data (revoke_ticket, |
785 | strlen (revoke_ticket), | 762 | strlen (revoke_ticket), |
@@ -865,7 +842,8 @@ main (int argc, char *const argv[]) | |||
865 | GNUNET_GETOPT_option_string ('a', | 842 | GNUNET_GETOPT_option_string ('a', |
866 | "add", | 843 | "add", |
867 | "NAME", | 844 | "NAME", |
868 | gettext_noop ("Add or update an attribute NAME"), | 845 | gettext_noop ( |
846 | "Add or update an attribute NAME"), | ||
869 | &attr_name), | 847 | &attr_name), |
870 | GNUNET_GETOPT_option_string ('d', | 848 | GNUNET_GETOPT_option_string ('d', |
871 | "delete", | 849 | "delete", |
@@ -888,6 +866,12 @@ main (int argc, char *const argv[]) | |||
888 | gettext_noop ( | 866 | gettext_noop ( |
889 | "Specify the relying party for issue"), | 867 | "Specify the relying party for issue"), |
890 | &rp), | 868 | &rp), |
869 | GNUNET_GETOPT_option_string ('U', | ||
870 | "rpuri", | ||
871 | "RPURI", | ||
872 | gettext_noop ( | ||
873 | "Specify the relying party URI for a ticket to consume"), | ||
874 | &ex_rp_uri), | ||
891 | GNUNET_GETOPT_option_flag ('D', | 875 | GNUNET_GETOPT_option_flag ('D', |
892 | "dump", | 876 | "dump", |
893 | gettext_noop ("List attributes for EGO"), | 877 | gettext_noop ("List attributes for EGO"), |
diff --git a/src/cli/reclaim/test_reclaim.conf b/src/cli/reclaim/test_reclaim.conf index faa195ae1..a8d2c808a 100644 --- a/src/cli/reclaim/test_reclaim.conf +++ b/src/cli/reclaim/test_reclaim.conf | |||
@@ -8,7 +8,8 @@ START_ON_DEMAND = YES | |||
8 | 8 | ||
9 | [rest] | 9 | [rest] |
10 | START_ON_DEMAND = YES | 10 | START_ON_DEMAND = YES |
11 | PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=$GNUNET_TMP/restlog | 11 | # PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=$GNUNET_TMP/restlog |
12 | BASIC_AUTH_ENABLED = NO | ||
12 | 13 | ||
13 | [transport] | 14 | [transport] |
14 | PLUGINS = | 15 | PLUGINS = |
@@ -18,6 +19,7 @@ START_ON_DEMAND = YES | |||
18 | IMMEDIATE_START = YES | 19 | IMMEDIATE_START = YES |
19 | 20 | ||
20 | [reclaim] | 21 | [reclaim] |
22 | IMMEDIATE_START = YES | ||
21 | START_ON_DEMAND = YES | 23 | START_ON_DEMAND = YES |
22 | TICKET_REFRESH_INTERVAL = 1 h | 24 | TICKET_REFRESH_INTERVAL = 1 h |
23 | #PREFIX = valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --log-file=$GNUNET_TMP/idplog | 25 | #PREFIX = valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --log-file=$GNUNET_TMP/idplog |
@@ -33,6 +35,10 @@ ZONE_PUBLISH_TIME_WINDOW = 1 h | |||
33 | DNS_ROOT=PD67SGHF3E0447TU9HADIVU9OM7V4QHTOG0EBU69TFRI2LG63DR0 | 35 | DNS_ROOT=PD67SGHF3E0447TU9HADIVU9OM7V4QHTOG0EBU69TFRI2LG63DR0 |
34 | 36 | ||
35 | [reclaim-rest-plugin] | 37 | [reclaim-rest-plugin] |
36 | address = http://localhost:8000/#/login | ||
37 | psw = mysupersecretpassword | ||
38 | expiration_time = 3600 | 38 | expiration_time = 3600 |
39 | JWT_SECRET = secret | ||
40 | OIDC_USERINFO_CONSUME_TIMEOUT = 5s | ||
41 | OIDC_DIR = $GNUNET_DATA_HOME/oidc | ||
42 | OIDC_CLIENT_HMAC_SECRET = secret | ||
43 | OIDC_JSON_WEB_ALGORITHM = RS256 | ||
44 | ADDRESS = https://ui.reclaim/#/login | ||
diff --git a/src/cli/reclaim/test_reclaim_consume.sh b/src/cli/reclaim/test_reclaim_consume.sh index 8a88136c6..00076fbf8 100755 --- a/src/cli/reclaim/test_reclaim_consume.sh +++ b/src/cli/reclaim/test_reclaim_consume.sh | |||
@@ -32,11 +32,13 @@ SUBJECT_KEY=$(gnunet-identity -d -e rpego -q -c test_reclaim.conf) | |||
32 | TEST_KEY=$(gnunet-identity -d -e testego -q -c test_reclaim.conf) | 32 | TEST_KEY=$(gnunet-identity -d -e testego -q -c test_reclaim.conf) |
33 | gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf | 33 | gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf |
34 | gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf | 34 | gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf |
35 | TICKET=$(gnunet-reclaim -e testego -i "email,name" -r $SUBJECT_KEY -c test_reclaim.conf | awk '{print $1}') | 35 | TICKET=$(gnunet-reclaim -e testego -U "urn:gns:$TEST_KEY" -i "email,name" -r $SUBJECT_KEY -c test_reclaim.conf | awk '{print $1}') |
36 | echo "Ticket: $TICKET" | ||
37 | gnunet-gns -u $TICKET -c test_reclaim.conf | ||
36 | gnunet-namestore -z testego -D -c test_reclaim.conf | 38 | gnunet-namestore -z testego -D -c test_reclaim.conf |
37 | gnunet-identity -d -c test_reclaim.conf | 39 | gnunet-identity -d -c test_reclaim.conf |
38 | sleep 1 | 40 | sleep 1 |
39 | gnunet-reclaim -e rpego -C $TICKET -c test_reclaim.conf | 41 | gnunet-reclaim -e rpego -U "urn:gns:$TEST_KEY" -C $TICKET -c test_reclaim.conf |
40 | 42 | ||
41 | RES=$? | 43 | RES=$? |
42 | gnunet-identity -D testego -c test_reclaim.conf | 44 | gnunet-identity -D testego -c test_reclaim.conf |
diff --git a/src/cli/reclaim/test_reclaim_issue.sh b/src/cli/reclaim/test_reclaim_issue.sh index 63140e54c..39e614d19 100755 --- a/src/cli/reclaim/test_reclaim_issue.sh +++ b/src/cli/reclaim/test_reclaim_issue.sh | |||
@@ -32,7 +32,7 @@ TEST_KEY=$(gnunet-identity -d -e testego -q -c test_reclaim.conf) | |||
32 | gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf | 32 | gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf |
33 | gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf | 33 | gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf |
34 | #gnunet-reclaim -e testego -D -c test_reclaim.conf | 34 | #gnunet-reclaim -e testego -D -c test_reclaim.conf |
35 | gnunet-reclaim -e testego -i "email,name" -r $SUBJECT_KEY -c test_reclaim.conf > /dev/null 2>&1 | 35 | gnunet-reclaim -e testego -u "urn:gns:$TEST_KEY" -i "email,name" -r $SUBJECT_KEY -c test_reclaim.conf > /dev/null 2>&1 |
36 | if test $? != 0 | 36 | if test $? != 0 |
37 | then | 37 | then |
38 | echo "Failed." | 38 | echo "Failed." |
diff --git a/src/cli/reclaim/test_reclaim_oidc.sh b/src/cli/reclaim/test_reclaim_oidc.sh new file mode 100755 index 000000000..cdea61a03 --- /dev/null +++ b/src/cli/reclaim/test_reclaim_oidc.sh | |||
@@ -0,0 +1,57 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_reclaim.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1>/dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_reclaim.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | which timeout >/dev/null 2>&1 && DO_TIMEOUT="timeout 30" | ||
19 | |||
20 | RES=0 | ||
21 | TEST_ATTR="test" | ||
22 | REDIRECT_URI="https://example.gns.alt/my_cb" | ||
23 | SCOPE="\"openid email name\"" | ||
24 | gnunet-arm -s -c test_reclaim.conf | ||
25 | gnunet-arm -i rest -c test_reclaim.conf | ||
26 | gnunet-arm -I | ||
27 | gnunet-identity -C testego -c test_reclaim.conf | ||
28 | gnunet-identity -C rpego -c test_reclaim.conf | ||
29 | TEST_KEY=$(gnunet-identity -d -e rpego -q -c test_reclaim.conf) | ||
30 | SUBJECT_KEY=$(gnunet-identity -d -e testego -q -c test_reclaim.conf) | ||
31 | gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf | ||
32 | gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf | ||
33 | |||
34 | # Register client | ||
35 | gnunet-namestore -z rpego -a -n @ -t RECLAIM_OIDC_CLIENT -V "My RP" -e 1d -p -c test_reclaim.conf | ||
36 | gnunet-namestore -z rpego -a -n @ -t RECLAIM_OIDC_REDIRECT -V $REDIRECT_URI -e 1d -p -c test_reclaim.conf | ||
37 | |||
38 | gnunet-gns -u @.$TEST_KEY -t RECLAIM_OIDC_REDIRECT -c test_reclaim.conf | ||
39 | curl -v -X POST -H -v "http://localhost:7776/openid/login" --data "{\"identity\": \"$SUBJECT_KEY\"}" | ||
40 | |||
41 | PKCE_CHALLENGE=$(echo -n secret | openssl dgst -binary -sha256 | openssl base64 | sed 's/\=//g' | sed 's/+/-/g' | sed 's/\//_/g') | ||
42 | |||
43 | CODE=$(curl -H "Cookie: Identity=$SUBJECT_KEY" "http://localhost:7776/openid/authorize?client_id=$TEST_KEY&response_type=code&redirect_uri=$REDIRECT_URI&scope=openid&claims=%7B%22userinfo%22%3A%20%7B%22email%22%3A%20%7B%22essential%22%20%20%20%20%3A%20true%7D%7D%2C%22id_token%22%3A%20%7B%22email%22%3A%20%7B%22essential%22%3A%20true%7D%7D%7D&state=xyz&code_challenge=$PKCE_CHALLENGE&code_challenge_method=S256" \ | ||
44 | -sS -D - -o /dev/null | grep "Location: " | cut -d" " -f2 | cut -d"?" -f2 | cut -d"&" -f1 | cut -d"=" -f2) | ||
45 | |||
46 | echo "Code: $CODE" | ||
47 | |||
48 | curl -v -X POST -u$TEST_KEY:"secret" "http://localhost:7776/openid/token?client_id=$TEST_KEY&response_type=code&redirect_uri=$REDIRECT_URI&scope=openid&claims=%7B%22userinfo%22%3A%20%7B%22email%22%3A%20%7B%22essential%22%20%20%20%20%3A%20true%7D%7D%2C%22id_token%22%3A%20%7B%22email%22%3A%20%7B%22essential%22%3A%20true%7D%7D%7D&state=xyz&grant_type=authorization_code&code=$CODE&code_verifier=secret" | ||
49 | |||
50 | gnunet-identity -D testego -c test_reclaim.conf | ||
51 | gnunet-identity -D rpego -c test_reclaim.conf | ||
52 | gnunet-arm -e -c test_reclaim.conf | ||
53 | if test $RES != 0 | ||
54 | then | ||
55 | echo "Failed." | ||
56 | fi | ||
57 | |||
diff --git a/src/cli/util/gnunet-config.c b/src/cli/util/gnunet-config.c index 714c683dd..979f0b3f4 100644 --- a/src/cli/util/gnunet-config.c +++ b/src/cli/util/gnunet-config.c | |||
@@ -35,7 +35,6 @@ | |||
35 | */ | 35 | */ |
36 | static char *backend_check; | 36 | static char *backend_check; |
37 | 37 | ||
38 | |||
39 | /** | 38 | /** |
40 | * If printing the value of CFLAGS has been requested. | 39 | * If printing the value of CFLAGS has been requested. |
41 | */ | 40 | */ |
@@ -46,13 +45,21 @@ static int cflags; | |||
46 | */ | 45 | */ |
47 | static int is_experimental; | 46 | static int is_experimental; |
48 | 47 | ||
48 | /** | ||
49 | * Do not load default configuration | ||
50 | */ | ||
51 | static int no_defaults; | ||
52 | |||
53 | /** | ||
54 | * Parse configuration from this memory. | ||
55 | */ | ||
56 | static char *ram_config; | ||
49 | 57 | ||
50 | /** | 58 | /** |
51 | * If printing the value of LIBS has been requested. | 59 | * If printing the value of LIBS has been requested. |
52 | */ | 60 | */ |
53 | static int libs; | 61 | static int libs; |
54 | 62 | ||
55 | |||
56 | /** | 63 | /** |
57 | * If printing the value of PREFIX has been requested. | 64 | * If printing the value of PREFIX has been requested. |
58 | */ | 65 | */ |
@@ -60,76 +67,6 @@ static int prefix; | |||
60 | 67 | ||
61 | 68 | ||
62 | /** | 69 | /** |
63 | * Print each option in a given section. | ||
64 | * Main task to run to perform operations typical for | ||
65 | * gnunet-config as per the configuration settings | ||
66 | * given in @a cls. | ||
67 | * | ||
68 | * @param cls closure with the `struct GNUNET_CONFIGURATION_ConfigSettings` | ||
69 | * @param args remaining command-line arguments | ||
70 | * @param cfgfile name of the configuration file used (for saving, | ||
71 | * can be NULL!) | ||
72 | * @param cfg configuration | ||
73 | */ | ||
74 | static void | ||
75 | run (void *cls, | ||
76 | char *const *args, | ||
77 | const char *cfgfile, | ||
78 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
79 | { | ||
80 | struct GNUNET_CONFIGURATION_ConfigSettings *cs = cls; | ||
81 | |||
82 | if (1 == is_experimental) | ||
83 | { | ||
84 | #ifdef GNUNET_EXPERIMENTAL | ||
85 | cs->global_ret = 0; | ||
86 | #else | ||
87 | cs->global_ret = 1; | ||
88 | #endif | ||
89 | return; | ||
90 | } | ||
91 | if (1 == cflags || 1 == libs || 1 == prefix) | ||
92 | { | ||
93 | char *prefixdir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_PREFIX); | ||
94 | char *libdir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR); | ||
95 | |||
96 | if (1 == cflags) | ||
97 | { | ||
98 | fprintf (stdout, "-I%sinclude\n", prefixdir); | ||
99 | } | ||
100 | if (1 == libs) | ||
101 | { | ||
102 | fprintf (stdout, "-L%s -lgnunetutil\n", libdir); | ||
103 | } | ||
104 | if (1 == prefix) | ||
105 | { | ||
106 | fprintf (stdout, "%s\n", prefixdir); | ||
107 | } | ||
108 | cs->global_ret = 0; | ||
109 | GNUNET_free (prefixdir); | ||
110 | GNUNET_free (libdir); | ||
111 | return; | ||
112 | } | ||
113 | if (NULL != backend_check) | ||
114 | { | ||
115 | char *name; | ||
116 | |||
117 | GNUNET_asprintf (&name, | ||
118 | "libgnunet_plugin_%s", | ||
119 | backend_check); | ||
120 | cs->global_ret = (GNUNET_OK == | ||
121 | GNUNET_PLUGIN_test (name)) ? 0 : 77; | ||
122 | GNUNET_free (name); | ||
123 | return; | ||
124 | } | ||
125 | GNUNET_CONFIGURATION_config_tool_run (cs, | ||
126 | args, | ||
127 | cfgfile, | ||
128 | cfg); | ||
129 | } | ||
130 | |||
131 | |||
132 | /** | ||
133 | * Program to manipulate configuration files. | 70 | * Program to manipulate configuration files. |
134 | * | 71 | * |
135 | * @param argc number of arguments from the command line | 72 | * @param argc number of arguments from the command line |
@@ -144,7 +81,17 @@ main (int argc, | |||
144 | .api_version = GNUNET_UTIL_VERSION, | 81 | .api_version = GNUNET_UTIL_VERSION, |
145 | .global_ret = EXIT_SUCCESS | 82 | .global_ret = EXIT_SUCCESS |
146 | }; | 83 | }; |
84 | const struct GNUNET_OS_ProjectData *pd | ||
85 | = GNUNET_OS_project_data_get (); | ||
86 | char *cfgfile = NULL; | ||
87 | char *loglev = NULL; | ||
88 | char *logfile = NULL; | ||
147 | struct GNUNET_GETOPT_CommandLineOption options[] = { | 89 | struct GNUNET_GETOPT_CommandLineOption options[] = { |
90 | GNUNET_GETOPT_option_cfgfile (&cfgfile), | ||
91 | GNUNET_GETOPT_option_help ("gnunet-config [OPTIONS]"), | ||
92 | GNUNET_GETOPT_option_loglevel (&loglev), | ||
93 | GNUNET_GETOPT_option_logfile (&logfile), | ||
94 | GNUNET_GETOPT_option_version (pd->version), | ||
148 | GNUNET_GETOPT_option_exclusive ( | 95 | GNUNET_GETOPT_option_exclusive ( |
149 | GNUNET_GETOPT_option_string ( | 96 | GNUNET_GETOPT_option_string ( |
150 | 'b', | 97 | 'b', |
@@ -171,34 +118,163 @@ main (int argc, | |||
171 | "Provide an appropriate value for LIBS to applications building on top of GNUnet"), | 118 | "Provide an appropriate value for LIBS to applications building on top of GNUnet"), |
172 | &libs), | 119 | &libs), |
173 | GNUNET_GETOPT_option_flag ( | 120 | GNUNET_GETOPT_option_flag ( |
121 | 'n', | ||
122 | "no-defaults", | ||
123 | gettext_noop ("Do not parse default configuration files"), | ||
124 | &no_defaults), | ||
125 | GNUNET_GETOPT_option_flag ( | ||
174 | 'p', | 126 | 'p', |
175 | "prefix", | 127 | "prefix", |
176 | gettext_noop ( | 128 | gettext_noop ( |
177 | "Provide the path under which GNUnet was installed"), | 129 | "Provide the path under which GNUnet was installed"), |
178 | &prefix), | 130 | &prefix), |
131 | GNUNET_GETOPT_option_string ( | ||
132 | 'R', | ||
133 | "ram-config", | ||
134 | "CONFIG_DATA", | ||
135 | gettext_noop ( | ||
136 | "Parse main configuration from this command-line argument and not from disk"), | ||
137 | &ram_config), | ||
179 | GNUNET_CONFIGURATION_CONFIG_OPTIONS (&cs), | 138 | GNUNET_CONFIGURATION_CONFIG_OPTIONS (&cs), |
180 | GNUNET_GETOPT_OPTION_END | 139 | GNUNET_GETOPT_OPTION_END |
181 | }; | 140 | }; |
182 | enum GNUNET_GenericReturnValue ret; | 141 | int iret; |
183 | 142 | ||
184 | if (GNUNET_OK != | 143 | if (GNUNET_OK != |
185 | GNUNET_STRINGS_get_utf8_args (argc, argv, | 144 | GNUNET_STRINGS_get_utf8_args (argc, argv, |
186 | &argc, &argv)) | 145 | &argc, &argv)) |
187 | return EXIT_FAILURE; | 146 | return EXIT_FAILURE; |
188 | ret = | 147 | if ( (NULL != pd->config_file) && |
189 | GNUNET_PROGRAM_run (argc, | 148 | (NULL != pd->user_config_file) ) |
190 | argv, | 149 | cfgfile = GNUNET_CONFIGURATION_default_filename (); |
191 | "gnunet-config [OPTIONS]", | 150 | iret = GNUNET_GETOPT_run ("gnunet-config", |
192 | gettext_noop ("Manipulate GNUnet configuration files"), | 151 | options, |
193 | options, | 152 | argc, |
194 | &run, | 153 | argv); |
195 | &cs); | 154 | if (GNUNET_SYSERR == iret) |
196 | GNUNET_free_nz ((void *) argv); | 155 | { |
197 | GNUNET_CONFIGURATION_config_settings_free (&cs); | 156 | GNUNET_free_nz ((void *) argv); |
198 | if (GNUNET_NO == ret) | ||
199 | return 0; | ||
200 | if (GNUNET_SYSERR == ret) | ||
201 | return EXIT_INVALIDARGUMENT; | 157 | return EXIT_INVALIDARGUMENT; |
158 | } | ||
159 | if (GNUNET_OK != | ||
160 | GNUNET_log_setup ("gnunet-config", | ||
161 | loglev, | ||
162 | logfile)) | ||
163 | { | ||
164 | GNUNET_free_nz ((void *) argv); | ||
165 | return EXIT_FAILURE; | ||
166 | } | ||
167 | if (1 == is_experimental) | ||
168 | { | ||
169 | GNUNET_free_nz ((void *) argv); | ||
170 | #ifdef GNUNET_EXPERIMENTAL | ||
171 | return 0; | ||
172 | #else | ||
173 | return 1; | ||
174 | #endif | ||
175 | } | ||
176 | if (1 == cflags || 1 == libs || 1 == prefix) | ||
177 | { | ||
178 | char *prefixdir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_PREFIX); | ||
179 | char *libdir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR); | ||
180 | |||
181 | if (1 == cflags) | ||
182 | { | ||
183 | fprintf (stdout, "-I%sinclude\n", prefixdir); | ||
184 | } | ||
185 | if (1 == libs) | ||
186 | { | ||
187 | fprintf (stdout, "-L%s -lgnunetutil\n", libdir); | ||
188 | } | ||
189 | if (1 == prefix) | ||
190 | { | ||
191 | fprintf (stdout, "%s\n", prefixdir); | ||
192 | } | ||
193 | GNUNET_free (prefixdir); | ||
194 | GNUNET_free (libdir); | ||
195 | GNUNET_free_nz ((void *) argv); | ||
196 | return 0; | ||
197 | } | ||
198 | if (NULL != backend_check) | ||
199 | { | ||
200 | char *name; | ||
201 | |||
202 | GNUNET_asprintf (&name, | ||
203 | "libgnunet_plugin_%s", | ||
204 | backend_check); | ||
205 | iret = (GNUNET_OK == | ||
206 | GNUNET_PLUGIN_test (name)) ? 0 : 77; | ||
207 | GNUNET_free (name); | ||
208 | GNUNET_free_nz ((void *) argv); | ||
209 | return iret; | ||
210 | } | ||
211 | |||
212 | { | ||
213 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
214 | |||
215 | cfg = GNUNET_CONFIGURATION_create (); | ||
216 | |||
217 | if (NULL != ram_config) | ||
218 | { | ||
219 | if ( (! no_defaults) && | ||
220 | (GNUNET_SYSERR == | ||
221 | GNUNET_CONFIGURATION_load (cfg, | ||
222 | NULL)) ) | ||
223 | { | ||
224 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
225 | _ ("Failed to load default configuration, exiting ...\n")); | ||
226 | GNUNET_free_nz ((void *) argv); | ||
227 | GNUNET_CONFIGURATION_destroy (cfg); | ||
228 | return EXIT_FAILURE; | ||
229 | } | ||
230 | if (GNUNET_OK != | ||
231 | GNUNET_CONFIGURATION_deserialize (cfg, | ||
232 | ram_config, | ||
233 | strlen (ram_config), | ||
234 | NULL)) | ||
235 | { | ||
236 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
237 | _ ("Failed to parse configuration, exiting ...\n")); | ||
238 | GNUNET_free_nz ((void *) argv); | ||
239 | GNUNET_CONFIGURATION_destroy (cfg); | ||
240 | return EXIT_FAILURE; | ||
241 | } | ||
242 | } | ||
243 | else | ||
244 | { | ||
245 | if (GNUNET_YES != | ||
246 | GNUNET_DISK_file_test (cfgfile)) | ||
247 | { | ||
248 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
249 | _ ("Unreadable configuration file `%s', exiting ...\n"), | ||
250 | cfgfile); | ||
251 | GNUNET_free_nz ((void *) argv); | ||
252 | GNUNET_CONFIGURATION_destroy (cfg); | ||
253 | return EXIT_FAILURE; | ||
254 | } | ||
255 | if (GNUNET_SYSERR == | ||
256 | (no_defaults | ||
257 | ? GNUNET_CONFIGURATION_parse (cfg, | ||
258 | cfgfile) | ||
259 | : GNUNET_CONFIGURATION_load (cfg, | ||
260 | cfgfile)) ) | ||
261 | { | ||
262 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
263 | _ ("Malformed configuration file `%s', exiting ...\n"), | ||
264 | cfgfile); | ||
265 | GNUNET_free_nz ((void *) argv); | ||
266 | GNUNET_CONFIGURATION_destroy (cfg); | ||
267 | return EXIT_FAILURE; | ||
268 | } | ||
269 | } | ||
270 | GNUNET_CONFIGURATION_config_tool_run (&cs, | ||
271 | &argv[iret], | ||
272 | cfgfile, | ||
273 | cfg); | ||
274 | GNUNET_free_nz ((void *) argv); | ||
275 | GNUNET_CONFIGURATION_config_settings_free (&cs); | ||
276 | GNUNET_CONFIGURATION_destroy (cfg); | ||
277 | } | ||
202 | return cs.global_ret; | 278 | return cs.global_ret; |
203 | } | 279 | } |
204 | 280 | ||
diff --git a/src/cli/util/gnunet-ecc.c b/src/cli/util/gnunet-ecc.c index 812745085..9a9fc17e4 100644 --- a/src/cli/util/gnunet-ecc.c +++ b/src/cli/util/gnunet-ecc.c | |||
@@ -168,10 +168,10 @@ create_keys (const char *fn, const char *prefix) | |||
168 | } | 168 | } |
169 | } | 169 | } |
170 | } | 170 | } |
171 | if (GNUNET_TESTING_HOSTKEYFILESIZE != | 171 | if (sizeof (struct GNUNET_PeerIdentity) != |
172 | fwrite (&pk, | 172 | fwrite (&pk, |
173 | 1, | 173 | 1, |
174 | GNUNET_TESTING_HOSTKEYFILESIZE, | 174 | sizeof (struct GNUNET_PeerIdentity), |
175 | f)) | 175 | f)) |
176 | { | 176 | { |
177 | fprintf (stderr, | 177 | fprintf (stderr, |
@@ -307,16 +307,22 @@ print_key (const char *filename) | |||
307 | 307 | ||
308 | /* Check hostkey file size, read entire thing into memory */ | 308 | /* Check hostkey file size, read entire thing into memory */ |
309 | if (GNUNET_OK != | 309 | if (GNUNET_OK != |
310 | GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) | 310 | GNUNET_DISK_file_size (filename, |
311 | &fs, | ||
312 | GNUNET_YES, | ||
313 | GNUNET_YES)) | ||
311 | fs = 0; | 314 | fs = 0; |
312 | if (0 == fs) | 315 | if (0 == fs) |
313 | { | 316 | { |
314 | fprintf (stderr, _ ("Hostkeys file `%s' is empty\n"), filename); | 317 | fprintf (stderr, |
318 | _ ("Hostkeys file `%s' is empty\n"), filename); | ||
315 | return; /* File is empty */ | 319 | return; /* File is empty */ |
316 | } | 320 | } |
317 | if (0 != (fs % GNUNET_TESTING_HOSTKEYFILESIZE)) | 321 | if (0 != (fs % sizeof (struct GNUNET_PeerIdentity))) |
318 | { | 322 | { |
319 | fprintf (stderr, _ ("Incorrect hostkey file format: %s\n"), filename); | 323 | fprintf (stderr, |
324 | _ ("Incorrect hostkey file format: %s\n"), | ||
325 | filename); | ||
320 | return; | 326 | return; |
321 | } | 327 | } |
322 | fd = GNUNET_DISK_file_open (filename, | 328 | fd = GNUNET_DISK_file_open (filename, |
@@ -340,12 +346,12 @@ print_key (const char *filename) | |||
340 | 346 | ||
341 | if (NULL == hostkeys_data) | 347 | if (NULL == hostkeys_data) |
342 | return; | 348 | return; |
343 | total_hostkeys = fs / GNUNET_TESTING_HOSTKEYFILESIZE; | 349 | total_hostkeys = fs / sizeof (struct GNUNET_PeerIdentity); |
344 | for (c = 0; (c < total_hostkeys) && (c < list_keys_count); c++) | 350 | for (c = 0; (c < total_hostkeys) && (c < list_keys_count); c++) |
345 | { | 351 | { |
346 | GNUNET_memcpy (&private_key, | 352 | GNUNET_memcpy (&private_key, |
347 | hostkeys_data + (c * GNUNET_TESTING_HOSTKEYFILESIZE), | 353 | hostkeys_data + (c * sizeof (struct GNUNET_PeerIdentity)), |
348 | GNUNET_TESTING_HOSTKEYFILESIZE); | 354 | sizeof (struct GNUNET_PeerIdentity)); |
349 | GNUNET_CRYPTO_eddsa_key_get_public (&private_key, &public_key); | 355 | GNUNET_CRYPTO_eddsa_key_get_public (&private_key, &public_key); |
350 | hostkey_str = GNUNET_CRYPTO_eddsa_public_key_to_string (&public_key); | 356 | hostkey_str = GNUNET_CRYPTO_eddsa_public_key_to_string (&public_key); |
351 | if (NULL != hostkey_str) | 357 | if (NULL != hostkey_str) |
diff --git a/src/include/Makefile.am b/src/include/Makefile.am index 8f39faab6..6942d2d0e 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am | |||
@@ -33,7 +33,6 @@ gnunetinclude_HEADERS = \ | |||
33 | gnunet_container_lib.h \ | 33 | gnunet_container_lib.h \ |
34 | gnunet_conversation_service.h \ | 34 | gnunet_conversation_service.h \ |
35 | gnunet_core_service.h \ | 35 | gnunet_core_service.h \ |
36 | gnunet_core_testing_lib.h \ | ||
37 | gnunet_crypto_lib.h \ | 36 | gnunet_crypto_lib.h \ |
38 | gnunet_curl_lib.h \ | 37 | gnunet_curl_lib.h \ |
39 | gnunet_datacache_lib.h \ | 38 | gnunet_datacache_lib.h \ |
@@ -110,18 +109,17 @@ gnunetinclude_HEADERS = \ | |||
110 | gnunet_sq_lib.h \ | 109 | gnunet_sq_lib.h \ |
111 | gnunet_statistics_service.h \ | 110 | gnunet_statistics_service.h \ |
112 | gnunet_strings_lib.h \ | 111 | gnunet_strings_lib.h \ |
113 | gnunet_testing_barrier.h \ | ||
114 | gnunet_testing_lib.h \ | 112 | gnunet_testing_lib.h \ |
115 | gnunet_testing_plugin.h \ | 113 | gnunet_testing_arm_lib.h \ |
116 | gnunet_testing_ng_lib.h \ | 114 | gnunet_testing_core_lib.h \ |
117 | gnunet_testing_loop_lib.h \ | 115 | gnunet_testing_testbed_lib.h \ |
118 | gnunet_testing_netjail_lib.h \ | 116 | gnunet_testing_transport_lib.h \ |
117 | gnunet_testbed_lib.h \ | ||
119 | gnunet_time_lib.h \ | 118 | gnunet_time_lib.h \ |
120 | gnunet_transport_application_service.h \ | 119 | gnunet_transport_application_service.h \ |
121 | gnunet_transport_communication_service.h \ | 120 | gnunet_transport_communication_service.h \ |
122 | gnunet_transport_monitor_service.h \ | 121 | gnunet_transport_monitor_service.h \ |
123 | gnunet_transport_core_service.h \ | 122 | gnunet_transport_core_service.h \ |
124 | gnunet_transport_testing_ng_lib.h \ | ||
125 | gnunet_tun_lib.h \ | 123 | gnunet_tun_lib.h \ |
126 | gnunet_uri_lib.h \ | 124 | gnunet_uri_lib.h \ |
127 | gnunet_util_lib.h \ | 125 | gnunet_util_lib.h \ |
diff --git a/src/include/gnunet_arm_service.h b/src/include/gnunet_arm_service.h index 639e723c5..ef860bff4 100644 --- a/src/include/gnunet_arm_service.h +++ b/src/include/gnunet_arm_service.h | |||
@@ -244,8 +244,9 @@ struct GNUNET_ARM_Operation; | |||
244 | * #GNUNET_SYSERR if there was an error. | 244 | * #GNUNET_SYSERR if there was an error. |
245 | */ | 245 | */ |
246 | typedef void | 246 | typedef void |
247 | (*GNUNET_ARM_ConnectionStatusCallback) (void *cls, | 247 | (*GNUNET_ARM_ConnectionStatusCallback) ( |
248 | int connected); | 248 | void *cls, |
249 | enum GNUNET_GenericReturnValue connected); | ||
249 | 250 | ||
250 | 251 | ||
251 | /** | 252 | /** |
@@ -259,9 +260,10 @@ typedef void | |||
259 | * @param result result of the operation | 260 | * @param result result of the operation |
260 | */ | 261 | */ |
261 | typedef void | 262 | typedef void |
262 | (*GNUNET_ARM_ResultCallback) (void *cls, | 263 | (*GNUNET_ARM_ResultCallback) ( |
263 | enum GNUNET_ARM_RequestStatus rs, | 264 | void *cls, |
264 | enum GNUNET_ARM_Result result); | 265 | enum GNUNET_ARM_RequestStatus rs, |
266 | enum GNUNET_ARM_Result result); | ||
265 | 267 | ||
266 | 268 | ||
267 | /** | 269 | /** |
@@ -276,10 +278,11 @@ typedef void | |||
276 | * @param list list of services managed by arm | 278 | * @param list list of services managed by arm |
277 | */ | 279 | */ |
278 | typedef void | 280 | typedef void |
279 | (*GNUNET_ARM_ServiceListCallback) (void *cls, | 281 | (*GNUNET_ARM_ServiceListCallback) ( |
280 | enum GNUNET_ARM_RequestStatus rs, | 282 | void *cls, |
281 | unsigned int count, | 283 | enum GNUNET_ARM_RequestStatus rs, |
282 | const struct GNUNET_ARM_ServiceInfo *list); | 284 | unsigned int count, |
285 | const struct GNUNET_ARM_ServiceInfo *list); | ||
283 | 286 | ||
284 | 287 | ||
285 | /** | 288 | /** |
@@ -294,18 +297,20 @@ typedef void | |||
294 | * @return context to use for further ARM operations, NULL on error. | 297 | * @return context to use for further ARM operations, NULL on error. |
295 | */ | 298 | */ |
296 | struct GNUNET_ARM_Handle * | 299 | struct GNUNET_ARM_Handle * |
297 | GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | 300 | GNUNET_ARM_connect ( |
298 | GNUNET_ARM_ConnectionStatusCallback conn_status, | 301 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
299 | void *conn_status_cls); | 302 | GNUNET_ARM_ConnectionStatusCallback conn_status, |
303 | void *conn_status_cls); | ||
300 | 304 | ||
301 | 305 | ||
302 | /** | 306 | /** |
303 | * Disconnect from the ARM service and destroy the handle. | 307 | * Disconnect from the ARM service and destroy the handle. |
304 | * | 308 | * |
305 | * @param h the handle that was being used | 309 | * @param[in] h the handle that was being used |
306 | */ | 310 | */ |
307 | void | 311 | void |
308 | GNUNET_ARM_disconnect (struct GNUNET_ARM_Handle *h); | 312 | GNUNET_ARM_disconnect ( |
313 | struct GNUNET_ARM_Handle *h); | ||
309 | 314 | ||
310 | 315 | ||
311 | /** | 316 | /** |
@@ -315,7 +320,8 @@ GNUNET_ARM_disconnect (struct GNUNET_ARM_Handle *h); | |||
315 | * @param op operation to cancel | 320 | * @param op operation to cancel |
316 | */ | 321 | */ |
317 | void | 322 | void |
318 | GNUNET_ARM_operation_cancel (struct GNUNET_ARM_Operation *op); | 323 | GNUNET_ARM_operation_cancel ( |
324 | struct GNUNET_ARM_Operation *op); | ||
319 | 325 | ||
320 | 326 | ||
321 | /** | 327 | /** |
@@ -327,9 +333,10 @@ GNUNET_ARM_operation_cancel (struct GNUNET_ARM_Operation *op); | |||
327 | * @return handle for the operation, NULL on error | 333 | * @return handle for the operation, NULL on error |
328 | */ | 334 | */ |
329 | struct GNUNET_ARM_Operation * | 335 | struct GNUNET_ARM_Operation * |
330 | GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h, | 336 | GNUNET_ARM_request_service_list ( |
331 | GNUNET_ARM_ServiceListCallback cont, | 337 | struct GNUNET_ARM_Handle *h, |
332 | void *cont_cls); | 338 | GNUNET_ARM_ServiceListCallback cont, |
339 | void *cont_cls); | ||
333 | 340 | ||
334 | 341 | ||
335 | /** | 342 | /** |
@@ -347,10 +354,11 @@ GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h, | |||
347 | * @return handle for the operation, NULL on error | 354 | * @return handle for the operation, NULL on error |
348 | */ | 355 | */ |
349 | struct GNUNET_ARM_Operation * | 356 | struct GNUNET_ARM_Operation * |
350 | GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h, | 357 | GNUNET_ARM_request_service_stop ( |
351 | const char *service_name, | 358 | struct GNUNET_ARM_Handle *h, |
352 | GNUNET_ARM_ResultCallback cont, | 359 | const char *service_name, |
353 | void *cont_cls); | 360 | GNUNET_ARM_ResultCallback cont, |
361 | void *cont_cls); | ||
354 | 362 | ||
355 | 363 | ||
356 | /** | 364 | /** |
@@ -364,12 +372,12 @@ GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h, | |||
364 | * @return handle for the operation, NULL on error | 372 | * @return handle for the operation, NULL on error |
365 | */ | 373 | */ |
366 | struct GNUNET_ARM_Operation * | 374 | struct GNUNET_ARM_Operation * |
367 | GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, | 375 | GNUNET_ARM_request_service_start ( |
368 | const char *service_name, | 376 | struct GNUNET_ARM_Handle *h, |
369 | enum GNUNET_OS_InheritStdioFlags | 377 | const char *service_name, |
370 | std_inheritance, | 378 | enum GNUNET_OS_InheritStdioFlags std_inheritance, |
371 | GNUNET_ARM_ResultCallback cont, | 379 | GNUNET_ARM_ResultCallback cont, |
372 | void *cont_cls); | 380 | void *cont_cls); |
373 | 381 | ||
374 | 382 | ||
375 | /** | 383 | /** |
@@ -386,10 +394,10 @@ struct GNUNET_ARM_MonitorHandle; | |||
386 | * @param status status of the service | 394 | * @param status status of the service |
387 | */ | 395 | */ |
388 | typedef void | 396 | typedef void |
389 | (*GNUNET_ARM_ServiceMonitorCallback) (void *cls, | 397 | (*GNUNET_ARM_ServiceMonitorCallback) ( |
390 | const char *service, | 398 | void *cls, |
391 | enum GNUNET_ARM_ServiceMonitorStatus | 399 | const char *service, |
392 | status); | 400 | enum GNUNET_ARM_ServiceMonitorStatus status); |
393 | 401 | ||
394 | 402 | ||
395 | /** | 403 | /** |
@@ -404,9 +412,10 @@ typedef void | |||
404 | * @return context to use for further ARM monitor operations, NULL on error. | 412 | * @return context to use for further ARM monitor operations, NULL on error. |
405 | */ | 413 | */ |
406 | struct GNUNET_ARM_MonitorHandle * | 414 | struct GNUNET_ARM_MonitorHandle * |
407 | GNUNET_ARM_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | 415 | GNUNET_ARM_monitor_start ( |
408 | GNUNET_ARM_ServiceMonitorCallback cont, | 416 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
409 | void *cont_cls); | 417 | GNUNET_ARM_ServiceMonitorCallback cont, |
418 | void *cont_cls); | ||
410 | 419 | ||
411 | 420 | ||
412 | /** | 421 | /** |
@@ -415,7 +424,8 @@ GNUNET_ARM_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
415 | * @param h the handle that was being used | 424 | * @param h the handle that was being used |
416 | */ | 425 | */ |
417 | void | 426 | void |
418 | GNUNET_ARM_monitor_stop (struct GNUNET_ARM_MonitorHandle *h); | 427 | GNUNET_ARM_monitor_stop ( |
428 | struct GNUNET_ARM_MonitorHandle *h); | ||
419 | 429 | ||
420 | #if 0 /* keep Emacsens' auto-indent happy */ | 430 | #if 0 /* keep Emacsens' auto-indent happy */ |
421 | { | 431 | { |
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h index 9fa3de37d..c5885e7c4 100644 --- a/src/include/gnunet_common.h +++ b/src/include/gnunet_common.h | |||
@@ -55,20 +55,20 @@ | |||
55 | #if defined(__FreeBSD__) | 55 | #if defined(__FreeBSD__) |
56 | 56 | ||
57 | #include <sys/endian.h> | 57 | #include <sys/endian.h> |
58 | #define bswap_32(x) bswap32(x) | 58 | #define bswap_32(x) bswap32 (x) |
59 | #define bswap_64(x) bswap64(x) | 59 | #define bswap_64(x) bswap64 (x) |
60 | 60 | ||
61 | #elif defined(__OpenBSD__) | 61 | #elif defined(__OpenBSD__) |
62 | 62 | ||
63 | #define bswap_32(x) swap32(x) | 63 | #define bswap_32(x) swap32 (x) |
64 | #define bswap_64(x) swap64(x) | 64 | #define bswap_64(x) swap64 (x) |
65 | 65 | ||
66 | #elif defined(__NetBSD__) | 66 | #elif defined(__NetBSD__) |
67 | 67 | ||
68 | #include <machine/bswap.h> | 68 | #include <machine/bswap.h> |
69 | #if defined(__BSWAP_RENAME) && !defined(__bswap_32) | 69 | #if defined(__BSWAP_RENAME) && ! defined(__bswap_32) |
70 | #define bswap_32(x) bswap32(x) | 70 | #define bswap_32(x) bswap32 (x) |
71 | #define bswap_64(x) bswap64(x) | 71 | #define bswap_64(x) bswap64 (x) |
72 | #endif | 72 | #endif |
73 | 73 | ||
74 | #elif defined(__linux__) || defined(GNU) | 74 | #elif defined(__linux__) || defined(GNU) |
@@ -166,15 +166,19 @@ enum GNUNET_GenericReturnValue | |||
166 | #define BYTE_SWAP_16(x) ((((x) & 0x00ff) << 8) | (((x) & 0xff00) >> 8)) | 166 | #define BYTE_SWAP_16(x) ((((x) & 0x00ff) << 8) | (((x) & 0xff00) >> 8)) |
167 | 167 | ||
168 | #define BYTE_SWAP_32(x) \ | 168 | #define BYTE_SWAP_32(x) \ |
169 | ((((x) & 0x000000ffU) << 24) | (((x) & 0x0000ff00U) << 8) \ | 169 | ((((x) & 0x000000ffU) << 24) | (((x) & 0x0000ff00U) << 8) \ |
170 | | (((x) & 0x00ff0000U) >> 8) | (((x) & 0xff000000U) >> 24)) | 170 | | (((x) & 0x00ff0000U) >> 8) | (((x) & 0xff000000U) >> 24)) |
171 | 171 | ||
172 | #define BYTE_SWAP_64(x) \ | 172 | #define BYTE_SWAP_64(x) \ |
173 | ((((x) & 0x00000000000000ffUL) << 56) | (((x) & 0x000000000000ff00UL) << 40) \ | 173 | ((((x) & 0x00000000000000ffUL) << 56) | (((x) & 0x000000000000ff00UL) << \ |
174 | | (((x) & 0x0000000000ff0000UL) << 24) | (((x) & 0x00000000ff000000UL) << 8) \ | 174 | 40) \ |
175 | | (((x) & 0x000000ff00000000UL) >> 8) | (((x) & 0x0000ff0000000000UL) >> 24) \ | 175 | | (((x) & 0x0000000000ff0000UL) << 24) | (((x) & 0x00000000ff000000UL) \ |
176 | | (((x) & 0x00ff000000000000UL) >> 40) | (((x) & 0xff00000000000000UL) >> \ | 176 | << 8) \ |
177 | 56)) | 177 | | (((x) & 0x000000ff00000000UL) >> 8) | (((x) & 0x0000ff0000000000UL) \ |
178 | >> 24) \ | ||
179 | | (((x) & 0x00ff000000000000UL) >> 40) | (((x) & 0xff00000000000000UL) \ | ||
180 | >> \ | ||
181 | 56)) | ||
178 | #endif | 182 | #endif |
179 | 183 | ||
180 | #if __BYTE_ORDER == __LITTLE_ENDIAN | 184 | #if __BYTE_ORDER == __LITTLE_ENDIAN |
@@ -479,7 +483,7 @@ GNUNET_get_log_call_status (int caller_level, | |||
479 | 483 | ||
480 | #endif | 484 | #endif |
481 | 485 | ||
482 | 486 | /* *INDENT-OFF* */ | |
483 | /** | 487 | /** |
484 | * @ingroup logging | 488 | * @ingroup logging |
485 | * Main log function. | 489 | * Main log function. |
@@ -489,13 +493,15 @@ GNUNET_get_log_call_status (int caller_level, | |||
489 | * @param ... arguments for format string | 493 | * @param ... arguments for format string |
490 | */ | 494 | */ |
491 | void | 495 | void |
492 | GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message, ...) | 496 | GNUNET_log_nocheck (enum GNUNET_ErrorType kind, |
497 | const char *message, | ||
498 | ...) | ||
493 | __attribute__ ((format (printf, 2, 3))); | 499 | __attribute__ ((format (printf, 2, 3))); |
494 | 500 | ||
495 | /* from glib */ | 501 | /* from glib */ |
496 | #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) | 502 | #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) |
497 | #define _GNUNET_BOOLEAN_EXPR(expr) \ | 503 | #define _GNUNET_BOOLEAN_EXPR(expr) \ |
498 | __extension__ ({ \ | 504 | __extension__ ({ \ |
499 | int _gnunet_boolean_var_; \ | 505 | int _gnunet_boolean_var_; \ |
500 | if (expr) \ | 506 | if (expr) \ |
501 | _gnunet_boolean_var_ = 1; \ | 507 | _gnunet_boolean_var_ = 1; \ |
@@ -513,6 +519,7 @@ __attribute__ ((format (printf, 2, 3))); | |||
513 | #if ! defined(GNUNET_LOG_CALL_STATUS) | 519 | #if ! defined(GNUNET_LOG_CALL_STATUS) |
514 | #define GNUNET_LOG_CALL_STATUS -1 | 520 | #define GNUNET_LOG_CALL_STATUS -1 |
515 | #endif | 521 | #endif |
522 | /* *INDENT-ON* */ | ||
516 | 523 | ||
517 | 524 | ||
518 | /** | 525 | /** |
@@ -534,56 +541,56 @@ __attribute__ ((format (printf, 3, 4))); | |||
534 | 541 | ||
535 | #if ! defined(GNUNET_CULL_LOGGING) | 542 | #if ! defined(GNUNET_CULL_LOGGING) |
536 | #define GNUNET_log_from(kind, comp, ...) \ | 543 | #define GNUNET_log_from(kind, comp, ...) \ |
537 | do \ | 544 | do \ |
538 | { \ | 545 | { \ |
539 | static int log_call_enabled = GNUNET_LOG_CALL_STATUS; \ | 546 | static int log_call_enabled = GNUNET_LOG_CALL_STATUS; \ |
540 | if ((GNUNET_EXTRA_LOGGING > 0) || \ | 547 | if ((GNUNET_EXTRA_LOGGING > 0) || \ |
541 | ((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) \ | 548 | ((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) \ |
542 | { \ | 549 | { \ |
543 | if (GN_UNLIKELY (log_call_enabled == -1)) \ | 550 | if (GN_UNLIKELY (log_call_enabled == -1)) \ |
544 | log_call_enabled = \ | 551 | log_call_enabled = \ |
545 | GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), \ | 552 | GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), \ |
546 | (comp), \ | 553 | (comp), \ |
547 | __FILE__, \ | 554 | __FILE__, \ |
548 | __FUNCTION__, \ | 555 | __FUNCTION__, \ |
549 | __LINE__); \ | 556 | __LINE__); \ |
550 | if (GN_UNLIKELY (GNUNET_get_log_skip () > 0)) \ | 557 | if (GN_UNLIKELY (GNUNET_get_log_skip () > 0)) \ |
551 | { \ | 558 | { \ |
552 | GNUNET_log_skip (-1, GNUNET_NO); \ | 559 | GNUNET_log_skip (-1, GNUNET_NO); \ |
553 | } \ | 560 | } \ |
554 | else \ | 561 | else \ |
555 | { \ | 562 | { \ |
556 | if (GN_UNLIKELY (log_call_enabled)) \ | 563 | if (GN_UNLIKELY (log_call_enabled)) \ |
557 | GNUNET_log_from_nocheck ((kind), comp, __VA_ARGS__); \ | 564 | GNUNET_log_from_nocheck ((kind), comp, __VA_ARGS__); \ |
558 | } \ | 565 | } \ |
559 | } \ | 566 | } \ |
560 | } while (0) | 567 | } while (0) |
561 | 568 | ||
562 | #define GNUNET_log(kind, ...) \ | 569 | #define GNUNET_log(kind, ...) \ |
563 | do \ | 570 | do \ |
564 | { \ | 571 | { \ |
565 | static int log_call_enabled = GNUNET_LOG_CALL_STATUS; \ | 572 | static int log_call_enabled = GNUNET_LOG_CALL_STATUS; \ |
566 | if ((GNUNET_EXTRA_LOGGING > 0) || \ | 573 | if ((GNUNET_EXTRA_LOGGING > 0) || \ |
567 | ((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) \ | 574 | ((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) \ |
568 | { \ | 575 | { \ |
569 | if (GN_UNLIKELY (log_call_enabled == -1)) \ | 576 | if (GN_UNLIKELY (log_call_enabled == -1)) \ |
570 | log_call_enabled = \ | 577 | log_call_enabled = \ |
571 | GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), \ | 578 | GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), \ |
572 | NULL, \ | 579 | NULL, \ |
573 | __FILE__, \ | 580 | __FILE__, \ |
574 | __FUNCTION__, \ | 581 | __FUNCTION__, \ |
575 | __LINE__); \ | 582 | __LINE__); \ |
576 | if (GN_UNLIKELY (GNUNET_get_log_skip () > 0)) \ | 583 | if (GN_UNLIKELY (GNUNET_get_log_skip () > 0)) \ |
577 | { \ | 584 | { \ |
578 | GNUNET_log_skip (-1, GNUNET_NO); \ | 585 | GNUNET_log_skip (-1, GNUNET_NO); \ |
579 | } \ | 586 | } \ |
580 | else \ | 587 | else \ |
581 | { \ | 588 | { \ |
582 | if (GN_UNLIKELY (log_call_enabled)) \ | 589 | if (GN_UNLIKELY (log_call_enabled)) \ |
583 | GNUNET_log_nocheck ((kind), __VA_ARGS__); \ | 590 | GNUNET_log_nocheck ((kind), __VA_ARGS__); \ |
584 | } \ | 591 | } \ |
585 | } \ | 592 | } \ |
586 | } while (0) | 593 | } while (0) |
587 | #else | 594 | #else |
588 | #define GNUNET_log(...) | 595 | #define GNUNET_log(...) |
589 | #define GNUNET_log_from(...) | 596 | #define GNUNET_log_from(...) |
@@ -642,7 +649,7 @@ GNUNET_abort_ (void) GNUNET_NORETURN; | |||
642 | */ | 649 | */ |
643 | const char * | 650 | const char * |
644 | GNUNET_b2s (const void *buf, | 651 | GNUNET_b2s (const void *buf, |
645 | size_t buf_size); | 652 | size_t buf_size); |
646 | 653 | ||
647 | 654 | ||
648 | /** | 655 | /** |
@@ -676,7 +683,9 @@ GNUNET_log_skip (int n, int check_reset); | |||
676 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if logfile could not be opened | 683 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if logfile could not be opened |
677 | */ | 684 | */ |
678 | enum GNUNET_GenericReturnValue | 685 | enum GNUNET_GenericReturnValue |
679 | GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile); | 686 | GNUNET_log_setup (const char *comp, |
687 | const char *loglevel, | ||
688 | const char *logfile); | ||
680 | 689 | ||
681 | 690 | ||
682 | /** | 691 | /** |
@@ -690,7 +699,8 @@ GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile); | |||
690 | * @param logger_cls closure for @a logger | 699 | * @param logger_cls closure for @a logger |
691 | */ | 700 | */ |
692 | void | 701 | void |
693 | GNUNET_logger_add (GNUNET_Logger logger, void *logger_cls); | 702 | GNUNET_logger_add (GNUNET_Logger logger, |
703 | void *logger_cls); | ||
694 | 704 | ||
695 | 705 | ||
696 | /** | 706 | /** |
@@ -701,7 +711,8 @@ GNUNET_logger_add (GNUNET_Logger logger, void *logger_cls); | |||
701 | * @param logger_cls closure for @a logger | 711 | * @param logger_cls closure for @a logger |
702 | */ | 712 | */ |
703 | void | 713 | void |
704 | GNUNET_logger_remove (GNUNET_Logger logger, void *logger_cls); | 714 | GNUNET_logger_remove (GNUNET_Logger logger, |
715 | void *logger_cls); | ||
705 | 716 | ||
706 | 717 | ||
707 | /** | 718 | /** |
@@ -916,36 +927,37 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind); | |||
916 | * @ingroup logging | 927 | * @ingroup logging |
917 | * Use this for fatal errors that cannot be handled | 928 | * Use this for fatal errors that cannot be handled |
918 | */ | 929 | */ |
919 | #if __GNUC__ >= 6 || __clang_major__ >= 6 | 930 | #if __GNUC__ >= 6 || __clang_major__ >= 6 |
920 | #define GNUNET_assert(cond) \ | 931 | #define GNUNET_assert(cond) \ |
921 | do \ | 932 | do \ |
922 | { \ | 933 | { \ |
923 | _Pragma("GCC diagnostic push") \ | 934 | _Pragma("GCC diagnostic push") \ |
924 | _Pragma("GCC diagnostic ignored \"-Wtautological-compare\"") \ | 935 | _Pragma("GCC diagnostic ignored \"-Wtautological-compare\"") \ |
925 | if (! (cond)) \ | 936 | if (! (cond)) \ |
926 | { \ | 937 | { \ |
927 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ | 938 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ |
928 | dgettext ("gnunet", "Assertion failed at %s:%d. Aborting.\n"), \ | 939 | dgettext ("gnunet", "Assertion failed at %s:%d. Aborting.\n"), \ |
929 | __FILE__, \ | 940 | __FILE__, \ |
930 | __LINE__); \ | 941 | __LINE__); \ |
931 | GNUNET_abort_ (); \ | 942 | GNUNET_abort_ (); \ |
932 | } \ | 943 | } \ |
933 | _Pragma("GCC diagnostic pop") \ | 944 | _Pragma("GCC diagnostic pop") \ |
934 | } while (0) | 945 | } while (0) |
935 | #else | 946 | #else |
936 | /* older GCC/clangs do not support -Wtautological-compare */ | 947 | /* older GCC/clangs do not support -Wtautological-compare */ |
937 | #define GNUNET_assert(cond) \ | 948 | #define GNUNET_assert(cond) \ |
938 | do \ | 949 | do \ |
939 | { \ | 950 | { \ |
940 | if (! (cond)) \ | 951 | if (! (cond)) \ |
941 | { \ | 952 | { \ |
942 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ | 953 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ |
943 | dgettext ("gnunet", "Assertion failed at %s:%d. Aborting.\n"), \ | 954 | dgettext ("gnunet", \ |
944 | __FILE__, \ | 955 | "Assertion failed at %s:%d. Aborting.\n"), \ |
945 | __LINE__); \ | 956 | __FILE__, \ |
946 | GNUNET_abort_ (); \ | 957 | __LINE__); \ |
947 | } \ | 958 | GNUNET_abort_ (); \ |
948 | } while (0) | 959 | } \ |
960 | } while (0) | ||
949 | #endif | 961 | #endif |
950 | 962 | ||
951 | /** | 963 | /** |
@@ -953,17 +965,18 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind); | |||
953 | * Use this for fatal errors that cannot be handled | 965 | * Use this for fatal errors that cannot be handled |
954 | */ | 966 | */ |
955 | #define GNUNET_assert_at(cond, f, l) \ | 967 | #define GNUNET_assert_at(cond, f, l) \ |
956 | do \ | 968 | do \ |
957 | { \ | 969 | { \ |
958 | if (! (cond)) \ | 970 | if (! (cond)) \ |
959 | { \ | 971 | { \ |
960 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ | 972 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ |
961 | dgettext ("gnunet", "Assertion failed at %s:%d. Aborting.\n"), \ | 973 | dgettext ("gnunet", \ |
962 | f, \ | 974 | "Assertion failed at %s:%d. Aborting.\n"), \ |
963 | l); \ | 975 | f, \ |
964 | GNUNET_abort_ (); \ | 976 | l); \ |
965 | } \ | 977 | GNUNET_abort_ (); \ |
966 | } while (0) | 978 | } \ |
979 | } while (0) | ||
967 | 980 | ||
968 | 981 | ||
969 | /** | 982 | /** |
@@ -974,18 +987,20 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind); | |||
974 | * @param comp Component string to use for logging | 987 | * @param comp Component string to use for logging |
975 | */ | 988 | */ |
976 | #define GNUNET_assert_from(cond, comp) \ | 989 | #define GNUNET_assert_from(cond, comp) \ |
977 | do \ | 990 | do \ |
978 | { \ | 991 | { \ |
979 | if (! (cond)) \ | 992 | if (! (cond)) \ |
980 | { \ | 993 | { \ |
981 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, \ | 994 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, \ |
982 | comp, \ | 995 | comp, \ |
983 | dgettext ("gnunet", "Assertion failed at %s:%d. Aborting.\n"), \ | 996 | dgettext ("gnunet", \ |
984 | __FILE__, \ | 997 | "Assertion failed at %s:%d. Aborting.\n") \ |
985 | __LINE__); \ | 998 | , \ |
986 | GNUNET_abort_ (); \ | 999 | __FILE__, \ |
987 | } \ | 1000 | __LINE__); \ |
988 | } while (0) | 1001 | GNUNET_abort_ (); \ |
1002 | } \ | ||
1003 | } while (0) | ||
989 | 1004 | ||
990 | 1005 | ||
991 | #ifdef _Static_assert | 1006 | #ifdef _Static_assert |
@@ -1016,16 +1031,16 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind); | |||
1016 | * not fatal (can be handled) but should not occur. | 1031 | * not fatal (can be handled) but should not occur. |
1017 | */ | 1032 | */ |
1018 | #define GNUNET_break(cond) \ | 1033 | #define GNUNET_break(cond) \ |
1019 | do \ | 1034 | do \ |
1020 | { \ | 1035 | { \ |
1021 | if (! (cond)) \ | 1036 | if (! (cond)) \ |
1022 | { \ | 1037 | { \ |
1023 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ | 1038 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ |
1024 | dgettext ("gnunet", "Assertion failed at %s:%d.\n"), \ | 1039 | dgettext ("gnunet", "Assertion failed at %s:%d.\n"), \ |
1025 | __FILE__, \ | 1040 | __FILE__, \ |
1026 | __LINE__); \ | 1041 | __LINE__); \ |
1027 | } \ | 1042 | } \ |
1028 | } while (0) | 1043 | } while (0) |
1029 | 1044 | ||
1030 | 1045 | ||
1031 | /** | 1046 | /** |
@@ -1038,16 +1053,17 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind); | |||
1038 | * development and testing. "OP == other peer". | 1053 | * development and testing. "OP == other peer". |
1039 | */ | 1054 | */ |
1040 | #define GNUNET_break_op(cond) \ | 1055 | #define GNUNET_break_op(cond) \ |
1041 | do \ | 1056 | do \ |
1042 | { \ | 1057 | { \ |
1043 | if (! (cond)) \ | 1058 | if (! (cond)) \ |
1044 | { \ | 1059 | { \ |
1045 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, \ | 1060 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, \ |
1046 | dgettext ("gnunet", "External protocol violation detected at %s:%d.\n"), \ | 1061 | dgettext ("gnunet", \ |
1047 | __FILE__, \ | 1062 | "External protocol violation detected at %s:%d.\n"), \ |
1048 | __LINE__); \ | 1063 | __FILE__, \ |
1049 | } \ | 1064 | __LINE__); \ |
1050 | } while (0) | 1065 | } \ |
1066 | } while (0) | ||
1051 | 1067 | ||
1052 | 1068 | ||
1053 | /** | 1069 | /** |
@@ -1057,15 +1073,16 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind); | |||
1057 | * by strerror(errno). | 1073 | * by strerror(errno). |
1058 | */ | 1074 | */ |
1059 | #define GNUNET_log_strerror(level, cmd) \ | 1075 | #define GNUNET_log_strerror(level, cmd) \ |
1060 | do \ | 1076 | do \ |
1061 | { \ | 1077 | { \ |
1062 | GNUNET_log (level, \ | 1078 | GNUNET_log (level, \ |
1063 | dgettext ("gnunet", "`%s' failed at %s:%d with error: %s\n"), \ | 1079 | dgettext ("gnunet", \ |
1064 | cmd, \ | 1080 | "`%s' failed at %s:%d with error: %s\n"), \ |
1065 | __FILE__, \ | 1081 | cmd, \ |
1066 | __LINE__, \ | 1082 | __FILE__, \ |
1067 | strerror (errno)); \ | 1083 | __LINE__, \ |
1068 | } while (0) | 1084 | strerror (errno)); \ |
1085 | } while (0) | ||
1069 | 1086 | ||
1070 | 1087 | ||
1071 | /** | 1088 | /** |
@@ -1075,16 +1092,17 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind); | |||
1075 | * by strerror(errno). | 1092 | * by strerror(errno). |
1076 | */ | 1093 | */ |
1077 | #define GNUNET_log_from_strerror(level, component, cmd) \ | 1094 | #define GNUNET_log_from_strerror(level, component, cmd) \ |
1078 | do \ | 1095 | do \ |
1079 | { \ | 1096 | { \ |
1080 | GNUNET_log_from (level, \ | 1097 | GNUNET_log_from (level, \ |
1081 | component, \ | 1098 | component, \ |
1082 | dgettext ("gnunet", "`%s' failed at %s:%d with error: %s\n"), \ | 1099 | dgettext ("gnunet", \ |
1083 | cmd, \ | 1100 | "`%s' failed at %s:%d with error: %s\n"), \ |
1084 | __FILE__, \ | 1101 | cmd, \ |
1085 | __LINE__, \ | 1102 | __FILE__, \ |
1086 | strerror (errno)); \ | 1103 | __LINE__, \ |
1087 | } while (0) | 1104 | strerror (errno)); \ |
1105 | } while (0) | ||
1088 | 1106 | ||
1089 | 1107 | ||
1090 | /** | 1108 | /** |
@@ -1094,16 +1112,17 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind); | |||
1094 | * by strerror(errno). | 1112 | * by strerror(errno). |
1095 | */ | 1113 | */ |
1096 | #define GNUNET_log_strerror_file(level, cmd, filename) \ | 1114 | #define GNUNET_log_strerror_file(level, cmd, filename) \ |
1097 | do \ | 1115 | do \ |
1098 | { \ | 1116 | { \ |
1099 | GNUNET_log (level, \ | 1117 | GNUNET_log (level, \ |
1100 | dgettext ("gnunet", "`%s' failed on file `%s' at %s:%d with error: %s\n"), \ | 1118 | dgettext ("gnunet", \ |
1101 | cmd, \ | 1119 | "`%s' failed on file `%s' at %s:%d with error: %s\n"), \ |
1102 | filename, \ | 1120 | cmd, \ |
1103 | __FILE__, \ | 1121 | filename, \ |
1104 | __LINE__, \ | 1122 | __FILE__, \ |
1105 | strerror (errno)); \ | 1123 | __LINE__, \ |
1106 | } while (0) | 1124 | strerror (errno)); \ |
1125 | } while (0) | ||
1107 | 1126 | ||
1108 | 1127 | ||
1109 | /** | 1128 | /** |
@@ -1113,17 +1132,18 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind); | |||
1113 | * by strerror(errno). | 1132 | * by strerror(errno). |
1114 | */ | 1133 | */ |
1115 | #define GNUNET_log_from_strerror_file(level, component, cmd, filename) \ | 1134 | #define GNUNET_log_from_strerror_file(level, component, cmd, filename) \ |
1116 | do \ | 1135 | do \ |
1117 | { \ | 1136 | { \ |
1118 | GNUNET_log_from (level, \ | 1137 | GNUNET_log_from (level, \ |
1119 | component, \ | 1138 | component, \ |
1120 | dgettext ("gnunet", "`%s' failed on file `%s' at %s:%d with error: %s\n"), \ | 1139 | dgettext ("gnunet", \ |
1121 | cmd, \ | 1140 | "`%s' failed on file `%s' at %s:%d with error: %s\n"), \ |
1122 | filename, \ | 1141 | cmd, \ |
1123 | __FILE__, \ | 1142 | filename, \ |
1124 | __LINE__, \ | 1143 | __FILE__, \ |
1125 | strerror (errno)); \ | 1144 | __LINE__, \ |
1126 | } while (0) | 1145 | strerror (errno)); \ |
1146 | } while (0) | ||
1127 | 1147 | ||
1128 | /* ************************* endianness conversion ****************** */ | 1148 | /* ************************* endianness conversion ****************** */ |
1129 | 1149 | ||
@@ -1216,7 +1236,7 @@ GNUNET_ntoh_double (double d); | |||
1216 | * the first element! | 1236 | * the first element! |
1217 | */ | 1237 | */ |
1218 | #define GNUNET_memcmp(a, b) \ | 1238 | #define GNUNET_memcmp(a, b) \ |
1219 | ({ \ | 1239 | ({ \ |
1220 | const typeof (*b) * _a = (a); \ | 1240 | const typeof (*b) * _a = (a); \ |
1221 | const typeof (*a) * _b = (b); \ | 1241 | const typeof (*a) * _b = (b); \ |
1222 | memcmp (_a, _b, sizeof(*a)); \ | 1242 | memcmp (_a, _b, sizeof(*a)); \ |
@@ -1245,7 +1265,7 @@ GNUNET_memcmp_ct_ (const void *b1, | |||
1245 | * the first element! | 1265 | * the first element! |
1246 | */ | 1266 | */ |
1247 | #define GNUNET_memcmp_priv(a, b) \ | 1267 | #define GNUNET_memcmp_priv(a, b) \ |
1248 | ({ \ | 1268 | ({ \ |
1249 | const typeof (*b) * _a = (a); \ | 1269 | const typeof (*b) * _a = (a); \ |
1250 | const typeof (*a) * _b = (b); \ | 1270 | const typeof (*a) * _b = (b); \ |
1251 | GNUNET_memcmp_ct_ (_a, _b, sizeof(*a)); \ | 1271 | GNUNET_memcmp_ct_ (_a, _b, sizeof(*a)); \ |
@@ -1258,9 +1278,9 @@ GNUNET_memcmp_ct_ (const void *b1, | |||
1258 | * @param a pointer to @a n bytes which should be tested for the | 1278 | * @param a pointer to @a n bytes which should be tested for the |
1259 | * entire memory being zero'ed out. | 1279 | * entire memory being zero'ed out. |
1260 | * @param n number of bytes in @a to be tested | 1280 | * @param n number of bytes in @a to be tested |
1261 | * @return GNUNET_YES if a is zero, GNUNET_NO otherwise | 1281 | * @return true if @a a is zero, false_NO otherwise |
1262 | */ | 1282 | */ |
1263 | enum GNUNET_GenericReturnValue | 1283 | bool |
1264 | GNUNET_is_zero_ (const void *a, | 1284 | GNUNET_is_zero_ (const void *a, |
1265 | size_t n); | 1285 | size_t n); |
1266 | 1286 | ||
@@ -1273,7 +1293,7 @@ GNUNET_is_zero_ (const void *a, | |||
1273 | * @return GNUNET_YES if a is zero, GNUNET_NO otherwise | 1293 | * @return GNUNET_YES if a is zero, GNUNET_NO otherwise |
1274 | */ | 1294 | */ |
1275 | #define GNUNET_is_zero(a) \ | 1295 | #define GNUNET_is_zero(a) \ |
1276 | GNUNET_is_zero_ ((a), sizeof (*(a))) | 1296 | GNUNET_is_zero_ ((a), sizeof (*(a))) |
1277 | 1297 | ||
1278 | 1298 | ||
1279 | /** | 1299 | /** |
@@ -1286,15 +1306,16 @@ GNUNET_is_zero_ (const void *a, | |||
1286 | * @param n number of bytes to copy | 1306 | * @param n number of bytes to copy |
1287 | */ | 1307 | */ |
1288 | #define GNUNET_memcpy(dst, src, n) \ | 1308 | #define GNUNET_memcpy(dst, src, n) \ |
1289 | do \ | 1309 | do \ |
1290 | { \ | 1310 | { \ |
1291 | if (0 != n) \ | 1311 | if (0 != n) \ |
1292 | { \ | 1312 | { \ |
1293 | (void) memcpy (dst, src, n); \ | 1313 | (void) memcpy (dst, src, n); \ |
1294 | } \ | 1314 | } \ |
1295 | } while (0) | 1315 | } while (0) |
1296 | 1316 | ||
1297 | 1317 | ||
1318 | /* *INDENT-OFF* */ | ||
1298 | /** | 1319 | /** |
1299 | * @ingroup memory | 1320 | * @ingroup memory |
1300 | * Allocate a size @a n array with structs or unions of the given @a type. | 1321 | * Allocate a size @a n array with structs or unions of the given @a type. |
@@ -1308,6 +1329,7 @@ GNUNET_is_zero_ (const void *a, | |||
1308 | GNUNET_assert (SIZE_MAX / sizeof (type) >= n); \ | 1329 | GNUNET_assert (SIZE_MAX / sizeof (type) >= n); \ |
1309 | (type *) GNUNET_malloc ((n) * sizeof(type)); \ | 1330 | (type *) GNUNET_malloc ((n) * sizeof(type)); \ |
1310 | }) | 1331 | }) |
1332 | /* *INDENT-ON* */ | ||
1311 | 1333 | ||
1312 | /** | 1334 | /** |
1313 | * @ingroup memory | 1335 | * @ingroup memory |
@@ -1319,7 +1341,7 @@ GNUNET_is_zero_ (const void *a, | |||
1319 | * @param type name of the struct or union, i.e. pass 'struct Foo'. | 1341 | * @param type name of the struct or union, i.e. pass 'struct Foo'. |
1320 | */ | 1342 | */ |
1321 | #define GNUNET_new_array_2d(n, m, type) \ | 1343 | #define GNUNET_new_array_2d(n, m, type) \ |
1322 | (type **) GNUNET_xnew_array_2d_ (n, m, sizeof(type), __FILE__, __LINE__) | 1344 | (type **) GNUNET_xnew_array_2d_ (n, m, sizeof(type), __FILE__, __LINE__) |
1323 | 1345 | ||
1324 | /** | 1346 | /** |
1325 | * @ingroup memory | 1347 | * @ingroup memory |
@@ -1332,7 +1354,8 @@ GNUNET_is_zero_ (const void *a, | |||
1332 | * @param type name of the struct or union, i.e. pass 'struct Foo'. | 1354 | * @param type name of the struct or union, i.e. pass 'struct Foo'. |
1333 | */ | 1355 | */ |
1334 | #define GNUNET_new_array_3d(n, m, o, type) \ | 1356 | #define GNUNET_new_array_3d(n, m, o, type) \ |
1335 | (type ***) GNUNET_xnew_array_3d_ (n, m, o, sizeof(type), __FILE__, __LINE__) | 1357 | (type ***) GNUNET_xnew_array_3d_ (n, m, o, sizeof(type), __FILE__, \ |
1358 | __LINE__) | ||
1336 | 1359 | ||
1337 | /** | 1360 | /** |
1338 | * @ingroup memory | 1361 | * @ingroup memory |
@@ -1364,7 +1387,7 @@ GNUNET_is_zero_ (const void *a, | |||
1364 | * @return pointer to size bytes of memory, NULL if we do not have enough memory | 1387 | * @return pointer to size bytes of memory, NULL if we do not have enough memory |
1365 | */ | 1388 | */ |
1366 | #define GNUNET_malloc_large(size) \ | 1389 | #define GNUNET_malloc_large(size) \ |
1367 | GNUNET_xmalloc_unchecked_ (size, __FILE__, __LINE__) | 1390 | GNUNET_xmalloc_unchecked_ (size, __FILE__, __LINE__) |
1368 | 1391 | ||
1369 | 1392 | ||
1370 | /** | 1393 | /** |
@@ -1377,7 +1400,7 @@ GNUNET_is_zero_ (const void *a, | |||
1377 | * @return pointer to size bytes of memory | 1400 | * @return pointer to size bytes of memory |
1378 | */ | 1401 | */ |
1379 | #define GNUNET_realloc(ptr, size) \ | 1402 | #define GNUNET_realloc(ptr, size) \ |
1380 | GNUNET_xrealloc_ (ptr, size, __FILE__, __LINE__) | 1403 | GNUNET_xrealloc_ (ptr, size, __FILE__, __LINE__) |
1381 | 1404 | ||
1382 | 1405 | ||
1383 | /** | 1406 | /** |
@@ -1404,8 +1427,8 @@ GNUNET_is_zero_ (const void *a, | |||
1404 | * been returned by #GNUNET_strdup, #GNUNET_strndup, #GNUNET_malloc or #GNUNET_array_grow earlier. NULL is allowed. | 1427 | * been returned by #GNUNET_strdup, #GNUNET_strndup, #GNUNET_malloc or #GNUNET_array_grow earlier. NULL is allowed. |
1405 | */ | 1428 | */ |
1406 | #define GNUNET_free(ptr) do { \ | 1429 | #define GNUNET_free(ptr) do { \ |
1407 | GNUNET_xfree_ (ptr, __FILE__, __LINE__); \ | 1430 | GNUNET_xfree_ (ptr, __FILE__, __LINE__); \ |
1408 | ptr = NULL; \ | 1431 | ptr = NULL; \ |
1409 | } while (0) | 1432 | } while (0) |
1410 | 1433 | ||
1411 | 1434 | ||
@@ -1419,6 +1442,7 @@ GNUNET_is_zero_ (const void *a, | |||
1419 | */ | 1442 | */ |
1420 | #define GNUNET_strdup(a) GNUNET_xstrdup_ (a, __FILE__, __LINE__) | 1443 | #define GNUNET_strdup(a) GNUNET_xstrdup_ (a, __FILE__, __LINE__) |
1421 | 1444 | ||
1445 | |||
1422 | /** | 1446 | /** |
1423 | * @ingroup memory | 1447 | * @ingroup memory |
1424 | * Wrapper around #GNUNET_xstrndup_. Makes a partial copy of the string | 1448 | * Wrapper around #GNUNET_xstrndup_. Makes a partial copy of the string |
@@ -1429,7 +1453,7 @@ GNUNET_is_zero_ (const void *a, | |||
1429 | * @return a partial copy of the string including zero-termination | 1453 | * @return a partial copy of the string including zero-termination |
1430 | */ | 1454 | */ |
1431 | #define GNUNET_strndup(a, length) \ | 1455 | #define GNUNET_strndup(a, length) \ |
1432 | GNUNET_xstrndup_ (a, length, __FILE__, __LINE__) | 1456 | GNUNET_xstrndup_ (a, length, __FILE__, __LINE__) |
1433 | 1457 | ||
1434 | /** | 1458 | /** |
1435 | * @ingroup memory | 1459 | * @ingroup memory |
@@ -1467,12 +1491,12 @@ GNUNET_is_zero_ (const void *a, | |||
1467 | * free the vector (then, arr will be NULL afterwards). | 1491 | * free the vector (then, arr will be NULL afterwards). |
1468 | */ | 1492 | */ |
1469 | #define GNUNET_array_grow(arr, size, tsize) \ | 1493 | #define GNUNET_array_grow(arr, size, tsize) \ |
1470 | GNUNET_xgrow_ ((void **) &(arr), \ | 1494 | GNUNET_xgrow_ ((void **) &(arr), \ |
1471 | sizeof((arr)[0]), \ | 1495 | sizeof((arr)[0]), \ |
1472 | &size, \ | 1496 | &size, \ |
1473 | tsize, \ | 1497 | tsize, \ |
1474 | __FILE__, \ | 1498 | __FILE__, \ |
1475 | __LINE__) | 1499 | __LINE__) |
1476 | 1500 | ||
1477 | /** | 1501 | /** |
1478 | * @ingroup memory | 1502 | * @ingroup memory |
@@ -1488,12 +1512,12 @@ GNUNET_is_zero_ (const void *a, | |||
1488 | * @param element the element that will be appended to the array | 1512 | * @param element the element that will be appended to the array |
1489 | */ | 1513 | */ |
1490 | #define GNUNET_array_append(arr, len, element) \ | 1514 | #define GNUNET_array_append(arr, len, element) \ |
1491 | do \ | 1515 | do \ |
1492 | { \ | 1516 | { \ |
1493 | GNUNET_assert ((len) + 1 > (len)); \ | 1517 | GNUNET_assert ((len) + 1 > (len)); \ |
1494 | GNUNET_array_grow (arr, len, len + 1); \ | 1518 | GNUNET_array_grow (arr, len, len + 1); \ |
1495 | (arr) [len - 1] = element; \ | 1519 | (arr) [len - 1] = element; \ |
1496 | } while (0) | 1520 | } while (0) |
1497 | 1521 | ||
1498 | 1522 | ||
1499 | /** | 1523 | /** |
@@ -1520,15 +1544,15 @@ GNUNET_is_zero_ (const void *a, | |||
1520 | 1544 | ||
1521 | */ | 1545 | */ |
1522 | #define GNUNET_array_concatenate(arr1, len1, arr2, len2) \ | 1546 | #define GNUNET_array_concatenate(arr1, len1, arr2, len2) \ |
1523 | do \ | 1547 | do \ |
1524 | { \ | 1548 | { \ |
1525 | const typeof (*arr2) * _a1 = (arr1); \ | 1549 | const typeof (*arr2) * _a1 = (arr1); \ |
1526 | const typeof (*arr1) * _a2 = (arr2); \ | 1550 | const typeof (*arr1) * _a2 = (arr2); \ |
1527 | GNUNET_assert ((len1) + (len2) >= (len1)); \ | 1551 | GNUNET_assert ((len1) + (len2) >= (len1)); \ |
1528 | GNUNET_assert (SIZE_MAX / sizeof (*_a1) >= ((len1) + (len2))); \ | 1552 | GNUNET_assert (SIZE_MAX / sizeof (*_a1) >= ((len1) + (len2))); \ |
1529 | GNUNET_array_grow (arr1, len1, (len1) + (len2)); \ | 1553 | GNUNET_array_grow (arr1, len1, (len1) + (len2)); \ |
1530 | memcpy (&(arr1) [(len1) - (len2)], _a2, (len2) * sizeof (*arr1)); \ | 1554 | memcpy (&(arr1) [(len1) - (len2)], _a2, (len2) * sizeof (*arr1)); \ |
1531 | } while (0) | 1555 | } while (0) |
1532 | 1556 | ||
1533 | 1557 | ||
1534 | /** | 1558 | /** |
@@ -1579,7 +1603,9 @@ __attribute__ ((format (printf, 2, 3))); | |||
1579 | * @return allocated memory, never NULL | 1603 | * @return allocated memory, never NULL |
1580 | */ | 1604 | */ |
1581 | void * | 1605 | void * |
1582 | GNUNET_xmalloc_ (size_t size, const char *filename, int linenumber); | 1606 | GNUNET_xmalloc_ (size_t size, |
1607 | const char *filename, | ||
1608 | int linenumber); | ||
1583 | 1609 | ||
1584 | 1610 | ||
1585 | /** | 1611 | /** |
@@ -1659,7 +1685,9 @@ GNUNET_xmemdup_ (const void *buf, | |||
1659 | * @return pointer to size bytes of memory, NULL if we do not have enough memory | 1685 | * @return pointer to size bytes of memory, NULL if we do not have enough memory |
1660 | */ | 1686 | */ |
1661 | void * | 1687 | void * |
1662 | GNUNET_xmalloc_unchecked_ (size_t size, const char *filename, int linenumber); | 1688 | GNUNET_xmalloc_unchecked_ (size_t size, |
1689 | const char *filename, | ||
1690 | int linenumber); | ||
1663 | 1691 | ||
1664 | 1692 | ||
1665 | /** | 1693 | /** |
@@ -1667,7 +1695,10 @@ GNUNET_xmalloc_unchecked_ (size_t size, const char *filename, int linenumber); | |||
1667 | * memory is available. | 1695 | * memory is available. |
1668 | */ | 1696 | */ |
1669 | void * | 1697 | void * |
1670 | GNUNET_xrealloc_ (void *ptr, size_t n, const char *filename, int linenumber); | 1698 | GNUNET_xrealloc_ (void *ptr, |
1699 | size_t n, | ||
1700 | const char *filename, | ||
1701 | int linenumber); | ||
1671 | 1702 | ||
1672 | 1703 | ||
1673 | /** | 1704 | /** |
@@ -1680,7 +1711,9 @@ GNUNET_xrealloc_ (void *ptr, size_t n, const char *filename, int linenumber); | |||
1680 | * @param linenumber line where this call is being made (for debugging) | 1711 | * @param linenumber line where this call is being made (for debugging) |
1681 | */ | 1712 | */ |
1682 | void | 1713 | void |
1683 | GNUNET_xfree_ (void *ptr, const char *filename, int linenumber); | 1714 | GNUNET_xfree_ (void *ptr, |
1715 | const char *filename, | ||
1716 | int linenumber); | ||
1684 | 1717 | ||
1685 | 1718 | ||
1686 | /** | 1719 | /** |
@@ -1691,7 +1724,9 @@ GNUNET_xfree_ (void *ptr, const char *filename, int linenumber); | |||
1691 | * @return the duplicated string | 1724 | * @return the duplicated string |
1692 | */ | 1725 | */ |
1693 | char * | 1726 | char * |
1694 | GNUNET_xstrdup_ (const char *str, const char *filename, int linenumber); | 1727 | GNUNET_xstrdup_ (const char *str, |
1728 | const char *filename, | ||
1729 | int linenumber); | ||
1695 | 1730 | ||
1696 | /** | 1731 | /** |
1697 | * Dup partially a string. Don't call GNUNET_xstrndup_ directly. Use the #GNUNET_strndup macro. | 1732 | * Dup partially a string. Don't call GNUNET_xstrndup_ directly. Use the #GNUNET_strndup macro. |
@@ -1861,6 +1896,8 @@ enum GNUNET_SCHEDULER_Priority | |||
1861 | }; | 1896 | }; |
1862 | 1897 | ||
1863 | 1898 | ||
1899 | /* *INDENT-OFF* */ | ||
1900 | |||
1864 | #if 0 /* keep Emacsens' auto-indent happy */ | 1901 | #if 0 /* keep Emacsens' auto-indent happy */ |
1865 | { | 1902 | { |
1866 | #endif | 1903 | #endif |
@@ -1869,5 +1906,3 @@ enum GNUNET_SCHEDULER_Priority | |||
1869 | #endif | 1906 | #endif |
1870 | 1907 | ||
1871 | #endif /* GNUNET_COMMON_H */ | 1908 | #endif /* GNUNET_COMMON_H */ |
1872 | |||
1873 | /** @} */ /* end of group addition */ | ||
diff --git a/src/include/gnunet_configuration_lib.h b/src/include/gnunet_configuration_lib.h index 3b9be5849..132172516 100644 --- a/src/include/gnunet_configuration_lib.h +++ b/src/include/gnunet_configuration_lib.h | |||
@@ -66,7 +66,8 @@ GNUNET_CONFIGURATION_create (void); | |||
66 | * @return duplicate configuration | 66 | * @return duplicate configuration |
67 | */ | 67 | */ |
68 | struct GNUNET_CONFIGURATION_Handle * | 68 | struct GNUNET_CONFIGURATION_Handle * |
69 | GNUNET_CONFIGURATION_dup (const struct GNUNET_CONFIGURATION_Handle *cfg); | 69 | GNUNET_CONFIGURATION_dup ( |
70 | const struct GNUNET_CONFIGURATION_Handle *cfg); | ||
70 | 71 | ||
71 | 72 | ||
72 | /** | 73 | /** |
@@ -75,7 +76,8 @@ GNUNET_CONFIGURATION_dup (const struct GNUNET_CONFIGURATION_Handle *cfg); | |||
75 | * @param cfg configuration to destroy | 76 | * @param cfg configuration to destroy |
76 | */ | 77 | */ |
77 | void | 78 | void |
78 | GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg); | 79 | GNUNET_CONFIGURATION_destroy ( |
80 | struct GNUNET_CONFIGURATION_Handle *cfg); | ||
79 | 81 | ||
80 | 82 | ||
81 | /** | 83 | /** |
@@ -88,8 +90,9 @@ GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg); | |||
88 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 90 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
89 | */ | 91 | */ |
90 | enum GNUNET_GenericReturnValue | 92 | enum GNUNET_GenericReturnValue |
91 | GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg, | 93 | GNUNET_CONFIGURATION_load ( |
92 | const char *filename); | 94 | struct GNUNET_CONFIGURATION_Handle *cfg, |
95 | const char *filename); | ||
93 | 96 | ||
94 | 97 | ||
95 | /** | 98 | /** |
@@ -101,8 +104,9 @@ GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
101 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 104 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
102 | */ | 105 | */ |
103 | enum GNUNET_GenericReturnValue | 106 | enum GNUNET_GenericReturnValue |
104 | GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg, | 107 | GNUNET_CONFIGURATION_load_from ( |
105 | const char *defaults_d); | 108 | struct GNUNET_CONFIGURATION_Handle *cfg, |
109 | const char *defaults_d); | ||
106 | 110 | ||
107 | 111 | ||
108 | /** | 112 | /** |
@@ -138,8 +142,9 @@ GNUNET_CONFIGURATION_default_filename (void); | |||
138 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 142 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
139 | */ | 143 | */ |
140 | enum GNUNET_GenericReturnValue | 144 | enum GNUNET_GenericReturnValue |
141 | GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, | 145 | GNUNET_CONFIGURATION_parse ( |
142 | const char *filename); | 146 | struct GNUNET_CONFIGURATION_Handle *cfg, |
147 | const char *filename); | ||
143 | 148 | ||
144 | 149 | ||
145 | /** | 150 | /** |
@@ -151,8 +156,9 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
151 | * present. This memory should be freed by the caller | 156 | * present. This memory should be freed by the caller |
152 | */ | 157 | */ |
153 | char * | 158 | char * |
154 | GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg, | 159 | GNUNET_CONFIGURATION_serialize ( |
155 | size_t *size); | 160 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
161 | size_t *size); | ||
156 | 162 | ||
157 | 163 | ||
158 | /** | 164 | /** |
@@ -168,6 +174,7 @@ char * | |||
168 | GNUNET_CONFIGURATION_serialize_diagnostics ( | 174 | GNUNET_CONFIGURATION_serialize_diagnostics ( |
169 | const struct GNUNET_CONFIGURATION_Handle *cfg); | 175 | const struct GNUNET_CONFIGURATION_Handle *cfg); |
170 | 176 | ||
177 | |||
171 | /** | 178 | /** |
172 | * De-serializes configuration | 179 | * De-serializes configuration |
173 | * | 180 | * |
@@ -179,10 +186,11 @@ GNUNET_CONFIGURATION_serialize_diagnostics ( | |||
179 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 186 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
180 | */ | 187 | */ |
181 | enum GNUNET_GenericReturnValue | 188 | enum GNUNET_GenericReturnValue |
182 | GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, | 189 | GNUNET_CONFIGURATION_deserialize ( |
183 | const char *mem, | 190 | struct GNUNET_CONFIGURATION_Handle *cfg, |
184 | size_t size, | 191 | const char *mem, |
185 | const char *source_filename); | 192 | size_t size, |
193 | const char *source_filename); | ||
186 | 194 | ||
187 | 195 | ||
188 | /** | 196 | /** |
@@ -193,8 +201,9 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
193 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 201 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
194 | */ | 202 | */ |
195 | enum GNUNET_GenericReturnValue | 203 | enum GNUNET_GenericReturnValue |
196 | GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg, | 204 | GNUNET_CONFIGURATION_write ( |
197 | const char *filename); | 205 | struct GNUNET_CONFIGURATION_Handle *cfg, |
206 | const char *filename); | ||
198 | 207 | ||
199 | 208 | ||
200 | /** | 209 | /** |
@@ -233,7 +242,8 @@ GNUNET_CONFIGURATION_get_diff ( | |||
233 | * @return #GNUNET_NO if clean, #GNUNET_YES if dirty, #GNUNET_SYSERR on error (i.e. last save failed) | 242 | * @return #GNUNET_NO if clean, #GNUNET_YES if dirty, #GNUNET_SYSERR on error (i.e. last save failed) |
234 | */ | 243 | */ |
235 | enum GNUNET_GenericReturnValue | 244 | enum GNUNET_GenericReturnValue |
236 | GNUNET_CONFIGURATION_is_dirty (const struct GNUNET_CONFIGURATION_Handle *cfg); | 245 | GNUNET_CONFIGURATION_is_dirty ( |
246 | const struct GNUNET_CONFIGURATION_Handle *cfg); | ||
237 | 247 | ||
238 | 248 | ||
239 | /** | 249 | /** |
@@ -244,8 +254,9 @@ GNUNET_CONFIGURATION_is_dirty (const struct GNUNET_CONFIGURATION_Handle *cfg); | |||
244 | * @return status code | 254 | * @return status code |
245 | */ | 255 | */ |
246 | typedef enum GNUNET_GenericReturnValue | 256 | typedef enum GNUNET_GenericReturnValue |
247 | (*GNUNET_CONFIGURATION_Callback)(void *cls, | 257 | (*GNUNET_CONFIGURATION_Callback)( |
248 | const struct GNUNET_CONFIGURATION_Handle *cfg); | 258 | void *cls, |
259 | const struct GNUNET_CONFIGURATION_Handle *cfg); | ||
249 | 260 | ||
250 | 261 | ||
251 | /** | 262 | /** |
@@ -260,9 +271,10 @@ typedef enum GNUNET_GenericReturnValue | |||
260 | * otherwise return value from @a cb. | 271 | * otherwise return value from @a cb. |
261 | */ | 272 | */ |
262 | enum GNUNET_GenericReturnValue | 273 | enum GNUNET_GenericReturnValue |
263 | GNUNET_CONFIGURATION_parse_and_run (const char *filename, | 274 | GNUNET_CONFIGURATION_parse_and_run ( |
264 | GNUNET_CONFIGURATION_Callback cb, | 275 | const char *filename, |
265 | void *cb_cls); | 276 | GNUNET_CONFIGURATION_Callback cb, |
277 | void *cb_cls); | ||
266 | 278 | ||
267 | /** | 279 | /** |
268 | * Enable extra diagnostics. Will produce more log output | 280 | * Enable extra diagnostics. Will produce more log output |
@@ -309,9 +321,10 @@ typedef void | |||
309 | * @param iter_cls closure for @a iter | 321 | * @param iter_cls closure for @a iter |
310 | */ | 322 | */ |
311 | void | 323 | void |
312 | GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, | 324 | GNUNET_CONFIGURATION_iterate ( |
313 | GNUNET_CONFIGURATION_Iterator iter, | 325 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
314 | void *iter_cls); | 326 | GNUNET_CONFIGURATION_Iterator iter, |
327 | void *iter_cls); | ||
315 | 328 | ||
316 | 329 | ||
317 | /** | 330 | /** |
@@ -335,8 +348,9 @@ GNUNET_CONFIGURATION_iterate_sections ( | |||
335 | * @param section name of the section to remove | 348 | * @param section name of the section to remove |
336 | */ | 349 | */ |
337 | void | 350 | void |
338 | GNUNET_CONFIGURATION_remove_section (struct GNUNET_CONFIGURATION_Handle *cfg, | 351 | GNUNET_CONFIGURATION_remove_section ( |
339 | const char *section); | 352 | struct GNUNET_CONFIGURATION_Handle *cfg, |
353 | const char *section); | ||
340 | 354 | ||
341 | 355 | ||
342 | /** | 356 | /** |
@@ -596,10 +610,11 @@ GNUNET_CONFIGURATION_set_value_number (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
596 | * @param value value to set | 610 | * @param value value to set |
597 | */ | 611 | */ |
598 | void | 612 | void |
599 | GNUNET_CONFIGURATION_set_value_string (struct GNUNET_CONFIGURATION_Handle *cfg, | 613 | GNUNET_CONFIGURATION_set_value_string ( |
600 | const char *section, | 614 | struct GNUNET_CONFIGURATION_Handle *cfg, |
601 | const char *option, | 615 | const char *section, |
602 | const char *value); | 616 | const char *option, |
617 | const char *value); | ||
603 | 618 | ||
604 | 619 | ||
605 | /** | 620 | /** |
@@ -649,10 +664,8 @@ struct GNUNET_CONFIGURATION_ConfigSettings | |||
649 | { | 664 | { |
650 | 665 | ||
651 | /** | 666 | /** |
652 | * Must be set to the API version, i.e. | 667 | * Must be set to the API version, i.e. #GNUNET_UTIL_VERSION. Used to |
653 | * #GNUNET_UTIL_VERSION. Used to detect | 668 | * detect which version of the struct the client is using. |
654 | * which version of the struct the client | ||
655 | * is using. | ||
656 | */ | 669 | */ |
657 | unsigned int api_version; | 670 | unsigned int api_version; |
658 | 671 | ||
@@ -696,7 +709,6 @@ struct GNUNET_CONFIGURATION_ConfigSettings | |||
696 | */ | 709 | */ |
697 | int full; | 710 | int full; |
698 | 711 | ||
699 | |||
700 | /** | 712 | /** |
701 | * Return value from the operation, to be returned | 713 | * Return value from the operation, to be returned |
702 | * from 'main'. | 714 | * from 'main'. |
@@ -714,50 +726,52 @@ struct GNUNET_CONFIGURATION_ConfigSettings | |||
714 | * @param cs configuration settings to initialize | 726 | * @param cs configuration settings to initialize |
715 | */ | 727 | */ |
716 | #define GNUNET_CONFIGURATION_CONFIG_OPTIONS(cs) \ | 728 | #define GNUNET_CONFIGURATION_CONFIG_OPTIONS(cs) \ |
717 | GNUNET_GETOPT_option_flag ( \ | 729 | GNUNET_GETOPT_option_flag ( \ |
718 | 'F', \ | 730 | 'F', \ |
719 | "full", \ | 731 | "full", \ |
720 | gettext_noop ( \ | 732 | gettext_noop ( \ |
721 | "write the full configuration file, including default values"), \ | 733 | "write the full configuration file, including default values"), \ |
722 | &(cs)->full), \ | 734 | &(cs)->full), \ |
723 | GNUNET_GETOPT_option_flag ( \ | 735 | GNUNET_GETOPT_option_flag ( \ |
724 | 'f', \ | 736 | 'f', \ |
725 | "filename", \ | 737 | "filename", \ |
726 | gettext_noop ("interpret option value as a filename (with $-expansion)"), \ | 738 | gettext_noop ( \ |
727 | &(cs)->is_filename), \ | 739 | "interpret option value as a filename (with $-expansion)"), \ |
728 | GNUNET_GETOPT_option_string ('o', \ | 740 | &(cs)->is_filename), \ |
729 | "option", \ | 741 | GNUNET_GETOPT_option_string ('o', \ |
730 | "OPTION", \ | 742 | "option", \ |
731 | gettext_noop ("name of the option to access"), \ | 743 | "OPTION", \ |
732 | &(cs)->option), \ | 744 | gettext_noop ( \ |
733 | GNUNET_GETOPT_option_flag ( \ | 745 | "name of the option to access"), \ |
734 | 'r', \ | 746 | &(cs)->option), \ |
735 | "rewrite", \ | 747 | GNUNET_GETOPT_option_flag ( \ |
736 | gettext_noop ( \ | 748 | 'r', \ |
737 | "rewrite the configuration file, even if nothing changed"), \ | 749 | "rewrite", \ |
738 | &(cs)->rewrite), \ | 750 | gettext_noop ( \ |
739 | GNUNET_GETOPT_option_flag ( \ | 751 | "rewrite the configuration file, even if nothing changed"), \ |
740 | 'd', \ | 752 | &(cs)->rewrite), \ |
741 | "diagnostics", \ | 753 | GNUNET_GETOPT_option_flag ( \ |
742 | gettext_noop ( \ | 754 | 'd', \ |
743 | "output extra diagnostics"), \ | 755 | "diagnostics", \ |
744 | &(cs)->diagnostics), \ | 756 | gettext_noop ( \ |
745 | GNUNET_GETOPT_option_flag ('S', \ | 757 | "output extra diagnostics"), \ |
746 | "list-sections", \ | 758 | &(cs)->diagnostics), \ |
747 | gettext_noop ( \ | 759 | GNUNET_GETOPT_option_flag ('S', \ |
748 | "print available configuration sections"), \ | 760 | "list-sections", \ |
749 | &(cs)->list_sections), \ | 761 | gettext_noop ( \ |
750 | GNUNET_GETOPT_option_string ('s', \ | 762 | "print available configuration sections"), \ |
751 | "section", \ | 763 | &(cs)->list_sections), \ |
752 | "SECTION", \ | 764 | GNUNET_GETOPT_option_string ('s', \ |
753 | gettext_noop ( \ | 765 | "section", \ |
754 | "name of the section to access"), \ | 766 | "SECTION", \ |
755 | &(cs)->section), \ | 767 | gettext_noop ( \ |
756 | GNUNET_GETOPT_option_string ('V', \ | 768 | "name of the section to access"), \ |
757 | "value", \ | 769 | &(cs)->section), \ |
758 | "VALUE", \ | 770 | GNUNET_GETOPT_option_string ('V', \ |
759 | gettext_noop ("value to set"), \ | 771 | "value", \ |
760 | &(cs)->value) | 772 | "VALUE", \ |
773 | gettext_noop ("value to set"), \ | ||
774 | &(cs)->value) | ||
761 | 775 | ||
762 | 776 | ||
763 | /** | 777 | /** |
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 50937324d..b74bbcd1e 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h | |||
@@ -1736,6 +1736,15 @@ GNUNET_CRYPTO_edx25519_key_clear (struct GNUNET_CRYPTO_Edx25519PrivateKey *pk); | |||
1736 | void | 1736 | void |
1737 | GNUNET_CRYPTO_ecdhe_key_clear (struct GNUNET_CRYPTO_EcdhePrivateKey *pk); | 1737 | GNUNET_CRYPTO_ecdhe_key_clear (struct GNUNET_CRYPTO_EcdhePrivateKey *pk); |
1738 | 1738 | ||
1739 | /** | ||
1740 | * @ingroup crypto | ||
1741 | * Clear memory that was used to store a private key. | ||
1742 | * | ||
1743 | * @param pk location of the key | ||
1744 | */ | ||
1745 | void | ||
1746 | GNUNET_CRYPTO_private_key_clear (struct GNUNET_CRYPTO_PrivateKey *pk); | ||
1747 | |||
1739 | 1748 | ||
1740 | /** | 1749 | /** |
1741 | * @ingroup crypto | 1750 | * @ingroup crypto |
diff --git a/src/include/gnunet_getopt_lib.h b/src/include/gnunet_getopt_lib.h index 390e8c153..91ba362e5 100644 --- a/src/include/gnunet_getopt_lib.h +++ b/src/include/gnunet_getopt_lib.h | |||
@@ -33,7 +33,7 @@ | |||
33 | * @{ | 33 | * @{ |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #if !defined (__GNUNET_UTIL_LIB_H_INSIDE__) | 36 | #if ! defined (__GNUNET_UTIL_LIB_H_INSIDE__) |
37 | #error "Only <gnunet_util_lib.h> can be included directly." | 37 | #error "Only <gnunet_util_lib.h> can be included directly." |
38 | #endif | 38 | #endif |
39 | 39 | ||
@@ -275,12 +275,12 @@ GNUNET_GETOPT_option_base32_fixed_size (char shortName, | |||
275 | argumentHelp, \ | 275 | argumentHelp, \ |
276 | description, \ | 276 | description, \ |
277 | val) \ | 277 | val) \ |
278 | GNUNET_GETOPT_option_base32_fixed_size (shortName, \ | 278 | GNUNET_GETOPT_option_base32_fixed_size (shortName, \ |
279 | name, \ | 279 | name, \ |
280 | argumentHelp, \ | 280 | argumentHelp, \ |
281 | description, \ | 281 | description, \ |
282 | val, \ | 282 | val, \ |
283 | sizeof(*val)) | 283 | sizeof(*val)) |
284 | 284 | ||
285 | 285 | ||
286 | /** | 286 | /** |
@@ -481,9 +481,9 @@ GNUNET_GETOPT_option_exclusive (struct GNUNET_GETOPT_CommandLineOption opt); | |||
481 | * Marker for the end of the list of options. | 481 | * Marker for the end of the list of options. |
482 | */ | 482 | */ |
483 | #define GNUNET_GETOPT_OPTION_END \ | 483 | #define GNUNET_GETOPT_OPTION_END \ |
484 | { \ | 484 | { \ |
485 | '\0', NULL, NULL, NULL, 0, 0, 0, NULL, NULL, NULL \ | 485 | '\0', NULL, NULL, NULL, 0, 0, 0, NULL, NULL, NULL \ |
486 | } | 486 | } |
487 | 487 | ||
488 | 488 | ||
489 | /** | 489 | /** |
diff --git a/src/include/gnunet_gns_service.h b/src/include/gnunet_gns_service.h index 1f19e58ac..e7ed2d3c2 100644 --- a/src/include/gnunet_gns_service.h +++ b/src/include/gnunet_gns_service.h | |||
@@ -227,6 +227,16 @@ GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle, | |||
227 | void * | 227 | void * |
228 | GNUNET_GNS_lookup_with_tld_cancel (struct GNUNET_GNS_LookupWithTldRequest *ltr); | 228 | GNUNET_GNS_lookup_with_tld_cancel (struct GNUNET_GNS_LookupWithTldRequest *ltr); |
229 | 229 | ||
230 | /** | ||
231 | * Try to parse the zTLD into a public key. | ||
232 | * | ||
233 | * @param[in] name the name to parse | ||
234 | * @param[out] ztld_key the identity key (must be allocated by caller). Only set of #GNUNET_OK is returned. | ||
235 | * @return GNUNET_OK on success. | ||
236 | */ | ||
237 | enum GNUNET_GenericReturnValue | ||
238 | GNUNET_GNS_parse_ztld (const char *name, | ||
239 | struct GNUNET_CRYPTO_PublicKey *ztld_key); | ||
230 | 240 | ||
231 | #if 0 /* keep Emacsens' auto-indent happy */ | 241 | #if 0 /* keep Emacsens' auto-indent happy */ |
232 | { | 242 | { |
diff --git a/src/include/gnunet_helper_lib.h b/src/include/gnunet_helper_lib.h index c329c4a33..57630c45c 100644 --- a/src/include/gnunet_helper_lib.h +++ b/src/include/gnunet_helper_lib.h | |||
@@ -173,7 +173,7 @@ struct GNUNET_HELPER_SendHandle; | |||
173 | struct GNUNET_HELPER_SendHandle * | 173 | struct GNUNET_HELPER_SendHandle * |
174 | GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, | 174 | GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, |
175 | const struct GNUNET_MessageHeader *msg, | 175 | const struct GNUNET_MessageHeader *msg, |
176 | int can_drop, | 176 | bool can_drop, |
177 | GNUNET_HELPER_Continuation cont, | 177 | GNUNET_HELPER_Continuation cont, |
178 | void *cont_cls); | 178 | void *cont_cls); |
179 | 179 | ||
diff --git a/src/include/gnunet_json_lib.h b/src/include/gnunet_json_lib.h index 203976b5c..2059e127f 100644 --- a/src/include/gnunet_json_lib.h +++ b/src/include/gnunet_json_lib.h | |||
@@ -430,6 +430,39 @@ GNUNET_JSON_spec_rsa_signature (const char *name, | |||
430 | struct GNUNET_CRYPTO_RsaSignature **sig); | 430 | struct GNUNET_CRYPTO_RsaSignature **sig); |
431 | 431 | ||
432 | 432 | ||
433 | /** | ||
434 | * Specification for parsing a blinded message. | ||
435 | * | ||
436 | * @param name name of the JSON field | ||
437 | * @param sig where to store the blinded message found under @a name | ||
438 | */ | ||
439 | struct GNUNET_JSON_Specification | ||
440 | GNUNET_JSON_spec_blinded_message (const char *name, | ||
441 | struct GNUNET_CRYPTO_BlindedMessage **msg); | ||
442 | |||
443 | |||
444 | /** | ||
445 | * Specification for parsing a blinded signature. | ||
446 | * | ||
447 | * @param name name of the JSON field | ||
448 | * @param sig where to store the blinded signature found under @a name | ||
449 | */ | ||
450 | struct GNUNET_JSON_Specification | ||
451 | GNUNET_JSON_spec_blinded_signature (const char *field, | ||
452 | struct GNUNET_CRYPTO_BlindedSignature **b_sig); | ||
453 | |||
454 | |||
455 | /** | ||
456 | * Specification for parsing a unblinded signature. | ||
457 | * | ||
458 | * @param name name of the JSON field | ||
459 | * @param sig where to store the unblinded signature found under @a name | ||
460 | */ | ||
461 | struct GNUNET_JSON_Specification | ||
462 | GNUNET_JSON_spec_unblinded_signature (const char *field, | ||
463 | struct GNUNET_CRYPTO_UnblindedSignature **ub_sig); | ||
464 | |||
465 | |||
433 | /* ****************** Generic generator interface ******************* */ | 466 | /* ****************** Generic generator interface ******************* */ |
434 | 467 | ||
435 | 468 | ||
@@ -966,6 +999,44 @@ GNUNET_JSON_pack_rsa_signature (const char *name, | |||
966 | const struct GNUNET_CRYPTO_RsaSignature *sig); | 999 | const struct GNUNET_CRYPTO_RsaSignature *sig); |
967 | 1000 | ||
968 | 1001 | ||
1002 | /** | ||
1003 | * Generate packer instruction for a JSON field of type | ||
1004 | * unblinded signature. | ||
1005 | * | ||
1006 | * @param name name of the field to add to the object | ||
1007 | * @param sig unblinded signature | ||
1008 | * @return json pack specification | ||
1009 | */ | ||
1010 | struct GNUNET_JSON_PackSpec | ||
1011 | GNUNET_JSON_pack_unblinded_signature (const char *name, | ||
1012 | const struct GNUNET_CRYPTO_UnblindedSignature *sig); | ||
1013 | |||
1014 | |||
1015 | /** | ||
1016 | * Generate packer instruction for a JSON field of type | ||
1017 | * blinded message. | ||
1018 | * | ||
1019 | * @param name name of the field to add to the object | ||
1020 | * @param msg blinded message | ||
1021 | * @return json pack specification | ||
1022 | */ | ||
1023 | struct GNUNET_JSON_PackSpec | ||
1024 | GNUNET_JSON_pack_blinded_message (const char *name, | ||
1025 | const struct GNUNET_CRYPTO_BlindedMessage *msg); | ||
1026 | |||
1027 | |||
1028 | /** | ||
1029 | * Generate packer instruction for a JSON field of type | ||
1030 | * blinded signature. | ||
1031 | * | ||
1032 | * @param name name of the field to add to the object | ||
1033 | * @param sig blinded signature | ||
1034 | * @return json pack specification | ||
1035 | */ | ||
1036 | struct GNUNET_JSON_PackSpec | ||
1037 | GNUNET_JSON_pack_blinded_sig (const char *name, | ||
1038 | const struct GNUNET_CRYPTO_BlindedSignature *sig); | ||
1039 | |||
969 | #endif | 1040 | #endif |
970 | 1041 | ||
971 | /* end of gnunet_json_lib.h */ | 1042 | /* end of gnunet_json_lib.h */ |
diff --git a/src/include/gnunet_messenger_service.h b/src/include/gnunet_messenger_service.h index 1bc68b87b..3f039f944 100644 --- a/src/include/gnunet_messenger_service.h +++ b/src/include/gnunet_messenger_service.h | |||
@@ -39,21 +39,14 @@ extern "C" { | |||
39 | #endif | 39 | #endif |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | #include "gnunet_common.h" | ||
43 | #include "gnunet_configuration_lib.h" | ||
44 | #include "gnunet_identity_service.h" | ||
45 | #include "gnunet_reclaim_lib.h" | ||
46 | #include "gnunet_reclaim_service.h" | ||
47 | #include "gnunet_scheduler_lib.h" | ||
48 | #include "gnunet_time_lib.h" | ||
49 | #include "gnunet_util_lib.h" | 42 | #include "gnunet_util_lib.h" |
50 | 43 | ||
51 | /** | 44 | /** |
52 | * Version number of GNUnet Messenger API. | 45 | * Version number of GNUnet Messenger API. |
53 | * | 46 | * |
54 | * Current version of the Messenger: 0.3 | 47 | * Current version of the Messenger: 0.4 |
55 | */ | 48 | */ |
56 | #define GNUNET_MESSENGER_VERSION 0x00000003 | 49 | #define GNUNET_MESSENGER_VERSION 0x00000004 |
57 | 50 | ||
58 | /** | 51 | /** |
59 | * Identifier of GNUnet MESSENGER Service. | 52 | * Identifier of GNUnet MESSENGER Service. |
@@ -91,7 +84,7 @@ struct GNUNET_MESSENGER_RoomEntryRecord | |||
91 | /** | 84 | /** |
92 | * The hash identifying the port of the room. | 85 | * The hash identifying the port of the room. |
93 | */ | 86 | */ |
94 | struct GNUNET_HashCode key; | 87 | struct GNUNET_HashCode key GNUNET_PACKED; |
95 | }; | 88 | }; |
96 | 89 | ||
97 | GNUNET_NETWORK_STRUCT_END | 90 | GNUNET_NETWORK_STRUCT_END |
@@ -536,14 +529,14 @@ struct GNUNET_MESSENGER_MessageConnection | |||
536 | * A ticket message body | 529 | * A ticket message body |
537 | * This allows to exchange ticket identifiers with an audience. | 530 | * This allows to exchange ticket identifiers with an audience. |
538 | * | 531 | * |
539 | * Message-body-size: 32 bytes | 532 | * Message-body-size: 0+ bytes |
540 | */ | 533 | */ |
541 | struct GNUNET_MESSENGER_MessageTicket | 534 | struct GNUNET_MESSENGER_MessageTicket |
542 | { | 535 | { |
543 | /** | 536 | /** |
544 | * The identifier of a RECLAIM ticket. | 537 | * The identifier of a ticket. |
545 | */ | 538 | */ |
546 | struct GNUNET_RECLAIM_Identifier identifier; | 539 | char *identifier; |
547 | }; | 540 | }; |
548 | 541 | ||
549 | /** | 542 | /** |
@@ -1010,22 +1003,6 @@ GNUNET_MESSENGER_iterate_members (struct GNUNET_MESSENGER_Room *room, | |||
1010 | GNUNET_MESSENGER_MemberCallback callback, | 1003 | GNUNET_MESSENGER_MemberCallback callback, |
1011 | void *cls); | 1004 | void *cls); |
1012 | 1005 | ||
1013 | /** | ||
1014 | * Send a <i>ticket</i> into a <i>room</i>. The ticket will automatically be converted | ||
1015 | * into a message to be sent only to its audience as a private message. | ||
1016 | * | ||
1017 | * A ticket can only be sent with this function if its issuer's public key is the one | ||
1018 | * being used by the messenger. The audience's public key is not allowed to be the | ||
1019 | * anonymous public key. The room needs to contain a member using the audience's public | ||
1020 | * key. | ||
1021 | * | ||
1022 | * @param[in,out] room Room handle | ||
1023 | * @param[in] ticket Ticket to send | ||
1024 | */ | ||
1025 | void | ||
1026 | GNUNET_MESSENGER_send_ticket (struct GNUNET_MESSENGER_Room *room, | ||
1027 | const struct GNUNET_RECLAIM_Ticket *ticket); | ||
1028 | |||
1029 | #if 0 /* keep Emacsens' auto-indent happy */ | 1006 | #if 0 /* keep Emacsens' auto-indent happy */ |
1030 | { | 1007 | { |
1031 | #endif | 1008 | #endif |
diff --git a/src/include/gnunet_mq_lib.h b/src/include/gnunet_mq_lib.h index 3eca71f0f..b40693cdb 100644 --- a/src/include/gnunet_mq_lib.h +++ b/src/include/gnunet_mq_lib.h | |||
@@ -19,7 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include "gnunet_common.h" | 21 | #include "gnunet_common.h" |
22 | #if !defined (__GNUNET_UTIL_LIB_H_INSIDE__) | 22 | #if ! defined (__GNUNET_UTIL_LIB_H_INSIDE__) |
23 | #error "Only <gnunet_util_lib.h> can be included directly." | 23 | #error "Only <gnunet_util_lib.h> can be included directly." |
24 | #endif | 24 | #endif |
25 | 25 | ||
@@ -61,9 +61,9 @@ | |||
61 | * @return the MQ message | 61 | * @return the MQ message |
62 | */ | 62 | */ |
63 | #define GNUNET_MQ_msg_extra(mvar, esize, type) \ | 63 | #define GNUNET_MQ_msg_extra(mvar, esize, type) \ |
64 | GNUNET_MQ_msg_ (((struct GNUNET_MessageHeader **) &(mvar)), \ | 64 | GNUNET_MQ_msg_ (((struct GNUNET_MessageHeader **) &(mvar)), \ |
65 | (esize) + sizeof *(mvar), \ | 65 | (esize) + sizeof *(mvar), \ |
66 | (type)) | 66 | (type)) |
67 | 67 | ||
68 | /** | 68 | /** |
69 | * Allocate a GNUNET_MQ_Envelope. | 69 | * Allocate a GNUNET_MQ_Envelope. |
@@ -85,7 +85,7 @@ | |||
85 | * @param type type of the message | 85 | * @param type type of the message |
86 | */ | 86 | */ |
87 | #define GNUNET_MQ_msg_header(type) \ | 87 | #define GNUNET_MQ_msg_header(type) \ |
88 | GNUNET_MQ_msg_ (NULL, sizeof(struct GNUNET_MessageHeader), type) | 88 | GNUNET_MQ_msg_ (NULL, sizeof(struct GNUNET_MessageHeader), type) |
89 | 89 | ||
90 | 90 | ||
91 | /** | 91 | /** |
@@ -97,7 +97,8 @@ | |||
97 | * @param type type of the message | 97 | * @param type type of the message |
98 | */ | 98 | */ |
99 | #define GNUNET_MQ_msg_header_extra(mh, esize, type) \ | 99 | #define GNUNET_MQ_msg_header_extra(mh, esize, type) \ |
100 | GNUNET_MQ_msg_ (&mh, (esize) + sizeof(struct GNUNET_MessageHeader), type) | 100 | GNUNET_MQ_msg_ (&mh, (esize) + sizeof(struct GNUNET_MessageHeader), type \ |
101 | ) | ||
101 | 102 | ||
102 | 103 | ||
103 | /** | 104 | /** |
@@ -111,7 +112,7 @@ | |||
111 | * @return a newly allocated 'struct GNUNET_MQ_Envelope *' | 112 | * @return a newly allocated 'struct GNUNET_MQ_Envelope *' |
112 | */ | 113 | */ |
113 | #define GNUNET_MQ_msg_nested_mh(mvar, type, mh) \ | 114 | #define GNUNET_MQ_msg_nested_mh(mvar, type, mh) \ |
114 | ({ \ | 115 | ({ \ |
115 | struct GNUNET_MQ_Envelope *_ev; \ | 116 | struct GNUNET_MQ_Envelope *_ev; \ |
116 | _ev = GNUNET_MQ_msg_nested_mh_ ((struct GNUNET_MessageHeader **) &(mvar), \ | 117 | _ev = GNUNET_MQ_msg_nested_mh_ ((struct GNUNET_MessageHeader **) &(mvar), \ |
117 | sizeof(*(mvar)), \ | 118 | sizeof(*(mvar)), \ |
@@ -131,8 +132,8 @@ | |||
131 | * or NULL if the given message in @a var does not have any space after the message struct | 132 | * or NULL if the given message in @a var does not have any space after the message struct |
132 | */ | 133 | */ |
133 | #define GNUNET_MQ_extract_nested_mh(var) \ | 134 | #define GNUNET_MQ_extract_nested_mh(var) \ |
134 | GNUNET_MQ_extract_nested_mh_ ((struct GNUNET_MessageHeader *) (var), \ | 135 | GNUNET_MQ_extract_nested_mh_ ((struct GNUNET_MessageHeader *) (var), \ |
135 | sizeof(*(var))) | 136 | sizeof(*(var))) |
136 | 137 | ||
137 | 138 | ||
138 | /** | 139 | /** |
@@ -330,7 +331,7 @@ typedef void | |||
330 | * @return #GNUNET_OK if the message is well-formed, | 331 | * @return #GNUNET_OK if the message is well-formed, |
331 | * #GNUNET_SYSERR if not | 332 | * #GNUNET_SYSERR if not |
332 | */ | 333 | */ |
333 | typedef int | 334 | typedef enum GNUNET_GenericReturnValue |
334 | (*GNUNET_MQ_MessageValidationCallback) ( | 335 | (*GNUNET_MQ_MessageValidationCallback) ( |
335 | void *cls, | 336 | void *cls, |
336 | const struct GNUNET_MessageHeader *msg); | 337 | const struct GNUNET_MessageHeader *msg); |
@@ -530,9 +531,9 @@ struct GNUNET_MQ_MessageHandler | |||
530 | * End-marker for the handlers array | 531 | * End-marker for the handlers array |
531 | */ | 532 | */ |
532 | #define GNUNET_MQ_handler_end() \ | 533 | #define GNUNET_MQ_handler_end() \ |
533 | { \ | 534 | { \ |
534 | NULL, NULL, NULL, 0, 0 \ | 535 | NULL, NULL, NULL, 0, 0 \ |
535 | } | 536 | } |
536 | 537 | ||
537 | 538 | ||
538 | /** | 539 | /** |
@@ -564,7 +565,7 @@ struct GNUNET_MQ_MessageHandler | |||
564 | * @param ctx context for the callbacks | 565 | * @param ctx context for the callbacks |
565 | */ | 566 | */ |
566 | #define GNUNET_MQ_hd_fixed_size(name, code, str, ctx) \ | 567 | #define GNUNET_MQ_hd_fixed_size(name, code, str, ctx) \ |
567 | ({ \ | 568 | ({ \ |
568 | void (*_cb)(void *cls, const str *msg) = &handle_ ## name; \ | 569 | void (*_cb)(void *cls, const str *msg) = &handle_ ## name; \ |
569 | ((struct GNUNET_MQ_MessageHandler){ NULL, \ | 570 | ((struct GNUNET_MQ_MessageHandler){ NULL, \ |
570 | (GNUNET_MQ_MessageCallback) _cb, \ | 571 | (GNUNET_MQ_MessageCallback) _cb, \ |
@@ -616,7 +617,7 @@ struct GNUNET_MQ_MessageHandler | |||
616 | * @param ctx context for the callbacks | 617 | * @param ctx context for the callbacks |
617 | */ | 618 | */ |
618 | #define GNUNET_MQ_hd_var_size(name, code, str, ctx) \ | 619 | #define GNUNET_MQ_hd_var_size(name, code, str, ctx) \ |
619 | __extension__ ({ \ | 620 | __extension__ ({ \ |
620 | int (*_mv)(void *cls, const str *msg) = &check_ ## name; \ | 621 | int (*_mv)(void *cls, const str *msg) = &check_ ## name; \ |
621 | void (*_cb)(void *cls, const str *msg) = &handle_ ## name; \ | 622 | void (*_cb)(void *cls, const str *msg) = &handle_ ## name; \ |
622 | ((struct GNUNET_MQ_MessageHandler){ (GNUNET_MQ_MessageValidationCallback) \ | 623 | ((struct GNUNET_MQ_MessageHandler){ (GNUNET_MQ_MessageValidationCallback) \ |
@@ -639,17 +640,17 @@ struct GNUNET_MQ_MessageHandler | |||
639 | * the size, starting with a `struct GNUNET_MessageHeader` | 640 | * the size, starting with a `struct GNUNET_MessageHeader` |
640 | */ | 641 | */ |
641 | #define GNUNET_MQ_check_zero_termination(m) \ | 642 | #define GNUNET_MQ_check_zero_termination(m) \ |
642 | { \ | 643 | { \ |
643 | const char *str = (const char *) &m[1]; \ | 644 | const char *str = (const char *) &m[1]; \ |
644 | const struct GNUNET_MessageHeader *hdr = \ | 645 | const struct GNUNET_MessageHeader *hdr = \ |
645 | (const struct GNUNET_MessageHeader *) m; \ | 646 | (const struct GNUNET_MessageHeader *) m; \ |
646 | uint16_t slen = ntohs (hdr->size) - sizeof(*m); \ | 647 | uint16_t slen = ntohs (hdr->size) - sizeof(*m); \ |
647 | if ((0 == slen) || (memchr (str, 0, slen) != &str[slen - 1])) \ | 648 | if ((0 == slen) || (memchr (str, 0, slen) != &str[slen - 1])) \ |
648 | { \ | 649 | { \ |
649 | GNUNET_break (0); \ | 650 | GNUNET_break (0); \ |
650 | return GNUNET_NO; \ | 651 | return GNUNET_NO; \ |
651 | } \ | 652 | } \ |
652 | } | 653 | } |
653 | 654 | ||
654 | 655 | ||
655 | /** | 656 | /** |
@@ -665,19 +666,19 @@ struct GNUNET_MQ_MessageHandler | |||
665 | * the size, starting with a `struct GNUNET_MessageHeader` | 666 | * the size, starting with a `struct GNUNET_MessageHeader` |
666 | */ | 667 | */ |
667 | #define GNUNET_MQ_check_boxed_message(m) \ | 668 | #define GNUNET_MQ_check_boxed_message(m) \ |
668 | { \ | 669 | { \ |
669 | const struct GNUNET_MessageHeader *inbox = \ | 670 | const struct GNUNET_MessageHeader *inbox = \ |
670 | (const struct GNUNET_MessageHeader *) &m[1]; \ | 671 | (const struct GNUNET_MessageHeader *) &m[1]; \ |
671 | const struct GNUNET_MessageHeader *hdr = \ | 672 | const struct GNUNET_MessageHeader *hdr = \ |
672 | (const struct GNUNET_MessageHeader *) m; \ | 673 | (const struct GNUNET_MessageHeader *) m; \ |
673 | uint16_t slen = ntohs (hdr->size) - sizeof(*m); \ | 674 | uint16_t slen = ntohs (hdr->size) - sizeof(*m); \ |
674 | if ((slen < sizeof(struct GNUNET_MessageHeader)) || \ | 675 | if ((slen < sizeof(struct GNUNET_MessageHeader)) || \ |
675 | (slen != ntohs (inbox->size))) \ | 676 | (slen != ntohs (inbox->size))) \ |
676 | { \ | 677 | { \ |
677 | GNUNET_break (0); \ | 678 | GNUNET_break (0); \ |
678 | return GNUNET_NO; \ | 679 | return GNUNET_NO; \ |
679 | } \ | 680 | } \ |
680 | } | 681 | } |
681 | 682 | ||
682 | 683 | ||
683 | /** | 684 | /** |
diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h index 8b4077d0e..7501bee12 100644 --- a/src/include/gnunet_pq_lib.h +++ b/src/include/gnunet_pq_lib.h | |||
@@ -1136,7 +1136,7 @@ GNUNET_PQ_result_spec_array_string ( | |||
1136 | struct GNUNET_PQ_ResultSpec | 1136 | struct GNUNET_PQ_ResultSpec |
1137 | GNUNET_PQ_result_spec_blind_sign_pub ( | 1137 | GNUNET_PQ_result_spec_blind_sign_pub ( |
1138 | const char *name, | 1138 | const char *name, |
1139 | struct GNUNET_CRYPTO_BlindSignPublicKey *public_key); | 1139 | struct GNUNET_CRYPTO_BlindSignPublicKey **public_key); |
1140 | 1140 | ||
1141 | 1141 | ||
1142 | /** | 1142 | /** |
@@ -1149,7 +1149,7 @@ GNUNET_PQ_result_spec_blind_sign_pub ( | |||
1149 | struct GNUNET_PQ_ResultSpec | 1149 | struct GNUNET_PQ_ResultSpec |
1150 | GNUNET_PQ_result_spec_blind_sign_priv ( | 1150 | GNUNET_PQ_result_spec_blind_sign_priv ( |
1151 | const char *name, | 1151 | const char *name, |
1152 | struct GNUNET_CRYPTO_BlindSignPrivateKey *private_key); | 1152 | struct GNUNET_CRYPTO_BlindSignPrivateKey **private_key); |
1153 | 1153 | ||
1154 | /* ************************* pq.c functions ************************ */ | 1154 | /* ************************* pq.c functions ************************ */ |
1155 | 1155 | ||
diff --git a/src/include/gnunet_reclaim_service.h b/src/include/gnunet_reclaim_service.h index a8ab8776e..086c3f021 100644 --- a/src/include/gnunet_reclaim_service.h +++ b/src/include/gnunet_reclaim_service.h | |||
@@ -49,7 +49,7 @@ extern "C" { | |||
49 | /** | 49 | /** |
50 | * Version number of the re:claimID API. | 50 | * Version number of the re:claimID API. |
51 | */ | 51 | */ |
52 | #define GNUNET_RECLAIM_VERSION 0x00000001 | 52 | #define GNUNET_RECLAIM_VERSION 0x00000002 |
53 | 53 | ||
54 | /** | 54 | /** |
55 | * Opaque handle to access the service. | 55 | * Opaque handle to access the service. |
@@ -62,6 +62,9 @@ struct GNUNET_RECLAIM_Handle; | |||
62 | */ | 62 | */ |
63 | struct GNUNET_RECLAIM_Operation; | 63 | struct GNUNET_RECLAIM_Operation; |
64 | 64 | ||
65 | #define GNUNET_RECLAIM_TICKET_RP_URI_MAX_LEN 256 | ||
66 | |||
67 | #define GNUNET_RECLAIM_TICKET_RP_URI_URN_PREFIX "urn:gns:" | ||
65 | 68 | ||
66 | /** | 69 | /** |
67 | * The authorization ticket. This ticket is meant to be transferred | 70 | * The authorization ticket. This ticket is meant to be transferred |
@@ -72,19 +75,30 @@ struct GNUNET_RECLAIM_Operation; | |||
72 | struct GNUNET_RECLAIM_Ticket | 75 | struct GNUNET_RECLAIM_Ticket |
73 | { | 76 | { |
74 | /** | 77 | /** |
75 | * The ticket issuer (= the user) | 78 | * The ticket. A GNS name ending in the |
79 | * zTLD for identity. | ||
80 | * Base32(rnd).zTLD(identity) | ||
81 | * 0-terminated string. | ||
76 | */ | 82 | */ |
77 | struct GNUNET_CRYPTO_PublicKey identity; | 83 | char gns_name[GNUNET_DNSPARSER_MAX_LABEL_LENGTH * 2 + 2]; |
78 | 84 | ||
79 | /** | 85 | /** |
80 | * The ticket audience (= relying party) | 86 | * The ticket issuer (= the user) |
81 | */ | 87 | */ |
82 | struct GNUNET_CRYPTO_PublicKey audience; | 88 | //struct GNUNET_CRYPTO_PublicKey identity; |
83 | 89 | ||
84 | /** | 90 | /** |
85 | * The ticket random identifier | 91 | * The ticket random identifier |
86 | */ | 92 | */ |
87 | struct GNUNET_RECLAIM_Identifier rnd; | 93 | //struct GNUNET_RECLAIM_Identifier rnd; |
94 | |||
95 | |||
96 | /** | ||
97 | * Followed by the ticket audience (= relying party) URI. | ||
98 | * 0-terminated string. | ||
99 | * Example: "urn:gns:000G002B4RF1XPBXDPGZA0PT16BHQCS427YQK4NC84KZMK7TK8C2Z5GMK8" | ||
100 | */ | ||
101 | //char rp_uri[GNUNET_RECLAIM_TICKET_RP_URI_MAX_LEN]; | ||
88 | }; | 102 | }; |
89 | 103 | ||
90 | 104 | ||
@@ -95,10 +109,12 @@ struct GNUNET_RECLAIM_Ticket | |||
95 | * | 109 | * |
96 | * @param cls closure | 110 | * @param cls closure |
97 | * @param ticket the ticket | 111 | * @param ticket the ticket |
112 | * @param rp_uri the RP URI of the ticket | ||
98 | */ | 113 | */ |
99 | typedef void (*GNUNET_RECLAIM_TicketCallback) ( | 114 | typedef void (*GNUNET_RECLAIM_TicketCallback) ( |
100 | void *cls, | 115 | void *cls, |
101 | const struct GNUNET_RECLAIM_Ticket *ticket); | 116 | const struct GNUNET_RECLAIM_Ticket *ticket, |
117 | const char* rp_uri); | ||
102 | 118 | ||
103 | /** | 119 | /** |
104 | * Method called when a token has been issued. | 120 | * Method called when a token has been issued. |
@@ -376,7 +392,7 @@ GNUNET_RECLAIM_get_credentials_stop ( | |||
376 | * | 392 | * |
377 | * @param h the identity provider to use | 393 | * @param h the identity provider to use |
378 | * @param iss the issuing identity (= the user) | 394 | * @param iss the issuing identity (= the user) |
379 | * @param rp the subject of the ticket (= the relying party) | 395 | * @param rp_uri the subject of the ticket (= the relying party) see #GNUNET_RECLAIM_Ticket |
380 | * @param attrs the attributes that the relying party is given access to | 396 | * @param attrs the attributes that the relying party is given access to |
381 | * @param cb the callback | 397 | * @param cb the callback |
382 | * @param cb_cls the callback closure | 398 | * @param cb_cls the callback closure |
@@ -386,7 +402,7 @@ struct GNUNET_RECLAIM_Operation * | |||
386 | GNUNET_RECLAIM_ticket_issue ( | 402 | GNUNET_RECLAIM_ticket_issue ( |
387 | struct GNUNET_RECLAIM_Handle *h, | 403 | struct GNUNET_RECLAIM_Handle *h, |
388 | const struct GNUNET_CRYPTO_PrivateKey *iss, | 404 | const struct GNUNET_CRYPTO_PrivateKey *iss, |
389 | const struct GNUNET_CRYPTO_PublicKey *rp, | 405 | const char *rp_uri, |
390 | const struct GNUNET_RECLAIM_AttributeList *attrs, | 406 | const struct GNUNET_RECLAIM_AttributeList *attrs, |
391 | GNUNET_RECLAIM_IssueTicketCallback cb, void *cb_cls); | 407 | GNUNET_RECLAIM_IssueTicketCallback cb, void *cb_cls); |
392 | 408 | ||
@@ -417,9 +433,8 @@ GNUNET_RECLAIM_ticket_revoke ( | |||
417 | * information from the issuer | 433 | * information from the issuer |
418 | * | 434 | * |
419 | * @param h the identity provider to use | 435 | * @param h the identity provider to use |
420 | * @param identity the identity that is the subject of the issued ticket (the | ||
421 | * relying party) | ||
422 | * @param ticket the issued ticket to consume | 436 | * @param ticket the issued ticket to consume |
437 | * @param rp_uri the RP URI | ||
423 | * @param cb the callback to call | 438 | * @param cb the callback to call |
424 | * @param cb_cls the callback closure | 439 | * @param cb_cls the callback closure |
425 | * @return handle to abort the operation | 440 | * @return handle to abort the operation |
@@ -427,8 +442,8 @@ GNUNET_RECLAIM_ticket_revoke ( | |||
427 | struct GNUNET_RECLAIM_Operation * | 442 | struct GNUNET_RECLAIM_Operation * |
428 | GNUNET_RECLAIM_ticket_consume ( | 443 | GNUNET_RECLAIM_ticket_consume ( |
429 | struct GNUNET_RECLAIM_Handle *h, | 444 | struct GNUNET_RECLAIM_Handle *h, |
430 | const struct GNUNET_CRYPTO_PrivateKey *identity, | ||
431 | const struct GNUNET_RECLAIM_Ticket *ticket, | 445 | const struct GNUNET_RECLAIM_Ticket *ticket, |
446 | const char *rp_uri, | ||
432 | GNUNET_RECLAIM_AttributeTicketResult cb, void *cb_cls); | 447 | GNUNET_RECLAIM_AttributeTicketResult cb, void *cb_cls); |
433 | 448 | ||
434 | 449 | ||
@@ -499,44 +514,6 @@ GNUNET_RECLAIM_disconnect (struct GNUNET_RECLAIM_Handle *h); | |||
499 | void | 514 | void |
500 | GNUNET_RECLAIM_cancel (struct GNUNET_RECLAIM_Operation *op); | 515 | GNUNET_RECLAIM_cancel (struct GNUNET_RECLAIM_Operation *op); |
501 | 516 | ||
502 | /** | ||
503 | * Get serialized ticket size | ||
504 | * | ||
505 | * @param tkt the ticket | ||
506 | * @return the buffer length requirement for a serialization | ||
507 | */ | ||
508 | size_t | ||
509 | GNUNET_RECLAIM_ticket_serialize_get_size (const struct GNUNET_RECLAIM_Ticket *tkt); | ||
510 | |||
511 | /** | ||
512 | * Deserializes a ticket | ||
513 | * | ||
514 | * @param buffer the buffer to read from | ||
515 | * @param len the length of the buffer | ||
516 | * @param tkt the ticket to write to (must be allocated) | ||
517 | * @param kb_read how many bytes were read from buffer | ||
518 | * @return GNUNET_SYSERR on error | ||
519 | */ | ||
520 | enum GNUNET_GenericReturnValue | ||
521 | GNUNET_RECLAIM_read_ticket_from_buffer (const void *buffer, | ||
522 | size_t len, | ||
523 | struct GNUNET_RECLAIM_Ticket *tkt, | ||
524 | size_t *tb_read); | ||
525 | |||
526 | /** | ||
527 | * Serializes a ticket | ||
528 | * | ||
529 | * @param tkt the ticket to serialize | ||
530 | * @param buffer the buffer to serialize to (must be allocated with sufficient size | ||
531 | * @param len the length of the buffer | ||
532 | * @return the number of written bytes or < 0 on error | ||
533 | */ | ||
534 | ssize_t | ||
535 | GNUNET_RECLAIM_write_ticket_to_buffer (const struct | ||
536 | GNUNET_RECLAIM_Ticket *tkt, | ||
537 | void *buffer, | ||
538 | size_t len); | ||
539 | |||
540 | #if 0 /* keep Emacsens' auto-indent happy */ | 517 | #if 0 /* keep Emacsens' auto-indent happy */ |
541 | { | 518 | { |
542 | #endif | 519 | #endif |
diff --git a/src/include/gnunet_testbed_lib.h b/src/include/gnunet_testbed_lib.h new file mode 100644 index 000000000..e33f31ee1 --- /dev/null +++ b/src/include/gnunet_testbed_lib.h | |||
@@ -0,0 +1,130 @@ | |||
1 | #ifndef GNUNET_TESTBED_LIB_H | ||
2 | #define GNUNET_TESTBED_LIB_H | ||
3 | |||
4 | /** | ||
5 | * FIXME. | ||
6 | */ | ||
7 | struct GNUNET_TESTBED_System; | ||
8 | |||
9 | #define GNUNET_TESTBED_PREFIX "GNUNET_TESTBED_PREFIX" | ||
10 | |||
11 | /** | ||
12 | * Create a system handle. There must only be one system | ||
13 | * handle per operating system. | ||
14 | * | ||
15 | * @param testdir only the directory name without any path. This is used for | ||
16 | * all service homes; the directory will be created in a temporary | ||
17 | * location depending on the underlying OS. This variable will be | ||
18 | * overridden with the value of the environmental variable | ||
19 | * GNUNET_TESTBED_PREFIX, if it exists. | ||
20 | * @param trusted_ip the ip address which will be set as TRUSTED HOST in all | ||
21 | * service configurations generated to allow control connections from | ||
22 | * this ip. This can either be a single ip address or a network address | ||
23 | * in CIDR notation. | ||
24 | * @param hostname the hostname of the system we are using for testing; NULL for | ||
25 | * localhost | ||
26 | * @param lowport lowest port number this system is allowed to allocate (inclusive) | ||
27 | * @param highport highest port number this system is allowed to allocate (exclusive) | ||
28 | * @return handle to this system, NULL on error | ||
29 | */ | ||
30 | struct GNUNET_TESTBED_System * | ||
31 | GNUNET_TESTBED_system_create_with_portrange ( | ||
32 | const char *testdir, | ||
33 | const char *trusted_ip, | ||
34 | const char *hostname, | ||
35 | uint16_t lowport, | ||
36 | uint16_t highport); | ||
37 | |||
38 | |||
39 | /** | ||
40 | * Create a system handle. There must only be one system handle per operating | ||
41 | * system. Uses a default range for allowed ports. Ports are still tested for | ||
42 | * availability. | ||
43 | * | ||
44 | * @param testdir only the directory name without any path. This is used for all | ||
45 | * service homes; the directory will be created in a temporary location | ||
46 | * depending on the underlying OS. This variable will be | ||
47 | * overridden with the value of the environmental variable | ||
48 | * GNUNET_TESTBED_PREFIX, if it exists. | ||
49 | * @param trusted_ip the ip address which will be set as TRUSTED HOST in all | ||
50 | * service configurations generated to allow control connections from | ||
51 | * this ip. This can either be a single ip address or a network address | ||
52 | * in CIDR notation. | ||
53 | * @param hostname the hostname of the system we are using for testing; NULL for | ||
54 | * localhost | ||
55 | * @param shared_services NULL terminated array describing services that are to | ||
56 | * be shared among peers | ||
57 | * @return handle to this system, NULL on error | ||
58 | */ | ||
59 | struct GNUNET_TESTBED_System * | ||
60 | GNUNET_TESTBED_system_create ( | ||
61 | const char *testdir, | ||
62 | const char *trusted_ip, | ||
63 | const char *hostname); | ||
64 | |||
65 | |||
66 | /** | ||
67 | * Free system resources. | ||
68 | * | ||
69 | * @param system system to be freed | ||
70 | * @param remove_paths should the 'testdir' and all subdirectories | ||
71 | * be removed (clean up on shutdown)? | ||
72 | */ | ||
73 | void | ||
74 | GNUNET_TESTBED_system_destroy ( | ||
75 | struct GNUNET_TESTBED_System *system, | ||
76 | bool remove_paths); | ||
77 | |||
78 | |||
79 | /** | ||
80 | * Reserve a TCP or UDP port for a peer. | ||
81 | * | ||
82 | * @param system system to use for reservation tracking | ||
83 | * @return 0 if no free port was available | ||
84 | */ | ||
85 | uint16_t | ||
86 | GNUNET_TESTBED_reserve_port ( | ||
87 | struct GNUNET_TESTBED_System *system); | ||
88 | |||
89 | |||
90 | /** | ||
91 | * Release reservation of a TCP or UDP port for a peer | ||
92 | * (used during #GNUNET_TESTBED_peer_destroy()). | ||
93 | * | ||
94 | * @param system system to use for reservation tracking | ||
95 | * @param port reserved port to release | ||
96 | */ | ||
97 | void | ||
98 | GNUNET_TESTBED_release_port ( | ||
99 | struct GNUNET_TESTBED_System *system, | ||
100 | uint16_t port); | ||
101 | |||
102 | |||
103 | /** | ||
104 | * Create a new configuration using the given configuration as a template; | ||
105 | * ports and paths will be modified to select available ports on the local | ||
106 | * system. The default configuration will be available in PATHS section under | ||
107 | * the option DEFAULTCONFIG after the call. GNUNET_HOME is also set in PATHS | ||
108 | * section to the temporary directory specific to this configuration. If we run | ||
109 | * out of "*port" numbers, return #GNUNET_SYSERR. | ||
110 | * | ||
111 | * This is primarily a helper function used internally | ||
112 | * by 'GNUNET_TESTBED_peer_configure'. | ||
113 | * | ||
114 | * @param system system to use to coordinate resource usage | ||
115 | * @param cfg template configuration to update | ||
116 | * @param ports array with port numbers used in the created configuration. | ||
117 | * Will be updated upon successful return. Can be NULL | ||
118 | * @param nports the size of the `ports' array. Will be updated. | ||
119 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - the configuration will | ||
120 | * be incomplete and should not be used there upon | ||
121 | */ | ||
122 | enum GNUNET_GenericReturnValue | ||
123 | GNUNET_TESTBED_configuration_create ( | ||
124 | struct GNUNET_TESTBED_System *system, | ||
125 | struct GNUNET_CONFIGURATION_Handle *cfg, | ||
126 | uint16_t **ports, | ||
127 | unsigned int *nports); | ||
128 | |||
129 | |||
130 | #endif | ||
diff --git a/src/include/gnunet_testing_arm_lib.h b/src/include/gnunet_testing_arm_lib.h new file mode 100644 index 000000000..abc5d187a --- /dev/null +++ b/src/include/gnunet_testing_arm_lib.h | |||
@@ -0,0 +1,47 @@ | |||
1 | #ifndef GNUNET_TESTING_ARM_LIB_H | ||
2 | #define GNUNET_TESTING_ARM_LIB_H | ||
3 | |||
4 | #include "gnunet_arm_service.h" | ||
5 | |||
6 | /** | ||
7 | * Create command. | ||
8 | * | ||
9 | * @param label name for command. | ||
10 | * @param system_label Label of the cmd to setup a test environment. | ||
11 | * @param cfgname Configuration file name for this peer. | ||
12 | * @return command. | ||
13 | */ | ||
14 | struct GNUNET_TESTING_Command | ||
15 | GNUNET_TESTING_ARM_cmd_start_peer ( | ||
16 | const char *label, | ||
17 | const char *system_label, | ||
18 | const char *cfgname); | ||
19 | |||
20 | |||
21 | /** | ||
22 | * Create command. | ||
23 | * | ||
24 | * @param label name for command. | ||
25 | * @param start_label Label of the cmd to start the peer. | ||
26 | * @return command. | ||
27 | */ | ||
28 | struct GNUNET_TESTING_Command | ||
29 | GNUNET_TESTING_cmd_stop_peer ( | ||
30 | const char *label, | ||
31 | const char *start_label); | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Call #op on all simple traits. | ||
36 | */ | ||
37 | #define GNUNET_TESTING_ARM_SIMPLE_TRAITS(op, prefix) \ | ||
38 | op (prefix, \ | ||
39 | arm_handle, \ | ||
40 | const struct GNUNET_ARM_Handle) | ||
41 | |||
42 | |||
43 | GNUNET_TESTING_ARM_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT, | ||
44 | GNUNET_TESTING_ARM) | ||
45 | |||
46 | |||
47 | #endif | ||
diff --git a/src/include/gnunet_testing_barrier.h b/src/include/gnunet_testing_barrier.h deleted file mode 100644 index b0f4e1c03..000000000 --- a/src/include/gnunet_testing_barrier.h +++ /dev/null | |||
@@ -1,122 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2022 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 include/gnunet_testing_barrier.h | ||
23 | * @brief API to manage barriers. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | |||
27 | #ifndef GNUNET_TESTING_BARRIER_LIB_H | ||
28 | #define GNUNET_TESTING_BARRIER_LIB_H | ||
29 | |||
30 | #include "gnunet_testing_plugin.h" | ||
31 | |||
32 | |||
33 | struct GNUNET_TESTING_Barrier; | ||
34 | |||
35 | |||
36 | #define GNUNET_TESTING_BARRIER_MAX 32 | ||
37 | |||
38 | /** | ||
39 | * An entry for a barrier list | ||
40 | * FIXME: why is this in the public API!??! | ||
41 | */ | ||
42 | struct GNUNET_TESTING_BarrierListEntry | ||
43 | { | ||
44 | /* DLL */ | ||
45 | struct GNUNET_TESTING_BarrierListEntry *next; | ||
46 | |||
47 | /* DLL */ | ||
48 | struct GNUNET_TESTING_BarrierListEntry *prev; | ||
49 | |||
50 | /* The barrier name*/ | ||
51 | char *barrier_name; | ||
52 | |||
53 | /** | ||
54 | * Number of commands attached to the barrier. | ||
55 | */ | ||
56 | unsigned int expected_reaches; | ||
57 | }; | ||
58 | |||
59 | /** | ||
60 | * A list to hold barriers provided by plugins | ||
61 | * FIXME: why is this in the public API!??! | ||
62 | */ | ||
63 | struct GNUNET_TESTING_BarrierList | ||
64 | { | ||
65 | /** List head **/ | ||
66 | struct GNUNET_TESTING_BarrierListEntry *head; | ||
67 | |||
68 | /** List tail **/ | ||
69 | struct GNUNET_TESTING_BarrierListEntry *tail; | ||
70 | }; | ||
71 | |||
72 | |||
73 | /** | ||
74 | * Command to create a barrier. | ||
75 | * | ||
76 | * FIXME: high-level it is baffling how we need both the GNUNET_TESTING_Barrier | ||
77 | * and the Command that creates barriers. Conceptually this seems to be | ||
78 | * very much separate. Can we move _Barrier completely into testing as private? | ||
79 | * | ||
80 | * @param label The label of this command. | ||
81 | * @param percentage_to_be_reached If this percentage of processes reached | ||
82 | * this barrier, all processes waiting at | ||
83 | * this barrier can pass it. Must not be | ||
84 | * used together with number_to_be_reached. | ||
85 | * @param number_to_be_reached If this number of processes reached | ||
86 | * this barrier, all processes waiting at | ||
87 | * this barrier can pass it. Must not be | ||
88 | * used together with percentage_to_be_reached. | ||
89 | */ | ||
90 | struct GNUNET_TESTING_Command | ||
91 | GNUNET_TESTING_cmd_barrier_create ( | ||
92 | const char *label, | ||
93 | double percentage_to_be_reached, | ||
94 | unsigned int number_to_be_reached); | ||
95 | |||
96 | |||
97 | /** | ||
98 | * If this command is executed the the process is signaling the master process | ||
99 | * that it reached a barrier. If this command is synchronous it will block. | ||
100 | * | ||
101 | * FIXME: Now this, as it returns a Command, seems to me like it should be | ||
102 | * part of the public API? | ||
103 | * | ||
104 | * @param label name for command. | ||
105 | * @param barrier_label The name of the barrier we waited for and which was reached. | ||
106 | * @param asynchronous_finish If #GNUNET_YES this command will not block. | ||
107 | * @param node_number The global number of the node the cmd runs on. | ||
108 | * @param running_on_master Is this cmd running on the master loop? | ||
109 | * @param write_message Callback to write messages to the master loop. | ||
110 | * @return command. | ||
111 | */ | ||
112 | struct GNUNET_TESTING_Command | ||
113 | GNUNET_TESTING_cmd_barrier_reached ( | ||
114 | const char *label, | ||
115 | const char *barrier_label, | ||
116 | unsigned int asynchronous_finish, /* FIXME: why not a bool? */ | ||
117 | unsigned int node_number, | ||
118 | unsigned int running_on_master, /* FIXME: why not a bool? */ | ||
119 | GNUNET_TESTING_cmd_helper_write_cb write_message); /* FIXME: no 'cls' closure argument!? */ | ||
120 | |||
121 | #endif | ||
122 | /* end of testing_barrier.h */ | ||
diff --git a/src/include/gnunet_core_testing_lib.h b/src/include/gnunet_testing_core_lib.h index bf6f416d9..bf6f416d9 100644 --- a/src/include/gnunet_core_testing_lib.h +++ b/src/include/gnunet_testing_core_lib.h | |||
diff --git a/src/include/gnunet_testing_lib.h b/src/include/gnunet_testing_lib.h index 0d74de8c2..0ee3a68b8 100644 --- a/src/include/gnunet_testing_lib.h +++ b/src/include/gnunet_testing_lib.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2008, 2009, 2012 GNUnet e.V. | 3 | Copyright (C) 2021, 2023, 2024 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 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 | 6 | under the terms of the GNU Affero General Public License as published |
@@ -19,445 +19,959 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @addtogroup Testing | 22 | * @brief Central interpreter and command loop for writing an interpreter to test asynchronous systems |
23 | * @{ | 23 | * @author Christian Grothoff <christian@grothoff.org> |
24 | * | 24 | * @author Marcello Stanisci |
25 | * @author Christian Grothoff | 25 | * @author t3sserakt |
26 | * | 26 | */ |
27 | * @file | 27 | #ifndef GNUNET_TESTING_LIB_H |
28 | * Convenience API for writing testcases for GNUnet | 28 | #define GNUNET_TESTING_LIB_H |
29 | |||
30 | #include "gnunet_util_lib.h" | ||
31 | |||
32 | /** | ||
33 | * Maximum length of label in command | ||
34 | */ | ||
35 | #define GNUNET_TESTING_CMD_MAX_LABEL_LENGTH 127 | ||
36 | |||
37 | /* ********************* Helper functions ********************* */ | ||
38 | |||
39 | /** | ||
40 | * Print failing line number and trigger shutdown. Useful | ||
41 | * quite any time after the command "run" method has been called. | ||
42 | * Returns from the current function. | ||
43 | */ | ||
44 | #define GNUNET_TESTING_FAIL(is) \ | ||
45 | do { \ | ||
46 | GNUNET_break (0); \ | ||
47 | GNUNET_TESTING_interpreter_fail (is); \ | ||
48 | return; \ | ||
49 | } while (0) | ||
50 | |||
51 | |||
52 | /** | ||
53 | * Log an error message about a command not having run to completion. | ||
29 | * | 54 | * |
30 | * @defgroup testing Testing library | 55 | * @param is interpreter |
31 | * Library for writing testcases for GNUnet. | 56 | * @param label command label of the incomplete command |
57 | */ | ||
58 | #define GNUNET_TESTING_command_incomplete(is,label) \ | ||
59 | do { \ | ||
60 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ | ||
61 | "Command %s (%s:%u) did not complete (at %s)\n", \ | ||
62 | label, \ | ||
63 | __FILE__, \ | ||
64 | __LINE__, \ | ||
65 | GNUNET_TESTING_interpreter_current_cmd_get_label (is)); \ | ||
66 | } while (0) | ||
67 | |||
68 | |||
69 | /* ******************* Generic interpreter logic ************ */ | ||
70 | |||
71 | /** | ||
72 | * Global state of the interpreter, used by a command | ||
73 | * to access information about other commands. | ||
74 | */ | ||
75 | struct GNUNET_TESTING_Interpreter; | ||
76 | |||
77 | /** | ||
78 | * State each asynchronous command must have in its closure. | ||
79 | */ | ||
80 | struct GNUNET_TESTING_AsyncContext | ||
81 | { | ||
82 | |||
83 | /** | ||
84 | * Interpreter we are part of. Initialized when | ||
85 | * the global interpreter starts. | ||
86 | */ | ||
87 | struct GNUNET_TESTING_Interpreter *is; | ||
88 | |||
89 | /** | ||
90 | * Function to call when async operation is done. | ||
91 | */ | ||
92 | GNUNET_SCHEDULER_TaskCallback notify_finished; | ||
93 | |||
94 | /** | ||
95 | * Closure for @e notify_finished. | ||
96 | */ | ||
97 | void *notify_finished_cls; | ||
98 | |||
99 | /** | ||
100 | * Indication if the command finished (#GNUNET_OK). | ||
101 | * #GNUNET_NO if it did not finish, | ||
102 | * #GNUNET_SYSERR if it failed. | ||
103 | */ | ||
104 | enum GNUNET_GenericReturnValue finished; | ||
105 | |||
106 | /** | ||
107 | * Set to true if interpreter_next() has already been | ||
108 | * called for this command. | ||
109 | */ | ||
110 | bool next_called; | ||
111 | }; | ||
112 | |||
113 | |||
114 | /** | ||
115 | * The asynchronous command of @a ac has failed. | ||
32 | * | 116 | * |
33 | * It can start/stop one or more peers on a system; testing is responsible for | 117 | * @param ac command-specific context |
34 | * managing private keys, ports and paths; it is a low-level library that does | 118 | */ |
35 | * not support higher-level functions such as P2P connection, topology | 119 | void |
36 | * management or distributed testbed maintenance (those are provided by the | 120 | GNUNET_TESTING_async_fail ( |
37 | * [Testbed service](@ref testbed)) | 121 | struct GNUNET_TESTING_AsyncContext *ac); |
122 | |||
123 | |||
124 | /** | ||
125 | * The asynchronous command of @a ac has finished. | ||
38 | * | 126 | * |
39 | * @see [Documentation](https://gnunet.org/writing_testcases) | 127 | * @param ac command-specific context |
128 | */ | ||
129 | void | ||
130 | GNUNET_TESTING_async_finish ( | ||
131 | struct GNUNET_TESTING_AsyncContext *ac); | ||
132 | |||
133 | |||
134 | /** | ||
135 | * Signature of a function used to start executing a command of a test. Runs | ||
136 | * the command. Note that upon return, the interpreter will not automatically | ||
137 | * run the next command if this is an asynchronous command unless the command | ||
138 | * was wrapped in #GNUNET_TESTING_cmd_make_unblocking(), as the command may | ||
139 | * then continue asynchronously in other scheduler tasks. In this case, | ||
140 | * #GNUNET_TESTING_async_finish() must be called to run the next task. | ||
40 | * | 141 | * |
41 | * @{ | 142 | * @param cls closure |
143 | * @param is interpreter running the command | ||
42 | */ | 144 | */ |
145 | typedef void | ||
146 | (*GNUNET_TESTING_CommandRunRoutine)( | ||
147 | void *cls, | ||
148 | struct GNUNET_TESTING_Interpreter *is); | ||
43 | 149 | ||
44 | #ifndef GNUNET_TESTING_LIB_H | ||
45 | #define GNUNET_TESTING_LIB_H | ||
46 | 150 | ||
151 | /** | ||
152 | * Signature of a function used to clean up resources allocated | ||
153 | * by a command. | ||
154 | * | ||
155 | * @param cls closure | ||
156 | */ | ||
157 | typedef void | ||
158 | (*GNUNET_TESTING_CommandCleanupRoutine)(void *cls); | ||
47 | 159 | ||
48 | #include "gnunet_util_lib.h" | ||
49 | #include "gnunet_statistics_service.h" | ||
50 | #include "gnunet_arm_service.h" | ||
51 | 160 | ||
52 | #ifdef __cplusplus | 161 | /** |
53 | extern "C" | 162 | * Signature of a function used to extract traits exposed by a |
54 | { | 163 | * command. |
55 | #if 0 /* keep Emacsens' auto-indent happy */ | 164 | * |
56 | } | 165 | * @param cls closure |
57 | #endif | 166 | * @param[out] ret where to return the trait data |
58 | #endif | 167 | * @param trait name of the trait to return |
168 | * @param index index of the trait (for traits that are indexed) | ||
169 | * @return #GNUNET_OK on success | ||
170 | */ | ||
171 | typedef enum GNUNET_GenericReturnValue | ||
172 | (*GNUNET_TESTING_CommandGetTraits) (void *cls, | ||
173 | const void **ret, | ||
174 | const char *trait, | ||
175 | unsigned int index); | ||
59 | 176 | ||
60 | /** | 177 | /** |
61 | * Size of each hostkey in the hostkey file (in BYTES). | 178 | * Create a new command that may be asynchronous. |
179 | * | ||
180 | * @param cls the closure | ||
181 | * @param label the Label. Maximum length is #GNUNET_TESTING_CMD_MAX_LABEL_LENGTH | ||
182 | * @param run the run routing | ||
183 | * @param cleanup the cleanup function | ||
184 | * @param traits the traits function (optional) | ||
185 | * @param ac the async context, NULL if command is always | ||
186 | * synchronous | ||
187 | * @return the command the function cannot fail | ||
62 | */ | 188 | */ |
63 | #define GNUNET_TESTING_HOSTKEYFILESIZE sizeof(struct \ | 189 | struct GNUNET_TESTING_Command |
64 | GNUNET_CRYPTO_EddsaPrivateKey) | 190 | GNUNET_TESTING_command_new_ac ( |
191 | void *cls, | ||
192 | const char *label, | ||
193 | GNUNET_TESTING_CommandRunRoutine run, | ||
194 | GNUNET_TESTING_CommandCleanupRoutine cleanup, | ||
195 | GNUNET_TESTING_CommandGetTraits traits, | ||
196 | struct GNUNET_TESTING_AsyncContext *ac); | ||
197 | |||
65 | 198 | ||
66 | /** | 199 | /** |
67 | * The environmental variable, if set, that dictates where testing should place | 200 | * Create a new command |
68 | * generated peer configurations | 201 | * |
202 | * @param cls the closure | ||
203 | * @param label the Label. Maximum length is #GNUNET_TESTING_CMD_MAX_LABEL_LENGTH | ||
204 | * @param run the run routing | ||
205 | * @param cleanup the cleanup function | ||
206 | * @param traits the traits function (optional) | ||
207 | * @return the command the function cannot fail | ||
69 | */ | 208 | */ |
70 | #define GNUNET_TESTING_PREFIX "GNUNET_TESTING_PREFIX" | 209 | #define GNUNET_TESTING_command_new(cls,label,run,cleanup,traits) \ |
210 | GNUNET_TESTING_command_new_ac (cls,label,run,cleanup,traits,NULL) | ||
71 | 211 | ||
72 | 212 | ||
73 | /** | 213 | /** |
74 | * Handle for a system on which GNUnet peers are executed; | 214 | * Structure with storage space for a label. |
75 | * a system is used for reserving unique paths and ports. | ||
76 | */ | 215 | */ |
77 | struct GNUNET_TESTING_System; | 216 | struct GNUNET_TESTING_CommandLabel |
217 | { | ||
218 | char value[GNUNET_TESTING_CMD_MAX_LABEL_LENGTH + 1]; | ||
219 | }; | ||
78 | 220 | ||
79 | 221 | ||
80 | /** | 222 | /** |
81 | * Handle for a GNUnet peer controlled by testing. | 223 | * Set @a label to @a value. Asserts that @a value is |
224 | * not longer than #GNUNET_TESTING_CMD_MAX_LABEL_LENGTH. | ||
225 | * | ||
226 | * @param[out] label label to initialize | ||
227 | * @param value value to store into @a label | ||
82 | */ | 228 | */ |
83 | struct GNUNET_TESTING_Peer; | 229 | void |
230 | GNUNET_TESTING_set_label ( | ||
231 | struct GNUNET_TESTING_CommandLabel *label, | ||
232 | const char *value); | ||
84 | 233 | ||
85 | 234 | ||
86 | /** | 235 | /** |
87 | * Specification of a service that is to be shared among peers | 236 | * A command to be run by the interpreter. |
88 | */ | 237 | */ |
89 | struct GNUNET_TESTING_SharedService | 238 | struct GNUNET_TESTING_Command |
90 | { | 239 | { |
240 | |||
241 | /** | ||
242 | * Label for the command. | ||
243 | */ | ||
244 | struct GNUNET_TESTING_CommandLabel label; | ||
245 | |||
246 | /** | ||
247 | * Closure for all commands with command-specific context information. | ||
248 | */ | ||
249 | void *cls; | ||
250 | |||
251 | /** | ||
252 | * Variable name for the command, NULL for none. | ||
253 | */ | ||
254 | const char *name; | ||
255 | |||
256 | /** | ||
257 | * Runs the command. Note that upon return, the interpreter | ||
258 | * will not automatically run the next command, as the command | ||
259 | * may continue asynchronously in other scheduler tasks. Thus, | ||
260 | * the command must ensure to eventually call | ||
261 | * #GNUNET_TESTING_interpreter_next() or | ||
262 | * #GNUNET_TESTING_interpreter_fail(). | ||
263 | * | ||
264 | * If this function creates some asynchronous activity, it should | ||
265 | * initialize @e finish to a function that can be used to wait for | ||
266 | * the asynchronous activity to terminate. | ||
267 | * | ||
268 | * @param cls closure | ||
269 | * @param is interpreter state | ||
270 | */ | ||
271 | GNUNET_TESTING_CommandRunRoutine run; | ||
272 | |||
273 | /** | ||
274 | * Pointer to the asynchronous context in the command's | ||
275 | * closure. Used by the | ||
276 | * #GNUNET_TESTING_async_finish() and | ||
277 | * #GNUNET_TESTING_async_fail() functions. | ||
278 | * | ||
279 | * Must be NULL if a command is synchronous. | ||
280 | */ | ||
281 | struct GNUNET_TESTING_AsyncContext *ac; | ||
282 | |||
91 | /** | 283 | /** |
92 | * The name of the service. | 284 | * Clean up after the command. Run during forced termination |
285 | * (CTRL-C) or test failure or test success. | ||
286 | * | ||
287 | * @param cls closure | ||
93 | */ | 288 | */ |
94 | const char *service; | 289 | GNUNET_TESTING_CommandCleanupRoutine cleanup; |
95 | 290 | ||
96 | /** | 291 | /** |
97 | * The configuration template for the service. Cannot be NULL | 292 | * Extract information from a command that is useful for other |
293 | * commands. Can be NULL if a command has no traits. | ||
294 | * | ||
295 | * @param cls closure | ||
296 | * @param[out] ret result (could be anything) | ||
297 | * @param trait name of the trait | ||
298 | * @param index index number of the object to extract. | ||
299 | * @return #GNUNET_OK on success, | ||
300 | * #GNUNET_NO if no trait was found | ||
98 | */ | 301 | */ |
99 | const struct GNUNET_CONFIGURATION_Handle *cfg; | 302 | GNUNET_TESTING_CommandGetTraits traits; |
100 | 303 | ||
101 | /** | 304 | /** |
102 | * The number of peers which share an instance of the service. 0 for sharing | 305 | * When did the execution of this command start? |
103 | * among all peers | ||
104 | */ | 306 | */ |
105 | unsigned int share; | 307 | struct GNUNET_TIME_Absolute start_time; |
308 | |||
309 | /** | ||
310 | * When did the execution of this command finish? | ||
311 | */ | ||
312 | struct GNUNET_TIME_Absolute finish_time; | ||
313 | |||
314 | /** | ||
315 | * When did we start the last run of this command? Delta to @e finish_time | ||
316 | * gives the latency for the last successful run. Useful in case @e | ||
317 | * num_tries was positive and the command was run multiple times. In that | ||
318 | * case, the @e start_time gives the time when we first tried to run the | ||
319 | * command, so the difference between @e start_time and @e finish_time would | ||
320 | * be the time all of the @e num_tries took, while the delta to @e | ||
321 | * last_req_time is the time the last (successful) execution took. | ||
322 | */ | ||
323 | struct GNUNET_TIME_Absolute last_req_time; | ||
324 | |||
325 | /** | ||
326 | * How often did we try to execute this command? (In case it is a request | ||
327 | * that is repated.) Note that a command must have some built-in retry | ||
328 | * mechanism for this value to be useful. | ||
329 | */ | ||
330 | unsigned int num_tries; | ||
331 | |||
332 | /** | ||
333 | * If "true", the interpreter should not immediately run the next command, | ||
334 | * even if this command did not complete via #GNUNET_TESTING_async_finish(). | ||
335 | * Otherwise, #GNUNET_TESTING_cmd_finish() must be used to ensure that a | ||
336 | * command actually completed. | ||
337 | */ | ||
338 | bool asynchronous_finish; | ||
339 | |||
106 | }; | 340 | }; |
107 | 341 | ||
108 | 342 | ||
109 | /** | 343 | /** |
110 | * Create a system handle. There must only be one system handle per operating | 344 | * Lookup command by label. |
111 | * system. Uses a default range for allowed ports. Ports are still tested for | 345 | * |
112 | * availability. | 346 | * @param is interpreter to lookup command in |
113 | * | 347 | * @param label label of the command to lookup. |
114 | * @param testdir only the directory name without any path. This is used for all | 348 | * @return the command, if it is found, or NULL. |
115 | * service homes; the directory will be created in a temporary location | 349 | */ |
116 | * depending on the underlying OS. This variable will be | 350 | const struct GNUNET_TESTING_Command * |
117 | * overridden with the value of the environmental variable | 351 | GNUNET_TESTING_interpreter_lookup_command ( |
118 | * GNUNET_TESTING_PREFIX, if it exists. | 352 | struct GNUNET_TESTING_Interpreter *is, |
119 | * @param trusted_ip the ip address which will be set as TRUSTED HOST in all | 353 | const char *label); |
120 | * service configurations generated to allow control connections from | 354 | |
121 | * this ip. This can either be a single ip address or a network address | 355 | |
122 | * in CIDR notation. | 356 | /** |
123 | * @param hostname the hostname of the system we are using for testing; NULL for | 357 | * Get command from hash map by variable name. |
124 | * localhost | 358 | * |
125 | * @param shared_services NULL terminated array describing services that are to | 359 | * @param is interpreter state. |
126 | * be shared among peers | 360 | * @param name name of the variable to get command by |
127 | * @return handle to this system, NULL on error | 361 | * @return the command, if it is found, or NULL. |
128 | */ | 362 | */ |
129 | struct GNUNET_TESTING_System * | 363 | const struct GNUNET_TESTING_Command * |
130 | GNUNET_TESTING_system_create (const char *testdir, | 364 | GNUNET_TESTING_interpreter_get_command ( |
131 | const char *trusted_ip, | 365 | struct GNUNET_TESTING_Interpreter *is, |
132 | const char *hostname, | 366 | const char *name); |
133 | const struct GNUNET_TESTING_SharedService * | 367 | |
134 | shared_services); | 368 | |
135 | 369 | /** | |
136 | 370 | * Update the last request time of the current command | |
137 | /** | 371 | * to the current time. |
138 | * Create a system handle. There must only be one system | 372 | * |
139 | * handle per operating system. Use this function directly | 373 | * @param[in,out] is interpreter state where to show |
140 | * if multiple system objects are created for the same host | 374 | * that we are doing something |
141 | * (only really useful when testing --- or to make the port | ||
142 | * range configurable). | ||
143 | * | ||
144 | * @param testdir only the directory name without any path. This is used for | ||
145 | * all service homes; the directory will be created in a temporary | ||
146 | * location depending on the underlying OS. This variable will be | ||
147 | * overridden with the value of the environmental variable | ||
148 | * GNUNET_TESTING_PREFIX, if it exists. | ||
149 | * @param trusted_ip the ip address which will be set as TRUSTED HOST in all | ||
150 | * service configurations generated to allow control connections from | ||
151 | * this ip. This can either be a single ip address or a network address | ||
152 | * in CIDR notation. | ||
153 | * @param hostname the hostname of the system we are using for testing; NULL for | ||
154 | * localhost | ||
155 | * @param shared_services NULL terminated array describing services that are to | ||
156 | * be shared among peers | ||
157 | * @param lowport lowest port number this system is allowed to allocate (inclusive) | ||
158 | * @param highport highest port number this system is allowed to allocate (exclusive) | ||
159 | * @return handle to this system, NULL on error | ||
160 | */ | ||
161 | struct GNUNET_TESTING_System * | ||
162 | GNUNET_TESTING_system_create_with_portrange (const char *testdir, | ||
163 | const char *trusted_ip, | ||
164 | const char *hostname, | ||
165 | const struct | ||
166 | GNUNET_TESTING_SharedService * | ||
167 | shared_services, | ||
168 | uint16_t lowport, | ||
169 | uint16_t highport); | ||
170 | |||
171 | |||
172 | /** | ||
173 | * Free system resources. | ||
174 | * | ||
175 | * @param system system to be freed | ||
176 | * @param remove_paths should the 'testdir' and all subdirectories | ||
177 | * be removed (clean up on shutdown)? | ||
178 | */ | 375 | */ |
179 | void | 376 | void |
180 | GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system, | 377 | GNUNET_TESTING_interpreter_current_cmd_touch ( |
181 | int remove_paths); | 378 | struct GNUNET_TESTING_Interpreter *is); |
182 | 379 | ||
183 | 380 | ||
184 | /** | 381 | /** |
185 | * Testing includes a number of pre-created hostkeys for | 382 | * Increment the 'num_tries' counter for the current command. |
186 | * faster peer startup. This function can be used to | ||
187 | * access the n-th key of those pre-created hostkeys; note | ||
188 | * that these keys are ONLY useful for testing and not | ||
189 | * secure as the private keys are part of the public | ||
190 | * GNUnet source code. | ||
191 | * | 383 | * |
192 | * This is primarily a helper function used internally | 384 | * @param[in,out] is interpreter state where to |
193 | * by #GNUNET_TESTING_peer_configure(). | 385 | * increment the counter |
386 | */ | ||
387 | void | ||
388 | GNUNET_TESTING_interpreter_current_cmd_inc_tries ( | ||
389 | struct GNUNET_TESTING_Interpreter *is); | ||
390 | |||
391 | |||
392 | /** | ||
393 | * Obtain label of the command being now run. | ||
194 | * | 394 | * |
195 | * @param system the testing system handle | 395 | * @param is interpreter state. |
196 | * @param key_number desired pre-created hostkey to obtain | 396 | * @return the label. |
197 | * @param id set to the peer's identity (hash of the public | ||
198 | * key; if NULL, #GNUNET_SYSERR is returned immediately | ||
199 | * @return NULL on error (not enough keys) | ||
200 | */ | 397 | */ |
201 | struct GNUNET_CRYPTO_EddsaPrivateKey * | 398 | const char * |
202 | GNUNET_TESTING_hostkey_get (const struct GNUNET_TESTING_System *system, | 399 | GNUNET_TESTING_interpreter_current_cmd_get_label ( |
203 | uint32_t key_number, | 400 | struct GNUNET_TESTING_Interpreter *is); |
204 | struct GNUNET_PeerIdentity *id); | ||
205 | 401 | ||
206 | 402 | ||
207 | /** | 403 | /** |
208 | * Reserve a port for a peer. | 404 | * Current command failed, clean up and fail the test case. |
209 | * | 405 | * |
210 | * @param system system to use for reservation tracking | 406 | * @param is interpreter state. |
211 | * @return 0 if no free port was available | ||
212 | */ | 407 | */ |
213 | uint16_t | 408 | void |
214 | GNUNET_TESTING_reserve_port (struct GNUNET_TESTING_System *system); | 409 | GNUNET_TESTING_interpreter_fail ( |
410 | struct GNUNET_TESTING_Interpreter *is); | ||
215 | 411 | ||
216 | 412 | ||
217 | /** | 413 | /** |
218 | * Release reservation of a TCP or UDP port for a peer | 414 | * Skips the current test, the environment is |
219 | * (used during GNUNET_TESTING_peer_destroy). | 415 | * not prepared correctly. |
220 | * | 416 | * |
221 | * @param system system to use for reservation tracking | 417 | * @param is interpreter state. |
222 | * @param port reserved port to release | ||
223 | */ | 418 | */ |
224 | void | 419 | void |
225 | GNUNET_TESTING_release_port (struct GNUNET_TESTING_System *system, | 420 | GNUNET_TESTING_interpreter_skip ( |
226 | uint16_t port); | 421 | struct GNUNET_TESTING_Interpreter *is); |
227 | 422 | ||
228 | 423 | ||
229 | /** | 424 | /** |
230 | * Create a new configuration using the given configuration as a template; | 425 | * Callback over commands of an interpreter. |
231 | * ports and paths will be modified to select available ports on the local | ||
232 | * system. The default configuration will be available in PATHS section under | ||
233 | * the option DEFAULTCONFIG after the call. SERVICE_HOME is also set in PATHS | ||
234 | * section to the temporary directory specific to this configuration. If we run | ||
235 | * out of "*port" numbers, return #GNUNET_SYSERR. | ||
236 | * | 426 | * |
237 | * This is primarily a helper function used internally | 427 | * @param cls closure |
238 | * by #GNUNET_TESTING_peer_configure(). | 428 | * @param cmd a command to process |
429 | */ | ||
430 | typedef void | ||
431 | (*GNUNET_TESTING_CommandIterator)( | ||
432 | void *cls, | ||
433 | const struct GNUNET_TESTING_Command *cmd); | ||
434 | |||
435 | |||
436 | /** | ||
437 | * Iterates over all of the top-level commands of an | ||
438 | * interpreter. | ||
239 | * | 439 | * |
240 | * @param system system to use to coordinate resource usage | 440 | * @param[in] is interpreter to iterate over |
241 | * @param cfg template configuration to update | 441 | * @param asc true in execution order, false for reverse execution order |
242 | * @return #GNUNET_OK on success, | 442 | * @param cb function to call on each command |
243 | * #GNUNET_SYSERR on error - the configuration will | 443 | * @param cb_cls closure for cb |
244 | * be incomplete and should not be used there upon | ||
245 | */ | 444 | */ |
246 | int | 445 | void |
247 | GNUNET_TESTING_configuration_create (struct GNUNET_TESTING_System *system, | 446 | GNUNET_TESTING_interpreter_commands_iterate ( |
248 | struct GNUNET_CONFIGURATION_Handle *cfg); | 447 | struct GNUNET_TESTING_Interpreter *is, |
448 | bool asc, | ||
449 | GNUNET_TESTING_CommandIterator cb, | ||
450 | void *cb_cls); | ||
249 | 451 | ||
250 | // FIXME: add dual to 'release' ports again... | 452 | |
453 | /* ************** Fundamental interpreter commands ************ */ | ||
251 | 454 | ||
252 | 455 | ||
253 | /** | 456 | /** |
254 | * Configure a GNUnet peer. GNUnet must be installed on the local | 457 | * Create command array terminator. |
255 | * system and available in the PATH. | ||
256 | * | 458 | * |
257 | * @param system system to use to coordinate resource usage | 459 | * @return a end-command. |
258 | * @param cfg configuration to use; will be UPDATED (to reflect needed | ||
259 | * changes in port numbers and paths) | ||
260 | * @param key_number number of the hostkey to use for the peer | ||
261 | * @param id identifier for the daemon, will be set, can be NULL | ||
262 | * @param emsg set to freshly allocated error message (set to NULL on success), | ||
263 | * can be NULL | ||
264 | * @return handle to the peer, NULL on error | ||
265 | */ | 460 | */ |
266 | struct GNUNET_TESTING_Peer * | 461 | struct GNUNET_TESTING_Command |
267 | GNUNET_TESTING_peer_configure (struct GNUNET_TESTING_System *system, | 462 | GNUNET_TESTING_cmd_end (void); |
268 | struct GNUNET_CONFIGURATION_Handle *cfg, | ||
269 | uint32_t key_number, | ||
270 | struct GNUNET_PeerIdentity *id, | ||
271 | char **emsg); | ||
272 | 463 | ||
273 | 464 | ||
274 | /** | 465 | /** |
275 | * Obtain the peer identity from a peer handle. | 466 | * Create a "batch" command. Such command takes a end_CMD-terminated array of |
467 | * CMDs and executed them. Once it hits the end CMD, it passes the control to | ||
468 | * the next top-level CMD, regardless of it being another batch or ordinary | ||
469 | * CMD. | ||
276 | * | 470 | * |
277 | * @param peer peer handle for which we want the peer's identity | 471 | * @param label the command label. |
278 | * @param id identifier for the daemon, will be set | 472 | * @param batch array of CMDs to execute. |
473 | * @return the command. | ||
279 | */ | 474 | */ |
280 | void | 475 | struct GNUNET_TESTING_Command |
281 | GNUNET_TESTING_peer_get_identity (struct GNUNET_TESTING_Peer *peer, | 476 | GNUNET_TESTING_cmd_batch ( |
282 | struct GNUNET_PeerIdentity *id); | 477 | const char *label, |
478 | struct GNUNET_TESTING_Command *batch); | ||
479 | |||
480 | |||
481 | /** | ||
482 | * Performance counter. | ||
483 | */ | ||
484 | struct GNUNET_TESTING_Timer | ||
485 | { | ||
486 | /** | ||
487 | * For which type of commands. | ||
488 | */ | ||
489 | const char *prefix; | ||
490 | |||
491 | /** | ||
492 | * Total time spend in all commands of this type. | ||
493 | */ | ||
494 | struct GNUNET_TIME_Relative total_duration; | ||
495 | |||
496 | /** | ||
497 | * Total time spend waiting for the *successful* exeuction | ||
498 | * in all commands of this type. | ||
499 | */ | ||
500 | struct GNUNET_TIME_Relative success_latency; | ||
501 | |||
502 | /** | ||
503 | * Number of commands summed up. | ||
504 | */ | ||
505 | unsigned int num_commands; | ||
283 | 506 | ||
507 | /** | ||
508 | * Number of retries summed up. | ||
509 | */ | ||
510 | unsigned int num_retries; | ||
511 | }; | ||
284 | 512 | ||
285 | /** | 513 | /** |
286 | * Start the peer. | 514 | * Obtain performance data from the interpreter. |
287 | * | 515 | * |
288 | * @param peer peer to start | 516 | * @param label command label. |
289 | * @return #GNUNET_OK on success, | 517 | * @param[in,out] timers NULL-prefix terminated array that specifies what commands (by label) to obtain runtimes for |
290 | * #GNUNET_SYSERR on error (i.e. peer already running) | 518 | * @return the command |
291 | */ | 519 | */ |
292 | int | 520 | struct GNUNET_TESTING_Command |
293 | GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer); | 521 | GNUNET_TESTING_cmd_stat ( |
522 | const char *label, | ||
523 | struct GNUNET_TESTING_Timer *timers); | ||
294 | 524 | ||
295 | 525 | ||
296 | /** | 526 | /** |
297 | * Stop the peer. This call is blocking as it kills the peer's main ARM process | 527 | * Set variable to command as side-effect of |
298 | * by sending a SIGTERM and waits on it. For asynchronous shutdown of peer, see | 528 | * running a command. |
299 | * GNUNET_TESTING_peer_stop_async(). | ||
300 | * | 529 | * |
301 | * @param peer peer to stop | 530 | * @param name name of the variable to set |
302 | * @return #GNUNET_OK on success, | 531 | * @param cmd command to set to variable when run |
303 | * #GNUNET_SYSERR on error (i.e. peer not running) | 532 | * @return modified command |
304 | */ | 533 | */ |
305 | int | 534 | struct GNUNET_TESTING_Command |
306 | GNUNET_TESTING_peer_stop (struct GNUNET_TESTING_Peer *peer); | 535 | GNUNET_TESTING_cmd_set_var ( |
536 | const char *name, | ||
537 | struct GNUNET_TESTING_Command cmd); | ||
307 | 538 | ||
308 | 539 | ||
309 | /** | 540 | /** |
310 | * Destroy the peer. Releases resources locked during peer configuration. | 541 | * Command to create a barrier. |
311 | * If the peer is still running, it will be stopped AND a warning will be | ||
312 | * printed (users of the API should stop the peer explicitly first). | ||
313 | * | 542 | * |
314 | * @param peer peer to destroy | 543 | * @param label The label of this command. |
544 | * @param number_to_be_reached If this number of processes reached | ||
545 | * this barrier, all processes waiting at | ||
546 | * this barrier can pass it. | ||
315 | */ | 547 | */ |
316 | void | 548 | struct GNUNET_TESTING_Command |
317 | GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer); | 549 | GNUNET_TESTING_cmd_barrier_create ( |
550 | const char *label, | ||
551 | unsigned int number_to_be_reached); | ||
318 | 552 | ||
319 | 553 | ||
320 | /** | 554 | /** |
321 | * Sends SIGTERM to the peer's main process | 555 | * If this command is executed the the process is signaling the master process |
556 | * that it reached a barrier. If this command is synchronous it will block. | ||
322 | * | 557 | * |
323 | * @param peer the handle to the peer | 558 | * @param label name for command. |
324 | * @return #GNUNET_OK if successful; #GNUNET_SYSERR if the main process is NULL | 559 | * @param barrier_label The name of the barrier we waited for and which was reached. |
325 | * or upon any error while sending SIGTERM | 560 | * @return command. |
326 | */ | 561 | */ |
327 | int | 562 | struct GNUNET_TESTING_Command |
328 | GNUNET_TESTING_peer_kill (struct GNUNET_TESTING_Peer *peer); | 563 | GNUNET_TESTING_cmd_barrier_reached ( |
564 | const char *label, | ||
565 | const char *barrier_label); | ||
566 | |||
329 | 567 | ||
568 | #define GNUNET_TESTING_NETJAIL_START_SCRIPT "netjail_start.sh" | ||
569 | |||
570 | #define GNUNET_TESTING_NETJAIL_STOP_SCRIPT "netjail_stop.sh" | ||
330 | 571 | ||
331 | /** | 572 | /** |
332 | * Waits for a peer to terminate. The peer's main process will also be destroyed. | 573 | * Create command. |
333 | * | 574 | * |
334 | * @param peer the handle to the peer | 575 | * @param label Name for the command. |
335 | * @return #GNUNET_OK if successful; #GNUNET_SYSERR if the main process is NULL | 576 | * @param topology_data topology data |
336 | * or upon any error while waiting | 577 | * @param timeout Before this timeout is reached this cmd MUST finish. |
578 | * @return command. | ||
337 | */ | 579 | */ |
338 | int | 580 | struct GNUNET_TESTING_Command |
339 | GNUNET_TESTING_peer_wait (struct GNUNET_TESTING_Peer *peer); | 581 | GNUNET_TESTING_cmd_netjail_start_helpers ( |
582 | const char *label, | ||
583 | const char *topology_cmd_label, | ||
584 | struct GNUNET_TIME_Relative timeout); | ||
340 | 585 | ||
341 | 586 | ||
342 | /** | 587 | /** |
343 | * Callback to inform whether the peer is running or stopped. | 588 | * This command executes a shell script to setup the netjail environment. |
344 | * | 589 | * |
345 | * @param cls the closure given to GNUNET_TESTING_peer_stop_async() | 590 | * @param label name for command. |
346 | * @param peer the respective peer whose status is being reported | 591 | * @param script which script to run, e.g. #GNUNET_TESTING_NETJAIL_START_SCRIPT |
347 | * @param success #GNUNET_YES if the peer is stopped; #GNUNET_SYSERR upon any | 592 | * @param topology_config Configuration file for the test topology. |
348 | * error | 593 | * @param read_file Flag indicating if the the name of the topology file is send to the helper, or a string with the topology data. |
594 | * @return command. | ||
349 | */ | 595 | */ |
350 | typedef void | 596 | struct GNUNET_TESTING_Command |
351 | (*GNUNET_TESTING_PeerStopCallback) (void *cls, | 597 | GNUNET_TESTING_cmd_netjail_setup ( |
352 | struct GNUNET_TESTING_Peer *peer, | 598 | const char *label, |
353 | int success); | 599 | const char *script, |
600 | const char *topology_cmd_label); | ||
601 | |||
602 | |||
603 | struct GNUNET_TESTING_Command | ||
604 | GNUNET_TESTING_cmd_load_topology_from_file ( | ||
605 | const char *label, | ||
606 | const char *filename); | ||
607 | |||
608 | |||
609 | struct GNUNET_TESTING_Command | ||
610 | GNUNET_TESTING_cmd_load_topology_from_string ( | ||
611 | const char *label, | ||
612 | const char *topology_data); | ||
354 | 613 | ||
355 | 614 | ||
356 | /** | 615 | /** |
357 | * Stop a peer asynchronously using ARM API. Peer's shutdown is signaled | 616 | * Turn asynchronous command into non-blocking command by setting |
358 | * through the GNUNET_TESTING_PeerStopCallback(). | 617 | * asynchronous_finish to true. Modifies (and then returns) @a cmd simply |
618 | * setting the bit. By default, most commands are blocking, and by wrapping | ||
619 | * the command construction in this function a blocking command can be turned | ||
620 | * into an asynchronous command where the interpreter continues after | ||
621 | * initiating the asynchronous action. Does nothing if the command is | ||
622 | * fundamentally synchronous. | ||
359 | * | 623 | * |
360 | * @param peer the peer to stop | 624 | * @param[in,out] cmd command to make non-blocking |
361 | * @param cb the callback to signal peer shutdown | 625 | * @return a finish-command. |
362 | * @param cb_cls closure for the @a cb | ||
363 | * @return #GNUNET_OK upon successfully giving the request to the ARM API (this | ||
364 | * does not mean that the peer is successfully stopped); #GNUNET_SYSERR | ||
365 | * upon any error. | ||
366 | */ | 626 | */ |
367 | int | 627 | struct GNUNET_TESTING_Command |
368 | GNUNET_TESTING_peer_stop_async (struct GNUNET_TESTING_Peer *peer, | 628 | GNUNET_TESTING_cmd_make_unblocking ( |
369 | GNUNET_TESTING_PeerStopCallback cb, | 629 | struct GNUNET_TESTING_Command cmd); |
370 | void *cb_cls); | ||
371 | 630 | ||
372 | 631 | ||
373 | /** | 632 | /** |
374 | * Cancel a previous asynchronous peer stop request. | 633 | * Create (synchronous) command that waits for another command to finish. |
375 | * GNUNET_TESTING_peer_stop_async() should have been called before on the given | 634 | * If @a cmd_ref did not finish after @a timeout, this command will fail |
376 | * peer. It is an error to call this function if the peer stop callback was | 635 | * the test case. |
377 | * already called | ||
378 | * | 636 | * |
379 | * @param peer the peer on which GNUNET_TESTING_peer_stop_async() was called | 637 | * @param finish_label label for this command |
380 | * before. | 638 | * @param cmd_ref reference to a previous command which we should |
639 | * wait for (call `finish()` on) | ||
640 | * @param timeout how long to wait at most for @a cmd_ref to finish | ||
641 | * @return a finish-command. | ||
381 | */ | 642 | */ |
382 | void | 643 | const struct GNUNET_TESTING_Command |
383 | GNUNET_TESTING_peer_stop_async_cancel (struct GNUNET_TESTING_Peer *peer); | 644 | GNUNET_TESTING_cmd_finish ( |
645 | const char *finish_label, | ||
646 | const char *cmd_ref, | ||
647 | struct GNUNET_TIME_Relative timeout); | ||
648 | |||
649 | |||
650 | /** | ||
651 | * Create a "signal" CMD. | ||
652 | * | ||
653 | * @param label command label. | ||
654 | * @param process_label label of a command that has a process trait | ||
655 | * @param signal signal to send to @a process. | ||
656 | * @return the command. | ||
657 | */ | ||
658 | struct GNUNET_TESTING_Command | ||
659 | GNUNET_TESTING_cmd_signal ( | ||
660 | const char *label, | ||
661 | const char *process_label, | ||
662 | int signal); | ||
663 | |||
664 | |||
665 | /** | ||
666 | * Sleep for @a duration. | ||
667 | * | ||
668 | * @param label command label. | ||
669 | * @param duration time to sleep | ||
670 | * @return the command. | ||
671 | */ | ||
672 | struct GNUNET_TESTING_Command | ||
673 | GNUNET_TESTING_cmd_sleep ( | ||
674 | const char *label, | ||
675 | struct GNUNET_TIME_Relative duration); | ||
676 | |||
677 | |||
678 | /** | ||
679 | * Command to execute a command. | ||
680 | * | ||
681 | * @param label Label of the command. | ||
682 | */ | ||
683 | const struct GNUNET_TESTING_Command | ||
684 | GNUNET_TESTING_cmd_exec ( | ||
685 | const char *label, | ||
686 | enum GNUNET_OS_ProcessStatusType expected_type, | ||
687 | unsigned long int expected_exit_code, | ||
688 | char *const script_argv[]); | ||
689 | |||
690 | |||
691 | /** | ||
692 | * Command to execute a command. | ||
693 | * | ||
694 | * @param label Label of the command. | ||
695 | */ | ||
696 | const struct GNUNET_TESTING_Command | ||
697 | GNUNET_TESTING_cmd_exec_va ( | ||
698 | const char *label, | ||
699 | enum GNUNET_OS_ProcessStatusType expected_type, | ||
700 | unsigned long int expected_exit_code, | ||
701 | ...); | ||
384 | 702 | ||
385 | 703 | ||
386 | /** | 704 | /** |
387 | * Signature of the 'main' function for a (single-peer) testcase that | 705 | * Make the instruction pointer point to @a target_label |
388 | * is run using #GNUNET_TESTING_peer_run(). | 706 | * only if @a counter is greater than zero. Note that |
707 | * the command that will be executed next in this case | ||
708 | * is the one AFTER @a target_label, as the command we | ||
709 | * jump to is skipped by the advancing IP after the | ||
710 | * rewind. | ||
711 | * | ||
712 | * @param label command label | ||
713 | * @param target_label label of the new instruction pointer's destination after the jump; | ||
714 | * must be before the current instruction (and the command at the @a target_label itself will not be run, but the one afterwards) | ||
715 | * @param counter counts how many times the rewinding is to happen. | ||
716 | */ | ||
717 | struct GNUNET_TESTING_Command | ||
718 | GNUNET_TESTING_cmd_rewind_ip ( | ||
719 | const char *label, | ||
720 | const char *target_label, | ||
721 | unsigned int counter); | ||
722 | |||
723 | |||
724 | /* ***************** main loop logic ************* */ | ||
725 | |||
726 | /** | ||
727 | * Function called with the final result of the test. | ||
389 | * | 728 | * |
390 | * @param cls closure | 729 | * @param cls closure |
391 | * @param cfg configuration of the peer that was started | 730 | * @param rv #GNUNET_OK if the test passed |
392 | * @param peer identity of the peer that was created | ||
393 | */ | 731 | */ |
394 | typedef void | 732 | typedef void |
395 | (*GNUNET_TESTING_TestMain) (void *cls, | 733 | (*GNUNET_TESTING_ResultCallback)( |
396 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 734 | void *cls, |
397 | struct GNUNET_TESTING_Peer *peer); | 735 | enum GNUNET_GenericReturnValue rv); |
398 | 736 | ||
399 | 737 | ||
400 | /** | 738 | /** |
401 | * Start a single peer and run a test using the testing library. | 739 | * Run the testsuite. Note, CMDs are copied into the interpreter state |
402 | * Starts a peer using the given configuration and then invokes the | 740 | * because they are _usually_ defined into the "run" method that returns after |
403 | * given callback. This function ALSO initializes the scheduler loop | 741 | * having scheduled the test interpreter. |
404 | * and should thus be called directly from "main". The testcase | ||
405 | * should self-terminate by invoking #GNUNET_SCHEDULER_shutdown(). | ||
406 | * | 742 | * |
407 | * @param testdir only the directory name without any path. This is used for | 743 | * @param commands the array of command to execute |
408 | * all service homes; the directory will be created in a temporary | 744 | * @param timeout how long to wait for each command to execute |
409 | * location depending on the underlying OS | 745 | * @param rc function to call with the final result |
410 | * @param cfgfilename name of the configuration file to use; | 746 | * @param rc_cls closure for @a rc |
411 | * use NULL to only run with defaults | 747 | * @return The interpreter. |
412 | * @param tm main function of the testcase | ||
413 | * @param tm_cls closure for @a tm | ||
414 | * @return 0 on success, 1 on error | ||
415 | */ | 748 | */ |
416 | int | 749 | struct GNUNET_TESTING_Interpreter * |
417 | GNUNET_TESTING_peer_run (const char *testdir, | 750 | GNUNET_TESTING_run ( |
418 | const char *cfgfilename, | 751 | const struct GNUNET_TESTING_Command *commands, |
419 | GNUNET_TESTING_TestMain tm, | 752 | struct GNUNET_TIME_Relative timeout, |
420 | void *tm_cls); | 753 | GNUNET_TESTING_ResultCallback rc, |
754 | void *rc_cls); | ||
421 | 755 | ||
422 | 756 | ||
423 | /** | 757 | /** |
424 | * Start a single service (no ARM, except of course if the given | 758 | * Start a GNUnet scheduler event loop and run the testsuite. Return 0 upon |
425 | * service name is 'arm') and run a test using the testing library. | 759 | * success. Expected to be called directly from main(). |
426 | * Starts a service using the given configuration and then invokes the | ||
427 | * given callback. This function ALSO initializes the scheduler loop | ||
428 | * and should thus be called directly from "main". The testcase | ||
429 | * should self-terminate by invoking #GNUNET_SCHEDULER_shutdown(). | ||
430 | * | 760 | * |
431 | * This function is useful if the testcase is for a single service | 761 | * @param commands the list of command to execute |
432 | * and if that service doesn't itself depend on other services. | 762 | * @param timeout how long to wait for each command to execute |
433 | * | 763 | * @return EXIT_SUCCESS on success, EXIT_FAILURE on failure |
434 | * @param testdir only the directory name without any path. This is used for | ||
435 | * all service homes; the directory will be created in a temporary | ||
436 | * location depending on the underlying OS | ||
437 | * @param service_name name of the service to run | ||
438 | * @param cfgfilename name of the configuration file to use; | ||
439 | * use NULL to only run with defaults | ||
440 | * @param tm main function of the testcase | ||
441 | * @param tm_cls closure for @a tm | ||
442 | * @return 0 on success, 1 on error | ||
443 | */ | 764 | */ |
444 | int | 765 | int |
445 | GNUNET_TESTING_service_run (const char *testdir, | 766 | GNUNET_TESTING_main ( |
446 | const char *service_name, | 767 | const struct GNUNET_TESTING_Command *commands, |
447 | const char *cfgfilename, | 768 | struct GNUNET_TIME_Relative timeout); |
448 | GNUNET_TESTING_TestMain tm, | 769 | |
449 | void *tm_cls); | 770 | |
771 | /* ***************** plugin logic ************* */ | ||
772 | |||
773 | |||
774 | /** | ||
775 | * The plugin API every test case plugin has to implement. | ||
776 | */ | ||
777 | struct GNUNET_TESTING_PluginFunctions; | ||
778 | |||
779 | |||
780 | struct GNUNET_TESTING_PluginFunctions * | ||
781 | GNUNET_TESTING_make_plugin ( | ||
782 | const struct GNUNET_TESTING_Command *commands); | ||
783 | |||
784 | #define GNUNET_TESTING_MAKE_PLUGIN(prefix,name,...) \ | ||
785 | void * \ | ||
786 | prefix ## _plugin_ ## name ## _init (void *cls) { \ | ||
787 | const char *my_node_id = cls; (void) my_node_id; \ | ||
788 | struct GNUNET_TESTING_Command commands[] = { \ | ||
789 | __VA_ARGS__, \ | ||
790 | GNUNET_TESTING_cmd_end () \ | ||
791 | }; \ | ||
792 | return GNUNET_TESTING_make_plugin (commands); \ | ||
793 | } \ | ||
794 | void * \ | ||
795 | prefix ## _plugin_ ## name ## _done (void *cls) { \ | ||
796 | struct GNUNET_TESTING_PluginFunctions *api = cls; \ | ||
797 | GNUNET_free (api); \ | ||
798 | return NULL; \ | ||
799 | } | ||
450 | 800 | ||
451 | 801 | ||
452 | #if 0 /* keep Emacsens' auto-indent happy */ | 802 | /* *** Generic trait logic for implementing traits ********* */ |
803 | |||
804 | /** | ||
805 | * A `struct GNUNET_TESTING_Trait` can be used to exchange data between cmds. | ||
806 | * | ||
807 | * Therefor the cmd which like to provide data to other cmds has to implement | ||
808 | * the trait function, where an array of traits is defined with the help of | ||
809 | * the #GNUNET_TESTING_make_trait_ macro. The data can be retrieved with the | ||
810 | * help of the #GNUNET_TESTING_get_trait_ macro. Traits name and type must be | ||
811 | * defined to make use of the macros. | ||
812 | */ | ||
813 | struct GNUNET_TESTING_Trait | ||
453 | { | 814 | { |
454 | #endif | 815 | /** |
455 | #ifdef __cplusplus | 816 | * Index number associated with the trait. This gives the |
456 | } | 817 | * possibility to have _multiple_ traits on offer under the |
457 | #endif | 818 | * same name. |
819 | */ | ||
820 | unsigned int index; | ||
821 | |||
822 | /** | ||
823 | * Trait type, for example "reserve-pub" or "coin-priv". | ||
824 | */ | ||
825 | const char *trait_name; | ||
826 | |||
827 | /** | ||
828 | * Pointer to the piece of data to offer. | ||
829 | */ | ||
830 | const void *ptr; | ||
831 | }; | ||
458 | 832 | ||
459 | #endif | ||
460 | 833 | ||
461 | /** @} */ /* end of group */ | 834 | /** |
835 | * "end" of traits array. Because traits are offered into arrays, this type | ||
836 | * of trait is used to mark the end of such arrays; useful when iterating over | ||
837 | * those. | ||
838 | */ | ||
839 | struct GNUNET_TESTING_Trait | ||
840 | GNUNET_TESTING_trait_end (void); | ||
462 | 841 | ||
463 | /** @} */ /* end of group addition */ | 842 | |
843 | /** | ||
844 | * Obtain value of a trait from a command. | ||
845 | * | ||
846 | * @param traits the array of all the traits. | ||
847 | * @param[out] ret where to store the result. | ||
848 | * @param trait type of the trait to extract. | ||
849 | * @param index index number of the trait to extract. | ||
850 | * @return #GNUNET_OK when the trait is found. | ||
851 | */ | ||
852 | enum GNUNET_GenericReturnValue | ||
853 | GNUNET_TESTING_get_trait ( | ||
854 | const struct GNUNET_TESTING_Trait *traits, | ||
855 | const void **ret, | ||
856 | const char *trait, | ||
857 | unsigned int index); | ||
858 | |||
859 | |||
860 | /** | ||
861 | * Create headers for a trait with name @a name for | ||
862 | * statically allocated data of type @a type. | ||
863 | * | ||
864 | * @param prefix symbol prefix to use | ||
865 | * @param name name of the trait | ||
866 | * @param type data type for the trait | ||
867 | */ | ||
868 | #define GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT(prefix,name,type) \ | ||
869 | enum GNUNET_GenericReturnValue \ | ||
870 | prefix ## _get_trait_ ## name ( \ | ||
871 | const struct GNUNET_TESTING_Command *cmd, \ | ||
872 | type * *ret); \ | ||
873 | struct GNUNET_TESTING_Trait \ | ||
874 | prefix ## _make_trait_ ## name ( \ | ||
875 | type * value); | ||
876 | |||
877 | |||
878 | /** | ||
879 | * Create C implementation for a trait with name @a name for statically | ||
880 | * allocated data of type @a type. | ||
881 | * | ||
882 | * @param prefix symbol prefix to use | ||
883 | * @param name name of the trait | ||
884 | * @param type data type for the trait | ||
885 | */ | ||
886 | #define GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT(prefix,name,type) \ | ||
887 | enum GNUNET_GenericReturnValue \ | ||
888 | prefix ## _get_trait_ ## name ( \ | ||
889 | const struct GNUNET_TESTING_Command *cmd, \ | ||
890 | type * *ret) \ | ||
891 | { \ | ||
892 | if (NULL == cmd->traits) return GNUNET_SYSERR; \ | ||
893 | return cmd->traits (cmd->cls, \ | ||
894 | (const void **) ret, \ | ||
895 | GNUNET_S (name), \ | ||
896 | 0); \ | ||
897 | } \ | ||
898 | struct GNUNET_TESTING_Trait \ | ||
899 | prefix ## _make_trait_ ## name ( \ | ||
900 | type * value) \ | ||
901 | { \ | ||
902 | struct GNUNET_TESTING_Trait ret = { \ | ||
903 | .trait_name = GNUNET_S (name), \ | ||
904 | .ptr = (const void *) value \ | ||
905 | }; \ | ||
906 | return ret; \ | ||
907 | } | ||
908 | |||
909 | |||
910 | /** | ||
911 | * Create headers for a trait with name @a name for | ||
912 | * statically allocated data of type @a type. | ||
913 | * | ||
914 | * @param prefix symbol prefix to use | ||
915 | * @param name name of the trait | ||
916 | * @param type data type for the trait | ||
917 | */ | ||
918 | #define GNUNET_TESTING_MAKE_DECL_INDEXED_TRAIT(prefix,name,type) \ | ||
919 | enum GNUNET_GenericReturnValue \ | ||
920 | prefix ## _get_trait_ ## name ( \ | ||
921 | const struct GNUNET_TESTING_Command *cmd, \ | ||
922 | unsigned int index, \ | ||
923 | type * *ret); \ | ||
924 | struct GNUNET_TESTING_Trait \ | ||
925 | prefix ## _make_trait_ ## name ( \ | ||
926 | unsigned int index, \ | ||
927 | type * value); | ||
928 | |||
929 | |||
930 | /** | ||
931 | * Create C implementation for a trait with name @a name for statically | ||
932 | * allocated data of type @a type. | ||
933 | */ | ||
934 | #define GNUNET_TESTING_MAKE_IMPL_INDEXED_TRAIT(prefix,name,type) \ | ||
935 | enum GNUNET_GenericReturnValue \ | ||
936 | prefix ## _get_trait_ ## name ( \ | ||
937 | const struct GNUNET_TESTING_Command *cmd, \ | ||
938 | unsigned int index, \ | ||
939 | type * *ret) \ | ||
940 | { \ | ||
941 | if (NULL == cmd->traits) return GNUNET_SYSERR; \ | ||
942 | return cmd->traits (cmd->cls, \ | ||
943 | (const void **) ret, \ | ||
944 | GNUNET_S (name), \ | ||
945 | index); \ | ||
946 | } \ | ||
947 | struct GNUNET_TESTING_Trait \ | ||
948 | prefix ## _make_trait_ ## name ( \ | ||
949 | unsigned int index, \ | ||
950 | type * value) \ | ||
951 | { \ | ||
952 | struct GNUNET_TESTING_Trait ret = { \ | ||
953 | .index = index, \ | ||
954 | .trait_name = GNUNET_S (name), \ | ||
955 | .ptr = (const void *) value \ | ||
956 | }; \ | ||
957 | return ret; \ | ||
958 | } | ||
959 | |||
960 | |||
961 | /** | ||
962 | * Call #op on all simple traits needed by testing core logic. | ||
963 | * | ||
964 | * @param op operation to perform | ||
965 | * @param prefix prefix to pass to @e op | ||
966 | */ | ||
967 | #define GNUNET_TESTING_SIMPLE_TRAITS(op,prefix) \ | ||
968 | op (prefix, process, struct GNUNET_OS_Process *) \ | ||
969 | op (prefix, cmd, const struct GNUNET_TESTING_Command) \ | ||
970 | op (prefix, batch_cmds, struct GNUNET_TESTING_Command *) | ||
971 | |||
972 | |||
973 | GNUNET_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT, | ||
974 | GNUNET_TESTING) | ||
975 | |||
976 | |||
977 | #endif | ||
diff --git a/src/include/gnunet_testing_loop_lib.h b/src/include/gnunet_testing_loop_lib.h deleted file mode 100644 index 7e13edfab..000000000 --- a/src/include/gnunet_testing_loop_lib.h +++ /dev/null | |||
@@ -1,697 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2021, 2023 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 | * @brief Central interpreter and command loop for writing an interpreter to test asynchronous systems | ||
23 | * @author Christian Grothoff <christian@grothoff.org> | ||
24 | * @author Marcello Stanisci | ||
25 | * @author t3sserakt | ||
26 | */ | ||
27 | #ifndef GNUNET_TESTING_LOOP_LIB_H | ||
28 | #define GNUNET_TESTING_LOOP_LIB_H | ||
29 | |||
30 | /** | ||
31 | * Maximum length of label in command | ||
32 | */ | ||
33 | #define GNUNET_TESTING_CMD_MAX_LABEL_LENGTH 127 | ||
34 | |||
35 | /* ********************* Helper functions ********************* */ | ||
36 | |||
37 | /** | ||
38 | * Print failing line number and trigger shutdown. Useful | ||
39 | * quite any time after the command "run" method has been called. | ||
40 | */ | ||
41 | #define GNUNET_TESTING_FAIL(is) \ | ||
42 | do \ | ||
43 | { \ | ||
44 | GNUNET_break (0); \ | ||
45 | GNUNET_TESTING_interpreter_fail (is); \ | ||
46 | return; \ | ||
47 | } while (0) | ||
48 | |||
49 | |||
50 | /* ******************* Generic interpreter logic ************ */ | ||
51 | |||
52 | /** | ||
53 | * Global state of the interpreter, used by a command | ||
54 | * to access information about other commands. | ||
55 | */ | ||
56 | struct GNUNET_TESTING_Interpreter; | ||
57 | |||
58 | /** | ||
59 | * State each asynchronous command must have in its closure. | ||
60 | */ | ||
61 | struct GNUNET_TESTING_AsyncContext | ||
62 | { | ||
63 | |||
64 | /** | ||
65 | * Interpreter we are part of. | ||
66 | */ | ||
67 | struct GNUNET_TESTING_Interpreter *is; // FIXME: Why needed? When available? | ||
68 | |||
69 | /** | ||
70 | * Function to call when done. | ||
71 | */ | ||
72 | GNUNET_SCHEDULER_TaskCallback cont; | ||
73 | |||
74 | /** | ||
75 | * Closure for @e cont. | ||
76 | */ | ||
77 | void *cont_cls; | ||
78 | |||
79 | /** | ||
80 | * Indication if the command finished (#GNUNET_OK). | ||
81 | * #GNUNET_NO if it did not finish, | ||
82 | * #GNUNET_SYSERR if it failed. | ||
83 | */ | ||
84 | enum GNUNET_GenericReturnValue finished; | ||
85 | }; | ||
86 | |||
87 | |||
88 | /** | ||
89 | * The asynchronous command of @a ac has failed. | ||
90 | * | ||
91 | * @param ac command-specific context | ||
92 | */ | ||
93 | void | ||
94 | GNUNET_TESTING_async_fail (struct GNUNET_TESTING_AsyncContext *ac); | ||
95 | |||
96 | |||
97 | /** | ||
98 | * The asynchronous command of @a ac has finished. | ||
99 | * | ||
100 | * @param ac command-specific context | ||
101 | */ | ||
102 | void | ||
103 | GNUNET_TESTING_async_finish (struct GNUNET_TESTING_AsyncContext *ac); | ||
104 | |||
105 | |||
106 | /** | ||
107 | * Signature of a function used to start executing a command | ||
108 | * of a test. | ||
109 | * | ||
110 | * @param cls closure | ||
111 | * @param is interpreter running the command | ||
112 | */ | ||
113 | typedef void | ||
114 | (*GNUNET_TESTING_CommandRunRoutine)(void *cls, | ||
115 | struct GNUNET_TESTING_Interpreter *is); | ||
116 | |||
117 | |||
118 | /** | ||
119 | * Signature of a function used to clean up resources allocated | ||
120 | * by a command. | ||
121 | * | ||
122 | * @param cls closure | ||
123 | */ | ||
124 | typedef void | ||
125 | (*GNUNET_TESTING_CommandCleanupRoutine)(void *cls); | ||
126 | |||
127 | |||
128 | /** | ||
129 | * Signature of a function used to extract traits exposed by a | ||
130 | * command. | ||
131 | * | ||
132 | * @param cls closure | ||
133 | * @param[out] ret where to return the trait data | ||
134 | * @param trait name of the trait to return | ||
135 | * @param index index of the trait (for traits that are indexed) | ||
136 | * @return #GNUNET_OK on success | ||
137 | */ | ||
138 | typedef enum GNUNET_GenericReturnValue | ||
139 | (*GNUNET_TESTING_CommandGetTraits) (void *cls, | ||
140 | const void **ret, | ||
141 | const char *trait, | ||
142 | unsigned int index); | ||
143 | |||
144 | /** | ||
145 | * Create a new command | ||
146 | * | ||
147 | * @param cls the closure | ||
148 | * @param label the Label. Maximum length is GNUNET_TESTING_CMD_MAX_LABEL_LENGTH | ||
149 | * @param run the run routing | ||
150 | * @param cleanup the cleanup function | ||
151 | * @param traits the traits function (optional) | ||
152 | * @param the async context | ||
153 | * @return the command the function cannot fail | ||
154 | */ | ||
155 | struct GNUNET_TESTING_Command | ||
156 | GNUNET_TESTING_command_new (void *cls, | ||
157 | const char *label, | ||
158 | GNUNET_TESTING_CommandRunRoutine run, | ||
159 | GNUNET_TESTING_CommandCleanupRoutine cleanup, | ||
160 | GNUNET_TESTING_CommandGetTraits traits, | ||
161 | struct GNUNET_TESTING_AsyncContext *ac); | ||
162 | |||
163 | |||
164 | /** | ||
165 | * Structure with storage space for a label. | ||
166 | */ | ||
167 | struct GNUNET_TESTING_CommandLabel | ||
168 | { | ||
169 | char value[GNUNET_TESTING_CMD_MAX_LABEL_LENGTH + 1]; | ||
170 | }; | ||
171 | |||
172 | |||
173 | /** | ||
174 | * Set @a label to @a value. Asserts that @a value is | ||
175 | * not longer than #GNUNET_TESTING_CMD_MAX_LABEL_LENGTH. | ||
176 | * | ||
177 | * @param[out] label label to initialize | ||
178 | * @param value value to store into @a label | ||
179 | */ | ||
180 | void | ||
181 | GNUNET_TESTING_set_label (struct GNUNET_TESTING_CommandLabel *label, | ||
182 | const char *value); | ||
183 | |||
184 | |||
185 | /** | ||
186 | * A command to be run by the interpreter. | ||
187 | */ | ||
188 | struct GNUNET_TESTING_Command | ||
189 | { | ||
190 | /** | ||
191 | * Closure for all commands with command-specific context information. | ||
192 | */ | ||
193 | void *cls; | ||
194 | |||
195 | /** | ||
196 | * Label for the command. | ||
197 | */ | ||
198 | struct GNUNET_TESTING_CommandLabel label; | ||
199 | |||
200 | /** | ||
201 | * Runs the command. Note that upon return, the interpreter | ||
202 | * will not automatically run the next command, as the command | ||
203 | * may continue asynchronously in other scheduler tasks. Thus, | ||
204 | * the command must ensure to eventually call | ||
205 | * #GNUNET_TESTING_interpreter_next() or | ||
206 | * #GNUNET_TESTING_interpreter_fail(). | ||
207 | * | ||
208 | * If this function creates some asynchronous activity, it should | ||
209 | * initialize @e finish to a function that can be used to wait for | ||
210 | * the asynchronous activity to terminate. | ||
211 | * | ||
212 | * @param cls closure | ||
213 | * @param is interpreter state | ||
214 | */ | ||
215 | GNUNET_TESTING_CommandRunRoutine run; | ||
216 | |||
217 | /** | ||
218 | * Pointer to the asynchronous context in the command's | ||
219 | * closure. Used by the | ||
220 | * #GNUNET_TESTING_async_finish() and | ||
221 | * #GNUNET_TESTING_async_fail() functions. | ||
222 | * | ||
223 | * Must be NULL if a command is synchronous. | ||
224 | */ | ||
225 | struct GNUNET_TESTING_AsyncContext *ac; | ||
226 | |||
227 | /** | ||
228 | * Clean up after the command. Run during forced termination | ||
229 | * (CTRL-C) or test failure or test success. | ||
230 | * | ||
231 | * @param cls closure | ||
232 | */ | ||
233 | GNUNET_TESTING_CommandCleanupRoutine cleanup; | ||
234 | |||
235 | /** | ||
236 | * Extract information from a command that is useful for other | ||
237 | * commands. Can be NULL if a command has no traits. | ||
238 | * | ||
239 | * @param cls closure | ||
240 | * @param[out] ret result (could be anything) | ||
241 | * @param trait name of the trait | ||
242 | * @param index index number of the object to extract. | ||
243 | * @return #GNUNET_OK on success, | ||
244 | * #GNUNET_NO if no trait was found | ||
245 | */ | ||
246 | GNUNET_TESTING_CommandGetTraits traits; | ||
247 | |||
248 | /** | ||
249 | * When did the execution of this command start? | ||
250 | */ | ||
251 | struct GNUNET_TIME_Absolute start_time; | ||
252 | |||
253 | /** | ||
254 | * When did the execution of this command finish? | ||
255 | */ | ||
256 | struct GNUNET_TIME_Absolute finish_time; | ||
257 | |||
258 | /** | ||
259 | * When did we start the last run of this command? Delta to @e finish_time | ||
260 | * gives the latency for the last successful run. Useful in case @e | ||
261 | * num_tries was positive and the command was run multiple times. In that | ||
262 | * case, the @e start_time gives the time when we first tried to run the | ||
263 | * command, so the difference between @e start_time and @e finish_time would | ||
264 | * be the time all of the @e num_tries took, while the delta to @e | ||
265 | * last_req_time is the time the last (successful) execution took. | ||
266 | */ | ||
267 | struct GNUNET_TIME_Absolute last_req_time; | ||
268 | |||
269 | /** | ||
270 | * In case @e asynchronous_finish is true, how long should we wait for this | ||
271 | * command to complete? If @e finish did not complete after this amount of | ||
272 | * time, the interpreter will fail. Should be set generously to ensure | ||
273 | * tests do not fail on slow systems. | ||
274 | */ | ||
275 | struct GNUNET_TIME_Relative default_timeout; | ||
276 | |||
277 | /** | ||
278 | * How often did we try to execute this command? (In case it is a request | ||
279 | * that is repated.) Note that a command must have some built-in retry | ||
280 | * mechanism for this value to be useful. | ||
281 | */ | ||
282 | unsigned int num_tries; | ||
283 | |||
284 | /** | ||
285 | * If "true", the interpreter should not immediately call | ||
286 | * @e finish, even if @e finish is non-NULL. Otherwise, | ||
287 | * #GNUNET_TESTING_cmd_finish() must be used | ||
288 | * to ensure that a command actually completed. | ||
289 | */ | ||
290 | bool asynchronous_finish; | ||
291 | |||
292 | }; | ||
293 | |||
294 | |||
295 | /** | ||
296 | * Lookup command by label. | ||
297 | * Only future commands are looked up. | ||
298 | * | ||
299 | * @param is interpreter to lookup command in | ||
300 | * @param label label of the command to lookup. | ||
301 | * @return the command, if it is found, or NULL. | ||
302 | * @deprecated (still in use in a very odd way) | ||
303 | */ | ||
304 | // FIXME: think harder about whether this is actually needed, likely not. | ||
305 | const struct GNUNET_TESTING_Command * | ||
306 | GNUNET_TESTING_interpreter_lookup_future_command ( | ||
307 | struct GNUNET_TESTING_Interpreter *is, | ||
308 | const char *label); | ||
309 | |||
310 | |||
311 | /** | ||
312 | * Lookup command by label. | ||
313 | * | ||
314 | * @param is interpreter to lookup command in | ||
315 | * @param label label of the command to lookup. | ||
316 | * @return the command, if it is found, or NULL. | ||
317 | */ | ||
318 | const struct GNUNET_TESTING_Command * | ||
319 | GNUNET_TESTING_interpreter_lookup_command ( | ||
320 | struct GNUNET_TESTING_Interpreter *is, | ||
321 | const char *label); | ||
322 | |||
323 | |||
324 | /** | ||
325 | * Lookup command by label. | ||
326 | * All commands, first into the past, then into the future are looked up. | ||
327 | * | ||
328 | * @param is interpreter to lookup command in | ||
329 | * @param label label of the command to lookup. | ||
330 | * @return the command, if it is found, or NULL. | ||
331 | * @deprecated (still in use in a very odd way) | ||
332 | */ | ||
333 | const struct GNUNET_TESTING_Command * | ||
334 | GNUNET_TESTING_interpreter_lookup_command_all ( | ||
335 | struct GNUNET_TESTING_Interpreter *is, | ||
336 | const char *label); | ||
337 | |||
338 | |||
339 | /** | ||
340 | * Current command failed, clean up and fail the test case. | ||
341 | * | ||
342 | * @param is interpreter state. | ||
343 | */ | ||
344 | void | ||
345 | GNUNET_TESTING_interpreter_fail (struct GNUNET_TESTING_Interpreter *is); | ||
346 | |||
347 | |||
348 | /** | ||
349 | * Turn asynchronous command into non-blocking command by setting | ||
350 | * asynchronous_finish to true. Modifies (and then returns) @a cmd simply | ||
351 | * setting the bit. By default, most commands are blocking, and by wrapping | ||
352 | * the command construction in this function a blocking command can be turned | ||
353 | * into an asynchronous command where the interpreter continues after | ||
354 | * initiating the asynchronous action. Does nothing if the command is | ||
355 | * fundamentally synchronous. | ||
356 | * | ||
357 | * @param[in,out] cmd command to make non-blocking | ||
358 | * @return a finish-command. | ||
359 | */ | ||
360 | struct GNUNET_TESTING_Command | ||
361 | GNUNET_TESTING_cmd_make_unblocking (struct GNUNET_TESTING_Command cmd); | ||
362 | |||
363 | |||
364 | /** | ||
365 | * Create (synchronous) command that waits for another command to finish. | ||
366 | * If @a cmd_ref did not finish after @a timeout, this command will fail | ||
367 | * the test case. | ||
368 | * | ||
369 | * @param finish_label label for this command | ||
370 | * @param cmd_ref reference to a previous command which we should | ||
371 | * wait for (call `finish()` on) | ||
372 | * @param timeout how long to wait at most for @a cmd_ref to finish | ||
373 | * @return a finish-command. | ||
374 | */ | ||
375 | const struct GNUNET_TESTING_Command | ||
376 | GNUNET_TESTING_cmd_finish (const char *finish_label, | ||
377 | const char *cmd_ref, | ||
378 | struct GNUNET_TIME_Relative timeout); | ||
379 | |||
380 | |||
381 | /** | ||
382 | * Make the instruction pointer point to @a target_label | ||
383 | * only if @a counter is greater than zero. | ||
384 | * | ||
385 | * @param label command label | ||
386 | * @param target_label label of the new instruction pointer's destination after the jump; | ||
387 | * must be before the current instruction | ||
388 | * @param counter counts how many times the rewinding is to happen. | ||
389 | */ | ||
390 | struct GNUNET_TESTING_Command | ||
391 | GNUNET_TESTING_cmd_rewind_ip (const char *label, | ||
392 | const char *target_label, | ||
393 | unsigned int counter); | ||
394 | |||
395 | |||
396 | /** | ||
397 | * Function called with the final result of the test. | ||
398 | * FIXME: This may want to use a GNUNET_ErrorCode (namespaced, e.g. | ||
399 | * GNUNET_EC_TESTING_*) | ||
400 | * | ||
401 | * @param cls closure | ||
402 | * @param rv #GNUNET_OK if the test passed | ||
403 | */ | ||
404 | typedef void | ||
405 | (*GNUNET_TESTING_ResultCallback)(void *cls, | ||
406 | enum GNUNET_GenericReturnValue rv); | ||
407 | |||
408 | |||
409 | /** | ||
410 | * Run the testsuite. Note, CMDs are copied into | ||
411 | * the interpreter state because they are _usually_ | ||
412 | * defined into the "run" method that returns after | ||
413 | * having scheduled the test interpreter. | ||
414 | * | ||
415 | * @param commands the array of command to execute | ||
416 | * @param timeout how long to wait for each command to execute | ||
417 | * @param rc function to call with the final result | ||
418 | * @param rc_cls closure for @a rc | ||
419 | * @return The interpreter. | ||
420 | */ | ||
421 | struct GNUNET_TESTING_Interpreter * | ||
422 | GNUNET_TESTING_run (const struct GNUNET_TESTING_Command *commands, | ||
423 | struct GNUNET_TIME_Relative timeout, | ||
424 | GNUNET_TESTING_ResultCallback rc, | ||
425 | void *rc_cls); | ||
426 | |||
427 | |||
428 | /** | ||
429 | * Start a GNUnet scheduler event loop and | ||
430 | * run the testsuite. Return 0 upon success. | ||
431 | * Expected to be called directly from main(). | ||
432 | * FIXME: Why is this commands array here not const? | ||
433 | * | ||
434 | * @param commands the list of command to execute | ||
435 | * @param timeout how long to wait for each command to execute | ||
436 | * @return EXIT_SUCCESS on success, EXIT_FAILURE on failure | ||
437 | */ | ||
438 | int | ||
439 | GNUNET_TESTING_main (struct GNUNET_TESTING_Command *commands, | ||
440 | struct GNUNET_TIME_Relative timeout); | ||
441 | |||
442 | |||
443 | |||
444 | /* ************** Fundamental interpreter commands ************ */ | ||
445 | |||
446 | |||
447 | /** | ||
448 | * Create command array terminator. | ||
449 | * | ||
450 | * @return a end-command. | ||
451 | */ | ||
452 | struct GNUNET_TESTING_Command | ||
453 | GNUNET_TESTING_cmd_end (void); | ||
454 | |||
455 | |||
456 | /** | ||
457 | * Create a "batch" command. Such command takes a end_CMD-terminated array of | ||
458 | * CMDs and executed them. Once it hits the end CMD, it passes the control to | ||
459 | * the next top-level CMD, regardless of it being another batch or ordinary | ||
460 | * CMD. | ||
461 | * | ||
462 | * @param label the command label. | ||
463 | * @param batch array of CMDs to execute. | ||
464 | * @return the command. | ||
465 | */ | ||
466 | struct GNUNET_TESTING_Command | ||
467 | GNUNET_TESTING_cmd_batch (const char *label, | ||
468 | struct GNUNET_TESTING_Command *batch); | ||
469 | |||
470 | |||
471 | /** | ||
472 | * Performance counter. | ||
473 | */ | ||
474 | struct GNUNET_TESTING_Timer | ||
475 | { | ||
476 | /** | ||
477 | * For which type of commands. | ||
478 | */ | ||
479 | const char *prefix; | ||
480 | |||
481 | /** | ||
482 | * Total time spend in all commands of this type. | ||
483 | */ | ||
484 | struct GNUNET_TIME_Relative total_duration; | ||
485 | |||
486 | /** | ||
487 | * Total time spend waiting for the *successful* exeuction | ||
488 | * in all commands of this type. | ||
489 | */ | ||
490 | struct GNUNET_TIME_Relative success_latency; | ||
491 | |||
492 | /** | ||
493 | * Number of commands summed up. | ||
494 | */ | ||
495 | unsigned int num_commands; | ||
496 | |||
497 | /** | ||
498 | * Number of retries summed up. | ||
499 | */ | ||
500 | unsigned int num_retries; | ||
501 | }; | ||
502 | |||
503 | /** | ||
504 | * Obtain performance data from the interpreter. | ||
505 | * | ||
506 | * @param[in,out] timers what commands (by label) to obtain runtimes for | ||
507 | * @return the command | ||
508 | */ | ||
509 | struct GNUNET_TESTING_Command | ||
510 | GNUNET_TESTING_cmd_stat (struct GNUNET_TESTING_Timer *timers); | ||
511 | |||
512 | |||
513 | /* *** Generic trait logic for implementing traits ********* */ | ||
514 | |||
515 | /** | ||
516 | * A `struct GNUNET_TESTING_Trait` can be used to exchange data between cmds. | ||
517 | * | ||
518 | * Therefor the cmd which like to provide data to other cmds has to implement | ||
519 | * the trait function, where an array of traits is defined with the help of the | ||
520 | * #GNUNET_TESTING_make_trait_ macro. The data can be retrieved with the help of the | ||
521 | * #GNUNET_TESTING_get_trait_ macro. Traits name and type must be defined to make | ||
522 | * use of the macros. | ||
523 | */ | ||
524 | struct GNUNET_TESTING_Trait | ||
525 | { | ||
526 | /** | ||
527 | * Index number associated with the trait. This gives the | ||
528 | * possibility to have _multiple_ traits on offer under the | ||
529 | * same name. | ||
530 | */ | ||
531 | unsigned int index; | ||
532 | |||
533 | /** | ||
534 | * Trait type, for example "reserve-pub" or "coin-priv". | ||
535 | */ | ||
536 | const char *trait_name; | ||
537 | |||
538 | /** | ||
539 | * Pointer to the piece of data to offer. | ||
540 | */ | ||
541 | const void *ptr; | ||
542 | }; | ||
543 | |||
544 | |||
545 | /** | ||
546 | * "end" of traits array. Because traits are offered into arrays, this type | ||
547 | * of trait is used to mark the end of such arrays; useful when iterating over | ||
548 | * those. | ||
549 | */ | ||
550 | struct GNUNET_TESTING_Trait | ||
551 | GNUNET_TESTING_trait_end (void); | ||
552 | |||
553 | |||
554 | /** | ||
555 | * Obtain value of a trait from a command. | ||
556 | * | ||
557 | * @param traits the array of all the traits. | ||
558 | * @param[out] ret where to store the result. | ||
559 | * @param trait type of the trait to extract. | ||
560 | * @param index index number of the trait to extract. | ||
561 | * @return #GNUNET_OK when the trait is found. | ||
562 | */ | ||
563 | enum GNUNET_GenericReturnValue | ||
564 | GNUNET_TESTING_get_trait (const struct GNUNET_TESTING_Trait *traits, | ||
565 | const void **ret, | ||
566 | const char *trait, | ||
567 | unsigned int index); | ||
568 | |||
569 | |||
570 | |||
571 | /** | ||
572 | * Create headers for a trait with name @a name for | ||
573 | * statically allocated data of type @a type. | ||
574 | * | ||
575 | * @param prefix symbol prefix to use | ||
576 | * @param name name of the trait | ||
577 | * @param type data type for the trait | ||
578 | */ | ||
579 | #define GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT(prefix,name,type) \ | ||
580 | enum GNUNET_GenericReturnValue \ | ||
581 | prefix ## _get_trait_ ## name ( \ | ||
582 | const struct GNUNET_TESTING_Command *cmd, \ | ||
583 | type **ret); \ | ||
584 | struct GNUNET_TESTING_Trait \ | ||
585 | prefix ## _make_trait_ ## name ( \ | ||
586 | type * value); | ||
587 | |||
588 | |||
589 | /** | ||
590 | * Create C implementation for a trait with name @a name for statically | ||
591 | * allocated data of type @a type. | ||
592 | * | ||
593 | * @param prefix symbol prefix to use | ||
594 | * @param name name of the trait | ||
595 | * @param type data type for the trait | ||
596 | */ | ||
597 | #define GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT(prefix,name,type) \ | ||
598 | enum GNUNET_GenericReturnValue \ | ||
599 | prefix ## _get_trait_ ## name ( \ | ||
600 | const struct GNUNET_TESTING_Command *cmd, \ | ||
601 | type * *ret) \ | ||
602 | { \ | ||
603 | if (NULL == cmd->traits) return GNUNET_SYSERR; \ | ||
604 | return cmd->traits (cmd->cls, \ | ||
605 | (const void **) ret, \ | ||
606 | GNUNET_S (name), \ | ||
607 | 0); \ | ||
608 | } \ | ||
609 | struct GNUNET_TESTING_Trait \ | ||
610 | prefix ## _make_trait_ ## name ( \ | ||
611 | type * value) \ | ||
612 | { \ | ||
613 | struct GNUNET_TESTING_Trait ret = { \ | ||
614 | .trait_name = GNUNET_S (name), \ | ||
615 | .ptr = (const void *) value \ | ||
616 | }; \ | ||
617 | return ret; \ | ||
618 | } | ||
619 | |||
620 | |||
621 | /** | ||
622 | * Create headers for a trait with name @a name for | ||
623 | * statically allocated data of type @a type. | ||
624 | * | ||
625 | * @param prefix symbol prefix to use | ||
626 | * @param name name of the trait | ||
627 | * @param type data type for the trait | ||
628 | */ | ||
629 | #define GNUNET_TESTING_MAKE_DECL_INDEXED_TRAIT(prefix,name,type) \ | ||
630 | enum GNUNET_GenericReturnValue \ | ||
631 | prefix ## _get_trait_ ## name ( \ | ||
632 | const struct GNUNET_TESTING_Command *cmd, \ | ||
633 | unsigned int index, \ | ||
634 | type **ret); \ | ||
635 | struct GNUNET_TESTING_Trait \ | ||
636 | prefix ## _make_trait_ ## name ( \ | ||
637 | unsigned int index, \ | ||
638 | type *value); | ||
639 | |||
640 | |||
641 | /** | ||
642 | * Create C implementation for a trait with name @a name for statically | ||
643 | * allocated data of type @a type. | ||
644 | */ | ||
645 | #define GNUNET_TESTING_MAKE_IMPL_INDEXED_TRAIT(prefix,name,type) \ | ||
646 | enum GNUNET_GenericReturnValue \ | ||
647 | prefix ## _get_trait_ ## name ( \ | ||
648 | const struct GNUNET_TESTING_Command *cmd, \ | ||
649 | unsigned int index, \ | ||
650 | type * *ret) \ | ||
651 | { \ | ||
652 | if (NULL == cmd->traits) return GNUNET_SYSERR; \ | ||
653 | return cmd->traits (cmd->cls, \ | ||
654 | (const void **) ret, \ | ||
655 | GNUNET_S (name), \ | ||
656 | index); \ | ||
657 | } \ | ||
658 | struct GNUNET_TESTING_Trait \ | ||
659 | prefix ## _make_trait_ ## name ( \ | ||
660 | unsigned int index, \ | ||
661 | type * value) \ | ||
662 | { \ | ||
663 | struct GNUNET_TESTING_Trait ret = { \ | ||
664 | .index = index, \ | ||
665 | .trait_name = GNUNET_S (name), \ | ||
666 | .ptr = (const void *) value \ | ||
667 | }; \ | ||
668 | return ret; \ | ||
669 | } | ||
670 | |||
671 | |||
672 | /** | ||
673 | * Call #op on all simple traits needed by loop logic. | ||
674 | * | ||
675 | * @param op operation to perform | ||
676 | * @param prefix prefix to pass to @e op | ||
677 | */ | ||
678 | #define GNUNET_TESTING_LOOP_SIMPLE_TRAITS(op,prefix) \ | ||
679 | op (prefix, batch_cmds, struct GNUNET_TESTING_Command *) | ||
680 | |||
681 | |||
682 | GNUNET_TESTING_LOOP_SIMPLE_TRAITS(GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT, GNUNET_TESTING) | ||
683 | |||
684 | |||
685 | /** | ||
686 | * Call #op on all indexed traits needed by loop logic. | ||
687 | * | ||
688 | * @param op operation to perform | ||
689 | * @param prefix prefix to pass to @e op | ||
690 | */ | ||
691 | #define GNUNET_TESTING_LOOP_INDEXED_TRAITS(op,prefix) \ | ||
692 | op (prefix, cmd, const struct GNUNET_TESTING_Command) | ||
693 | |||
694 | GNUNET_TESTING_LOOP_INDEXED_TRAITS (GNUNET_TESTING_MAKE_DECL_INDEXED_TRAIT, GNUNET_TESTING) | ||
695 | |||
696 | |||
697 | #endif | ||
diff --git a/src/include/gnunet_testing_netjail_lib.h b/src/include/gnunet_testing_netjail_lib.h deleted file mode 100644 index 843fce0d5..000000000 --- a/src/include/gnunet_testing_netjail_lib.h +++ /dev/null | |||
@@ -1,546 +0,0 @@ | |||
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 | * @brief API for writing an interpreter to test GNUnet components | ||
23 | * @author Christian Grothoff <christian@grothoff.org> | ||
24 | * @author Marcello Stanisci | ||
25 | * @author t3sserakt | ||
26 | */ | ||
27 | #ifndef GNUNET_TESTING_NETJAIL_LIB_H | ||
28 | #define GNUNET_TESTING_NETJAIL_LIB_H | ||
29 | |||
30 | #include "gnunet_testing_ng_lib.h" | ||
31 | #include "gnunet_testing_plugin.h" | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Router of a netjail subnet. | ||
36 | */ | ||
37 | struct GNUNET_TESTING_NetjailRouter | ||
38 | { | ||
39 | /** | ||
40 | * Will tcp be forwarded? | ||
41 | */ | ||
42 | unsigned int tcp_port; | ||
43 | |||
44 | /** | ||
45 | * Will udp be forwarded? | ||
46 | */ | ||
47 | unsigned int udp_port; | ||
48 | }; | ||
49 | |||
50 | |||
51 | /** | ||
52 | * Enum for the different types of nodes. | ||
53 | */ | ||
54 | enum GNUNET_TESTING_NodeType | ||
55 | { | ||
56 | /** | ||
57 | * Node in a subnet. | ||
58 | */ | ||
59 | GNUNET_TESTING_SUBNET_NODE, | ||
60 | |||
61 | /** | ||
62 | * Global known node. | ||
63 | */ | ||
64 | GNUNET_TESTING_GLOBAL_NODE | ||
65 | }; | ||
66 | |||
67 | /** | ||
68 | * Protocol address prefix für a connection between nodes. | ||
69 | */ | ||
70 | struct GNUNET_TESTING_AddressPrefix | ||
71 | { | ||
72 | /** | ||
73 | * Pointer to the previous prefix in the DLL. | ||
74 | */ | ||
75 | struct GNUNET_TESTING_AddressPrefix *prev; | ||
76 | |||
77 | /** | ||
78 | * Pointer to the next prefix in the DLL. | ||
79 | */ | ||
80 | struct GNUNET_TESTING_AddressPrefix *next; | ||
81 | |||
82 | /** | ||
83 | * The address prefix. | ||
84 | */ | ||
85 | char *address_prefix; | ||
86 | }; | ||
87 | |||
88 | |||
89 | /** | ||
90 | * Node in a netjail topology. | ||
91 | */ | ||
92 | struct GNUNET_TESTING_NetjailNode; | ||
93 | |||
94 | /** | ||
95 | * Connection to another node. | ||
96 | */ | ||
97 | struct GNUNET_TESTING_NodeConnection | ||
98 | { | ||
99 | /** | ||
100 | * Pointer to the previous connection in the DLL. | ||
101 | */ | ||
102 | struct GNUNET_TESTING_NodeConnection *prev; | ||
103 | |||
104 | /** | ||
105 | * Pointer to the next connection in the DLL. | ||
106 | */ | ||
107 | struct GNUNET_TESTING_NodeConnection *next; | ||
108 | |||
109 | /** | ||
110 | * The number of the subnet of the node this connection points to. This is 0, | ||
111 | * if the node is a global known node. | ||
112 | */ | ||
113 | unsigned int namespace_n; | ||
114 | |||
115 | /** | ||
116 | * The number of the node this connection points to. | ||
117 | */ | ||
118 | unsigned int node_n; | ||
119 | |||
120 | /** | ||
121 | * The type of the node this connection points to. | ||
122 | */ | ||
123 | enum GNUNET_TESTING_NodeType node_type; | ||
124 | |||
125 | /** | ||
126 | * The node which establish the connection | ||
127 | */ | ||
128 | struct GNUNET_TESTING_NetjailNode *node; | ||
129 | |||
130 | /** | ||
131 | * Head of the DLL with the address prefixes for the protocolls this node is reachable. | ||
132 | */ | ||
133 | struct GNUNET_TESTING_AddressPrefix *address_prefixes_head; | ||
134 | |||
135 | /** | ||
136 | * Tail of the DLL with the address prefixes for the protocolls this node is reachable. | ||
137 | */ | ||
138 | struct GNUNET_TESTING_AddressPrefix *address_prefixes_tail; | ||
139 | }; | ||
140 | |||
141 | /** | ||
142 | * Node in the netjail topology. | ||
143 | */ | ||
144 | struct GNUNET_TESTING_NetjailNode | ||
145 | { | ||
146 | /** | ||
147 | * Head of the DLL with the connections which shall be established to other nodes. | ||
148 | */ | ||
149 | struct GNUNET_TESTING_NodeConnection *node_connections_head; | ||
150 | |||
151 | /** | ||
152 | * Tail of the DLL with the connections which shall be established to other nodes. | ||
153 | */ | ||
154 | struct GNUNET_TESTING_NodeConnection *node_connections_tail; | ||
155 | |||
156 | /** | ||
157 | * Plugin for the test case to be run on this node. | ||
158 | */ | ||
159 | char *plugin; | ||
160 | |||
161 | /** | ||
162 | * Flag indicating if this node is a global known node. | ||
163 | */ | ||
164 | unsigned int is_global; | ||
165 | |||
166 | /** | ||
167 | * The number of the subnet this node is running in. | ||
168 | */ | ||
169 | unsigned int namespace_n; | ||
170 | |||
171 | /** | ||
172 | * The number of this node in the subnet. | ||
173 | */ | ||
174 | unsigned int node_n; | ||
175 | |||
176 | /** | ||
177 | * The overall number of the node in the whole test system. | ||
178 | */ | ||
179 | unsigned int node_number; | ||
180 | |||
181 | /** | ||
182 | * The number of unintentional additional connections this node waits for. This overwrites the global additional_connects value. | ||
183 | */ | ||
184 | unsigned int additional_connects; | ||
185 | |||
186 | /** | ||
187 | * The number of cmds waiting for a specific barrier. | ||
188 | */ | ||
189 | unsigned int expected_reaches; | ||
190 | }; | ||
191 | |||
192 | |||
193 | /** | ||
194 | * Subnet in a topology. | ||
195 | */ | ||
196 | struct GNUNET_TESTING_NetjailNamespace | ||
197 | { | ||
198 | /** | ||
199 | * The number of the subnet. | ||
200 | */ | ||
201 | unsigned int namespace_n; | ||
202 | |||
203 | /** | ||
204 | * Router of the subnet. | ||
205 | */ | ||
206 | struct GNUNET_TESTING_NetjailRouter *router; | ||
207 | |||
208 | /** | ||
209 | * Hash map containing the nodes in this subnet. | ||
210 | */ | ||
211 | struct GNUNET_CONTAINER_MultiShortmap *nodes; | ||
212 | }; | ||
213 | |||
214 | /** | ||
215 | * Toplogy of our netjail setup. | ||
216 | */ | ||
217 | struct GNUNET_TESTING_NetjailTopology | ||
218 | { | ||
219 | |||
220 | /** | ||
221 | * Default plugin for the test case to be run on nodes. | ||
222 | */ | ||
223 | char *plugin; | ||
224 | |||
225 | /** | ||
226 | * Number of subnets. | ||
227 | */ | ||
228 | unsigned int namespaces_n; | ||
229 | |||
230 | /** | ||
231 | * Number of nodes per subnet. | ||
232 | */ | ||
233 | unsigned int nodes_m; | ||
234 | |||
235 | /** | ||
236 | * Number of global known nodes. | ||
237 | */ | ||
238 | unsigned int nodes_x; | ||
239 | |||
240 | /** | ||
241 | * Hash map containing the subnets (for natted nodes) of the topology. | ||
242 | */ | ||
243 | struct GNUNET_CONTAINER_MultiShortmap *map_namespaces; | ||
244 | |||
245 | /** | ||
246 | * Hash map containing the global known nodes which are not natted. | ||
247 | */ | ||
248 | struct GNUNET_CONTAINER_MultiShortmap *map_globals; | ||
249 | |||
250 | /** | ||
251 | * Additional connects we do expect, beside the connects which are configured in the topology. | ||
252 | */ | ||
253 | unsigned int additional_connects; | ||
254 | }; | ||
255 | |||
256 | /** | ||
257 | * Getting the topology from file. | ||
258 | * | ||
259 | * @param filename The name of the topology file. | ||
260 | * @return The GNUNET_TESTING_NetjailTopology | ||
261 | */ | ||
262 | struct GNUNET_TESTING_NetjailTopology * | ||
263 | GNUNET_TESTING_get_topo_from_file (const char *filename); | ||
264 | |||
265 | |||
266 | /** | ||
267 | * FIXME: this could use a "to_string". | ||
268 | * Parse the topology data. | ||
269 | * | ||
270 | * @param data The topology data. | ||
271 | * @return The GNUNET_TESTING_NetjailTopology | ||
272 | */ | ||
273 | struct GNUNET_TESTING_NetjailTopology * | ||
274 | GNUNET_TESTING_get_topo_from_string (const char *data); | ||
275 | |||
276 | |||
277 | /** | ||
278 | * Get the number of unintentional additional connections the node waits for. | ||
279 | * | ||
280 | * @param num The specific node we want the additional connects for. | ||
281 | * @return The number of additional connects | ||
282 | */ | ||
283 | unsigned int | ||
284 | GNUNET_TESTING_get_additional_connects (unsigned int num, | ||
285 | struct GNUNET_TESTING_NetjailTopology * | ||
286 | topology); | ||
287 | |||
288 | /** | ||
289 | * Get a node from the topology. | ||
290 | * | ||
291 | * @param num The specific node we want the connections for. | ||
292 | * @param topology The topology we get the connections from. | ||
293 | * @return The connections of the node. | ||
294 | */ | ||
295 | struct GNUNET_TESTING_NetjailNode * | ||
296 | GNUNET_TESTING_get_node (unsigned int num, | ||
297 | struct GNUNET_TESTING_NetjailTopology *topology); | ||
298 | |||
299 | |||
300 | /** | ||
301 | * Get the connections to other nodes for a specific node. | ||
302 | * | ||
303 | * @param num The specific node we want the connections for. | ||
304 | * @param topology The topology we get the connections from. | ||
305 | * @return The connections of the node. | ||
306 | */ | ||
307 | struct GNUNET_TESTING_NodeConnection * | ||
308 | GNUNET_TESTING_get_connections (unsigned int num, | ||
309 | const struct GNUNET_TESTING_NetjailTopology *topology); | ||
310 | |||
311 | |||
312 | /** | ||
313 | * Get the address for a specific communicator from a connection. | ||
314 | * | ||
315 | * @param connection The connection we like to have the address from. | ||
316 | * @param prefix The communicator protocol prefix. | ||
317 | * @return The address of the communicator. | ||
318 | */ | ||
319 | char * | ||
320 | GNUNET_TESTING_get_address (struct GNUNET_TESTING_NodeConnection *connection, | ||
321 | const char *prefix); | ||
322 | |||
323 | |||
324 | /** | ||
325 | * Deallocate memory of the struct GNUNET_TESTING_NetjailTopology. | ||
326 | * | ||
327 | * @param topology The GNUNET_TESTING_NetjailTopology to be deallocated. | ||
328 | */ | ||
329 | void | ||
330 | GNUNET_TESTING_free_topology (struct GNUNET_TESTING_NetjailTopology *topology); | ||
331 | |||
332 | |||
333 | /** | ||
334 | * Calculate the unique id identifying a node from a given connection. | ||
335 | * | ||
336 | * @param node_connection The connection we calculate the id from. | ||
337 | * @param topology The topology we get all needed information from. | ||
338 | * @return The unique id of the node from the connection. | ||
339 | */ | ||
340 | unsigned int | ||
341 | GNUNET_TESTING_calculate_num (struct | ||
342 | GNUNET_TESTING_NodeConnection *node_connection, | ||
343 | struct GNUNET_TESTING_NetjailTopology *topology); | ||
344 | |||
345 | |||
346 | /** | ||
347 | * Struct with information for callbacks. | ||
348 | * | ||
349 | */ | ||
350 | struct GNUNET_TESTING_BlockState | ||
351 | { | ||
352 | /** | ||
353 | * Context for our asynchronous completion. | ||
354 | */ | ||
355 | struct GNUNET_TESTING_AsyncContext ac; | ||
356 | |||
357 | /** | ||
358 | * The label of this command. | ||
359 | */ | ||
360 | const char *label; | ||
361 | |||
362 | /** | ||
363 | * If this command will block. | ||
364 | */ | ||
365 | unsigned int asynchronous_finish; | ||
366 | }; | ||
367 | |||
368 | /** | ||
369 | * Struct to hold information for callbacks. | ||
370 | * | ||
371 | */ | ||
372 | struct GNUNET_TESTING_LocalPreparedState | ||
373 | { | ||
374 | /** | ||
375 | * Context for our asynchronous completion. | ||
376 | */ | ||
377 | struct GNUNET_TESTING_AsyncContext ac; | ||
378 | |||
379 | /** | ||
380 | * Callback to write messages to the master loop. | ||
381 | * | ||
382 | */ | ||
383 | GNUNET_TESTING_cmd_helper_write_cb write_message; | ||
384 | }; | ||
385 | |||
386 | /** | ||
387 | * This command destroys the ressources allocated for the test system setup. | ||
388 | * | ||
389 | * @param label Name for command. | ||
390 | * @param create_label Label of the cmd which started the test system. | ||
391 | * @param write_message Callback to write messages to the master loop. | ||
392 | * @return command. | ||
393 | */ | ||
394 | struct GNUNET_TESTING_Command | ||
395 | GNUNET_TESTING_cmd_system_destroy (const char *label, | ||
396 | const char *create_label); | ||
397 | |||
398 | /** | ||
399 | * This command is setting up a test environment for a peer to start. | ||
400 | * | ||
401 | * @param label Name for command. | ||
402 | * @param testdir Only the directory name without any path. Temporary | ||
403 | * directory used for all service homes. | ||
404 | */ | ||
405 | struct GNUNET_TESTING_Command | ||
406 | GNUNET_TESTING_cmd_system_create (const char *label, | ||
407 | const char *testdir); | ||
408 | |||
409 | |||
410 | /** | ||
411 | * This command executes a shell script to setup the netjail environment. | ||
412 | * | ||
413 | * @param label name for command. | ||
414 | * @param topology_config Configuration file for the test topology. | ||
415 | * @param read_file Flag indicating if the the name of the topology file is send to the helper, or a string with the topology data. | ||
416 | * @return command. | ||
417 | */ | ||
418 | struct GNUNET_TESTING_Command | ||
419 | GNUNET_TESTING_cmd_netjail_start (const char *label, | ||
420 | char *topology_config, | ||
421 | unsigned int *read_file); | ||
422 | |||
423 | |||
424 | /** | ||
425 | * This command executes a shell script to remove the netjail environment. | ||
426 | * | ||
427 | * @param label name for command. | ||
428 | * @param topology_config Configuration file for the test topology. | ||
429 | * @param read_file Flag indicating if the the name of the topology file is send to the helper, or a string with the topology data. | ||
430 | * @return command. | ||
431 | */ | ||
432 | struct GNUNET_TESTING_Command | ||
433 | GNUNET_TESTING_cmd_netjail_stop (const char *label, | ||
434 | char *topology_config, | ||
435 | unsigned int *read_file); | ||
436 | |||
437 | |||
438 | /** | ||
439 | * This command executes a shell script which starts a helper process. | ||
440 | * This process is running on a netjail node, executing a defined test case. | ||
441 | * | ||
442 | * @param label Name for the command. | ||
443 | * @param topology The complete topology information. | ||
444 | * @param read_file Flag indicating if the the name of the topology file is send to the helper, or a string with the topology data. | ||
445 | * @param topology_data If read_file is GNUNET_NO, topology_data holds the string with the topology. | ||
446 | * @param timeout Before this timeout is reached this cmd MUST finish. | ||
447 | * @return command. | ||
448 | */ | ||
449 | struct GNUNET_TESTING_Command | ||
450 | GNUNET_TESTING_cmd_netjail_start_cmds_helper ( | ||
451 | const char *label, | ||
452 | struct GNUNET_TESTING_NetjailTopology *topology, | ||
453 | unsigned int *read_file, | ||
454 | char *topology_data, | ||
455 | struct GNUNET_TIME_Relative timeout); | ||
456 | |||
457 | |||
458 | /** | ||
459 | * Create command. | ||
460 | * | ||
461 | * @param label name for command. | ||
462 | * @param helper_start_label label of the cmd to start the test system. | ||
463 | * @param topology The complete topology information. | ||
464 | * @return command. | ||
465 | */ | ||
466 | struct GNUNET_TESTING_Command | ||
467 | GNUNET_TESTING_cmd_stop_cmds_helper ( | ||
468 | const char *label, | ||
469 | const char *helper_start_label, | ||
470 | struct GNUNET_TESTING_NetjailTopology *topology); | ||
471 | |||
472 | |||
473 | /** | ||
474 | * This command is used to block the loop, until the command is finished by other commands, | ||
475 | * using a trait to get this commands struct GNUNET_TESTING_AsyncContext. | ||
476 | * | ||
477 | * @param label name for command. | ||
478 | * @return command. | ||
479 | */ | ||
480 | struct GNUNET_TESTING_Command | ||
481 | GNUNET_TESTING_cmd_block_until_external_trigger ( | ||
482 | const char *label); | ||
483 | |||
484 | /** | ||
485 | * DEPRECATED | ||
486 | * This command sends a GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED message to the master loop. | ||
487 | * | ||
488 | * @param label name for command. | ||
489 | * @param write_message Callback to write messages to the master loop. | ||
490 | * @return command. | ||
491 | */ | ||
492 | struct GNUNET_TESTING_Command | ||
493 | GNUNET_TESTING_cmd_send_peer_ready (const char *label, | ||
494 | GNUNET_TESTING_cmd_helper_write_cb write_message); | ||
495 | |||
496 | |||
497 | /** | ||
498 | * This command sends a GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TESTS_PREPARED message to the master loop. | ||
499 | * | ||
500 | * @param label name for command. | ||
501 | * @param write_message Callback to write messages to the master loop. | ||
502 | * @return command. | ||
503 | */ | ||
504 | struct GNUNET_TESTING_Command | ||
505 | GNUNET_TESTING_cmd_local_test_prepared (const char *label, | ||
506 | GNUNET_TESTING_cmd_helper_write_cb | ||
507 | write_message); | ||
508 | |||
509 | |||
510 | /** | ||
511 | * Create command. | ||
512 | * | ||
513 | * @param label name for command. | ||
514 | * @param system_label Label of the cmd to setup a test environment. | ||
515 | * @param no Decimal number representing the last byte of the IP address of this peer. | ||
516 | * @param node_ip The IP address of this node. | ||
517 | * @param cfgname Configuration file name for this peer. | ||
518 | * @param broadcast Flag indicating, if broadcast should be switched on. | ||
519 | * @return command. | ||
520 | */ | ||
521 | struct GNUNET_TESTING_Command | ||
522 | GNUNET_TESTING_cmd_start_peer (const char *label, | ||
523 | const char *system_label, | ||
524 | uint32_t no, | ||
525 | const char *node_ip, | ||
526 | const char *cfgname, | ||
527 | unsigned int broadcast); | ||
528 | |||
529 | |||
530 | /* ***** Netjail trait support ***** */ | ||
531 | |||
532 | |||
533 | /** | ||
534 | * Call #op on all simple traits. | ||
535 | */ | ||
536 | #define GNUNET_TESTING_SIMPLE_NETJAIL_TRAITS(op, prefix) \ | ||
537 | op (prefix, test_system, const struct GNUNET_TESTING_System) \ | ||
538 | op (prefix, async_context, struct GNUNET_TESTING_AsyncContext) \ | ||
539 | op (prefix, helper_handles, const struct GNUNET_HELPER_Handle *) \ | ||
540 | op (prefix, local_prepared_state, const struct GNUNET_TESTING_LocalPreparedState) \ | ||
541 | op (prefix, block_state, struct GNUNET_TESTING_BlockState) | ||
542 | |||
543 | GNUNET_TESTING_SIMPLE_NETJAIL_TRAITS (GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT, GNUNET_TESTING) | ||
544 | |||
545 | |||
546 | #endif | ||
diff --git a/src/include/gnunet_testing_ng_lib.h b/src/include/gnunet_testing_ng_lib.h deleted file mode 100644 index 407f50bb7..000000000 --- a/src/include/gnunet_testing_ng_lib.h +++ /dev/null | |||
@@ -1,115 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2021, 2023 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 | * @brief Meta-header for next-generation testing logic | ||
23 | * @author Christian Grothoff <christian@grothoff.org> | ||
24 | * @author Marcello Stanisci | ||
25 | * @author t3sserakt | ||
26 | */ | ||
27 | #ifndef GNUNET_TESTING_NG_LIB_H | ||
28 | #define GNUNET_TESTING_NG_LIB_H | ||
29 | |||
30 | |||
31 | #include "gnunet_util_lib.h" | ||
32 | |||
33 | /* FIXME: legacy test header, to be removed!! */ | ||
34 | #include "gnunet_testing_lib.h" | ||
35 | |||
36 | #include "gnunet_testing_plugin.h" | ||
37 | #include "gnunet_testing_loop_lib.h" | ||
38 | #include "gnunet_testing_netjail_lib.h" | ||
39 | |||
40 | |||
41 | /** | ||
42 | * Create a "signal" CMD. | ||
43 | * | ||
44 | * @param label command label. | ||
45 | * @param process_label label of a command that has a process trait | ||
46 | * @param signal signal to send to @a process. | ||
47 | * @return the command. | ||
48 | */ | ||
49 | struct GNUNET_TESTING_Command | ||
50 | GNUNET_TESTING_cmd_signal (const char *label, | ||
51 | const char *process_label, | ||
52 | int signal); | ||
53 | |||
54 | |||
55 | /** | ||
56 | * Sleep for @a duration. | ||
57 | * | ||
58 | * @param label command label. | ||
59 | * @param duration time to sleep | ||
60 | * @return the command. | ||
61 | */ | ||
62 | struct GNUNET_TESTING_Command | ||
63 | GNUNET_TESTING_cmd_sleep (const char *label, | ||
64 | struct GNUNET_TIME_Relative duration); | ||
65 | |||
66 | |||
67 | /** | ||
68 | * Command to execute a script synchronously. | ||
69 | * | ||
70 | * FIXME: is this accurate? How is this limited to BASH scripts or even scripts? | ||
71 | * | ||
72 | * @param label Label of the command. | ||
73 | * @param script The name of the script. | ||
74 | * @param script_argv The arguments of the script. | ||
75 | */ | ||
76 | const struct GNUNET_TESTING_Command | ||
77 | GNUNET_TESTING_cmd_exec_bash_script (const char *label, | ||
78 | const char *script, | ||
79 | char *const script_argv[], | ||
80 | // FIXME: wtf are these two args here for!? | ||
81 | int argc, | ||
82 | GNUNET_ChildCompletedCallback cb); | ||
83 | |||
84 | |||
85 | |||
86 | /* ****** Specific traits needed by this component ******* */ | ||
87 | |||
88 | |||
89 | /** | ||
90 | * Call #op on all simple traits. | ||
91 | */ | ||
92 | #define GNUNET_TESTING_SIMPLE_TRAITS(op, prefix) \ | ||
93 | op (prefix, process, struct GNUNET_OS_Process *) | ||
94 | |||
95 | |||
96 | GNUNET_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT, GNUNET_TESTING) | ||
97 | |||
98 | /** | ||
99 | * Call #op on all indexed traits. | ||
100 | */ | ||
101 | #define GNUNET_TESTING_INDEXED_TRAITS(op, prefix) \ | ||
102 | op (prefix, uint32, const uint32_t) \ | ||
103 | op (prefix, uint64, const uint64_t) \ | ||
104 | op (prefix, int64, const int64_t) \ | ||
105 | op (prefix, uint, const unsigned int) \ | ||
106 | op (prefix, string, const char) \ | ||
107 | op (prefix, uuid, const struct GNUNET_Uuid) \ | ||
108 | op (prefix, time, const struct GNUNET_TIME_Absolute) \ | ||
109 | op (prefix, absolute_time, const struct GNUNET_TIME_Absolute) \ | ||
110 | op (prefix, relative_time, const struct GNUNET_TIME_Relative) | ||
111 | |||
112 | GNUNET_TESTING_INDEXED_TRAITS (GNUNET_TESTING_MAKE_DECL_INDEXED_TRAIT, GNUNET_TESTING) | ||
113 | |||
114 | |||
115 | #endif | ||
diff --git a/src/include/gnunet_testing_plugin.h b/src/include/gnunet_testing_plugin.h deleted file mode 100644 index b030bc8a8..000000000 --- a/src/include/gnunet_testing_plugin.h +++ /dev/null | |||
@@ -1,145 +0,0 @@ | |||
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 | * | ||
23 | * @author t3sserakt | ||
24 | * | ||
25 | * Plugin API to start test cases. | ||
26 | * | ||
27 | */ | ||
28 | #ifndef GNUNET_TESTING_PLUGIN_H | ||
29 | #define GNUNET_TESTING_PLUGIN_H | ||
30 | |||
31 | #include "gnunet_common.h" | ||
32 | |||
33 | #ifdef __cplusplus | ||
34 | extern "C" | ||
35 | { | ||
36 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
37 | } | ||
38 | #endif | ||
39 | #endif | ||
40 | |||
41 | |||
42 | /** | ||
43 | * Callback function to write messages from the helper process running on a netjail node to the master process. | ||
44 | * | ||
45 | * @param message The message to write. | ||
46 | * @param msg_length The length of the message. | ||
47 | */ | ||
48 | typedef void | ||
49 | (*GNUNET_TESTING_cmd_helper_write_cb) (struct GNUNET_MessageHeader *message, | ||
50 | size_t msg_length); | ||
51 | |||
52 | /** | ||
53 | * Callback function which writes a message from the helper process running on a netjail node to the master process * signaling that the test case running on the netjail node finished. | ||
54 | */ | ||
55 | typedef void | ||
56 | (*GNUNET_TESTING_cmd_helper_finish_cb) (); | ||
57 | |||
58 | |||
59 | /** | ||
60 | * Function to be implemented for each test case plugin which starts the test case on a netjail node. | ||
61 | * | ||
62 | * @param write_message Callback function to write messages from the helper process running on a | ||
63 | * netjail node to the master process. | ||
64 | * @param router_ip Global address of the network namespace, if the helper process is for a node in a subnet. | ||
65 | * @param node_ip The IP address of the node. | ||
66 | * @param m The number of the node in a network namespace. | ||
67 | * @param n The number of the network namespace. | ||
68 | * @param local_m The number of nodes in a network namespace. | ||
69 | * @param topology_data A file name for the file containing the topology configuration, or a string containing | ||
70 | * the topology configuration. | ||
71 | * @param read_file If read_file is GNUNET_YES this string is the filename for the topology configuration, | ||
72 | * if read_file is GNUNET_NO the string contains the topology configuration. | ||
73 | * @param finish_cb Callback function which writes a message from the helper process running on a netjail | ||
74 | * node to the master process * signaling that the test case running on the netjail node finished. | ||
75 | * @return Returns The struct GNUNET_TESTING_Interpreter of the command loop running on this netjail node. | ||
76 | */ | ||
77 | typedef struct GNUNET_TESTING_Interpreter * | ||
78 | (*GNUNET_TESTING_PLUGIN_StartTestCase) ( | ||
79 | GNUNET_TESTING_cmd_helper_write_cb write_message, | ||
80 | const char *router_ip, | ||
81 | const char *node_ip, | ||
82 | const char *n, | ||
83 | const char *m, | ||
84 | const char *local_m, | ||
85 | const char *topology_data, | ||
86 | unsigned int *read_file, | ||
87 | GNUNET_TESTING_cmd_helper_finish_cb | ||
88 | finish_cb); | ||
89 | |||
90 | /** | ||
91 | * DEPRECATED | ||
92 | * The helper process received a message of type | ||
93 | * GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED. This will finish the blocking command | ||
94 | * GNUNET_TESTING_cmd_block_until_external_trigger which was execute right after the command | ||
95 | * GNUNET_TESTING_cmd_send_peer_ready. | ||
96 | */ | ||
97 | typedef void | ||
98 | (*GNUNET_TESTING_PLUGIN_ALL_PEERS_STARTED) (); | ||
99 | |||
100 | /** | ||
101 | * DEPRECATED | ||
102 | * The helper process received a message of type | ||
103 | * GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED. This will finish the blocking command | ||
104 | * GNUNET_TESTING_cmd_local_test_prepared which was execute right after the command | ||
105 | * GNUNET_TRANSPORT_cmd_connect_peers. | ||
106 | * FIXME: do not use ALL CAPS | ||
107 | */ | ||
108 | typedef void | ||
109 | (*GNUNET_TESTING_PLUGIN_ALL_LOCAL_TESTS_PREPARED) (); | ||
110 | |||
111 | |||
112 | /** | ||
113 | * This function returns a struct GNUNET_TESTING_BarrierList, which is a list of all barriers | ||
114 | * this test case will wait for. | ||
115 | * | ||
116 | * @return A struct GNUNET_TESTING_BarrierList. | ||
117 | * FIXME: do not use ALL CAPS | ||
118 | */ | ||
119 | typedef struct GNUNET_TESTING_BarrierList* | ||
120 | (*GNUNET_TESTING_PLUGIN_GET_WAITING_FOR_BARRIERS) (void); | ||
121 | |||
122 | |||
123 | /** | ||
124 | * The plugin API every test case plugin has to implement. | ||
125 | */ | ||
126 | struct GNUNET_TESTING_PluginFunctions | ||
127 | { | ||
128 | |||
129 | GNUNET_TESTING_PLUGIN_StartTestCase start_testcase; | ||
130 | |||
131 | GNUNET_TESTING_PLUGIN_ALL_PEERS_STARTED all_peers_started; | ||
132 | |||
133 | GNUNET_TESTING_PLUGIN_ALL_LOCAL_TESTS_PREPARED all_local_tests_prepared; | ||
134 | |||
135 | GNUNET_TESTING_PLUGIN_GET_WAITING_FOR_BARRIERS get_waiting_for_barriers; | ||
136 | }; | ||
137 | |||
138 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
139 | { | ||
140 | #endif | ||
141 | #ifdef __cplusplus | ||
142 | } | ||
143 | #endif | ||
144 | |||
145 | #endif | ||
diff --git a/src/include/gnunet_testing_testbed_lib.h b/src/include/gnunet_testing_testbed_lib.h new file mode 100644 index 000000000..872382706 --- /dev/null +++ b/src/include/gnunet_testing_testbed_lib.h | |||
@@ -0,0 +1,42 @@ | |||
1 | #ifndef GNUNET_TESTING_TESTBED_LIB_H | ||
2 | #define GNUNET_TESTING_TESTBED_LIB_H | ||
3 | |||
4 | #include "gnunet_testing_lib.h" | ||
5 | #include "gnunet_testbed_lib.h" | ||
6 | |||
7 | /** | ||
8 | * This command destroys the ressources allocated for the test system setup. | ||
9 | * | ||
10 | * @param label Name for command. | ||
11 | * @param create_label Label of the cmd which started the test system. | ||
12 | * @param write_message Callback to write messages to the master loop. | ||
13 | * @return command. | ||
14 | */ | ||
15 | struct GNUNET_TESTING_Command | ||
16 | GNUNET_TESTBED_cmd_system_destroy (const char *label, | ||
17 | const char *create_label); | ||
18 | |||
19 | /** | ||
20 | * This command is setting up a test environment for a peer to start. | ||
21 | * | ||
22 | * @param label Name for command. | ||
23 | * @param testdir Only the directory name without any path. Temporary | ||
24 | * directory used for all service homes. | ||
25 | */ | ||
26 | struct GNUNET_TESTING_Command | ||
27 | GNUNET_TESTBED_cmd_system_create (const char *label, | ||
28 | const char *testdir); | ||
29 | |||
30 | |||
31 | /** | ||
32 | * Call #op on all simple traits. | ||
33 | */ | ||
34 | #define GNUNET_TESTING_TESTBED_SIMPLE_TRAITS(op, prefix) \ | ||
35 | op (prefix, test_system, struct GNUNET_TESTBED_System) | ||
36 | |||
37 | |||
38 | GNUNET_TESTING_TESTBED_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT, | ||
39 | GNUNET_TESTING_TESTBED) | ||
40 | |||
41 | |||
42 | #endif | ||
diff --git a/src/include/gnunet_transport_testing_ng_lib.h b/src/include/gnunet_testing_transport_lib.h index be904cf4c..db2749661 100644 --- a/src/include/gnunet_transport_testing_ng_lib.h +++ b/src/include/gnunet_testing_transport_lib.h | |||
@@ -27,18 +27,13 @@ | |||
27 | 27 | ||
28 | 28 | ||
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | #include "gnunet_testing_ng_lib.h" | 30 | #include "gnunet_testing_lib.h" |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * Application handle; FIXME: what exactly is this? | 33 | * Application handle; FIXME: what exactly is this? |
34 | */ | 34 | */ |
35 | struct GNUNET_TRANSPORT_ApplicationHandle; | 35 | struct GNUNET_TRANSPORT_ApplicationHandle; |
36 | 36 | ||
37 | /** | ||
38 | * FIXME: what is this? | ||
39 | */ | ||
40 | struct GNUNET_TESTING_StartPeerState; | ||
41 | |||
42 | 37 | ||
43 | // FIXME: breaks naming conventions | 38 | // FIXME: breaks naming conventions |
44 | typedef void * | 39 | typedef void * |
@@ -46,7 +41,6 @@ typedef void * | |||
46 | const struct GNUNET_PeerIdentity *peer); | 41 | const struct GNUNET_PeerIdentity *peer); |
47 | 42 | ||
48 | 43 | ||
49 | |||
50 | // FIXME: breaks naming conventions! Needed public? | 44 | // FIXME: breaks naming conventions! Needed public? |
51 | struct GNUNET_TESTING_StartPeerState | 45 | struct GNUNET_TESTING_StartPeerState |
52 | { | 46 | { |
@@ -153,7 +147,6 @@ struct GNUNET_TESTING_StartPeerState | |||
153 | }; | 147 | }; |
154 | 148 | ||
155 | 149 | ||
156 | |||
157 | /** | 150 | /** |
158 | * Create command. | 151 | * Create command. |
159 | * | 152 | * |
@@ -191,21 +184,22 @@ GNUNET_TESTING_get_peer (unsigned int num, | |||
191 | const struct GNUNET_TESTING_System *tl_system); | 184 | const struct GNUNET_TESTING_System *tl_system); |
192 | 185 | ||
193 | 186 | ||
194 | |||
195 | |||
196 | /** | 187 | /** |
197 | * Call #op on all simple traits. | 188 | * Call #op on all simple traits. |
198 | */ | 189 | */ |
199 | #define GNUNET_TRANSPORT_TESTING_SIMPLE_TRAITS(op, prefix) \ | 190 | #define GNUNET_TRANSPORT_TESTING_SIMPLE_TRAITS(op, prefix) \ |
200 | op (prefix, connected_peers_map, const struct GNUNET_CONTAINER_MultiShortmap) \ | 191 | op (prefix, connected_peers_map, const struct \ |
201 | op (prefix, peer_id, const struct GNUNET_PeerIdentity) \ | 192 | GNUNET_CONTAINER_MultiShortmap) \ |
202 | op (prefix, hello_size, const size_t) \ | 193 | op (prefix, peer_id, const struct GNUNET_PeerIdentity) \ |
203 | op (prefix, hello, const char) \ | 194 | op (prefix, hello_size, const size_t) \ |
204 | op (prefix, application_handle, const struct GNUNET_TRANSPORT_ApplicationHandle) \ | 195 | op (prefix, hello, const char) \ |
205 | op (prefix, state, const struct GNUNET_TESTING_StartPeerState) \ | 196 | op (prefix, application_handle, const struct \ |
206 | op (prefix, broadcast, const enum GNUNET_GenericReturnValue) | 197 | GNUNET_TRANSPORT_ApplicationHandle) \ |
207 | 198 | op (prefix, state, const struct GNUNET_TESTING_StartPeerState) \ | |
208 | 199 | op (prefix, broadcast, const enum GNUNET_GenericReturnValue) | |
209 | GNUNET_TRANSPORT_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT, GNUNET_TRANSPORT_TESTING) | 200 | |
201 | |||
202 | GNUNET_TRANSPORT_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT, | ||
203 | GNUNET_TRANSPORT_TESTING) | ||
210 | 204 | ||
211 | #endif | 205 | #endif |
diff --git a/src/include/gnunet_transport_application_service.h b/src/include/gnunet_transport_application_service.h index 66512089a..c093ad96a 100644 --- a/src/include/gnunet_transport_application_service.h +++ b/src/include/gnunet_transport_application_service.h | |||
@@ -36,8 +36,6 @@ | |||
36 | 36 | ||
37 | #include "gnunet_constants.h" | 37 | #include "gnunet_constants.h" |
38 | #include "gnunet_util_lib.h" | 38 | #include "gnunet_util_lib.h" |
39 | #include "gnunet_testing_lib.h" | ||
40 | #include "gnunet_testing_ng_lib.h" | ||
41 | 39 | ||
42 | /** | 40 | /** |
43 | * Handle to the TRANSPORT subsystem for making suggestions about | 41 | * Handle to the TRANSPORT subsystem for making suggestions about |
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index c9871d8c7..89a34b299 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am | |||
@@ -4,10 +4,11 @@ endif | |||
4 | 4 | ||
5 | SUBDIRS = \ | 5 | SUBDIRS = \ |
6 | util \ | 6 | util \ |
7 | hello \ | ||
8 | block \ | ||
9 | gnsrecord \ | ||
10 | curl \ | 7 | curl \ |
11 | json \ | 8 | json \ |
12 | sq \ | 9 | sq \ |
13 | $(POSTGRES_DIR) | 10 | $(POSTGRES_DIR) \ |
11 | hello \ | ||
12 | block \ | ||
13 | gnsrecord \ | ||
14 | testing | ||
diff --git a/src/lib/gnsrecord/test_gnsrecord_block_expiration.c b/src/lib/gnsrecord/test_gnsrecord_block_expiration.c index bc580954e..14b2acd97 100644 --- a/src/lib/gnsrecord/test_gnsrecord_block_expiration.c +++ b/src/lib/gnsrecord/test_gnsrecord_block_expiration.c | |||
@@ -83,7 +83,8 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
83 | rd[1].record_type = TEST_RECORD_TYPE; | 83 | rd[1].record_type = TEST_RECORD_TYPE; |
84 | rd[1].data_size = TEST_RECORD_DATALEN; | 84 | rd[1].data_size = TEST_RECORD_DATALEN; |
85 | GNUNET_free (tmp_data1); | 85 | GNUNET_free (tmp_data1); |
86 | rd[1].data = GNUNET_malloc (TEST_RECORD_DATALEN); | 86 | tmp_data1 = GNUNET_malloc (TEST_RECORD_DATALEN); |
87 | rd[1].data = tmp_data1; | ||
87 | rd[1].flags = GNUNET_GNSRECORD_RF_SHADOW; | 88 | rd[1].flags = GNUNET_GNSRECORD_RF_SHADOW; |
88 | memset ((char *) rd[1].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); | 89 | memset ((char *) rd[1].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); |
89 | 90 | ||
diff --git a/src/lib/gnsrecord/test_gnsrecord_testvectors.c b/src/lib/gnsrecord/test_gnsrecord_testvectors.c index 21a7a83b0..12b9efe56 100644 --- a/src/lib/gnsrecord/test_gnsrecord_testvectors.c +++ b/src/lib/gnsrecord/test_gnsrecord_testvectors.c | |||
@@ -655,6 +655,7 @@ main () | |||
655 | printf ("FAIL: query does not match:"); | 655 | printf ("FAIL: query does not match:"); |
656 | printf (" expected: %s", GNUNET_h2s (&expected_query)); | 656 | printf (" expected: %s", GNUNET_h2s (&expected_query)); |
657 | printf (", was: %s\n", GNUNET_h2s (&query)); | 657 | printf (", was: %s\n", GNUNET_h2s (&query)); |
658 | GNUNET_free (rrblock); | ||
658 | res = 1; | 659 | res = 1; |
659 | break; | 660 | break; |
660 | } | 661 | } |
@@ -671,6 +672,7 @@ main () | |||
671 | { | 672 | { |
672 | printf ("FAIL: Deserialization of RDATA failed\n"); | 673 | printf ("FAIL: Deserialization of RDATA failed\n"); |
673 | res = 1; | 674 | res = 1; |
675 | GNUNET_free (rrblock); | ||
674 | break; | 676 | break; |
675 | } | 677 | } |
676 | expire = GNUNET_GNSRECORD_record_get_expiration_time ( | 678 | expire = GNUNET_GNSRECORD_record_get_expiration_time ( |
@@ -681,6 +683,7 @@ main () | |||
681 | (GNUNET_OK != check_derivations_pkey (label, expire, &pub, &tvs[i]))) | 683 | (GNUNET_OK != check_derivations_pkey (label, expire, &pub, &tvs[i]))) |
682 | { | 684 | { |
683 | res = 1; | 685 | res = 1; |
686 | GNUNET_free (rrblock); | ||
684 | break; | 687 | break; |
685 | } | 688 | } |
686 | else if ((GNUNET_GNSRECORD_TYPE_EDKEY == ntohl (pub.type)) && | 689 | else if ((GNUNET_GNSRECORD_TYPE_EDKEY == ntohl (pub.type)) && |
@@ -688,6 +691,7 @@ main () | |||
688 | &tvs[i]))) | 691 | &tvs[i]))) |
689 | { | 692 | { |
690 | res = 1; | 693 | res = 1; |
694 | GNUNET_free (rrblock); | ||
691 | break; | 695 | break; |
692 | } | 696 | } |
693 | if (GNUNET_OK != GNUNET_GNSRECORD_block_decrypt (rrblock, | 697 | if (GNUNET_OK != GNUNET_GNSRECORD_block_decrypt (rrblock, |
@@ -698,10 +702,14 @@ main () | |||
698 | { | 702 | { |
699 | printf ("FAIL: Decryption of RRBLOCK failed\n"); | 703 | printf ("FAIL: Decryption of RRBLOCK failed\n"); |
700 | res = 1; | 704 | res = 1; |
705 | GNUNET_free (rrblock); | ||
701 | break; | 706 | break; |
702 | } | 707 | } |
703 | if (0 != res) | 708 | if (0 != res) |
709 | { | ||
710 | GNUNET_free (rrblock); | ||
704 | break; | 711 | break; |
712 | } | ||
705 | printf ("Good.\n"); | 713 | printf ("Good.\n"); |
706 | } | 714 | } |
707 | return res; | 715 | return res; |
diff --git a/src/lib/json/json_helper.c b/src/lib/json/json_helper.c index b6965e080..5c2f8ae05 100644 --- a/src/lib/json/json_helper.c +++ b/src/lib/json/json_helper.c | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_json_lib.h" | 28 | #include "gnunet_json_lib.h" |
29 | #include "gnunet_common.h" | ||
29 | 30 | ||
30 | 31 | ||
31 | struct GNUNET_JSON_Specification | 32 | struct GNUNET_JSON_Specification |
@@ -42,6 +43,29 @@ GNUNET_JSON_spec_end () | |||
42 | 43 | ||
43 | 44 | ||
44 | /** | 45 | /** |
46 | * Convert string value to numeric cipher value. | ||
47 | * | ||
48 | * @param cipher_s input string | ||
49 | * @return numeric cipher value | ||
50 | */ | ||
51 | static enum GNUNET_CRYPTO_BlindSignatureAlgorithm | ||
52 | string_to_cipher (const char *cipher_s) | ||
53 | { | ||
54 | if ((0 == strcasecmp (cipher_s, | ||
55 | "RSA")) || | ||
56 | (0 == strcasecmp (cipher_s, | ||
57 | "RSA+age_restricted"))) | ||
58 | return GNUNET_CRYPTO_BSA_RSA; | ||
59 | if ((0 == strcasecmp (cipher_s, | ||
60 | "CS")) || | ||
61 | (0 == strcasecmp (cipher_s, | ||
62 | "CS+age_restricted"))) | ||
63 | return GNUNET_CRYPTO_BSA_CS; | ||
64 | return GNUNET_CRYPTO_BSA_INVALID; | ||
65 | } | ||
66 | |||
67 | |||
68 | /** | ||
45 | * Parse given JSON object to fixed size data | 69 | * Parse given JSON object to fixed size data |
46 | * | 70 | * |
47 | * @param cls closure, NULL | 71 | * @param cls closure, NULL |
@@ -1180,4 +1204,408 @@ GNUNET_JSON_spec_boolean (const char *name, | |||
1180 | } | 1204 | } |
1181 | 1205 | ||
1182 | 1206 | ||
1207 | /** | ||
1208 | * Parse given JSON object to a blinded message. | ||
1209 | * | ||
1210 | * @param cls closure, NULL | ||
1211 | * @param root the json object representing data | ||
1212 | * @param[out] spec where to write the data | ||
1213 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | ||
1214 | */ | ||
1215 | static enum GNUNET_GenericReturnValue | ||
1216 | parse_blinded_message (void *cls, | ||
1217 | json_t *root, | ||
1218 | struct GNUNET_JSON_Specification *spec) | ||
1219 | { | ||
1220 | struct GNUNET_CRYPTO_BlindedMessage **target = spec->ptr; | ||
1221 | struct GNUNET_CRYPTO_BlindedMessage *blinded_message; | ||
1222 | const char *cipher; | ||
1223 | struct GNUNET_JSON_Specification dspec[] = { | ||
1224 | GNUNET_JSON_spec_string ("cipher", | ||
1225 | &cipher), | ||
1226 | GNUNET_JSON_spec_end () | ||
1227 | }; | ||
1228 | const char *emsg; | ||
1229 | unsigned int eline; | ||
1230 | |||
1231 | (void) cls; | ||
1232 | if (GNUNET_OK != | ||
1233 | GNUNET_JSON_parse (root, | ||
1234 | dspec, | ||
1235 | &emsg, | ||
1236 | &eline)) | ||
1237 | { | ||
1238 | GNUNET_break_op (0); | ||
1239 | return GNUNET_SYSERR; | ||
1240 | } | ||
1241 | blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); | ||
1242 | blinded_message->rc = 1; | ||
1243 | blinded_message->cipher = string_to_cipher (cipher); | ||
1244 | switch (blinded_message->cipher) | ||
1245 | { | ||
1246 | case GNUNET_CRYPTO_BSA_INVALID: | ||
1247 | break; | ||
1248 | case GNUNET_CRYPTO_BSA_RSA: | ||
1249 | { | ||
1250 | struct GNUNET_JSON_Specification ispec[] = { | ||
1251 | GNUNET_JSON_spec_varsize ( | ||
1252 | /* TODO: Change this field name to something | ||
1253 | more generic / pass in as argument. */ | ||
1254 | "rsa_blinded_planchet", | ||
1255 | &blinded_message->details.rsa_blinded_message.blinded_msg, | ||
1256 | &blinded_message->details.rsa_blinded_message.blinded_msg_size), | ||
1257 | GNUNET_JSON_spec_end () | ||
1258 | }; | ||
1259 | |||
1260 | if (GNUNET_OK != | ||
1261 | GNUNET_JSON_parse (root, | ||
1262 | ispec, | ||
1263 | &emsg, | ||
1264 | &eline)) | ||
1265 | { | ||
1266 | GNUNET_break_op (0); | ||
1267 | GNUNET_free (blinded_message); | ||
1268 | return GNUNET_SYSERR; | ||
1269 | } | ||
1270 | *target = blinded_message; | ||
1271 | return GNUNET_OK; | ||
1272 | } | ||
1273 | case GNUNET_CRYPTO_BSA_CS: | ||
1274 | { | ||
1275 | struct GNUNET_JSON_Specification ispec[] = { | ||
1276 | GNUNET_JSON_spec_fixed_auto ( | ||
1277 | "cs_nonce", | ||
1278 | &blinded_message->details.cs_blinded_message.nonce), | ||
1279 | GNUNET_JSON_spec_fixed_auto ( | ||
1280 | "cs_blinded_c0", | ||
1281 | &blinded_message->details.cs_blinded_message.c[0]), | ||
1282 | GNUNET_JSON_spec_fixed_auto ( | ||
1283 | "cs_blinded_c1", | ||
1284 | &blinded_message->details.cs_blinded_message.c[1]), | ||
1285 | GNUNET_JSON_spec_end () | ||
1286 | }; | ||
1287 | |||
1288 | if (GNUNET_OK != | ||
1289 | GNUNET_JSON_parse (root, | ||
1290 | ispec, | ||
1291 | &emsg, | ||
1292 | &eline)) | ||
1293 | { | ||
1294 | GNUNET_break_op (0); | ||
1295 | GNUNET_free (blinded_message); | ||
1296 | return GNUNET_SYSERR; | ||
1297 | } | ||
1298 | *target = blinded_message; | ||
1299 | return GNUNET_OK; | ||
1300 | } | ||
1301 | } | ||
1302 | GNUNET_break_op (0); | ||
1303 | GNUNET_free (blinded_message); | ||
1304 | return GNUNET_SYSERR; | ||
1305 | } | ||
1306 | |||
1307 | /** | ||
1308 | * Cleanup data left from parsing blinded message. | ||
1309 | * | ||
1310 | * @param cls closure, NULL | ||
1311 | * @param[out] spec where to free the data | ||
1312 | */ | ||
1313 | static void | ||
1314 | clean_blinded_message (void *cls, | ||
1315 | struct GNUNET_JSON_Specification *spec) | ||
1316 | { | ||
1317 | struct GNUNET_CRYPTO_BlindedMessage **blinded_message = spec->ptr; | ||
1318 | |||
1319 | (void) cls; | ||
1320 | if (NULL != blinded_message) | ||
1321 | { | ||
1322 | GNUNET_CRYPTO_blinded_message_decref (*blinded_message); | ||
1323 | *blinded_message = NULL; | ||
1324 | } | ||
1325 | } | ||
1326 | |||
1327 | |||
1328 | struct GNUNET_JSON_Specification | ||
1329 | GNUNET_JSON_spec_blinded_message (const char *name, | ||
1330 | struct GNUNET_CRYPTO_BlindedMessage **msg) | ||
1331 | { | ||
1332 | struct GNUNET_JSON_Specification ret = { | ||
1333 | .parser = &parse_blinded_message, | ||
1334 | .cleaner = &clean_blinded_message, | ||
1335 | .cls = NULL, | ||
1336 | .field = name, | ||
1337 | .ptr = msg, | ||
1338 | .ptr_size = 0, | ||
1339 | .size_ptr = NULL | ||
1340 | }; | ||
1341 | |||
1342 | *msg = NULL; | ||
1343 | return ret; | ||
1344 | } | ||
1345 | |||
1346 | |||
1347 | /** | ||
1348 | * Parse given JSON object to a blinded signature. | ||
1349 | * | ||
1350 | * @param cls closure, NULL | ||
1351 | * @param root the json object representing data | ||
1352 | * @param[out] spec where to write the data | ||
1353 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | ||
1354 | */ | ||
1355 | static enum GNUNET_GenericReturnValue | ||
1356 | parse_blinded_sig (void *cls, | ||
1357 | json_t *root, | ||
1358 | struct GNUNET_JSON_Specification *spec) | ||
1359 | { | ||
1360 | struct GNUNET_CRYPTO_BlindedSignature **target = spec->ptr; | ||
1361 | struct GNUNET_CRYPTO_BlindedSignature *blinded_sig; | ||
1362 | const char *cipher; | ||
1363 | struct GNUNET_JSON_Specification dspec[] = { | ||
1364 | GNUNET_JSON_spec_string ("cipher", | ||
1365 | &cipher), | ||
1366 | GNUNET_JSON_spec_end () | ||
1367 | }; | ||
1368 | const char *emsg; | ||
1369 | unsigned int eline; | ||
1370 | |||
1371 | (void) cls; | ||
1372 | if (GNUNET_OK != | ||
1373 | GNUNET_JSON_parse (root, | ||
1374 | dspec, | ||
1375 | &emsg, | ||
1376 | &eline)) | ||
1377 | { | ||
1378 | GNUNET_break_op (0); | ||
1379 | return GNUNET_SYSERR; | ||
1380 | } | ||
1381 | blinded_sig = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature); | ||
1382 | blinded_sig->cipher = string_to_cipher (cipher); | ||
1383 | blinded_sig->rc = 1; | ||
1384 | switch (blinded_sig->cipher) | ||
1385 | { | ||
1386 | case GNUNET_CRYPTO_BSA_INVALID: | ||
1387 | break; | ||
1388 | case GNUNET_CRYPTO_BSA_RSA: | ||
1389 | { | ||
1390 | struct GNUNET_JSON_Specification ispec[] = { | ||
1391 | GNUNET_JSON_spec_rsa_signature ( | ||
1392 | "blinded_rsa_signature", | ||
1393 | &blinded_sig->details.blinded_rsa_signature), | ||
1394 | GNUNET_JSON_spec_end () | ||
1395 | }; | ||
1396 | |||
1397 | if (GNUNET_OK != | ||
1398 | GNUNET_JSON_parse (root, | ||
1399 | ispec, | ||
1400 | &emsg, | ||
1401 | &eline)) | ||
1402 | { | ||
1403 | GNUNET_break_op (0); | ||
1404 | GNUNET_free (blinded_sig); | ||
1405 | return GNUNET_SYSERR; | ||
1406 | } | ||
1407 | *target = blinded_sig; | ||
1408 | return GNUNET_OK; | ||
1409 | } | ||
1410 | case GNUNET_CRYPTO_BSA_CS: | ||
1411 | { | ||
1412 | struct GNUNET_JSON_Specification ispec[] = { | ||
1413 | GNUNET_JSON_spec_uint32 ("b", | ||
1414 | &blinded_sig->details.blinded_cs_answer.b), | ||
1415 | GNUNET_JSON_spec_fixed_auto ("s", | ||
1416 | &blinded_sig->details.blinded_cs_answer. | ||
1417 | s_scalar), | ||
1418 | GNUNET_JSON_spec_end () | ||
1419 | }; | ||
1420 | |||
1421 | if (GNUNET_OK != | ||
1422 | GNUNET_JSON_parse (root, | ||
1423 | ispec, | ||
1424 | &emsg, | ||
1425 | &eline)) | ||
1426 | { | ||
1427 | GNUNET_break_op (0); | ||
1428 | GNUNET_free (blinded_sig); | ||
1429 | return GNUNET_SYSERR; | ||
1430 | } | ||
1431 | *target = blinded_sig; | ||
1432 | return GNUNET_OK; | ||
1433 | } | ||
1434 | } | ||
1435 | GNUNET_break_op (0); | ||
1436 | GNUNET_free (blinded_sig); | ||
1437 | return GNUNET_SYSERR; | ||
1438 | } | ||
1439 | |||
1440 | |||
1441 | /** | ||
1442 | * Cleanup data left from parsing blinded sig. | ||
1443 | * | ||
1444 | * @param cls closure, NULL | ||
1445 | * @param[out] spec where to free the data | ||
1446 | */ | ||
1447 | static void | ||
1448 | clean_blinded_sig (void *cls, | ||
1449 | struct GNUNET_JSON_Specification *spec) | ||
1450 | { | ||
1451 | struct GNUNET_CRYPTO_BlindedSignature **b_sig = spec->ptr; | ||
1452 | |||
1453 | (void) cls; | ||
1454 | |||
1455 | if (NULL != *b_sig) | ||
1456 | { | ||
1457 | GNUNET_CRYPTO_blinded_sig_decref (*b_sig); | ||
1458 | *b_sig = NULL; | ||
1459 | } | ||
1460 | } | ||
1461 | |||
1462 | |||
1463 | struct GNUNET_JSON_Specification | ||
1464 | GNUNET_JSON_spec_blinded_signature (const char *field, | ||
1465 | struct GNUNET_CRYPTO_BlindedSignature **b_sig) | ||
1466 | { | ||
1467 | struct GNUNET_JSON_Specification ret = { | ||
1468 | .parser = &parse_blinded_sig, | ||
1469 | .cleaner = &clean_blinded_sig, | ||
1470 | .field = field, | ||
1471 | .ptr = b_sig | ||
1472 | }; | ||
1473 | |||
1474 | *b_sig = NULL; | ||
1475 | return ret; | ||
1476 | } | ||
1477 | |||
1478 | /** | ||
1479 | * Parse given JSON object to unblinded signature. | ||
1480 | * | ||
1481 | * @param cls closure, NULL | ||
1482 | * @param root the json object representing data | ||
1483 | * @param[out] spec where to write the data | ||
1484 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | ||
1485 | */ | ||
1486 | static enum GNUNET_GenericReturnValue | ||
1487 | parse_unblinded_sig (void *cls, | ||
1488 | json_t *root, | ||
1489 | struct GNUNET_JSON_Specification *spec) | ||
1490 | { | ||
1491 | struct GNUNET_CRYPTO_UnblindedSignature **target = spec->ptr; | ||
1492 | struct GNUNET_CRYPTO_UnblindedSignature *unblinded_sig; | ||
1493 | const char *cipher; | ||
1494 | struct GNUNET_JSON_Specification dspec[] = { | ||
1495 | GNUNET_JSON_spec_string ("cipher", | ||
1496 | &cipher), | ||
1497 | GNUNET_JSON_spec_end () | ||
1498 | }; | ||
1499 | const char *emsg; | ||
1500 | unsigned int eline; | ||
1501 | |||
1502 | (void) cls; | ||
1503 | if (GNUNET_OK != | ||
1504 | GNUNET_JSON_parse (root, | ||
1505 | dspec, | ||
1506 | &emsg, | ||
1507 | &eline)) | ||
1508 | { | ||
1509 | GNUNET_break_op (0); | ||
1510 | return GNUNET_SYSERR; | ||
1511 | } | ||
1512 | unblinded_sig = GNUNET_new (struct GNUNET_CRYPTO_UnblindedSignature); | ||
1513 | unblinded_sig->cipher = string_to_cipher (cipher); | ||
1514 | unblinded_sig->rc = 1; | ||
1515 | switch (unblinded_sig->cipher) | ||
1516 | { | ||
1517 | case GNUNET_CRYPTO_BSA_INVALID: | ||
1518 | break; | ||
1519 | case GNUNET_CRYPTO_BSA_RSA: | ||
1520 | { | ||
1521 | struct GNUNET_JSON_Specification ispec[] = { | ||
1522 | GNUNET_JSON_spec_rsa_signature ( | ||
1523 | "rsa_signature", | ||
1524 | &unblinded_sig->details.rsa_signature), | ||
1525 | GNUNET_JSON_spec_end () | ||
1526 | }; | ||
1527 | |||
1528 | if (GNUNET_OK != | ||
1529 | GNUNET_JSON_parse (root, | ||
1530 | ispec, | ||
1531 | &emsg, | ||
1532 | &eline)) | ||
1533 | { | ||
1534 | GNUNET_break_op (0); | ||
1535 | GNUNET_free (unblinded_sig); | ||
1536 | return GNUNET_SYSERR; | ||
1537 | } | ||
1538 | *target = unblinded_sig; | ||
1539 | return GNUNET_OK; | ||
1540 | } | ||
1541 | case GNUNET_CRYPTO_BSA_CS: | ||
1542 | { | ||
1543 | struct GNUNET_JSON_Specification ispec[] = { | ||
1544 | GNUNET_JSON_spec_fixed_auto ("cs_signature_r", | ||
1545 | &unblinded_sig->details.cs_signature. | ||
1546 | r_point), | ||
1547 | GNUNET_JSON_spec_fixed_auto ("cs_signature_s", | ||
1548 | &unblinded_sig->details.cs_signature. | ||
1549 | s_scalar), | ||
1550 | GNUNET_JSON_spec_end () | ||
1551 | }; | ||
1552 | |||
1553 | if (GNUNET_OK != | ||
1554 | GNUNET_JSON_parse (root, | ||
1555 | ispec, | ||
1556 | &emsg, | ||
1557 | &eline)) | ||
1558 | { | ||
1559 | GNUNET_break_op (0); | ||
1560 | GNUNET_free (unblinded_sig); | ||
1561 | return GNUNET_SYSERR; | ||
1562 | } | ||
1563 | *target = unblinded_sig; | ||
1564 | return GNUNET_OK; | ||
1565 | } | ||
1566 | } | ||
1567 | GNUNET_break_op (0); | ||
1568 | GNUNET_free (unblinded_sig); | ||
1569 | return GNUNET_SYSERR; | ||
1570 | } | ||
1571 | |||
1572 | |||
1573 | /** | ||
1574 | * Cleanup data left from parsing unblinded signature. | ||
1575 | * | ||
1576 | * @param cls closure, NULL | ||
1577 | * @param[out] spec where to free the data | ||
1578 | */ | ||
1579 | static void | ||
1580 | clean_unblinded_sig (void *cls, | ||
1581 | struct GNUNET_JSON_Specification *spec) | ||
1582 | { | ||
1583 | struct GNUNET_CRYPTO_UnblindedSignature **ub_sig = spec->ptr; | ||
1584 | |||
1585 | (void) cls; | ||
1586 | if (NULL != *ub_sig) | ||
1587 | { | ||
1588 | GNUNET_CRYPTO_unblinded_sig_decref (*ub_sig); | ||
1589 | *ub_sig = NULL; | ||
1590 | } | ||
1591 | } | ||
1592 | |||
1593 | |||
1594 | struct GNUNET_JSON_Specification | ||
1595 | GNUNET_JSON_spec_unblinded_signature (const char *field, | ||
1596 | struct GNUNET_CRYPTO_UnblindedSignature **ub_sig) | ||
1597 | { | ||
1598 | struct GNUNET_JSON_Specification ret = { | ||
1599 | .parser = &parse_unblinded_sig, | ||
1600 | .cleaner = &clean_unblinded_sig, | ||
1601 | .field = field, | ||
1602 | .ptr = ub_sig | ||
1603 | }; | ||
1604 | |||
1605 | *ub_sig = NULL; | ||
1606 | return ret; | ||
1607 | } | ||
1608 | |||
1609 | |||
1610 | |||
1183 | /* end of json_helper.c */ | 1611 | /* end of json_helper.c */ |
diff --git a/src/lib/json/json_pack.c b/src/lib/json/json_pack.c index 18487c3f4..d298e6efe 100644 --- a/src/lib/json/json_pack.c +++ b/src/lib/json/json_pack.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include "platform.h" | 25 | #include "platform.h" |
26 | #include "gnunet_json_lib.h" | 26 | #include "gnunet_json_lib.h" |
27 | 27 | ||
28 | |||
29 | json_t * | 28 | json_t * |
30 | GNUNET_JSON_pack_ (struct GNUNET_JSON_PackSpec spec[]) | 29 | GNUNET_JSON_pack_ (struct GNUNET_JSON_PackSpec spec[]) |
31 | { | 30 | { |
@@ -364,4 +363,118 @@ GNUNET_JSON_pack_rsa_signature (const char *name, | |||
364 | } | 363 | } |
365 | 364 | ||
366 | 365 | ||
366 | struct GNUNET_JSON_PackSpec | ||
367 | GNUNET_JSON_pack_unblinded_signature (const char *name, | ||
368 | const struct GNUNET_CRYPTO_UnblindedSignature *sig) | ||
369 | { | ||
370 | struct GNUNET_JSON_PackSpec ps = { | ||
371 | .field_name = name | ||
372 | }; | ||
373 | |||
374 | if (NULL == sig) | ||
375 | return ps; | ||
376 | |||
377 | switch (sig->cipher) | ||
378 | { | ||
379 | case GNUNET_CRYPTO_BSA_INVALID: | ||
380 | break; | ||
381 | case GNUNET_CRYPTO_BSA_RSA: | ||
382 | ps.object = GNUNET_JSON_PACK ( | ||
383 | GNUNET_JSON_pack_string ("cipher", | ||
384 | "RSA"), | ||
385 | GNUNET_JSON_pack_rsa_signature ("rsa_signature", | ||
386 | sig->details.rsa_signature)); | ||
387 | return ps; | ||
388 | case GNUNET_CRYPTO_BSA_CS: | ||
389 | ps.object = GNUNET_JSON_PACK ( | ||
390 | GNUNET_JSON_pack_string ("cipher", | ||
391 | "CS"), | ||
392 | GNUNET_JSON_pack_data_auto ("cs_signature_r", | ||
393 | &sig->details.cs_signature.r_point), | ||
394 | GNUNET_JSON_pack_data_auto ("cs_signature_s", | ||
395 | &sig->details.cs_signature.s_scalar)); | ||
396 | return ps; | ||
397 | } | ||
398 | GNUNET_assert (0); | ||
399 | return ps; | ||
400 | } | ||
401 | |||
402 | |||
403 | struct GNUNET_JSON_PackSpec | ||
404 | GNUNET_JSON_pack_blinded_message (const char *name, | ||
405 | const struct GNUNET_CRYPTO_BlindedMessage *msg) | ||
406 | { | ||
407 | struct GNUNET_JSON_PackSpec ps = { | ||
408 | .field_name = name, | ||
409 | }; | ||
410 | |||
411 | switch (msg->cipher) | ||
412 | { | ||
413 | case GNUNET_CRYPTO_BSA_INVALID: | ||
414 | break; | ||
415 | case GNUNET_CRYPTO_BSA_RSA: | ||
416 | ps.object = GNUNET_JSON_PACK ( | ||
417 | GNUNET_JSON_pack_string ("cipher", | ||
418 | "RSA"), | ||
419 | GNUNET_JSON_pack_data_varsize ( | ||
420 | "rsa_blinded_planchet", | ||
421 | msg->details.rsa_blinded_message.blinded_msg, | ||
422 | msg->details.rsa_blinded_message.blinded_msg_size)); | ||
423 | return ps; | ||
424 | case GNUNET_CRYPTO_BSA_CS: | ||
425 | ps.object = GNUNET_JSON_PACK ( | ||
426 | GNUNET_JSON_pack_string ("cipher", | ||
427 | "CS"), | ||
428 | GNUNET_JSON_pack_data_auto ( | ||
429 | "cs_nonce", | ||
430 | &msg->details.cs_blinded_message.nonce), | ||
431 | GNUNET_JSON_pack_data_auto ( | ||
432 | "cs_blinded_c0", | ||
433 | &msg->details.cs_blinded_message.c[0]), | ||
434 | GNUNET_JSON_pack_data_auto ( | ||
435 | "cs_blinded_c1", | ||
436 | &msg->details.cs_blinded_message.c[1])); | ||
437 | return ps; | ||
438 | } | ||
439 | GNUNET_assert (0); | ||
440 | return ps; | ||
441 | } | ||
442 | |||
443 | |||
444 | struct GNUNET_JSON_PackSpec | ||
445 | GNUNET_JSON_pack_blinded_sig ( | ||
446 | const char *name, | ||
447 | const struct GNUNET_CRYPTO_BlindedSignature *sig) | ||
448 | { | ||
449 | struct GNUNET_JSON_PackSpec ps = { | ||
450 | .field_name = name, | ||
451 | }; | ||
452 | |||
453 | if (NULL == sig) | ||
454 | return ps; | ||
455 | switch (sig->cipher) | ||
456 | { | ||
457 | case GNUNET_CRYPTO_BSA_INVALID: | ||
458 | break; | ||
459 | case GNUNET_CRYPTO_BSA_RSA: | ||
460 | ps.object = GNUNET_JSON_PACK ( | ||
461 | GNUNET_JSON_pack_string ("cipher", | ||
462 | "RSA"), | ||
463 | GNUNET_JSON_pack_rsa_signature ("blinded_rsa_signature", | ||
464 | sig->details.blinded_rsa_signature)); | ||
465 | return ps; | ||
466 | case GNUNET_CRYPTO_BSA_CS: | ||
467 | ps.object = GNUNET_JSON_PACK ( | ||
468 | GNUNET_JSON_pack_string ("cipher", | ||
469 | "CS"), | ||
470 | GNUNET_JSON_pack_uint64 ("b", | ||
471 | sig->details.blinded_cs_answer.b), | ||
472 | GNUNET_JSON_pack_data_auto ("s", | ||
473 | &sig->details.blinded_cs_answer.s_scalar)); | ||
474 | return ps; | ||
475 | } | ||
476 | GNUNET_assert (0); | ||
477 | return ps; | ||
478 | } | ||
479 | |||
367 | /* end of json_pack.c */ | 480 | /* end of json_pack.c */ |
diff --git a/src/lib/meson.build b/src/lib/meson.build index 41c662a4f..93dbf5c4d 100644 --- a/src/lib/meson.build +++ b/src/lib/meson.build | |||
@@ -6,3 +6,4 @@ subdir('curl', if_found : [curl_dep]) | |||
6 | subdir('sq', if_found : [sqlite_dep]) | 6 | subdir('sq', if_found : [sqlite_dep]) |
7 | subdir('pq', if_found : [pq_dep]) | 7 | subdir('pq', if_found : [pq_dep]) |
8 | subdir('gnsrecord') | 8 | subdir('gnsrecord') |
9 | subdir('testing') | ||
diff --git a/src/lib/pq/pq_result_helper.c b/src/lib/pq/pq_result_helper.c index f8759eba1..cbb1e8e8e 100644 --- a/src/lib/pq/pq_result_helper.c +++ b/src/lib/pq/pq_result_helper.c | |||
@@ -1816,7 +1816,8 @@ extract_blind_sign_pub (void *cls, | |||
1816 | size_t *dst_size, | 1816 | size_t *dst_size, |
1817 | void *dst) | 1817 | void *dst) |
1818 | { | 1818 | { |
1819 | struct GNUNET_CRYPTO_BlindSignPublicKey *bpk = dst; | 1819 | struct GNUNET_CRYPTO_BlindSignPublicKey **bpk = dst; |
1820 | struct GNUNET_CRYPTO_BlindSignPublicKey *tmp; | ||
1820 | size_t len; | 1821 | size_t len; |
1821 | const char *res; | 1822 | const char *res; |
1822 | int fnum; | 1823 | int fnum; |
@@ -1854,44 +1855,46 @@ extract_blind_sign_pub (void *cls, | |||
1854 | sizeof (be)); | 1855 | sizeof (be)); |
1855 | res += sizeof (be); | 1856 | res += sizeof (be); |
1856 | len -= sizeof (be); | 1857 | len -= sizeof (be); |
1857 | bpk = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey); | 1858 | tmp = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey); |
1858 | bpk->cipher = ntohl (be); | 1859 | tmp->cipher = ntohl (be); |
1859 | bpk->rc = 1; | 1860 | tmp->rc = 1; |
1860 | switch (bpk->cipher) | 1861 | switch (tmp->cipher) |
1861 | { | 1862 | { |
1862 | case GNUNET_CRYPTO_BSA_INVALID: | 1863 | case GNUNET_CRYPTO_BSA_INVALID: |
1863 | break; | 1864 | break; |
1864 | case GNUNET_CRYPTO_BSA_RSA: | 1865 | case GNUNET_CRYPTO_BSA_RSA: |
1865 | bpk->details.rsa_public_key | 1866 | tmp->details.rsa_public_key |
1866 | = GNUNET_CRYPTO_rsa_public_key_decode (res, | 1867 | = GNUNET_CRYPTO_rsa_public_key_decode (res, |
1867 | len); | 1868 | len); |
1868 | if (NULL == bpk->details.rsa_public_key) | 1869 | if (NULL == tmp->details.rsa_public_key) |
1869 | { | 1870 | { |
1870 | GNUNET_break (0); | 1871 | GNUNET_break (0); |
1871 | GNUNET_free (bpk); | 1872 | GNUNET_free (tmp); |
1872 | return GNUNET_SYSERR; | 1873 | return GNUNET_SYSERR; |
1873 | } | 1874 | } |
1874 | GNUNET_CRYPTO_hash (res, | 1875 | GNUNET_CRYPTO_hash (res, |
1875 | len, | 1876 | len, |
1876 | &bpk->pub_key_hash); | 1877 | &tmp->pub_key_hash); |
1878 | *bpk = tmp; | ||
1877 | return GNUNET_OK; | 1879 | return GNUNET_OK; |
1878 | case GNUNET_CRYPTO_BSA_CS: | 1880 | case GNUNET_CRYPTO_BSA_CS: |
1879 | if (sizeof (bpk->details.cs_public_key) != len) | 1881 | if (sizeof (tmp->details.cs_public_key) != len) |
1880 | { | 1882 | { |
1881 | GNUNET_break (0); | 1883 | GNUNET_break (0); |
1882 | GNUNET_free (bpk); | 1884 | GNUNET_free (tmp); |
1883 | return GNUNET_SYSERR; | 1885 | return GNUNET_SYSERR; |
1884 | } | 1886 | } |
1885 | GNUNET_memcpy (&bpk->details.cs_public_key, | 1887 | GNUNET_memcpy (&tmp->details.cs_public_key, |
1886 | res, | 1888 | res, |
1887 | len); | 1889 | len); |
1888 | GNUNET_CRYPTO_hash (res, | 1890 | GNUNET_CRYPTO_hash (res, |
1889 | len, | 1891 | len, |
1890 | &bpk->pub_key_hash); | 1892 | &tmp->pub_key_hash); |
1893 | *bpk = tmp; | ||
1891 | return GNUNET_OK; | 1894 | return GNUNET_OK; |
1892 | } | 1895 | } |
1893 | GNUNET_break (0); | 1896 | GNUNET_break (0); |
1894 | GNUNET_free (bpk); | 1897 | GNUNET_free (tmp); |
1895 | return GNUNET_SYSERR; | 1898 | return GNUNET_SYSERR; |
1896 | } | 1899 | } |
1897 | 1900 | ||
@@ -1907,17 +1910,17 @@ static void | |||
1907 | clean_blind_sign_pub (void *cls, | 1910 | clean_blind_sign_pub (void *cls, |
1908 | void *rd) | 1911 | void *rd) |
1909 | { | 1912 | { |
1910 | struct GNUNET_CRYPTO_BlindSignPublicKey *pub = rd; | 1913 | struct GNUNET_CRYPTO_BlindSignPublicKey **pub = rd; |
1911 | 1914 | ||
1912 | (void) cls; | 1915 | (void) cls; |
1913 | GNUNET_CRYPTO_blind_sign_pub_decref (pub); | 1916 | GNUNET_CRYPTO_blind_sign_pub_decref (*pub); |
1914 | pub = NULL; | 1917 | *pub = NULL; |
1915 | } | 1918 | } |
1916 | 1919 | ||
1917 | 1920 | ||
1918 | struct GNUNET_PQ_ResultSpec | 1921 | struct GNUNET_PQ_ResultSpec |
1919 | GNUNET_PQ_result_spec_blind_sign_pub (const char *name, | 1922 | GNUNET_PQ_result_spec_blind_sign_pub (const char *name, |
1920 | struct GNUNET_CRYPTO_BlindSignPublicKey *pub) | 1923 | struct GNUNET_CRYPTO_BlindSignPublicKey **pub) |
1921 | { | 1924 | { |
1922 | struct GNUNET_PQ_ResultSpec res = { | 1925 | struct GNUNET_PQ_ResultSpec res = { |
1923 | .conv = &extract_blind_sign_pub, | 1926 | .conv = &extract_blind_sign_pub, |
@@ -1951,7 +1954,8 @@ extract_blind_sign_priv (void *cls, | |||
1951 | size_t *dst_size, | 1954 | size_t *dst_size, |
1952 | void *dst) | 1955 | void *dst) |
1953 | { | 1956 | { |
1954 | struct GNUNET_CRYPTO_BlindSignPrivateKey *bpk = dst; | 1957 | struct GNUNET_CRYPTO_BlindSignPrivateKey **bpk = dst; |
1958 | struct GNUNET_CRYPTO_BlindSignPrivateKey *tmp; | ||
1955 | size_t len; | 1959 | size_t len; |
1956 | const char *res; | 1960 | const char *res; |
1957 | int fnum; | 1961 | int fnum; |
@@ -1989,38 +1993,40 @@ extract_blind_sign_priv (void *cls, | |||
1989 | sizeof (be)); | 1993 | sizeof (be)); |
1990 | res += sizeof (be); | 1994 | res += sizeof (be); |
1991 | len -= sizeof (be); | 1995 | len -= sizeof (be); |
1992 | bpk = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPrivateKey); | 1996 | tmp = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPrivateKey); |
1993 | bpk->cipher = ntohl (be); | 1997 | tmp->cipher = ntohl (be); |
1994 | bpk->rc = 1; | 1998 | tmp->rc = 1; |
1995 | switch (bpk->cipher) | 1999 | switch (tmp->cipher) |
1996 | { | 2000 | { |
1997 | case GNUNET_CRYPTO_BSA_INVALID: | 2001 | case GNUNET_CRYPTO_BSA_INVALID: |
1998 | break; | 2002 | break; |
1999 | case GNUNET_CRYPTO_BSA_RSA: | 2003 | case GNUNET_CRYPTO_BSA_RSA: |
2000 | bpk->details.rsa_private_key | 2004 | tmp->details.rsa_private_key |
2001 | = GNUNET_CRYPTO_rsa_private_key_decode (res, | 2005 | = GNUNET_CRYPTO_rsa_private_key_decode (res, |
2002 | len); | 2006 | len); |
2003 | if (NULL == bpk->details.rsa_private_key) | 2007 | if (NULL == tmp->details.rsa_private_key) |
2004 | { | 2008 | { |
2005 | GNUNET_break (0); | 2009 | GNUNET_break (0); |
2006 | GNUNET_free (bpk); | 2010 | GNUNET_free (bpk); |
2007 | return GNUNET_SYSERR; | 2011 | return GNUNET_SYSERR; |
2008 | } | 2012 | } |
2013 | *bpk = tmp; | ||
2009 | return GNUNET_OK; | 2014 | return GNUNET_OK; |
2010 | case GNUNET_CRYPTO_BSA_CS: | 2015 | case GNUNET_CRYPTO_BSA_CS: |
2011 | if (sizeof (bpk->details.cs_private_key) != len) | 2016 | if (sizeof (tmp->details.cs_private_key) != len) |
2012 | { | 2017 | { |
2013 | GNUNET_break (0); | 2018 | GNUNET_break (0); |
2014 | GNUNET_free (bpk); | 2019 | GNUNET_free (tmp); |
2015 | return GNUNET_SYSERR; | 2020 | return GNUNET_SYSERR; |
2016 | } | 2021 | } |
2017 | GNUNET_memcpy (&bpk->details.cs_private_key, | 2022 | GNUNET_memcpy (&tmp->details.cs_private_key, |
2018 | res, | 2023 | res, |
2019 | len); | 2024 | len); |
2025 | *bpk = tmp; | ||
2020 | return GNUNET_OK; | 2026 | return GNUNET_OK; |
2021 | } | 2027 | } |
2022 | GNUNET_break (0); | 2028 | GNUNET_break (0); |
2023 | GNUNET_free (bpk); | 2029 | GNUNET_free (tmp); |
2024 | return GNUNET_SYSERR; | 2030 | return GNUNET_SYSERR; |
2025 | } | 2031 | } |
2026 | 2032 | ||
@@ -2036,17 +2042,17 @@ static void | |||
2036 | clean_blind_sign_priv (void *cls, | 2042 | clean_blind_sign_priv (void *cls, |
2037 | void *rd) | 2043 | void *rd) |
2038 | { | 2044 | { |
2039 | struct GNUNET_CRYPTO_BlindSignPublicKey *pub = rd; | 2045 | struct GNUNET_CRYPTO_BlindSignPrivateKey **priv = rd; |
2040 | 2046 | ||
2041 | (void) cls; | 2047 | (void) cls; |
2042 | GNUNET_CRYPTO_blind_sign_pub_decref (pub); | 2048 | GNUNET_CRYPTO_blind_sign_priv_decref (*priv); |
2043 | pub = NULL; | 2049 | *priv = NULL; |
2044 | } | 2050 | } |
2045 | 2051 | ||
2046 | 2052 | ||
2047 | struct GNUNET_PQ_ResultSpec | 2053 | struct GNUNET_PQ_ResultSpec |
2048 | GNUNET_PQ_result_spec_blind_sign_priv (const char *name, | 2054 | GNUNET_PQ_result_spec_blind_sign_priv (const char *name, |
2049 | struct GNUNET_CRYPTO_BlindSignPrivateKey *priv) | 2055 | struct GNUNET_CRYPTO_BlindSignPrivateKey **priv) |
2050 | { | 2056 | { |
2051 | struct GNUNET_PQ_ResultSpec res = { | 2057 | struct GNUNET_PQ_ResultSpec res = { |
2052 | .conv = &extract_blind_sign_priv, | 2058 | .conv = &extract_blind_sign_priv, |
diff --git a/src/service/testing/.gitignore b/src/lib/testing/.gitignore index a1e77a8e4..2e66a9259 100644 --- a/src/service/testing/.gitignore +++ b/src/lib/testing/.gitignore | |||
@@ -7,3 +7,5 @@ test_testing_portreservation | |||
7 | test_testing_servicestartup | 7 | test_testing_servicestartup |
8 | test_testing_sharedservices | 8 | test_testing_sharedservices |
9 | gnunet-cmds-helper | 9 | gnunet-cmds-helper |
10 | test_testing_api | ||
11 | gnunet-testing-netjail-launcher | ||
diff --git a/src/lib/testing/Makefile.am b/src/lib/testing/Makefile.am new file mode 100644 index 000000000..077ea4447 --- /dev/null +++ b/src/lib/testing/Makefile.am | |||
@@ -0,0 +1,92 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | ||
3 | |||
4 | if USE_COVERAGE | ||
5 | AM_CFLAGS = --coverage -O0 | ||
6 | XLIB = -lgcov | ||
7 | endif | ||
8 | |||
9 | libexecdir= $(pkglibdir)/libexec/ | ||
10 | |||
11 | libexec_PROGRAMS = \ | ||
12 | gnunet-cmds-helper | ||
13 | |||
14 | plugindir = $(libdir)/gnunet | ||
15 | |||
16 | lib_LTLIBRARIES = \ | ||
17 | libgnunettesting.la | ||
18 | |||
19 | gnunet_cmds_helper_SOURCES = \ | ||
20 | gnunet-cmds-helper.c | ||
21 | gnunet_cmds_helper_LDADD = $(XLIB) \ | ||
22 | libgnunettesting.la \ | ||
23 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
24 | $(LTLIBINTL) | ||
25 | |||
26 | libgnunettesting_la_SOURCES = \ | ||
27 | testing_api_barrier.c testing_api_barrier.h \ | ||
28 | testing_api_cmd_barrier_create.c \ | ||
29 | testing_api_cmd_barrier_reached.c \ | ||
30 | testing_api_cmd_batch.c testing_api_cmd_batch.h \ | ||
31 | testing_api_cmd_exec.c \ | ||
32 | testing_api_cmd_finish.c \ | ||
33 | testing_api_cmd_get_topo.c \ | ||
34 | testing_api_cmd_netjail_start.c \ | ||
35 | testing_api_cmd_netjail_start_cmds_helper.c \ | ||
36 | testing_api_cmd_signal.c \ | ||
37 | testing_api_cmd_stat.c \ | ||
38 | testing_api_cmds.c \ | ||
39 | testing_api_loop.c testing_api_loop.h \ | ||
40 | testing_api_main.c \ | ||
41 | testing_api_traits.c \ | ||
42 | testing_api_topology.c testing_api_topology.h | ||
43 | libgnunettesting_la_LIBADD = \ | ||
44 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
45 | $(LTLIBINTL) | ||
46 | libgnunettesting_la_LDFLAGS = \ | ||
47 | $(GN_LIB_LDFLAGS) \ | ||
48 | -version-info 3:0:0 | ||
49 | |||
50 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; | ||
51 | |||
52 | |||
53 | bin_PROGRAMS = \ | ||
54 | gnunet-testing-netjail-launcher | ||
55 | |||
56 | gnunet_testing_netjail_launcher_SOURCES = \ | ||
57 | gnunet-testing-netjail-launcher.c | ||
58 | gnunet_testing_netjail_launcher_LDADD = $(XLIB) \ | ||
59 | libgnunettesting.la \ | ||
60 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
61 | $(LTLIBINTL) | ||
62 | |||
63 | check_PROGRAMS = \ | ||
64 | test_testing_api | ||
65 | |||
66 | check_SCRIPTS = \ | ||
67 | test_netjail_api.sh | ||
68 | |||
69 | TESTS = \ | ||
70 | $(check_PROGRAMS) \ | ||
71 | $(check_SCRIPTS) | ||
72 | |||
73 | test_testing_api_SOURCES = \ | ||
74 | test_testing_api.c | ||
75 | test_testing_api_LDADD = \ | ||
76 | libgnunettesting.la \ | ||
77 | -lgnunetutil \ | ||
78 | $(XLIB) | ||
79 | |||
80 | EXTRA_DIST = \ | ||
81 | $(check_SCRIPTS) \ | ||
82 | test_netjail_topo.conf | ||
83 | |||
84 | plugin_LTLIBRARIES = \ | ||
85 | libgnunet_test_testing_plugin_ping.la | ||
86 | |||
87 | libgnunet_test_testing_plugin_ping_la_SOURCES = \ | ||
88 | test_testing_plugin_ping.c | ||
89 | libgnunet_test_testing_plugin_ping_la_LIBADD = \ | ||
90 | libgnunettesting.la \ | ||
91 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
92 | $(LTLIBINTL) | ||
diff --git a/src/lib/testing/gnunet-cmds-helper.c b/src/lib/testing/gnunet-cmds-helper.c new file mode 100644 index 000000000..edbbd8d13 --- /dev/null +++ b/src/lib/testing/gnunet-cmds-helper.c | |||
@@ -0,0 +1,530 @@ | |||
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 testbed/gnunet-cmds-helper.c | ||
23 | * @brief Helper binary that is started from a remote interpreter loop to start | ||
24 | * a local interpreter loop. | ||
25 | * | ||
26 | * This helper monitors for three termination events. They are: (1)The | ||
27 | * stdin of the helper is closed for reading; (2)the helper received | ||
28 | * SIGTERM/SIGINT; (3)the local loop crashed. In case of events 1 and 2 | ||
29 | * the helper kills the interpreter loop. When the interpreter loop | ||
30 | * crashed (event 3), the helper should send a SIGTERM to its own process | ||
31 | * group; this behaviour will help terminate any child processes the loop | ||
32 | * has started and prevents them from leaking and running forever. | ||
33 | * | ||
34 | * @author t3sserakt | ||
35 | * @author Sree Harsha Totakura <sreeharsha@totakura.in> | ||
36 | */ | ||
37 | #include "platform.h" | ||
38 | #include "gnunet_util_lib.h" | ||
39 | #include "gnunet_testing_lib.h" | ||
40 | #include "testing_api_loop.h" | ||
41 | #include "testing_cmds.h" | ||
42 | #include "testing_api_topology.h" | ||
43 | |||
44 | /** | ||
45 | * Generic logging shortcut | ||
46 | */ | ||
47 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | ||
48 | |||
49 | /** | ||
50 | * Debug logging shorthand | ||
51 | */ | ||
52 | #define LOG_DEBUG(...) LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) | ||
53 | |||
54 | /** | ||
55 | * Context for a single write on a chunk of memory | ||
56 | */ | ||
57 | struct WriteContext | ||
58 | { | ||
59 | |||
60 | struct WriteContext *next; | ||
61 | |||
62 | struct WriteContext *prev; | ||
63 | |||
64 | /** | ||
65 | * The data to write | ||
66 | */ | ||
67 | void *data; | ||
68 | |||
69 | /** | ||
70 | * The length of the data | ||
71 | */ | ||
72 | size_t length; | ||
73 | |||
74 | /** | ||
75 | * The current position from where the write operation should begin | ||
76 | */ | ||
77 | size_t pos; | ||
78 | }; | ||
79 | |||
80 | |||
81 | static struct WriteContext *wc_head; | ||
82 | |||
83 | static struct WriteContext *wc_tail; | ||
84 | |||
85 | static struct GNUNET_TESTING_Interpreter *is; | ||
86 | |||
87 | static const char *my_node_id; | ||
88 | |||
89 | /** | ||
90 | * Plugin to dynamically load a test case. | ||
91 | */ | ||
92 | static struct GNUNET_TESTING_PluginFunctions *plugin; | ||
93 | |||
94 | /** | ||
95 | * Name of our plugin. | ||
96 | */ | ||
97 | static char *plugin_name; | ||
98 | |||
99 | /** | ||
100 | * Our message stream tokenizer | ||
101 | */ | ||
102 | static struct GNUNET_MessageStreamTokenizer *tokenizer; | ||
103 | |||
104 | /** | ||
105 | * Disk handle from stdin | ||
106 | */ | ||
107 | static struct GNUNET_DISK_FileHandle *stdin_fd; | ||
108 | |||
109 | /** | ||
110 | * Disk handle for stdout | ||
111 | */ | ||
112 | static struct GNUNET_DISK_FileHandle *stdout_fd; | ||
113 | |||
114 | /** | ||
115 | * Task identifier for the read task | ||
116 | */ | ||
117 | static struct GNUNET_SCHEDULER_Task *read_task_id; | ||
118 | |||
119 | /** | ||
120 | * Task identifier for the write task | ||
121 | */ | ||
122 | static struct GNUNET_SCHEDULER_Task *write_task_id; | ||
123 | |||
124 | /** | ||
125 | * Result to return in case we fail | ||
126 | */ | ||
127 | static int global_ret; | ||
128 | |||
129 | /** | ||
130 | * Set to true once we are finished and should exit | ||
131 | * after sending our final message to the parent. | ||
132 | */ | ||
133 | static bool finished; | ||
134 | |||
135 | |||
136 | /** | ||
137 | * Task to shut down cleanly | ||
138 | * | ||
139 | * @param cls NULL | ||
140 | */ | ||
141 | static void | ||
142 | do_shutdown (void *cls) | ||
143 | { | ||
144 | struct WriteContext *wc; | ||
145 | |||
146 | if (NULL != read_task_id) | ||
147 | { | ||
148 | GNUNET_SCHEDULER_cancel (read_task_id); | ||
149 | read_task_id = NULL; | ||
150 | } | ||
151 | if (NULL != write_task_id) | ||
152 | { | ||
153 | GNUNET_SCHEDULER_cancel (write_task_id); | ||
154 | write_task_id = NULL; | ||
155 | } | ||
156 | while (NULL != (wc = wc_head)) | ||
157 | { | ||
158 | GNUNET_CONTAINER_DLL_remove (wc_head, | ||
159 | wc_tail, | ||
160 | wc); | ||
161 | GNUNET_free (wc->data); | ||
162 | GNUNET_free (wc); | ||
163 | } | ||
164 | if (NULL != tokenizer) | ||
165 | { | ||
166 | GNUNET_MST_destroy (tokenizer); | ||
167 | tokenizer = NULL; | ||
168 | } | ||
169 | if (NULL != plugin) | ||
170 | { | ||
171 | GNUNET_PLUGIN_unload (plugin_name, | ||
172 | plugin); | ||
173 | GNUNET_free (plugin_name); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | |||
178 | /** | ||
179 | * Task to write to the standard out | ||
180 | * | ||
181 | * @param cls the WriteContext | ||
182 | */ | ||
183 | static void | ||
184 | write_task (void *cls) | ||
185 | { | ||
186 | struct WriteContext *wc = wc_head; | ||
187 | ssize_t bytes_wrote; | ||
188 | |||
189 | write_task_id = NULL; | ||
190 | if (NULL == wc) | ||
191 | { | ||
192 | if (finished) | ||
193 | GNUNET_SCHEDULER_shutdown (); | ||
194 | return; | ||
195 | } | ||
196 | bytes_wrote | ||
197 | = GNUNET_DISK_file_write (stdout_fd, | ||
198 | wc->data + wc->pos, | ||
199 | wc->length - wc->pos); | ||
200 | if (GNUNET_SYSERR == bytes_wrote) | ||
201 | { | ||
202 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, | ||
203 | "write"); | ||
204 | GNUNET_free (wc->data); | ||
205 | GNUNET_free (wc); | ||
206 | global_ret = EXIT_FAILURE; | ||
207 | GNUNET_SCHEDULER_shutdown (); | ||
208 | return; | ||
209 | } | ||
210 | wc->pos += bytes_wrote; | ||
211 | if (wc->pos == wc->length) | ||
212 | { | ||
213 | GNUNET_CONTAINER_DLL_remove (wc_head, | ||
214 | wc_tail, | ||
215 | wc); | ||
216 | GNUNET_free (wc->data); | ||
217 | GNUNET_free (wc); | ||
218 | } | ||
219 | write_task_id | ||
220 | = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
221 | stdout_fd, | ||
222 | &write_task, | ||
223 | NULL); | ||
224 | } | ||
225 | |||
226 | |||
227 | /** | ||
228 | * Callback to write a message to the parent process. | ||
229 | * | ||
230 | */ | ||
231 | static void | ||
232 | write_message (const struct GNUNET_MessageHeader *message) | ||
233 | { | ||
234 | struct WriteContext *wc; | ||
235 | size_t msg_length = ntohl (message->size); | ||
236 | |||
237 | wc = GNUNET_new (struct WriteContext); | ||
238 | wc->length = msg_length; | ||
239 | wc->data = GNUNET_memdup (message, | ||
240 | msg_length); | ||
241 | GNUNET_CONTAINER_DLL_insert_tail (wc_head, | ||
242 | wc_tail, | ||
243 | wc); | ||
244 | if (NULL == write_task_id) | ||
245 | { | ||
246 | GNUNET_assert (wc_head == wc); | ||
247 | write_task_id | ||
248 | = GNUNET_SCHEDULER_add_write_file ( | ||
249 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
250 | stdout_fd, | ||
251 | &write_task, | ||
252 | NULL); | ||
253 | } | ||
254 | } | ||
255 | |||
256 | |||
257 | static void | ||
258 | finished_cb (void *cls, | ||
259 | enum GNUNET_GenericReturnValue rv) | ||
260 | { | ||
261 | struct GNUNET_TESTING_CommandLocalFinished reply = { | ||
262 | .header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED), | ||
263 | .header.size = htons (sizeof (reply)), | ||
264 | .rv = htonl ((uint32_t) rv) | ||
265 | }; | ||
266 | |||
267 | (void) cls; | ||
268 | finished = true; | ||
269 | write_message (&reply.header); | ||
270 | } | ||
271 | |||
272 | |||
273 | static enum GNUNET_GenericReturnValue | ||
274 | check_helper_init ( | ||
275 | void *cls, | ||
276 | const struct GNUNET_TESTING_CommandHelperInit *msg) | ||
277 | { | ||
278 | uint16_t msize = htons (msg->header.size); | ||
279 | uint32_t barrier_count = htonl (msg->barrier_count); | ||
280 | size_t bs = barrier_count * sizeof (struct GNUNET_ShortHashCode); | ||
281 | size_t left = msize - bs - sizeof (*msg); | ||
282 | const struct GNUNET_ShortHashCode *bd | ||
283 | = (const struct GNUNET_ShortHashCode *) &msg[1]; | ||
284 | const char *topo = (const char *) &bd[barrier_count]; | ||
285 | |||
286 | if (msize < bs + sizeof (*msg)) | ||
287 | { | ||
288 | GNUNET_break_op (0); | ||
289 | return GNUNET_SYSERR; | ||
290 | } | ||
291 | if ('\0' != topo[left - 1]) | ||
292 | { | ||
293 | GNUNET_break_op (0); | ||
294 | return GNUNET_SYSERR; | ||
295 | } | ||
296 | return GNUNET_OK; | ||
297 | } | ||
298 | |||
299 | |||
300 | static void | ||
301 | handle_helper_init ( | ||
302 | void *cls, | ||
303 | const struct GNUNET_TESTING_CommandHelperInit *msg) | ||
304 | { | ||
305 | uint16_t msize = htons (msg->header.size); | ||
306 | uint32_t barrier_count = htonl (msg->barrier_count); | ||
307 | size_t bs = barrier_count * sizeof (struct GNUNET_ShortHashCode); | ||
308 | size_t left = msize - bs - sizeof (*msg); | ||
309 | const struct GNUNET_ShortHashCode *bd | ||
310 | = (const struct GNUNET_ShortHashCode *) &msg[1]; | ||
311 | const char *topo = (const char *) &bd[barrier_count]; | ||
312 | struct GNUNET_TESTING_NetjailTopology *njt; | ||
313 | |||
314 | GNUNET_assert ('\0' == topo[left - 1]); | ||
315 | njt = GNUNET_TESTING_get_topo_from_string_ (topo); | ||
316 | if (NULL == njt) | ||
317 | { | ||
318 | GNUNET_break_op (0); | ||
319 | global_ret = EXIT_FAILURE; | ||
320 | GNUNET_SCHEDULER_shutdown (); | ||
321 | return; | ||
322 | } | ||
323 | plugin_name = GNUNET_TESTING_get_plugin_from_topo (njt, | ||
324 | my_node_id); | ||
325 | GNUNET_TESTING_free_topology (njt); | ||
326 | plugin = GNUNET_PLUGIN_load (plugin_name, | ||
327 | (void *) my_node_id); | ||
328 | if (NULL == plugin) | ||
329 | { | ||
330 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
331 | "Plugin `%s' not found!\n", | ||
332 | plugin_name); | ||
333 | global_ret = EXIT_FAILURE; | ||
334 | GNUNET_SCHEDULER_shutdown (); | ||
335 | return; | ||
336 | } | ||
337 | is = plugin->start_testcase (plugin->cls, | ||
338 | topo, | ||
339 | barrier_count, | ||
340 | bd, | ||
341 | &write_message, | ||
342 | &finished_cb, | ||
343 | NULL); | ||
344 | } | ||
345 | |||
346 | |||
347 | static void | ||
348 | handle_helper_barrier_crossable ( | ||
349 | void *cls, | ||
350 | const struct GNUNET_TESTING_CommandBarrierSatisfied *cbs) | ||
351 | { | ||
352 | struct GNUNET_TESTING_Barrier *barrier; | ||
353 | |||
354 | if (NULL == is) | ||
355 | { | ||
356 | /* Barrier satisfied *before* helper_init?! */ | ||
357 | GNUNET_break_op (0); | ||
358 | global_ret = EXIT_FAILURE; | ||
359 | GNUNET_SCHEDULER_shutdown (); | ||
360 | return; | ||
361 | } | ||
362 | barrier = GNUNET_TESTING_get_barrier2_ (is, | ||
363 | &cbs->barrier_key); | ||
364 | if (barrier->satisfied) | ||
365 | { | ||
366 | /* Barrier satisfied *twice* is strange... */ | ||
367 | GNUNET_break_op (0); | ||
368 | global_ret = EXIT_FAILURE; | ||
369 | GNUNET_SCHEDULER_shutdown (); | ||
370 | return; | ||
371 | } | ||
372 | barrier->satisfied = true; | ||
373 | GNUNET_TESTING_loop_notify_children_ (is, | ||
374 | &cbs->header); | ||
375 | for (unsigned int i = 0; i<barrier->cnt_waiting; i++) | ||
376 | GNUNET_TESTING_async_finish (barrier->waiting[i]); | ||
377 | GNUNET_array_grow (barrier->waiting, | ||
378 | barrier->cnt_waiting, | ||
379 | 0); | ||
380 | } | ||
381 | |||
382 | |||
383 | /** | ||
384 | * Functions with this signature are called whenever a | ||
385 | * complete message is received by the tokenizer. | ||
386 | * | ||
387 | * Do not call #GNUNET_mst_destroy() in this callback | ||
388 | * | ||
389 | * @param cls identification of the client | ||
390 | * @param message the actual message | ||
391 | * @return #GNUNET_OK on success, | ||
392 | * #GNUNET_NO to stop further processing (no error) | ||
393 | * #GNUNET_SYSERR to stop further processing with error | ||
394 | */ | ||
395 | static enum GNUNET_GenericReturnValue | ||
396 | tokenizer_cb (void *cls, | ||
397 | const struct GNUNET_MessageHeader *message) | ||
398 | { | ||
399 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
400 | GNUNET_MQ_hd_var_size ( | ||
401 | helper_init, | ||
402 | GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT, | ||
403 | struct GNUNET_TESTING_CommandHelperInit, | ||
404 | NULL), | ||
405 | GNUNET_MQ_hd_fixed_size ( | ||
406 | helper_barrier_crossable, | ||
407 | GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_CROSSABLE, | ||
408 | struct GNUNET_TESTING_CommandBarrierSatisfied, | ||
409 | NULL), | ||
410 | GNUNET_MQ_handler_end () | ||
411 | }; | ||
412 | |||
413 | return GNUNET_MQ_handle_message (handlers, | ||
414 | message); | ||
415 | } | ||
416 | |||
417 | |||
418 | /** | ||
419 | * Task to read from stdin | ||
420 | * | ||
421 | * @param cls NULL | ||
422 | */ | ||
423 | static void | ||
424 | read_task (void *cls) | ||
425 | { | ||
426 | char buf[GNUNET_MAX_MESSAGE_SIZE]; | ||
427 | ssize_t sread; | ||
428 | |||
429 | read_task_id = NULL; | ||
430 | sread = GNUNET_DISK_file_read (stdin_fd, | ||
431 | buf, | ||
432 | sizeof(buf)); | ||
433 | if (GNUNET_SYSERR == sread) | ||
434 | { | ||
435 | GNUNET_break (0); | ||
436 | global_ret = EXIT_FAILURE; | ||
437 | GNUNET_SCHEDULER_shutdown (); | ||
438 | return; | ||
439 | } | ||
440 | if (0 == sread) | ||
441 | { | ||
442 | LOG_DEBUG ("STDIN eof\n"); | ||
443 | GNUNET_SCHEDULER_shutdown (); | ||
444 | return; | ||
445 | } | ||
446 | if (GNUNET_OK != | ||
447 | GNUNET_MST_from_buffer (tokenizer, | ||
448 | buf, | ||
449 | sread, | ||
450 | GNUNET_NO, | ||
451 | GNUNET_NO)) | ||
452 | { | ||
453 | GNUNET_break (0); | ||
454 | global_ret = EXIT_FAILURE; | ||
455 | GNUNET_SCHEDULER_shutdown (); | ||
456 | return; | ||
457 | } | ||
458 | read_task_id | ||
459 | = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
460 | stdin_fd, | ||
461 | &read_task, | ||
462 | NULL); | ||
463 | } | ||
464 | |||
465 | |||
466 | /** | ||
467 | * Main function that will be run. | ||
468 | * | ||
469 | * @param cls closure | ||
470 | * @param args remaining command-line arguments | ||
471 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
472 | * @param cfg configuration | ||
473 | */ | ||
474 | static void | ||
475 | run (void *cls, | ||
476 | char *const *args, | ||
477 | const char *cfgfile, | ||
478 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
479 | { | ||
480 | if (NULL == args[0]) | ||
481 | { | ||
482 | /* must be called with our node ID as 1st argument */ | ||
483 | GNUNET_break_op (0); | ||
484 | global_ret = EXIT_INVALIDARGUMENT; | ||
485 | return; | ||
486 | } | ||
487 | my_node_id = args[0]; | ||
488 | tokenizer = GNUNET_MST_create (&tokenizer_cb, | ||
489 | NULL); | ||
490 | stdin_fd = GNUNET_DISK_get_handle_from_native (stdin); | ||
491 | stdout_fd = GNUNET_DISK_get_handle_from_native (stdout); | ||
492 | read_task_id = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
493 | stdin_fd, | ||
494 | &read_task, | ||
495 | NULL); | ||
496 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | ||
497 | NULL); | ||
498 | } | ||
499 | |||
500 | |||
501 | /** | ||
502 | * Main function | ||
503 | * | ||
504 | * @param argc the number of command line arguments | ||
505 | * @param argv command line arg array | ||
506 | * @return return code | ||
507 | */ | ||
508 | int | ||
509 | main (int argc, | ||
510 | char **argv) | ||
511 | { | ||
512 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
513 | GNUNET_GETOPT_OPTION_END | ||
514 | }; | ||
515 | enum GNUNET_GenericReturnValue ret; | ||
516 | |||
517 | ret = GNUNET_PROGRAM_run (argc, | ||
518 | argv, | ||
519 | "gnunet-cmds-helper", | ||
520 | "Helper for starting a local interpreter loop", | ||
521 | options, | ||
522 | &run, | ||
523 | NULL); | ||
524 | if (GNUNET_OK != ret) | ||
525 | return 1; | ||
526 | return global_ret; | ||
527 | } | ||
528 | |||
529 | |||
530 | /* end of gnunet-cmds-helper.c */ | ||
diff --git a/src/lib/testing/gnunet-testing-netjail-launcher.c b/src/lib/testing/gnunet-testing-netjail-launcher.c new file mode 100644 index 000000000..2d425207e --- /dev/null +++ b/src/lib/testing/gnunet-testing-netjail-launcher.c | |||
@@ -0,0 +1,87 @@ | |||
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/gnunet-testing-netjail-launcher.c | ||
23 | * @brief Generic program to start testcases in an configurable topology. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_testing_lib.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | |||
30 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600) | ||
31 | |||
32 | int | ||
33 | main (int argc, | ||
34 | char *const *argv) | ||
35 | { | ||
36 | char *filename = NULL; | ||
37 | char *topology_data = NULL; | ||
38 | |||
39 | GNUNET_log_setup ("test-netjail", | ||
40 | "INFO", | ||
41 | NULL); | ||
42 | if (NULL == argv[1]) | ||
43 | { | ||
44 | GNUNET_break (0); | ||
45 | return EXIT_FAILURE; | ||
46 | } | ||
47 | if (0 == strcmp ("-s", argv[1])) | ||
48 | { | ||
49 | topology_data = argv[2]; | ||
50 | if (NULL == topology_data) | ||
51 | { | ||
52 | GNUNET_break (0); | ||
53 | return EXIT_FAILURE; | ||
54 | } | ||
55 | } | ||
56 | else | ||
57 | { | ||
58 | filename = argv[1]; | ||
59 | } | ||
60 | { | ||
61 | struct GNUNET_TESTING_Command commands[] = { | ||
62 | NULL == filename | ||
63 | ? GNUNET_TESTING_cmd_load_topology_from_string ( | ||
64 | "load-topology", | ||
65 | topology_data) | ||
66 | : GNUNET_TESTING_cmd_load_topology_from_file ( | ||
67 | "load-topology", | ||
68 | filename), | ||
69 | #if FUTURE | ||
70 | GNUNET_TESTING_cmd_barrier_create ("peers-started-barrier", | ||
71 | NUM_PEERS), | ||
72 | #endif | ||
73 | GNUNET_TESTING_cmd_netjail_setup ( | ||
74 | "netjail-start", | ||
75 | GNUNET_TESTING_NETJAIL_START_SCRIPT, | ||
76 | "load-topology"), | ||
77 | GNUNET_TESTING_cmd_netjail_start_helpers ( | ||
78 | "netjail-start-testbed", | ||
79 | "load-topology", | ||
80 | TIMEOUT), | ||
81 | GNUNET_TESTING_cmd_end () | ||
82 | }; | ||
83 | |||
84 | return GNUNET_TESTING_main (commands, | ||
85 | TIMEOUT); | ||
86 | } | ||
87 | } | ||
diff --git a/src/service/testing/meson.build b/src/lib/testing/meson.build index ea8956c1b..aa2de5314 100644 --- a/src/service/testing/meson.build +++ b/src/lib/testing/meson.build | |||
@@ -1,40 +1,26 @@ | |||
1 | libgnunettesting_src = [ | 1 | libgnunettesting_src = [ |
2 | 'testing_api_cmd_exec_bash_script.c', | 2 | 'testing_api_barrier.c', |
3 | 'testing_api_cmd_barrier.c', | 3 | 'testing_api_cmd_barrier_create.c', |
4 | 'testing_api_cmd_barrier_reached.c', | 4 | 'testing_api_cmd_barrier_reached.c', |
5 | 'testing_api_cmd_batch.c', | ||
6 | 'testing_api_cmd_exec.c', | ||
5 | 'testing_api_cmd_finish.c', | 7 | 'testing_api_cmd_finish.c', |
6 | 'testing_api_cmd_local_test_prepared.c', | 8 | 'testing_api_cmd_get_topo.c', |
7 | 'testing_api_cmd_send_peer_ready.c', | ||
8 | 'testing_api_cmd_block_until_external_trigger.c', | ||
9 | 'testing_api_cmd_netjail_start.c', | 9 | 'testing_api_cmd_netjail_start.c', |
10 | 'testing_api_cmd_netjail_start_cmds_helper.c', | 10 | 'testing_api_cmd_netjail_start_cmds_helper.c', |
11 | 'testing_api_cmd_netjail_stop_cmds_helper.c', | 11 | 'testing_api_cmds.c', |
12 | 'testing_api_cmd_netjail_stop.c', | ||
13 | 'testing.c', | ||
14 | 'testing_api_cmd_system_create.c', | ||
15 | 'testing_api_cmd_system_destroy.c', | ||
16 | 'testing_api_cmd_batch.c', | ||
17 | 'testing_api_loop.c', | 12 | 'testing_api_loop.c', |
13 | 'testing_api_main.c', | ||
18 | 'testing_api_traits.c' | 14 | 'testing_api_traits.c' |
15 | 'testing_api_topology.c' | ||
19 | ] | 16 | ] |
20 | 17 | ||
21 | gnunettesting_src = ['gnunet-testing.c'] | ||
22 | gnunetservicetesting_src = ['gnunet-service-testing.c'] | ||
23 | |||
24 | configure_file(input : 'testing.conf', | ||
25 | output : 'testing.conf', | ||
26 | configuration : cdata, | ||
27 | install: true, | ||
28 | install_dir: pkgcfgdir) | ||
29 | |||
30 | |||
31 | libgnunettesting = library('gnunettesting', | 18 | libgnunettesting = library('gnunettesting', |
32 | libgnunettesting_src, | 19 | libgnunettesting_src, |
33 | soversion: '1', | 20 | soversion: '1', |
34 | version: '1.1.0', | 21 | version: '1.1.0', |
35 | dependencies: [libgnunetutil_dep, | 22 | dependencies: [libgnunetutil_dep, |
36 | m_dep, | 23 | m_dep], |
37 | libgnunetarm_dep], | ||
38 | include_directories: [incdir, configuration_inc], | 24 | include_directories: [incdir, configuration_inc], |
39 | install: true, | 25 | install: true, |
40 | install_dir: get_option('libdir')) | 26 | install_dir: get_option('libdir')) |
@@ -42,15 +28,6 @@ libgnunettesting_dep = declare_dependency(link_with : libgnunettesting) | |||
42 | pkg.generate(libgnunettesting, url: 'https://www.gnunet.org', | 28 | pkg.generate(libgnunettesting, url: 'https://www.gnunet.org', |
43 | description : 'Provides API for gnunet testing') | 29 | description : 'Provides API for gnunet testing') |
44 | 30 | ||
45 | executable ('gnunet-testing', | ||
46 | gnunettesting_src, | ||
47 | dependencies: [libgnunettesting_dep, | ||
48 | libgnunetutil_dep, | ||
49 | ], | ||
50 | include_directories: [incdir, configuration_inc], | ||
51 | install: true, | ||
52 | install_dir: get_option('bindir')) | ||
53 | |||
54 | executable ('gnunet-cmds-helper', | 31 | executable ('gnunet-cmds-helper', |
55 | ['gnunet-cmds-helper.c'], | 32 | ['gnunet-cmds-helper.c'], |
56 | dependencies: [libgnunettesting_dep, | 33 | dependencies: [libgnunettesting_dep, |
@@ -59,4 +36,3 @@ executable ('gnunet-cmds-helper', | |||
59 | include_directories: [incdir, configuration_inc], | 36 | include_directories: [incdir, configuration_inc], |
60 | install: true, | 37 | install: true, |
61 | install_dir: get_option('libdir')/'gnunet'/'libexec') | 38 | install_dir: get_option('libdir')/'gnunet'/'libexec') |
62 | |||
diff --git a/src/lib/testing/test_netjail_api.sh b/src/lib/testing/test_netjail_api.sh new file mode 100755 index 000000000..d9cb35c28 --- /dev/null +++ b/src/lib/testing/test_netjail_api.sh | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/bin/bash | ||
2 | exec ../../../scripts/netjail/netjail_test_master.sh gnunet-testing-netjail-launcher test_netjail_topo.conf # --num-peers=2 | ||
diff --git a/src/lib/testing/test_netjail_topo.conf b/src/lib/testing/test_netjail_topo.conf new file mode 100644 index 000000000..064fb7d27 --- /dev/null +++ b/src/lib/testing/test_netjail_topo.conf | |||
@@ -0,0 +1,658 @@ | |||
1 | [abd] | ||
2 | BINARY = gnunet-service-abd | ||
3 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-abd.sock | ||
4 | RUN_PER_USER = YES | ||
5 | OPTIONS = -L DEBUG | ||
6 | |||
7 | [arm] | ||
8 | HOSTNAME = localhost | ||
9 | BINARY = gnunet-service-arm | ||
10 | ACCEPT_FROM = 127.0.0.1; | ||
11 | ACCEPT_FROM6 = ::1; | ||
12 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-arm.sock | ||
13 | UNIX_MATCH_UID = YES | ||
14 | UNIX_MATCH_GID = YES | ||
15 | GLOBAL_PREFIX = | ||
16 | OPTIONS = -l $GNUNET_CACHE_HOME/gnunet-%Y-%m-%d.log | ||
17 | CONFIG = /home/user/Documents/gnunet/src/lib/testing/test_netjail_topo.conf | ||
18 | |||
19 | [auction] | ||
20 | START_ON_DEMAND = NO | ||
21 | BINARY = gnunet-service-auction | ||
22 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-auction.sock | ||
23 | |||
24 | [cadet] | ||
25 | IMMEDIATE_START = YES | ||
26 | START_ON_DEMAND = YES | ||
27 | HOSTNAME = localhost | ||
28 | BINARY = gnunet-service-cadet | ||
29 | ACCEPT_FROM = 127.0.0.1; | ||
30 | ACCEPT_FROM6 = ::1; | ||
31 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-cadet.sock | ||
32 | UNIX_MATCH_UID = NO | ||
33 | UNIX_MATCH_GID = YES | ||
34 | REFRESH_CONNECTION_TIME = 5 min | ||
35 | ID_ANNOUNCE_TIME = 1 h | ||
36 | CONNECT_TIMEOUT = 30 s | ||
37 | DHT_REPLICATION_LEVEL = 3 | ||
38 | MAX_CONNECTIONS = 1000 | ||
39 | MAX_ROUTES = 5000 | ||
40 | MAX_MSGS_QUEUE = 10000 | ||
41 | MAX_PEERS = 1000 | ||
42 | RATCHET_TIME = 1 h | ||
43 | RATCHET_MESSAGES = 64 | ||
44 | |||
45 | [consensus] | ||
46 | START_ON_DEMAND = YES | ||
47 | HOSTNAME = localhost | ||
48 | BINARY = gnunet-service-consensus | ||
49 | ACCEPT_FROM = 127.0.0.1; | ||
50 | ACCEPT_FROM6 = ::1; | ||
51 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-consensus.sock | ||
52 | UNIX_MATCH_UID = YES | ||
53 | UNIX_MATCH_GID = YES | ||
54 | |||
55 | [core] | ||
56 | START_ON_DEMAND = YES | ||
57 | HOSTNAME = localhost | ||
58 | BINARY = gnunet-service-core | ||
59 | ACCEPT_FROM = 127.0.0.1; | ||
60 | ACCEPT_FROM6 = ::1; | ||
61 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-core.sock | ||
62 | UNIX_MATCH_UID = NO | ||
63 | UNIX_MATCH_GID = YES | ||
64 | USE_EPHEMERAL_KEYS = YES | ||
65 | |||
66 | [datacache-postgres] | ||
67 | CONFIG = postgres:///gnunet | ||
68 | SQL_DIR = $DATADIR/sql/ | ||
69 | |||
70 | [datastore] | ||
71 | START_ON_DEMAND = YES | ||
72 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-datastore.sock | ||
73 | UNIX_MATCH_UID = NO | ||
74 | UNIX_MATCH_GID = YES | ||
75 | HOSTNAME = localhost | ||
76 | BINARY = gnunet-service-datastore | ||
77 | ACCEPT_FROM = 127.0.0.1; | ||
78 | ACCEPT_FROM6 = ::1; | ||
79 | QUOTA = 5 GB | ||
80 | BLOOMFILTER = $GNUNET_DATA_HOME/datastore/bloomfilter | ||
81 | DATABASE = sqlite | ||
82 | |||
83 | [datastore-sqlite] | ||
84 | FILENAME = $GNUNET_DATA_HOME/datastore/sqlite.db | ||
85 | |||
86 | [datastore-postgres] | ||
87 | CONFIG = postgres:///gnunet | ||
88 | SQL_DIR = ${DATADIR}/sql/ | ||
89 | |||
90 | [datastore-mysql] | ||
91 | DATABASE = gnunet | ||
92 | CONFIG = ~/.my.cnf | ||
93 | |||
94 | [datastore-heap] | ||
95 | HASHMAPSIZE = 1024 | ||
96 | |||
97 | [dht] | ||
98 | IMMEDIATE_START = YES | ||
99 | START_ON_DEMAND = YES | ||
100 | HOSTNAME = localhost | ||
101 | BINARY = gnunet-service-dht | ||
102 | ACCEPT_FROM = 127.0.0.1; | ||
103 | ACCEPT_FROM6 = ::1; | ||
104 | BUCKET_SIZE = 4 | ||
105 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-dht.sock | ||
106 | UNIX_MATCH_UID = NO | ||
107 | UNIX_MATCH_GID = YES | ||
108 | CACHE_RESULTS = YES | ||
109 | DISABLE_TRY_CONNECT = NO | ||
110 | |||
111 | [dhtcache] | ||
112 | DATABASE = heap | ||
113 | QUOTA = 50 MB | ||
114 | DISABLE_BF_RC = NO | ||
115 | |||
116 | [dhtu-gnunet] | ||
117 | ENABLED = YES | ||
118 | |||
119 | [dhtu-ip] | ||
120 | ENABLED = NO | ||
121 | NSE = 4 | ||
122 | UDP_PORT = 6666 | ||
123 | |||
124 | [dns] | ||
125 | START_ON_DEMAND = YES | ||
126 | HOSTNAME = localhost | ||
127 | BINARY = gnunet-service-dns | ||
128 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-dns.sock | ||
129 | UNIX_MATCH_UID = YES | ||
130 | UNIX_MATCH_GID = YES | ||
131 | IFNAME = gnunet-dns | ||
132 | IPV6ADDR = 2001:DB8::1 | ||
133 | IPV6PREFIX = 126 | ||
134 | IPV4ADDR = 169.254.1.1 | ||
135 | IPV4MASK = 255.255.0.0 | ||
136 | DNS_EXIT = 8.8.8.8 | ||
137 | |||
138 | [exit] | ||
139 | BINARY = gnunet-daemon-exit | ||
140 | IPV6ADDR = 2001:DB8::1 | ||
141 | IPV6PREFIX = 64 | ||
142 | IPV4ADDR = 169.254.86.1 | ||
143 | IPV4MASK = 255.255.255.0 | ||
144 | EXIT_RANGE_IPV4_POLICY = 0.0.0.0/0:!25; | ||
145 | EXIT_RANGE_IPV6_POLICY = ::/0:!25; | ||
146 | NOARMBIND = YES | ||
147 | TUN_IFNAME = exit-gnunet | ||
148 | EXIT_IFNAME = eth0 | ||
149 | EXIT_IPV4 = NO | ||
150 | EXIT_IPV6 = NO | ||
151 | EXIT_DNS = NO | ||
152 | DNS_RESOLVER = 8.8.8.8 | ||
153 | ENABLE_IPV4 = YES | ||
154 | ENABLE_IPV6 = YES | ||
155 | MAX_CONNECTIONS = 256 | ||
156 | |||
157 | [fs] | ||
158 | RUN_PER_USER = YES | ||
159 | START_ON_DEMAND = YES | ||
160 | IMMEDIATE_START = YES | ||
161 | INDEXDB = $GNUNET_DATA_HOME/fs/idxinfo.lst | ||
162 | RESPECT = $GNUNET_DATA_HOME/fs/credit/ | ||
163 | STATE_DIR = $GNUNET_DATA_HOME/fs/persistence/ | ||
164 | UPDATE_DIR = $GNUNET_DATA_HOME/fs/updates/ | ||
165 | HOSTNAME = localhost | ||
166 | BINARY = gnunet-service-fs | ||
167 | ACCEPT_FROM = 127.0.0.1; | ||
168 | ACCEPT_FROM6 = ::1; | ||
169 | DELAY = YES | ||
170 | CONTENT_CACHING = YES | ||
171 | CONTENT_PUSHING = YES | ||
172 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-fs.sock | ||
173 | UNIX_MATCH_UID = NO | ||
174 | UNIX_MATCH_GID = YES | ||
175 | MAX_PENDING_REQUESTS = 65536 | ||
176 | DATASTORE_QUEUE_SIZE = 32 | ||
177 | MIN_MIGRATION_DELAY = 100 ms | ||
178 | EXPECTED_NEIGHBOUR_COUNT = 128 | ||
179 | DISABLE_ANON_TRANSFER = NO | ||
180 | MAX_CADET_CLIENTS = 128 | ||
181 | |||
182 | [gns] | ||
183 | START_ON_DEMAND = YES | ||
184 | IMMEDIATE_START = YES | ||
185 | HOSTNAME = localhost | ||
186 | BINARY = gnunet-service-gns | ||
187 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-gns.sock | ||
188 | UNIX_MATCH_UID = NO | ||
189 | UNIX_MATCH_GID = YES | ||
190 | MAX_PARALLEL_BACKGROUND_QUERIES = 1000 | ||
191 | INTERCEPT_DNS = NO | ||
192 | .pin.gns.alt = 000G0522TTKQESZ9KPRT2K0RA9ZC8YMD52D2XYVYVGPDCNPMWHH9QXXF4W | ||
193 | .gnunet.gns.alt = 000G0522TTKQESZ9KPRT2K0RA9ZC8YMD52D2XYVYVGPDCNPMWHH9QXXF4W | ||
194 | |||
195 | [gns-proxy] | ||
196 | BINARY = gnunet-gns-proxy | ||
197 | START_ON_DEMAND = NO | ||
198 | RUN_PER_USER = YES | ||
199 | BIND_TO = 127.0.0.1 | ||
200 | BIND_TO6 = ::1 | ||
201 | PROXY_CACERT = $GNUNET_DATA_HOME/gns/gns_ca_cert.pem | ||
202 | PROXY_UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-gns-proxy.sock | ||
203 | |||
204 | [bcd] | ||
205 | BINARY = gnunet-bcd | ||
206 | OPTIONS = -p 8888 | ||
207 | START_ON_DEMAND = NO | ||
208 | RUN_PER_USER = YES | ||
209 | |||
210 | [dns2gns] | ||
211 | BINARY = gnunet-dns2gns | ||
212 | START_ON_DEMAND = NO | ||
213 | RUN_PER_USER = NO | ||
214 | BIND_TO = 127.0.0.1 | ||
215 | BIND_TO6 = ::1 | ||
216 | OPTIONS = -d 9.9.9.9 | ||
217 | PORT = 15353 | ||
218 | ENABLE_RESOLVECTL_NMDISPATCHER = NO | ||
219 | |||
220 | [hostlist] | ||
221 | IMMEDIATE_START = YES | ||
222 | NOARMBIND = YES | ||
223 | BINARY = gnunet-daemon-hostlist | ||
224 | HTTPPORT = 8080 | ||
225 | HOSTLISTFILE = $GNUNET_CONFIG_HOME/hostlist/learned.txt | ||
226 | OPTIONS = -b | ||
227 | SERVERS = https://v21.gnunet.org/hostlist | ||
228 | |||
229 | [identity] | ||
230 | START_ON_DEMAND = YES | ||
231 | RUN_PER_USER = YES | ||
232 | HOSTNAME = localhost | ||
233 | BINARY = gnunet-service-identity | ||
234 | ACCEPT_FROM = 127.0.0.1; | ||
235 | ACCEPT_FROM6 = ::1; | ||
236 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-identity.sock | ||
237 | UNIX_MATCH_UID = NO | ||
238 | UNIX_MATCH_GID = YES | ||
239 | EGODIR = $GNUNET_DATA_HOME/identity/egos/ | ||
240 | SUBSYSTEM_CFG = $GNUNET_CONFIG_HOME/identity/subsystem_defaults.conf | ||
241 | |||
242 | [messenger] | ||
243 | START_ON_DEMAND = YES | ||
244 | RUN_PER_USER = YES | ||
245 | HOSTNAME = localhost | ||
246 | BINARY = gnunet-service-messenger | ||
247 | ACCEPT_FROM = 127.0.0.1; | ||
248 | ACCEPT_FROM6 = ::1; | ||
249 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-messenger.sock | ||
250 | UNIX_MATCH_UID = NO | ||
251 | UNIX_MATCH_GID = YES | ||
252 | MESSENGER_DIR = $GNUNET_DATA_HOME/messenger/ | ||
253 | MESSENGER_AUTO_CONNECTING = YES | ||
254 | MESSENGER_AUTO_ROUTING = YES | ||
255 | MESSENGER_MIN_ROUTERS = 3 | ||
256 | |||
257 | [namecache] | ||
258 | START_ON_DEMAND = YES | ||
259 | RUN_PER_USER = NO | ||
260 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-namecache.sock | ||
261 | UNIX_MATCH_UID = NO | ||
262 | UNIX_MATCH_GID = YES | ||
263 | HOSTNAME = localhost | ||
264 | BINARY = gnunet-service-namecache | ||
265 | ACCEPT_FROM = 127.0.0.1; | ||
266 | ACCEPT_FROM6 = ::1; | ||
267 | DATABASE = sqlite | ||
268 | DISABLE = NO | ||
269 | |||
270 | [namecache-sqlite] | ||
271 | FILENAME = $GNUNET_DATA_HOME/namecache/sqlite.db | ||
272 | |||
273 | [namecache-flat] | ||
274 | FILENAME = $GNUNET_DATA_HOME/namecache/flat.db | ||
275 | |||
276 | [namecache-postgres] | ||
277 | CONFIG = postgres:///gnunet | ||
278 | SQL_DIR = ${DATADIR}/sql/ | ||
279 | |||
280 | [namestore] | ||
281 | START_ON_DEMAND = YES | ||
282 | RUN_PER_USER = YES | ||
283 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-namestore.sock | ||
284 | UNIX_MATCH_UID = NO | ||
285 | UNIX_MATCH_GID = YES | ||
286 | HOSTNAME = localhost | ||
287 | BINARY = gnunet-service-namestore | ||
288 | ACCEPT_FROM = 127.0.0.1; | ||
289 | ACCEPT_FROM6 = ::1; | ||
290 | DATABASE = sqlite | ||
291 | CACHE_KEYS = YES | ||
292 | |||
293 | [namestore-sqlite] | ||
294 | INIT_ON_CONNECT = YES | ||
295 | FILENAME = $GNUNET_DATA_HOME/namestore/sqlite.db | ||
296 | |||
297 | [namestore-postgres] | ||
298 | CONFIG = postgres:///gnunet | ||
299 | ASYNC_COMMIT = NO | ||
300 | INIT_ON_CONNECT = YES | ||
301 | SQL_DIR = ${DATADIR}/sql/ | ||
302 | |||
303 | [uri] | ||
304 | gns = gnunet-namestore -e 1a -u | ||
305 | |||
306 | [nat-auto] | ||
307 | START_ON_DEMAND = YES | ||
308 | HOSTNAME = localhost | ||
309 | BINARY = gnunet-service-nat-auto | ||
310 | ACCEPT_FROM = 127.0.0.1; | ||
311 | ACCEPT_FROM6 = ::1; | ||
312 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-nat-auto.sock | ||
313 | UNIX_MATCH_UID = YES | ||
314 | UNIX_MATCH_GID = YES | ||
315 | |||
316 | [gnunet-nat-server] | ||
317 | HOSTNAME = gnunet.org | ||
318 | PORT = 5724 | ||
319 | NOARMBIND = YES | ||
320 | |||
321 | [nat] | ||
322 | START_ON_DEMAND = YES | ||
323 | HOSTNAME = localhost | ||
324 | BINARY = gnunet-service-nat | ||
325 | ACCEPT_FROM = 127.0.0.1; | ||
326 | ACCEPT_FROM6 = ::1; | ||
327 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-nat.sock | ||
328 | UNIX_MATCH_UID = YES | ||
329 | UNIX_MATCH_GID = YES | ||
330 | ENABLE_UPNP = YES | ||
331 | ENABLE_IPSCAN = YES | ||
332 | DISABLEV6 = NO | ||
333 | HOSTNAME_DNS_FREQUENCY = 20 min | ||
334 | IFC_SCAN_FREQUENCY = 15 min | ||
335 | DYNDNS_FREQUENCY = 7 min | ||
336 | USE_STUN = YES | ||
337 | STUN_FREQUENCY = 5 min | ||
338 | STUN_SERVERS = stun.gnunet.org stun.services.mozilla.com:3478 stun.ekiga.net:3478 | ||
339 | STUN_STALE = 60 min | ||
340 | |||
341 | [nse] | ||
342 | START_ON_DEMAND = YES | ||
343 | IMMEDIATE_START = YES | ||
344 | HOSTNAME = localhost | ||
345 | BINARY = gnunet-service-nse | ||
346 | ACCEPT_FROM = 127.0.0.1; | ||
347 | ACCEPT_FROM6 = ::1; | ||
348 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-nse.sock | ||
349 | UNIX_MATCH_UID = NO | ||
350 | UNIX_MATCH_GID = YES | ||
351 | PROOFFILE = $GNUNET_DATA_HOME/nse/proof.dat | ||
352 | HISTOGRAM_DIR = $GNUNET_CACHE_HOME/nse/histogram | ||
353 | WORKDELAY = 5 ms | ||
354 | INTERVAL = 1 h | ||
355 | WORKBITS = 15 | ||
356 | |||
357 | [peerstore] | ||
358 | IMMEDIATE_START = YES | ||
359 | USE_INCLUDED_HELLOS = YES | ||
360 | HOSTNAME = localhost | ||
361 | BINARY = gnunet-service-peerstore | ||
362 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-peerstore.sock | ||
363 | UNIX_MATCH_UID = NO | ||
364 | UNIX_MATCH_GID = YES | ||
365 | DATABASE = sqlite | ||
366 | |||
367 | [peerstore-sqlite] | ||
368 | FILENAME = $GNUNET_DATA_HOME/peerstore/sqlite.db | ||
369 | |||
370 | [pt] | ||
371 | BINARY = gnunet-daemon-pt | ||
372 | NOARMBIND = YES | ||
373 | TUNNEL_IPV4 = NO | ||
374 | TUNNEL_IPV6 = NO | ||
375 | TUNNEL_DNS = NO | ||
376 | |||
377 | [reclaim] | ||
378 | START_ON_DEMAND = YES | ||
379 | RUN_PER_USER = YES | ||
380 | HOSTNAME = localhost | ||
381 | BINARY = gnunet-service-reclaim | ||
382 | ACCEPT_FROM = 127.0.0.1; | ||
383 | ACCEPT_FROM6 = ::1; | ||
384 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-reclaim.sock | ||
385 | UNIX_MATCH_UID = NO | ||
386 | UNIX_MATCH_GID = YES | ||
387 | TICKET_REFRESH_INTERVAL = 6h | ||
388 | |||
389 | [reclaim-rest-plugin] | ||
390 | ADDRESS = https://ui.reclaim/#/login | ||
391 | OIDC_JSON_WEB_ALGORITHM = RS256 | ||
392 | OIDC_CLIENT_HMAC_SECRET = secret | ||
393 | OIDC_DIR = $GNUNET_DATA_HOME/oidc | ||
394 | OIDC_USERINFO_CONSUME_TIMEOUT = 5s | ||
395 | JWT_SECRET = secret | ||
396 | EXPIRATION_TIME = 1d | ||
397 | |||
398 | [regex] | ||
399 | START_ON_DEMAND = YES | ||
400 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-regex.sock | ||
401 | HOSTNAME = localhost | ||
402 | BINARY = gnunet-service-regex | ||
403 | ACCEPT_FROM = 127.0.0.1; | ||
404 | ACCEPT_FROM6 = ::1; | ||
405 | |||
406 | [resolver] | ||
407 | START_ON_DEMAND = YES | ||
408 | HOSTNAME = localhost | ||
409 | BINARY = gnunet-service-resolver | ||
410 | ACCEPT_FROM = 127.0.0.1; | ||
411 | ACCEPT_FROM6 = ::1; | ||
412 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver.sock | ||
413 | UNIX_MATCH_UID = NO | ||
414 | UNIX_MATCH_GID = NO | ||
415 | |||
416 | [rest] | ||
417 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-rest.sock | ||
418 | BINARY = gnunet-rest-server | ||
419 | IMMEDIATE_START = YES | ||
420 | HTTP_PORT = 7776 | ||
421 | BIND_TO = 127.0.0.1 | ||
422 | BIND_TO6 = ::1 | ||
423 | REST_ALLOW_HEADERS = Authorization,Accept,Content-Type | ||
424 | REST_ECHO_ORIGIN_WEBEXT = YES | ||
425 | REST_ALLOW_ORIGIN = http://localhost:4200 | ||
426 | REST_ALLOW_CREDENTIALS = true | ||
427 | RUN_PER_USER = NO | ||
428 | BASIC_AUTH_SECRET_FILE = $GNUNET_DATA_HOME/rest/secret | ||
429 | BASIC_AUTH_ENABLED = YES | ||
430 | |||
431 | [revocation] | ||
432 | START_ON_DEMAND = YES | ||
433 | IMMEDIATE_START = YES | ||
434 | HOSTNAME = localhost | ||
435 | BINARY = gnunet-service-revocation | ||
436 | ACCEPT_FROM = 127.0.0.1; | ||
437 | ACCEPT_FROM6 = ::1; | ||
438 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-revocation.sock | ||
439 | UNIX_MATCH_UID = NO | ||
440 | UNIX_MATCH_GID = YES | ||
441 | WORKBITS = 22 | ||
442 | EPOCH_DURATION = 365 d | ||
443 | DATABASE = $GNUNET_DATA_HOME/revocation.dat | ||
444 | |||
445 | [rps] | ||
446 | START_ON_DEMAND = YES | ||
447 | IMMEDIATE_START = YES | ||
448 | BINARY = gnunet-service-rps | ||
449 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-rps.sock | ||
450 | HOME = $SERVICEHOME | ||
451 | UNIX_MATCH_UID = NO | ||
452 | UNIX_MATCH_GID = YES | ||
453 | HOSTNAME = localhost | ||
454 | ACCEPT_FROM = 127.0.0.1; | ||
455 | ACCEPT_FROM6 = ::1; | ||
456 | ROUNDINTERVAL = 30 s | ||
457 | FILENAME_VALID_PEERS = $GNUNET_DATA_HOME/rps/valid_peers.txt | ||
458 | MINSIZE = 10 | ||
459 | DESIRED_PROBABILITY = 0.9 | ||
460 | DEFICIENCY_FACTOR = 0.4 | ||
461 | |||
462 | [scalarproduct-alice] | ||
463 | START_ON_DEMAND = YES | ||
464 | BINARY = gnunet-service-scalarproduct-ecc-alice | ||
465 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-scalarproduct-alice.sock | ||
466 | UNIX_MATCH_UID = NO | ||
467 | UNIX_MATCH_GID = YES | ||
468 | |||
469 | [scalarproduct-bob] | ||
470 | START_ON_DEMAND = YES | ||
471 | HOSTNAME = localhost | ||
472 | BINARY = gnunet-service-scalarproduct-ecc-bob | ||
473 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-scalarproduct-bob.sock | ||
474 | UNIX_MATCH_UID = NO | ||
475 | UNIX_MATCH_GID = YES | ||
476 | |||
477 | [secretsharing] | ||
478 | START_ON_DEMAND = NO | ||
479 | HOSTNAME = localhost | ||
480 | BINARY = gnunet-service-secretsharing | ||
481 | ACCEPT_FROM = 127.0.0.1; | ||
482 | ACCEPT_FROM6 = ::1; | ||
483 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-secretsharing.sock | ||
484 | UNIX_MATCH_UID = YES | ||
485 | UNIX_MATCH_GID = YES | ||
486 | |||
487 | [set] | ||
488 | START_ON_DEMAND = YES | ||
489 | HOSTNAME = localhost | ||
490 | BINARY = gnunet-service-set | ||
491 | ACCEPT_FROM = 127.0.0.1; | ||
492 | ACCEPT_FROM6 = ::1; | ||
493 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-set.sock | ||
494 | UNIX_MATCH_UID = YES | ||
495 | UNIX_MATCH_GID = YES | ||
496 | |||
497 | [seti] | ||
498 | START_ON_DEMAND = YES | ||
499 | HOSTNAME = localhost | ||
500 | BINARY = gnunet-service-seti | ||
501 | ACCEPT_FROM = 127.0.0.1; | ||
502 | ACCEPT_FROM6 = ::1; | ||
503 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-seti.sock | ||
504 | UNIX_MATCH_UID = YES | ||
505 | UNIX_MATCH_GID = YES | ||
506 | |||
507 | [setu] | ||
508 | START_ON_DEMAND = YES | ||
509 | HOSTNAME = localhost | ||
510 | BINARY = gnunet-service-setu | ||
511 | ACCEPT_FROM = 127.0.0.1; | ||
512 | ACCEPT_FROM6 = ::1; | ||
513 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-setu.sock | ||
514 | UNIX_MATCH_UID = YES | ||
515 | UNIX_MATCH_GID = YES | ||
516 | |||
517 | [statistics] | ||
518 | START_ON_DEMAND = YES | ||
519 | HOSTNAME = localhost | ||
520 | BINARY = gnunet-service-statistics | ||
521 | ACCEPT_FROM = 127.0.0.1; | ||
522 | ACCEPT_FROM6 = ::1; | ||
523 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-statistics.sock | ||
524 | UNIX_MATCH_UID = NO | ||
525 | UNIX_MATCH_GID = YES | ||
526 | DATABASE = $GNUNET_DATA_HOME/statistics.dat | ||
527 | |||
528 | [template] | ||
529 | START_ON_DEMAND = NO | ||
530 | PORT = 99999 | ||
531 | HOSTNAME = localhost | ||
532 | BINARY = gnunet-service-template | ||
533 | ACCEPT_FROM = 127.0.0.1; | ||
534 | ACCEPT_FROM6 = ::1; | ||
535 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-template.sock | ||
536 | UNIX_MATCH_UID = YES | ||
537 | UNIX_MATCH_GID = YES | ||
538 | |||
539 | [TESTING] | ||
540 | CONNECT_TIMEOUT = 30 s | ||
541 | CONNECT_ATTEMPTS = 3 | ||
542 | MAX_OUTSTANDING_CONNECTIONS = 50 | ||
543 | DELETE_FILES = YES | ||
544 | SPEEDUP_INTERVAL = 0 ms | ||
545 | SPEEDUP_DELTA = 0 ms | ||
546 | USE_ABSTRACT_SOCKETS = NO | ||
547 | |||
548 | [topology] | ||
549 | IMMEDIATE_START = YES | ||
550 | NOARMBIND = YES | ||
551 | TARGET-CONNECTION-COUNT = 16 | ||
552 | BINARY = gnunet-daemon-topology | ||
553 | |||
554 | [transport] | ||
555 | START_ON_DEMAND = YES | ||
556 | HOSTNAME = localhost | ||
557 | BINARY = gnunet-service-transport | ||
558 | ACCEPT_FROM = 127.0.0.1; | ||
559 | ACCEPT_FROM6 = ::1; | ||
560 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport.sock | ||
561 | |||
562 | [communicator-tcp] | ||
563 | BINDTO = 2086 | ||
564 | DISABLE_V6 = NO | ||
565 | BINARY = gnunet-communicator-tcp | ||
566 | IMMEDIATE_START = YES | ||
567 | |||
568 | [communicator-udp] | ||
569 | BINARY = gnunet-communicator-udp | ||
570 | BINDTO = 2086 | ||
571 | DISABLE_V6 = NO | ||
572 | IMMEDIATE_START = YES | ||
573 | |||
574 | [communicator-quic] | ||
575 | BINDTO = 127.0.0.1 | ||
576 | |||
577 | [PEER] | ||
578 | PRIVATE_KEY = $GNUNET_DATA_HOME/private_key.ecc | ||
579 | SYSTEM_TYPE = UNKNOWN | ||
580 | |||
581 | [vpn] | ||
582 | START_ON_DEMAND = YES | ||
583 | HOSTNAME = localhost | ||
584 | BINARY = gnunet-service-vpn | ||
585 | ACCEPT_FROM = 127.0.0.1; | ||
586 | ACCEPT_FROM6 = ::1; | ||
587 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-vpn.sock | ||
588 | UNIX_MATCH_UID = NO | ||
589 | UNIX_MATCH_GID = YES | ||
590 | IPV6ADDR = 1234::1 | ||
591 | IPV6PREFIX = 32 | ||
592 | IPV4ADDR = 10.11.10.1 | ||
593 | IPV4MASK = 255.255.0.0 | ||
594 | VIRTDNS = 10.11.10.2 | ||
595 | VIRTDNS6 = 1234::17 | ||
596 | IFNAME = vpn-gnunet | ||
597 | |||
598 | [zonemaster] | ||
599 | START_ON_DEMAND = YES | ||
600 | RUN_PER_USER = YES | ||
601 | IMMEDIATE_START = YES | ||
602 | HOSTNAME = localhost | ||
603 | BINARY = gnunet-service-zonemaster | ||
604 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-zonemaster.sock | ||
605 | WORKER_COUNT = 4 | ||
606 | UNIX_MATCH_UID = NO | ||
607 | UNIX_MATCH_GID = NO | ||
608 | MAX_PARALLEL_BACKGROUND_QUERIES = 1000 | ||
609 | ZONE_PUBLISH_TIME_WINDOW = 4 h | ||
610 | |||
611 | [DEFAULTS] | ||
612 | SUBNETS = 42 | ||
613 | CARRIER_SETUP_PROGRAMMS = iptables -A INPUT -p icmp -j DROP;tc qdisc add dev $UPLINK root netm delay 100ms 10ms; | ||
614 | SUBNET_SETUP_PROGRAMMS = iptables -A INPUT -p icmp -j DROP;tc qdisc add dev $UPLINK root netm delay 100ms 10ms; | ||
615 | PEER_SETUP_PROGRAMMS = iptables -A INPUT -p icmp -j DROP;tc qdisc add dev $UPLINK root netm delay 100ms 10ms; | ||
616 | TESTBED_PLUGIN = normal | ||
617 | PLUGIN_ENV = key=value;key=value; | ||
618 | CARRIER_PEERS = 1 | ||
619 | SUBNET_PEERS = 4 | ||
620 | |||
621 | [BACKBONE] | ||
622 | CARRIERS = 2 | ||
623 | BACKBONE_PEERS = 1 | ||
624 | |||
625 | [BACKBONE-PEER-1] | ||
626 | TESTBED_PLUGIN = server | ||
627 | |||
628 | [CARRIER-1] | ||
629 | CARRIER_PEERS = 2 | ||
630 | SUBNETS = 2 | ||
631 | |||
632 | [CARRIER-2] | ||
633 | TESTBED_PLUGIN = mobile_network | ||
634 | |||
635 | [CARRIER-2-PEER-1] | ||
636 | TESTBED_PLUGIN = mobile_network | ||
637 | |||
638 | [CARRIER-1-SUBNET-1] | ||
639 | SUBNET = 8.8.0.0/16 | ||
640 | SUBNET_PEERS = 2 | ||
641 | TESTBED_PLUGIN = pc | ||
642 | |||
643 | [CARRIER-1-SUBNET-2] | ||
644 | IPTABLES_ARGS = -A ... $UPLINK; -A ... $DOWNLINK; | ||
645 | |||
646 | [CARRIER-1-SUBNET-1-PEER-1] | ||
647 | TESTBED_PLUGIN = evil | ||
648 | IPTABLES_ARGS = -A ... $DOWNLINK; | ||
649 | |||
650 | [PATHS] | ||
651 | GNUNET_HOME = ${GNUNET_TEST_HOME:-${HOME:-${USERPROFILE}}} | ||
652 | GNUNET_DATA_HOME = ${XDG_DATA_HOME:-$GNUNET_HOME/.local/share}/gnunet/ | ||
653 | GNUNET_CONFIG_HOME = ${XDG_CONFIG_HOME:-$GNUNET_HOME/.config}/gnunet/ | ||
654 | GNUNET_CACHE_HOME = ${XDG_CACHE_HOME:-$GNUNET_HOME/.cache}/gnunet/ | ||
655 | GNUNET_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/gnunet-system-runtime/ | ||
656 | GNUNET_USER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/gnunet-${USERHOME:-${USER:-user}}-runtime/ | ||
657 | GNUNET_TMP = ${TMPDIR:-${TMP:-/tmp}}/gnunet/ | ||
658 | |||
diff --git a/src/lib/testing/test_testing_api.c b/src/lib/testing/test_testing_api.c new file mode 100644 index 000000000..2a5b614fd --- /dev/null +++ b/src/lib/testing/test_testing_api.c | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | This file is part of GNUNET | ||
3 | Copyright (C) 2016-2024 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as | ||
7 | published by the Free Software Foundation; either version 3, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public | ||
16 | License along with GNUnet; see the file COPYING. If not, | ||
17 | see <http://www.gnu.org/licenses/> | ||
18 | */ | ||
19 | /** | ||
20 | * @file testing/test_testing_api.c | ||
21 | * @brief testcase to test the testing framework | ||
22 | * @author Christian Grothoff | ||
23 | */ | ||
24 | #include "platform.h" | ||
25 | #include "gnunet_util_lib.h" | ||
26 | #include "gnunet_testing_lib.h" | ||
27 | |||
28 | |||
29 | int | ||
30 | main (int argc, | ||
31 | char *const *argv) | ||
32 | { | ||
33 | struct GNUNET_TESTING_Timer timers[] = { | ||
34 | { .prefix = "batch" }, | ||
35 | { .prefix = NULL } | ||
36 | }; | ||
37 | struct GNUNET_TESTING_Command batch[] = { | ||
38 | GNUNET_TESTING_cmd_exec_va ("batch-echo-once", | ||
39 | GNUNET_OS_PROCESS_EXITED, | ||
40 | 0, | ||
41 | "echo", | ||
42 | "-n", | ||
43 | "LI", | ||
44 | NULL), | ||
45 | GNUNET_TESTING_cmd_exec_va ("batch-echo", | ||
46 | GNUNET_OS_PROCESS_EXITED, | ||
47 | 0, | ||
48 | "echo", | ||
49 | "-n", | ||
50 | "LA", | ||
51 | NULL), | ||
52 | GNUNET_TESTING_cmd_end () | ||
53 | }; | ||
54 | struct GNUNET_TESTING_Command netjail[] = { | ||
55 | GNUNET_TESTING_cmd_load_topology_from_string ( | ||
56 | "load-topology", | ||
57 | ""), // try "M" | ||
58 | GNUNET_TESTING_cmd_end () | ||
59 | }; | ||
60 | struct GNUNET_TESTING_Command commands[] = { | ||
61 | GNUNET_TESTING_cmd_batch ("batch", | ||
62 | batch), | ||
63 | GNUNET_TESTING_cmd_rewind_ip ("rewind", | ||
64 | "batch-echo-once", | ||
65 | 2), | ||
66 | GNUNET_TESTING_cmd_barrier_create ("barrier", | ||
67 | 1), | ||
68 | GNUNET_TESTING_cmd_barrier_reached ("barrier-reached", | ||
69 | "barrier"), | ||
70 | GNUNET_TESTING_cmd_barrier_create ("barrier3", | ||
71 | 3), | ||
72 | GNUNET_TESTING_cmd_make_unblocking ( | ||
73 | GNUNET_TESTING_cmd_barrier_reached ("barrier3a-reached-nonblocking", | ||
74 | "barrier3")), | ||
75 | GNUNET_TESTING_cmd_make_unblocking ( | ||
76 | GNUNET_TESTING_cmd_barrier_reached ("barrier3b-reached-nonblocking", | ||
77 | "barrier3")), | ||
78 | GNUNET_TESTING_cmd_barrier_reached ("barrier3c-reached-blocking", | ||
79 | "barrier3"), | ||
80 | GNUNET_TESTING_cmd_finish ("barrier3a-reached-nonblocking-finish", | ||
81 | "barrier3a-reached-nonblocking", | ||
82 | GNUNET_TIME_UNIT_SECONDS), | ||
83 | GNUNET_TESTING_cmd_finish ("barrier3b-reached-nonblocking-finish", | ||
84 | "barrier3b-reached-nonblocking", | ||
85 | GNUNET_TIME_UNIT_SECONDS), | ||
86 | GNUNET_TESTING_cmd_stat ("stat", | ||
87 | timers), | ||
88 | GNUNET_TESTING_cmd_exec_va ("sleep", | ||
89 | GNUNET_OS_PROCESS_EXITED, | ||
90 | 0, | ||
91 | "sleep", | ||
92 | "0.01", | ||
93 | NULL), | ||
94 | GNUNET_TESTING_cmd_make_unblocking ( | ||
95 | GNUNET_TESTING_cmd_exec_va ("sleep", | ||
96 | GNUNET_OS_PROCESS_SIGNALED, | ||
97 | SIGKILL, | ||
98 | "sleep", | ||
99 | "5", | ||
100 | NULL)), | ||
101 | GNUNET_TESTING_cmd_signal ("kill-sleep", | ||
102 | "sleep", | ||
103 | SIGKILL), | ||
104 | GNUNET_TESTING_cmd_finish ("wait-sleep", | ||
105 | "sleep", | ||
106 | GNUNET_TIME_UNIT_SECONDS), | ||
107 | GNUNET_TESTING_cmd_exec_va ("echo", | ||
108 | GNUNET_OS_PROCESS_EXITED, | ||
109 | 0, | ||
110 | "echo", | ||
111 | "-n", | ||
112 | "LA", | ||
113 | NULL), | ||
114 | GNUNET_TESTING_cmd_rewind_ip ("rewind", | ||
115 | "wait-sleep", | ||
116 | 4), | ||
117 | GNUNET_TESTING_cmd_batch ("netjail", | ||
118 | netjail), | ||
119 | GNUNET_TESTING_cmd_end () | ||
120 | }; | ||
121 | |||
122 | GNUNET_log_setup ("test-testing-api", | ||
123 | "DEBUG", | ||
124 | NULL); | ||
125 | return GNUNET_TESTING_main (commands, | ||
126 | GNUNET_TIME_UNIT_MINUTES); | ||
127 | } | ||
128 | |||
129 | |||
130 | /* end of test_testing_api.c */ | ||
diff --git a/src/lib/testing/test_testing_plugin_ping.c b/src/lib/testing/test_testing_plugin_ping.c new file mode 100644 index 000000000..7054c10ff --- /dev/null +++ b/src/lib/testing/test_testing_plugin_ping.c | |||
@@ -0,0 +1,54 @@ | |||
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_plugin_ping.c | ||
23 | * @brief a plugin to provide the API for running test cases. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_lib.h" | ||
29 | |||
30 | GNUNET_TESTING_MAKE_PLUGIN ( | ||
31 | test_testing, | ||
32 | ping, | ||
33 | GNUNET_TESTING_cmd_exec_va ("ping", | ||
34 | GNUNET_OS_PROCESS_EXITED, | ||
35 | 0, | ||
36 | "ping", | ||
37 | "-c1", | ||
38 | (0 == strcmp (strchr (my_node_id, | ||
39 | '-'), | ||
40 | "-0001")) | ||
41 | ? "127.0.0.1" | ||
42 | : "127.0.0.2", | ||
43 | NULL), | ||
44 | GNUNET_TESTING_cmd_barrier_create ("barrier", | ||
45 | 1) | ||
46 | #if LATER | ||
47 | GNUNET_TESTING_cmd_barrier_reached ("label", | ||
48 | "peers-started-barrier" | ||
49 | ), | ||
50 | // peer runs here! | ||
51 | #endif | ||
52 | ) | ||
53 | |||
54 | /* end of test_testing_plugin_ping.c */ | ||
diff --git a/src/service/testing/testing.conf b/src/lib/testing/testing.conf index 7e25f8c13..7e25f8c13 100644 --- a/src/service/testing/testing.conf +++ b/src/lib/testing/testing.conf | |||
diff --git a/src/lib/testing/testing_api_barrier.c b/src/lib/testing/testing_api_barrier.c new file mode 100644 index 000000000..51dd85f91 --- /dev/null +++ b/src/lib/testing/testing_api_barrier.c | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2024 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/barrier.c | ||
23 | * @brief convenience API for writing testcases for GNUnet | ||
24 | * Many testcases need to start and stop a peer/service | ||
25 | * and this library is supposed to make that easier | ||
26 | * for TESTCASES. Normal programs should always | ||
27 | * use functions from gnunet_{util,arm}_lib.h. This API is | ||
28 | * ONLY for writing testcases (or internal use of the testbed). | ||
29 | * @author Christian Grothoff | ||
30 | * | ||
31 | */ | ||
32 | #include "platform.h" | ||
33 | #include "gnunet_util_lib.h" | ||
34 | #include "gnunet_testing_lib.h" | ||
35 | #include "testing_api_barrier.h" | ||
36 | |||
37 | |||
38 | void | ||
39 | GNUNET_TESTING_barrier_name_hash_ ( | ||
40 | const char *barrier_name, | ||
41 | struct GNUNET_ShortHashCode *bkey) | ||
42 | { | ||
43 | struct GNUNET_HashCode hc; | ||
44 | |||
45 | GNUNET_CRYPTO_hash (barrier_name, | ||
46 | strlen (barrier_name), | ||
47 | &hc); | ||
48 | memcpy (bkey, | ||
49 | &hc, | ||
50 | sizeof (*bkey)); | ||
51 | } | ||
diff --git a/src/lib/testing/testing_api_barrier.h b/src/lib/testing/testing_api_barrier.h new file mode 100644 index 000000000..4ed25783c --- /dev/null +++ b/src/lib/testing/testing_api_barrier.h | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2022 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 barrier.h | ||
23 | * @brief API to manage barriers. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | |||
27 | #ifndef TESTING_API_BARRIER_H | ||
28 | #define TESTING_API_BARRIER_H | ||
29 | |||
30 | /** | ||
31 | * An entry for a barrier list | ||
32 | */ | ||
33 | struct GNUNET_TESTING_Barrier | ||
34 | { | ||
35 | |||
36 | struct GNUNET_ShortHashCode barrier_id; | ||
37 | |||
38 | /** | ||
39 | * Context of barrier reached commands of our local interpreter that are | ||
40 | * currently blocked on this barrier. | ||
41 | */ | ||
42 | struct GNUNET_TESTING_AsyncContext **waiting; | ||
43 | |||
44 | /** | ||
45 | * Length of the @e waiting array. | ||
46 | */ | ||
47 | unsigned int cnt_waiting; | ||
48 | |||
49 | /** | ||
50 | * Number of total commands expected to be reached by the barrier. | ||
51 | */ | ||
52 | unsigned int expected_reaches; | ||
53 | |||
54 | /** | ||
55 | * Number of times the barrier has been reached. | ||
56 | * Only used if @e inherited is false. | ||
57 | */ | ||
58 | unsigned int reached; | ||
59 | |||
60 | /** | ||
61 | * Did we inherit the barrier from our parent loop? | ||
62 | */ | ||
63 | bool inherited; | ||
64 | |||
65 | /** | ||
66 | * Did we reach @e expected_reaches? Used in particular if | ||
67 | * @e inherited is true and we cannot compute locally. | ||
68 | */ | ||
69 | bool satisfied; | ||
70 | |||
71 | }; | ||
72 | |||
73 | |||
74 | void | ||
75 | GNUNET_TESTING_barrier_name_hash_ ( | ||
76 | const char *barrier_name, | ||
77 | struct GNUNET_ShortHashCode *bkey); | ||
78 | |||
79 | |||
80 | #endif | ||
81 | /* end of barrier.h */ | ||
diff --git a/src/lib/testing/testing_api_cmd_barrier_create.c b/src/lib/testing/testing_api_cmd_barrier_create.c new file mode 100644 index 000000000..353dd37bc --- /dev/null +++ b/src/lib/testing/testing_api_cmd_barrier_create.c | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2022 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_barrier.c | ||
23 | * @brief Barrier functionality. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_testing_lib.h" | ||
28 | #include "testing_api_barrier.h" | ||
29 | #include "testing_api_loop.h" | ||
30 | |||
31 | |||
32 | /** | ||
33 | * Offer internal data from a "barrier" CMD, to other commands. | ||
34 | * | ||
35 | * @param cls closure. | ||
36 | * @param[out] ret result. | ||
37 | * @param trait name of the trait. | ||
38 | * @param index index number of the object to offer. | ||
39 | * @return #GNUNET_OK on success. | ||
40 | */ | ||
41 | static enum GNUNET_GenericReturnValue | ||
42 | barrier_traits (void *cls, | ||
43 | const void **ret, | ||
44 | const char *trait, | ||
45 | unsigned int index) | ||
46 | { | ||
47 | struct GNUNET_TESTING_Trait traits[] = { | ||
48 | GNUNET_TESTING_trait_end () | ||
49 | }; | ||
50 | |||
51 | return GNUNET_TESTING_get_trait (traits, | ||
52 | ret, | ||
53 | trait, | ||
54 | index); | ||
55 | } | ||
56 | |||
57 | |||
58 | /** | ||
59 | * Cleanup the state from a "barrier" CMD, and possibly | ||
60 | * cancel a pending operation thereof. | ||
61 | * | ||
62 | * @param cls closure. | ||
63 | */ | ||
64 | static void | ||
65 | barrier_cleanup (void *cls) | ||
66 | { | ||
67 | struct GNUNET_TESTING_Barrier *barrier = cls; | ||
68 | |||
69 | GNUNET_free (barrier); | ||
70 | } | ||
71 | |||
72 | |||
73 | /** | ||
74 | * Run the command. | ||
75 | * | ||
76 | * @param cls closure. | ||
77 | * @param is the interpreter state. | ||
78 | */ | ||
79 | static void | ||
80 | barrier_run (void *cls, | ||
81 | struct GNUNET_TESTING_Interpreter *is) | ||
82 | { | ||
83 | struct GNUNET_TESTING_Barrier *barrier = cls; | ||
84 | |||
85 | GNUNET_TESTING_add_barrier_ (is, | ||
86 | barrier); | ||
87 | } | ||
88 | |||
89 | |||
90 | struct GNUNET_TESTING_Command | ||
91 | GNUNET_TESTING_cmd_barrier_create ( | ||
92 | const char *label, | ||
93 | unsigned int number_to_be_reached) | ||
94 | { | ||
95 | struct GNUNET_TESTING_Barrier *barrier; | ||
96 | |||
97 | barrier = GNUNET_new (struct GNUNET_TESTING_Barrier); | ||
98 | GNUNET_TESTING_barrier_name_hash_ (label, | ||
99 | &barrier->barrier_id); | ||
100 | barrier->expected_reaches = number_to_be_reached; | ||
101 | return GNUNET_TESTING_command_new (barrier, | ||
102 | label, | ||
103 | &barrier_run, | ||
104 | &barrier_cleanup, | ||
105 | &barrier_traits); | ||
106 | } | ||
diff --git a/src/lib/testing/testing_api_cmd_barrier_reached.c b/src/lib/testing/testing_api_cmd_barrier_reached.c new file mode 100644 index 000000000..35d3cbcd9 --- /dev/null +++ b/src/lib/testing/testing_api_cmd_barrier_reached.c | |||
@@ -0,0 +1,189 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2022 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_barrier_reached.c | ||
23 | * @brief Command to signal barrier was reached. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_testing_lib.h" | ||
28 | #include "testing_api_loop.h" | ||
29 | #include "testing_cmds.h" | ||
30 | |||
31 | /** | ||
32 | * Generic logging shortcut | ||
33 | */ | ||
34 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | ||
35 | |||
36 | /** | ||
37 | * Struct with information for callbacks. | ||
38 | * | ||
39 | */ | ||
40 | struct BarrierReachedState | ||
41 | { | ||
42 | /** | ||
43 | * Context for our asynchronous completion. | ||
44 | */ | ||
45 | struct GNUNET_TESTING_AsyncContext ac; | ||
46 | |||
47 | /** | ||
48 | * The label of this command. | ||
49 | */ | ||
50 | const char *label; | ||
51 | |||
52 | /** | ||
53 | * The name of the barrier this commands wait (if finishing asynchronous) for or/and reaches. | ||
54 | */ | ||
55 | const char *barrier_name; | ||
56 | |||
57 | }; | ||
58 | |||
59 | |||
60 | /** | ||
61 | * Run the command. | ||
62 | * | ||
63 | * @param cls closure. | ||
64 | * @param is the interpreter state. | ||
65 | */ | ||
66 | static void | ||
67 | barrier_reached_run (void *cls, | ||
68 | struct GNUNET_TESTING_Interpreter *is) | ||
69 | { | ||
70 | struct BarrierReachedState *brs = cls; | ||
71 | struct GNUNET_TESTING_Barrier *barrier; | ||
72 | |||
73 | barrier = GNUNET_TESTING_get_barrier_ (is, | ||
74 | brs->barrier_name); | ||
75 | if (NULL == barrier) | ||
76 | { | ||
77 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
78 | "No barrier `%s'\n", | ||
79 | brs->barrier_name); | ||
80 | GNUNET_TESTING_async_fail (&brs->ac); | ||
81 | return; | ||
82 | } | ||
83 | if (barrier->satisfied) | ||
84 | { | ||
85 | GNUNET_TESTING_async_finish (&brs->ac); | ||
86 | return; | ||
87 | } | ||
88 | if (barrier->inherited) | ||
89 | { | ||
90 | struct GNUNET_TESTING_CommandBarrierReached cbr = { | ||
91 | .header.size = htons (sizeof (cbr)), | ||
92 | .header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_REACHED) | ||
93 | }; | ||
94 | |||
95 | GNUNET_TESTING_barrier_name_hash_ (brs->barrier_name, | ||
96 | &cbr.barrier_key); | ||
97 | GNUNET_TESTING_loop_notify_parent_ (is, | ||
98 | &cbr.header); | ||
99 | return; | ||
100 | } | ||
101 | barrier->reached++; | ||
102 | if (barrier->reached == barrier->expected_reaches) | ||
103 | { | ||
104 | struct GNUNET_TESTING_CommandBarrierSatisfied cbs = { | ||
105 | .header.size = htons (sizeof (cbs)), | ||
106 | .header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_CROSSABLE) | ||
107 | }; | ||
108 | |||
109 | GNUNET_TESTING_barrier_name_hash_ (brs->barrier_name, | ||
110 | &cbs.barrier_key); | ||
111 | barrier->satisfied = true; | ||
112 | GNUNET_TESTING_loop_notify_children_ (is, | ||
113 | &cbs.header); | ||
114 | } | ||
115 | if (barrier->satisfied) | ||
116 | { | ||
117 | GNUNET_TESTING_async_finish (&brs->ac); | ||
118 | for (unsigned int i = 0; i<barrier->cnt_waiting; i++) | ||
119 | GNUNET_TESTING_async_finish (barrier->waiting[i]); | ||
120 | GNUNET_array_grow (barrier->waiting, | ||
121 | barrier->cnt_waiting, | ||
122 | 0); | ||
123 | return; | ||
124 | } | ||
125 | GNUNET_array_append (barrier->waiting, | ||
126 | barrier->cnt_waiting, | ||
127 | &brs->ac); | ||
128 | } | ||
129 | |||
130 | |||
131 | /** | ||
132 | * Cleanup the state from a "barrier reached" CMD, and possibly | ||
133 | * cancel a pending operation thereof. | ||
134 | * | ||
135 | * @param cls closure. | ||
136 | */ | ||
137 | static void | ||
138 | barrier_reached_cleanup (void *cls) | ||
139 | { | ||
140 | struct BarrierReachedState *brs = cls; | ||
141 | |||
142 | GNUNET_free (brs); | ||
143 | } | ||
144 | |||
145 | |||
146 | /** | ||
147 | * Offer internal data from a "batch" CMD, to other commands. | ||
148 | * | ||
149 | * @param cls closure. | ||
150 | * @param[out] ret result. | ||
151 | * @param trait name of the trait. | ||
152 | * @param index index number of the object to offer. | ||
153 | * @return #GNUNET_OK on success. | ||
154 | */ | ||
155 | static enum GNUNET_GenericReturnValue | ||
156 | barrier_reached_traits (void *cls, | ||
157 | const void **ret, | ||
158 | const char *trait, | ||
159 | unsigned int index) | ||
160 | { | ||
161 | struct GNUNET_TESTING_Trait traits[] = { | ||
162 | GNUNET_TESTING_trait_end () | ||
163 | }; | ||
164 | |||
165 | return GNUNET_TESTING_get_trait (traits, | ||
166 | ret, | ||
167 | trait, | ||
168 | index); | ||
169 | } | ||
170 | |||
171 | |||
172 | struct GNUNET_TESTING_Command | ||
173 | GNUNET_TESTING_cmd_barrier_reached ( | ||
174 | const char *label, | ||
175 | const char *barrier_label) | ||
176 | { | ||
177 | struct BarrierReachedState *brs; | ||
178 | |||
179 | brs = GNUNET_new (struct BarrierReachedState); | ||
180 | brs->label = label; | ||
181 | brs->barrier_name = barrier_label; | ||
182 | return GNUNET_TESTING_command_new_ac ( | ||
183 | brs, | ||
184 | label, | ||
185 | &barrier_reached_run, | ||
186 | &barrier_reached_cleanup, | ||
187 | &barrier_reached_traits, | ||
188 | &brs->ac); | ||
189 | } | ||
diff --git a/src/service/testing/testing_api_cmd_batch.c b/src/lib/testing/testing_api_cmd_batch.c index 2f1faf288..f4e866b78 100644 --- a/src/service/testing/testing_api_cmd_batch.c +++ b/src/lib/testing/testing_api_cmd_batch.c | |||
@@ -25,8 +25,9 @@ | |||
25 | * @author t3sserakt | 25 | * @author t3sserakt |
26 | */ | 26 | */ |
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_testing_ng_lib.h" | 28 | #include "gnunet_testing_lib.h" |
29 | #include "testing.h" | 29 | #include "testing_api_cmd_batch.h" |
30 | #include "testing_api_loop.h" | ||
30 | 31 | ||
31 | /** | 32 | /** |
32 | * State for a "batch" CMD. | 33 | * State for a "batch" CMD. |
@@ -61,26 +62,25 @@ batch_run (void *cls, | |||
61 | struct GNUNET_TESTING_Interpreter *is) | 62 | struct GNUNET_TESTING_Interpreter *is) |
62 | { | 63 | { |
63 | struct BatchState *bs = cls; | 64 | struct BatchState *bs = cls; |
65 | struct GNUNET_TESTING_Command *cmd; | ||
64 | 66 | ||
65 | if (NULL != bs->batch[bs->batch_ip].run) | 67 | cmd = &bs->batch[bs->batch_ip]; |
68 | if (NULL != cmd->run) | ||
66 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 69 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
67 | "Running batched command: %s\n", | 70 | "Running batched command: %s\n", |
68 | bs->batch[bs->batch_ip].label.value); | 71 | cmd->label.value); |
69 | 72 | ||
70 | /* hit end command, leap to next top-level command. */ | 73 | /* hit end command, leap to next top-level command. */ |
71 | if (NULL == bs->batch[bs->batch_ip].run) | 74 | if (NULL == cmd->run) |
72 | { | 75 | { |
73 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 76 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
74 | "Exiting from batch: %s\n", | 77 | "Exiting from batch: %s\n", |
75 | bs->label.value); | 78 | bs->label.value); |
79 | GNUNET_TESTING_interpreter_next_ (is); | ||
76 | return; | 80 | return; |
77 | } | 81 | } |
78 | bs->batch[bs->batch_ip].start_time | 82 | GNUNET_TESTING_interpreter_run_cmd_ (is, |
79 | = bs->batch[bs->batch_ip].last_req_time | 83 | cmd); |
80 | = GNUNET_TIME_absolute_get (); | ||
81 | bs->batch[bs->batch_ip].num_tries = 1; | ||
82 | bs->batch[bs->batch_ip].run (bs->batch[bs->batch_ip].cls, | ||
83 | is); | ||
84 | } | 84 | } |
85 | 85 | ||
86 | 86 | ||
@@ -120,14 +120,9 @@ batch_traits (void *cls, | |||
120 | unsigned int index) | 120 | unsigned int index) |
121 | { | 121 | { |
122 | struct BatchState *bs = cls; | 122 | struct BatchState *bs = cls; |
123 | // FIXME: these constants should be more global! | ||
124 | #define CURRENT_CMD_INDEX 0 | ||
125 | #define BATCH_INDEX 1 | ||
126 | struct GNUNET_TESTING_Trait traits[] = { | 123 | struct GNUNET_TESTING_Trait traits[] = { |
127 | GNUNET_TESTING_make_trait_cmd (CURRENT_CMD_INDEX, | 124 | GNUNET_TESTING_make_trait_cmd (&bs->batch[bs->batch_ip]), |
128 | &bs->batch[bs->batch_ip]), | 125 | GNUNET_TESTING_make_trait_batch_cmds (&bs->batch), |
129 | GNUNET_TESTING_make_trait_cmd (BATCH_INDEX, | ||
130 | bs->batch), | ||
131 | GNUNET_TESTING_trait_end () | 126 | GNUNET_TESTING_trait_end () |
132 | }; | 127 | }; |
133 | 128 | ||
@@ -175,7 +170,7 @@ GNUNET_TESTING_cmd_batch (const char *label, | |||
175 | label, | 170 | label, |
176 | &batch_run, | 171 | &batch_run, |
177 | &batch_cleanup, | 172 | &batch_cleanup, |
178 | &batch_traits, NULL); | 173 | &batch_traits); |
179 | } | 174 | } |
180 | 175 | ||
181 | 176 | ||
@@ -183,13 +178,24 @@ bool | |||
183 | GNUNET_TESTING_cmd_batch_next_ (void *cls) | 178 | GNUNET_TESTING_cmd_batch_next_ (void *cls) |
184 | { | 179 | { |
185 | struct BatchState *bs = cls; | 180 | struct BatchState *bs = cls; |
181 | struct GNUNET_TESTING_Command *bcmd = &bs->batch[bs->batch_ip]; | ||
186 | 182 | ||
187 | if (NULL == bs->batch[bs->batch_ip].run) | 183 | if (NULL == bcmd->run) |
188 | return false; | 184 | return true; /* this batch is done */ |
189 | bs->batch[bs->batch_ip].finish_time | 185 | if (GNUNET_TESTING_cmd_is_batch_ (bcmd)) |
190 | = GNUNET_TIME_absolute_get (); | 186 | { |
187 | if (GNUNET_TESTING_cmd_batch_next_ (bcmd->cls)) | ||
188 | { | ||
189 | /* sub-batch is done */ | ||
190 | bcmd->finish_time = GNUNET_TIME_absolute_get (); | ||
191 | bs->batch_ip++; | ||
192 | return false; | ||
193 | } | ||
194 | } | ||
195 | /* Simple command is done */ | ||
196 | bcmd->finish_time = GNUNET_TIME_absolute_get (); | ||
191 | bs->batch_ip++; | 197 | bs->batch_ip++; |
192 | return true; | 198 | return false; |
193 | } | 199 | } |
194 | 200 | ||
195 | 201 | ||
@@ -211,13 +217,16 @@ GNUNET_TESTING_cmd_batch_get_current_ (const struct GNUNET_TESTING_Command *cmd) | |||
211 | 217 | ||
212 | 218 | ||
213 | void | 219 | void |
214 | GNUNET_TESTING_cmd_batch_set_current_ (const struct GNUNET_TESTING_Command *cmd, | 220 | GNUNET_TESTING_cmd_batch_set_current_ ( |
215 | unsigned int new_ip) | 221 | const struct GNUNET_TESTING_Command *cmd, |
222 | unsigned int new_ip) | ||
216 | { | 223 | { |
217 | struct BatchState *bs = cmd->cls; | 224 | struct BatchState *bs = cmd->cls; |
218 | 225 | ||
219 | /* sanity checks */ | 226 | /* sanity checks */ |
220 | GNUNET_assert (GNUNET_TESTING_cmd_is_batch_ (cmd)); | 227 | GNUNET_assert (cmd->run == &batch_run); |
228 | for (unsigned int i = 0; i < new_ip; i++) | ||
229 | GNUNET_assert (NULL != bs->batch[i].run); | ||
221 | /* actual logic */ | 230 | /* actual logic */ |
222 | bs->batch_ip = new_ip; | 231 | bs->batch_ip = new_ip; |
223 | } | 232 | } |
diff --git a/src/lib/testing/testing_api_cmd_batch.h b/src/lib/testing/testing_api_cmd_batch.h new file mode 100644 index 000000000..f9f54c6cb --- /dev/null +++ b/src/lib/testing/testing_api_cmd_batch.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2022 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_api_cmd_batch.h | ||
23 | * @brief | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #ifndef TESTING_API_CMD_BATCH_H | ||
27 | #define TESTING_API_CMD_BATCH_H | ||
28 | |||
29 | |||
30 | /** | ||
31 | * Test if this command is a batch command. | ||
32 | * | ||
33 | * @return false if not, true if it is a batch command | ||
34 | */ | ||
35 | bool | ||
36 | GNUNET_TESTING_cmd_is_batch_ ( | ||
37 | const struct GNUNET_TESTING_Command *cmd); | ||
38 | |||
39 | |||
40 | /** | ||
41 | * Advance internal pointer to next command. | ||
42 | * | ||
43 | * @param cls batch internal state | ||
44 | * @return true if we could advance, false if the batch | ||
45 | * has completed and cannot advance anymore | ||
46 | */ | ||
47 | bool | ||
48 | GNUNET_TESTING_cmd_batch_next_ (void *cls); | ||
49 | |||
50 | |||
51 | /** | ||
52 | * Obtain what command the batch is at. | ||
53 | * | ||
54 | * @return cmd current batch command | ||
55 | */ | ||
56 | struct GNUNET_TESTING_Command * | ||
57 | GNUNET_TESTING_cmd_batch_get_current_ ( | ||
58 | const struct GNUNET_TESTING_Command *cmd); | ||
59 | |||
60 | |||
61 | /** | ||
62 | * Set what command the batch should be at. | ||
63 | * | ||
64 | * @param cmd current batch command | ||
65 | * @param new_ip where to move the IP | ||
66 | */ | ||
67 | void | ||
68 | GNUNET_TESTING_cmd_batch_set_current_ ( | ||
69 | const struct GNUNET_TESTING_Command *cmd, | ||
70 | unsigned int new_ip); | ||
71 | |||
72 | #endif | ||
diff --git a/src/lib/testing/testing_api_cmd_exec.c b/src/lib/testing/testing_api_cmd_exec.c new file mode 100644 index 000000000..3a931e220 --- /dev/null +++ b/src/lib/testing/testing_api_cmd_exec.c | |||
@@ -0,0 +1,254 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2023 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_api_cmd_exec.c | ||
23 | * @brief cmd to block the interpreter loop until all peers started. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_lib.h" | ||
29 | |||
30 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | ||
31 | |||
32 | struct BashScriptState | ||
33 | { | ||
34 | /** | ||
35 | * Context for our asynchronous completion. | ||
36 | */ | ||
37 | struct GNUNET_TESTING_AsyncContext ac; | ||
38 | |||
39 | /** | ||
40 | * Callback handed over to the command, which should | ||
41 | * be called upon death or completion of the script. | ||
42 | */ | ||
43 | GNUNET_ChildCompletedCallback cb; | ||
44 | |||
45 | /** | ||
46 | * Wait for death of @e start_proc. | ||
47 | */ | ||
48 | struct GNUNET_ChildWaitHandle *cwh; | ||
49 | |||
50 | /** | ||
51 | * The process id of the script. | ||
52 | */ | ||
53 | struct GNUNET_OS_Process *start_proc; | ||
54 | |||
55 | /** | ||
56 | * NULL-terminated array of command-line arguments. | ||
57 | */ | ||
58 | char **args; | ||
59 | |||
60 | /** | ||
61 | * | ||
62 | */ | ||
63 | enum GNUNET_OS_ProcessStatusType expected_type; | ||
64 | |||
65 | /** | ||
66 | * | ||
67 | */ | ||
68 | unsigned long int expected_exit_code; | ||
69 | |||
70 | }; | ||
71 | |||
72 | /** | ||
73 | * The cleanup function of this cmd frees resources the cmd allocated. | ||
74 | * | ||
75 | */ | ||
76 | static void | ||
77 | exec_bash_script_cleanup (void *cls) | ||
78 | { | ||
79 | struct BashScriptState *bss = cls; | ||
80 | |||
81 | if (NULL != bss->cwh) | ||
82 | { | ||
83 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
84 | "Cancel child\n"); | ||
85 | GNUNET_wait_child_cancel (bss->cwh); | ||
86 | bss->cwh = NULL; | ||
87 | } | ||
88 | if (NULL != bss->start_proc) | ||
89 | { | ||
90 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
91 | "Kill process\n"); | ||
92 | GNUNET_assert (0 == | ||
93 | GNUNET_OS_process_kill (bss->start_proc, | ||
94 | SIGKILL)); | ||
95 | GNUNET_assert (GNUNET_OK == | ||
96 | GNUNET_OS_process_wait (bss->start_proc)); | ||
97 | GNUNET_OS_process_destroy (bss->start_proc); | ||
98 | bss->start_proc = NULL; | ||
99 | } | ||
100 | for (unsigned int i = 0; NULL != bss->args[i]; i++) | ||
101 | GNUNET_free (bss->args[i]); | ||
102 | GNUNET_free (bss->args); | ||
103 | GNUNET_free (bss); | ||
104 | } | ||
105 | |||
106 | |||
107 | /** | ||
108 | * Callback which will be called if the setup script finished. | ||
109 | * | ||
110 | */ | ||
111 | static void | ||
112 | child_completed_callback (void *cls, | ||
113 | enum GNUNET_OS_ProcessStatusType type, | ||
114 | long unsigned int exit_code) | ||
115 | { | ||
116 | struct BashScriptState *bss = cls; | ||
117 | |||
118 | bss->cwh = NULL; | ||
119 | GNUNET_OS_process_destroy (bss->start_proc); | ||
120 | bss->start_proc = NULL; | ||
121 | if ( (bss->expected_type != type) || | ||
122 | (bss->expected_exit_code != exit_code) ) | ||
123 | { | ||
124 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
125 | "Child failed with error %lu (wanted %lu) %d/%d!\n", | ||
126 | exit_code, | ||
127 | bss->expected_exit_code, | ||
128 | type, | ||
129 | bss->expected_type); | ||
130 | GNUNET_TESTING_async_fail (&bss->ac); | ||
131 | return; | ||
132 | } | ||
133 | GNUNET_TESTING_async_finish (&bss->ac); | ||
134 | } | ||
135 | |||
136 | |||
137 | /** | ||
138 | * Run method of the command created by the interpreter to wait for another | ||
139 | * command to finish. | ||
140 | * | ||
141 | */ | ||
142 | static void | ||
143 | exec_bash_script_run (void *cls, | ||
144 | struct GNUNET_TESTING_Interpreter *is) | ||
145 | { | ||
146 | struct BashScriptState *bss = cls; | ||
147 | |||
148 | GNUNET_assert (NULL == bss->cwh); | ||
149 | bss->start_proc | ||
150 | = GNUNET_OS_start_process_vap ( | ||
151 | GNUNET_OS_INHERIT_STD_ERR, | ||
152 | NULL, | ||
153 | NULL, | ||
154 | NULL, | ||
155 | bss->args[0], | ||
156 | bss->args); | ||
157 | bss->cwh = GNUNET_wait_child (bss->start_proc, | ||
158 | &child_completed_callback, | ||
159 | bss); | ||
160 | GNUNET_break (NULL != bss->cwh); | ||
161 | } | ||
162 | |||
163 | |||
164 | /** | ||
165 | * This function prepares an array with traits. | ||
166 | */ | ||
167 | static enum GNUNET_GenericReturnValue | ||
168 | traits (void *cls, | ||
169 | const void **ret, | ||
170 | const char *trait, | ||
171 | unsigned int index) | ||
172 | { | ||
173 | struct BashScriptState *bss = cls; | ||
174 | struct GNUNET_TESTING_Trait traits[] = { | ||
175 | GNUNET_TESTING_make_trait_process (&bss->start_proc), | ||
176 | GNUNET_TESTING_trait_end () | ||
177 | }; | ||
178 | |||
179 | return GNUNET_TESTING_get_trait (traits, | ||
180 | ret, | ||
181 | trait, | ||
182 | index); | ||
183 | } | ||
184 | |||
185 | |||
186 | const struct GNUNET_TESTING_Command | ||
187 | GNUNET_TESTING_cmd_exec ( | ||
188 | const char *label, | ||
189 | enum GNUNET_OS_ProcessStatusType expected_type, | ||
190 | unsigned long int expected_exit_code, | ||
191 | char *const script_argv[]) | ||
192 | { | ||
193 | struct BashScriptState *bss; | ||
194 | unsigned int cnt; | ||
195 | |||
196 | cnt = 0; | ||
197 | while (NULL != script_argv[cnt]) | ||
198 | cnt++; | ||
199 | bss = GNUNET_new (struct BashScriptState); | ||
200 | bss->args = GNUNET_new_array (cnt + 1, | ||
201 | char *); | ||
202 | for (unsigned int i = 0; i<cnt; i++) | ||
203 | bss->args[i] = GNUNET_strdup (script_argv[i]); | ||
204 | bss->expected_type = expected_type; | ||
205 | bss->expected_exit_code = expected_exit_code; | ||
206 | return GNUNET_TESTING_command_new_ac ( | ||
207 | bss, | ||
208 | label, | ||
209 | &exec_bash_script_run, | ||
210 | &exec_bash_script_cleanup, | ||
211 | &traits, | ||
212 | &bss->ac); | ||
213 | } | ||
214 | |||
215 | |||
216 | const struct GNUNET_TESTING_Command | ||
217 | GNUNET_TESTING_cmd_exec_va ( | ||
218 | const char *label, | ||
219 | enum GNUNET_OS_ProcessStatusType expected_type, | ||
220 | unsigned long int expected_exit_code, | ||
221 | ...) | ||
222 | { | ||
223 | struct BashScriptState *bss; | ||
224 | va_list ap; | ||
225 | const char *arg; | ||
226 | unsigned int cnt; | ||
227 | |||
228 | bss = GNUNET_new (struct BashScriptState); | ||
229 | va_start (ap, | ||
230 | expected_exit_code); | ||
231 | cnt = 1; | ||
232 | while (NULL != (arg = va_arg (ap, | ||
233 | const char *))) | ||
234 | cnt++; | ||
235 | va_end (ap); | ||
236 | bss->args = GNUNET_new_array (cnt, | ||
237 | char *); | ||
238 | cnt = 0; | ||
239 | va_start (ap, | ||
240 | expected_exit_code); | ||
241 | while (NULL != (arg = va_arg (ap, | ||
242 | const char *))) | ||
243 | bss->args[cnt++] = GNUNET_strdup (arg); | ||
244 | va_end (ap); | ||
245 | bss->expected_type = expected_type; | ||
246 | bss->expected_exit_code = expected_exit_code; | ||
247 | return GNUNET_TESTING_command_new_ac ( | ||
248 | bss, | ||
249 | label, | ||
250 | &exec_bash_script_run, | ||
251 | &exec_bash_script_cleanup, | ||
252 | &traits, | ||
253 | &bss->ac); | ||
254 | } | ||
diff --git a/src/service/testing/testing_api_cmd_finish.c b/src/lib/testing/testing_api_cmd_finish.c index e1fc69a09..24642e0b6 100644 --- a/src/service/testing/testing_api_cmd_finish.c +++ b/src/lib/testing/testing_api_cmd_finish.c | |||
@@ -24,10 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | #include "platform.h" | 25 | #include "platform.h" |
26 | #include "gnunet_util_lib.h" | 26 | #include "gnunet_util_lib.h" |
27 | #include "gnunet_testing_ng_lib.h" | 27 | #include "gnunet_testing_lib.h" |
28 | #include "gnunet_testing_plugin.h" | ||
29 | #include "gnunet_testing_barrier.h" | ||
30 | #include "gnunet_testing_netjail_lib.h" | ||
31 | 28 | ||
32 | 29 | ||
33 | /** | 30 | /** |
@@ -42,12 +39,24 @@ struct FinishState | |||
42 | void *cls; | 39 | void *cls; |
43 | 40 | ||
44 | /** | 41 | /** |
45 | * Label of the asynchronous command the synchronous command of this closure waits for. | 42 | * Label of the asynchronous command the synchronous command of this closure |
43 | * waits for. | ||
46 | */ | 44 | */ |
47 | const char *async_label; | 45 | const char *async_label; |
48 | 46 | ||
49 | /** | 47 | /** |
50 | * Task for running the finish method of the asynchronous task the command is waiting for. | 48 | * Function to call when async operation is done. |
49 | */ | ||
50 | GNUNET_SCHEDULER_TaskCallback old_notify; | ||
51 | |||
52 | /** | ||
53 | * Closure for @e notify_finished. | ||
54 | */ | ||
55 | void *old_notify_cls; | ||
56 | |||
57 | /** | ||
58 | * Task for running the finish method of the asynchronous task the command | ||
59 | * is waiting for. | ||
51 | */ | 60 | */ |
52 | struct GNUNET_SCHEDULER_Task *finish_task; | 61 | struct GNUNET_SCHEDULER_Task *finish_task; |
53 | 62 | ||
@@ -77,6 +86,11 @@ done_finish (void *cls) | |||
77 | 86 | ||
78 | GNUNET_SCHEDULER_cancel (finish_state->finish_task); | 87 | GNUNET_SCHEDULER_cancel (finish_state->finish_task); |
79 | finish_state->finish_task = NULL; | 88 | finish_state->finish_task = NULL; |
89 | if (NULL != finish_state->old_notify) | ||
90 | { | ||
91 | finish_state->old_notify (finish_state->old_notify_cls); | ||
92 | finish_state->old_notify = NULL; | ||
93 | } | ||
80 | GNUNET_TESTING_async_finish (&finish_state->ac); | 94 | GNUNET_TESTING_async_finish (&finish_state->ac); |
81 | } | 95 | } |
82 | 96 | ||
@@ -106,8 +120,9 @@ timeout_finish (void *cls) | |||
106 | * | 120 | * |
107 | */ | 121 | */ |
108 | static void | 122 | static void |
109 | run_finish (void *cls, | 123 | run_finish ( |
110 | struct GNUNET_TESTING_Interpreter *is) | 124 | void *cls, |
125 | struct GNUNET_TESTING_Interpreter *is) | ||
111 | { | 126 | { |
112 | struct FinishState *finish_state = cls; | 127 | struct FinishState *finish_state = cls; |
113 | const struct GNUNET_TESTING_Command *async_cmd; | 128 | const struct GNUNET_TESTING_Command *async_cmd; |
@@ -121,8 +136,7 @@ run_finish (void *cls, | |||
121 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 136 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
122 | "Did not find command `%s'\n", | 137 | "Did not find command `%s'\n", |
123 | finish_state->async_label); | 138 | finish_state->async_label); |
124 | GNUNET_TESTING_interpreter_fail (is); | 139 | GNUNET_TESTING_FAIL (is); |
125 | return; | ||
126 | } | 140 | } |
127 | if ( (NULL == (aac = async_cmd->ac)) || | 141 | if ( (NULL == (aac = async_cmd->ac)) || |
128 | (! async_cmd->asynchronous_finish) ) | 142 | (! async_cmd->asynchronous_finish) ) |
@@ -130,21 +144,24 @@ run_finish (void *cls, | |||
130 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 144 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
131 | "Cannot finish `%s': not asynchronous\n", | 145 | "Cannot finish `%s': not asynchronous\n", |
132 | finish_state->async_label); | 146 | finish_state->async_label); |
133 | GNUNET_TESTING_interpreter_fail (is); | 147 | GNUNET_TESTING_FAIL (is); |
134 | return; | ||
135 | } | 148 | } |
136 | if (GNUNET_NO != aac->finished) | 149 | if (aac->finished) |
137 | { | 150 | { |
138 | /* Command is already finished, so are we! */ | 151 | /* Command is already finished, so are we! */ |
139 | GNUNET_TESTING_async_finish (&finish_state->ac); | 152 | GNUNET_TESTING_async_finish (&finish_state->ac); |
140 | return; | 153 | return; |
141 | } | 154 | } |
155 | /* add timeout */ | ||
142 | finish_state->finish_task | 156 | finish_state->finish_task |
143 | = GNUNET_SCHEDULER_add_delayed (finish_state->timeout, | 157 | = GNUNET_SCHEDULER_add_delayed (finish_state->timeout, |
144 | &timeout_finish, | 158 | &timeout_finish, |
145 | finish_state); | 159 | finish_state); |
146 | aac->cont = &done_finish; | 160 | /* back up old notification that we will override */ |
147 | aac->cont_cls = finish_state; | 161 | finish_state->old_notify = aac->notify_finished; |
162 | finish_state->old_notify_cls = aac->notify_finished_cls; | ||
163 | aac->notify_finished = &done_finish; | ||
164 | aac->notify_finished_cls = finish_state; | ||
148 | } | 165 | } |
149 | 166 | ||
150 | 167 | ||
@@ -168,24 +185,29 @@ cleanup_finish (void *cls) | |||
168 | 185 | ||
169 | 186 | ||
170 | const struct GNUNET_TESTING_Command | 187 | const struct GNUNET_TESTING_Command |
171 | GNUNET_TESTING_cmd_finish (const char *finish_label, | 188 | GNUNET_TESTING_cmd_finish ( |
172 | const char *cmd_ref, | 189 | const char *finish_label, |
173 | struct GNUNET_TIME_Relative timeout) | 190 | const char *cmd_ref, |
191 | struct GNUNET_TIME_Relative timeout) | ||
174 | { | 192 | { |
175 | struct FinishState *finish_state; | 193 | struct FinishState *finish_state; |
176 | 194 | ||
177 | finish_state = GNUNET_new (struct FinishState); | 195 | finish_state = GNUNET_new (struct FinishState); |
178 | finish_state->async_label = cmd_ref; | 196 | finish_state->async_label = cmd_ref; |
179 | finish_state->timeout = timeout; | 197 | finish_state->timeout = timeout; |
180 | return GNUNET_TESTING_command_new (finish_state, finish_label, | 198 | return GNUNET_TESTING_command_new_ac ( |
181 | &run_finish, | 199 | finish_state, |
182 | &cleanup_finish, | 200 | finish_label, |
183 | NULL, &finish_state->ac); | 201 | &run_finish, |
202 | &cleanup_finish, | ||
203 | NULL, | ||
204 | &finish_state->ac); | ||
184 | } | 205 | } |
185 | 206 | ||
186 | 207 | ||
187 | struct GNUNET_TESTING_Command | 208 | struct GNUNET_TESTING_Command |
188 | GNUNET_TESTING_cmd_make_unblocking (struct GNUNET_TESTING_Command cmd) | 209 | GNUNET_TESTING_cmd_make_unblocking ( |
210 | struct GNUNET_TESTING_Command cmd) | ||
189 | { | 211 | { |
190 | /* do not permit this function to be used on | 212 | /* do not permit this function to be used on |
191 | a finish command! */ | 213 | a finish command! */ |
diff --git a/src/lib/testing/testing_api_cmd_get_topo.c b/src/lib/testing/testing_api_cmd_get_topo.c new file mode 100644 index 000000000..486278489 --- /dev/null +++ b/src/lib/testing/testing_api_cmd_get_topo.c | |||
@@ -0,0 +1,214 @@ | |||
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_get_topo.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 "testing_api_topology.h" | ||
29 | |||
30 | /** | ||
31 | * Generic logging shortcut | ||
32 | */ | ||
33 | #define LOG(kind, ...) GNUNET_log_from (kind, "udp-backchannel",__VA_ARGS__) | ||
34 | |||
35 | struct TopologyState | ||
36 | { | ||
37 | /** | ||
38 | * The label of the command. | ||
39 | */ | ||
40 | const char *label; | ||
41 | |||
42 | /** | ||
43 | * The topology we parsed. | ||
44 | */ | ||
45 | struct GNUNET_TESTING_NetjailTopology *topology; | ||
46 | |||
47 | /** | ||
48 | * A string with the name of the topology file, if @e read_file is true, | ||
49 | * otherwise a string containing the topology data. | ||
50 | */ | ||
51 | const char *topology_string; | ||
52 | |||
53 | /** | ||
54 | * Same as @e topology_string, but set if we need | ||
55 | * to release the memory. | ||
56 | */ | ||
57 | char *topology_alloc; | ||
58 | |||
59 | /** | ||
60 | * A string with the name of the topology file. | ||
61 | */ | ||
62 | const char *file_name; | ||
63 | }; | ||
64 | |||
65 | /** | ||
66 | * The cleanup function of this cmd frees resources the cmd allocated. | ||
67 | * | ||
68 | */ | ||
69 | static void | ||
70 | cleanup (void *cls) | ||
71 | { | ||
72 | struct TopologyState *ts = cls; | ||
73 | |||
74 | if (NULL != ts->topology) | ||
75 | { | ||
76 | GNUNET_TESTING_free_topology (ts->topology); | ||
77 | ts->topology = NULL; | ||
78 | } | ||
79 | GNUNET_free (ts->topology_alloc); | ||
80 | GNUNET_free (ts); | ||
81 | } | ||
82 | |||
83 | |||
84 | /** | ||
85 | * This function prepares an array with traits. | ||
86 | */ | ||
87 | static enum GNUNET_GenericReturnValue | ||
88 | traits (void *cls, | ||
89 | const void **ret, | ||
90 | const char *trait, | ||
91 | unsigned int index) | ||
92 | { | ||
93 | struct TopologyState *ts = cls; | ||
94 | struct GNUNET_TESTING_Trait traits[] = { | ||
95 | GNUNET_TESTING_make_trait_topology (ts->topology), | ||
96 | GNUNET_TESTING_make_trait_topology_string (ts->topology_string), | ||
97 | GNUNET_TESTING_trait_end () | ||
98 | }; | ||
99 | |||
100 | return GNUNET_TESTING_get_trait (traits, | ||
101 | ret, | ||
102 | trait, | ||
103 | index); | ||
104 | } | ||
105 | |||
106 | |||
107 | static char * | ||
108 | get_topo_string_from_file (const char *topology_data_file) | ||
109 | { | ||
110 | uint64_t fs; | ||
111 | char *data; | ||
112 | |||
113 | if (GNUNET_YES != | ||
114 | GNUNET_DISK_file_test (topology_data_file)) | ||
115 | { | ||
116 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
117 | "Topology file %s not found\n", | ||
118 | topology_data_file); | ||
119 | return NULL; | ||
120 | } | ||
121 | if (GNUNET_OK != | ||
122 | GNUNET_DISK_file_size (topology_data_file, | ||
123 | &fs, | ||
124 | GNUNET_YES, | ||
125 | GNUNET_YES)) | ||
126 | { | ||
127 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
128 | "Could not determine size of topology file %s\n", | ||
129 | topology_data_file); | ||
130 | return NULL; | ||
131 | } | ||
132 | data = GNUNET_malloc_large (fs + 1); | ||
133 | GNUNET_assert (NULL != data); | ||
134 | if (fs != | ||
135 | GNUNET_DISK_fn_read (topology_data_file, | ||
136 | data, | ||
137 | fs)) | ||
138 | { | ||
139 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
140 | "Topology file %s cannot be read\n", | ||
141 | topology_data_file); | ||
142 | GNUNET_free (data); | ||
143 | return NULL; | ||
144 | } | ||
145 | return data; | ||
146 | } | ||
147 | |||
148 | |||
149 | /** | ||
150 | * The run method starts the script which setup the network namespaces. | ||
151 | * | ||
152 | * @param cls closure. | ||
153 | * @param is interpreter state. | ||
154 | */ | ||
155 | static void | ||
156 | run (void *cls, | ||
157 | struct GNUNET_TESTING_Interpreter *is) | ||
158 | { | ||
159 | struct TopologyState *ts = cls; | ||
160 | |||
161 | if (NULL == ts->topology_string) | ||
162 | { | ||
163 | ts->topology_alloc | ||
164 | = get_topo_string_from_file (ts->file_name); | ||
165 | if (NULL == ts->topology_alloc) | ||
166 | GNUNET_TESTING_FAIL (is); | ||
167 | ts->topology_string = ts->topology_alloc; | ||
168 | } | ||
169 | ts->topology | ||
170 | = GNUNET_TESTING_get_topo_from_string_ (ts->topology_string); | ||
171 | if (NULL == ts->topology) | ||
172 | GNUNET_TESTING_FAIL (is); | ||
173 | } | ||
174 | |||
175 | |||
176 | struct GNUNET_TESTING_Command | ||
177 | GNUNET_TESTING_cmd_load_topology_from_file ( | ||
178 | const char *label, | ||
179 | const char *file_name) | ||
180 | { | ||
181 | struct TopologyState *ts; | ||
182 | |||
183 | ts = GNUNET_new (struct TopologyState); | ||
184 | ts->label = label; | ||
185 | ts->file_name = file_name; | ||
186 | return GNUNET_TESTING_command_new_ac ( | ||
187 | ts, | ||
188 | label, | ||
189 | &run, | ||
190 | &cleanup, | ||
191 | traits, | ||
192 | NULL); | ||
193 | } | ||
194 | |||
195 | |||
196 | struct GNUNET_TESTING_Command | ||
197 | GNUNET_TESTING_cmd_load_topology_from_string ( | ||
198 | const char *label, | ||
199 | const char *topology_string) | ||
200 | { | ||
201 | struct TopologyState *ts; | ||
202 | |||
203 | GNUNET_assert (NULL != topology_string); | ||
204 | ts = GNUNET_new (struct TopologyState); | ||
205 | ts->label = label; | ||
206 | ts->topology_string = topology_string; | ||
207 | return GNUNET_TESTING_command_new_ac ( | ||
208 | ts, | ||
209 | label, | ||
210 | &run, | ||
211 | &cleanup, | ||
212 | traits, | ||
213 | NULL); | ||
214 | } | ||
diff --git a/src/service/testing/testing_api_cmd_netjail_start.c b/src/lib/testing/testing_api_cmd_netjail_start.c index f45ab939b..8a84b2769 100644 --- a/src/service/testing/testing_api_cmd_netjail_start.c +++ b/src/lib/testing/testing_api_cmd_netjail_start.c | |||
@@ -25,12 +25,8 @@ | |||
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_testing_ng_lib.h" | 28 | #include "gnunet_testing_lib.h" |
29 | #include "gnunet_testing_plugin.h" | 29 | #include "testing_api_topology.h" |
30 | #include "gnunet_testing_barrier.h" | ||
31 | #include "gnunet_testing_netjail_lib.h" | ||
32 | |||
33 | #define NETJAIL_START_SCRIPT "netjail_start.sh" | ||
34 | 30 | ||
35 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | 31 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) |
36 | 32 | ||
@@ -45,7 +41,6 @@ struct NetJailState | |||
45 | */ | 41 | */ |
46 | struct GNUNET_TESTING_AsyncContext ac; | 42 | struct GNUNET_TESTING_AsyncContext ac; |
47 | 43 | ||
48 | // Child Wait handle | ||
49 | struct GNUNET_ChildWaitHandle *cwh; | 44 | struct GNUNET_ChildWaitHandle *cwh; |
50 | 45 | ||
51 | /** | 46 | /** |
@@ -56,12 +51,13 @@ struct NetJailState | |||
56 | /** | 51 | /** |
57 | * Configuration file for the test topology. | 52 | * Configuration file for the test topology. |
58 | */ | 53 | */ |
59 | char *topology_config; | 54 | const char *topology_cmd_label; |
60 | 55 | ||
61 | /** | 56 | /** |
62 | * Shall we read the topology from file, or from a string. | 57 | * Start or stop? |
63 | */ | 58 | */ |
64 | unsigned int *read_file; | 59 | const char *script; |
60 | |||
65 | }; | 61 | }; |
66 | 62 | ||
67 | 63 | ||
@@ -76,18 +72,13 @@ netjail_start_cleanup (void *cls) | |||
76 | 72 | ||
77 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 73 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
78 | "netjail_start_cleanup!\n"); | 74 | "netjail_start_cleanup!\n"); |
79 | |||
80 | if (NULL != ns->cwh) | 75 | if (NULL != ns->cwh) |
81 | { | 76 | { |
82 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
83 | "Cancel child\n"); | ||
84 | GNUNET_wait_child_cancel (ns->cwh); | 77 | GNUNET_wait_child_cancel (ns->cwh); |
85 | ns->cwh = NULL; | 78 | ns->cwh = NULL; |
86 | } | 79 | } |
87 | if (NULL != ns->start_proc) | 80 | if (NULL != ns->start_proc) |
88 | { | 81 | { |
89 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
90 | "Kill process\n"); | ||
91 | GNUNET_assert (0 == | 82 | GNUNET_assert (0 == |
92 | GNUNET_OS_process_kill (ns->start_proc, | 83 | GNUNET_OS_process_kill (ns->start_proc, |
93 | SIGKILL)); | 84 | SIGKILL)); |
@@ -102,29 +93,27 @@ netjail_start_cleanup (void *cls) | |||
102 | 93 | ||
103 | /** | 94 | /** |
104 | * Callback which will be called if the setup script finished. | 95 | * Callback which will be called if the setup script finished. |
105 | * | ||
106 | */ | 96 | */ |
107 | static void | 97 | static void |
108 | child_completed_callback (void *cls, | 98 | child_completed_callback (void *cls, |
109 | enum GNUNET_OS_ProcessStatusType type, | 99 | enum GNUNET_OS_ProcessStatusType type, |
110 | long unsigned int exit_code) | 100 | unsigned long int exit_code) |
111 | { | 101 | { |
112 | struct NetJailState *ns = cls; | 102 | struct NetJailState *ns = cls; |
113 | 103 | ||
114 | GNUNET_OS_process_destroy (ns->start_proc); | 104 | GNUNET_OS_process_destroy (ns->start_proc); |
115 | ns->start_proc = NULL; | 105 | ns->start_proc = NULL; |
116 | ns->cwh = NULL; | 106 | ns->cwh = NULL; |
117 | if (0 == exit_code) | 107 | if ( (GNUNET_OS_PROCESS_EXITED != type) || |
118 | { | 108 | (0 != exit_code) ) |
119 | GNUNET_TESTING_async_finish (&ns->ac); | ||
120 | } | ||
121 | else | ||
122 | { | 109 | { |
123 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 110 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
124 | "Child failed with error %lu!\n", | 111 | "Child failed with error %lu!\n", |
125 | exit_code); | 112 | exit_code); |
126 | GNUNET_TESTING_async_fail (&ns->ac); | 113 | GNUNET_TESTING_async_fail (&ns->ac); |
114 | return; | ||
127 | } | 115 | } |
116 | GNUNET_TESTING_async_finish (&ns->ac); | ||
128 | } | 117 | } |
129 | 118 | ||
130 | 119 | ||
@@ -139,31 +128,37 @@ netjail_start_run (void *cls, | |||
139 | struct GNUNET_TESTING_Interpreter *is) | 128 | struct GNUNET_TESTING_Interpreter *is) |
140 | { | 129 | { |
141 | struct NetJailState *ns = cls; | 130 | struct NetJailState *ns = cls; |
131 | const struct GNUNET_TESTING_Command *topo_cmd; | ||
142 | char pid[15]; | 132 | char pid[15]; |
143 | enum GNUNET_GenericReturnValue helper_check; | 133 | enum GNUNET_GenericReturnValue helper_check; |
144 | char *data_dir; | 134 | char *data_dir; |
145 | char *script_name; | 135 | char *script_name; |
146 | char *read_file; | 136 | const char *topology_data; |
147 | 137 | ||
138 | topo_cmd = GNUNET_TESTING_interpreter_lookup_command ( | ||
139 | is, | ||
140 | ns->topology_cmd_label); | ||
141 | if (NULL == topo_cmd) | ||
142 | GNUNET_TESTING_FAIL (is); | ||
143 | if (GNUNET_OK != | ||
144 | GNUNET_TESTING_get_trait_topology_string (topo_cmd, | ||
145 | &topology_data)) | ||
146 | GNUNET_TESTING_FAIL (is); | ||
148 | data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); | 147 | data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); |
149 | GNUNET_asprintf (&script_name, "%s%s", data_dir, NETJAIL_START_SCRIPT); | 148 | GNUNET_asprintf (&script_name, |
150 | GNUNET_asprintf (&read_file, "%u", *(ns->read_file)); | 149 | "%s%s", |
151 | 150 | data_dir, | |
151 | ns->script); | ||
152 | helper_check = GNUNET_OS_check_helper_binary ( | 152 | helper_check = GNUNET_OS_check_helper_binary ( |
153 | script_name, | 153 | script_name, |
154 | GNUNET_YES, | 154 | true, |
155 | NULL); | 155 | NULL); |
156 | |||
157 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
158 | "script_name %s\n", | ||
159 | script_name); | ||
160 | |||
161 | if (GNUNET_NO == helper_check) | 156 | if (GNUNET_NO == helper_check) |
162 | { | 157 | { |
163 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 158 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
164 | "No SUID for %s!\n", | 159 | "No SUID for %s!\n", |
165 | script_name); | 160 | script_name); |
166 | GNUNET_TESTING_interpreter_fail (is); | 161 | GNUNET_TESTING_interpreter_skip (is); |
167 | return; | 162 | return; |
168 | } | 163 | } |
169 | if (GNUNET_SYSERR == helper_check) | 164 | if (GNUNET_SYSERR == helper_check) |
@@ -171,7 +166,7 @@ netjail_start_run (void *cls, | |||
171 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 166 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
172 | "%s not found!\n", | 167 | "%s not found!\n", |
173 | script_name); | 168 | script_name); |
174 | GNUNET_TESTING_interpreter_fail (is); | 169 | GNUNET_TESTING_interpreter_skip (is); |
175 | return; | 170 | return; |
176 | } | 171 | } |
177 | 172 | ||
@@ -182,9 +177,8 @@ netjail_start_run (void *cls, | |||
182 | { | 177 | { |
183 | char *const script_argv[] = { | 178 | char *const script_argv[] = { |
184 | script_name, | 179 | script_name, |
185 | ns->topology_config, | 180 | (char *) topology_data, |
186 | pid, | 181 | "0", |
187 | read_file, | ||
188 | NULL | 182 | NULL |
189 | }; | 183 | }; |
190 | 184 | ||
@@ -201,31 +195,27 @@ netjail_start_run (void *cls, | |||
201 | &child_completed_callback, | 195 | &child_completed_callback, |
202 | ns); | 196 | ns); |
203 | GNUNET_break (NULL != ns->cwh); | 197 | GNUNET_break (NULL != ns->cwh); |
204 | GNUNET_free (read_file); | ||
205 | GNUNET_free (script_name); | 198 | GNUNET_free (script_name); |
206 | GNUNET_free (data_dir); | 199 | GNUNET_free (data_dir); |
207 | } | 200 | } |
208 | 201 | ||
209 | 202 | ||
210 | /** | ||
211 | * Create command. | ||
212 | * | ||
213 | * @param label name for command. | ||
214 | * @param topology_config Configuration file for the test topology. | ||
215 | * @return command. | ||
216 | */ | ||
217 | struct GNUNET_TESTING_Command | 203 | struct GNUNET_TESTING_Command |
218 | GNUNET_TESTING_cmd_netjail_start (const char *label, | 204 | GNUNET_TESTING_cmd_netjail_setup ( |
219 | char *topology_config, | 205 | const char *label, |
220 | unsigned int *read_file) | 206 | const char *script, |
207 | const char *topology_cmd_label) | ||
221 | { | 208 | { |
222 | struct NetJailState *ns; | 209 | struct NetJailState *ns; |
223 | 210 | ||
224 | ns = GNUNET_new (struct NetJailState); | 211 | ns = GNUNET_new (struct NetJailState); |
225 | ns->topology_config = topology_config; | 212 | ns->script = script; |
226 | ns->read_file = read_file; | 213 | ns->topology_cmd_label = topology_cmd_label; |
227 | return GNUNET_TESTING_command_new (ns, label, | 214 | return GNUNET_TESTING_command_new_ac ( |
228 | &netjail_start_run, | 215 | ns, |
229 | &netjail_start_cleanup, | 216 | label, |
230 | NULL, &ns->ac); | 217 | &netjail_start_run, |
218 | &netjail_start_cleanup, | ||
219 | NULL, | ||
220 | &ns->ac); | ||
231 | } | 221 | } |
diff --git a/src/lib/testing/testing_api_cmd_netjail_start_cmds_helper.c b/src/lib/testing/testing_api_cmd_netjail_start_cmds_helper.c new file mode 100644 index 000000000..dcfa40b7c --- /dev/null +++ b/src/lib/testing/testing_api_cmd_netjail_start_cmds_helper.c | |||
@@ -0,0 +1,586 @@ | |||
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 | * @file testing/testing_api_cmd_netjail_start_cmds_helper.c | ||
22 | * @brief Command to start the netjail peers. | ||
23 | * @author t3sserakt | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include "gnunet_testing_lib.h" | ||
28 | #include "testing_api_barrier.h" | ||
29 | #include "testing_api_loop.h" | ||
30 | #include "testing_cmds.h" | ||
31 | #include "testing_api_topology.h" | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Generic logging shortcut | ||
36 | */ | ||
37 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | ||
38 | |||
39 | |||
40 | /** | ||
41 | * Struct containing the number of the netjail node and the NetJailState which | ||
42 | * will be handed to callbacks specific to a test environment. | ||
43 | */ | ||
44 | struct TestingSystemCount; | ||
45 | |||
46 | |||
47 | /** | ||
48 | * Struct to store information handed over to callbacks. | ||
49 | */ | ||
50 | struct NetJailState | ||
51 | { | ||
52 | /** | ||
53 | * Global state of the interpreter, used by a command | ||
54 | * to access information about other commands. | ||
55 | */ | ||
56 | struct GNUNET_TESTING_Interpreter *is; | ||
57 | |||
58 | /** | ||
59 | * Context for our asynchronous completion. | ||
60 | */ | ||
61 | struct GNUNET_TESTING_AsyncContext ac; | ||
62 | |||
63 | /** | ||
64 | * Command with topology data. | ||
65 | */ | ||
66 | const char *topology_cmd_label; | ||
67 | |||
68 | /** | ||
69 | * Array with handles of helper processes. | ||
70 | */ | ||
71 | struct GNUNET_HELPER_Handle **helpers; | ||
72 | |||
73 | /** | ||
74 | * Time after this cmd has to finish. | ||
75 | */ | ||
76 | struct GNUNET_TIME_Relative timeout; | ||
77 | |||
78 | /** | ||
79 | * Timeout task. | ||
80 | */ | ||
81 | struct GNUNET_SCHEDULER_Task *timeout_task; | ||
82 | |||
83 | /** | ||
84 | * Kept in a DLL. | ||
85 | */ | ||
86 | struct TestingSystemCount *tbc_head; | ||
87 | |||
88 | /** | ||
89 | * Kept in a DLL. | ||
90 | */ | ||
91 | struct TestingSystemCount *tbc_tail; | ||
92 | |||
93 | /** | ||
94 | * Data about our topology as a string. | ||
95 | */ | ||
96 | const char *topology_data; | ||
97 | |||
98 | /** | ||
99 | * Size of the array @e helpers. | ||
100 | */ | ||
101 | unsigned int n_helpers; | ||
102 | |||
103 | /** | ||
104 | * Counts number of helpers that finished. | ||
105 | */ | ||
106 | unsigned int n_finished; | ||
107 | |||
108 | /** | ||
109 | * Set to true if we already failed the command. | ||
110 | */ | ||
111 | bool failed; | ||
112 | }; | ||
113 | |||
114 | /** | ||
115 | * Struct containing the number of the netjail node and the NetJailState which | ||
116 | * will be handed to callbacks specific to a test environment. | ||
117 | */ | ||
118 | struct TestingSystemCount | ||
119 | { | ||
120 | |||
121 | /** | ||
122 | * Kept in a DLL. | ||
123 | */ | ||
124 | struct TestingSystemCount *next; | ||
125 | |||
126 | /** | ||
127 | * Kept in a DLL. | ||
128 | */ | ||
129 | struct TestingSystemCount *prev; | ||
130 | |||
131 | /** | ||
132 | * The send handle for the helper | ||
133 | */ | ||
134 | struct GNUNET_HELPER_SendHandle *shandle; | ||
135 | |||
136 | /** | ||
137 | * Struct to store information handed over to callbacks. | ||
138 | */ | ||
139 | struct NetJailState *ns; | ||
140 | |||
141 | |||
142 | }; | ||
143 | |||
144 | |||
145 | /** | ||
146 | * Continuation function from GNUNET_HELPER_send() | ||
147 | * | ||
148 | * @param cls closure | ||
149 | * @param result #GNUNET_OK on success, | ||
150 | * #GNUNET_NO if helper process died | ||
151 | * #GNUNET_SYSERR during GNUNET_HELPER_stop | ||
152 | */ | ||
153 | static void | ||
154 | clear_msg (void *cls, | ||
155 | enum GNUNET_GenericReturnValue result) | ||
156 | { | ||
157 | struct TestingSystemCount *tbc = cls; | ||
158 | struct NetJailState *ns = tbc->ns; | ||
159 | |||
160 | GNUNET_assert (NULL != tbc->shandle); | ||
161 | tbc->shandle = NULL; | ||
162 | GNUNET_CONTAINER_DLL_remove (ns->tbc_head, | ||
163 | ns->tbc_tail, | ||
164 | tbc); | ||
165 | GNUNET_free (tbc); | ||
166 | if ( (! ns->failed) && | ||
167 | (GNUNET_OK != result) ) | ||
168 | { | ||
169 | ns->failed = true; | ||
170 | GNUNET_TESTING_FAIL (ns->is); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | |||
175 | static void | ||
176 | handle_helper_barrier_reached ( | ||
177 | void *cls, | ||
178 | const struct GNUNET_TESTING_CommandBarrierReached *rm) | ||
179 | { | ||
180 | struct NetJailState *ns = cls; | ||
181 | struct GNUNET_TESTING_Barrier *barrier; | ||
182 | |||
183 | barrier = GNUNET_TESTING_get_barrier2_ (ns->is, | ||
184 | &rm->barrier_key); | ||
185 | if (NULL == barrier) | ||
186 | { | ||
187 | if (! ns->failed) | ||
188 | { | ||
189 | ns->failed = true; | ||
190 | GNUNET_TESTING_async_fail (&ns->ac); | ||
191 | } | ||
192 | return; | ||
193 | } | ||
194 | if (barrier->inherited) | ||
195 | { | ||
196 | /* pass on to parent */ | ||
197 | GNUNET_TESTING_loop_notify_parent_ (ns->is, | ||
198 | &rm->header); | ||
199 | } | ||
200 | else | ||
201 | { | ||
202 | barrier->reached++; | ||
203 | if (barrier->reached == barrier->expected_reaches) | ||
204 | { | ||
205 | struct GNUNET_TESTING_CommandBarrierSatisfied cbs = { | ||
206 | .header.size | ||
207 | = htons (sizeof (cbs)), | ||
208 | .header.type | ||
209 | = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_CROSSABLE), | ||
210 | .barrier_key | ||
211 | = rm->barrier_key | ||
212 | }; | ||
213 | |||
214 | GNUNET_assert (! barrier->satisfied); | ||
215 | barrier->satisfied = true; | ||
216 | /* unblock children */ | ||
217 | GNUNET_TESTING_loop_notify_children_ (ns->is, | ||
218 | &cbs.header); | ||
219 | /* unblock self */ | ||
220 | for (unsigned int i = 0; i<barrier->cnt_waiting; i++) | ||
221 | GNUNET_TESTING_async_finish (barrier->waiting[i]); | ||
222 | GNUNET_array_grow (barrier->waiting, | ||
223 | barrier->cnt_waiting, | ||
224 | 0); | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | |||
229 | |||
230 | static void | ||
231 | handle_helper_local_finished ( | ||
232 | void *cls, | ||
233 | const struct GNUNET_TESTING_CommandLocalFinished *lf) | ||
234 | { | ||
235 | struct NetJailState *ns = cls; | ||
236 | |||
237 | ns->n_finished++; | ||
238 | if ( (! ns->failed) && | ||
239 | (GNUNET_OK != ntohl (lf->rv)) ) | ||
240 | { | ||
241 | ns->failed = true; | ||
242 | GNUNET_TESTING_async_fail (&ns->ac); | ||
243 | return; | ||
244 | } | ||
245 | if (ns->n_finished == ns->n_helpers) | ||
246 | { | ||
247 | GNUNET_SCHEDULER_cancel (ns->timeout_task); | ||
248 | ns->timeout_task = NULL; | ||
249 | GNUNET_TESTING_async_finish (&ns->ac); | ||
250 | } | ||
251 | } | ||
252 | |||
253 | |||
254 | /** | ||
255 | * Functions with this signature are called whenever a | ||
256 | * complete message is received by the tokenizer. | ||
257 | * | ||
258 | * Do not call GNUNET_SERVER_mst_destroy in callback | ||
259 | * | ||
260 | * @param cls closure | ||
261 | * @param message the actual message | ||
262 | * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing | ||
263 | */ | ||
264 | static enum GNUNET_GenericReturnValue | ||
265 | helper_mst (void *cls, | ||
266 | const struct GNUNET_MessageHeader *message) | ||
267 | { | ||
268 | struct NetJailState *ns = cls; | ||
269 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
270 | GNUNET_MQ_hd_fixed_size ( | ||
271 | helper_barrier_reached, | ||
272 | GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_REACHED, | ||
273 | struct GNUNET_TESTING_CommandBarrierReached, | ||
274 | ns), | ||
275 | GNUNET_MQ_hd_fixed_size ( | ||
276 | helper_local_finished, | ||
277 | GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED, | ||
278 | struct GNUNET_TESTING_CommandLocalFinished, | ||
279 | ns), | ||
280 | GNUNET_MQ_handler_end () | ||
281 | }; | ||
282 | enum GNUNET_GenericReturnValue ret; | ||
283 | |||
284 | ret = GNUNET_MQ_handle_message (handlers, | ||
285 | message); | ||
286 | if (GNUNET_OK != ret) | ||
287 | { | ||
288 | GNUNET_break (0); | ||
289 | if (! ns->failed) | ||
290 | { | ||
291 | ns->failed = true; | ||
292 | GNUNET_TESTING_async_fail (&ns->ac); | ||
293 | } | ||
294 | } | ||
295 | return ret; | ||
296 | } | ||
297 | |||
298 | |||
299 | /** | ||
300 | * Callback called if there was an exception during execution of the helper. | ||
301 | */ | ||
302 | static void | ||
303 | exp_cb (void *cls) | ||
304 | { | ||
305 | struct NetJailState *ns = cls; | ||
306 | |||
307 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
308 | "Called exp_cb.\n"); | ||
309 | if (NULL != ns->timeout_task) | ||
310 | { | ||
311 | GNUNET_SCHEDULER_cancel (ns->timeout_task); | ||
312 | ns->timeout_task = NULL; | ||
313 | } | ||
314 | if (! ns->failed) | ||
315 | GNUNET_TESTING_async_fail (&ns->ac); | ||
316 | } | ||
317 | |||
318 | |||
319 | static enum GNUNET_GenericReturnValue | ||
320 | add_barrier (void *cls, | ||
321 | const struct GNUNET_ShortHashCode *key, | ||
322 | void *value) | ||
323 | { | ||
324 | struct GNUNET_ShortHashCode **bar_posp = cls; | ||
325 | struct GNUNET_ShortHashCode *bar_pos = *bar_posp; | ||
326 | |||
327 | *bar_pos = *key; | ||
328 | *bar_posp = bar_pos + 1; | ||
329 | return GNUNET_OK; | ||
330 | } | ||
331 | |||
332 | |||
333 | /** | ||
334 | * @return true on success | ||
335 | */ | ||
336 | static bool | ||
337 | send_start_messages (struct NetJailState *ns, | ||
338 | struct GNUNET_HELPER_Handle *helper) | ||
339 | { | ||
340 | struct GNUNET_TESTING_CommandHelperInit *msg; | ||
341 | struct TestingSystemCount *tbc; | ||
342 | struct GNUNET_ShortHashCode *bar; | ||
343 | struct GNUNET_ShortHashCode *bar_pos; | ||
344 | unsigned int num_barriers = GNUNET_TESTING_barrier_count_ (ns->is); | ||
345 | size_t topo_length; | ||
346 | size_t msg_len; | ||
347 | |||
348 | topo_length = strlen (ns->topology_data) + 1; | ||
349 | GNUNET_assert (topo_length < SIZE_MAX - sizeof (*msg)); | ||
350 | GNUNET_assert (SIZE_MAX / sizeof (struct GNUNET_ShortHashCode) > | ||
351 | num_barriers); | ||
352 | GNUNET_assert (sizeof (*msg) + topo_length < | ||
353 | SIZE_MAX | ||
354 | - num_barriers * sizeof (struct GNUNET_ShortHashCode)); | ||
355 | msg_len = sizeof (*msg) + topo_length | ||
356 | + num_barriers * sizeof (struct GNUNET_ShortHashCode); | ||
357 | if (msg_len > UINT16_MAX) | ||
358 | { | ||
359 | /* ask a wizzard to enhance the protocol; | ||
360 | start with gzip topology_data? multiple | ||
361 | init messages for barriers + topo data, | ||
362 | etc.*/ | ||
363 | GNUNET_break (0); | ||
364 | return false; | ||
365 | } | ||
366 | msg = GNUNET_malloc (msg_len); | ||
367 | msg->header.size = htons ((uint16_t) msg_len); | ||
368 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT); | ||
369 | bar = (struct GNUNET_ShortHashCode *) &msg[1]; | ||
370 | bar_pos = bar; | ||
371 | GNUNET_TESTING_barrier_iterate_ (ns->is, | ||
372 | &add_barrier, | ||
373 | &bar_pos); | ||
374 | GNUNET_assert (bar_pos == &bar[num_barriers]); | ||
375 | memcpy (&bar[num_barriers], | ||
376 | ns->topology_data, | ||
377 | topo_length); | ||
378 | tbc = GNUNET_new (struct TestingSystemCount); | ||
379 | tbc->ns = ns; | ||
380 | tbc->shandle = GNUNET_HELPER_send ( | ||
381 | helper, | ||
382 | &msg->header, | ||
383 | GNUNET_NO, | ||
384 | &clear_msg, | ||
385 | tbc); | ||
386 | GNUNET_free (msg); | ||
387 | if (NULL == tbc->shandle) | ||
388 | { | ||
389 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
390 | "Send handle is NULL!\n"); | ||
391 | GNUNET_free (tbc); | ||
392 | return false; | ||
393 | } | ||
394 | GNUNET_CONTAINER_DLL_insert (ns->tbc_head, | ||
395 | ns->tbc_tail, | ||
396 | tbc); | ||
397 | return true; | ||
398 | } | ||
399 | |||
400 | |||
401 | /** | ||
402 | * Function which start a single helper process. | ||
403 | * @return true on success | ||
404 | */ | ||
405 | static bool | ||
406 | start_helper (struct NetJailState *ns, | ||
407 | unsigned int script_num) | ||
408 | { | ||
409 | char *gnunet_cmds_helper | ||
410 | = GNUNET_OS_get_libexec_binary_path (HELPER_CMDS_BINARY); | ||
411 | char node_id[32]; | ||
412 | char *const script_argv[] = { | ||
413 | "ip", | ||
414 | "netns", | ||
415 | "exec", | ||
416 | node_id, | ||
417 | gnunet_cmds_helper, | ||
418 | node_id, | ||
419 | NULL | ||
420 | }; | ||
421 | struct GNUNET_HELPER_Handle *helper; | ||
422 | |||
423 | GNUNET_snprintf (node_id, | ||
424 | sizeof (node_id), | ||
425 | "if%06x-%06x\n", | ||
426 | (unsigned int) getpid (), | ||
427 | script_num); | ||
428 | helper = GNUNET_HELPER_start ( | ||
429 | GNUNET_YES, /* with control pipe */ | ||
430 | script_argv[0], | ||
431 | script_argv, | ||
432 | &helper_mst, | ||
433 | &exp_cb, | ||
434 | ns); | ||
435 | GNUNET_free (gnunet_cmds_helper); | ||
436 | if (NULL == helper) | ||
437 | { | ||
438 | GNUNET_break (0); | ||
439 | return false; | ||
440 | } | ||
441 | GNUNET_array_append (ns->helpers, | ||
442 | ns->n_helpers, | ||
443 | helper); | ||
444 | GNUNET_TESTING_add_netjail_helper_ (ns->is, | ||
445 | helper); | ||
446 | return send_start_messages (ns, | ||
447 | helper); | ||
448 | } | ||
449 | |||
450 | |||
451 | /** | ||
452 | * Function run when the cmd terminates (good or bad) with timeout. | ||
453 | * | ||
454 | * @param cls the interpreter state | ||
455 | */ | ||
456 | static void | ||
457 | do_timeout (void *cls) | ||
458 | { | ||
459 | struct NetJailState *ns = cls; | ||
460 | |||
461 | ns->timeout_task = NULL; | ||
462 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
463 | "Terminating cmd due to global timeout\n"); | ||
464 | GNUNET_TESTING_async_finish (&ns->ac); | ||
465 | } | ||
466 | |||
467 | |||
468 | /** | ||
469 | * This function starts a helper process for each node. | ||
470 | * | ||
471 | * @param cls closure. | ||
472 | * @param cmd CMD being run. | ||
473 | * @param is interpreter state. | ||
474 | */ | ||
475 | static void | ||
476 | netjail_exec_run (void *cls, | ||
477 | struct GNUNET_TESTING_Interpreter *is) | ||
478 | { | ||
479 | struct NetJailState *ns = cls; | ||
480 | struct GNUNET_TESTING_NetjailTopology *topology; | ||
481 | bool failed = false; | ||
482 | const struct GNUNET_TESTING_Command *topo_cmd; | ||
483 | |||
484 | ns->is = is; | ||
485 | topo_cmd = GNUNET_TESTING_interpreter_lookup_command (is, | ||
486 | ns->topology_cmd_label); | ||
487 | if (NULL == topo_cmd) | ||
488 | GNUNET_TESTING_FAIL (is); | ||
489 | if (GNUNET_OK != | ||
490 | GNUNET_TESTING_get_trait_topology_string (topo_cmd, | ||
491 | &ns->topology_data)) | ||
492 | GNUNET_TESTING_FAIL (is); | ||
493 | topology | ||
494 | = GNUNET_TESTING_get_topo_from_string_ (ns->topology_data); | ||
495 | for (unsigned int i = 1; i <= topology->total; i++) | ||
496 | { | ||
497 | if (! start_helper (ns, | ||
498 | i)) | ||
499 | { | ||
500 | failed = true; | ||
501 | break; | ||
502 | } | ||
503 | } | ||
504 | GNUNET_TESTING_free_topology (topology); | ||
505 | if (failed) | ||
506 | { | ||
507 | ns->failed = true; | ||
508 | GNUNET_TESTING_FAIL (is); | ||
509 | } | ||
510 | ns->timeout_task | ||
511 | = GNUNET_SCHEDULER_add_delayed (ns->timeout, | ||
512 | &do_timeout, | ||
513 | ns); | ||
514 | } | ||
515 | |||
516 | |||
517 | /** | ||
518 | * Code to clean up resource this cmd used. | ||
519 | * | ||
520 | * @param cls closure | ||
521 | */ | ||
522 | static void | ||
523 | netjail_exec_cleanup (void *cls) | ||
524 | { | ||
525 | struct NetJailState *ns = cls; | ||
526 | |||
527 | if (NULL != ns->timeout_task) | ||
528 | { | ||
529 | GNUNET_SCHEDULER_cancel (ns->timeout_task); | ||
530 | ns->timeout_task = NULL; | ||
531 | } | ||
532 | for (unsigned int i = 0; i<ns->n_helpers; i++) | ||
533 | GNUNET_HELPER_stop (ns->helpers[i], | ||
534 | GNUNET_YES); | ||
535 | GNUNET_free (ns); | ||
536 | } | ||
537 | |||
538 | |||
539 | /** | ||
540 | * This function prepares an array with traits. | ||
541 | */ | ||
542 | static enum GNUNET_GenericReturnValue | ||
543 | netjail_exec_traits (void *cls, | ||
544 | const void **ret, | ||
545 | const char *trait, | ||
546 | unsigned int index) | ||
547 | { | ||
548 | struct NetJailState *ns = cls; | ||
549 | struct GNUNET_TESTING_Trait traits[] = { | ||
550 | GNUNET_TESTING_trait_end () | ||
551 | }; | ||
552 | |||
553 | (void) ns; | ||
554 | return GNUNET_TESTING_get_trait (traits, | ||
555 | ret, | ||
556 | trait, | ||
557 | index); | ||
558 | } | ||
559 | |||
560 | |||
561 | /** | ||
562 | * Create command. | ||
563 | * | ||
564 | * @param label Name for the command. | ||
565 | * @param topology_data topology data | ||
566 | * @param timeout Before this timeout is reached this cmd MUST finish. | ||
567 | * @return command. | ||
568 | */ | ||
569 | struct GNUNET_TESTING_Command | ||
570 | GNUNET_TESTING_cmd_netjail_start_helpers ( | ||
571 | const char *label, | ||
572 | const char *topology_cmd_label, | ||
573 | struct GNUNET_TIME_Relative timeout) | ||
574 | { | ||
575 | struct NetJailState *ns; | ||
576 | |||
577 | ns = GNUNET_new (struct NetJailState); | ||
578 | ns->topology_cmd_label = topology_cmd_label; | ||
579 | ns->timeout = timeout; | ||
580 | return GNUNET_TESTING_command_new_ac (ns, | ||
581 | label, | ||
582 | &netjail_exec_run, | ||
583 | &netjail_exec_cleanup, | ||
584 | &netjail_exec_traits, | ||
585 | &ns->ac); | ||
586 | } | ||
diff --git a/src/lib/testing/testing_api_cmd_signal.c b/src/lib/testing/testing_api_cmd_signal.c new file mode 100644 index 000000000..adbcda946 --- /dev/null +++ b/src/lib/testing/testing_api_cmd_signal.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | This file is part of GNUNET | ||
3 | (C) 2018 GNUnet e.V. | ||
4 | |||
5 | GNUNET is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as | ||
7 | published by the Free Software Foundation; either version 3, or | ||
8 | (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 | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public | ||
16 | License along with GNUNET; see the file COPYING. If not, see | ||
17 | <http://www.gnu.org/licenses/> | ||
18 | */ | ||
19 | /** | ||
20 | * @file testing/testing_api_cmd_signal.c | ||
21 | * @brief command(s) to send signals to processes. | ||
22 | * @author Marcello Stanisci | ||
23 | */ | ||
24 | #include "platform.h" | ||
25 | #include "gnunet_testing_lib.h" | ||
26 | |||
27 | |||
28 | /** | ||
29 | * State for a "signal" CMD. | ||
30 | */ | ||
31 | struct SignalState | ||
32 | { | ||
33 | /** | ||
34 | * Label of the process to send the signal to. | ||
35 | */ | ||
36 | const char *process_label; | ||
37 | |||
38 | /** | ||
39 | * The signal to send to the process. | ||
40 | */ | ||
41 | int signal; | ||
42 | }; | ||
43 | |||
44 | /** | ||
45 | * Run the command. | ||
46 | * | ||
47 | * @param cls closure. | ||
48 | * @param cmd the command to execute. | ||
49 | * @param is the interpreter state. | ||
50 | */ | ||
51 | static void | ||
52 | signal_run (void *cls, | ||
53 | struct GNUNET_TESTING_Interpreter *is) | ||
54 | { | ||
55 | struct SignalState *ss = cls; | ||
56 | const struct GNUNET_TESTING_Command *pcmd; | ||
57 | struct GNUNET_OS_Process **process; | ||
58 | |||
59 | pcmd | ||
60 | = GNUNET_TESTING_interpreter_lookup_command (is, | ||
61 | ss->process_label); | ||
62 | if (NULL == pcmd) | ||
63 | { | ||
64 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
65 | "Did not find command `%s'\n", | ||
66 | ss->process_label); | ||
67 | GNUNET_TESTING_FAIL (is); | ||
68 | } | ||
69 | if (GNUNET_OK != | ||
70 | GNUNET_TESTING_get_trait_process (pcmd, | ||
71 | &process)) | ||
72 | GNUNET_TESTING_FAIL (is); | ||
73 | GNUNET_break (0 == | ||
74 | GNUNET_OS_process_kill (*process, | ||
75 | ss->signal)); | ||
76 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
77 | "Signaling '%d'..\n", | ||
78 | ss->signal); | ||
79 | } | ||
80 | |||
81 | |||
82 | /** | ||
83 | * Cleanup the state from a "signal" CMD. | ||
84 | * | ||
85 | * @param cls closure. | ||
86 | */ | ||
87 | static void | ||
88 | signal_cleanup (void *cls) | ||
89 | { | ||
90 | struct SignalState *ss = cls; | ||
91 | |||
92 | GNUNET_free (ss); | ||
93 | } | ||
94 | |||
95 | |||
96 | /** | ||
97 | * Create a "signal" CMD. | ||
98 | * | ||
99 | * @param label command label. | ||
100 | * @param process handle to the process to signal. | ||
101 | * @param signal signal to send. | ||
102 | * @return the command. | ||
103 | */ | ||
104 | struct GNUNET_TESTING_Command | ||
105 | GNUNET_TESTING_cmd_signal ( | ||
106 | const char *label, | ||
107 | const char *process_label, | ||
108 | int signal) | ||
109 | { | ||
110 | struct SignalState *ss; | ||
111 | |||
112 | ss = GNUNET_new (struct SignalState); | ||
113 | ss->process_label = process_label; | ||
114 | ss->signal = signal; | ||
115 | return GNUNET_TESTING_command_new (ss, | ||
116 | label, | ||
117 | &signal_run, | ||
118 | &signal_cleanup, | ||
119 | NULL); | ||
120 | } | ||
diff --git a/src/lib/testing/testing_api_cmd_stat.c b/src/lib/testing/testing_api_cmd_stat.c new file mode 100644 index 000000000..f751a01d0 --- /dev/null +++ b/src/lib/testing/testing_api_cmd_stat.c | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2018, 2024 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as | ||
7 | published by the Free Software Foundation; either version 3, or | ||
8 | (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 | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public | ||
16 | License along with GNUnet; see the file COPYING. If not, see | ||
17 | <http://www.gnu.org/licenses/> | ||
18 | */ | ||
19 | /** | ||
20 | * @file testing/testing_api_cmd_stat.c | ||
21 | * @brief command(s) to get performance statistics on other commands | ||
22 | * @author Christian Grothoff | ||
23 | */ | ||
24 | #include "platform.h" | ||
25 | #include "gnunet_testing_lib.h" | ||
26 | #include "testing_api_cmd_batch.h" | ||
27 | |||
28 | /** | ||
29 | * Run a "stat" CMD. | ||
30 | * | ||
31 | * @param cls closure. | ||
32 | * @param is the interpreter state. | ||
33 | */ | ||
34 | static void | ||
35 | stat_run (void *cls, | ||
36 | struct GNUNET_TESTING_Interpreter *is); | ||
37 | |||
38 | |||
39 | /** | ||
40 | * Add the time @a cmd took to the respective duration in @a timings. | ||
41 | * | ||
42 | * @param timings where to add up times | ||
43 | * @param cmd command to evaluate | ||
44 | */ | ||
45 | static void | ||
46 | stat_cmd (struct GNUNET_TESTING_Timer *timings, | ||
47 | const struct GNUNET_TESTING_Command *cmd) | ||
48 | { | ||
49 | struct GNUNET_TIME_Relative duration; | ||
50 | struct GNUNET_TIME_Relative lat; | ||
51 | |||
52 | if (GNUNET_TIME_absolute_cmp (cmd->start_time, | ||
53 | >, | ||
54 | cmd->finish_time)) | ||
55 | { | ||
56 | /* This is a problem, except of course for | ||
57 | this command itself, as we clearly did not yet | ||
58 | finish... */ | ||
59 | if (cmd->run != &stat_run) | ||
60 | { | ||
61 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
62 | "Bad timings for `%s'\n", | ||
63 | cmd->label.value); | ||
64 | GNUNET_break (0); | ||
65 | } | ||
66 | return; | ||
67 | } | ||
68 | duration = GNUNET_TIME_absolute_get_difference (cmd->start_time, | ||
69 | cmd->finish_time); | ||
70 | lat = GNUNET_TIME_absolute_get_difference (cmd->last_req_time, | ||
71 | cmd->finish_time); | ||
72 | for (unsigned int i = 0; | ||
73 | NULL != timings[i].prefix; | ||
74 | i++) | ||
75 | { | ||
76 | if (0 == strncmp (timings[i].prefix, | ||
77 | cmd->label.value, | ||
78 | strlen (timings[i].prefix))) | ||
79 | { | ||
80 | timings[i].total_duration | ||
81 | = GNUNET_TIME_relative_add (duration, | ||
82 | timings[i].total_duration); | ||
83 | timings[i].success_latency | ||
84 | = GNUNET_TIME_relative_add (lat, | ||
85 | timings[i].success_latency); | ||
86 | timings[i].num_commands++; | ||
87 | timings[i].num_retries += cmd->num_tries; | ||
88 | break; | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | |||
93 | |||
94 | /** | ||
95 | * Obtain statistics for @a timings of @a cmd | ||
96 | * | ||
97 | * @param[in,out] cls what timings to get | ||
98 | * @param cmd command to process | ||
99 | */ | ||
100 | static void | ||
101 | do_stat (void *cls, | ||
102 | const struct GNUNET_TESTING_Command *cmd) | ||
103 | { | ||
104 | struct GNUNET_TESTING_Timer *timings = cls; | ||
105 | |||
106 | if (GNUNET_TESTING_cmd_is_batch_ (cmd)) | ||
107 | { | ||
108 | struct GNUNET_TESTING_Command **bcmd; | ||
109 | |||
110 | if (GNUNET_OK != | ||
111 | GNUNET_TESTING_get_trait_batch_cmds (cmd, | ||
112 | &bcmd)) | ||
113 | { | ||
114 | GNUNET_break (0); | ||
115 | return; | ||
116 | } | ||
117 | for (unsigned int j = 0; | ||
118 | NULL != (*bcmd)[j].run; | ||
119 | j++) | ||
120 | do_stat (timings, | ||
121 | &(*bcmd)[j]); | ||
122 | return; | ||
123 | } | ||
124 | stat_cmd (timings, | ||
125 | cmd); | ||
126 | } | ||
127 | |||
128 | |||
129 | /** | ||
130 | * Run a "stat" CMD. | ||
131 | * | ||
132 | * @param cls closure. | ||
133 | * @param cmd the command being run. | ||
134 | * @param is the interpreter state. | ||
135 | */ | ||
136 | static void | ||
137 | stat_run (void *cls, | ||
138 | struct GNUNET_TESTING_Interpreter *is) | ||
139 | { | ||
140 | struct GNUNET_TESTING_Timer *timings = cls; | ||
141 | |||
142 | GNUNET_TESTING_interpreter_commands_iterate (is, | ||
143 | true, | ||
144 | &do_stat, | ||
145 | timings); | ||
146 | } | ||
147 | |||
148 | |||
149 | struct GNUNET_TESTING_Command | ||
150 | GNUNET_TESTING_cmd_stat (const char *label, | ||
151 | struct GNUNET_TESTING_Timer *timers) | ||
152 | { | ||
153 | return GNUNET_TESTING_command_new ((void *) timers, | ||
154 | label, | ||
155 | &stat_run, | ||
156 | NULL, | ||
157 | NULL); | ||
158 | } | ||
159 | |||
160 | |||
161 | /* end of testing_api_cmd_stat.c */ | ||
diff --git a/src/lib/testing/testing_api_cmds.c b/src/lib/testing/testing_api_cmds.c new file mode 100644 index 000000000..31d35f6c4 --- /dev/null +++ b/src/lib/testing/testing_api_cmds.c | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2021-2024 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_loop.c | ||
23 | * @brief main interpreter loop for testcases | ||
24 | * @author Christian Grothoff (GNU Taler testing) | ||
25 | * @author Marcello Stanisci (GNU Taler testing) | ||
26 | * @author t3sserakt | ||
27 | */ | ||
28 | #include "platform.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_testing_lib.h" | ||
31 | |||
32 | |||
33 | struct GNUNET_TESTING_Command | ||
34 | GNUNET_TESTING_command_new_ac ( | ||
35 | void *cls, | ||
36 | const char *label, | ||
37 | GNUNET_TESTING_CommandRunRoutine run, | ||
38 | GNUNET_TESTING_CommandCleanupRoutine cleanup, | ||
39 | GNUNET_TESTING_CommandGetTraits traits, | ||
40 | struct GNUNET_TESTING_AsyncContext *ac) | ||
41 | { | ||
42 | struct GNUNET_TESTING_Command cmd = { | ||
43 | .cls = cls, | ||
44 | .run = run, | ||
45 | .ac = ac, | ||
46 | .cleanup = cleanup, | ||
47 | .traits = traits | ||
48 | }; | ||
49 | |||
50 | GNUNET_assert (NULL != run); | ||
51 | if (NULL != label) | ||
52 | GNUNET_TESTING_set_label (&cmd.label, | ||
53 | label); | ||
54 | return cmd; | ||
55 | } | ||
56 | |||
57 | |||
58 | void | ||
59 | GNUNET_TESTING_set_label ( | ||
60 | struct GNUNET_TESTING_CommandLabel *label, | ||
61 | const char *value) | ||
62 | { | ||
63 | size_t len; | ||
64 | |||
65 | len = strlen (value); | ||
66 | GNUNET_assert (len <= | ||
67 | GNUNET_TESTING_CMD_MAX_LABEL_LENGTH); | ||
68 | memcpy (label->value, | ||
69 | value, | ||
70 | len + 1); | ||
71 | } | ||
72 | |||
73 | |||
74 | struct GNUNET_TESTING_Command | ||
75 | GNUNET_TESTING_cmd_set_var ( | ||
76 | const char *name, | ||
77 | struct GNUNET_TESTING_Command cmd) | ||
78 | { | ||
79 | cmd.name = name; | ||
80 | return cmd; | ||
81 | } | ||
82 | |||
83 | |||
84 | struct GNUNET_TESTING_Command | ||
85 | GNUNET_TESTING_cmd_end (void) | ||
86 | { | ||
87 | struct GNUNET_TESTING_Command cmd = { | ||
88 | .run = NULL | ||
89 | }; | ||
90 | |||
91 | return cmd; | ||
92 | } | ||
diff --git a/src/lib/testing/testing_api_loop.c b/src/lib/testing/testing_api_loop.c new file mode 100644 index 000000000..7bb88ddda --- /dev/null +++ b/src/lib/testing/testing_api_loop.c | |||
@@ -0,0 +1,1012 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2021-2024 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_loop.c | ||
23 | * @brief main interpreter loop for testcases | ||
24 | * @author Christian Grothoff (GNU Taler testing) | ||
25 | * @author Marcello Stanisci (GNU Taler testing) | ||
26 | * @author t3sserakt | ||
27 | */ | ||
28 | #include "platform.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_testing_lib.h" | ||
31 | #include "testing_api_loop.h" | ||
32 | #include "testing_api_cmd_batch.h" | ||
33 | #include "testing_api_topology.h" | ||
34 | #include "testing_cmds.h" | ||
35 | |||
36 | |||
37 | struct SendContext | ||
38 | { | ||
39 | struct SendContext *next; | ||
40 | struct SendContext *prev; | ||
41 | |||
42 | /** | ||
43 | * Handle to a send op | ||
44 | */ | ||
45 | struct GNUNET_HELPER_SendHandle *send_handle; | ||
46 | |||
47 | struct GNUNET_TESTING_Interpreter *is; | ||
48 | }; | ||
49 | |||
50 | /** | ||
51 | * Global state of the interpreter, used by a command | ||
52 | * to access information about other commands. | ||
53 | */ | ||
54 | struct GNUNET_TESTING_Interpreter | ||
55 | { | ||
56 | /** | ||
57 | * Array with handles of helper processes for communication with netjails. | ||
58 | */ | ||
59 | struct GNUNET_HELPER_Handle **helpers; | ||
60 | |||
61 | /** | ||
62 | * Function to call with the test result. | ||
63 | */ | ||
64 | GNUNET_TESTING_ResultCallback rc; | ||
65 | |||
66 | /** | ||
67 | * Closure for @e rc. | ||
68 | */ | ||
69 | void *rc_cls; | ||
70 | |||
71 | /** | ||
72 | * Commands the interpreter will run. | ||
73 | */ | ||
74 | struct GNUNET_TESTING_Command *commands; | ||
75 | |||
76 | /** | ||
77 | * Map with barriers for this loop. | ||
78 | */ | ||
79 | struct GNUNET_CONTAINER_MultiShortmap *barriers; | ||
80 | |||
81 | /** | ||
82 | * Interpreter task (if one is scheduled). | ||
83 | */ | ||
84 | struct GNUNET_SCHEDULER_Task *task; | ||
85 | |||
86 | /** | ||
87 | * Final task that returns the result. | ||
88 | */ | ||
89 | struct GNUNET_SCHEDULER_Task *final_task; | ||
90 | |||
91 | /** | ||
92 | * Task run on timeout. | ||
93 | */ | ||
94 | struct GNUNET_SCHEDULER_Task *timeout_task; | ||
95 | |||
96 | /** | ||
97 | * Hash map mapping variable names to commands. | ||
98 | */ | ||
99 | struct GNUNET_CONTAINER_MultiHashMap *vars; | ||
100 | |||
101 | struct SendContext *sender_head; | ||
102 | struct SendContext *sender_tail; | ||
103 | |||
104 | /** | ||
105 | * Function to call to send messages to our parent. | ||
106 | */ | ||
107 | GNUNET_TESTING_cmd_helper_write_cb parent_writer; | ||
108 | |||
109 | /** | ||
110 | * Number of GNUNET_TESTING_Command in @e commands. | ||
111 | */ | ||
112 | unsigned int cmds_n; | ||
113 | |||
114 | /** | ||
115 | * Size of the array @e helpers. | ||
116 | */ | ||
117 | unsigned int n_helpers; | ||
118 | |||
119 | /** | ||
120 | * Instruction pointer. Tells #interpreter_run() which instruction to run | ||
121 | * next. Need (signed) int because it gets -1 when rewinding the | ||
122 | * interpreter to the first CMD. | ||
123 | */ | ||
124 | int ip; | ||
125 | |||
126 | /** | ||
127 | * Result of the testcases, #GNUNET_OK on success, | ||
128 | * #GNUNET_SYSERR on failure, #GNUNET_NO if undecided. | ||
129 | */ | ||
130 | enum GNUNET_GenericReturnValue result; | ||
131 | |||
132 | /** | ||
133 | * Is the interpreter finishing? | ||
134 | */ | ||
135 | bool finishing; | ||
136 | |||
137 | /** | ||
138 | * Is the real result to "skip" because we could not | ||
139 | * get the environment working? | ||
140 | */ | ||
141 | bool skip; | ||
142 | |||
143 | }; | ||
144 | |||
145 | |||
146 | const struct GNUNET_TESTING_Command * | ||
147 | GNUNET_TESTING_interpreter_lookup_command ( | ||
148 | struct GNUNET_TESTING_Interpreter *is, | ||
149 | const char *label) | ||
150 | { | ||
151 | if (NULL == label) | ||
152 | { | ||
153 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
154 | "Attempt to lookup command for empty label\n"); | ||
155 | return NULL; | ||
156 | } | ||
157 | for (int i = is->ip; i >= 0; i--) | ||
158 | { | ||
159 | const struct GNUNET_TESTING_Command *cmd = &is->commands[i]; | ||
160 | |||
161 | /* Give precedence to top-level commands. */ | ||
162 | if ( (NULL != cmd->run) && | ||
163 | (0 == strcmp (cmd->label.value, | ||
164 | label)) ) | ||
165 | return cmd; | ||
166 | |||
167 | if (GNUNET_TESTING_cmd_is_batch_ (cmd)) | ||
168 | { | ||
169 | struct GNUNET_TESTING_Command **batch; | ||
170 | const struct GNUNET_TESTING_Command *current; | ||
171 | const struct GNUNET_TESTING_Command *icmd; | ||
172 | const struct GNUNET_TESTING_Command *match; | ||
173 | |||
174 | GNUNET_assert (GNUNET_OK == | ||
175 | GNUNET_TESTING_get_trait_cmd (cmd, | ||
176 | ¤t)); | ||
177 | GNUNET_assert (GNUNET_OK == | ||
178 | GNUNET_TESTING_get_trait_batch_cmds (cmd, | ||
179 | &batch)); | ||
180 | /* We must do the loop forward, but we can find the last match */ | ||
181 | match = NULL; | ||
182 | for (unsigned int j = 0; | ||
183 | NULL != (icmd = &(*batch)[j])->run; | ||
184 | j++) | ||
185 | { | ||
186 | if (current == icmd) | ||
187 | break; /* do not go past current command */ | ||
188 | if ( (NULL != icmd->run) && | ||
189 | (0 == strcmp (icmd->label.value, | ||
190 | label)) ) | ||
191 | match = icmd; | ||
192 | } | ||
193 | if (NULL != match) | ||
194 | return match; | ||
195 | } | ||
196 | } | ||
197 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
198 | "Command `%s' not found\n", | ||
199 | label); | ||
200 | return NULL; | ||
201 | } | ||
202 | |||
203 | |||
204 | const struct GNUNET_TESTING_Command * | ||
205 | GNUNET_TESTING_interpreter_get_command ( | ||
206 | struct GNUNET_TESTING_Interpreter *is, | ||
207 | const char *name) | ||
208 | { | ||
209 | const struct GNUNET_TESTING_Command *cmd; | ||
210 | struct GNUNET_HashCode h_name; | ||
211 | |||
212 | GNUNET_CRYPTO_hash (name, | ||
213 | strlen (name), | ||
214 | &h_name); | ||
215 | cmd = GNUNET_CONTAINER_multihashmap_get (is->vars, | ||
216 | &h_name); | ||
217 | if (NULL == cmd) | ||
218 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
219 | "Command not found by variable name: %s\n", | ||
220 | name); | ||
221 | return cmd; | ||
222 | } | ||
223 | |||
224 | |||
225 | static void | ||
226 | send_finished (void *cls, | ||
227 | enum GNUNET_GenericReturnValue result) | ||
228 | { | ||
229 | struct SendContext *sctx = cls; | ||
230 | struct GNUNET_TESTING_Interpreter *is = sctx->is; | ||
231 | |||
232 | GNUNET_break (GNUNET_OK == result); | ||
233 | GNUNET_CONTAINER_DLL_remove (is->sender_head, | ||
234 | is->sender_tail, | ||
235 | sctx); | ||
236 | GNUNET_free (sctx); | ||
237 | } | ||
238 | |||
239 | |||
240 | void | ||
241 | GNUNET_TESTING_loop_notify_children_ (struct GNUNET_TESTING_Interpreter *is, | ||
242 | const struct GNUNET_MessageHeader *hdr) | ||
243 | { | ||
244 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
245 | "Send notification to children of type %u\n", | ||
246 | (unsigned int) ntohs (hdr->type)); | ||
247 | for (unsigned int i = 0; i<is->n_helpers; i++) | ||
248 | { | ||
249 | struct SendContext *sctx; | ||
250 | |||
251 | sctx = GNUNET_new (struct SendContext); | ||
252 | sctx->is = is; | ||
253 | GNUNET_CONTAINER_DLL_insert (is->sender_head, | ||
254 | is->sender_tail, | ||
255 | sctx); | ||
256 | sctx->send_handle | ||
257 | = GNUNET_HELPER_send (is->helpers[i], | ||
258 | hdr, | ||
259 | false, /* never drop */ | ||
260 | &send_finished, | ||
261 | sctx); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | |||
266 | void | ||
267 | GNUNET_TESTING_loop_notify_parent_ (struct GNUNET_TESTING_Interpreter *is, | ||
268 | const struct GNUNET_MessageHeader *hdr) | ||
269 | { | ||
270 | /* We must have a parent */ | ||
271 | if (NULL == is->parent_writer) | ||
272 | GNUNET_TESTING_FAIL (is); | ||
273 | is->parent_writer (hdr); | ||
274 | } | ||
275 | |||
276 | |||
277 | /** | ||
278 | * Finish the test run, return the final result. | ||
279 | * | ||
280 | * @param cls the `struct GNUNET_TESTING_Interpreter` | ||
281 | */ | ||
282 | static void | ||
283 | finish_test (void *cls) | ||
284 | { | ||
285 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
286 | struct GNUNET_TESTING_Command *cmd; | ||
287 | const char *label; | ||
288 | |||
289 | is->finishing = true; | ||
290 | is->final_task = NULL; | ||
291 | label = is->commands[is->ip].label.value; | ||
292 | if (NULL == is->commands[is->ip].run) | ||
293 | label = "END"; | ||
294 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
295 | "Interpreter finishes at `%s' with status %d\n", | ||
296 | label, | ||
297 | is->result); | ||
298 | for (unsigned int j = 0; | ||
299 | NULL != (cmd = &is->commands[j])->run; | ||
300 | j++) | ||
301 | if (NULL != cmd->cleanup) | ||
302 | cmd->cleanup (cmd->cls); | ||
303 | if (NULL != is->task) | ||
304 | { | ||
305 | GNUNET_SCHEDULER_cancel (is->task); | ||
306 | is->task = NULL; | ||
307 | } | ||
308 | if (NULL != is->timeout_task) | ||
309 | { | ||
310 | GNUNET_SCHEDULER_cancel (is->timeout_task); | ||
311 | is->timeout_task = NULL; | ||
312 | } | ||
313 | { | ||
314 | struct SendContext *sctx; | ||
315 | |||
316 | while (NULL != (sctx = is->sender_head)) | ||
317 | { | ||
318 | GNUNET_CONTAINER_DLL_remove (is->sender_head, | ||
319 | is->sender_tail, | ||
320 | sctx); | ||
321 | GNUNET_HELPER_send_cancel (sctx->send_handle); | ||
322 | GNUNET_free (sctx); | ||
323 | } | ||
324 | } | ||
325 | GNUNET_free (is->commands); | ||
326 | is->rc (is->rc_cls, | ||
327 | is->skip ? GNUNET_NO : is->result); | ||
328 | if (NULL != is->barriers) | ||
329 | { | ||
330 | GNUNET_CONTAINER_multishortmap_destroy (is->barriers); | ||
331 | is->barriers = NULL; | ||
332 | } | ||
333 | if (NULL != is->vars) | ||
334 | { | ||
335 | GNUNET_CONTAINER_multihashmap_destroy (is->vars); | ||
336 | is->vars = NULL; | ||
337 | } | ||
338 | GNUNET_free (is->helpers); | ||
339 | GNUNET_free (is); | ||
340 | } | ||
341 | |||
342 | |||
343 | /** | ||
344 | * Run the main interpreter loop that performs exchange operations. | ||
345 | * | ||
346 | * @param cls contains the `struct InterpreterState` | ||
347 | */ | ||
348 | static void | ||
349 | interpreter_run (void *cls); | ||
350 | |||
351 | |||
352 | void | ||
353 | GNUNET_TESTING_interpreter_next_ (void *cls) | ||
354 | { | ||
355 | static unsigned long long ipc; | ||
356 | static struct GNUNET_TIME_Absolute last_report; | ||
357 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
358 | struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip]; | ||
359 | |||
360 | if (GNUNET_SYSERR == is->result) | ||
361 | return; /* ignore, we already failed! */ | ||
362 | |||
363 | if (GNUNET_TESTING_cmd_is_batch_ (cmd)) | ||
364 | { | ||
365 | if (GNUNET_TESTING_cmd_batch_next_ (cmd->cls)) | ||
366 | { | ||
367 | /* batch is done */ | ||
368 | cmd->finish_time = GNUNET_TIME_absolute_get (); | ||
369 | is->ip++; | ||
370 | } | ||
371 | } | ||
372 | else | ||
373 | { | ||
374 | cmd->finish_time = GNUNET_TIME_absolute_get (); | ||
375 | is->ip++; | ||
376 | } | ||
377 | |||
378 | if (0 == (ipc % 1000)) | ||
379 | { | ||
380 | if (0 != ipc) | ||
381 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
382 | "Interpreter executed 1000 instructions in %s\n", | ||
383 | GNUNET_STRINGS_relative_time_to_string ( | ||
384 | GNUNET_TIME_absolute_get_duration (last_report), | ||
385 | true)); | ||
386 | last_report = GNUNET_TIME_absolute_get (); | ||
387 | } | ||
388 | ipc++; | ||
389 | is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, | ||
390 | is); | ||
391 | } | ||
392 | |||
393 | |||
394 | void | ||
395 | GNUNET_TESTING_interpreter_run_cmd_ ( | ||
396 | struct GNUNET_TESTING_Interpreter *is, | ||
397 | struct GNUNET_TESTING_Command *cmd) | ||
398 | { | ||
399 | cmd->last_req_time | ||
400 | = GNUNET_TIME_absolute_get (); | ||
401 | if (0 == cmd->num_tries) | ||
402 | cmd->start_time = cmd->last_req_time; | ||
403 | cmd->num_tries = 1; | ||
404 | if (NULL != cmd->name) | ||
405 | { | ||
406 | struct GNUNET_HashCode h_name; | ||
407 | |||
408 | GNUNET_CRYPTO_hash (cmd->name, | ||
409 | strlen (cmd->name), | ||
410 | &h_name); | ||
411 | (void) GNUNET_CONTAINER_multihashmap_put ( | ||
412 | is->vars, | ||
413 | &h_name, | ||
414 | cmd, | ||
415 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | ||
416 | } | ||
417 | if (NULL != cmd->ac) | ||
418 | { | ||
419 | cmd->ac->is = is; | ||
420 | cmd->ac->finished = GNUNET_NO; | ||
421 | cmd->ac->next_called = false; | ||
422 | } | ||
423 | cmd->run (cmd->cls, | ||
424 | is); | ||
425 | if ( (! GNUNET_TESTING_cmd_is_batch_ (cmd)) && | ||
426 | ( (NULL == cmd->ac) || | ||
427 | (cmd->asynchronous_finish) ) ) | ||
428 | { | ||
429 | if (NULL != cmd->ac) | ||
430 | cmd->ac->next_called = true; | ||
431 | GNUNET_TESTING_interpreter_next_ (is); | ||
432 | } | ||
433 | } | ||
434 | |||
435 | |||
436 | /** | ||
437 | * Run the main interpreter loop. | ||
438 | * | ||
439 | * @param cls contains the `struct GNUNET_TESTING_Interpreter` | ||
440 | */ | ||
441 | static void | ||
442 | interpreter_run (void *cls) | ||
443 | { | ||
444 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
445 | struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip]; | ||
446 | |||
447 | is->task = NULL; | ||
448 | if (NULL == cmd->run) | ||
449 | { | ||
450 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
451 | "Running command END\n"); | ||
452 | is->result = GNUNET_OK; | ||
453 | finish_test (is); | ||
454 | return; | ||
455 | } | ||
456 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
457 | "Running command `%s'\n", | ||
458 | cmd->label.value); | ||
459 | GNUNET_TESTING_interpreter_run_cmd_ (is, | ||
460 | cmd); | ||
461 | } | ||
462 | |||
463 | |||
464 | void | ||
465 | GNUNET_TESTING_interpreter_fail (struct GNUNET_TESTING_Interpreter *is) | ||
466 | { | ||
467 | struct GNUNET_TESTING_Command *cmd | ||
468 | = &is->commands[is->ip]; | ||
469 | |||
470 | if (GNUNET_SYSERR == is->result) | ||
471 | { | ||
472 | GNUNET_break (0); | ||
473 | return; /* ignore, we already failed! */ | ||
474 | } | ||
475 | if (NULL == cmd) | ||
476 | { | ||
477 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
478 | "Failed with CMD being NULL!\n"); | ||
479 | } | ||
480 | else | ||
481 | { | ||
482 | const struct GNUNET_TESTING_Command *pos = cmd; | ||
483 | |||
484 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
485 | "Failed during command `%s'\n", | ||
486 | cmd->label.value); | ||
487 | while (GNUNET_TESTING_cmd_is_batch_ (pos)) | ||
488 | { | ||
489 | GNUNET_assert (GNUNET_OK == | ||
490 | GNUNET_TESTING_get_trait_cmd (pos, | ||
491 | &pos)); | ||
492 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
493 | "Failed in batch during command `%s'\n", | ||
494 | pos->label.value); | ||
495 | } | ||
496 | } | ||
497 | if (NULL != is->timeout_task) | ||
498 | { | ||
499 | GNUNET_SCHEDULER_cancel (is->timeout_task); | ||
500 | is->timeout_task = NULL; | ||
501 | } | ||
502 | is->result = GNUNET_SYSERR; | ||
503 | GNUNET_assert (NULL == is->final_task); | ||
504 | is->final_task = GNUNET_SCHEDULER_add_now (&finish_test, | ||
505 | is); | ||
506 | } | ||
507 | |||
508 | |||
509 | void | ||
510 | GNUNET_TESTING_interpreter_skip ( | ||
511 | struct GNUNET_TESTING_Interpreter *is) | ||
512 | { | ||
513 | is->skip = true; | ||
514 | GNUNET_TESTING_interpreter_fail (is); | ||
515 | } | ||
516 | |||
517 | |||
518 | void | ||
519 | GNUNET_TESTING_async_fail (struct GNUNET_TESTING_AsyncContext *ac) | ||
520 | { | ||
521 | GNUNET_assert (GNUNET_NO == ac->finished); | ||
522 | ac->finished = GNUNET_SYSERR; | ||
523 | GNUNET_TESTING_interpreter_fail (ac->is); | ||
524 | } | ||
525 | |||
526 | |||
527 | void | ||
528 | GNUNET_TESTING_async_finish (struct GNUNET_TESTING_AsyncContext *ac) | ||
529 | { | ||
530 | GNUNET_assert (GNUNET_NO == ac->finished); | ||
531 | ac->finished = GNUNET_OK; | ||
532 | if (NULL != ac->notify_finished) | ||
533 | { | ||
534 | ac->notify_finished (ac->notify_finished_cls); | ||
535 | ac->notify_finished = NULL; | ||
536 | } | ||
537 | if (! ac->next_called) | ||
538 | { | ||
539 | ac->next_called = true; | ||
540 | GNUNET_TESTING_interpreter_next_ (ac->is); | ||
541 | } | ||
542 | } | ||
543 | |||
544 | |||
545 | /** | ||
546 | * Function run when the test terminates (good or bad) with timeout. | ||
547 | * | ||
548 | * @param cls the interpreter state | ||
549 | */ | ||
550 | static void | ||
551 | do_timeout (void *cls) | ||
552 | { | ||
553 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
554 | |||
555 | is->timeout_task = NULL; | ||
556 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
557 | "Terminating test due to global timeout\n"); | ||
558 | is->result = GNUNET_SYSERR; | ||
559 | finish_test (is); | ||
560 | } | ||
561 | |||
562 | |||
563 | static void | ||
564 | setup_is (struct GNUNET_TESTING_Interpreter *is, | ||
565 | const struct GNUNET_TESTING_Command *bcommand, | ||
566 | const struct GNUNET_TESTING_Command *commands) | ||
567 | { | ||
568 | unsigned int i; | ||
569 | |||
570 | is->vars = GNUNET_CONTAINER_multihashmap_create (1024, | ||
571 | false); | ||
572 | /* get the number of commands */ | ||
573 | for (i = 0; NULL != commands[i].run; i++) | ||
574 | ; | ||
575 | if (NULL != bcommand) | ||
576 | i++; | ||
577 | is->cmds_n = i + 1; | ||
578 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
579 | "Got %u commands\n", | ||
580 | i); | ||
581 | is->commands = GNUNET_malloc_large ( | ||
582 | (i + 1) | ||
583 | * sizeof (struct GNUNET_TESTING_Command)); | ||
584 | GNUNET_assert (NULL != is->commands); | ||
585 | if (NULL == bcommand) | ||
586 | { | ||
587 | memcpy (is->commands, | ||
588 | commands, | ||
589 | sizeof (struct GNUNET_TESTING_Command) * i); | ||
590 | } | ||
591 | else | ||
592 | { | ||
593 | is->commands[0] = *bcommand; | ||
594 | memcpy (&is->commands[1], | ||
595 | commands, | ||
596 | sizeof (struct GNUNET_TESTING_Command) * i); | ||
597 | } | ||
598 | is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, | ||
599 | is); | ||
600 | } | ||
601 | |||
602 | |||
603 | struct GNUNET_TESTING_Interpreter * | ||
604 | GNUNET_TESTING_run (const struct GNUNET_TESTING_Command *commands, | ||
605 | struct GNUNET_TIME_Relative timeout, | ||
606 | GNUNET_TESTING_ResultCallback rc, | ||
607 | void *rc_cls) | ||
608 | { | ||
609 | struct GNUNET_TESTING_Interpreter *is; | ||
610 | |||
611 | is = GNUNET_new (struct GNUNET_TESTING_Interpreter); | ||
612 | is->timeout_task | ||
613 | = GNUNET_SCHEDULER_add_delayed (timeout, | ||
614 | &do_timeout, | ||
615 | is); | ||
616 | is->rc = rc; | ||
617 | is->rc_cls = rc_cls; | ||
618 | setup_is (is, | ||
619 | NULL, | ||
620 | commands); | ||
621 | return is; | ||
622 | } | ||
623 | |||
624 | |||
625 | static struct GNUNET_TESTING_Interpreter * | ||
626 | start_testcase ( | ||
627 | void *cls, | ||
628 | const char *topology_data, | ||
629 | uint32_t inherited_barrier_count, | ||
630 | const struct GNUNET_ShortHashCode *inherited_barriers, | ||
631 | GNUNET_TESTING_cmd_helper_write_cb parent_writer, | ||
632 | GNUNET_TESTING_ResultCallback finish_cb, | ||
633 | void *finish_cb_cls) | ||
634 | { | ||
635 | const struct GNUNET_TESTING_Command *commands = cls; | ||
636 | struct GNUNET_TESTING_Interpreter *is; | ||
637 | |||
638 | is = GNUNET_new (struct GNUNET_TESTING_Interpreter); | ||
639 | if (0 != inherited_barrier_count) | ||
640 | { | ||
641 | is->barriers | ||
642 | = GNUNET_CONTAINER_multishortmap_create (inherited_barrier_count * 4 / 3, | ||
643 | true); | ||
644 | for (unsigned int j = 0; j<inherited_barrier_count; j++) | ||
645 | { | ||
646 | struct GNUNET_TESTING_Barrier *barrier; | ||
647 | |||
648 | barrier = GNUNET_new (struct GNUNET_TESTING_Barrier); | ||
649 | barrier->barrier_id = inherited_barriers[j]; | ||
650 | barrier->inherited = true; | ||
651 | (void) GNUNET_CONTAINER_multishortmap_put ( | ||
652 | is->barriers, | ||
653 | &barrier->barrier_id, | ||
654 | barrier, | ||
655 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | ||
656 | } | ||
657 | } | ||
658 | is->parent_writer = parent_writer; | ||
659 | is->rc = finish_cb; | ||
660 | is->rc_cls = finish_cb_cls; | ||
661 | { | ||
662 | struct GNUNET_TESTING_Command bcmd; | ||
663 | |||
664 | bcmd = GNUNET_TESTING_cmd_set_var ( | ||
665 | "topology", | ||
666 | GNUNET_TESTING_cmd_load_topology_from_string ( | ||
667 | "_boot_", | ||
668 | topology_data)); | ||
669 | setup_is (is, | ||
670 | &bcmd, | ||
671 | commands); | ||
672 | } | ||
673 | return is; | ||
674 | |||
675 | } | ||
676 | |||
677 | |||
678 | struct GNUNET_TESTING_PluginFunctions * | ||
679 | GNUNET_TESTING_make_plugin ( | ||
680 | const struct GNUNET_TESTING_Command *commands) | ||
681 | { | ||
682 | struct GNUNET_TESTING_PluginFunctions *api; | ||
683 | |||
684 | api = GNUNET_new (struct GNUNET_TESTING_PluginFunctions); | ||
685 | api->cls = (void *) commands; | ||
686 | api->start_testcase = &start_testcase; | ||
687 | return api; | ||
688 | } | ||
689 | |||
690 | |||
691 | void | ||
692 | GNUNET_TESTING_add_netjail_helper_ (struct GNUNET_TESTING_Interpreter *is, | ||
693 | struct GNUNET_HELPER_Handle *helper) | ||
694 | { | ||
695 | GNUNET_array_append (is->helpers, | ||
696 | is->n_helpers, | ||
697 | helper); | ||
698 | } | ||
699 | |||
700 | |||
701 | struct GNUNET_TESTING_Barrier * | ||
702 | GNUNET_TESTING_get_barrier2_ (struct GNUNET_TESTING_Interpreter *is, | ||
703 | const struct GNUNET_ShortHashCode *create_key) | ||
704 | { | ||
705 | return GNUNET_CONTAINER_multishortmap_get (is->barriers, | ||
706 | create_key); | ||
707 | } | ||
708 | |||
709 | |||
710 | struct GNUNET_TESTING_Barrier * | ||
711 | GNUNET_TESTING_get_barrier_ (struct GNUNET_TESTING_Interpreter *is, | ||
712 | const char *barrier_name) | ||
713 | { | ||
714 | struct GNUNET_ShortHashCode create_key; | ||
715 | |||
716 | if (NULL == is->barriers) | ||
717 | return NULL; | ||
718 | GNUNET_TESTING_barrier_name_hash_ (barrier_name, | ||
719 | &create_key); | ||
720 | return GNUNET_TESTING_get_barrier2_ (is, | ||
721 | &create_key); | ||
722 | } | ||
723 | |||
724 | |||
725 | void | ||
726 | GNUNET_TESTING_add_barrier_ (struct GNUNET_TESTING_Interpreter *is, | ||
727 | struct GNUNET_TESTING_Barrier *barrier) | ||
728 | { | ||
729 | if (NULL == is->barriers) | ||
730 | is->barriers | ||
731 | = GNUNET_CONTAINER_multishortmap_create (1, | ||
732 | true); | ||
733 | /* We always use the barrier we encountered | ||
734 | most recently under a given label, thus replace */ | ||
735 | (void) GNUNET_CONTAINER_multishortmap_put ( | ||
736 | is->barriers, | ||
737 | &barrier->barrier_id, | ||
738 | barrier, | ||
739 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | ||
740 | } | ||
741 | |||
742 | |||
743 | unsigned int | ||
744 | GNUNET_TESTING_barrier_count_ ( | ||
745 | struct GNUNET_TESTING_Interpreter *is) | ||
746 | { | ||
747 | return GNUNET_CONTAINER_multishortmap_size (is->barriers); | ||
748 | } | ||
749 | |||
750 | |||
751 | void | ||
752 | GNUNET_TESTING_barrier_iterate_ ( | ||
753 | struct GNUNET_TESTING_Interpreter *is, | ||
754 | GNUNET_CONTAINER_ShortmapIterator cb, | ||
755 | void *cb_cls) | ||
756 | { | ||
757 | GNUNET_CONTAINER_multishortmap_iterate (is->barriers, | ||
758 | cb, | ||
759 | cb_cls); | ||
760 | } | ||
761 | |||
762 | |||
763 | void | ||
764 | GNUNET_TESTING_interpreter_commands_iterate ( | ||
765 | struct GNUNET_TESTING_Interpreter *is, | ||
766 | bool asc, | ||
767 | GNUNET_TESTING_CommandIterator cb, | ||
768 | void *cb_cls) | ||
769 | { | ||
770 | unsigned int start; | ||
771 | unsigned int end; | ||
772 | int inc; | ||
773 | |||
774 | if (asc) | ||
775 | { | ||
776 | inc = 1; | ||
777 | start = 0; | ||
778 | end = is->ip; | ||
779 | } | ||
780 | else | ||
781 | { | ||
782 | inc = -1; | ||
783 | start = is->ip; | ||
784 | end = 0; | ||
785 | } | ||
786 | for (unsigned int off = start; off != end + inc; off += inc) | ||
787 | { | ||
788 | const struct GNUNET_TESTING_Command *cmd | ||
789 | = &is->commands[off]; | ||
790 | |||
791 | cb (cb_cls, | ||
792 | cmd); | ||
793 | } | ||
794 | } | ||
795 | |||
796 | |||
797 | void | ||
798 | GNUNET_TESTING_interpreter_current_cmd_touch ( | ||
799 | struct GNUNET_TESTING_Interpreter *is) | ||
800 | { | ||
801 | is->commands[is->ip].last_req_time | ||
802 | = GNUNET_TIME_absolute_get (); | ||
803 | } | ||
804 | |||
805 | |||
806 | void | ||
807 | GNUNET_TESTING_interpreter_current_cmd_inc_tries ( | ||
808 | struct GNUNET_TESTING_Interpreter *is) | ||
809 | { | ||
810 | is->commands[is->ip].num_tries++; | ||
811 | } | ||
812 | |||
813 | |||
814 | const char * | ||
815 | GNUNET_TESTING_interpreter_current_cmd_get_label ( | ||
816 | struct GNUNET_TESTING_Interpreter *is) | ||
817 | { | ||
818 | return is->commands[is->ip].label.value; | ||
819 | } | ||
820 | |||
821 | |||
822 | /** | ||
823 | * State for a "rewind" CMD. | ||
824 | */ | ||
825 | struct RewindIpState | ||
826 | { | ||
827 | /** | ||
828 | * Instruction pointer to set into the interpreter. | ||
829 | */ | ||
830 | const char *target_label; | ||
831 | |||
832 | /** | ||
833 | * How many times this set should take place. However, this value lives at | ||
834 | * the calling process, and this CMD is only in charge of checking and | ||
835 | * decremeting it. | ||
836 | */ | ||
837 | unsigned int counter; | ||
838 | }; | ||
839 | |||
840 | |||
841 | /** | ||
842 | * Seek for the @a target command in @a batch (and rewind to it | ||
843 | * if successful). | ||
844 | * | ||
845 | * @param is the interpreter state (for failures) | ||
846 | * @param cmd batch to search for @a target | ||
847 | * @param target command to search for | ||
848 | * @return #GNUNET_OK on success, #GNUNET_NO if target was not found, | ||
849 | * #GNUNET_SYSERR if target is in the future and we failed | ||
850 | */ | ||
851 | static enum GNUNET_GenericReturnValue | ||
852 | seek_batch (struct GNUNET_TESTING_Interpreter *is, | ||
853 | const struct GNUNET_TESTING_Command *cmd, | ||
854 | const struct GNUNET_TESTING_Command *target) | ||
855 | { | ||
856 | unsigned int new_ip; | ||
857 | struct GNUNET_TESTING_Command **batch; | ||
858 | const struct GNUNET_TESTING_Command *current; | ||
859 | const struct GNUNET_TESTING_Command *icmd; | ||
860 | bool found = false; | ||
861 | |||
862 | GNUNET_assert (GNUNET_OK == | ||
863 | GNUNET_TESTING_get_trait_cmd (cmd, | ||
864 | ¤t)); | ||
865 | GNUNET_assert (GNUNET_OK == | ||
866 | GNUNET_TESTING_get_trait_batch_cmds (cmd, | ||
867 | &batch)); | ||
868 | for (new_ip = 0; | ||
869 | NULL != (icmd = &((*batch)[new_ip]))->run; | ||
870 | new_ip++) | ||
871 | { | ||
872 | if (current == target) | ||
873 | current = NULL; | ||
874 | if (icmd == target) | ||
875 | { | ||
876 | found = true; | ||
877 | break; | ||
878 | } | ||
879 | if (GNUNET_TESTING_cmd_is_batch_ (icmd)) | ||
880 | { | ||
881 | enum GNUNET_GenericReturnValue ret | ||
882 | = seek_batch (is, | ||
883 | icmd, | ||
884 | target); | ||
885 | if (GNUNET_SYSERR == ret) | ||
886 | return GNUNET_SYSERR; /* failure! */ | ||
887 | if (GNUNET_OK == ret) | ||
888 | { | ||
889 | found = true; | ||
890 | break; | ||
891 | } | ||
892 | } | ||
893 | } | ||
894 | if (! found) | ||
895 | return GNUNET_NO; /* not found */ | ||
896 | if (NULL == current) | ||
897 | { | ||
898 | /* refuse to jump forward */ | ||
899 | GNUNET_break (0); | ||
900 | GNUNET_TESTING_interpreter_fail (is); | ||
901 | return GNUNET_SYSERR; | ||
902 | } | ||
903 | GNUNET_TESTING_cmd_batch_set_current_ (cmd, | ||
904 | new_ip); | ||
905 | return GNUNET_OK; | ||
906 | } | ||
907 | |||
908 | |||
909 | /** | ||
910 | * Run the "rewind" CMD. | ||
911 | * | ||
912 | * @param cls closure. | ||
913 | * @param cmd command being executed now. | ||
914 | * @param is the interpreter state. | ||
915 | */ | ||
916 | static void | ||
917 | rewind_ip_run (void *cls, | ||
918 | struct GNUNET_TESTING_Interpreter *is) | ||
919 | { | ||
920 | struct RewindIpState *ris = cls; | ||
921 | const struct GNUNET_TESTING_Command *target; | ||
922 | const struct GNUNET_TESTING_Command *icmd; | ||
923 | unsigned int new_ip; | ||
924 | bool found = false; | ||
925 | |||
926 | if (0 == ris->counter) | ||
927 | return; | ||
928 | target | ||
929 | = GNUNET_TESTING_interpreter_lookup_command (is, | ||
930 | ris->target_label); | ||
931 | if (NULL == target) | ||
932 | { | ||
933 | GNUNET_break (0); | ||
934 | GNUNET_TESTING_interpreter_fail (is); | ||
935 | return; | ||
936 | } | ||
937 | ris->counter--; | ||
938 | for (new_ip = 0; | ||
939 | NULL != (icmd = &is->commands[new_ip])->run; | ||
940 | new_ip++) | ||
941 | { | ||
942 | if (icmd == target) | ||
943 | { | ||
944 | found = true; | ||
945 | break; | ||
946 | } | ||
947 | if (GNUNET_TESTING_cmd_is_batch_ (icmd)) | ||
948 | { | ||
949 | enum GNUNET_GenericReturnValue ret | ||
950 | = seek_batch (is, | ||
951 | icmd, | ||
952 | target); | ||
953 | if (GNUNET_SYSERR == ret) | ||
954 | { | ||
955 | /* failure! */ | ||
956 | GNUNET_break (0); | ||
957 | GNUNET_TESTING_interpreter_fail (is); | ||
958 | return; | ||
959 | } | ||
960 | if (GNUNET_OK == ret) | ||
961 | { | ||
962 | /* counter subtraction below for batch */ | ||
963 | found = true; | ||
964 | break; | ||
965 | } | ||
966 | } | ||
967 | } | ||
968 | if (! found) | ||
969 | { | ||
970 | GNUNET_break (0); | ||
971 | GNUNET_TESTING_interpreter_fail (is); | ||
972 | return; | ||
973 | } | ||
974 | if (new_ip > (unsigned int) is->ip) | ||
975 | { | ||
976 | /* refuse to jump forward */ | ||
977 | GNUNET_break (0); | ||
978 | GNUNET_TESTING_interpreter_fail (is); | ||
979 | return; | ||
980 | } | ||
981 | is->ip = new_ip; | ||
982 | } | ||
983 | |||
984 | |||
985 | static void | ||
986 | rewind_ip_free (void *cls) | ||
987 | { | ||
988 | struct RewindIpState *ris = cls; | ||
989 | |||
990 | GNUNET_free (ris); | ||
991 | } | ||
992 | |||
993 | |||
994 | struct GNUNET_TESTING_Command | ||
995 | GNUNET_TESTING_cmd_rewind_ip (const char *label, | ||
996 | const char *target_label, | ||
997 | unsigned int counter) | ||
998 | { | ||
999 | struct RewindIpState *ris; | ||
1000 | |||
1001 | ris = GNUNET_new (struct RewindIpState); | ||
1002 | ris->target_label = target_label; | ||
1003 | ris->counter = counter; | ||
1004 | return GNUNET_TESTING_command_new (ris, | ||
1005 | label, | ||
1006 | &rewind_ip_run, | ||
1007 | &rewind_ip_free, | ||
1008 | NULL); | ||
1009 | } | ||
1010 | |||
1011 | |||
1012 | /* end of testing_api_loop.c */ | ||
diff --git a/src/lib/testing/testing_api_loop.h b/src/lib/testing/testing_api_loop.h new file mode 100644 index 000000000..2a3047183 --- /dev/null +++ b/src/lib/testing/testing_api_loop.h | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2022 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_api_loop.h | ||
23 | * @brief | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #ifndef TESTING_API_LOOP_H | ||
27 | #define TESTING_API_LOOP_H | ||
28 | |||
29 | #include "testing_api_barrier.h" | ||
30 | |||
31 | |||
32 | /** | ||
33 | * Callback function to write messages from the helper process running on a netjail node to the master process. | ||
34 | * | ||
35 | * @param message The message to write. | ||
36 | */ | ||
37 | typedef void | ||
38 | (*GNUNET_TESTING_cmd_helper_write_cb) ( | ||
39 | const struct GNUNET_MessageHeader *message); | ||
40 | |||
41 | |||
42 | /** | ||
43 | * The plugin API every test case plugin has to implement. | ||
44 | */ | ||
45 | struct GNUNET_TESTING_PluginFunctions | ||
46 | { | ||
47 | |||
48 | /** | ||
49 | * Closure to pass to start_testcase. | ||
50 | */ | ||
51 | void *cls; | ||
52 | |||
53 | /** | ||
54 | * Function to be implemented for each test case plugin which starts the test case on a netjail node. | ||
55 | * | ||
56 | * @param topology_data A file name for the file containing the topology configuration, or a string containing | ||
57 | * the topology configuration. | ||
58 | * @param barrier_count length of the @a barriers array | ||
59 | * @param barriers inherited barriers | ||
60 | * @param write_message Callback function to write messages from the helper process running on a | ||
61 | * netjail node to the master process. | ||
62 | * @param finish_cb Callback function which writes a message from the helper process running on a netjail | ||
63 | * node to the master process * signaling that the test case running on the netjail node finished. | ||
64 | * @return Returns The struct GNUNET_TESTING_Interpreter of the command loop running on this netjail node. | ||
65 | */ | ||
66 | struct GNUNET_TESTING_Interpreter * | ||
67 | (*start_testcase) ( | ||
68 | void *cls, | ||
69 | const char *topology_data, | ||
70 | uint32_t barrier_count, | ||
71 | const struct GNUNET_ShortHashCode *barriers, | ||
72 | GNUNET_TESTING_cmd_helper_write_cb write_message, | ||
73 | GNUNET_TESTING_ResultCallback finish_cb, | ||
74 | void *finish_cb_cls); | ||
75 | |||
76 | }; | ||
77 | |||
78 | |||
79 | /** | ||
80 | * Send message to our parent. Fails very hard if | ||
81 | * we do not have one. | ||
82 | * | ||
83 | * @param is The interpreter loop. | ||
84 | */ | ||
85 | void | ||
86 | GNUNET_TESTING_loop_notify_parent_ ( | ||
87 | struct GNUNET_TESTING_Interpreter *is, | ||
88 | const struct GNUNET_MessageHeader *hdr); | ||
89 | |||
90 | |||
91 | /** | ||
92 | * Send message to all netjail children (if there | ||
93 | * are any). | ||
94 | * | ||
95 | * @param is The interpreter loop. | ||
96 | */ | ||
97 | void | ||
98 | GNUNET_TESTING_loop_notify_children_ ( | ||
99 | struct GNUNET_TESTING_Interpreter *is, | ||
100 | const struct GNUNET_MessageHeader *hdr); | ||
101 | |||
102 | |||
103 | /** | ||
104 | * Current command is done, run the next one. | ||
105 | */ | ||
106 | void | ||
107 | GNUNET_TESTING_interpreter_next_ (void *cls); | ||
108 | |||
109 | |||
110 | void | ||
111 | GNUNET_TESTING_interpreter_run_cmd_ ( | ||
112 | struct GNUNET_TESTING_Interpreter *is, | ||
113 | struct GNUNET_TESTING_Command *cmd); | ||
114 | |||
115 | /** | ||
116 | * Adding a helper handle to the interpreter. | ||
117 | * | ||
118 | * @param is The interpreter. | ||
119 | * @param helper The helper handle. | ||
120 | */ | ||
121 | void | ||
122 | GNUNET_TESTING_add_netjail_helper_ ( | ||
123 | struct GNUNET_TESTING_Interpreter *is, | ||
124 | struct GNUNET_HELPER_Handle *helper); | ||
125 | |||
126 | |||
127 | /** | ||
128 | * Add a barrier to the interpreter to share it with | ||
129 | * all children as an inherited barrier. | ||
130 | * | ||
131 | * @param is The interpreter. | ||
132 | * @param barrier The barrier to add. | ||
133 | */ | ||
134 | void | ||
135 | GNUNET_TESTING_add_barrier_ ( | ||
136 | struct GNUNET_TESTING_Interpreter *is, | ||
137 | struct GNUNET_TESTING_Barrier *barrier); | ||
138 | |||
139 | |||
140 | struct GNUNET_TESTING_Barrier * | ||
141 | GNUNET_TESTING_get_barrier2_ ( | ||
142 | struct GNUNET_TESTING_Interpreter *is, | ||
143 | const struct GNUNET_ShortHashCode *create_key); | ||
144 | |||
145 | |||
146 | struct GNUNET_TESTING_Barrier * | ||
147 | GNUNET_TESTING_get_barrier_ ( | ||
148 | struct GNUNET_TESTING_Interpreter *is, | ||
149 | const char *barrier_name); | ||
150 | |||
151 | |||
152 | unsigned int | ||
153 | GNUNET_TESTING_barrier_count_ ( | ||
154 | struct GNUNET_TESTING_Interpreter *is); | ||
155 | |||
156 | |||
157 | void | ||
158 | GNUNET_TESTING_barrier_iterate_ ( | ||
159 | struct GNUNET_TESTING_Interpreter *is, | ||
160 | GNUNET_CONTAINER_ShortmapIterator cb, | ||
161 | void *cb_cls); | ||
162 | |||
163 | #endif | ||
diff --git a/src/lib/testing/testing_api_main.c b/src/lib/testing/testing_api_main.c new file mode 100644 index 000000000..fc60cb2c9 --- /dev/null +++ b/src/lib/testing/testing_api_main.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2021-2024 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_loop.c | ||
23 | * @brief main interpreter loop for testcases | ||
24 | * @author Christian Grothoff (GNU Taler testing) | ||
25 | * @author Marcello Stanisci (GNU Taler testing) | ||
26 | * @author t3sserakt | ||
27 | */ | ||
28 | #include "platform.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_testing_lib.h" | ||
31 | |||
32 | |||
33 | /** | ||
34 | * Closure for #loop_run(). | ||
35 | */ | ||
36 | struct MainParams | ||
37 | { | ||
38 | |||
39 | /** | ||
40 | * NULL-label terminated array of commands. | ||
41 | */ | ||
42 | const struct GNUNET_TESTING_Command *commands; | ||
43 | |||
44 | /** | ||
45 | * The interpreter. | ||
46 | */ | ||
47 | struct GNUNET_TESTING_Interpreter *is; | ||
48 | |||
49 | /** | ||
50 | * Global timeout for the test. | ||
51 | */ | ||
52 | struct GNUNET_TIME_Relative timeout; | ||
53 | |||
54 | /** | ||
55 | * Set to #EXIT_FAILURE on error. | ||
56 | */ | ||
57 | int rv; | ||
58 | }; | ||
59 | |||
60 | |||
61 | /** | ||
62 | * Function called with the final result of the test. | ||
63 | * | ||
64 | * @param cls the `struct MainParams` | ||
65 | * @param rv #GNUNET_OK if the test passed | ||
66 | */ | ||
67 | static void | ||
68 | handle_result (void *cls, | ||
69 | enum GNUNET_GenericReturnValue rv) | ||
70 | { | ||
71 | struct MainParams *mp = cls; | ||
72 | |||
73 | mp->is = NULL; | ||
74 | switch (rv) | ||
75 | { | ||
76 | case GNUNET_OK: | ||
77 | mp->rv = EXIT_SUCCESS; | ||
78 | break; | ||
79 | case GNUNET_NO: | ||
80 | mp->rv = 77; | ||
81 | break; | ||
82 | case GNUNET_SYSERR: | ||
83 | mp->rv = EXIT_FAILURE; | ||
84 | break; | ||
85 | } | ||
86 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
87 | "Test exits with status %d\n", | ||
88 | mp->rv); | ||
89 | GNUNET_SCHEDULER_shutdown (); | ||
90 | } | ||
91 | |||
92 | |||
93 | static void | ||
94 | do_shutdown (void *cls) | ||
95 | { | ||
96 | struct MainParams *mp = cls; | ||
97 | |||
98 | if (NULL != mp->is) | ||
99 | { | ||
100 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
101 | "Terminating test due to shutdown\n"); | ||
102 | GNUNET_TESTING_interpreter_fail (mp->is); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | |||
107 | /** | ||
108 | * Main function to run the test cases. | ||
109 | * | ||
110 | * @param cls a `struct MainParams *` | ||
111 | */ | ||
112 | static void | ||
113 | loop_run (void *cls) | ||
114 | { | ||
115 | struct MainParams *mp = cls; | ||
116 | |||
117 | mp->is = GNUNET_TESTING_run (mp->commands, | ||
118 | mp->timeout, | ||
119 | &handle_result, | ||
120 | mp); | ||
121 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | ||
122 | mp); | ||
123 | } | ||
124 | |||
125 | |||
126 | int | ||
127 | GNUNET_TESTING_main ( | ||
128 | const struct GNUNET_TESTING_Command *commands, | ||
129 | struct GNUNET_TIME_Relative timeout) | ||
130 | { | ||
131 | struct MainParams mp = { | ||
132 | .commands = commands, | ||
133 | .timeout = timeout, | ||
134 | .rv = EXIT_SUCCESS | ||
135 | }; | ||
136 | |||
137 | GNUNET_SCHEDULER_run (&loop_run, | ||
138 | &mp); | ||
139 | return mp.rv; | ||
140 | } | ||
diff --git a/src/lib/testing/testing_api_topology.c b/src/lib/testing/testing_api_topology.c new file mode 100644 index 000000000..7221d4f39 --- /dev/null +++ b/src/lib/testing/testing_api_topology.c | |||
@@ -0,0 +1,1083 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2008, 2009, 2012 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.c | ||
23 | * @brief convenience API for writing testcases for GNUnet | ||
24 | * Many testcases need to start and stop a peer/service | ||
25 | * and this library is supposed to make that easier | ||
26 | * for TESTCASES. Normal programs should always | ||
27 | * use functions from gnunet_{util,arm}_lib.h. This API is | ||
28 | * ONLY for writing testcases (or internal use of the testbed). | ||
29 | * @author Christian Grothoff | ||
30 | * | ||
31 | */ | ||
32 | #include "platform.h" | ||
33 | #include "gnunet_util_lib.h" | ||
34 | #include "gnunet_testing_lib.h" | ||
35 | #include "testing_api_topology.h" | ||
36 | #include "testing_cmds.h" | ||
37 | |||
38 | #define LOG(kind, ...) GNUNET_log_from (kind, "testing-api", __VA_ARGS__) | ||
39 | |||
40 | #define CONNECT_ADDRESS_TEMPLATE "%s-192.168.15.%u" | ||
41 | |||
42 | #define ROUTER_CONNECT_ADDRESS_TEMPLATE "%s-92.68.150.%u" | ||
43 | |||
44 | #define KNOWN_CONNECT_ADDRESS_TEMPLATE "%s-92.68.151.%u" | ||
45 | |||
46 | #define PREFIX_TCP "tcp" | ||
47 | |||
48 | #define PREFIX_UDP "udp" | ||
49 | |||
50 | #define PREFIX_TCP_NATTED "tcp_natted" | ||
51 | |||
52 | #define PREFIX_UDP_NATTED "udp_natted" | ||
53 | |||
54 | |||
55 | /** | ||
56 | * Every line in the topology configuration starts with a string indicating which | ||
57 | * kind of information will be configured with this line. Configuration values following | ||
58 | * this string are seperated by special sequences of characters. An integer value seperated | ||
59 | * by ':' is returned by this function. | ||
60 | * | ||
61 | * @param line The line of configuration. Example: "a:42[:43]" | ||
62 | * @return An integer value (42) | ||
63 | */ | ||
64 | static unsigned int | ||
65 | get_first_value (const char *line) | ||
66 | { | ||
67 | const char *colon = strchr (line, ':'); | ||
68 | char dummy; | ||
69 | int ret; | ||
70 | |||
71 | GNUNET_assert (NULL != colon); | ||
72 | ret = sscanf (colon + 1, | ||
73 | "%u%c", | ||
74 | &ret, | ||
75 | &dummy); | ||
76 | if (2 == ret) | ||
77 | GNUNET_assert (':' == dummy); | ||
78 | else | ||
79 | GNUNET_assert (1 == ret); | ||
80 | return ret; | ||
81 | } | ||
82 | |||
83 | |||
84 | /** | ||
85 | * Every line in the topology configuration starts with a string indicating | ||
86 | * which kind of information will be configured with this line. This string is | ||
87 | * returned by this function. | ||
88 | * | ||
89 | * @param line The line of configuration, e.g. "D:452" | ||
90 | * @return The leading string of this configuration line ("D") | ||
91 | */ | ||
92 | static char * | ||
93 | get_key (const char *line) | ||
94 | { | ||
95 | const char *colon = strchr (line, ':'); | ||
96 | |||
97 | GNUNET_assert (NULL != colon); | ||
98 | return GNUNET_strndup (line, | ||
99 | colon - line); | ||
100 | } | ||
101 | |||
102 | |||
103 | /** | ||
104 | * Every line in the topology configuration starts with a string indicating which | ||
105 | * kind of information will be configured with this line. Configuration values following | ||
106 | * this string are seperated by special sequences of characters. A string value seperated | ||
107 | * by ':' is returned by this function. | ||
108 | * | ||
109 | * @param line The line of configuration ("FOO:BAR") | ||
110 | * @return A string value ("BAR"). | ||
111 | */ | ||
112 | // FIXME: avoid strdup, return const? | ||
113 | static char * | ||
114 | get_first_string_value (const char *line) | ||
115 | { | ||
116 | const char *colon = strchr (line, ':'); | ||
117 | |||
118 | GNUNET_assert (NULL != colon); | ||
119 | return GNUNET_strdup (colon + 1); | ||
120 | } | ||
121 | |||
122 | |||
123 | /** | ||
124 | * Every line in the topology configuration starts with a string indicating | ||
125 | * which kind of information will be configured with this line. Configuration | ||
126 | * values following this string are seperated by special sequences of | ||
127 | * characters. A second integer value seperated by ':' from a first value is | ||
128 | * returned by this function. | ||
129 | * | ||
130 | * @param line The line of configuration (example: "P:1:3") | ||
131 | * @return An integer value (3) | ||
132 | */ | ||
133 | static unsigned int | ||
134 | get_second_value (const char *line) | ||
135 | { | ||
136 | const char *colon; | ||
137 | char dummy; | ||
138 | int ret; | ||
139 | |||
140 | colon = strchr (line, ':'); | ||
141 | GNUNET_assert (NULL != colon); | ||
142 | colon = strchr (colon + 1, ':'); | ||
143 | GNUNET_assert (NULL != colon); | ||
144 | GNUNET_assert (1 == | ||
145 | sscanf (colon + 1, | ||
146 | "%u%c", | ||
147 | &ret, | ||
148 | &dummy)); | ||
149 | return ret; | ||
150 | } | ||
151 | |||
152 | |||
153 | /** | ||
154 | * Every line in the topology configuration starts with a string indicating which | ||
155 | * kind of information will be configured with this line. Configuration values following | ||
156 | * this string are seperated by special sequences of characters. A value might be | ||
157 | * a key value pair. | ||
158 | * This function returns the value for a specific key in a configuration line. | ||
159 | * | ||
160 | * @param key The key of the key value pair. | ||
161 | * @return The value of the key value pair. | ||
162 | */ | ||
163 | static char * | ||
164 | get_value (const char *key, const char *line) | ||
165 | { | ||
166 | char copy[strlen (line) + 1]; | ||
167 | size_t slen; | ||
168 | char *token; | ||
169 | char *token2; | ||
170 | char *temp; | ||
171 | char *rest = NULL; | ||
172 | |||
173 | slen = strlen (line) + 1; | ||
174 | memcpy (copy, line, slen); | ||
175 | temp = strstr (copy, key); | ||
176 | if (NULL == temp) | ||
177 | return NULL; | ||
178 | token = strtok_r (temp, ":", &rest); | ||
179 | if (NULL == token) | ||
180 | return NULL; | ||
181 | token = strtok_r (NULL, ":", &rest); | ||
182 | if (NULL == token) | ||
183 | return NULL; | ||
184 | token2 = strtok_r (token, "}", &rest); | ||
185 | if (NULL == token2) | ||
186 | return NULL; | ||
187 | return GNUNET_strdup (token2); | ||
188 | } | ||
189 | |||
190 | |||
191 | /** | ||
192 | * Every line in the topology configuration starts with a string indicating which | ||
193 | * kind of information will be configured with this line. Configuration values following | ||
194 | * this string are seperated by special sequences of characters. A value might be | ||
195 | * a key value pair. A special key is the 'connect' key which can appear more than once. | ||
196 | * The value is the information about a connection via some protocol to some other node. | ||
197 | * This function returns the struct GNUNET_TESTING_NodeConnection which holds the information | ||
198 | * of the connect value. | ||
199 | * | ||
200 | * @param value The value of the connect key value pair. | ||
201 | * @return The struct GNUNET_TESTING_NodeConnection. | ||
202 | */ | ||
203 | static struct GNUNET_TESTING_NodeConnection * | ||
204 | get_connect_value (const char *line, | ||
205 | struct GNUNET_TESTING_NetjailNode *node) | ||
206 | { | ||
207 | struct GNUNET_TESTING_NodeConnection *node_connection; | ||
208 | char *copy; | ||
209 | char *token; | ||
210 | char *token2; | ||
211 | unsigned int node_n; | ||
212 | unsigned int namespace_n; | ||
213 | char *rest = NULL; | ||
214 | char *rest2 = NULL; | ||
215 | struct GNUNET_TESTING_AddressPrefix *prefix; | ||
216 | unsigned int sscanf_ret; | ||
217 | |||
218 | node_connection = GNUNET_new (struct GNUNET_TESTING_NodeConnection); | ||
219 | node_connection->node = node; | ||
220 | |||
221 | copy = GNUNET_strdup (line); | ||
222 | token = strtok_r (copy, ":", &rest); | ||
223 | if (0 == strcmp ("{K", token)) | ||
224 | { | ||
225 | node_connection->node_type = GNUNET_TESTING_GLOBAL_NODE; | ||
226 | token = strtok_r (NULL, ":", &rest); | ||
227 | GNUNET_assert (1 == sscanf (token, "%u", &node_n)); | ||
228 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
229 | "node_n %u\n", | ||
230 | node_n); | ||
231 | node_connection->node_n = node_n; | ||
232 | node_connection->namespace_n = 0; | ||
233 | } | ||
234 | else if (0 == strcmp ("{P", token)) | ||
235 | { | ||
236 | node_connection->node_type = GNUNET_TESTING_SUBNET_NODE; | ||
237 | token = strtok_r (NULL, ":", &rest); | ||
238 | errno = 0; | ||
239 | sscanf_ret = sscanf (token, "%u", &namespace_n); | ||
240 | if (errno != 0) | ||
241 | { | ||
242 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sscanf"); | ||
243 | } | ||
244 | GNUNET_assert (0 < sscanf_ret); | ||
245 | node_connection->namespace_n = namespace_n; | ||
246 | token = strtok_r (NULL, ":", &rest); | ||
247 | errno = 0; | ||
248 | sscanf_ret = sscanf (token, "%u", &node_n); | ||
249 | if (errno != 0) | ||
250 | { | ||
251 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sscanf"); | ||
252 | } | ||
253 | GNUNET_assert (0 < sscanf_ret); | ||
254 | node_connection->node_n = node_n; | ||
255 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
256 | "node_n %u namespace_n %u node->node_n %u node->namespace_n %u\n", | ||
257 | node_n, | ||
258 | namespace_n, | ||
259 | node->node_n, | ||
260 | node->namespace_n); | ||
261 | } | ||
262 | else | ||
263 | { | ||
264 | GNUNET_break (0); | ||
265 | GNUNET_free (node_connection); | ||
266 | GNUNET_free (copy); | ||
267 | return NULL; | ||
268 | } | ||
269 | |||
270 | while (NULL != (token = strtok_r (NULL, ":", &rest))) | ||
271 | { | ||
272 | prefix = GNUNET_new (struct GNUNET_TESTING_AddressPrefix); | ||
273 | token2 = strtok_r (token, "}", &rest2); | ||
274 | if (NULL != token2) | ||
275 | prefix->address_prefix = GNUNET_strdup (token2); | ||
276 | else | ||
277 | prefix->address_prefix = GNUNET_strdup (token); | ||
278 | |||
279 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
280 | "address_prefix %s\n", | ||
281 | prefix->address_prefix); | ||
282 | |||
283 | GNUNET_CONTAINER_DLL_insert (node_connection->address_prefixes_head, | ||
284 | node_connection->address_prefixes_tail, | ||
285 | prefix); | ||
286 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
287 | "address_prefix %s\n", | ||
288 | prefix->address_prefix); | ||
289 | } | ||
290 | |||
291 | GNUNET_free (copy); | ||
292 | return node_connection; | ||
293 | } | ||
294 | |||
295 | |||
296 | /** | ||
297 | * Every line in the topology configuration starts with a string indicating which | ||
298 | * kind of information will be configured with this line. Configuration values following | ||
299 | * this string are seperated by special sequences of characters. A value might be | ||
300 | * a key value pair. A special key is the 'connect' key. | ||
301 | * The value is the information about a connections via some protocol to other nodes. | ||
302 | * Each connection itself is a key value pair separated by the character '|' and | ||
303 | * surrounded by the characters '{' and '}'. | ||
304 | * The struct GNUNET_TESTING_NodeConnection holds the information of each connection value. | ||
305 | * This function extracts the values of each connection into a DLL of | ||
306 | * struct GNUNET_TESTING_NodeConnection which will be added to a node. | ||
307 | * | ||
308 | * @param line The line of configuration. | ||
309 | * @param node The struct GNUNET_TESTING_NetjailNode to which the DLL of | ||
310 | * struct GNUNET_TESTING_NodeConnection will be added. | ||
311 | */ | ||
312 | static void | ||
313 | node_connections (const char *line, | ||
314 | struct GNUNET_TESTING_NetjailNode *node) | ||
315 | { | ||
316 | char *value, *value2; | ||
317 | char *temp; | ||
318 | char *copy; | ||
319 | char *rest = NULL; | ||
320 | char *rest2 = NULL; | ||
321 | struct GNUNET_TESTING_NodeConnection *node_connection; | ||
322 | |||
323 | temp = strstr (line, "connect"); | ||
324 | if (NULL != temp) | ||
325 | { | ||
326 | copy = GNUNET_strdup (temp); | ||
327 | strtok_r (copy, ":", &rest); | ||
328 | value = strtok_r (rest, "|", &rest2); | ||
329 | |||
330 | while (NULL != value) | ||
331 | { | ||
332 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
333 | "node_connections value %s\n", | ||
334 | value); | ||
335 | node_connection = get_connect_value (value, node); | ||
336 | if (NULL == node_connection) | ||
337 | { | ||
338 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
339 | "connect key was not expected in this configuration line: %s\n", | ||
340 | line); | ||
341 | break; | ||
342 | } | ||
343 | GNUNET_CONTAINER_DLL_insert (node->node_connections_head, | ||
344 | node->node_connections_tail, | ||
345 | node_connection); | ||
346 | value2 = strstr (value, "}}"); | ||
347 | if (NULL != value2) | ||
348 | break; | ||
349 | value = strtok_r (NULL, "|", &rest2); | ||
350 | |||
351 | } | ||
352 | GNUNET_free (copy); | ||
353 | } | ||
354 | } | ||
355 | |||
356 | |||
357 | /** | ||
358 | * A helper function to log information about individual nodes. | ||
359 | * | ||
360 | * @param cls This is not used actually. | ||
361 | * @param id The key of this value in the map. | ||
362 | * @param value A struct GNUNET_TESTING_NetjailNode which holds information about a node. | ||
363 | * return GNUNET_YES to continue with iterating, GNUNET_NO otherwise. | ||
364 | */ | ||
365 | static int | ||
366 | log_nodes (void *cls, | ||
367 | const struct GNUNET_ShortHashCode *id, | ||
368 | void *value) | ||
369 | { | ||
370 | struct GNUNET_TESTING_NetjailNode *node = value; | ||
371 | struct GNUNET_TESTING_NodeConnection *pos_connection; | ||
372 | struct GNUNET_TESTING_AddressPrefix *pos_prefix; | ||
373 | |||
374 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
375 | "plugin: %s space: %u node: %u global: %u\n", | ||
376 | node->plugin, | ||
377 | node->namespace_n, | ||
378 | node->node_n, | ||
379 | node->is_global); | ||
380 | |||
381 | for (pos_connection = node->node_connections_head; NULL != pos_connection; | ||
382 | pos_connection = pos_connection->next) | ||
383 | { | ||
384 | |||
385 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
386 | "namespace_n: %u node_n: %u node_type: %u\n", | ||
387 | pos_connection->namespace_n, | ||
388 | pos_connection->node_n, | ||
389 | pos_connection->node_type); | ||
390 | |||
391 | for (pos_prefix = pos_connection->address_prefixes_head; NULL != pos_prefix; | ||
392 | pos_prefix = | ||
393 | pos_prefix->next) | ||
394 | { | ||
395 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
396 | "prefix: %s\n", | ||
397 | pos_prefix->address_prefix); | ||
398 | } | ||
399 | } | ||
400 | return GNUNET_YES; | ||
401 | } | ||
402 | |||
403 | |||
404 | /** | ||
405 | * Helper function to log information about namespaces. | ||
406 | * | ||
407 | * @param cls This is not used actually. | ||
408 | * @param id The key of this value in the map. | ||
409 | * @param value A struct GNUNET_TESTING_NetjailNamespace which holds information about a subnet. | ||
410 | * return GNUNET_YES to continue with iterating, GNUNET_NO otherwise. | ||
411 | */ | ||
412 | static int | ||
413 | log_namespaces (void *cls, | ||
414 | const struct GNUNET_ShortHashCode *id, | ||
415 | void *value) | ||
416 | { | ||
417 | struct GNUNET_TESTING_NetjailNamespace *namespace = value; | ||
418 | |||
419 | GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes, | ||
420 | &log_nodes, | ||
421 | NULL); | ||
422 | return GNUNET_YES; | ||
423 | } | ||
424 | |||
425 | |||
426 | /** | ||
427 | * Helper function to log the configuration in case of a problem with configuration. | ||
428 | * | ||
429 | * @param topology The struct GNUNET_TESTING_NetjailTopology holding the configuration information. | ||
430 | */ | ||
431 | static int | ||
432 | log_topo (const struct GNUNET_TESTING_NetjailTopology *topology) | ||
433 | { | ||
434 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
435 | "plugin: %s spaces: %u nodes: %u known: %u\n", | ||
436 | topology->plugin, | ||
437 | topology->namespaces_n, | ||
438 | topology->nodes_m, | ||
439 | topology->nodes_x); | ||
440 | |||
441 | GNUNET_CONTAINER_multishortmap_iterate (topology->map_namespaces, | ||
442 | log_namespaces, NULL); | ||
443 | GNUNET_CONTAINER_multishortmap_iterate (topology->map_globals, &log_nodes, | ||
444 | NULL); | ||
445 | return GNUNET_YES; | ||
446 | } | ||
447 | |||
448 | |||
449 | /** | ||
450 | * This function extracts information about a specific node from the topology. | ||
451 | * | ||
452 | * @param num The global index number of the node. | ||
453 | * @param[out] node_ex A struct GNUNET_TESTING_NetjailNode with information about the node. | ||
454 | * @param[out] namespace_ex A struct GNUNET_TESTING_NetjailNamespace with information about the namespace | ||
455 | the node is in or NULL, if the node is a global node. | ||
456 | * @param[out] node_connections_ex A struct GNUNET_TESTING_NodeConnection with information about the connection | ||
457 | of this node to other nodes. | ||
458 | */ | ||
459 | static void | ||
460 | get_node_info (unsigned int num, | ||
461 | const struct GNUNET_TESTING_NetjailTopology *topology, | ||
462 | struct GNUNET_TESTING_NetjailNode **node_ex, | ||
463 | struct GNUNET_TESTING_NetjailNamespace **namespace_ex, | ||
464 | struct GNUNET_TESTING_NodeConnection **node_connections_ex) | ||
465 | { | ||
466 | struct GNUNET_ShortHashCode hkey; | ||
467 | struct GNUNET_HashCode hc; | ||
468 | unsigned int namespace_n; | ||
469 | unsigned int node_m; | ||
470 | struct GNUNET_TESTING_NetjailNode *node; | ||
471 | struct GNUNET_TESTING_NetjailNamespace *namespace; | ||
472 | struct GNUNET_TESTING_NodeConnection *node_connections = NULL; | ||
473 | |||
474 | log_topo (topology); | ||
475 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
476 | "num: %u \n", | ||
477 | num); | ||
478 | if (topology->nodes_x >= num) | ||
479 | { | ||
480 | |||
481 | GNUNET_CRYPTO_hash (&num, sizeof(num), &hc); | ||
482 | memcpy (&hkey, | ||
483 | &hc, | ||
484 | sizeof (hkey)); | ||
485 | node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals, | ||
486 | &hkey); | ||
487 | if (NULL != node) | ||
488 | { | ||
489 | *node_ex = node; | ||
490 | *node_connections_ex = node->node_connections_head; | ||
491 | } | ||
492 | } | ||
493 | else | ||
494 | { | ||
495 | namespace_n = (unsigned int) ceil ((double) (num - topology->nodes_x) | ||
496 | / topology->nodes_m); | ||
497 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
498 | "ceil num: %u nodes_x: %u nodes_m: %u namespace_n: %u\n", | ||
499 | num, | ||
500 | topology->nodes_x, | ||
501 | topology->nodes_m, | ||
502 | namespace_n); | ||
503 | GNUNET_CRYPTO_hash (&namespace_n, sizeof(namespace_n), &hc); | ||
504 | memcpy (&hkey, | ||
505 | &hc, | ||
506 | sizeof (hkey)); | ||
507 | namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces, | ||
508 | &hkey); | ||
509 | if (NULL != namespace) | ||
510 | { | ||
511 | node_m = num - topology->nodes_x - topology->nodes_m * (namespace_n - 1); | ||
512 | GNUNET_CRYPTO_hash (&node_m, sizeof(node_m), &hc); | ||
513 | memcpy (&hkey, | ||
514 | &hc, | ||
515 | sizeof (hkey)); | ||
516 | node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes, | ||
517 | &hkey); | ||
518 | if (NULL != node) | ||
519 | { | ||
520 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
521 | "node additional_connects: %u %p\n", | ||
522 | node->additional_connects, | ||
523 | node); | ||
524 | node_connections = node->node_connections_head; | ||
525 | } | ||
526 | *node_ex = node; | ||
527 | *namespace_ex = namespace; | ||
528 | *node_connections_ex = node_connections; | ||
529 | } | ||
530 | } | ||
531 | } | ||
532 | |||
533 | |||
534 | /** | ||
535 | * Get a node from the topology. | ||
536 | * | ||
537 | * @param num The specific node we want the connections for. | ||
538 | * @param topology The topology we get the connections from. | ||
539 | * @return The connections of the node. | ||
540 | */ | ||
541 | struct GNUNET_TESTING_NetjailNode * | ||
542 | GNUNET_TESTING_get_node (unsigned int num, | ||
543 | struct GNUNET_TESTING_NetjailTopology *topology) | ||
544 | { | ||
545 | struct GNUNET_TESTING_NetjailNode *node; | ||
546 | struct GNUNET_TESTING_NetjailNamespace *namespace; | ||
547 | struct GNUNET_TESTING_NodeConnection *node_connections; | ||
548 | |||
549 | get_node_info (num, topology, &node, &namespace, &node_connections); | ||
550 | |||
551 | return node; | ||
552 | |||
553 | } | ||
554 | |||
555 | |||
556 | /** | ||
557 | * Get the connections to other nodes for a specific node. | ||
558 | * | ||
559 | * @param num The specific node we want the connections for. | ||
560 | * @param topology The topology we get the connections from. | ||
561 | * @return The connections of the node. | ||
562 | */ | ||
563 | struct GNUNET_TESTING_NodeConnection * | ||
564 | GNUNET_TESTING_get_connections (unsigned int num, | ||
565 | const struct | ||
566 | GNUNET_TESTING_NetjailTopology *topology) | ||
567 | { | ||
568 | struct GNUNET_TESTING_NetjailNode *node; | ||
569 | struct GNUNET_TESTING_NetjailNamespace *namespace; | ||
570 | struct GNUNET_TESTING_NodeConnection *node_connections; | ||
571 | |||
572 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
573 | "get_connections\n"); | ||
574 | |||
575 | get_node_info (num, topology, &node, &namespace, &node_connections); | ||
576 | |||
577 | return node_connections; | ||
578 | } | ||
579 | |||
580 | |||
581 | int | ||
582 | free_nodes_cb (void *cls, | ||
583 | const struct GNUNET_ShortHashCode *key, | ||
584 | void *value) | ||
585 | { | ||
586 | (void) cls; | ||
587 | struct GNUNET_TESTING_NetjailNode *node = value; | ||
588 | struct GNUNET_TESTING_NodeConnection *pos_connection; | ||
589 | struct GNUNET_TESTING_AddressPrefix *pos_prefix; | ||
590 | |||
591 | while (NULL != (pos_connection = node->node_connections_head)) | ||
592 | { | ||
593 | while (NULL != (pos_prefix = pos_connection->address_prefixes_head)) | ||
594 | { | ||
595 | GNUNET_CONTAINER_DLL_remove (pos_connection->address_prefixes_head, | ||
596 | pos_connection->address_prefixes_tail, | ||
597 | pos_prefix); | ||
598 | GNUNET_free (pos_prefix->address_prefix); | ||
599 | GNUNET_free (pos_prefix); | ||
600 | } | ||
601 | GNUNET_CONTAINER_DLL_remove (node->node_connections_head, | ||
602 | node->node_connections_tail, | ||
603 | pos_connection); | ||
604 | GNUNET_free (pos_connection); | ||
605 | } | ||
606 | |||
607 | GNUNET_free (node->plugin); | ||
608 | GNUNET_free (node); | ||
609 | return GNUNET_OK; | ||
610 | } | ||
611 | |||
612 | |||
613 | int | ||
614 | free_namespaces_cb (void *cls, | ||
615 | const struct GNUNET_ShortHashCode *key, | ||
616 | void *value) | ||
617 | { | ||
618 | (void) cls; | ||
619 | struct GNUNET_TESTING_NetjailNamespace *namespace = value; | ||
620 | |||
621 | GNUNET_free (namespace->router); | ||
622 | GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes, free_nodes_cb, | ||
623 | namespace->nodes); | ||
624 | return GNUNET_OK; | ||
625 | |||
626 | } | ||
627 | |||
628 | |||
629 | /** | ||
630 | * Deallocate memory of the struct GNUNET_TESTING_NetjailTopology. | ||
631 | * | ||
632 | * @param topology The GNUNET_TESTING_NetjailTopology to be deallocated. | ||
633 | */ | ||
634 | void | ||
635 | GNUNET_TESTING_free_topology (struct GNUNET_TESTING_NetjailTopology *topology) | ||
636 | { | ||
637 | GNUNET_CONTAINER_multishortmap_iterate (topology->map_namespaces, | ||
638 | &free_namespaces_cb, | ||
639 | NULL); | ||
640 | GNUNET_CONTAINER_multishortmap_destroy (topology->map_namespaces); | ||
641 | GNUNET_CONTAINER_multishortmap_iterate (topology->map_globals, | ||
642 | &free_nodes_cb, | ||
643 | NULL); | ||
644 | GNUNET_CONTAINER_multishortmap_destroy (topology->map_globals); | ||
645 | GNUNET_free (topology->plugin); | ||
646 | GNUNET_free (topology); | ||
647 | } | ||
648 | |||
649 | |||
650 | unsigned int | ||
651 | GNUNET_TESTING_calculate_num ( | ||
652 | struct GNUNET_TESTING_NodeConnection *node_connection, | ||
653 | struct GNUNET_TESTING_NetjailTopology *topology) | ||
654 | { | ||
655 | unsigned int n, m, num; | ||
656 | |||
657 | n = node_connection->namespace_n; | ||
658 | m = node_connection->node_n; | ||
659 | |||
660 | if (0 == n) | ||
661 | num = m; | ||
662 | else | ||
663 | num = (n - 1) * topology->nodes_m + m + topology->nodes_x; | ||
664 | |||
665 | return num; | ||
666 | } | ||
667 | |||
668 | |||
669 | /** | ||
670 | * Get the address for a specific communicator from a connection. | ||
671 | * | ||
672 | * @param connection The connection we like to have the address from. | ||
673 | * @param prefix The communicator protocol prefix. | ||
674 | * @return The address of the communicator. | ||
675 | */ | ||
676 | char * | ||
677 | GNUNET_TESTING_get_address (struct GNUNET_TESTING_NodeConnection *connection, | ||
678 | const char *prefix) | ||
679 | { | ||
680 | struct GNUNET_TESTING_NetjailNode *node; | ||
681 | char *addr; | ||
682 | char *template; | ||
683 | unsigned int node_n; | ||
684 | |||
685 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
686 | "get address prefix: %s node_n: %u\n", | ||
687 | prefix, | ||
688 | connection->node_n); | ||
689 | |||
690 | node = connection->node; | ||
691 | if (connection->namespace_n == node->namespace_n) | ||
692 | { | ||
693 | template = CONNECT_ADDRESS_TEMPLATE; | ||
694 | node_n = connection->node_n; | ||
695 | } | ||
696 | else if (0 == connection->namespace_n) | ||
697 | { | ||
698 | template = KNOWN_CONNECT_ADDRESS_TEMPLATE; | ||
699 | node_n = connection->node_n; | ||
700 | } | ||
701 | else if (1 == connection->node_n) | ||
702 | { | ||
703 | template = ROUTER_CONNECT_ADDRESS_TEMPLATE; | ||
704 | node_n = connection->namespace_n; | ||
705 | } | ||
706 | else | ||
707 | { | ||
708 | return NULL; | ||
709 | } | ||
710 | |||
711 | if (0 == strcmp (PREFIX_TCP, prefix) || | ||
712 | 0 == strcmp (PREFIX_UDP, prefix) || | ||
713 | 0 == strcmp (PREFIX_UDP_NATTED, prefix) || | ||
714 | 0 == strcmp (PREFIX_TCP_NATTED, prefix)) | ||
715 | { | ||
716 | GNUNET_asprintf (&addr, | ||
717 | template, | ||
718 | prefix, | ||
719 | node_n); | ||
720 | } | ||
721 | else | ||
722 | { | ||
723 | GNUNET_assert (0); | ||
724 | } | ||
725 | |||
726 | return addr; | ||
727 | } | ||
728 | |||
729 | |||
730 | /** | ||
731 | * Get the number of unintentional additional connections the node waits for. | ||
732 | * | ||
733 | * @param num The specific node we want the additional connects for. | ||
734 | * @return The number of additional connects | ||
735 | */ | ||
736 | unsigned int | ||
737 | GNUNET_TESTING_get_additional_connects (unsigned int num, | ||
738 | struct GNUNET_TESTING_NetjailTopology * | ||
739 | topology) | ||
740 | { | ||
741 | struct GNUNET_TESTING_NetjailNode *node; | ||
742 | struct GNUNET_TESTING_NetjailNamespace *namespace; | ||
743 | struct GNUNET_TESTING_NodeConnection *node_connections; | ||
744 | |||
745 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
746 | "get_additional_connects\n"); | ||
747 | |||
748 | get_node_info (num, topology, &node, &namespace, &node_connections); | ||
749 | |||
750 | if (NULL == node) | ||
751 | { | ||
752 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
753 | "No info found for node %d\n", num); | ||
754 | return 0; | ||
755 | } | ||
756 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
757 | "node additional_connects for node %p\n", | ||
758 | node); | ||
759 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
760 | "node additional_connects: %u\n", | ||
761 | node->additional_connects); | ||
762 | |||
763 | return node->additional_connects; | ||
764 | } | ||
765 | |||
766 | |||
767 | static void | ||
768 | parse_ac (struct GNUNET_TESTING_NetjailNode *p_node, const char *token) | ||
769 | { | ||
770 | char *ac_value; | ||
771 | int ret; | ||
772 | |||
773 | ac_value = get_value ("AC", token); | ||
774 | if (NULL != ac_value) | ||
775 | { | ||
776 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
777 | "ac value: %s\n", | ||
778 | ac_value); | ||
779 | errno = 0; | ||
780 | ret = sscanf (ac_value, "%u", &p_node->additional_connects); | ||
781 | if (errno != 0) | ||
782 | { | ||
783 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sscanf"); | ||
784 | } | ||
785 | GNUNET_assert (0 < ret); | ||
786 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
787 | "AC %u\n", | ||
788 | p_node->additional_connects); | ||
789 | } | ||
790 | else | ||
791 | { | ||
792 | p_node->additional_connects = 0; | ||
793 | } | ||
794 | GNUNET_free (ac_value); | ||
795 | } | ||
796 | |||
797 | |||
798 | char * | ||
799 | GNUNET_TESTING_get_plugin_from_topo ( | ||
800 | struct GNUNET_TESTING_NetjailTopology *njt, | ||
801 | const char *my_node_id) | ||
802 | { | ||
803 | return njt->plugin; | ||
804 | } | ||
805 | |||
806 | |||
807 | /** | ||
808 | * Parse the topology data. | ||
809 | * | ||
810 | * @param data The topology data. | ||
811 | * @return The GNUNET_TESTING_NetjailTopology | ||
812 | */ | ||
813 | struct GNUNET_TESTING_NetjailTopology * | ||
814 | GNUNET_TESTING_get_topo_from_string_ (const char *input) | ||
815 | { | ||
816 | char *token; | ||
817 | char *key = NULL; | ||
818 | unsigned int out; | ||
819 | char *rest = NULL; | ||
820 | char *value = NULL; | ||
821 | char *value2; | ||
822 | char *data; | ||
823 | int ret; | ||
824 | struct GNUNET_TESTING_NetjailTopology *topo; | ||
825 | struct GNUNET_TESTING_NetjailRouter *router; | ||
826 | struct GNUNET_TESTING_NetjailNamespace *namespace; | ||
827 | struct GNUNET_HashCode hc; | ||
828 | |||
829 | data = GNUNET_strdup (input); | ||
830 | token = strtok_r (data, "\n", &rest); | ||
831 | topo = GNUNET_new (struct GNUNET_TESTING_NetjailTopology); | ||
832 | topo->map_namespaces = | ||
833 | GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO); | ||
834 | topo->map_globals = | ||
835 | GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO); | ||
836 | |||
837 | while (NULL != token) | ||
838 | { | ||
839 | if (NULL != key) | ||
840 | GNUNET_free (key); | ||
841 | key = get_key (token); | ||
842 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
843 | "In the loop with token: %s beginning with %s\n", | ||
844 | token, | ||
845 | key); | ||
846 | if (0 == strcmp (key, "M")) | ||
847 | { | ||
848 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
849 | "Get first Value for M.\n"); | ||
850 | out = get_first_value (token); | ||
851 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
852 | "M: %u\n", | ||
853 | out); | ||
854 | topo->nodes_m = out; | ||
855 | } | ||
856 | else if (0 == strcmp (key, "N")) | ||
857 | { | ||
858 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
859 | "Get first Value for N.\n"); | ||
860 | out = get_first_value (token); | ||
861 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
862 | "N: %u\n", | ||
863 | out); | ||
864 | topo->namespaces_n = out; | ||
865 | } | ||
866 | else if (0 == strcmp (key, "X")) | ||
867 | { | ||
868 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
869 | "Get first Value for X.\n"); | ||
870 | out = get_first_value (token); | ||
871 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
872 | "X: %u\n", | ||
873 | out); | ||
874 | topo->nodes_x = out; | ||
875 | } | ||
876 | else if (0 == strcmp (key, "AC")) | ||
877 | { | ||
878 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
879 | "Get first Value for AC.\n"); | ||
880 | out = get_first_value (token); | ||
881 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
882 | "AC: %u\n", | ||
883 | out); | ||
884 | topo->additional_connects = out; | ||
885 | } | ||
886 | else if (0 == strcmp (key, "T")) | ||
887 | { | ||
888 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
889 | "Get first string value for T.\n"); | ||
890 | value = get_first_string_value (token); | ||
891 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
892 | "value: %s\n", | ||
893 | value); | ||
894 | topo->plugin = value; | ||
895 | } | ||
896 | else if (0 == strcmp (key, "K")) | ||
897 | { | ||
898 | struct GNUNET_ShortHashCode hkey_k; | ||
899 | struct GNUNET_TESTING_NetjailNode *k_node = GNUNET_new (struct | ||
900 | GNUNET_TESTING_NetjailNode); | ||
901 | |||
902 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
903 | "Get first Value for K.\n"); | ||
904 | out = get_first_value (token); | ||
905 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
906 | "K: %u\n", | ||
907 | out); | ||
908 | k_node->node_n = out; | ||
909 | GNUNET_CRYPTO_hash (&out, sizeof(out), &hc); | ||
910 | memcpy (&hkey_k, | ||
911 | &hc, | ||
912 | sizeof (hkey_k)); | ||
913 | k_node->is_global = GNUNET_YES; | ||
914 | |||
915 | if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains ( | ||
916 | topo->map_globals, | ||
917 | &hkey_k)) | ||
918 | GNUNET_break (0); | ||
919 | else | ||
920 | GNUNET_CONTAINER_multishortmap_put (topo->map_globals, | ||
921 | &hkey_k, | ||
922 | k_node, | ||
923 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
924 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
925 | "Get value for key value on K.\n"); | ||
926 | value = get_value ("plugin", token); | ||
927 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
928 | "value: %s\n", | ||
929 | value); | ||
930 | k_node->plugin = value; | ||
931 | parse_ac (k_node, token); | ||
932 | node_connections (token, k_node); | ||
933 | GNUNET_free (value); | ||
934 | } | ||
935 | else if (0 == strcmp (key, "R")) | ||
936 | { | ||
937 | struct GNUNET_ShortHashCode hkey_r; | ||
938 | router = GNUNET_new (struct GNUNET_TESTING_NetjailRouter); | ||
939 | |||
940 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
941 | "Get first Value for R.\n"); | ||
942 | out = get_first_value (token); | ||
943 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
944 | "R: %u\n", | ||
945 | out); | ||
946 | GNUNET_CRYPTO_hash (&out, sizeof(out), &hc); | ||
947 | memcpy (&hkey_r, | ||
948 | &hc, | ||
949 | sizeof (hkey_r)); | ||
950 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
951 | "Get value for key tcp_port on R.\n"); | ||
952 | value = get_value ("tcp_port", token); | ||
953 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
954 | "tcp_port: %s\n", | ||
955 | value); | ||
956 | ret = sscanf (value, "%u", &(router->tcp_port)); | ||
957 | GNUNET_free (value); | ||
958 | GNUNET_break (0 != ret && 1 >= router->tcp_port); | ||
959 | |||
960 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
961 | "Get value for key udp_port on R.\n"); | ||
962 | value2 = get_value ("udp_port", token); | ||
963 | ret = sscanf (value2, "%u", &(router->udp_port)); | ||
964 | GNUNET_free (value2); | ||
965 | GNUNET_break (0 != ret && 1 >= router->udp_port); | ||
966 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
967 | "udp_port: %s\n", | ||
968 | value2); | ||
969 | GNUNET_free (value2); | ||
970 | if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains ( | ||
971 | topo->map_namespaces, | ||
972 | &hkey_r)) | ||
973 | { | ||
974 | namespace = GNUNET_CONTAINER_multishortmap_get (topo->map_namespaces, | ||
975 | &hkey_r); | ||
976 | } | ||
977 | else | ||
978 | { | ||
979 | namespace = GNUNET_new (struct GNUNET_TESTING_NetjailNamespace); | ||
980 | namespace->namespace_n = out; | ||
981 | namespace->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO); | ||
982 | GNUNET_CONTAINER_multishortmap_put (topo->map_namespaces, | ||
983 | &hkey_r, | ||
984 | namespace, | ||
985 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
986 | } | ||
987 | namespace->router = router; | ||
988 | |||
989 | } | ||
990 | else if (0 == strcmp (key, "P")) | ||
991 | { | ||
992 | struct GNUNET_TESTING_NetjailNode *p_node = GNUNET_new (struct | ||
993 | GNUNET_TESTING_NetjailNode); | ||
994 | struct GNUNET_ShortHashCode hkey_p; | ||
995 | |||
996 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
997 | "Get first Value for P.\n"); | ||
998 | out = get_first_value (token); | ||
999 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1000 | "P: %u\n", | ||
1001 | out); | ||
1002 | GNUNET_CRYPTO_hash (&out, sizeof(out), &hc); | ||
1003 | memcpy (&hkey_p, | ||
1004 | &hc, | ||
1005 | sizeof (hkey_p)); | ||
1006 | |||
1007 | if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains ( | ||
1008 | topo->map_namespaces, | ||
1009 | &hkey_p)) | ||
1010 | { | ||
1011 | namespace = GNUNET_CONTAINER_multishortmap_get (topo->map_namespaces, | ||
1012 | &hkey_p); | ||
1013 | } | ||
1014 | else | ||
1015 | { | ||
1016 | namespace = GNUNET_new (struct GNUNET_TESTING_NetjailNamespace); | ||
1017 | namespace->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO); | ||
1018 | namespace->namespace_n = out; | ||
1019 | GNUNET_CONTAINER_multishortmap_put (topo->map_namespaces, | ||
1020 | &hkey_p, | ||
1021 | namespace, | ||
1022 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
1023 | } | ||
1024 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1025 | "Get second Value for P.\n"); | ||
1026 | out = get_second_value (token); | ||
1027 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1028 | "P: %u\n", | ||
1029 | out); | ||
1030 | GNUNET_CRYPTO_hash (&out, sizeof(out), &hc); | ||
1031 | memcpy (&hkey_p, | ||
1032 | &hc, | ||
1033 | sizeof (hkey_p)); | ||
1034 | if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains ( | ||
1035 | namespace->nodes, | ||
1036 | &hkey_p)) | ||
1037 | { | ||
1038 | GNUNET_break (0); | ||
1039 | } | ||
1040 | else | ||
1041 | { | ||
1042 | |||
1043 | GNUNET_CONTAINER_multishortmap_put (namespace->nodes, | ||
1044 | &hkey_p, | ||
1045 | p_node, | ||
1046 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
1047 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1048 | "Get value for key plugin on P.\n"); | ||
1049 | value = get_value ("plugin", token); | ||
1050 | if (NULL != value) | ||
1051 | { | ||
1052 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1053 | "plugin: %s\n", | ||
1054 | value); | ||
1055 | p_node->plugin = value; | ||
1056 | } | ||
1057 | p_node->node_n = out; | ||
1058 | p_node->namespace_n = namespace->namespace_n; | ||
1059 | } | ||
1060 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1061 | "Get AC Value for P.\n"); | ||
1062 | parse_ac (p_node, token); | ||
1063 | node_connections (token, p_node); | ||
1064 | } | ||
1065 | token = strtok_r (NULL, "\n", &rest); | ||
1066 | if (NULL != token) | ||
1067 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1068 | "Next token %s\n", | ||
1069 | token); | ||
1070 | } | ||
1071 | if (NULL != key) | ||
1072 | GNUNET_free (key); | ||
1073 | GNUNET_free (data); | ||
1074 | return topo; | ||
1075 | } | ||
1076 | |||
1077 | |||
1078 | GNUNET_TESTING_SIMPLE_NETJAIL_TRAITS ( | ||
1079 | GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, | ||
1080 | GNUNET_TESTING) | ||
1081 | |||
1082 | |||
1083 | /* end of netjail.c */ | ||
diff --git a/src/lib/testing/testing_api_topology.h b/src/lib/testing/testing_api_topology.h new file mode 100644 index 000000000..7306f0728 --- /dev/null +++ b/src/lib/testing/testing_api_topology.h | |||
@@ -0,0 +1,367 @@ | |||
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 | * @brief API for writing an interpreter to test GNUnet components | ||
23 | * @author Christian Grothoff <christian@grothoff.org> | ||
24 | * @author Marcello Stanisci | ||
25 | * @author t3sserakt | ||
26 | */ | ||
27 | #ifndef NETJAIL_H | ||
28 | #define NETJAIL_H | ||
29 | |||
30 | #include "gnunet_util_lib.h" | ||
31 | #include "gnunet_testing_lib.h" | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Router of a netjail subnet. | ||
36 | */ | ||
37 | struct GNUNET_TESTING_NetjailRouter | ||
38 | { | ||
39 | /** | ||
40 | * Will tcp be forwarded? | ||
41 | */ | ||
42 | unsigned int tcp_port; | ||
43 | |||
44 | /** | ||
45 | * Will udp be forwarded? | ||
46 | */ | ||
47 | unsigned int udp_port; | ||
48 | }; | ||
49 | |||
50 | |||
51 | /** | ||
52 | * Enum for the different types of nodes. | ||
53 | */ | ||
54 | enum GNUNET_TESTING_NodeType | ||
55 | { | ||
56 | /** | ||
57 | * Node in a subnet. | ||
58 | */ | ||
59 | GNUNET_TESTING_SUBNET_NODE, | ||
60 | |||
61 | /** | ||
62 | * Global known node. | ||
63 | */ | ||
64 | GNUNET_TESTING_GLOBAL_NODE | ||
65 | }; | ||
66 | |||
67 | /** | ||
68 | * Protocol address prefix für a connection between nodes. | ||
69 | */ | ||
70 | struct GNUNET_TESTING_AddressPrefix | ||
71 | { | ||
72 | /** | ||
73 | * Pointer to the previous prefix in the DLL. | ||
74 | */ | ||
75 | struct GNUNET_TESTING_AddressPrefix *prev; | ||
76 | |||
77 | /** | ||
78 | * Pointer to the next prefix in the DLL. | ||
79 | */ | ||
80 | struct GNUNET_TESTING_AddressPrefix *next; | ||
81 | |||
82 | /** | ||
83 | * The address prefix. | ||
84 | */ | ||
85 | char *address_prefix; | ||
86 | }; | ||
87 | |||
88 | |||
89 | /** | ||
90 | * Node in a netjail topology. | ||
91 | */ | ||
92 | struct GNUNET_TESTING_NetjailNode; | ||
93 | |||
94 | /** | ||
95 | * Connection to another node. | ||
96 | */ | ||
97 | struct GNUNET_TESTING_NodeConnection | ||
98 | { | ||
99 | /** | ||
100 | * Pointer to the previous connection in the DLL. | ||
101 | */ | ||
102 | struct GNUNET_TESTING_NodeConnection *prev; | ||
103 | |||
104 | /** | ||
105 | * Pointer to the next connection in the DLL. | ||
106 | */ | ||
107 | struct GNUNET_TESTING_NodeConnection *next; | ||
108 | |||
109 | /** | ||
110 | * The number of the subnet of the node this connection points to. This is 0, | ||
111 | * if the node is a global known node. | ||
112 | */ | ||
113 | unsigned int namespace_n; | ||
114 | |||
115 | /** | ||
116 | * The number of the node this connection points to. | ||
117 | */ | ||
118 | unsigned int node_n; | ||
119 | |||
120 | /** | ||
121 | * The type of the node this connection points to. | ||
122 | */ | ||
123 | enum GNUNET_TESTING_NodeType node_type; | ||
124 | |||
125 | /** | ||
126 | * The node which establish the connection | ||
127 | */ | ||
128 | struct GNUNET_TESTING_NetjailNode *node; | ||
129 | |||
130 | /** | ||
131 | * Head of the DLL with the address prefixes for the protocolls this node is reachable. | ||
132 | */ | ||
133 | struct GNUNET_TESTING_AddressPrefix *address_prefixes_head; | ||
134 | |||
135 | /** | ||
136 | * Tail of the DLL with the address prefixes for the protocolls this node is reachable. | ||
137 | */ | ||
138 | struct GNUNET_TESTING_AddressPrefix *address_prefixes_tail; | ||
139 | }; | ||
140 | |||
141 | /** | ||
142 | * Node in the netjail topology. | ||
143 | */ | ||
144 | struct GNUNET_TESTING_NetjailNode | ||
145 | { | ||
146 | /** | ||
147 | * Head of the DLL with the connections which shall be established to other nodes. | ||
148 | */ | ||
149 | struct GNUNET_TESTING_NodeConnection *node_connections_head; | ||
150 | |||
151 | /** | ||
152 | * Tail of the DLL with the connections which shall be established to other nodes. | ||
153 | */ | ||
154 | struct GNUNET_TESTING_NodeConnection *node_connections_tail; | ||
155 | |||
156 | /** | ||
157 | * Plugin for the test case to be run on this node. | ||
158 | */ | ||
159 | char *plugin; | ||
160 | |||
161 | /** | ||
162 | * Flag indicating if this node is a global known node. | ||
163 | */ | ||
164 | unsigned int is_global; | ||
165 | |||
166 | /** | ||
167 | * The number of the subnet this node is running in. | ||
168 | */ | ||
169 | unsigned int namespace_n; | ||
170 | |||
171 | /** | ||
172 | * The number of this node in the subnet. | ||
173 | */ | ||
174 | unsigned int node_n; | ||
175 | |||
176 | /** | ||
177 | * The overall number of the node in the whole test system. | ||
178 | */ | ||
179 | unsigned int node_number; | ||
180 | |||
181 | /** | ||
182 | * The number of unintentional additional connections this node waits for. This overwrites the global additional_connects value. | ||
183 | */ | ||
184 | unsigned int additional_connects; | ||
185 | |||
186 | /** | ||
187 | * The number of cmds waiting for a specific barrier. | ||
188 | */ | ||
189 | unsigned int expected_reaches; | ||
190 | }; | ||
191 | |||
192 | |||
193 | /** | ||
194 | * Subnet in a topology. | ||
195 | */ | ||
196 | struct GNUNET_TESTING_NetjailNamespace | ||
197 | { | ||
198 | /** | ||
199 | * The number of the subnet. | ||
200 | */ | ||
201 | unsigned int namespace_n; | ||
202 | |||
203 | /** | ||
204 | * Router of the subnet. | ||
205 | */ | ||
206 | struct GNUNET_TESTING_NetjailRouter *router; | ||
207 | |||
208 | /** | ||
209 | * Hash map containing the nodes in this subnet. | ||
210 | */ | ||
211 | struct GNUNET_CONTAINER_MultiShortmap *nodes; | ||
212 | }; | ||
213 | |||
214 | /** | ||
215 | * Toplogy of our netjail setup. | ||
216 | */ | ||
217 | struct GNUNET_TESTING_NetjailTopology | ||
218 | { | ||
219 | |||
220 | /** | ||
221 | * Default plugin for the test case to be run on nodes. | ||
222 | */ | ||
223 | char *plugin; | ||
224 | |||
225 | /** | ||
226 | * Total number of namespaces in the topology; | ||
227 | * numbered starting from 1 (!). | ||
228 | */ | ||
229 | unsigned int total; | ||
230 | |||
231 | /** | ||
232 | * Number of subnets. | ||
233 | */ | ||
234 | unsigned int namespaces_n; | ||
235 | |||
236 | /** | ||
237 | * Number of nodes per subnet. | ||
238 | */ | ||
239 | unsigned int nodes_m; | ||
240 | |||
241 | /** | ||
242 | * Number of global known nodes. | ||
243 | */ | ||
244 | unsigned int nodes_x; | ||
245 | |||
246 | /** | ||
247 | * Hash map containing the subnets (for natted nodes) of the topology. | ||
248 | */ | ||
249 | struct GNUNET_CONTAINER_MultiShortmap *map_namespaces; | ||
250 | |||
251 | /** | ||
252 | * Hash map containing the global known nodes which are not natted. | ||
253 | */ | ||
254 | struct GNUNET_CONTAINER_MultiShortmap *map_globals; | ||
255 | |||
256 | /** | ||
257 | * Additional connects we do expect, beside the connects which are configured in the topology. | ||
258 | */ | ||
259 | unsigned int additional_connects; | ||
260 | }; | ||
261 | |||
262 | |||
263 | /** | ||
264 | * Parse the topology data. | ||
265 | * | ||
266 | * @param data The topology data. | ||
267 | * @return The GNUNET_TESTING_NetjailTopology | ||
268 | */ | ||
269 | struct GNUNET_TESTING_NetjailTopology * | ||
270 | GNUNET_TESTING_get_topo_from_string_ (const char *data); | ||
271 | |||
272 | |||
273 | /** | ||
274 | * Get the number of unintentional additional connections the node waits for. | ||
275 | * | ||
276 | * @param num The specific node we want the additional connects for. | ||
277 | * @return The number of additional connects | ||
278 | */ | ||
279 | unsigned int | ||
280 | GNUNET_TESTING_get_additional_connects ( | ||
281 | unsigned int num, | ||
282 | struct GNUNET_TESTING_NetjailTopology *topology); | ||
283 | |||
284 | |||
285 | /** | ||
286 | * Get a node from the topology. | ||
287 | * | ||
288 | * @param num The specific node we want the connections for. | ||
289 | * @param topology The topology we get the connections from. | ||
290 | * @return The connections of the node. | ||
291 | */ | ||
292 | struct GNUNET_TESTING_NetjailNode * | ||
293 | GNUNET_TESTING_get_node (unsigned int num, | ||
294 | struct GNUNET_TESTING_NetjailTopology *topology); | ||
295 | |||
296 | |||
297 | /** | ||
298 | * Get the connections to other nodes for a specific node. | ||
299 | * | ||
300 | * @param num The specific node we want the connections for. | ||
301 | * @param topology The topology we get the connections from. | ||
302 | * @return The connections of the node. | ||
303 | */ | ||
304 | struct GNUNET_TESTING_NodeConnection * | ||
305 | GNUNET_TESTING_get_connections ( | ||
306 | unsigned int num, | ||
307 | const struct GNUNET_TESTING_NetjailTopology *topology); | ||
308 | |||
309 | |||
310 | /** | ||
311 | * Get the address for a specific communicator from a connection. | ||
312 | * | ||
313 | * @param connection The connection we like to have the address from. | ||
314 | * @param prefix The communicator protocol prefix. | ||
315 | * @return The address of the communicator. | ||
316 | */ | ||
317 | char * | ||
318 | GNUNET_TESTING_get_address ( | ||
319 | struct GNUNET_TESTING_NodeConnection *connection, | ||
320 | const char *prefix); | ||
321 | |||
322 | |||
323 | /** | ||
324 | * Get the global plugin name form the topology file | ||
325 | */ | ||
326 | char * | ||
327 | GNUNET_TESTING_get_plugin_from_topo ( | ||
328 | struct GNUNET_TESTING_NetjailTopology *njt, | ||
329 | const char *my_node_id); | ||
330 | |||
331 | |||
332 | /** | ||
333 | * Deallocate memory of the struct GNUNET_TESTING_NetjailTopology. | ||
334 | * | ||
335 | * @param[in] topology The GNUNET_TESTING_NetjailTopology to be deallocated. | ||
336 | */ | ||
337 | void | ||
338 | GNUNET_TESTING_free_topology (struct GNUNET_TESTING_NetjailTopology *topology); | ||
339 | |||
340 | |||
341 | /** | ||
342 | * Calculate the unique id identifying a node from a given connection. | ||
343 | * | ||
344 | * @param node_connection The connection we calculate the id from. | ||
345 | * @param topology The topology we get all needed information from. | ||
346 | * @return The unique id of the node from the connection. | ||
347 | */ | ||
348 | unsigned int | ||
349 | GNUNET_TESTING_calculate_num ( | ||
350 | struct GNUNET_TESTING_NodeConnection *node_connection, | ||
351 | struct GNUNET_TESTING_NetjailTopology *topology); | ||
352 | |||
353 | |||
354 | /** | ||
355 | * Call #op on all simple traits. | ||
356 | */ | ||
357 | #define GNUNET_TESTING_SIMPLE_NETJAIL_TRAITS(op, prefix) \ | ||
358 | op (prefix, topology, const struct GNUNET_TESTING_NetjailTopology) \ | ||
359 | op (prefix, topology_string, const char) \ | ||
360 | op (prefix, async_context, struct GNUNET_TESTING_AsyncContext) \ | ||
361 | op (prefix, helper_handles, const struct GNUNET_HELPER_Handle *) | ||
362 | |||
363 | GNUNET_TESTING_SIMPLE_NETJAIL_TRAITS (GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT, | ||
364 | GNUNET_TESTING) | ||
365 | |||
366 | |||
367 | #endif | ||
diff --git a/src/service/testing/testing_api_traits.c b/src/lib/testing/testing_api_traits.c index 18faa2d04..0726a7576 100644 --- a/src/service/testing/testing_api_traits.c +++ b/src/lib/testing/testing_api_traits.c | |||
@@ -26,23 +26,11 @@ | |||
26 | * @author t3sserakt | 26 | * @author t3sserakt |
27 | */ | 27 | */ |
28 | #include "platform.h" | 28 | #include "platform.h" |
29 | #include "gnunet_testing_ng_lib.h" | 29 | #include "gnunet_testing_lib.h" |
30 | #include "gnunet_testing_plugin.h" | ||
31 | #include "gnunet_testing_barrier.h" | ||
32 | #include "gnunet_testing_netjail_lib.h" | ||
33 | 30 | ||
34 | 31 | ||
35 | /* FIXME: move these into respective sub-libs? */ | 32 | GNUNET_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, |
36 | 33 | GNUNET_TESTING) | |
37 | GNUNET_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, GNUNET_TESTING) | ||
38 | |||
39 | GNUNET_TESTING_INDEXED_TRAITS (GNUNET_TESTING_MAKE_IMPL_INDEXED_TRAIT, GNUNET_TESTING) | ||
40 | |||
41 | GNUNET_TESTING_LOOP_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, GNUNET_TESTING) | ||
42 | |||
43 | GNUNET_TESTING_LOOP_INDEXED_TRAITS (GNUNET_TESTING_MAKE_IMPL_INDEXED_TRAIT, GNUNET_TESTING) | ||
44 | |||
45 | GNUNET_TESTING_SIMPLE_NETJAIL_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, GNUNET_TESTING) | ||
46 | 34 | ||
47 | /** | 35 | /** |
48 | * End a trait array. Usually, commands offer several traits, | 36 | * End a trait array. Usually, commands offer several traits, |
diff --git a/src/lib/testing/testing_cmds.h b/src/lib/testing/testing_cmds.h new file mode 100644 index 000000000..3493dbbf9 --- /dev/null +++ b/src/lib/testing/testing_cmds.h | |||
@@ -0,0 +1,106 @@ | |||
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_cmds.h | ||
23 | * @brief Message formats for communication between testing cmds helper and testcase plugins. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | |||
27 | #ifndef TESTING_CMDS_H | ||
28 | #define TESTING_CMDS_H | ||
29 | |||
30 | #define HELPER_CMDS_BINARY "gnunet-cmds-helper" | ||
31 | #include "gnunet_common.h" | ||
32 | |||
33 | GNUNET_NETWORK_STRUCT_BEGIN | ||
34 | |||
35 | /** | ||
36 | * Initialization message for gnunet-cmds-testbed to start cmd binary. | ||
37 | */ | ||
38 | struct GNUNET_TESTING_CommandHelperInit | ||
39 | { | ||
40 | /** | ||
41 | * Type is #GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT | ||
42 | */ | ||
43 | struct GNUNET_MessageHeader header; | ||
44 | |||
45 | /** | ||
46 | * Number of barriers the helper inherits. | ||
47 | */ | ||
48 | uint32_t barrier_count GNUNET_PACKED; | ||
49 | |||
50 | /* Followed by barrier_count barrier hashes */ | ||
51 | |||
52 | /* Followed by topology data */ | ||
53 | }; | ||
54 | |||
55 | |||
56 | struct GNUNET_TESTING_CommandLocalFinished | ||
57 | { | ||
58 | /** | ||
59 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED | ||
60 | */ | ||
61 | struct GNUNET_MessageHeader header; | ||
62 | |||
63 | /** | ||
64 | * The exit status local test return with in NBO. | ||
65 | */ | ||
66 | uint32_t rv GNUNET_PACKED; | ||
67 | }; | ||
68 | |||
69 | |||
70 | /** | ||
71 | * Child to parent: I reached the given barrier, | ||
72 | * increment the counter (or pass to grandparent). | ||
73 | */ | ||
74 | struct GNUNET_TESTING_CommandBarrierReached | ||
75 | { | ||
76 | struct GNUNET_MessageHeader header; | ||
77 | struct GNUNET_ShortHashCode barrier_key; | ||
78 | }; | ||
79 | |||
80 | |||
81 | /** | ||
82 | * Parent to child: you're inheriting a barrier. | ||
83 | * If the barrier was already satisfied, the parent | ||
84 | * must sent a separate barrier satisfied message. | ||
85 | */ | ||
86 | struct GNUNET_TESTING_CommandBarrierInherited | ||
87 | { | ||
88 | struct GNUNET_MessageHeader header; | ||
89 | struct GNUNET_ShortHashCode barrier_key; | ||
90 | }; | ||
91 | |||
92 | |||
93 | /** | ||
94 | * Parent to child: this barrier was satisfied. | ||
95 | */ | ||
96 | struct GNUNET_TESTING_CommandBarrierSatisfied | ||
97 | { | ||
98 | struct GNUNET_MessageHeader header; | ||
99 | struct GNUNET_ShortHashCode barrier_key; | ||
100 | }; | ||
101 | |||
102 | |||
103 | GNUNET_NETWORK_STRUCT_END | ||
104 | |||
105 | #endif | ||
106 | /* end of testing_cmds.h */ | ||
diff --git a/src/lib/util/.gitignore b/src/lib/util/.gitignore index c6306639c..c31c9ec28 100644 --- a/src/lib/util/.gitignore +++ b/src/lib/util/.gitignore | |||
@@ -20,6 +20,7 @@ test_container_meta_data | |||
20 | test_container_multihashmap | 20 | test_container_multihashmap |
21 | test_container_multihashmap32 | 21 | test_container_multihashmap32 |
22 | test_container_multipeermap | 22 | test_container_multipeermap |
23 | test_crypto_blind | ||
23 | test_crypto_crc | 24 | test_crypto_crc |
24 | test_crypto_ecc_dlog | 25 | test_crypto_ecc_dlog |
25 | test_crypto_ecdh_ecdsa | 26 | test_crypto_ecdh_ecdsa |
@@ -28,6 +29,7 @@ test_crypto_ecdhe | |||
28 | test_crypto_ecdsa | 29 | test_crypto_ecdsa |
29 | test_crypto_eddsa | 30 | test_crypto_eddsa |
30 | test_crypto_edx25519 | 31 | test_crypto_edx25519 |
32 | test_crypto_elligator | ||
31 | test_crypto_hash | 33 | test_crypto_hash |
32 | test_crypto_hash_context | 34 | test_crypto_hash_context |
33 | test_crypto_hkdf | 35 | test_crypto_hkdf |
diff --git a/src/lib/util/Makefile.am b/src/lib/util/Makefile.am index 00538847b..4d052c57b 100644 --- a/src/lib/util/Makefile.am +++ b/src/lib/util/Makefile.am | |||
@@ -147,7 +147,7 @@ libgnunetutil_la_LIBADD = \ | |||
147 | 147 | ||
148 | libgnunetutil_la_LDFLAGS = \ | 148 | libgnunetutil_la_LDFLAGS = \ |
149 | $(GN_LIB_LDFLAGS) \ | 149 | $(GN_LIB_LDFLAGS) \ |
150 | -version-info 16:0:0 | 150 | -version-info 16:1:0 |
151 | 151 | ||
152 | lib_LTLIBRARIES = libgnunetutil.la | 152 | lib_LTLIBRARIES = libgnunetutil.la |
153 | 153 | ||
diff --git a/src/lib/util/common_allocation.c b/src/lib/util/common_allocation.c index 36d49eddb..afd701720 100644 --- a/src/lib/util/common_allocation.c +++ b/src/lib/util/common_allocation.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2001, 2002, 2003, 2005, 2006 GNUnet e.V. | 3 | Copyright (C) 2001, 2002, 2003, 2005, 2006, 2024 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 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 | 6 | under the terms of the GNU Affero General Public License as published |
@@ -34,60 +34,41 @@ | |||
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | #define LOG(kind, ...) \ | 36 | #define LOG(kind, ...) \ |
37 | GNUNET_log_from (kind, "util-common-allocation", __VA_ARGS__) | 37 | GNUNET_log_from (kind, "util-common-allocation", __VA_ARGS__) |
38 | 38 | ||
39 | #define LOG_STRERROR(kind, syscall) \ | 39 | #define LOG_STRERROR(kind, syscall) \ |
40 | GNUNET_log_from_strerror (kind, "util-common-allocation", syscall) | 40 | GNUNET_log_from_strerror (kind, "util-common-allocation", syscall) |
41 | 41 | ||
42 | #ifndef INT_MAX | 42 | #ifndef INT_MAX |
43 | #define INT_MAX 0x7FFFFFFF | 43 | #define INT_MAX 0x7FFFFFFF |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | 46 | ||
47 | /** | ||
48 | * Allocate memory. Checks the return value, aborts if no more | ||
49 | * memory is available. | ||
50 | * | ||
51 | * @param size how many bytes of memory to allocate, do NOT use | ||
52 | * this function (or GNUNET_malloc()) to allocate more than several MB | ||
53 | * of memory, if you are possibly needing a very large chunk use | ||
54 | * #GNUNET_xmalloc_unchecked_() instead. | ||
55 | * @param filename where in the code was the call to GNUNET_malloc() | ||
56 | * @param linenumber where in the code was the call to GNUNET_malloc() | ||
57 | * @return pointer to size bytes of memory | ||
58 | */ | ||
59 | void * | 47 | void * |
60 | GNUNET_xmalloc_ (size_t size, const char *filename, int linenumber) | 48 | GNUNET_xmalloc_ (size_t size, |
49 | const char *filename, | ||
50 | int linenumber) | ||
61 | { | 51 | { |
62 | void *ret; | 52 | void *ret; |
63 | 53 | ||
64 | /* As a security precaution, we generally do not allow very large | 54 | /* As a security precaution, we generally do not allow very large |
65 | * allocations using the default 'GNUNET_malloc()' macro */ | 55 | * allocations using the default 'GNUNET_malloc()' macro */ |
66 | GNUNET_assert_at (size <= GNUNET_MAX_MALLOC_CHECKED, filename, linenumber); | 56 | GNUNET_assert_at (size <= GNUNET_MAX_MALLOC_CHECKED, |
67 | ret = GNUNET_xmalloc_unchecked_ (size, filename, linenumber); | 57 | filename, |
58 | linenumber); | ||
59 | ret = GNUNET_xmalloc_unchecked_ (size, | ||
60 | filename, | ||
61 | linenumber); | ||
68 | if (NULL == ret) | 62 | if (NULL == ret) |
69 | { | 63 | { |
70 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "malloc"); | 64 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, |
65 | "malloc"); | ||
71 | GNUNET_assert (0); | 66 | GNUNET_assert (0); |
72 | } | 67 | } |
73 | return ret; | 68 | return ret; |
74 | } | 69 | } |
75 | 70 | ||
76 | 71 | ||
77 | /** | ||
78 | * Allocate memory for a two dimensional array in one block | ||
79 | * and set up pointers. Aborts if no more memory is available. | ||
80 | * Don't use GNUNET_xnew_array_2d_ directly. Use the | ||
81 | * #GNUNET_new_array_2d macro. | ||
82 | * The memory of the elements will be zero'ed out. | ||
83 | * | ||
84 | * @param n size of the first dimension | ||
85 | * @param m size of the second dimension | ||
86 | * @param elementSize size of a single element in bytes | ||
87 | * @param filename where is this call being made (for debugging) | ||
88 | * @param linenumber line where this call is being made (for debugging) | ||
89 | * @return allocated memory, never NULL | ||
90 | */ | ||
91 | void ** | 72 | void ** |
92 | GNUNET_xnew_array_2d_ (size_t n, | 73 | GNUNET_xnew_array_2d_ (size_t n, |
93 | size_t m, | 74 | size_t m, |
@@ -109,21 +90,6 @@ GNUNET_xnew_array_2d_ (size_t n, | |||
109 | } | 90 | } |
110 | 91 | ||
111 | 92 | ||
112 | /** | ||
113 | * Allocate memory for a three dimensional array in one block | ||
114 | * and set up pointers. Aborts if no more memory is available. | ||
115 | * Don't use GNUNET_xnew_array_3d_ directly. Use the | ||
116 | * #GNUNET_new_array_3d macro. | ||
117 | * The memory of the elements will be zero'ed out. | ||
118 | * | ||
119 | * @param n size of the first dimension | ||
120 | * @param m size of the second dimension | ||
121 | * @param o size of the third dimension | ||
122 | * @param elementSize size of a single element in bytes | ||
123 | * @param filename where is this call being made (for debugging) | ||
124 | * @param linenumber line where this call is being made (for debugging) | ||
125 | * @return allocated memory, never NULL | ||
126 | */ | ||
127 | void *** | 93 | void *** |
128 | GNUNET_xnew_array_3d_ (size_t n, | 94 | GNUNET_xnew_array_3d_ (size_t n, |
129 | size_t m, | 95 | size_t m, |
@@ -166,58 +132,50 @@ GNUNET_xmemdup_ (const void *buf, | |||
166 | 132 | ||
167 | /* As a security precaution, we generally do not allow very large | 133 | /* As a security precaution, we generally do not allow very large |
168 | * allocations here */ | 134 | * allocations here */ |
169 | GNUNET_assert_at (size <= GNUNET_MAX_MALLOC_CHECKED, filename, linenumber); | 135 | GNUNET_assert_at (size <= GNUNET_MAX_MALLOC_CHECKED, |
170 | GNUNET_assert_at (size < INT_MAX, filename, linenumber); | 136 | filename, |
137 | linenumber); | ||
138 | GNUNET_assert_at (size < INT_MAX, | ||
139 | filename, | ||
140 | linenumber); | ||
171 | ret = malloc (size); | 141 | ret = malloc (size); |
172 | if (ret == NULL) | 142 | if (NULL == ret) |
173 | { | 143 | { |
174 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "malloc"); | 144 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, |
145 | "malloc"); | ||
175 | GNUNET_assert (0); | 146 | GNUNET_assert (0); |
176 | } | 147 | } |
177 | GNUNET_memcpy (ret, buf, size); | 148 | GNUNET_memcpy (ret, |
149 | buf, | ||
150 | size); | ||
178 | return ret; | 151 | return ret; |
179 | } | 152 | } |
180 | 153 | ||
181 | 154 | ||
182 | /** | ||
183 | * Wrapper around malloc(). Allocates size bytes of memory. | ||
184 | * The memory will be zero'ed out. | ||
185 | * | ||
186 | * @param size the number of bytes to allocate | ||
187 | * @param filename where in the code was the call to GNUNET_malloc_unchecked() | ||
188 | * @param linenumber where in the code was the call to GNUNET_malloc_unchecked() | ||
189 | * @return pointer to size bytes of memory, NULL if we do not have enough memory | ||
190 | */ | ||
191 | void * | 155 | void * |
192 | GNUNET_xmalloc_unchecked_ (size_t size, const char *filename, int linenumber) | 156 | GNUNET_xmalloc_unchecked_ (size_t size, |
157 | const char *filename, | ||
158 | int linenumber) | ||
193 | { | 159 | { |
194 | void *result; | 160 | void *result; |
195 | 161 | ||
196 | (void) filename; | 162 | (void) filename; |
197 | (void) linenumber; | 163 | (void) linenumber; |
198 | |||
199 | result = malloc (size); | 164 | result = malloc (size); |
200 | if (NULL == result) | 165 | if (NULL == result) |
201 | return NULL; | 166 | return NULL; |
202 | memset (result, 0, size); | 167 | memset (result, |
203 | 168 | 0, | |
169 | size); | ||
204 | return result; | 170 | return result; |
205 | } | 171 | } |
206 | 172 | ||
207 | 173 | ||
208 | /** | ||
209 | * Reallocate memory. Checks the return value, aborts if no more | ||
210 | * memory is available. | ||
211 | * The content of the intersection of the new and old size will be unchanged. | ||
212 | * | ||
213 | * @param ptr the pointer to reallocate | ||
214 | * @param n how many bytes of memory to allocate | ||
215 | * @param filename where in the code was the call to GNUNET_realloc() | ||
216 | * @param linenumber where in the code was the call to GNUNET_realloc() | ||
217 | * @return pointer to size bytes of memory | ||
218 | */ | ||
219 | void * | 174 | void * |
220 | GNUNET_xrealloc_ (void *ptr, size_t n, const char *filename, int linenumber) | 175 | GNUNET_xrealloc_ (void *ptr, |
176 | size_t n, | ||
177 | const char *filename, | ||
178 | int linenumber) | ||
221 | { | 179 | { |
222 | (void) filename; | 180 | (void) filename; |
223 | (void) linenumber; | 181 | (void) linenumber; |
@@ -249,7 +207,8 @@ GNUNET_xrealloc_ (void *ptr, size_t n, const char *filename, int linenumber) | |||
249 | ptr = realloc (ptr, n); | 207 | ptr = realloc (ptr, n); |
250 | if ((NULL == ptr) && (n > 0)) | 208 | if ((NULL == ptr) && (n > 0)) |
251 | { | 209 | { |
252 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "realloc"); | 210 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, |
211 | "realloc"); | ||
253 | GNUNET_assert (0); | 212 | GNUNET_assert (0); |
254 | } | 213 | } |
255 | return ptr; | 214 | return ptr; |
@@ -272,14 +231,6 @@ GNUNET_xrealloc_ (void *ptr, size_t n, const char *filename, int linenumber) | |||
272 | #define M_SIZE(p) malloc_size (p) | 231 | #define M_SIZE(p) malloc_size (p) |
273 | #endif | 232 | #endif |
274 | 233 | ||
275 | /** | ||
276 | * Free memory. Merely a wrapper for the case that we | ||
277 | * want to keep track of allocations. | ||
278 | * | ||
279 | * @param ptr the pointer to free | ||
280 | * @param filename where in the code was the call to GNUNET_free() | ||
281 | * @param linenumber where in the code was the call to GNUNET_free() | ||
282 | */ | ||
283 | void | 234 | void |
284 | GNUNET_xfree_ (void *ptr, | 235 | GNUNET_xfree_ (void *ptr, |
285 | const char *filename, | 236 | const char *filename, |
@@ -304,35 +255,37 @@ GNUNET_xfree_ (void *ptr, | |||
304 | } | 255 | } |
305 | 256 | ||
306 | 257 | ||
307 | /** | ||
308 | * Dup a string (same semantics as strdup). | ||
309 | * | ||
310 | * @param str the string to dup | ||
311 | * @param filename where in the code was the call to GNUNET_strdup() | ||
312 | * @param linenumber where in the code was the call to GNUNET_strdup() | ||
313 | * @return `strdup(@a str)` | ||
314 | */ | ||
315 | char * | 258 | char * |
316 | GNUNET_xstrdup_ (const char *str, const char *filename, int linenumber) | 259 | GNUNET_xstrdup_ (const char *str, |
260 | const char *filename, | ||
261 | int linenumber) | ||
317 | { | 262 | { |
263 | size_t slen = strlen (str) + 1; | ||
318 | char *res; | 264 | char *res; |
319 | size_t slen; | ||
320 | 265 | ||
321 | GNUNET_assert_at (str != NULL, filename, linenumber); | 266 | GNUNET_assert_at (str != NULL, |
322 | slen = strlen (str) + 1; | 267 | filename, |
323 | res = GNUNET_xmalloc_ (slen, filename, linenumber); | 268 | linenumber); |
324 | GNUNET_memcpy (res, str, slen); | 269 | res = GNUNET_xmalloc_ (slen, |
270 | filename, | ||
271 | linenumber); | ||
272 | GNUNET_memcpy (res, | ||
273 | str, | ||
274 | slen); | ||
325 | return res; | 275 | return res; |
326 | } | 276 | } |
327 | 277 | ||
328 | 278 | ||
329 | #if ! HAVE_STRNLEN | 279 | #if ! HAVE_STRNLEN |
330 | static size_t | 280 | static size_t |
331 | strnlen (const char *s, size_t n) | 281 | strnlen (const char *s, |
282 | size_t n) | ||
332 | { | 283 | { |
333 | const char *e; | 284 | const char *e; |
334 | 285 | ||
335 | e = memchr (s, '\0', n); | 286 | e = memchr (s, |
287 | '\0', | ||
288 | n); | ||
336 | if (NULL == e) | 289 | if (NULL == e) |
337 | return n; | 290 | return n; |
338 | return e - s; | 291 | return e - s; |
@@ -342,15 +295,6 @@ strnlen (const char *s, size_t n) | |||
342 | #endif | 295 | #endif |
343 | 296 | ||
344 | 297 | ||
345 | /** | ||
346 | * Dup partially a string (same semantics as strndup). | ||
347 | * | ||
348 | * @param str the string to dup | ||
349 | * @param len the length of the string to dup | ||
350 | * @param filename where in the code was the call to GNUNET_strndup() | ||
351 | * @param linenumber where in the code was the call to GNUNET_strndup() | ||
352 | * @return `strndup(@a str,@a len)` | ||
353 | */ | ||
354 | char * | 298 | char * |
355 | GNUNET_xstrndup_ (const char *str, | 299 | GNUNET_xstrndup_ (const char *str, |
356 | size_t len, | 300 | size_t len, |
@@ -361,27 +305,19 @@ GNUNET_xstrndup_ (const char *str, | |||
361 | 305 | ||
362 | if (0 == len) | 306 | if (0 == len) |
363 | return GNUNET_strdup (""); | 307 | return GNUNET_strdup (""); |
364 | GNUNET_assert_at (NULL != str, filename, linenumber); | 308 | GNUNET_assert_at (NULL != str, |
309 | filename, | ||
310 | linenumber); | ||
365 | len = strnlen (str, len); | 311 | len = strnlen (str, len); |
366 | res = GNUNET_xmalloc_ (len + 1, filename, linenumber); | 312 | res = GNUNET_xmalloc_ (len + 1, |
313 | filename, | ||
314 | linenumber); | ||
367 | GNUNET_memcpy (res, str, len); | 315 | GNUNET_memcpy (res, str, len); |
368 | /* res[len] = '\0'; 'malloc' zeros out anyway */ | 316 | /* res[len] = '\0'; 'malloc' zeros out anyway */ |
369 | return res; | 317 | return res; |
370 | } | 318 | } |
371 | 319 | ||
372 | 320 | ||
373 | /** | ||
374 | * Grow an array. Grows old by (*oldCount-newCount)*elementSize bytes | ||
375 | * and sets *oldCount to newCount. | ||
376 | * | ||
377 | * @param old address of the pointer to the array | ||
378 | * *old may be NULL | ||
379 | * @param elementSize the size of the elements of the array | ||
380 | * @param oldCount address of the number of elements in the *old array | ||
381 | * @param newCount number of elements in the new array, may be 0 | ||
382 | * @param filename where in the code was the call to GNUNET_array_grow() | ||
383 | * @param linenumber where in the code was the call to GNUNET_array_grow() | ||
384 | */ | ||
385 | void | 321 | void |
386 | GNUNET_xgrow_ (void **old, | 322 | GNUNET_xgrow_ (void **old, |
387 | size_t elementSize, | 323 | size_t elementSize, |
@@ -401,65 +337,70 @@ GNUNET_xgrow_ (void **old, | |||
401 | } | 337 | } |
402 | else | 338 | else |
403 | { | 339 | { |
404 | tmp = GNUNET_xmalloc_ (size, filename, linenumber); | 340 | tmp = GNUNET_xmalloc_ (size, |
341 | filename, | ||
342 | linenumber); | ||
405 | if (NULL != *old) | 343 | if (NULL != *old) |
406 | { | 344 | { |
407 | GNUNET_memcpy (tmp, *old, elementSize * GNUNET_MIN (*oldCount, newCount)); | 345 | GNUNET_memcpy (tmp, |
346 | *old, | ||
347 | elementSize * GNUNET_MIN (*oldCount, | ||
348 | newCount)); | ||
408 | } | 349 | } |
409 | } | 350 | } |
410 | 351 | ||
411 | if (NULL != *old) | 352 | if (NULL != *old) |
412 | { | 353 | { |
413 | GNUNET_xfree_ (*old, filename, linenumber); | 354 | GNUNET_xfree_ (*old, |
355 | filename, | ||
356 | linenumber); | ||
414 | } | 357 | } |
415 | *old = tmp; | 358 | *old = tmp; |
416 | *oldCount = newCount; | 359 | *oldCount = newCount; |
417 | } | 360 | } |
418 | 361 | ||
419 | 362 | ||
420 | /** | ||
421 | * Like asprintf(), just portable. | ||
422 | * | ||
423 | * @param buf set to a buffer of sufficient size (allocated, caller must free) | ||
424 | * @param format format string (see printf(), fprintf(), etc.) | ||
425 | * @param ... data for format string | ||
426 | * @return number of bytes in `*@a buf`, excluding 0-termination | ||
427 | */ | ||
428 | int | 363 | int |
429 | GNUNET_asprintf (char **buf, const char *format, ...) | 364 | GNUNET_asprintf (char **buf, |
365 | const char *format, | ||
366 | ...) | ||
430 | { | 367 | { |
431 | int ret; | 368 | int ret; |
432 | va_list args; | 369 | va_list args; |
433 | 370 | ||
434 | va_start (args, format); | 371 | va_start (args, |
435 | ret = vsnprintf (NULL, 0, format, args); | 372 | format); |
373 | ret = vsnprintf (NULL, | ||
374 | 0, | ||
375 | format, | ||
376 | args); | ||
436 | va_end (args); | 377 | va_end (args); |
437 | GNUNET_assert (ret >= 0); | 378 | GNUNET_assert (ret >= 0); |
438 | *buf = GNUNET_malloc (ret + 1); | 379 | *buf = GNUNET_malloc (ret + 1); |
439 | va_start (args, format); | 380 | va_start (args, format); |
440 | ret = vsprintf (*buf, format, args); | 381 | ret = vsprintf (*buf, |
382 | format, | ||
383 | args); | ||
441 | va_end (args); | 384 | va_end (args); |
442 | return ret; | 385 | return ret; |
443 | } | 386 | } |
444 | 387 | ||
445 | 388 | ||
446 | /** | ||
447 | * Like snprintf(), just aborts if the buffer is of insufficient size. | ||
448 | * | ||
449 | * @param buf pointer to buffer that is written to | ||
450 | * @param size number of bytes in buf | ||
451 | * @param format format strings | ||
452 | * @param ... data for format string | ||
453 | * @return number of bytes written to buf or negative value on error | ||
454 | */ | ||
455 | int | 389 | int |
456 | GNUNET_snprintf (char *buf, size_t size, const char *format, ...) | 390 | GNUNET_snprintf (char *buf, |
391 | size_t size, | ||
392 | const char *format, | ||
393 | ...) | ||
457 | { | 394 | { |
458 | int ret; | 395 | int ret; |
459 | va_list args; | 396 | va_list args; |
460 | 397 | ||
461 | va_start (args, format); | 398 | va_start (args, |
462 | ret = vsnprintf (buf, size, format, args); | 399 | format); |
400 | ret = vsnprintf (buf, | ||
401 | size, | ||
402 | format, | ||
403 | args); | ||
463 | va_end (args); | 404 | va_end (args); |
464 | GNUNET_assert ((ret >= 0) && (((size_t) ret) < size)); | 405 | GNUNET_assert ((ret >= 0) && (((size_t) ret) < size)); |
465 | return ret; | 406 | return ret; |
@@ -480,15 +421,7 @@ GNUNET_copy_message (const struct GNUNET_MessageHeader *msg) | |||
480 | } | 421 | } |
481 | 422 | ||
482 | 423 | ||
483 | /** | 424 | bool |
484 | * Check that memory in @a a is all zeros. @a a must be a pointer. | ||
485 | * | ||
486 | * @param a pointer to @a n bytes which should be tested for the | ||
487 | * entire memory being zero'ed out. | ||
488 | * @param n number of bytes in @a to be tested | ||
489 | * @return GNUNET_YES if a is zero, GNUNET_NO otherwise | ||
490 | */ | ||
491 | enum GNUNET_GenericReturnValue | ||
492 | GNUNET_is_zero_ (const void *a, | 425 | GNUNET_is_zero_ (const void *a, |
493 | size_t n) | 426 | size_t n) |
494 | { | 427 | { |
@@ -496,8 +429,8 @@ GNUNET_is_zero_ (const void *a, | |||
496 | 429 | ||
497 | for (size_t i = 0; i < n; i++) | 430 | for (size_t i = 0; i < n; i++) |
498 | if (b[i]) | 431 | if (b[i]) |
499 | return GNUNET_NO; | 432 | return false; |
500 | return GNUNET_YES; | 433 | return true; |
501 | } | 434 | } |
502 | 435 | ||
503 | 436 | ||
diff --git a/src/lib/util/crypto_ecc.c b/src/lib/util/crypto_ecc.c index 11c3e50d4..8ea17fda0 100644 --- a/src/lib/util/crypto_ecc.c +++ b/src/lib/util/crypto_ecc.c | |||
@@ -411,24 +411,39 @@ GNUNET_CRYPTO_eddsa_private_key_from_string ( | |||
411 | } | 411 | } |
412 | 412 | ||
413 | 413 | ||
414 | static void | ||
415 | buffer_clear (void *buf, size_t len) | ||
416 | { | ||
417 | #if HAVE_MEMSET_S | ||
418 | memset_s (buf, len, 0, len); | ||
419 | #elif HAVE_EXPLICIT_BZERO | ||
420 | explicit_bzero (buf, len); | ||
421 | #else | ||
422 | volatile unsigned char *p = buf; | ||
423 | while (len--) | ||
424 | *p++ = 0; | ||
425 | #endif | ||
426 | } | ||
427 | |||
428 | |||
414 | void | 429 | void |
415 | GNUNET_CRYPTO_ecdhe_key_clear (struct GNUNET_CRYPTO_EcdhePrivateKey *pk) | 430 | GNUNET_CRYPTO_ecdhe_key_clear (struct GNUNET_CRYPTO_EcdhePrivateKey *pk) |
416 | { | 431 | { |
417 | memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey)); | 432 | buffer_clear (pk, sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey)); |
418 | } | 433 | } |
419 | 434 | ||
420 | 435 | ||
421 | void | 436 | void |
422 | GNUNET_CRYPTO_ecdsa_key_clear (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk) | 437 | GNUNET_CRYPTO_ecdsa_key_clear (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk) |
423 | { | 438 | { |
424 | memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey)); | 439 | buffer_clear (pk, sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey)); |
425 | } | 440 | } |
426 | 441 | ||
427 | 442 | ||
428 | void | 443 | void |
429 | GNUNET_CRYPTO_eddsa_key_clear (struct GNUNET_CRYPTO_EddsaPrivateKey *pk) | 444 | GNUNET_CRYPTO_eddsa_key_clear (struct GNUNET_CRYPTO_EddsaPrivateKey *pk) |
430 | { | 445 | { |
431 | memset (pk, 0, sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)); | 446 | buffer_clear (pk, sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)); |
432 | } | 447 | } |
433 | 448 | ||
434 | 449 | ||
diff --git a/src/lib/util/crypto_ecc_setup.c b/src/lib/util/crypto_ecc_setup.c index 2ee9ed931..07e28f89d 100644 --- a/src/lib/util/crypto_ecc_setup.c +++ b/src/lib/util/crypto_ecc_setup.c | |||
@@ -297,6 +297,7 @@ GNUNET_CRYPTO_sign_by_peer_identity (const struct | |||
297 | struct GNUNET_CRYPTO_EddsaSignature *sig) | 297 | struct GNUNET_CRYPTO_EddsaSignature *sig) |
298 | { | 298 | { |
299 | struct GNUNET_CRYPTO_EddsaPrivateKey *priv; | 299 | struct GNUNET_CRYPTO_EddsaPrivateKey *priv; |
300 | enum GNUNET_GenericReturnValue result; | ||
300 | 301 | ||
301 | if (NULL == (priv = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg))) | 302 | if (NULL == (priv = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg))) |
302 | { | 303 | { |
@@ -305,7 +306,9 @@ GNUNET_CRYPTO_sign_by_peer_identity (const struct | |||
305 | return GNUNET_SYSERR; | 306 | return GNUNET_SYSERR; |
306 | } | 307 | } |
307 | 308 | ||
308 | return GNUNET_CRYPTO_eddsa_sign_ (priv, purpose, sig); | 309 | result = GNUNET_CRYPTO_eddsa_sign_ (priv, purpose, sig); |
310 | GNUNET_CRYPTO_eddsa_key_clear (priv); | ||
311 | return result; | ||
309 | } | 312 | } |
310 | 313 | ||
311 | 314 | ||
diff --git a/src/lib/util/crypto_pkey.c b/src/lib/util/crypto_pkey.c index a9d4831fb..92e0fba36 100644 --- a/src/lib/util/crypto_pkey.c +++ b/src/lib/util/crypto_pkey.c | |||
@@ -43,6 +43,23 @@ check_key_type (uint32_t type) | |||
43 | } | 43 | } |
44 | 44 | ||
45 | 45 | ||
46 | void | ||
47 | GNUNET_CRYPTO_private_key_clear (struct GNUNET_CRYPTO_PrivateKey *key) | ||
48 | { | ||
49 | switch (ntohl (key->type)) | ||
50 | { | ||
51 | case GNUNET_PUBLIC_KEY_TYPE_ECDSA: | ||
52 | GNUNET_CRYPTO_ecdsa_key_clear (&key->ecdsa_key); | ||
53 | break; | ||
54 | case GNUNET_PUBLIC_KEY_TYPE_EDDSA: | ||
55 | GNUNET_CRYPTO_eddsa_key_clear (&key->eddsa_key); | ||
56 | break; | ||
57 | default: | ||
58 | GNUNET_break (0); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | |||
46 | ssize_t | 63 | ssize_t |
47 | GNUNET_CRYPTO_private_key_get_length (const struct | 64 | GNUNET_CRYPTO_private_key_get_length (const struct |
48 | GNUNET_CRYPTO_PrivateKey *key) | 65 | GNUNET_CRYPTO_PrivateKey *key) |
diff --git a/src/lib/util/crypto_symmetric.c b/src/lib/util/crypto_symmetric.c index a9217febd..c08b84c17 100644 --- a/src/lib/util/crypto_symmetric.c +++ b/src/lib/util/crypto_symmetric.c | |||
@@ -137,7 +137,7 @@ GNUNET_CRYPTO_symmetric_encrypt (const void *block, | |||
137 | void *result) | 137 | void *result) |
138 | { | 138 | { |
139 | gcry_cipher_hd_t handle; | 139 | gcry_cipher_hd_t handle; |
140 | char tmp[size]; | 140 | char tmp[GNUNET_NZL(size)]; |
141 | 141 | ||
142 | if (GNUNET_OK != setup_cipher_aes (&handle, sessionkey, iv)) | 142 | if (GNUNET_OK != setup_cipher_aes (&handle, sessionkey, iv)) |
143 | return -1; | 143 | return -1; |
diff --git a/src/lib/util/helper.c b/src/lib/util/helper.c index 1dd3e33e2..87ea749e9 100644 --- a/src/lib/util/helper.c +++ b/src/lib/util/helper.c | |||
@@ -612,7 +612,7 @@ helper_write (void *cls) | |||
612 | struct GNUNET_HELPER_SendHandle * | 612 | struct GNUNET_HELPER_SendHandle * |
613 | GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, | 613 | GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, |
614 | const struct GNUNET_MessageHeader *msg, | 614 | const struct GNUNET_MessageHeader *msg, |
615 | int can_drop, | 615 | bool can_drop, |
616 | GNUNET_HELPER_Continuation cont, | 616 | GNUNET_HELPER_Continuation cont, |
617 | void *cont_cls) | 617 | void *cont_cls) |
618 | { | 618 | { |
@@ -621,7 +621,7 @@ GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, | |||
621 | 621 | ||
622 | if (NULL == h->fh_to_helper) | 622 | if (NULL == h->fh_to_helper) |
623 | return NULL; | 623 | return NULL; |
624 | if ((GNUNET_YES == can_drop) && (NULL != h->sh_head)) | 624 | if (can_drop && (NULL != h->sh_head)) |
625 | return NULL; | 625 | return NULL; |
626 | mlen = ntohs (msg->size); | 626 | mlen = ntohs (msg->size); |
627 | sh = GNUNET_malloc (sizeof(struct GNUNET_HELPER_SendHandle) + mlen); | 627 | sh = GNUNET_malloc (sizeof(struct GNUNET_HELPER_SendHandle) + mlen); |
diff --git a/src/lib/util/service.c b/src/lib/util/service.c index 7aeabf687..363210c61 100644 --- a/src/lib/util/service.c +++ b/src/lib/util/service.c | |||
@@ -24,7 +24,6 @@ | |||
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * @author Florian Dold | 25 | * @author Florian Dold |
26 | */ | 26 | */ |
27 | |||
28 | #include "platform.h" | 27 | #include "platform.h" |
29 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
30 | #include "gnunet_protocols.h" | 29 | #include "gnunet_protocols.h" |
@@ -233,15 +232,10 @@ struct GNUNET_SERVICE_Handle | |||
233 | int ready_confirm_fd; | 232 | int ready_confirm_fd; |
234 | 233 | ||
235 | /** | 234 | /** |
236 | * Overall success/failure of the service start. | 235 | * If true, consider unknown message types an error where the |
237 | */ | ||
238 | int ret; | ||
239 | |||
240 | /** | ||
241 | * If #GNUNET_YES, consider unknown message types an error where the | ||
242 | * client is disconnected. | 236 | * client is disconnected. |
243 | */ | 237 | */ |
244 | int require_found; | 238 | bool require_found; |
245 | }; | 239 | }; |
246 | 240 | ||
247 | 241 | ||
@@ -330,19 +324,19 @@ struct GNUNET_SERVICE_Client | |||
330 | * force the OS to close once the process actually dies. Should only | 324 | * force the OS to close once the process actually dies. Should only |
331 | * be used in special cases! | 325 | * be used in special cases! |
332 | */ | 326 | */ |
333 | int persist; | 327 | bool persist; |
334 | 328 | ||
335 | /** | 329 | /** |
336 | * Is this client a 'monitor' client that should not be counted | 330 | * Is this client a 'monitor' client that should not be counted |
337 | * when deciding on destroying the server during soft shutdown? | 331 | * when deciding on destroying the server during soft shutdown? |
338 | * (see also #GNUNET_SERVICE_start) | 332 | * (see also #GNUNET_SERVICE_start) |
339 | */ | 333 | */ |
340 | int is_monitor; | 334 | bool is_monitor; |
341 | 335 | ||
342 | /** | 336 | /** |
343 | * Are we waiting for the application to call #GNUNET_SERVICE_client_continue()? | 337 | * Are we waiting for the application to call #GNUNET_SERVICE_client_continue()? |
344 | */ | 338 | */ |
345 | int needs_continue; | 339 | bool needs_continue; |
346 | 340 | ||
347 | /** | 341 | /** |
348 | * Type of last message processed (for warn_no_receive_done). | 342 | * Type of last message processed (for warn_no_receive_done). |
@@ -356,19 +350,22 @@ struct GNUNET_SERVICE_Client | |||
356 | * monitoring. | 350 | * monitoring. |
357 | * | 351 | * |
358 | * @param sh service to check clients for | 352 | * @param sh service to check clients for |
359 | * @return #GNUNET_YES if we have non-monitoring clients left | 353 | * @return true if we have non-monitoring clients left |
360 | */ | 354 | */ |
361 | static int | 355 | static enum GNUNET_GenericReturnValue |
362 | have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh) | 356 | have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh) |
363 | { | 357 | { |
364 | for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client; | 358 | for (struct GNUNET_SERVICE_Client *client = sh->clients_head; |
359 | NULL != client; | ||
365 | client = client->next) | 360 | client = client->next) |
366 | { | 361 | { |
362 | if (NULL != client->drop_task) | ||
363 | continue; | ||
367 | if (client->is_monitor) | 364 | if (client->is_monitor) |
368 | continue; | 365 | continue; |
369 | return GNUNET_YES; | 366 | return true; |
370 | } | 367 | } |
371 | return GNUNET_NO; | 368 | return false; |
372 | } | 369 | } |
373 | 370 | ||
374 | 371 | ||
@@ -380,13 +377,14 @@ have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh) | |||
380 | * @param sr reason for suspending accepting connections | 377 | * @param sr reason for suspending accepting connections |
381 | */ | 378 | */ |
382 | static void | 379 | static void |
383 | do_suspend (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | 380 | do_suspend (struct GNUNET_SERVICE_Handle *sh, |
381 | enum SuspendReason sr) | ||
384 | { | 382 | { |
385 | struct ServiceListenContext *slc; | ||
386 | |||
387 | GNUNET_assert (0 == (sh->suspend_state & sr)); | 383 | GNUNET_assert (0 == (sh->suspend_state & sr)); |
388 | sh->suspend_state |= sr; | 384 | sh->suspend_state |= sr; |
389 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) | 385 | for (struct ServiceListenContext *slc = sh->slc_head; |
386 | NULL != slc; | ||
387 | slc = slc->next) | ||
390 | { | 388 | { |
391 | if (NULL != slc->listen_task) | 389 | if (NULL != slc->listen_task) |
392 | { | 390 | { |
@@ -423,7 +421,7 @@ service_shutdown (void *cls) | |||
423 | case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN: | 421 | case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN: |
424 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) | 422 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) |
425 | do_suspend (sh, SUSPEND_STATE_SHUTDOWN); | 423 | do_suspend (sh, SUSPEND_STATE_SHUTDOWN); |
426 | if (GNUNET_NO == have_non_monitor_clients (sh)) | 424 | if (! have_non_monitor_clients (sh)) |
427 | GNUNET_SERVICE_shutdown (sh); | 425 | GNUNET_SERVICE_shutdown (sh); |
428 | break; | 426 | break; |
429 | } | 427 | } |
@@ -435,25 +433,21 @@ service_shutdown (void *cls) | |||
435 | * | 433 | * |
436 | * @param list a list of networks | 434 | * @param list a list of networks |
437 | * @param add the IP to check (in network byte order) | 435 | * @param add the IP to check (in network byte order) |
438 | * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is | 436 | * @return false if the IP is not in the list, true if it it is |
439 | */ | 437 | */ |
440 | static int | 438 | static bool |
441 | check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, | 439 | check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, |
442 | const struct in_addr *add) | 440 | const struct in_addr *add) |
443 | { | 441 | { |
444 | unsigned int i; | 442 | for (unsigned int i = 0; |
445 | 443 | 0 != list[i].network.s_addr; | |
446 | if (NULL == list) | 444 | i++) |
447 | return GNUNET_NO; | ||
448 | i = 0; | ||
449 | while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr)) | ||
450 | { | 445 | { |
451 | if ((add->s_addr & list[i].netmask.s_addr) == | 446 | if ( (add->s_addr & list[i].netmask.s_addr) == |
452 | (list[i].network.s_addr & list[i].netmask.s_addr)) | 447 | (list[i].network.s_addr & list[i].netmask.s_addr) ) |
453 | return GNUNET_YES; | 448 | return true; |
454 | i++; | ||
455 | } | 449 | } |
456 | return GNUNET_NO; | 450 | return false; |
457 | } | 451 | } |
458 | 452 | ||
459 | 453 | ||
@@ -462,30 +456,29 @@ check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, | |||
462 | * | 456 | * |
463 | * @param list a list of networks | 457 | * @param list a list of networks |
464 | * @param ip the IP to check (in network byte order) | 458 | * @param ip the IP to check (in network byte order) |
465 | * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is | 459 | * @return false if the IP is not in the list, true if it it is |
466 | */ | 460 | */ |
467 | static int | 461 | static bool |
468 | check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, | 462 | check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, |
469 | const struct in6_addr *ip) | 463 | const struct in6_addr *ip) |
470 | { | 464 | { |
471 | unsigned int i; | 465 | for (unsigned int i = 0; |
472 | 466 | ! GNUNET_is_zero (&list[i].network); | |
473 | if (NULL == list) | 467 | i++) |
474 | return GNUNET_NO; | ||
475 | i = 0; | ||
476 | NEXT: | ||
477 | while (GNUNET_NO == GNUNET_is_zero (&list[i].network)) | ||
478 | { | 468 | { |
469 | bool match = true; | ||
470 | |||
479 | for (unsigned int j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++) | 471 | for (unsigned int j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++) |
480 | if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) != | 472 | if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) != |
481 | (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j])) | 473 | (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j])) |
482 | { | 474 | { |
483 | i++; | 475 | match = false; |
484 | goto NEXT; | 476 | break; |
485 | } | 477 | } |
486 | return GNUNET_YES; | 478 | if (match) |
479 | return true; | ||
487 | } | 480 | } |
488 | return GNUNET_NO; | 481 | return false; |
489 | } | 482 | } |
490 | 483 | ||
491 | 484 | ||
@@ -593,7 +586,8 @@ service_mq_send (struct GNUNET_MQ_Handle *mq, | |||
593 | * @param impl_state state specific to the implementation | 586 | * @param impl_state state specific to the implementation |
594 | */ | 587 | */ |
595 | static void | 588 | static void |
596 | service_mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state) | 589 | service_mq_cancel (struct GNUNET_MQ_Handle *mq, |
590 | void *impl_state) | ||
597 | { | 591 | { |
598 | struct GNUNET_SERVICE_Client *client = impl_state; | 592 | struct GNUNET_SERVICE_Client *client = impl_state; |
599 | 593 | ||
@@ -615,12 +609,14 @@ service_mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state) | |||
615 | * @param error error code | 609 | * @param error error code |
616 | */ | 610 | */ |
617 | static void | 611 | static void |
618 | service_mq_error_handler (void *cls, enum GNUNET_MQ_Error error) | 612 | service_mq_error_handler (void *cls, |
613 | enum GNUNET_MQ_Error error) | ||
619 | { | 614 | { |
620 | struct GNUNET_SERVICE_Client *client = cls; | 615 | struct GNUNET_SERVICE_Client *client = cls; |
621 | struct GNUNET_SERVICE_Handle *sh = client->sh; | 616 | struct GNUNET_SERVICE_Handle *sh = client->sh; |
622 | 617 | ||
623 | if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found)) | 618 | if ( (GNUNET_MQ_ERROR_NO_MATCH == error) && |
619 | (! sh->require_found) ) | ||
624 | { | 620 | { |
625 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 621 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
626 | "No handler for message of type %u found\n", | 622 | "No handler for message of type %u found\n", |
@@ -680,8 +676,8 @@ service_client_mst_cb (void *cls, | |||
680 | "Received message of type %u and size %u from client\n", | 676 | "Received message of type %u and size %u from client\n", |
681 | ntohs (message->type), | 677 | ntohs (message->type), |
682 | ntohs (message->size)); | 678 | ntohs (message->size)); |
683 | GNUNET_assert (GNUNET_NO == client->needs_continue); | 679 | GNUNET_assert (! client->needs_continue); |
684 | client->needs_continue = GNUNET_YES; | 680 | client->needs_continue = true; |
685 | client->warn_type = ntohs (message->type); | 681 | client->warn_type = ntohs (message->type); |
686 | client->warn_start = GNUNET_TIME_absolute_get (); | 682 | client->warn_start = GNUNET_TIME_absolute_get (); |
687 | GNUNET_assert (NULL == client->warn_task); | 683 | GNUNET_assert (NULL == client->warn_task); |
@@ -717,7 +713,7 @@ service_client_recv (void *cls) | |||
717 | /* client closed connection (or IO error) */ | 713 | /* client closed connection (or IO error) */ |
718 | if (NULL == client->drop_task) | 714 | if (NULL == client->drop_task) |
719 | { | 715 | { |
720 | GNUNET_assert (GNUNET_NO == client->needs_continue); | 716 | GNUNET_assert (! client->needs_continue); |
721 | GNUNET_SERVICE_client_drop (client); | 717 | GNUNET_SERVICE_client_drop (client); |
722 | } | 718 | } |
723 | return; | 719 | return; |
@@ -726,7 +722,7 @@ service_client_recv (void *cls) | |||
726 | return; /* more messages in buffer, wait for application | 722 | return; /* more messages in buffer, wait for application |
727 | to be done processing */ | 723 | to be done processing */ |
728 | GNUNET_assert (GNUNET_OK == ret); | 724 | GNUNET_assert (GNUNET_OK == ret); |
729 | if (GNUNET_YES == client->needs_continue) | 725 | if (client->needs_continue) |
730 | return; | 726 | return; |
731 | if (NULL != client->recv_task) | 727 | if (NULL != client->recv_task) |
732 | return; | 728 | return; |
@@ -753,7 +749,9 @@ start_client (struct GNUNET_SERVICE_Handle *sh, | |||
753 | struct GNUNET_SERVICE_Client *client; | 749 | struct GNUNET_SERVICE_Client *client; |
754 | 750 | ||
755 | client = GNUNET_new (struct GNUNET_SERVICE_Client); | 751 | client = GNUNET_new (struct GNUNET_SERVICE_Client); |
756 | GNUNET_CONTAINER_DLL_insert (sh->clients_head, sh->clients_tail, client); | 752 | GNUNET_CONTAINER_DLL_insert (sh->clients_head, |
753 | sh->clients_tail, | ||
754 | client); | ||
757 | client->sh = sh; | 755 | client->sh = sh; |
758 | client->sock = csock; | 756 | client->sock = csock; |
759 | client->mq = GNUNET_MQ_queue_for_callbacks (&service_mq_send, | 757 | client->mq = GNUNET_MQ_queue_for_callbacks (&service_mq_send, |
@@ -806,7 +804,8 @@ accept_client (void *cls) | |||
806 | if (EMFILE == errno) | 804 | if (EMFILE == errno) |
807 | do_suspend (sh, SUSPEND_STATE_EMFILE); | 805 | do_suspend (sh, SUSPEND_STATE_EMFILE); |
808 | else if (EAGAIN != errno) | 806 | else if (EAGAIN != errno) |
809 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept"); | 807 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, |
808 | "accept"); | ||
810 | break; | 809 | break; |
811 | } | 810 | } |
812 | switch (sa.ss_family) | 811 | switch (sa.ss_family) |
@@ -815,18 +814,22 @@ accept_client (void *cls) | |||
815 | GNUNET_assert (addrlen == sizeof(struct sockaddr_in)); | 814 | GNUNET_assert (addrlen == sizeof(struct sockaddr_in)); |
816 | v4 = (const struct sockaddr_in *) &sa; | 815 | v4 = (const struct sockaddr_in *) &sa; |
817 | ok = (((NULL == sh->v4_allowed) || | 816 | ok = (((NULL == sh->v4_allowed) || |
818 | (check_ipv4_listed (sh->v4_allowed, &v4->sin_addr))) && | 817 | (check_ipv4_listed (sh->v4_allowed, |
818 | &v4->sin_addr))) && | ||
819 | ((NULL == sh->v4_denied) || | 819 | ((NULL == sh->v4_denied) || |
820 | (! check_ipv4_listed (sh->v4_denied, &v4->sin_addr)))); | 820 | (! check_ipv4_listed (sh->v4_denied, |
821 | &v4->sin_addr)))); | ||
821 | break; | 822 | break; |
822 | 823 | ||
823 | case AF_INET6: | 824 | case AF_INET6: |
824 | GNUNET_assert (addrlen == sizeof(struct sockaddr_in6)); | 825 | GNUNET_assert (addrlen == sizeof(struct sockaddr_in6)); |
825 | v6 = (const struct sockaddr_in6 *) &sa; | 826 | v6 = (const struct sockaddr_in6 *) &sa; |
826 | ok = (((NULL == sh->v6_allowed) || | 827 | ok = (((NULL == sh->v6_allowed) || |
827 | (check_ipv6_listed (sh->v6_allowed, &v6->sin6_addr))) && | 828 | (check_ipv6_listed (sh->v6_allowed, |
829 | &v6->sin6_addr))) && | ||
828 | ((NULL == sh->v6_denied) || | 830 | ((NULL == sh->v6_denied) || |
829 | (! check_ipv6_listed (sh->v6_denied, &v6->sin6_addr)))); | 831 | (! check_ipv6_listed (sh->v6_denied, |
832 | &v6->sin6_addr)))); | ||
830 | break; | 833 | break; |
831 | 834 | ||
832 | case AF_UNIX: | 835 | case AF_UNIX: |
@@ -850,7 +853,8 @@ accept_client (void *cls) | |||
850 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 853 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
851 | "Service accepted incoming connection from %s.\n", | 854 | "Service accepted incoming connection from %s.\n", |
852 | GNUNET_a2s ((const struct sockaddr *) &sa, addrlen)); | 855 | GNUNET_a2s ((const struct sockaddr *) &sa, addrlen)); |
853 | start_client (slc->sh, sock); | 856 | start_client (slc->sh, |
857 | sock); | ||
854 | } | 858 | } |
855 | if (0 != sh->suspend_state) | 859 | if (0 != sh->suspend_state) |
856 | return; | 860 | return; |
@@ -870,15 +874,16 @@ accept_client (void *cls) | |||
870 | * or #SUSPEND_STATE_NONE on first startup | 874 | * or #SUSPEND_STATE_NONE on first startup |
871 | */ | 875 | */ |
872 | static void | 876 | static void |
873 | do_resume (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | 877 | do_resume (struct GNUNET_SERVICE_Handle *sh, |
878 | enum SuspendReason sr) | ||
874 | { | 879 | { |
875 | struct ServiceListenContext *slc; | ||
876 | |||
877 | GNUNET_assert ((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr))); | 880 | GNUNET_assert ((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr))); |
878 | sh->suspend_state -= sr; | 881 | sh->suspend_state -= sr; |
879 | if (SUSPEND_STATE_NONE != sh->suspend_state) | 882 | if (SUSPEND_STATE_NONE != sh->suspend_state) |
880 | return; | 883 | return; |
881 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) | 884 | for (struct ServiceListenContext *slc = sh->slc_head; |
885 | NULL != slc; | ||
886 | slc = slc->next) | ||
882 | { | 887 | { |
883 | GNUNET_assert (NULL == slc->listen_task); | 888 | GNUNET_assert (NULL == slc->listen_task); |
884 | slc->listen_task = | 889 | slc->listen_task = |
@@ -928,7 +933,7 @@ service_main (void *cls) | |||
928 | * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including | 933 | * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including |
929 | * no ACL configured) | 934 | * no ACL configured) |
930 | */ | 935 | */ |
931 | static int | 936 | static enum GNUNET_GenericReturnValue |
932 | process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, | 937 | process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, |
933 | struct GNUNET_SERVICE_Handle *sh, | 938 | struct GNUNET_SERVICE_Handle *sh, |
934 | const char *option) | 939 | const char *option) |
@@ -969,7 +974,7 @@ process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, | |||
969 | * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including | 974 | * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including |
970 | * no ACL configured) | 975 | * no ACL configured) |
971 | */ | 976 | */ |
972 | static int | 977 | static enum GNUNET_GenericReturnValue |
973 | process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, | 978 | process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, |
974 | struct GNUNET_SERVICE_Handle *sh, | 979 | struct GNUNET_SERVICE_Handle *sh, |
975 | const char *option) | 980 | const char *option) |
@@ -1457,7 +1462,7 @@ open_listen_socket (const struct sockaddr *server_addr, | |||
1457 | * @param sh service context to initialize | 1462 | * @param sh service context to initialize |
1458 | * @return #GNUNET_OK if configuration succeeded | 1463 | * @return #GNUNET_OK if configuration succeeded |
1459 | */ | 1464 | */ |
1460 | static int | 1465 | static enum GNUNET_GenericReturnValue |
1461 | setup_service (struct GNUNET_SERVICE_Handle *sh) | 1466 | setup_service (struct GNUNET_SERVICE_Handle *sh) |
1462 | { | 1467 | { |
1463 | int tolerant; | 1468 | int tolerant; |
@@ -1489,8 +1494,8 @@ setup_service (struct GNUNET_SERVICE_Handle *sh) | |||
1489 | 1494 | ||
1490 | lsocks = NULL; | 1495 | lsocks = NULL; |
1491 | errno = 0; | 1496 | errno = 0; |
1492 | if ((NULL != (nfds = getenv ("LISTEN_FDS"))) && | 1497 | if ( (NULL != (nfds = getenv ("LISTEN_FDS"))) && |
1493 | (1 == sscanf (nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) && | 1498 | (1 == sscanf (nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) && |
1494 | (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE)) | 1499 | (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE)) |
1495 | { | 1500 | { |
1496 | lsocks = GNUNET_new_array (cnt + 1, struct GNUNET_NETWORK_Handle *); | 1501 | lsocks = GNUNET_new_array (cnt + 1, struct GNUNET_NETWORK_Handle *); |
@@ -1532,7 +1537,9 @@ setup_service (struct GNUNET_SERVICE_Handle *sh) | |||
1532 | slc = GNUNET_new (struct ServiceListenContext); | 1537 | slc = GNUNET_new (struct ServiceListenContext); |
1533 | slc->sh = sh; | 1538 | slc->sh = sh; |
1534 | slc->listen_socket = *ls; | 1539 | slc->listen_socket = *ls; |
1535 | GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc); | 1540 | GNUNET_CONTAINER_DLL_insert (sh->slc_head, |
1541 | sh->slc_tail, | ||
1542 | slc); | ||
1536 | } | 1543 | } |
1537 | GNUNET_free (lsocks); | 1544 | GNUNET_free (lsocks); |
1538 | } | 1545 | } |
@@ -1552,7 +1559,8 @@ setup_service (struct GNUNET_SERVICE_Handle *sh) | |||
1552 | 1559 | ||
1553 | slc = GNUNET_new (struct ServiceListenContext); | 1560 | slc = GNUNET_new (struct ServiceListenContext); |
1554 | slc->sh = sh; | 1561 | slc->sh = sh; |
1555 | slc->listen_socket = open_listen_socket (addrs[i], addrlens[i]); | 1562 | slc->listen_socket = open_listen_socket (addrs[i], |
1563 | addrlens[i]); | ||
1556 | GNUNET_free (addrs[i]); | 1564 | GNUNET_free (addrs[i]); |
1557 | if (NULL == slc->listen_socket) | 1565 | if (NULL == slc->listen_socket) |
1558 | { | 1566 | { |
@@ -1560,7 +1568,9 @@ setup_service (struct GNUNET_SERVICE_Handle *sh) | |||
1560 | GNUNET_free (slc); | 1568 | GNUNET_free (slc); |
1561 | continue; | 1569 | continue; |
1562 | } | 1570 | } |
1563 | GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc); | 1571 | GNUNET_CONTAINER_DLL_insert (sh->slc_head, |
1572 | sh->slc_tail, | ||
1573 | slc); | ||
1564 | } | 1574 | } |
1565 | GNUNET_free (addrlens); | 1575 | GNUNET_free (addrlens); |
1566 | GNUNET_free (addrs); | 1576 | GNUNET_free (addrs); |
@@ -1582,7 +1592,7 @@ setup_service (struct GNUNET_SERVICE_Handle *sh) | |||
1582 | GNUNET_NETWORK_socket_close (*ls); | 1592 | GNUNET_NETWORK_socket_close (*ls); |
1583 | GNUNET_free (csocks); | 1593 | GNUNET_free (csocks); |
1584 | } | 1594 | } |
1585 | sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES; | 1595 | sh->require_found = (GNUNET_NO == tolerant); |
1586 | sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg, | 1596 | sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg, |
1587 | sh->service_name, | 1597 | sh->service_name, |
1588 | "UNIX_MATCH_UID"); | 1598 | "UNIX_MATCH_UID"); |
@@ -1609,10 +1619,11 @@ get_user_name (struct GNUNET_SERVICE_Handle *sh) | |||
1609 | { | 1619 | { |
1610 | char *un; | 1620 | char *un; |
1611 | 1621 | ||
1612 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (sh->cfg, | 1622 | if (GNUNET_OK != |
1613 | sh->service_name, | 1623 | GNUNET_CONFIGURATION_get_value_filename (sh->cfg, |
1614 | "USERNAME", | 1624 | sh->service_name, |
1615 | &un)) | 1625 | "USERNAME", |
1626 | &un)) | ||
1616 | return NULL; | 1627 | return NULL; |
1617 | return un; | 1628 | return un; |
1618 | } | 1629 | } |
@@ -1624,16 +1635,14 @@ get_user_name (struct GNUNET_SERVICE_Handle *sh) | |||
1624 | * @param sh service context | 1635 | * @param sh service context |
1625 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 1636 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
1626 | */ | 1637 | */ |
1627 | static int | 1638 | static enum GNUNET_GenericReturnValue |
1628 | set_user_id (struct GNUNET_SERVICE_Handle *sh) | 1639 | set_user_id (struct GNUNET_SERVICE_Handle *sh) |
1629 | { | 1640 | { |
1630 | char *user; | 1641 | char *user; |
1642 | struct passwd *pws; | ||
1631 | 1643 | ||
1632 | if (NULL == (user = get_user_name (sh))) | 1644 | if (NULL == (user = get_user_name (sh))) |
1633 | return GNUNET_OK; /* keep */ | 1645 | return GNUNET_OK; /* keep */ |
1634 | |||
1635 | struct passwd *pws; | ||
1636 | |||
1637 | errno = 0; | 1646 | errno = 0; |
1638 | pws = getpwnam (user); | 1647 | pws = getpwnam (user); |
1639 | if (NULL == pws) | 1648 | if (NULL == pws) |
@@ -1649,7 +1658,8 @@ set_user_id (struct GNUNET_SERVICE_Handle *sh) | |||
1649 | #if HAVE_INITGROUPS | 1658 | #if HAVE_INITGROUPS |
1650 | (0 != initgroups (user, pws->pw_gid)) || | 1659 | (0 != initgroups (user, pws->pw_gid)) || |
1651 | #endif | 1660 | #endif |
1652 | (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid))) | 1661 | (0 != setuid (pws->pw_uid)) || |
1662 | (0 != seteuid (pws->pw_uid))) | ||
1653 | { | 1663 | { |
1654 | if ((0 != setregid (pws->pw_gid, pws->pw_gid)) || | 1664 | if ((0 != setregid (pws->pw_gid, pws->pw_gid)) || |
1655 | (0 != setreuid (pws->pw_uid, pws->pw_uid))) | 1665 | (0 != setreuid (pws->pw_uid, pws->pw_uid))) |
@@ -1680,10 +1690,11 @@ get_pid_file_name (struct GNUNET_SERVICE_Handle *sh) | |||
1680 | { | 1690 | { |
1681 | char *pif; | 1691 | char *pif; |
1682 | 1692 | ||
1683 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (sh->cfg, | 1693 | if (GNUNET_OK != |
1684 | sh->service_name, | 1694 | GNUNET_CONFIGURATION_get_value_filename (sh->cfg, |
1685 | "PIDFILE", | 1695 | sh->service_name, |
1686 | &pif)) | 1696 | "PIDFILE", |
1697 | &pif)) | ||
1687 | return NULL; | 1698 | return NULL; |
1688 | return pif; | 1699 | return pif; |
1689 | } | 1700 | } |
@@ -1702,7 +1713,9 @@ pid_file_delete (struct GNUNET_SERVICE_Handle *sh) | |||
1702 | if (NULL == pif) | 1713 | if (NULL == pif) |
1703 | return; /* no PID file */ | 1714 | return; /* no PID file */ |
1704 | if (0 != unlink (pif)) | 1715 | if (0 != unlink (pif)) |
1705 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif); | 1716 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, |
1717 | "unlink", | ||
1718 | pif); | ||
1706 | GNUNET_free (pif); | 1719 | GNUNET_free (pif); |
1707 | } | 1720 | } |
1708 | 1721 | ||
@@ -1713,7 +1726,7 @@ pid_file_delete (struct GNUNET_SERVICE_Handle *sh) | |||
1713 | * @param sh service context | 1726 | * @param sh service context |
1714 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 1727 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
1715 | */ | 1728 | */ |
1716 | static int | 1729 | static enum GNUNET_GenericReturnValue |
1717 | detach_terminal (struct GNUNET_SERVICE_Handle *sh) | 1730 | detach_terminal (struct GNUNET_SERVICE_Handle *sh) |
1718 | { | 1731 | { |
1719 | pid_t pid; | 1732 | pid_t pid; |
@@ -1722,13 +1735,15 @@ detach_terminal (struct GNUNET_SERVICE_Handle *sh) | |||
1722 | 1735 | ||
1723 | if (0 != pipe (filedes)) | 1736 | if (0 != pipe (filedes)) |
1724 | { | 1737 | { |
1725 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe"); | 1738 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, |
1739 | "pipe"); | ||
1726 | return GNUNET_SYSERR; | 1740 | return GNUNET_SYSERR; |
1727 | } | 1741 | } |
1728 | pid = fork (); | 1742 | pid = fork (); |
1729 | if (pid < 0) | 1743 | if (pid < 0) |
1730 | { | 1744 | { |
1731 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork"); | 1745 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, |
1746 | "fork"); | ||
1732 | return GNUNET_SYSERR; | 1747 | return GNUNET_SYSERR; |
1733 | } | 1748 | } |
1734 | if (0 != pid) | 1749 | if (0 != pid) |
@@ -1739,7 +1754,8 @@ detach_terminal (struct GNUNET_SERVICE_Handle *sh) | |||
1739 | GNUNET_break (0 == close (filedes[1])); | 1754 | GNUNET_break (0 == close (filedes[1])); |
1740 | c = 'X'; | 1755 | c = 'X'; |
1741 | if (1 != read (filedes[0], &c, sizeof(char))) | 1756 | if (1 != read (filedes[0], &c, sizeof(char))) |
1742 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "read"); | 1757 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, |
1758 | "read"); | ||
1743 | fflush (stdout); | 1759 | fflush (stdout); |
1744 | switch (c) | 1760 | switch (c) |
1745 | { | 1761 | { |
@@ -1780,7 +1796,8 @@ detach_terminal (struct GNUNET_SERVICE_Handle *sh) | |||
1780 | /* Detach from controlling terminal */ | 1796 | /* Detach from controlling terminal */ |
1781 | pid = setsid (); | 1797 | pid = setsid (); |
1782 | if (-1 == pid) | 1798 | if (-1 == pid) |
1783 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid"); | 1799 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, |
1800 | "setsid"); | ||
1784 | sh->ready_confirm_fd = filedes[1]; | 1801 | sh->ready_confirm_fd = filedes[1]; |
1785 | 1802 | ||
1786 | return GNUNET_OK; | 1803 | return GNUNET_OK; |
@@ -1804,7 +1821,9 @@ teardown_service (struct GNUNET_SERVICE_Handle *sh) | |||
1804 | GNUNET_free (sh->v6_allowed); | 1821 | GNUNET_free (sh->v6_allowed); |
1805 | while (NULL != (slc = sh->slc_head)) | 1822 | while (NULL != (slc = sh->slc_head)) |
1806 | { | 1823 | { |
1807 | GNUNET_CONTAINER_DLL_remove (sh->slc_head, sh->slc_tail, slc); | 1824 | GNUNET_CONTAINER_DLL_remove (sh->slc_head, |
1825 | sh->slc_tail, | ||
1826 | slc); | ||
1808 | if (NULL != slc->listen_task) | 1827 | if (NULL != slc->listen_task) |
1809 | GNUNET_SCHEDULER_cancel (slc->listen_task); | 1828 | GNUNET_SCHEDULER_cancel (slc->listen_task); |
1810 | GNUNET_break (GNUNET_OK == | 1829 | GNUNET_break (GNUNET_OK == |
@@ -1821,7 +1840,8 @@ teardown_service (struct GNUNET_SERVICE_Handle *sh) | |||
1821 | * @param msg AGPL request | 1840 | * @param msg AGPL request |
1822 | */ | 1841 | */ |
1823 | static void | 1842 | static void |
1824 | return_agpl (void *cls, const struct GNUNET_MessageHeader *msg) | 1843 | return_agpl (void *cls, |
1844 | const struct GNUNET_MessageHeader *msg) | ||
1825 | { | 1845 | { |
1826 | struct GNUNET_SERVICE_Client *client = cls; | 1846 | struct GNUNET_SERVICE_Client *client = cls; |
1827 | struct GNUNET_MQ_Handle *mq; | 1847 | struct GNUNET_MQ_Handle *mq; |
@@ -1832,50 +1852,17 @@ return_agpl (void *cls, const struct GNUNET_MessageHeader *msg) | |||
1832 | 1852 | ||
1833 | (void) msg; | 1853 | (void) msg; |
1834 | slen = strlen (pd->agpl_url) + 1; | 1854 | slen = strlen (pd->agpl_url) + 1; |
1835 | env = GNUNET_MQ_msg_extra (res, GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, slen); | 1855 | env = GNUNET_MQ_msg_extra (res, |
1836 | memcpy (&res[1], GNUNET_AGPL_URL, slen); | 1856 | GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, slen); |
1857 | memcpy (&res[1], | ||
1858 | GNUNET_AGPL_URL, | ||
1859 | slen); | ||
1837 | mq = GNUNET_SERVICE_client_get_mq (client); | 1860 | mq = GNUNET_SERVICE_client_get_mq (client); |
1838 | GNUNET_MQ_send (mq, env); | 1861 | GNUNET_MQ_send (mq, env); |
1839 | GNUNET_SERVICE_client_continue (client); | 1862 | GNUNET_SERVICE_client_continue (client); |
1840 | } | 1863 | } |
1841 | 1864 | ||
1842 | 1865 | ||
1843 | /** | ||
1844 | * Low-level function to start a service if the scheduler | ||
1845 | * is already running. Should only be used directly in | ||
1846 | * special cases. | ||
1847 | * | ||
1848 | * The function will launch the service with the name @a service_name | ||
1849 | * using the @a service_options to configure its shutdown | ||
1850 | * behavior. When clients connect or disconnect, the respective | ||
1851 | * @a connect_cb or @a disconnect_cb functions will be called. For | ||
1852 | * messages received from the clients, the respective @a handlers will | ||
1853 | * be invoked; for the closure of the handlers we use the return value | ||
1854 | * from the @a connect_cb invocation of the respective client. | ||
1855 | * | ||
1856 | * Each handler MUST call #GNUNET_SERVICE_client_continue() after each | ||
1857 | * message to receive further messages from this client. If | ||
1858 | * #GNUNET_SERVICE_client_continue() is not called within a short | ||
1859 | * time, a warning will be logged. If delays are expected, services | ||
1860 | * should call #GNUNET_SERVICE_client_disable_continue_warning() to | ||
1861 | * disable the warning. | ||
1862 | * | ||
1863 | * Clients sending invalid messages (based on @a handlers) will be | ||
1864 | * dropped. Additionally, clients can be dropped at any time using | ||
1865 | * #GNUNET_SERVICE_client_drop(). | ||
1866 | * | ||
1867 | * The service must be stopped using #GNUNET_SERVICE_stop(). | ||
1868 | * | ||
1869 | * @param service_name name of the service to run | ||
1870 | * @param cfg configuration to use | ||
1871 | * @param connect_cb function to call whenever a client connects | ||
1872 | * @param disconnect_cb function to call whenever a client disconnects | ||
1873 | * @param cls closure argument for @a connect_cb and @a disconnect_cb | ||
1874 | * @param handlers NULL-terminated array of message handlers for the service, | ||
1875 | * the closure will be set to the value returned by | ||
1876 | * the @a connect_cb for the respective connection | ||
1877 | * @return NULL on error | ||
1878 | */ | ||
1879 | struct GNUNET_SERVICE_Handle * | 1866 | struct GNUNET_SERVICE_Handle * |
1880 | GNUNET_SERVICE_start (const char *service_name, | 1867 | GNUNET_SERVICE_start (const char *service_name, |
1881 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 1868 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
@@ -1892,23 +1879,61 @@ GNUNET_SERVICE_start (const char *service_name, | |||
1892 | sh->connect_cb = connect_cb; | 1879 | sh->connect_cb = connect_cb; |
1893 | sh->disconnect_cb = disconnect_cb; | 1880 | sh->disconnect_cb = disconnect_cb; |
1894 | sh->cb_cls = cls; | 1881 | sh->cb_cls = cls; |
1895 | sh->handlers = GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL); | 1882 | sh->handlers = GNUNET_MQ_copy_handlers2 (handlers, |
1883 | &return_agpl, | ||
1884 | NULL); | ||
1896 | if (GNUNET_OK != setup_service (sh)) | 1885 | if (GNUNET_OK != setup_service (sh)) |
1897 | { | 1886 | { |
1898 | GNUNET_free (sh->handlers); | 1887 | GNUNET_free (sh->handlers); |
1899 | GNUNET_free (sh); | 1888 | GNUNET_free (sh); |
1900 | return NULL; | 1889 | return NULL; |
1901 | } | 1890 | } |
1902 | do_resume (sh, SUSPEND_STATE_NONE); | 1891 | do_resume (sh, |
1892 | SUSPEND_STATE_NONE); | ||
1903 | return sh; | 1893 | return sh; |
1904 | } | 1894 | } |
1905 | 1895 | ||
1906 | 1896 | ||
1907 | /** | 1897 | /** |
1908 | * Stops a service that was started with #GNUNET_SERVICE_start(). | 1898 | * Asynchronously finish dropping the client. |
1909 | * | 1899 | * |
1910 | * @param srv service to stop | 1900 | * @param cls the `struct GNUNET_SERVICE_Client`. |
1911 | */ | 1901 | */ |
1902 | static void | ||
1903 | finish_client_drop (void *cls) | ||
1904 | { | ||
1905 | struct GNUNET_SERVICE_Client *c = cls; | ||
1906 | struct GNUNET_SERVICE_Handle *sh = c->sh; | ||
1907 | |||
1908 | c->drop_task = NULL; | ||
1909 | GNUNET_CONTAINER_DLL_remove (sh->clients_head, | ||
1910 | sh->clients_tail, | ||
1911 | c); | ||
1912 | GNUNET_assert (NULL == c->send_task); | ||
1913 | GNUNET_assert (NULL == c->recv_task); | ||
1914 | GNUNET_assert (NULL == c->warn_task); | ||
1915 | GNUNET_MST_destroy (c->mst); | ||
1916 | GNUNET_MQ_destroy (c->mq); | ||
1917 | if (! c->persist) | ||
1918 | { | ||
1919 | GNUNET_break (GNUNET_OK == | ||
1920 | GNUNET_NETWORK_socket_close (c->sock)); | ||
1921 | if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) && | ||
1922 | (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state))) | ||
1923 | do_resume (sh, | ||
1924 | SUSPEND_STATE_EMFILE); | ||
1925 | } | ||
1926 | else | ||
1927 | { | ||
1928 | GNUNET_NETWORK_socket_free_memory_only_ (c->sock); | ||
1929 | } | ||
1930 | GNUNET_free (c); | ||
1931 | if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) && | ||
1932 | (! have_non_monitor_clients (sh))) | ||
1933 | GNUNET_SERVICE_shutdown (sh); | ||
1934 | } | ||
1935 | |||
1936 | |||
1912 | void | 1937 | void |
1913 | GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv) | 1938 | GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv) |
1914 | { | 1939 | { |
@@ -1916,7 +1941,12 @@ GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv) | |||
1916 | 1941 | ||
1917 | GNUNET_SERVICE_suspend (srv); | 1942 | GNUNET_SERVICE_suspend (srv); |
1918 | while (NULL != (client = srv->clients_head)) | 1943 | while (NULL != (client = srv->clients_head)) |
1919 | GNUNET_SERVICE_client_drop (client); | 1944 | { |
1945 | if (NULL == client->drop_task) | ||
1946 | GNUNET_SERVICE_client_drop (client); | ||
1947 | GNUNET_SCHEDULER_cancel (client->drop_task); | ||
1948 | finish_client_drop (client); | ||
1949 | } | ||
1920 | teardown_service (srv); | 1950 | teardown_service (srv); |
1921 | GNUNET_free (srv->handlers); | 1951 | GNUNET_free (srv->handlers); |
1922 | GNUNET_free (srv); | 1952 | GNUNET_free (srv); |
@@ -1988,7 +2018,6 @@ GNUNET_SERVICE_run_ (int argc, | |||
1988 | ? GNUNET_MQ_copy_handlers (handlers) | 2018 | ? GNUNET_MQ_copy_handlers (handlers) |
1989 | : GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL); | 2019 | : GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL); |
1990 | sh.service_name = service_name; | 2020 | sh.service_name = service_name; |
1991 | sh.ret = 0; | ||
1992 | /* setup subsystems */ | 2021 | /* setup subsystems */ |
1993 | loglev = NULL; | 2022 | loglev = NULL; |
1994 | logfile = NULL; | 2023 | logfile = NULL; |
@@ -2040,9 +2069,12 @@ GNUNET_SERVICE_run_ (int argc, | |||
2040 | } | 2069 | } |
2041 | else | 2070 | else |
2042 | { | 2071 | { |
2043 | if (GNUNET_YES == GNUNET_DISK_file_test (cfg_filename)) | 2072 | if (GNUNET_YES == |
2073 | GNUNET_DISK_file_test (cfg_filename)) | ||
2044 | { | 2074 | { |
2045 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_filename)) | 2075 | if (GNUNET_SYSERR == |
2076 | GNUNET_CONFIGURATION_load (cfg, | ||
2077 | cfg_filename)) | ||
2046 | { | 2078 | { |
2047 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 2079 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2048 | _ ("Malformed configuration file `%s', exit ...\n"), | 2080 | _ ("Malformed configuration file `%s', exit ...\n"), |
@@ -2052,7 +2084,9 @@ GNUNET_SERVICE_run_ (int argc, | |||
2052 | } | 2084 | } |
2053 | else | 2085 | else |
2054 | { | 2086 | { |
2055 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL)) | 2087 | if (GNUNET_SYSERR == |
2088 | GNUNET_CONFIGURATION_load (cfg, | ||
2089 | NULL)) | ||
2056 | { | 2090 | { |
2057 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 2091 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2058 | _ ("Malformed configuration, exit ...\n")); | 2092 | _ ("Malformed configuration, exit ...\n")); |
@@ -2062,7 +2096,8 @@ GNUNET_SERVICE_run_ (int argc, | |||
2062 | } | 2096 | } |
2063 | if (GNUNET_OK != setup_service (&sh)) | 2097 | if (GNUNET_OK != setup_service (&sh)) |
2064 | goto shutdown; | 2098 | goto shutdown; |
2065 | if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sh))) | 2099 | if ( (1 == do_daemonize) && |
2100 | (GNUNET_OK != detach_terminal (&sh)) ) | ||
2066 | { | 2101 | { |
2067 | GNUNET_break (0); | 2102 | GNUNET_break (0); |
2068 | goto shutdown; | 2103 | goto shutdown; |
@@ -2073,14 +2108,16 @@ GNUNET_SERVICE_run_ (int argc, | |||
2073 | "Service `%s' runs with configuration from `%s'\n", | 2108 | "Service `%s' runs with configuration from `%s'\n", |
2074 | service_name, | 2109 | service_name, |
2075 | (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename); | 2110 | (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename); |
2076 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sh.cfg, | 2111 | if ( (GNUNET_OK == |
2077 | "TESTING", | 2112 | GNUNET_CONFIGURATION_get_value_number (sh.cfg, |
2078 | "SKEW_OFFSET", | 2113 | "TESTING", |
2079 | &skew_offset)) && | 2114 | "SKEW_OFFSET", |
2080 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sh.cfg, | 2115 | &skew_offset)) && |
2081 | "TESTING", | 2116 | (GNUNET_OK == |
2082 | "SKEW_VARIANCE", | 2117 | GNUNET_CONFIGURATION_get_value_number (sh.cfg, |
2083 | &skew_variance))) | 2118 | "TESTING", |
2119 | "SKEW_VARIANCE", | ||
2120 | &skew_variance)) ) | ||
2084 | { | 2121 | { |
2085 | clock_offset = skew_offset - skew_variance; | 2122 | clock_offset = skew_offset - skew_variance; |
2086 | GNUNET_TIME_set_offset (clock_offset); | 2123 | GNUNET_TIME_set_offset (clock_offset); |
@@ -2108,18 +2145,23 @@ shutdown: | |||
2108 | { | 2145 | { |
2109 | char *counter; | 2146 | char *counter; |
2110 | 2147 | ||
2111 | if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (sh.cfg, | 2148 | if ( (GNUNET_YES == |
2112 | service_name, | 2149 | GNUNET_CONFIGURATION_have_value (sh.cfg, |
2113 | "GAUGER_HEAP")) && | 2150 | service_name, |
2114 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (sh.cfg, | 2151 | "GAUGER_HEAP")) && |
2115 | service_name, | 2152 | (GNUNET_OK == |
2116 | "GAUGER_HEAP", | 2153 | GNUNET_CONFIGURATION_get_value_string (sh.cfg, |
2117 | &counter))) | 2154 | service_name, |
2155 | "GAUGER_HEAP", | ||
2156 | &counter))) | ||
2118 | { | 2157 | { |
2119 | struct mallinfo2 mi; | 2158 | struct mallinfo2 mi; |
2120 | 2159 | ||
2121 | mi = mallinfo2 (); | 2160 | mi = mallinfo2 (); |
2122 | GAUGER (service_name, counter, mi.usmblks, "blocks"); | 2161 | GAUGER (service_name, |
2162 | counter, | ||
2163 | mi.usmblks, | ||
2164 | "blocks"); | ||
2123 | GNUNET_free (counter); | 2165 | GNUNET_free (counter); |
2124 | } | 2166 | } |
2125 | } | 2167 | } |
@@ -2133,11 +2175,12 @@ shutdown: | |||
2133 | GNUNET_free (cfg_filename); | 2175 | GNUNET_free (cfg_filename); |
2134 | GNUNET_free (opt_cfg_filename); | 2176 | GNUNET_free (opt_cfg_filename); |
2135 | 2177 | ||
2136 | return err ? GNUNET_SYSERR : sh.ret; | 2178 | return err ? GNUNET_SYSERR : 0; |
2137 | } | 2179 | } |
2138 | 2180 | ||
2139 | 2181 | ||
2140 | /* A list of service to be launched when GNUNET_SERVICE_main() | 2182 | /** |
2183 | * A list of service to be launched when GNUNET_SERVICE_main() | ||
2141 | * is called | 2184 | * is called |
2142 | */ | 2185 | */ |
2143 | struct ServiceHandleList | 2186 | struct ServiceHandleList |
@@ -2153,10 +2196,11 @@ struct ServiceHandleList | |||
2153 | }; | 2196 | }; |
2154 | 2197 | ||
2155 | /* The service list */ | 2198 | /* The service list */ |
2156 | static struct ServiceHandleList *hll_head = NULL; | 2199 | static struct ServiceHandleList *hll_head; |
2157 | 2200 | ||
2158 | /* The service list */ | 2201 | /* The service list */ |
2159 | static struct ServiceHandleList *hll_tail = NULL; | 2202 | static struct ServiceHandleList *hll_tail; |
2203 | |||
2160 | 2204 | ||
2161 | int | 2205 | int |
2162 | GNUNET_SERVICE_register_ (const char *service_name, | 2206 | GNUNET_SERVICE_register_ (const char *service_name, |
@@ -2181,30 +2225,34 @@ GNUNET_SERVICE_register_ (const char *service_name, | |||
2181 | ? GNUNET_MQ_copy_handlers (handlers) | 2225 | ? GNUNET_MQ_copy_handlers (handlers) |
2182 | : GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL); | 2226 | : GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL); |
2183 | sh->service_name = service_name; | 2227 | sh->service_name = service_name; |
2184 | sh->ret = 0; | ||
2185 | hle = GNUNET_new (struct ServiceHandleList); | 2228 | hle = GNUNET_new (struct ServiceHandleList); |
2186 | hle->sh = sh; | 2229 | hle->sh = sh; |
2187 | GNUNET_CONTAINER_DLL_insert (hll_head, hll_tail, hle); | 2230 | GNUNET_CONTAINER_DLL_insert (hll_head, |
2188 | return GNUNET_OK; | 2231 | hll_tail, |
2232 | hle); | ||
2233 | return 0; | ||
2189 | } | 2234 | } |
2190 | 2235 | ||
2191 | 2236 | ||
2192 | static void | 2237 | static void |
2193 | do_registered_services_shutdown (void *cls) | 2238 | do_registered_services_shutdown (void *cls) |
2194 | { | 2239 | { |
2195 | struct GNUNET_SERVICE_Handle *sh; | 2240 | while (NULL != hll_head) |
2196 | struct ServiceHandleList *shl; | ||
2197 | |||
2198 | for (shl = hll_head; NULL != shl;) | ||
2199 | { | 2241 | { |
2200 | sh = shl->sh; | 2242 | struct ServiceHandleList *shl = hll_head; |
2201 | GNUNET_CONTAINER_DLL_remove (hll_head, hll_tail, shl); | 2243 | struct GNUNET_SERVICE_Handle *sh = shl->sh; |
2244 | |||
2245 | GNUNET_CONTAINER_DLL_remove (hll_head, | ||
2246 | hll_tail, | ||
2247 | shl); | ||
2202 | GNUNET_free (shl); | 2248 | GNUNET_free (shl); |
2203 | if (-1 != sh->ready_confirm_fd) | 2249 | if (-1 != sh->ready_confirm_fd) |
2204 | { | 2250 | { |
2205 | if (1 != write (sh->ready_confirm_fd, "S", 1)) | 2251 | if (1 != write (sh->ready_confirm_fd, "S", 1)) |
2206 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write"); | 2252 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, |
2207 | GNUNET_break (0 == close (sh->ready_confirm_fd)); | 2253 | "write"); |
2254 | GNUNET_break (0 == | ||
2255 | close (sh->ready_confirm_fd)); | ||
2208 | } | 2256 | } |
2209 | teardown_service (sh); | 2257 | teardown_service (sh); |
2210 | GNUNET_free (sh->handlers); | 2258 | GNUNET_free (sh->handlers); |
@@ -2216,20 +2264,22 @@ do_registered_services_shutdown (void *cls) | |||
2216 | static void | 2264 | static void |
2217 | launch_registered_services (void *cls) | 2265 | launch_registered_services (void *cls) |
2218 | { | 2266 | { |
2219 | struct ServiceHandleList *shl; | ||
2220 | struct GNUNET_CONFIGURATION_Handle *cfg = cls; | 2267 | struct GNUNET_CONFIGURATION_Handle *cfg = cls; |
2221 | 2268 | ||
2222 | for (shl = hll_head; NULL != shl; shl = shl->next) | 2269 | for (struct ServiceHandleList *shl = hll_head; |
2270 | NULL != shl; | ||
2271 | shl = shl->next) | ||
2223 | { | 2272 | { |
2224 | shl->sh->cfg = cfg; | 2273 | shl->sh->cfg = cfg; |
2225 | if (GNUNET_OK != setup_service (shl->sh)) | 2274 | if (GNUNET_OK != setup_service (shl->sh)) |
2226 | continue; | 2275 | continue; |
2227 | if (GNUNET_OK != set_user_id (shl->sh)) | 2276 | if (GNUNET_OK != set_user_id (shl->sh)) |
2228 | continue; | 2277 | continue; |
2229 | 2278 | GNUNET_SCHEDULER_add_now (&service_main, | |
2230 | GNUNET_SCHEDULER_add_now (&service_main, shl->sh); | 2279 | shl->sh); |
2231 | } | 2280 | } |
2232 | GNUNET_SCHEDULER_add_shutdown (&do_registered_services_shutdown, NULL); | 2281 | GNUNET_SCHEDULER_add_shutdown (&do_registered_services_shutdown, |
2282 | NULL); | ||
2233 | } | 2283 | } |
2234 | 2284 | ||
2235 | 2285 | ||
@@ -2246,7 +2296,6 @@ GNUNET_SERVICE_main (int argc, | |||
2246 | int ret; | 2296 | int ret; |
2247 | struct GNUNET_CONFIGURATION_Handle *cfg; | 2297 | struct GNUNET_CONFIGURATION_Handle *cfg; |
2248 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get (); | 2298 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get (); |
2249 | |||
2250 | struct GNUNET_GETOPT_CommandLineOption service_options[] = { | 2299 | struct GNUNET_GETOPT_CommandLineOption service_options[] = { |
2251 | GNUNET_GETOPT_option_cfgfile (&opt_cfg_filename), | 2300 | GNUNET_GETOPT_option_cfgfile (&opt_cfg_filename), |
2252 | GNUNET_GETOPT_option_flag ('d', | 2301 | GNUNET_GETOPT_option_flag ('d', |
@@ -2260,6 +2309,7 @@ GNUNET_SERVICE_main (int argc, | |||
2260 | GNUNET_GETOPT_option_version (pd->version), | 2309 | GNUNET_GETOPT_option_version (pd->version), |
2261 | GNUNET_GETOPT_OPTION_END | 2310 | GNUNET_GETOPT_OPTION_END |
2262 | }; | 2311 | }; |
2312 | |||
2263 | xdg = getenv ("XDG_CONFIG_HOME"); | 2313 | xdg = getenv ("XDG_CONFIG_HOME"); |
2264 | if (NULL != xdg) | 2314 | if (NULL != xdg) |
2265 | GNUNET_asprintf (&cfg_filename, | 2315 | GNUNET_asprintf (&cfg_filename, |
@@ -2282,17 +2332,22 @@ GNUNET_SERVICE_main (int argc, | |||
2282 | goto shutdown; | 2332 | goto shutdown; |
2283 | } | 2333 | } |
2284 | // FIXME we need to set this up for each service! | 2334 | // FIXME we need to set this up for each service! |
2285 | if (GNUNET_OK != GNUNET_log_setup ("libgnunet", | 2335 | // NOTE: that was not the idea. What are you proposing? -CG |
2286 | loglev, | 2336 | if (GNUNET_OK != |
2287 | logfile)) | 2337 | GNUNET_log_setup ("libgnunet", |
2338 | loglev, | ||
2339 | logfile)) | ||
2288 | { | 2340 | { |
2289 | GNUNET_break (0); | 2341 | GNUNET_break (0); |
2290 | goto shutdown; | 2342 | goto shutdown; |
2291 | } | 2343 | } |
2292 | if (NULL != opt_cfg_filename) | 2344 | if (NULL != opt_cfg_filename) |
2293 | { | 2345 | { |
2294 | if ((GNUNET_YES != GNUNET_DISK_file_test (opt_cfg_filename)) || | 2346 | if ( (GNUNET_YES != |
2295 | (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_filename))) | 2347 | GNUNET_DISK_file_test (opt_cfg_filename)) || |
2348 | (GNUNET_SYSERR == | ||
2349 | GNUNET_CONFIGURATION_load (cfg, | ||
2350 | opt_cfg_filename)) ) | ||
2296 | { | 2351 | { |
2297 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 2352 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2298 | _ ("Malformed configuration file `%s', exit ...\n"), | 2353 | _ ("Malformed configuration file `%s', exit ...\n"), |
@@ -2302,9 +2357,12 @@ GNUNET_SERVICE_main (int argc, | |||
2302 | } | 2357 | } |
2303 | else | 2358 | else |
2304 | { | 2359 | { |
2305 | if (GNUNET_YES == GNUNET_DISK_file_test (cfg_filename)) | 2360 | if (GNUNET_YES == |
2361 | GNUNET_DISK_file_test (cfg_filename)) | ||
2306 | { | 2362 | { |
2307 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_filename)) | 2363 | if (GNUNET_SYSERR == |
2364 | GNUNET_CONFIGURATION_load (cfg, | ||
2365 | cfg_filename)) | ||
2308 | { | 2366 | { |
2309 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 2367 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2310 | _ ("Malformed configuration file `%s', exit ...\n"), | 2368 | _ ("Malformed configuration file `%s', exit ...\n"), |
@@ -2315,7 +2373,9 @@ GNUNET_SERVICE_main (int argc, | |||
2315 | } | 2373 | } |
2316 | else | 2374 | else |
2317 | { | 2375 | { |
2318 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL)) | 2376 | if (GNUNET_SYSERR == |
2377 | GNUNET_CONFIGURATION_load (cfg, | ||
2378 | NULL)) | ||
2319 | { | 2379 | { |
2320 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 2380 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2321 | _ ("Malformed configuration, exit ...\n")); | 2381 | _ ("Malformed configuration, exit ...\n")); |
@@ -2326,7 +2386,8 @@ GNUNET_SERVICE_main (int argc, | |||
2326 | } | 2386 | } |
2327 | GNUNET_RESOLVER_connect (cfg); | 2387 | GNUNET_RESOLVER_connect (cfg); |
2328 | 2388 | ||
2329 | GNUNET_SCHEDULER_run (&launch_registered_services, cfg); | 2389 | GNUNET_SCHEDULER_run (&launch_registered_services, |
2390 | cfg); | ||
2330 | shutdown: | 2391 | shutdown: |
2331 | GNUNET_SPEEDUP_stop_ (); | 2392 | GNUNET_SPEEDUP_stop_ (); |
2332 | GNUNET_CONFIGURATION_destroy (cfg); | 2393 | GNUNET_CONFIGURATION_destroy (cfg); |
@@ -2337,28 +2398,19 @@ shutdown: | |||
2337 | } | 2398 | } |
2338 | 2399 | ||
2339 | 2400 | ||
2340 | /** | ||
2341 | * Suspend accepting connections from the listen socket temporarily. | ||
2342 | * Resume activity using #GNUNET_SERVICE_resume. | ||
2343 | * | ||
2344 | * @param sh service to stop accepting connections. | ||
2345 | */ | ||
2346 | void | 2401 | void |
2347 | GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh) | 2402 | GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh) |
2348 | { | 2403 | { |
2349 | do_suspend (sh, SUSPEND_STATE_APP); | 2404 | do_suspend (sh, |
2405 | SUSPEND_STATE_APP); | ||
2350 | } | 2406 | } |
2351 | 2407 | ||
2352 | 2408 | ||
2353 | /** | ||
2354 | * Resume accepting connections from the listen socket. | ||
2355 | * | ||
2356 | * @param sh service to resume accepting connections. | ||
2357 | */ | ||
2358 | void | 2409 | void |
2359 | GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh) | 2410 | GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh) |
2360 | { | 2411 | { |
2361 | do_resume (sh, SUSPEND_STATE_APP); | 2412 | do_resume (sh, |
2413 | SUSPEND_STATE_APP); | ||
2362 | } | 2414 | } |
2363 | 2415 | ||
2364 | 2416 | ||
@@ -2376,7 +2428,8 @@ resume_client_receive (void *cls) | |||
2376 | 2428 | ||
2377 | c->recv_task = NULL; | 2429 | c->recv_task = NULL; |
2378 | /* first, check if there is still something in the buffer */ | 2430 | /* first, check if there is still something in the buffer */ |
2379 | ret = GNUNET_MST_next (c->mst, GNUNET_YES); | 2431 | ret = GNUNET_MST_next (c->mst, |
2432 | GNUNET_YES); | ||
2380 | if (GNUNET_SYSERR == ret) | 2433 | if (GNUNET_SYSERR == ret) |
2381 | { | 2434 | { |
2382 | if (NULL == c->drop_task) | 2435 | if (NULL == c->drop_task) |
@@ -2386,7 +2439,7 @@ resume_client_receive (void *cls) | |||
2386 | if (GNUNET_NO == ret) | 2439 | if (GNUNET_NO == ret) |
2387 | return; /* done processing, wait for more later */ | 2440 | return; /* done processing, wait for more later */ |
2388 | GNUNET_assert (GNUNET_OK == ret); | 2441 | GNUNET_assert (GNUNET_OK == ret); |
2389 | if (GNUNET_YES == c->needs_continue) | 2442 | if (c->needs_continue) |
2390 | return; /* #GNUNET_MST_next() did give a message to the client */ | 2443 | return; /* #GNUNET_MST_next() did give a message to the client */ |
2391 | /* need to receive more data from the network first */ | 2444 | /* need to receive more data from the network first */ |
2392 | if (NULL != c->recv_task) | 2445 | if (NULL != c->recv_task) |
@@ -2398,36 +2451,23 @@ resume_client_receive (void *cls) | |||
2398 | } | 2451 | } |
2399 | 2452 | ||
2400 | 2453 | ||
2401 | /** | ||
2402 | * Continue receiving further messages from the given client. | ||
2403 | * Must be called after each message received. | ||
2404 | * | ||
2405 | * @param c the client to continue receiving from | ||
2406 | */ | ||
2407 | void | 2454 | void |
2408 | GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c) | 2455 | GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c) |
2409 | { | 2456 | { |
2410 | GNUNET_assert (NULL == c->drop_task); | 2457 | GNUNET_assert (NULL == c->drop_task); |
2411 | GNUNET_assert (GNUNET_YES == c->needs_continue); | 2458 | GNUNET_assert (c->needs_continue); |
2412 | GNUNET_assert (NULL == c->recv_task); | 2459 | GNUNET_assert (NULL == c->recv_task); |
2413 | c->needs_continue = GNUNET_NO; | 2460 | c->needs_continue = false; |
2414 | if (NULL != c->warn_task) | 2461 | if (NULL != c->warn_task) |
2415 | { | 2462 | { |
2416 | GNUNET_SCHEDULER_cancel (c->warn_task); | 2463 | GNUNET_SCHEDULER_cancel (c->warn_task); |
2417 | c->warn_task = NULL; | 2464 | c->warn_task = NULL; |
2418 | } | 2465 | } |
2419 | c->recv_task = GNUNET_SCHEDULER_add_now (&resume_client_receive, c); | 2466 | c->recv_task = GNUNET_SCHEDULER_add_now (&resume_client_receive, |
2467 | c); | ||
2420 | } | 2468 | } |
2421 | 2469 | ||
2422 | 2470 | ||
2423 | /** | ||
2424 | * Disable the warning the server issues if a message is not | ||
2425 | * acknowledged in a timely fashion. Use this call if a client is | ||
2426 | * intentionally delayed for a while. Only applies to the current | ||
2427 | * message. | ||
2428 | * | ||
2429 | * @param c client for which to disable the warning | ||
2430 | */ | ||
2431 | void | 2471 | void |
2432 | GNUNET_SERVICE_client_disable_continue_warning (struct GNUNET_SERVICE_Client *c) | 2472 | GNUNET_SERVICE_client_disable_continue_warning (struct GNUNET_SERVICE_Client *c) |
2433 | { | 2473 | { |
@@ -2440,51 +2480,6 @@ GNUNET_SERVICE_client_disable_continue_warning (struct GNUNET_SERVICE_Client *c) | |||
2440 | } | 2480 | } |
2441 | 2481 | ||
2442 | 2482 | ||
2443 | /** | ||
2444 | * Asynchronously finish dropping the client. | ||
2445 | * | ||
2446 | * @param cls the `struct GNUNET_SERVICE_Client`. | ||
2447 | */ | ||
2448 | static void | ||
2449 | finish_client_drop (void *cls) | ||
2450 | { | ||
2451 | struct GNUNET_SERVICE_Client *c = cls; | ||
2452 | struct GNUNET_SERVICE_Handle *sh = c->sh; | ||
2453 | |||
2454 | c->drop_task = NULL; | ||
2455 | GNUNET_assert (NULL == c->send_task); | ||
2456 | GNUNET_assert (NULL == c->recv_task); | ||
2457 | GNUNET_assert (NULL == c->warn_task); | ||
2458 | GNUNET_MST_destroy (c->mst); | ||
2459 | GNUNET_MQ_destroy (c->mq); | ||
2460 | if (GNUNET_NO == c->persist) | ||
2461 | { | ||
2462 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (c->sock)); | ||
2463 | if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) && | ||
2464 | (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state))) | ||
2465 | do_resume (sh, SUSPEND_STATE_EMFILE); | ||
2466 | } | ||
2467 | else | ||
2468 | { | ||
2469 | GNUNET_NETWORK_socket_free_memory_only_ (c->sock); | ||
2470 | } | ||
2471 | GNUNET_free (c); | ||
2472 | if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) && | ||
2473 | (GNUNET_NO == have_non_monitor_clients (sh))) | ||
2474 | GNUNET_SERVICE_shutdown (sh); | ||
2475 | } | ||
2476 | |||
2477 | |||
2478 | /** | ||
2479 | * Ask the server to disconnect from the given client. This is the | ||
2480 | * same as returning #GNUNET_SYSERR within the check procedure when | ||
2481 | * handling a message, wexcept that it allows dropping of a client even | ||
2482 | * when not handling a message from that client. The `disconnect_cb` | ||
2483 | * will be called on @a c even if the application closes the connection | ||
2484 | * using this function. | ||
2485 | * | ||
2486 | * @param c client to disconnect now | ||
2487 | */ | ||
2488 | void | 2483 | void |
2489 | GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c) | 2484 | GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c) |
2490 | { | 2485 | { |
@@ -2497,9 +2492,11 @@ GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c) | |||
2497 | #if EXECINFO | 2492 | #if EXECINFO |
2498 | { | 2493 | { |
2499 | void *backtrace_array[MAX_TRACE_DEPTH]; | 2494 | void *backtrace_array[MAX_TRACE_DEPTH]; |
2500 | int num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH); | 2495 | int num_backtrace_strings = backtrace (backtrace_array, |
2496 | MAX_TRACE_DEPTH); | ||
2501 | char **backtrace_strings = | 2497 | char **backtrace_strings = |
2502 | backtrace_symbols (backtrace_array, t->num_backtrace_strings); | 2498 | backtrace_symbols (backtrace_array, |
2499 | t->num_backtrace_strings); | ||
2503 | for (unsigned int i = 0; i < num_backtrace_strings; i++) | 2500 | for (unsigned int i = 0; i < num_backtrace_strings; i++) |
2504 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2501 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2505 | "client drop trace %u: %s\n", | 2502 | "client drop trace %u: %s\n", |
@@ -2507,15 +2504,7 @@ GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c) | |||
2507 | backtrace_strings[i]); | 2504 | backtrace_strings[i]); |
2508 | } | 2505 | } |
2509 | #endif | 2506 | #endif |
2510 | if (NULL != c->drop_task) | 2507 | GNUNET_assert (NULL == c->drop_task); |
2511 | { | ||
2512 | /* asked to drop twice! */ | ||
2513 | GNUNET_assert (0); | ||
2514 | return; | ||
2515 | } | ||
2516 | GNUNET_CONTAINER_DLL_remove (sh->clients_head, | ||
2517 | sh->clients_tail, | ||
2518 | c); | ||
2519 | if (NULL != sh->disconnect_cb) | 2508 | if (NULL != sh->disconnect_cb) |
2520 | sh->disconnect_cb (sh->cb_cls, | 2509 | sh->disconnect_cb (sh->cb_cls, |
2521 | c, | 2510 | c, |
@@ -2535,69 +2524,44 @@ GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c) | |||
2535 | GNUNET_SCHEDULER_cancel (c->send_task); | 2524 | GNUNET_SCHEDULER_cancel (c->send_task); |
2536 | c->send_task = NULL; | 2525 | c->send_task = NULL; |
2537 | } | 2526 | } |
2538 | c->drop_task = GNUNET_SCHEDULER_add_now (&finish_client_drop, c); | 2527 | c->drop_task = GNUNET_SCHEDULER_add_now (&finish_client_drop, |
2528 | c); | ||
2539 | } | 2529 | } |
2540 | 2530 | ||
2541 | 2531 | ||
2542 | /** | ||
2543 | * Explicitly stops the service. | ||
2544 | * | ||
2545 | * @param sh server to shutdown | ||
2546 | */ | ||
2547 | void | 2532 | void |
2548 | GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh) | 2533 | GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh) |
2549 | { | 2534 | { |
2550 | struct GNUNET_SERVICE_Client *client; | ||
2551 | |||
2552 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) | 2535 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) |
2553 | do_suspend (sh, SUSPEND_STATE_SHUTDOWN); | 2536 | do_suspend (sh, |
2554 | while (NULL != (client = sh->clients_head)) | 2537 | SUSPEND_STATE_SHUTDOWN); |
2555 | GNUNET_SERVICE_client_drop (client); | 2538 | for (struct GNUNET_SERVICE_Client *client = sh->clients_head; |
2539 | NULL != client; | ||
2540 | client = client->next) | ||
2541 | { | ||
2542 | if (NULL == client->drop_task) | ||
2543 | GNUNET_SERVICE_client_drop (client); | ||
2544 | } | ||
2556 | } | 2545 | } |
2557 | 2546 | ||
2558 | 2547 | ||
2559 | /** | ||
2560 | * Set the 'monitor' flag on this client. Clients which have been | ||
2561 | * marked as 'monitors' won't prevent the server from shutting down | ||
2562 | * once #GNUNET_SERVICE_stop_listening() has been invoked. The idea is | ||
2563 | * that for "normal" clients we likely want to allow them to process | ||
2564 | * their requests; however, monitor-clients are likely to 'never' | ||
2565 | * disconnect during shutdown and thus will not be considered when | ||
2566 | * determining if the server should continue to exist after | ||
2567 | * shutdown has been triggered. | ||
2568 | * | ||
2569 | * @param c client to mark as a monitor | ||
2570 | */ | ||
2571 | void | 2548 | void |
2572 | GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c) | 2549 | GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c) |
2573 | { | 2550 | { |
2574 | c->is_monitor = GNUNET_YES; | 2551 | c->is_monitor = true; |
2575 | if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) && | 2552 | if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) && |
2576 | (GNUNET_NO == have_non_monitor_clients (c->sh)))) | 2553 | (! have_non_monitor_clients (c->sh)))) |
2577 | GNUNET_SERVICE_shutdown (c->sh); | 2554 | GNUNET_SERVICE_shutdown (c->sh); |
2578 | } | 2555 | } |
2579 | 2556 | ||
2580 | 2557 | ||
2581 | /** | ||
2582 | * Set the persist option on this client. Indicates that the | ||
2583 | * underlying socket or fd should never really be closed. Used for | ||
2584 | * indicating process death. | ||
2585 | * | ||
2586 | * @param c client to persist the socket (never to be closed) | ||
2587 | */ | ||
2588 | void | 2558 | void |
2589 | GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c) | 2559 | GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c) |
2590 | { | 2560 | { |
2591 | c->persist = GNUNET_YES; | 2561 | c->persist = true; |
2592 | } | 2562 | } |
2593 | 2563 | ||
2594 | 2564 | ||
2595 | /** | ||
2596 | * Obtain the message queue of @a c. Convenience function. | ||
2597 | * | ||
2598 | * @param c the client to continue receiving from | ||
2599 | * @return the message queue of @a c | ||
2600 | */ | ||
2601 | struct GNUNET_MQ_Handle * | 2565 | struct GNUNET_MQ_Handle * |
2602 | GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c) | 2566 | GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c) |
2603 | { | 2567 | { |
diff --git a/src/lib/util/strings.c b/src/lib/util/strings.c index fe7a030dd..dc9fd0daf 100644 --- a/src/lib/util/strings.c +++ b/src/lib/util/strings.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #define LOG(kind, ...) GNUNET_log_from (kind, "util-strings", __VA_ARGS__) | 37 | #define LOG(kind, ...) GNUNET_log_from (kind, "util-strings", __VA_ARGS__) |
38 | 38 | ||
39 | #define LOG_STRERROR(kind, syscall) \ | 39 | #define LOG_STRERROR(kind, syscall) \ |
40 | GNUNET_log_from_strerror (kind, "util-strings", syscall) | 40 | GNUNET_log_from_strerror (kind, "util-strings", syscall) |
41 | 41 | ||
42 | 42 | ||
43 | size_t | 43 | size_t |
@@ -1699,7 +1699,7 @@ GNUNET_STRINGS_base64url_encode (const void *in, | |||
1699 | 1699 | ||
1700 | 1700 | ||
1701 | #define cvtfind(a) \ | 1701 | #define cvtfind(a) \ |
1702 | ((((a) >= 'A') && ((a) <= 'Z')) \ | 1702 | ((((a) >= 'A') && ((a) <= 'Z')) \ |
1703 | ? (a) - 'A' \ | 1703 | ? (a) - 'A' \ |
1704 | : (((a) >= 'a') && ((a) <= 'z')) \ | 1704 | : (((a) >= 'a') && ((a) <= 'z')) \ |
1705 | ? (a) - 'a' + 26 \ | 1705 | ? (a) - 'a' + 26 \ |
@@ -1709,15 +1709,15 @@ GNUNET_STRINGS_base64url_encode (const void *in, | |||
1709 | 1709 | ||
1710 | 1710 | ||
1711 | #define CHECK_CRLF \ | 1711 | #define CHECK_CRLF \ |
1712 | while ( (data[i] == '\r') || (data[i] == '\n') ) \ | 1712 | while ( (data[i] == '\r') || (data[i] == '\n') ) \ |
1713 | { \ | 1713 | { \ |
1714 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, \ | 1714 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, \ |
1715 | "ignoring CR/LF\n"); \ | 1715 | "ignoring CR/LF\n"); \ |
1716 | i++; \ | 1716 | i++; \ |
1717 | if (i >= len) { \ | 1717 | if (i >= len) { \ |
1718 | goto END; \ | 1718 | goto END; \ |
1719 | } \ | 1719 | } \ |
1720 | } | 1720 | } |
1721 | 1721 | ||
1722 | 1722 | ||
1723 | size_t | 1723 | size_t |
@@ -1853,7 +1853,15 @@ GNUNET_STRINGS_urldecode (const char *data, | |||
1853 | if (1 != sscanf (rpos + 1, | 1853 | if (1 != sscanf (rpos + 1, |
1854 | "%2x", | 1854 | "%2x", |
1855 | &num)) | 1855 | &num)) |
1856 | { | ||
1857 | /* Invalid URL encoding, try to continue anyway */ | ||
1858 | GNUNET_break_op (0); | ||
1859 | *wpos = *rpos; | ||
1860 | wpos++; | ||
1861 | resl++; | ||
1862 | rpos++; | ||
1856 | break; | 1863 | break; |
1864 | } | ||
1857 | *wpos = (char) ((unsigned char) num); | 1865 | *wpos = (char) ((unsigned char) num); |
1858 | wpos++; | 1866 | wpos++; |
1859 | resl++; | 1867 | resl++; |
diff --git a/src/lib/util/test_crypto_blind.c b/src/lib/util/test_crypto_blind.c index d7efd79ea..1b256fca3 100644 --- a/src/lib/util/test_crypto_blind.c +++ b/src/lib/util/test_crypto_blind.c | |||
@@ -77,6 +77,7 @@ main (int argc, | |||
77 | sig, | 77 | sig, |
78 | "hello", | 78 | "hello", |
79 | 5)); | 79 | 5)); |
80 | GNUNET_CRYPTO_blinding_input_values_decref (biv); | ||
80 | GNUNET_CRYPTO_blinded_sig_decref (bsig); | 81 | GNUNET_CRYPTO_blinded_sig_decref (bsig); |
81 | GNUNET_CRYPTO_unblinded_sig_decref (sig); | 82 | GNUNET_CRYPTO_unblinded_sig_decref (sig); |
82 | GNUNET_CRYPTO_blinded_message_decref (bm); | 83 | GNUNET_CRYPTO_blinded_message_decref (bm); |
diff --git a/src/plugin/reclaim/plugin_gnsrecord_reclaim.c b/src/plugin/reclaim/plugin_gnsrecord_reclaim.c index ce6fe483d..baf2fc37a 100644 --- a/src/plugin/reclaim/plugin_gnsrecord_reclaim.c +++ b/src/plugin/reclaim/plugin_gnsrecord_reclaim.c | |||
@@ -44,12 +44,12 @@ value_to_string (void *cls, uint32_t type, const void *data, size_t data_size) | |||
44 | { | 44 | { |
45 | switch (type) | 45 | switch (type) |
46 | { | 46 | { |
47 | case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET: | ||
47 | case GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT: | 48 | case GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT: |
48 | case GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT: | 49 | case GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT: |
49 | return GNUNET_strndup (data, data_size); | 50 | return GNUNET_strndup (data, data_size); |
50 | case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE: | 51 | case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE: |
51 | case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF: | 52 | case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF: |
52 | case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET: | ||
53 | case GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL: | 53 | case GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL: |
54 | case GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION: | 54 | case GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION: |
55 | return GNUNET_STRINGS_data_to_string_alloc (data, data_size); | 55 | return GNUNET_STRINGS_data_to_string_alloc (data, data_size); |
@@ -79,6 +79,7 @@ string_to_value (void *cls, uint32_t type, const char *s, void **data, | |||
79 | return GNUNET_SYSERR; | 79 | return GNUNET_SYSERR; |
80 | switch (type) | 80 | switch (type) |
81 | { | 81 | { |
82 | case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET: | ||
82 | case GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT: | 83 | case GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT: |
83 | case GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT: | 84 | case GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT: |
84 | *data = GNUNET_strdup (s); | 85 | *data = GNUNET_strdup (s); |
@@ -86,7 +87,6 @@ string_to_value (void *cls, uint32_t type, const char *s, void **data, | |||
86 | return GNUNET_OK; | 87 | return GNUNET_OK; |
87 | case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE: | 88 | case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE: |
88 | case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF: | 89 | case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF: |
89 | case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET: | ||
90 | case GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL: | 90 | case GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL: |
91 | case GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION: | 91 | case GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION: |
92 | return GNUNET_STRINGS_string_to_data (s, strlen (s), *data, *data_size); | 92 | return GNUNET_STRINGS_string_to_data (s, strlen (s), *data, *data_size); |
diff --git a/src/service/Makefile.am b/src/service/Makefile.am index 610971725..557f56b8a 100644 --- a/src/service/Makefile.am +++ b/src/service/Makefile.am | |||
@@ -1,9 +1,9 @@ | |||
1 | SUBDIRS = \ | 1 | SUBDIRS = \ |
2 | util \ | 2 | util \ |
3 | testbed \ | ||
3 | statistics \ | 4 | statistics \ |
4 | arm \ | 5 | arm \ |
5 | peerstore \ | 6 | peerstore \ |
6 | testing \ | ||
7 | nat \ | 7 | nat \ |
8 | nat-auto \ | 8 | nat-auto \ |
9 | transport \ | 9 | transport \ |
@@ -32,4 +32,3 @@ SUBDIRS = \ | |||
32 | reclaim \ | 32 | reclaim \ |
33 | messenger \ | 33 | messenger \ |
34 | rest | 34 | rest |
35 | |||
diff --git a/src/service/arm/Makefile.am b/src/service/arm/Makefile.am index 32addeef1..26c940688 100644 --- a/src/service/arm/Makefile.am +++ b/src/service/arm/Makefile.am | |||
@@ -13,10 +13,14 @@ if USE_COVERAGE | |||
13 | XLIB = -lgcov | 13 | XLIB = -lgcov |
14 | endif | 14 | endif |
15 | 15 | ||
16 | lib_LTLIBRARIES = libgnunetarm.la | 16 | lib_LTLIBRARIES = \ |
17 | libgnunetarm.la \ | ||
18 | libgnunettestingarm.la | ||
17 | 19 | ||
18 | libgnunetarm_la_SOURCES = \ | 20 | libgnunetarm_la_SOURCES = \ |
19 | arm_api.c arm_monitor_api.c arm.h | 21 | arm_api.c \ |
22 | arm_monitor_api.c \ | ||
23 | arm.h | ||
20 | libgnunetarm_la_LIBADD = \ | 24 | libgnunetarm_la_LIBADD = \ |
21 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | 25 | $(top_builddir)/src/lib/util/libgnunetutil.la \ |
22 | $(GN_LIBINTL) $(XLIB) | 26 | $(GN_LIBINTL) $(XLIB) |
@@ -24,6 +28,21 @@ libgnunetarm_la_LDFLAGS = \ | |||
24 | $(GN_LIB_LDFLAGS) \ | 28 | $(GN_LIB_LDFLAGS) \ |
25 | -version-info 2:0:0 | 29 | -version-info 2:0:0 |
26 | 30 | ||
31 | libgnunettestingarm_la_SOURCES = \ | ||
32 | testing_arm_cmd_start_peer.c \ | ||
33 | testing_arm_cmd_stop_peer.c \ | ||
34 | testing_arm_traits.c | ||
35 | libgnunettestingarm_la_LIBADD = \ | ||
36 | libgnunetarm.la \ | ||
37 | $(top_builddir)/src/service/testbed/libgnunettestingtestbed.la \ | ||
38 | $(top_builddir)/src/service/testbed/libgnunettestbed.la \ | ||
39 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ | ||
40 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
41 | $(GN_LIBINTL) $(XLIB) | ||
42 | libgnunettestingarm_la_LDFLAGS = \ | ||
43 | $(GN_LIB_LDFLAGS) \ | ||
44 | -version-info 0:0:0 | ||
45 | |||
27 | 46 | ||
28 | noinst_PROGRAMS = \ | 47 | noinst_PROGRAMS = \ |
29 | mockup-service | 48 | mockup-service |
diff --git a/src/service/arm/testing_arm_cmd_start_peer.c b/src/service/arm/testing_arm_cmd_start_peer.c new file mode 100644 index 000000000..73d7ca4e7 --- /dev/null +++ b/src/service/arm/testing_arm_cmd_start_peer.c | |||
@@ -0,0 +1,293 @@ | |||
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_api_cmd_start_peer.c | ||
23 | * @brief cmd to start a peer. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_lib.h" | ||
29 | #include "gnunet_testbed_lib.h" | ||
30 | #include "gnunet_testing_testbed_lib.h" | ||
31 | #include "gnunet_testing_arm_lib.h" | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Handle for a peer controlled via ARM. | ||
36 | */ | ||
37 | struct GNUNET_TESTING_StartPeerState | ||
38 | { | ||
39 | |||
40 | const char *system_label; | ||
41 | |||
42 | const char *cfgname; | ||
43 | |||
44 | /** | ||
45 | * Our interpreter. | ||
46 | */ | ||
47 | struct GNUNET_TESTING_Interpreter *is; | ||
48 | |||
49 | /** | ||
50 | * Asynchronous start context. | ||
51 | */ | ||
52 | struct GNUNET_TESTING_AsyncContext ac; | ||
53 | |||
54 | /** | ||
55 | * The TESTBED system associated with this peer | ||
56 | */ | ||
57 | struct GNUNET_TESTBED_System *system; | ||
58 | |||
59 | /** | ||
60 | * The handle to the peer's ARM service | ||
61 | */ | ||
62 | struct GNUNET_ARM_Handle *ah; | ||
63 | |||
64 | /** | ||
65 | * Handle to the ARM process information. | ||
66 | */ | ||
67 | struct GNUNET_OS_Process *arm; | ||
68 | |||
69 | /** | ||
70 | * The config of the peer | ||
71 | */ | ||
72 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
73 | |||
74 | }; | ||
75 | |||
76 | |||
77 | /** | ||
78 | * Function called whenever we connect to or disconnect from ARM. | ||
79 | * | ||
80 | * @param cls closure | ||
81 | * @param connected #GNUNET_YES if connected, #GNUNET_NO if disconnected, | ||
82 | * #GNUNET_SYSERR if there was an error. | ||
83 | */ | ||
84 | static void | ||
85 | conn_status ( | ||
86 | void *cls, | ||
87 | enum GNUNET_GenericReturnValue connected) | ||
88 | { | ||
89 | struct GNUNET_TESTING_StartPeerState *sps = cls; | ||
90 | |||
91 | if (GNUNET_OK != connected) | ||
92 | { | ||
93 | GNUNET_break (0); | ||
94 | GNUNET_TESTING_async_fail (&sps->ac); | ||
95 | return; | ||
96 | } | ||
97 | GNUNET_TESTING_async_finish (&sps->ac); | ||
98 | } | ||
99 | |||
100 | |||
101 | /** | ||
102 | * The run method of this cmd will start all services of a peer to test the transport service. | ||
103 | * | ||
104 | */ | ||
105 | static void | ||
106 | start_peer_run (void *cls, | ||
107 | struct GNUNET_TESTING_Interpreter *is) | ||
108 | { | ||
109 | struct GNUNET_TESTING_StartPeerState *sps = cls; | ||
110 | const struct GNUNET_TESTING_Command *system_cmd; | ||
111 | |||
112 | sps->is = is; | ||
113 | if (GNUNET_NO == | ||
114 | GNUNET_DISK_file_test (sps->cfgname)) | ||
115 | { | ||
116 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
117 | "File not found: `%s'\n", | ||
118 | sps->cfgname); | ||
119 | GNUNET_TESTING_FAIL (is); | ||
120 | } | ||
121 | system_cmd | ||
122 | = GNUNET_TESTING_interpreter_lookup_command (is, | ||
123 | sps->system_label); | ||
124 | if (NULL == system_cmd) | ||
125 | GNUNET_TESTING_FAIL (is); | ||
126 | if (GNUNET_OK != | ||
127 | GNUNET_TESTING_TESTBED_get_trait_test_system ( | ||
128 | system_cmd, | ||
129 | &sps->system)) | ||
130 | GNUNET_TESTING_FAIL (is); | ||
131 | sps->cfg = GNUNET_CONFIGURATION_create (); | ||
132 | if (GNUNET_OK != | ||
133 | GNUNET_CONFIGURATION_load (sps->cfg, | ||
134 | sps->cfgname)) | ||
135 | GNUNET_TESTING_FAIL (is); | ||
136 | if (GNUNET_SYSERR == | ||
137 | GNUNET_TESTBED_configuration_create (sps->system, | ||
138 | sps->cfg, | ||
139 | NULL, | ||
140 | NULL)) | ||
141 | GNUNET_TESTING_FAIL (is); | ||
142 | { | ||
143 | char *config_filename; | ||
144 | char *libexec_binary; | ||
145 | char *main_binary; | ||
146 | char *args; | ||
147 | char *prefix; | ||
148 | |||
149 | GNUNET_assert ( | ||
150 | GNUNET_OK == | ||
151 | GNUNET_CONFIGURATION_get_value_filename ( | ||
152 | sps->cfg, | ||
153 | "PATHS", | ||
154 | "DEFAULTCONFIG", | ||
155 | &config_filename)); | ||
156 | if (GNUNET_OK != | ||
157 | GNUNET_CONFIGURATION_write (sps->cfg, | ||
158 | config_filename)) | ||
159 | { | ||
160 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
161 | "Failed to write configuration file `%s': %s\n", | ||
162 | config_filename, | ||
163 | strerror (errno)); | ||
164 | GNUNET_free (config_filename); | ||
165 | GNUNET_TESTING_FAIL (is); | ||
166 | } | ||
167 | |||
168 | libexec_binary | ||
169 | = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm"); | ||
170 | |||
171 | if (GNUNET_SYSERR == | ||
172 | GNUNET_CONFIGURATION_get_value_string (sps->cfg, | ||
173 | "arm", | ||
174 | "PREFIX", | ||
175 | &prefix)) | ||
176 | { | ||
177 | /* No prefix */ | ||
178 | main_binary = libexec_binary; | ||
179 | args = GNUNET_strdup (""); | ||
180 | } | ||
181 | else | ||
182 | { | ||
183 | main_binary = prefix; | ||
184 | args = libexec_binary; | ||
185 | } | ||
186 | sps->arm | ||
187 | = GNUNET_OS_start_process_s (GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | ||
188 | NULL, | ||
189 | main_binary, | ||
190 | args, | ||
191 | "-c", | ||
192 | config_filename, | ||
193 | NULL); | ||
194 | if (NULL == sps->arm) | ||
195 | { | ||
196 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
197 | _ ("Failed to start `%s': %s\n"), | ||
198 | main_binary, | ||
199 | strerror (errno)); | ||
200 | GNUNET_TESTING_FAIL (is); | ||
201 | } | ||
202 | GNUNET_free (config_filename); | ||
203 | GNUNET_free (main_binary); | ||
204 | GNUNET_free (args); | ||
205 | } | ||
206 | |||
207 | sps->ah = GNUNET_ARM_connect (sps->cfg, | ||
208 | &conn_status, | ||
209 | sps); | ||
210 | if (NULL == sps->ah) | ||
211 | GNUNET_TESTING_FAIL (is); | ||
212 | } | ||
213 | |||
214 | |||
215 | /** | ||
216 | * The cleanup function of this cmd frees resources the cmd allocated. | ||
217 | * | ||
218 | */ | ||
219 | static void | ||
220 | start_peer_cleanup (void *cls) | ||
221 | { | ||
222 | struct GNUNET_TESTING_StartPeerState *sps = cls; | ||
223 | |||
224 | if (NULL != sps->ah) | ||
225 | { | ||
226 | GNUNET_ARM_disconnect (sps->ah); | ||
227 | sps->ah = NULL; | ||
228 | } | ||
229 | if (NULL != sps->arm) | ||
230 | { | ||
231 | GNUNET_break (0 == | ||
232 | GNUNET_OS_process_kill (sps->arm, | ||
233 | SIGTERM)); | ||
234 | GNUNET_break (GNUNET_OK == | ||
235 | GNUNET_OS_process_wait (sps->arm)); | ||
236 | GNUNET_OS_process_destroy (sps->arm); | ||
237 | sps->ah = NULL; | ||
238 | } | ||
239 | |||
240 | if (NULL != sps->cfg) | ||
241 | { | ||
242 | GNUNET_CONFIGURATION_destroy (sps->cfg); | ||
243 | sps->cfg = NULL; | ||
244 | } | ||
245 | GNUNET_free (sps); | ||
246 | } | ||
247 | |||
248 | |||
249 | /** | ||
250 | * This function prepares an array with traits. | ||
251 | * | ||
252 | */ | ||
253 | static enum GNUNET_GenericReturnValue | ||
254 | start_peer_traits (void *cls, | ||
255 | const void **ret, | ||
256 | const char *trait, | ||
257 | unsigned int index) | ||
258 | { | ||
259 | struct GNUNET_TESTING_StartPeerState *sps = cls; | ||
260 | struct GNUNET_TESTING_Trait traits[] = { | ||
261 | GNUNET_TESTING_make_trait_process ( | ||
262 | &sps->arm), | ||
263 | // FIXME: expose sps->cfg as trait... | ||
264 | GNUNET_TESTING_ARM_make_trait_arm_handle ( | ||
265 | sps->ah), | ||
266 | GNUNET_TESTING_trait_end () | ||
267 | }; | ||
268 | |||
269 | return GNUNET_TESTING_get_trait (traits, | ||
270 | ret, | ||
271 | trait, | ||
272 | index); | ||
273 | } | ||
274 | |||
275 | |||
276 | struct GNUNET_TESTING_Command | ||
277 | GNUNET_TESTING_ARM_cmd_start_peer ( | ||
278 | const char *label, | ||
279 | const char *system_label, | ||
280 | const char *cfgname) | ||
281 | { | ||
282 | struct GNUNET_TESTING_StartPeerState *sps; | ||
283 | |||
284 | sps = GNUNET_new (struct GNUNET_TESTING_StartPeerState); | ||
285 | sps->system_label = GNUNET_strdup (system_label); | ||
286 | sps->cfgname = cfgname; | ||
287 | return GNUNET_TESTING_command_new_ac (sps, | ||
288 | label, | ||
289 | &start_peer_run, | ||
290 | &start_peer_cleanup, | ||
291 | &start_peer_traits, | ||
292 | &sps->ac); | ||
293 | } | ||
diff --git a/src/service/transport/testing_api_cmd_stop_peer.c b/src/service/arm/testing_arm_cmd_stop_peer.c index ce8d824f5..f0394dd5e 100644 --- a/src/service/transport/testing_api_cmd_stop_peer.c +++ b/src/service/arm/testing_arm_cmd_stop_peer.c | |||
@@ -25,14 +25,9 @@ | |||
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_testing_ng_lib.h" | 28 | #include "gnunet_testing_lib.h" |
29 | #include "gnunet_transport_testing_ng_lib.h" | 29 | #include "gnunet_testbed_lib.h" |
30 | 30 | #include "gnunet_testing_transport_lib.h" | |
31 | /** | ||
32 | * Generic logging shortcut | ||
33 | */ | ||
34 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | ||
35 | |||
36 | 31 | ||
37 | /** | 32 | /** |
38 | * Struct to hold information for callbacks. | 33 | * Struct to hold information for callbacks. |
@@ -40,7 +35,9 @@ | |||
40 | */ | 35 | */ |
41 | struct StopPeerState | 36 | struct StopPeerState |
42 | { | 37 | { |
43 | // Label of the cmd to start the peer. | 38 | /** |
39 | * Label of the cmd to start the peer. | ||
40 | */ | ||
44 | const char *start_label; | 41 | const char *start_label; |
45 | }; | 42 | }; |
46 | 43 | ||
@@ -54,28 +51,28 @@ stop_peer_run (void *cls, | |||
54 | struct GNUNET_TESTING_Interpreter *is) | 51 | struct GNUNET_TESTING_Interpreter *is) |
55 | { | 52 | { |
56 | struct StopPeerState *stop_ps = cls; | 53 | struct StopPeerState *stop_ps = cls; |
57 | const struct GNUNET_TESTING_StartPeerState *sps; | ||
58 | const struct GNUNET_TESTING_Command *start_cmd; | 54 | const struct GNUNET_TESTING_Command *start_cmd; |
59 | 55 | struct GNUNET_OS_Process **proc; | |
60 | start_cmd = GNUNET_TESTING_interpreter_lookup_command (is, | 56 | |
61 | stop_ps->start_label); | 57 | start_cmd |
62 | GNUNET_TRANSPORT_TESTING_get_trait_state (start_cmd, | 58 | = GNUNET_TESTING_interpreter_lookup_command (is, |
63 | &sps); | 59 | stop_ps->start_label); |
64 | 60 | if (NULL == start_cmd) | |
65 | if (NULL != sps->peer) | 61 | GNUNET_TESTING_FAIL (is); |
66 | { | 62 | /* FIMXE: maybe use the *ARM* handle to stop the peer |
67 | if (GNUNET_OK != | 63 | and actually _wait_ for it to be down (making this |
68 | GNUNET_TESTING_peer_stop (sps->peer)) | 64 | an asynchronous operation...) instead of just |
69 | { | 65 | killing it without waiting for it to be done? |
70 | LOG (GNUNET_ERROR_TYPE_ERROR, | 66 | Or use a child wait handle and wait for |
71 | "Testing lib failed to stop peer %u (`%s')\n", | 67 | completion, and then NULL *proc in start? */ |
72 | sps->no, | 68 | if (GNUNET_OK != |
73 | GNUNET_i2s (&sps->id)); | 69 | GNUNET_TESTING_get_trait_process (start_cmd, |
74 | } | 70 | &proc)) |
75 | GNUNET_TESTING_peer_destroy (sps->peer); | 71 | GNUNET_TESTING_FAIL (is); |
76 | } | 72 | if (0 != |
77 | if (NULL != sps->rh_task) | 73 | GNUNET_OS_process_kill (*proc, |
78 | GNUNET_SCHEDULER_cancel (sps->rh_task); | 74 | SIGTERM)) |
75 | GNUNET_TESTING_FAIL (is); | ||
79 | } | 76 | } |
80 | 77 | ||
81 | 78 | ||
@@ -102,20 +99,21 @@ stop_peer_traits (void *cls, | |||
102 | const char *trait, | 99 | const char *trait, |
103 | unsigned int index) | 100 | unsigned int index) |
104 | { | 101 | { |
105 | return GNUNET_OK; | 102 | struct GNUNET_TESTING_Trait traits[] = { |
103 | GNUNET_TESTING_trait_end () | ||
104 | }; | ||
105 | |||
106 | (void) cls; | ||
107 | return GNUNET_TESTING_get_trait (traits, | ||
108 | ret, | ||
109 | trait, | ||
110 | index); | ||
106 | } | 111 | } |
107 | 112 | ||
108 | 113 | ||
109 | /** | ||
110 | * Create command. | ||
111 | * | ||
112 | * @param label name for command. | ||
113 | * @param start_label Label of the cmd to start the peer. | ||
114 | * @return command. | ||
115 | */ | ||
116 | struct GNUNET_TESTING_Command | 114 | struct GNUNET_TESTING_Command |
117 | GNUNET_TESTING_cmd_stop_peer (const char *label, | 115 | GNUNET_TESTING_cmd_stop_peer (const char *label, |
118 | const char *start_label) | 116 | const char *start_label) |
119 | { | 117 | { |
120 | struct StopPeerState *sps; | 118 | struct StopPeerState *sps; |
121 | 119 | ||
@@ -125,6 +123,5 @@ GNUNET_TESTING_cmd_stop_peer (const char *label, | |||
125 | label, | 123 | label, |
126 | &stop_peer_run, | 124 | &stop_peer_run, |
127 | &stop_peer_cleanup, | 125 | &stop_peer_cleanup, |
128 | &stop_peer_traits, | 126 | &stop_peer_traits); |
129 | NULL); | ||
130 | } | 127 | } |
diff --git a/src/service/cadet/gnunet-service-cadet_dht.c b/src/service/cadet/gnunet-service-cadet_dht.c index 28b5448fd..dcd1efaa2 100644 --- a/src/service/cadet/gnunet-service-cadet_dht.c +++ b/src/service/cadet/gnunet-service-cadet_dht.c | |||
@@ -217,6 +217,7 @@ announce_id (void *cls) | |||
217 | expiration, /* Data expiration */ | 217 | expiration, /* Data expiration */ |
218 | NULL, /* Continuation */ | 218 | NULL, /* Continuation */ |
219 | NULL); /* Continuation closure */ | 219 | NULL); /* Continuation closure */ |
220 | GNUNET_free (block); | ||
220 | } | 221 | } |
221 | 222 | ||
222 | 223 | ||
diff --git a/src/service/core/Makefile.am b/src/service/core/Makefile.am index 220da838f..95f22c82c 100644 --- a/src/service/core/Makefile.am +++ b/src/service/core/Makefile.am | |||
@@ -44,7 +44,7 @@ libgnunet_test_core_plugin_cmd_just_run_la_LIBADD = \ | |||
44 | $(top_builddir)/src/lib/hello/libgnunethello.la \ | 44 | $(top_builddir)/src/lib/hello/libgnunethello.la \ |
45 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ | 45 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ |
46 | $(top_builddir)/src/service/transport/libgnunettransporttesting2.la \ | 46 | $(top_builddir)/src/service/transport/libgnunettransporttesting2.la \ |
47 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 47 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
48 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ | 48 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ |
49 | $(top_builddir)/src/service/arm/libgnunetarm.la \ | 49 | $(top_builddir)/src/service/arm/libgnunetarm.la \ |
50 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | 50 | $(top_builddir)/src/lib/util/libgnunetutil.la \ |
@@ -53,9 +53,9 @@ libgnunet_test_core_plugin_cmd_just_run_la_LDFLAGS = \ | |||
53 | $(GN_PLUGIN_LDFLAGS) | 53 | $(GN_PLUGIN_LDFLAGS) |
54 | 54 | ||
55 | libgnunetcoretesting_la_SOURCES = \ | 55 | libgnunetcoretesting_la_SOURCES = \ |
56 | core_api_cmd_connecting_peers.c | 56 | core_api_cmd_connecting_peers.c |
57 | libgnunetcoretesting_la_LIBADD = \ | 57 | libgnunetcoretesting_la_LIBADD = \ |
58 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 58 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
59 | $(top_builddir)/src/service/arm/libgnunetarm.la \ | 59 | $(top_builddir)/src/service/arm/libgnunetarm.la \ |
60 | $(top_builddir)/src/service/transport/libgnunettransportapplication.la \ | 60 | $(top_builddir)/src/service/transport/libgnunettransportapplication.la \ |
61 | $(top_builddir)/src/service/transport/libgnunettransporttesting2.la \ | 61 | $(top_builddir)/src/service/transport/libgnunettransporttesting2.la \ |
@@ -106,13 +106,13 @@ test_core_api_send_to_self_SOURCES = \ | |||
106 | test_core_api_send_to_self.c | 106 | test_core_api_send_to_self.c |
107 | test_core_api_send_to_self_LDADD = \ | 107 | test_core_api_send_to_self_LDADD = \ |
108 | libgnunetcore.la \ | 108 | libgnunetcore.la \ |
109 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 109 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
110 | $(top_builddir)/src/lib/util/libgnunetutil.la | 110 | $(top_builddir)/src/lib/util/libgnunetutil.la |
111 | 111 | ||
112 | test_core_api_start_only_SOURCES = \ | 112 | test_core_api_start_only_SOURCES = \ |
113 | test_core_api_start_only.c | 113 | test_core_api_start_only.c |
114 | test_core_api_start_only_LDADD = \ | 114 | test_core_api_start_only_LDADD = \ |
115 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 115 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
116 | libgnunetcore.la \ | 116 | libgnunetcore.la \ |
117 | $(top_builddir)/src/lib/util/libgnunetutil.la | 117 | $(top_builddir)/src/lib/util/libgnunetutil.la |
118 | 118 | ||
diff --git a/src/service/core/core_api_cmd_connecting_peers.c b/src/service/core/core_api_cmd_connecting_peers.c index a6aa818fa..0d177a8e9 100644 --- a/src/service/core/core_api_cmd_connecting_peers.c +++ b/src/service/core/core_api_cmd_connecting_peers.c | |||
@@ -64,9 +64,9 @@ connect_peers_run (void *cls, | |||
64 | peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (is, | 64 | peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (is, |
65 | cps->start_peer_label); | 65 | cps->start_peer_label); |
66 | GNUNET_TRANSPORT_TESTING_get_trait_broadcast (peer1_cmd, | 66 | GNUNET_TRANSPORT_TESTING_get_trait_broadcast (peer1_cmd, |
67 | &broadcast); | 67 | &broadcast); |
68 | GNUNET_TRANSPORT_TESTING_get_trait_state (peer1_cmd, | 68 | GNUNET_TRANSPORT_TESTING_get_trait_state (peer1_cmd, |
69 | &sps); | 69 | &sps); |
70 | 70 | ||
71 | system_cmd = GNUNET_TESTING_interpreter_lookup_command (is, | 71 | system_cmd = GNUNET_TESTING_interpreter_lookup_command (is, |
72 | cps->create_label); | 72 | cps->create_label); |
@@ -78,7 +78,7 @@ connect_peers_run (void *cls, | |||
78 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 78 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
79 | "cps->num: %u \n", | 79 | "cps->num: %u \n", |
80 | cps->num); | 80 | cps->num); |
81 | 81 | ||
82 | 82 | ||
83 | cps->ah = GNUNET_TRANSPORT_application_init (sps->cfg); | 83 | cps->ah = GNUNET_TRANSPORT_application_init (sps->cfg); |
84 | if (NULL == cps->ah) | 84 | if (NULL == cps->ah) |
@@ -224,7 +224,7 @@ GNUNET_CORE_cmd_connect_peers ( | |||
224 | struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map = | 224 | struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map = |
225 | GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO); | 225 | GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO); |
226 | unsigned int i; | 226 | unsigned int i; |
227 | 227 | ||
228 | node_additional_connects = GNUNET_TESTING_get_additional_connects (num, | 228 | node_additional_connects = GNUNET_TESTING_get_additional_connects (num, |
229 | topology); | 229 | topology); |
230 | 230 | ||
@@ -255,24 +255,23 @@ GNUNET_CORE_cmd_connect_peers ( | |||
255 | handlers, | 255 | handlers, |
256 | i * sizeof(struct GNUNET_MQ_MessageHandler)); | 256 | i * sizeof(struct GNUNET_MQ_MessageHandler)); |
257 | } | 257 | } |
258 | 258 | // FIXME: wrap with cmd_make_unblocking! | |
259 | if (GNUNET_YES == wait_for_connect) | 259 | if (GNUNET_YES == wait_for_connect) |
260 | return GNUNET_TESTING_command_new (cps, | 260 | return GNUNET_TESTING_command_new_ac (cps, |
261 | label, | 261 | label, |
262 | &connect_peers_run, | 262 | &connect_peers_run, |
263 | &connect_peers_cleanup, | 263 | &connect_peers_cleanup, |
264 | &connect_peers_traits, | 264 | &connect_peers_traits, |
265 | &cps->ac); | 265 | &cps->ac); |
266 | else | 266 | else |
267 | return GNUNET_TESTING_command_new (cps, | 267 | return GNUNET_TESTING_command_new (cps, |
268 | label, | 268 | label, |
269 | &connect_peers_run, | 269 | &connect_peers_run, |
270 | &connect_peers_cleanup, | 270 | &connect_peers_cleanup, |
271 | &connect_peers_traits, | 271 | &connect_peers_traits); |
272 | NULL); | ||
273 | } | 272 | } |
274 | 273 | ||
275 | 274 | ||
276 | // FIXME: likely not ideally placed here, move to its own file | 275 | // FIXME: likely not ideally placed here, move to its own file |
277 | GNUNET_CORE_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, GNUNET_CORE_TESTING) | 276 | GNUNET_CORE_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, |
278 | 277 | GNUNET_CORE_TESTING) | |
diff --git a/src/service/dht/gnunet-service-dht.c b/src/service/dht/gnunet-service-dht.c index ab9e179bc..4579bfc2b 100644 --- a/src/service/dht/gnunet-service-dht.c +++ b/src/service/dht/gnunet-service-dht.c | |||
@@ -79,11 +79,6 @@ struct GDS_Underlay | |||
79 | * Name of the underlay (i.e. "gnunet" or "ip"). | 79 | * Name of the underlay (i.e. "gnunet" or "ip"). |
80 | */ | 80 | */ |
81 | char *name; | 81 | char *name; |
82 | |||
83 | /** | ||
84 | * Name of the library providing the underlay. | ||
85 | */ | ||
86 | char *libname; | ||
87 | }; | 82 | }; |
88 | 83 | ||
89 | 84 | ||
@@ -383,8 +378,6 @@ shutdown_task (void *cls) | |||
383 | 378 | ||
384 | while (NULL != (u = u_head)) | 379 | while (NULL != (u = u_head)) |
385 | { | 380 | { |
386 | GNUNET_PLUGIN_unload (u->libname, | ||
387 | u->dhtu); | ||
388 | GNUNET_CONTAINER_DLL_remove (u_head, | 381 | GNUNET_CONTAINER_DLL_remove (u_head, |
389 | u_tail, | 382 | u_tail, |
390 | u); | 383 | u); |
diff --git a/src/service/dht/meson.build b/src/service/dht/meson.build index 8b4555687..45157243d 100644 --- a/src/service/dht/meson.build +++ b/src/service/dht/meson.build | |||
@@ -54,12 +54,6 @@ executable ('gnunet-service-dht', | |||
54 | install: true, | 54 | install: true, |
55 | install_dir: get_option('libdir')/'gnunet'/'libexec') | 55 | install_dir: get_option('libdir')/'gnunet'/'libexec') |
56 | 56 | ||
57 | configure_file(input : 'dhtu.conf', | ||
58 | output : 'dhtu.conf', | ||
59 | configuration : cdata, | ||
60 | install: true, | ||
61 | install_dir: pkgcfgdir) | ||
62 | |||
63 | libgnunettestingdhtu = library('gnunettestingdhtu', | 57 | libgnunettestingdhtu = library('gnunettestingdhtu', |
64 | ['testing_dhtu_cmd_send.c'], | 58 | ['testing_dhtu_cmd_send.c'], |
65 | soversion: '0', | 59 | soversion: '0', |
diff --git a/src/service/gns/gns_tld_api.c b/src/service/gns/gns_tld_api.c index 1ea87fd97..7a6864010 100644 --- a/src/service/gns/gns_tld_api.c +++ b/src/service/gns/gns_tld_api.c | |||
@@ -24,6 +24,7 @@ | |||
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_common.h" | ||
27 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_constants.h" | 29 | #include "gnunet_constants.h" |
29 | #include "gnunet_arm_service.h" | 30 | #include "gnunet_arm_service.h" |
@@ -223,19 +224,18 @@ identity_zone_cb (void *cls, | |||
223 | } | 224 | } |
224 | 225 | ||
225 | 226 | ||
226 | /** | 227 | enum GNUNET_GenericReturnValue |
227 | * Perform an asynchronous lookup operation on the GNS, | 228 | GNUNET_GNS_parse_ztld (const char *name, |
228 | * determining the zone using the TLD of the given name | 229 | struct GNUNET_CRYPTO_PublicKey *ztld_key) |
229 | * and the current configuration to resolve TLDs to zones. | 230 | { |
230 | * | 231 | const char *tld; |
231 | * @param handle handle to the GNS service | 232 | |
232 | * @param name the name to look up, including TLD (in UTF-8 encoding) | 233 | /* start with trivial case: TLD is zkey */ |
233 | * @param type the record type to look up | 234 | tld = get_tld (name); |
234 | * @param options local options for the lookup | 235 | return GNUNET_CRYPTO_public_key_from_string (tld, ztld_key); |
235 | * @param proc processor to call on result | 236 | } |
236 | * @param proc_cls closure for @a proc | 237 | |
237 | * @return handle to the get request, NULL on error (e.g. bad configuration) | 238 | |
238 | */ | ||
239 | struct GNUNET_GNS_LookupWithTldRequest * | 239 | struct GNUNET_GNS_LookupWithTldRequest * |
240 | GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle, | 240 | GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle, |
241 | const char *name, | 241 | const char *name, |
@@ -258,10 +258,10 @@ GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle, | |||
258 | ltr->lookup_proc = proc; | 258 | ltr->lookup_proc = proc; |
259 | ltr->lookup_proc_cls = proc_cls; | 259 | ltr->lookup_proc_cls = proc_cls; |
260 | /* start with trivial case: TLD is zkey */ | 260 | /* start with trivial case: TLD is zkey */ |
261 | tld = get_tld (ltr->name); | ||
262 | if (GNUNET_OK == | 261 | if (GNUNET_OK == |
263 | GNUNET_CRYPTO_public_key_from_string (tld, &pkey)) | 262 | GNUNET_GNS_parse_ztld (ltr->name, &pkey)) |
264 | { | 263 | { |
264 | tld = get_tld (ltr->name); | ||
265 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 265 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
266 | "`%s' seems to be a valid zone key\n", tld); | 266 | "`%s' seems to be a valid zone key\n", tld); |
267 | eat_tld (ltr->name, tld); | 267 | eat_tld (ltr->name, tld); |
@@ -283,7 +283,7 @@ GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle, | |||
283 | { | 283 | { |
284 | if (GNUNET_OK != | 284 | if (GNUNET_OK != |
285 | GNUNET_CRYPTO_public_key_from_string (zonestr, | 285 | GNUNET_CRYPTO_public_key_from_string (zonestr, |
286 | &pkey)) | 286 | &pkey)) |
287 | { | 287 | { |
288 | GNUNET_log_config_invalid ( | 288 | GNUNET_log_config_invalid ( |
289 | GNUNET_ERROR_TYPE_ERROR, | 289 | GNUNET_ERROR_TYPE_ERROR, |
diff --git a/src/service/hostlist/gnunet-daemon-hostlist_server.c b/src/service/hostlist/gnunet-daemon-hostlist_server.c index f243deb00..7cfeaec63 100644 --- a/src/service/hostlist/gnunet-daemon-hostlist_server.c +++ b/src/service/hostlist/gnunet-daemon-hostlist_server.c | |||
@@ -25,8 +25,8 @@ | |||
25 | * @author David Barksdale | 25 | * @author David Barksdale |
26 | * @brief application to provide an integrated hostlist HTTP server | 26 | * @brief application to provide an integrated hostlist HTTP server |
27 | */ | 27 | */ |
28 | #include "gnunet_common.h" | ||
29 | #include "platform.h" | 28 | #include "platform.h" |
29 | #include "gnunet_common.h" | ||
30 | #include <microhttpd.h> | 30 | #include <microhttpd.h> |
31 | #include "gnunet-daemon-hostlist_server.h" | 31 | #include "gnunet-daemon-hostlist_server.h" |
32 | #include "gnunet_hello_uri_lib.h" | 32 | #include "gnunet_hello_uri_lib.h" |
diff --git a/src/service/meson.build b/src/service/meson.build index ff874a1ec..2d749bdec 100644 --- a/src/service/meson.build +++ b/src/service/meson.build | |||
@@ -7,7 +7,6 @@ endif | |||
7 | subdir('util') | 7 | subdir('util') |
8 | subdir('statistics') | 8 | subdir('statistics') |
9 | subdir('arm') | 9 | subdir('arm') |
10 | subdir('testing') | ||
11 | subdir('peerstore') | 10 | subdir('peerstore') |
12 | subdir('nat') | 11 | subdir('nat') |
13 | subdir('nat-auto') | 12 | subdir('nat-auto') |
diff --git a/src/service/messenger/Makefile.am b/src/service/messenger/Makefile.am index 93dcf9a78..876b19985 100644 --- a/src/service/messenger/Makefile.am +++ b/src/service/messenger/Makefile.am | |||
@@ -62,7 +62,7 @@ libgnunetmessengertesting_la_SOURCES = \ | |||
62 | messenger-testing.c messenger-testing.h | 62 | messenger-testing.c messenger-testing.h |
63 | libgnunetmessengertesting_la_LIBADD = \ | 63 | libgnunetmessengertesting_la_LIBADD = \ |
64 | libgnunetmessenger.la \ | 64 | libgnunetmessenger.la \ |
65 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 65 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
66 | $(top_builddir)/src/service/cadet/libgnunetcadet.la \ | 66 | $(top_builddir)/src/service/cadet/libgnunetcadet.la \ |
67 | $(top_builddir)/src/service/transport/libgnunettransporttesting2.la \ | 67 | $(top_builddir)/src/service/transport/libgnunettransporttesting2.la \ |
68 | $(top_builddir)/src/service/transport/libgnunettransportapplication.la \ | 68 | $(top_builddir)/src/service/transport/libgnunettransportapplication.la \ |
@@ -90,7 +90,7 @@ libgnunet_test_messenger_plugin_cmd_simple_join_la_LIBADD = \ | |||
90 | $(top_builddir)/src/service/transport/libgnunettransporttesting2.la \ | 90 | $(top_builddir)/src/service/transport/libgnunettransporttesting2.la \ |
91 | $(top_builddir)/src/service/transport/libgnunettransportapplication.la \ | 91 | $(top_builddir)/src/service/transport/libgnunettransportapplication.la \ |
92 | $(top_builddir)/src/service/transport/libgnunettransportcore.la \ | 92 | $(top_builddir)/src/service/transport/libgnunettransportcore.la \ |
93 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 93 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
94 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ | 94 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ |
95 | $(top_builddir)/src/service/identity/libgnunetidentity.la \ | 95 | $(top_builddir)/src/service/identity/libgnunetidentity.la \ |
96 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ | 96 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ |
@@ -147,14 +147,14 @@ test_messenger_api_SOURCES = \ | |||
147 | test_messenger.c | 147 | test_messenger.c |
148 | test_messenger_api_LDADD = \ | 148 | test_messenger_api_LDADD = \ |
149 | libgnunetmessenger.la \ | 149 | libgnunetmessenger.la \ |
150 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 150 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
151 | $(top_builddir)/src/lib/util/libgnunetutil.la | 151 | $(top_builddir)/src/lib/util/libgnunetutil.la |
152 | 152 | ||
153 | test_messenger_anonymous_SOURCES = \ | 153 | test_messenger_anonymous_SOURCES = \ |
154 | test_messenger_anonymous.c | 154 | test_messenger_anonymous.c |
155 | test_messenger_anonymous_LDADD = \ | 155 | test_messenger_anonymous_LDADD = \ |
156 | libgnunetmessenger.la \ | 156 | libgnunetmessenger.la \ |
157 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 157 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
158 | $(top_builddir)/src/lib/util/libgnunetutil.la | 158 | $(top_builddir)/src/lib/util/libgnunetutil.la |
159 | 159 | ||
160 | EXTRA_DIST = \ | 160 | EXTRA_DIST = \ |
diff --git a/src/service/messenger/gnunet-service-messenger.c b/src/service/messenger/gnunet-service-messenger.c index e97ab0d35..06f9384aa 100644 --- a/src/service/messenger/gnunet-service-messenger.c +++ b/src/service/messenger/gnunet-service-messenger.c | |||
@@ -287,16 +287,31 @@ check_send_message (void *cls, | |||
287 | 287 | ||
288 | if (msg_length < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN, | 288 | if (msg_length < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN, |
289 | GNUNET_YES)) | 289 | GNUNET_YES)) |
290 | { | ||
291 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Too short message: %s\n", GNUNET_h2s ( | ||
292 | &(msg->key))); | ||
290 | return GNUNET_NO; | 293 | return GNUNET_NO; |
294 | } | ||
291 | 295 | ||
292 | if (GNUNET_YES != decode_message (&message, msg_length, msg_buffer, | 296 | if (GNUNET_YES != decode_message (&message, msg_length, msg_buffer, |
293 | GNUNET_YES, | 297 | GNUNET_YES, |
294 | NULL)) | 298 | NULL)) |
299 | { | ||
300 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Decoding message failed: %s\n", | ||
301 | GNUNET_h2s ( | ||
302 | &(msg->key))); | ||
295 | return GNUNET_NO; | 303 | return GNUNET_NO; |
304 | } | ||
296 | 305 | ||
297 | enum GNUNET_GenericReturnValue allowed; | 306 | enum GNUNET_GenericReturnValue allowed; |
298 | allowed = filter_message_sending (&message); | 307 | allowed = filter_message_sending (&message); |
299 | 308 | ||
309 | if (GNUNET_SYSERR == allowed) | ||
310 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
311 | "Sending message not allowed: %s to %s\n", | ||
312 | GNUNET_MESSENGER_name_of_kind (message.header.kind), | ||
313 | GNUNET_h2s (&(msg->key))); | ||
314 | |||
300 | cleanup_message (&message); | 315 | cleanup_message (&message); |
301 | return GNUNET_SYSERR != allowed? GNUNET_OK : GNUNET_NO; | 316 | return GNUNET_SYSERR != allowed? GNUNET_OK : GNUNET_NO; |
302 | } | 317 | } |
@@ -341,6 +356,10 @@ callback_found_message (void *cls, | |||
341 | 356 | ||
342 | if (! message) | 357 | if (! message) |
343 | { | 358 | { |
359 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
360 | "Notifying client about missing message: %s\n", | ||
361 | GNUNET_h2s (hash)); | ||
362 | |||
344 | struct GNUNET_MESSENGER_GetMessage *response; | 363 | struct GNUNET_MESSENGER_GetMessage *response; |
345 | struct GNUNET_MQ_Envelope *env; | 364 | struct GNUNET_MQ_Envelope *env; |
346 | 365 | ||
diff --git a/src/service/messenger/gnunet-service-messenger_handle.c b/src/service/messenger/gnunet-service-messenger_handle.c index c13517603..ca9dcfb15 100644 --- a/src/service/messenger/gnunet-service-messenger_handle.c +++ b/src/service/messenger/gnunet-service-messenger_handle.c | |||
@@ -240,6 +240,7 @@ open_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, | |||
240 | key, | 240 | key, |
241 | NULL, | 241 | NULL, |
242 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)) | 242 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)) |
243 | |||
243 | return GNUNET_NO; | 244 | return GNUNET_NO; |
244 | 245 | ||
245 | if ((! get_srv_handle_member_id (handle, key)) && | 246 | if ((! get_srv_handle_member_id (handle, key)) && |
@@ -449,8 +450,8 @@ notify_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, | |||
449 | } | 450 | } |
450 | else | 451 | else |
451 | { | 452 | { |
452 | const struct GNUNET_CRYPTO_PublicKey *pubkey = get_contact_key ( | 453 | const struct GNUNET_CRYPTO_PublicKey *pubkey; |
453 | session->member->contact); | 454 | pubkey = get_member_session_public_key (session->member); |
454 | GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &sender); | 455 | GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &sender); |
455 | 456 | ||
456 | context = get_next_member_session_context (session->member); | 457 | context = get_next_member_session_context (session->member); |
@@ -499,6 +500,10 @@ iterate_next_member_ids (void *cls, | |||
499 | struct GNUNET_MESSENGER_SrvHandle *handle = cls; | 500 | struct GNUNET_MESSENGER_SrvHandle *handle = cls; |
500 | struct GNUNET_MESSENGER_NextMemberId *next = value; | 501 | struct GNUNET_MESSENGER_NextMemberId *next = value; |
501 | 502 | ||
503 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
504 | "Notifying client about next member id: %s (%s)\n", | ||
505 | GNUNET_sh2s (&(next->id)), GNUNET_h2s (key)); | ||
506 | |||
502 | struct GNUNET_MESSENGER_MemberMessage *msg; | 507 | struct GNUNET_MESSENGER_MemberMessage *msg; |
503 | struct GNUNET_MQ_Envelope *env; | 508 | struct GNUNET_MQ_Envelope *env; |
504 | 509 | ||
diff --git a/src/service/messenger/gnunet-service-messenger_list_messages.c b/src/service/messenger/gnunet-service-messenger_list_messages.c index 0cb4e5787..cd59c8aec 100644 --- a/src/service/messenger/gnunet-service-messenger_list_messages.c +++ b/src/service/messenger/gnunet-service-messenger_list_messages.c | |||
@@ -111,7 +111,8 @@ load_list_messages (struct GNUNET_MESSENGER_ListMessages *messages, | |||
111 | return; | 111 | return; |
112 | 112 | ||
113 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | 113 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ |
114 | | GNUNET_DISK_PERM_USER_WRITE); | 114 | | GNUNET_DISK_PERM_USER_WRITE |
115 | ); | ||
115 | 116 | ||
116 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( | 117 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( |
117 | path, GNUNET_DISK_OPEN_READ, permission | 118 | path, GNUNET_DISK_OPEN_READ, permission |
@@ -145,7 +146,8 @@ save_list_messages (const struct GNUNET_MESSENGER_ListMessages *messages, | |||
145 | GNUNET_assert ((messages) && (path)); | 146 | GNUNET_assert ((messages) && (path)); |
146 | 147 | ||
147 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | 148 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ |
148 | | GNUNET_DISK_PERM_USER_WRITE); | 149 | | GNUNET_DISK_PERM_USER_WRITE |
150 | ); | ||
149 | 151 | ||
150 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( | 152 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( |
151 | path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission | 153 | path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission |
diff --git a/src/service/messenger/gnunet-service-messenger_member_session.c b/src/service/messenger/gnunet-service-messenger_member_session.c index dc1124360..ed1fd75b7 100644 --- a/src/service/messenger/gnunet-service-messenger_member_session.c +++ b/src/service/messenger/gnunet-service-messenger_member_session.c | |||
@@ -154,8 +154,6 @@ completion: | |||
154 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Completed session history (%s)\n", | 154 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Completed session history (%s)\n", |
155 | GNUNET_sh2s (get_member_session_id (session))); | 155 | GNUNET_sh2s (get_member_session_id (session))); |
156 | 156 | ||
157 | GNUNET_CONTAINER_multihashmap_clear (session->history); | ||
158 | |||
159 | struct GNUNET_MESSENGER_ContactStore *store = get_member_contact_store ( | 157 | struct GNUNET_MESSENGER_ContactStore *store = get_member_contact_store ( |
160 | session->member->store); | 158 | session->member->store); |
161 | 159 | ||
@@ -418,7 +416,15 @@ verify_member_session_as_sender (const struct | |||
418 | GNUNET_assert ((session) && (message) && (hash)); | 416 | GNUNET_assert ((session) && (message) && (hash)); |
419 | 417 | ||
420 | if (GNUNET_YES == is_member_session_completed (session)) | 418 | if (GNUNET_YES == is_member_session_completed (session)) |
421 | return GNUNET_SYSERR; | 419 | { |
420 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Check message (%s) using history!\n", | ||
421 | GNUNET_h2s (hash)); | ||
422 | |||
423 | if (GNUNET_YES == check_member_session_history (session, hash, GNUNET_YES)) | ||
424 | return GNUNET_OK; | ||
425 | else | ||
426 | return GNUNET_SYSERR; | ||
427 | } | ||
422 | 428 | ||
423 | if (0 != GNUNET_memcmp (get_member_session_id (session), | 429 | if (0 != GNUNET_memcmp (get_member_session_id (session), |
424 | &(message->header.sender_id))) | 430 | &(message->header.sender_id))) |
@@ -533,7 +539,8 @@ load_member_session_history (struct GNUNET_MESSENGER_MemberSession *session, | |||
533 | return; | 539 | return; |
534 | 540 | ||
535 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | 541 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ |
536 | | GNUNET_DISK_PERM_USER_WRITE); | 542 | | GNUNET_DISK_PERM_USER_WRITE |
543 | ); | ||
537 | 544 | ||
538 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( | 545 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( |
539 | path, GNUNET_DISK_OPEN_READ, permission | 546 | path, GNUNET_DISK_OPEN_READ, permission |
@@ -757,7 +764,8 @@ save_member_session_history (struct GNUNET_MESSENGER_MemberSession *session, | |||
757 | GNUNET_assert ((session) && (path)); | 764 | GNUNET_assert ((session) && (path)); |
758 | 765 | ||
759 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | 766 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ |
760 | | GNUNET_DISK_PERM_USER_WRITE); | 767 | | GNUNET_DISK_PERM_USER_WRITE |
768 | ); | ||
761 | 769 | ||
762 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( | 770 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( |
763 | path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission | 771 | path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission |
diff --git a/src/service/messenger/gnunet-service-messenger_message_recv.c b/src/service/messenger/gnunet-service-messenger_message_recv.c index 53e96b524..6d4d537b6 100644 --- a/src/service/messenger/gnunet-service-messenger_message_recv.c +++ b/src/service/messenger/gnunet-service-messenger_message_recv.c | |||
@@ -51,6 +51,7 @@ forward_about_members (struct GNUNET_MESSENGER_SrvRoom *room, | |||
51 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (map, &(element->hash), | 51 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (map, &(element->hash), |
52 | NULL, | 52 | NULL, |
53 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 53 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
54 | |||
54 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 55 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
55 | "Forwarding of session message could be duplicated!\n"); | 56 | "Forwarding of session message could be duplicated!\n"); |
56 | 57 | ||
diff --git a/src/service/messenger/gnunet-service-messenger_message_send.c b/src/service/messenger/gnunet-service-messenger_message_send.c index e7b92007b..05032e455 100644 --- a/src/service/messenger/gnunet-service-messenger_message_send.c +++ b/src/service/messenger/gnunet-service-messenger_message_send.c | |||
@@ -76,6 +76,7 @@ notify_about_members (struct GNUNET_MESSENGER_MemberNotify *notify, | |||
76 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (map, &(element->hash), | 76 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (map, &(element->hash), |
77 | NULL, | 77 | NULL, |
78 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 78 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
79 | |||
79 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 80 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
80 | "Notification of session message could be duplicated!\n"); | 81 | "Notification of session message could be duplicated!\n"); |
81 | 82 | ||
diff --git a/src/service/messenger/gnunet-service-messenger_message_store.c b/src/service/messenger/gnunet-service-messenger_message_store.c index d39e3f7bb..1eb275f9b 100644 --- a/src/service/messenger/gnunet-service-messenger_message_store.c +++ b/src/service/messenger/gnunet-service-messenger_message_store.c | |||
@@ -217,6 +217,7 @@ load_message_store_links (struct GNUNET_MESSENGER_MessageStore *store, | |||
217 | (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links, | 217 | (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links, |
218 | &(storage.hash), link, | 218 | &(storage.hash), link, |
219 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) | 219 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) |
220 | |||
220 | break; | 221 | break; |
221 | } | 222 | } |
222 | while (link); | 223 | while (link); |
@@ -235,7 +236,8 @@ load_message_store (struct GNUNET_MESSENGER_MessageStore *store, | |||
235 | GNUNET_assert ((store) && (directory)); | 236 | GNUNET_assert ((store) && (directory)); |
236 | 237 | ||
237 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | 238 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ |
238 | | GNUNET_DISK_PERM_USER_WRITE); | 239 | | GNUNET_DISK_PERM_USER_WRITE |
240 | ); | ||
239 | 241 | ||
240 | if (store->storage_messages) | 242 | if (store->storage_messages) |
241 | GNUNET_DISK_file_close (store->storage_messages); | 243 | GNUNET_DISK_file_close (store->storage_messages); |
@@ -369,7 +371,8 @@ save_message_store (struct GNUNET_MESSENGER_MessageStore *store, | |||
369 | struct GNUNET_MESSENGER_ClosureMessageSave save; | 371 | struct GNUNET_MESSENGER_ClosureMessageSave save; |
370 | 372 | ||
371 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | 373 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ |
372 | | GNUNET_DISK_PERM_USER_WRITE); | 374 | | GNUNET_DISK_PERM_USER_WRITE |
375 | ); | ||
373 | 376 | ||
374 | char *filename; | 377 | char *filename; |
375 | 378 | ||
@@ -526,6 +529,7 @@ get_store_message (struct GNUNET_MESSENGER_MessageStore *store, | |||
526 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (store->messages, hash, | 529 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (store->messages, hash, |
527 | message, | 530 | message, |
528 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 531 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
532 | |||
529 | goto free_buffer; | 533 | goto free_buffer; |
530 | 534 | ||
531 | free_message : destroy_message (message); | 535 | free_message : destroy_message (message); |
@@ -609,6 +613,7 @@ add_link (struct GNUNET_MESSENGER_MessageStore *store, | |||
609 | 613 | ||
610 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links, hash, link, | 614 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links, hash, link, |
611 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 615 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
616 | |||
612 | GNUNET_free (link); | 617 | GNUNET_free (link); |
613 | else | 618 | else |
614 | store->write_links = GNUNET_YES; | 619 | store->write_links = GNUNET_YES; |
diff --git a/src/service/messenger/gnunet-service-messenger_peer_store.c b/src/service/messenger/gnunet-service-messenger_peer_store.c index 5a2fd5f58..fdfbf599b 100644 --- a/src/service/messenger/gnunet-service-messenger_peer_store.c +++ b/src/service/messenger/gnunet-service-messenger_peer_store.c | |||
@@ -85,7 +85,8 @@ load_peer_store (struct GNUNET_MESSENGER_PeerStore *store, | |||
85 | path); | 85 | path); |
86 | 86 | ||
87 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | 87 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ |
88 | | GNUNET_DISK_PERM_USER_WRITE); | 88 | | GNUNET_DISK_PERM_USER_WRITE |
89 | ); | ||
89 | 90 | ||
90 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( | 91 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( |
91 | path, GNUNET_DISK_OPEN_READ, permission | 92 | path, GNUNET_DISK_OPEN_READ, permission |
@@ -158,7 +159,8 @@ save_peer_store (const struct GNUNET_MESSENGER_PeerStore *store, | |||
158 | path); | 159 | path); |
159 | 160 | ||
160 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | 161 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ |
161 | | GNUNET_DISK_PERM_USER_WRITE); | 162 | | GNUNET_DISK_PERM_USER_WRITE |
163 | ); | ||
162 | 164 | ||
163 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( | 165 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( |
164 | path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission | 166 | path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission |
diff --git a/src/service/messenger/gnunet-service-messenger_room.c b/src/service/messenger/gnunet-service-messenger_room.c index db2a158c7..570d2f990 100644 --- a/src/service/messenger/gnunet-service-messenger_room.c +++ b/src/service/messenger/gnunet-service-messenger_room.c | |||
@@ -1116,6 +1116,11 @@ handle_room_messages (struct GNUNET_MESSENGER_SrvRoom *room) | |||
1116 | get_srv_room_member_store (room); | 1116 | get_srv_room_member_store (room); |
1117 | struct GNUNET_MESSENGER_PeerStore *peer_store = get_srv_room_peer_store ( | 1117 | struct GNUNET_MESSENGER_PeerStore *peer_store = get_srv_room_peer_store ( |
1118 | room); | 1118 | room); |
1119 | |||
1120 | const struct GNUNET_HashCode *key = get_srv_room_key (room); | ||
1121 | |||
1122 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1123 | "Handling room messages: %s\n", GNUNET_h2s (key)); | ||
1119 | 1124 | ||
1120 | while (room->handling.head) | 1125 | while (room->handling.head) |
1121 | { | 1126 | { |
diff --git a/src/service/messenger/gnunet-service-messenger_service.c b/src/service/messenger/gnunet-service-messenger_service.c index 39ec0611e..11656d6b7 100644 --- a/src/service/messenger/gnunet-service-messenger_service.c +++ b/src/service/messenger/gnunet-service-messenger_service.c | |||
@@ -445,6 +445,11 @@ handle_service_message (struct GNUNET_MESSENGER_Service *service, | |||
445 | { | 445 | { |
446 | GNUNET_assert ((service) && (room) && (session) && (message) && (hash)); | 446 | GNUNET_assert ((service) && (room) && (session) && (message) && (hash)); |
447 | 447 | ||
448 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
449 | "Notify active clients about message: %s (%s)\n", | ||
450 | GNUNET_h2s (hash), GNUNET_MESSENGER_name_of_kind ( | ||
451 | message->header.kind)); | ||
452 | |||
448 | struct GNUNET_MESSENGER_ListHandle *element = service->handles.head; | 453 | struct GNUNET_MESSENGER_ListHandle *element = service->handles.head; |
449 | 454 | ||
450 | while (element) | 455 | while (element) |
diff --git a/src/service/messenger/messenger_api.c b/src/service/messenger/messenger_api.c index ecdd1feb2..12a326202 100644 --- a/src/service/messenger/messenger_api.c +++ b/src/service/messenger/messenger_api.c | |||
@@ -602,6 +602,8 @@ GNUNET_MESSENGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
602 | if ((! key) || (0 < GNUNET_CRYPTO_private_key_get_length (key))) | 602 | if ((! key) || (0 < GNUNET_CRYPTO_private_key_get_length (key))) |
603 | set_handle_key (handle, key); | 603 | set_handle_key (handle, key); |
604 | 604 | ||
605 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connect handle!\n"); | ||
606 | |||
605 | struct GNUNET_MESSENGER_CreateMessage *msg; | 607 | struct GNUNET_MESSENGER_CreateMessage *msg; |
606 | struct GNUNET_MQ_Envelope *env; | 608 | struct GNUNET_MQ_Envelope *env; |
607 | 609 | ||
@@ -623,6 +625,8 @@ GNUNET_MESSENGER_disconnect (struct GNUNET_MESSENGER_Handle *handle) | |||
623 | if (! handle) | 625 | if (! handle) |
624 | return; | 626 | return; |
625 | 627 | ||
628 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnect handle!\n"); | ||
629 | |||
626 | struct GNUNET_MESSENGER_DestroyMessage *msg; | 630 | struct GNUNET_MESSENGER_DestroyMessage *msg; |
627 | struct GNUNET_MQ_Envelope *env; | 631 | struct GNUNET_MQ_Envelope *env; |
628 | 632 | ||
@@ -634,6 +638,18 @@ GNUNET_MESSENGER_disconnect (struct GNUNET_MESSENGER_Handle *handle) | |||
634 | 638 | ||
635 | 639 | ||
636 | static void | 640 | static void |
641 | callback_leave_message_sent (void *cls) | ||
642 | { | ||
643 | struct GNUNET_MESSENGER_Room *room = cls; | ||
644 | |||
645 | room->opened = GNUNET_NO; | ||
646 | clear_list_tunnels (&(room->entries)); | ||
647 | |||
648 | send_close_room (room->handle, room); | ||
649 | } | ||
650 | |||
651 | |||
652 | static void | ||
637 | send_message_to_room (struct GNUNET_MESSENGER_Room *room, | 653 | send_message_to_room (struct GNUNET_MESSENGER_Room *room, |
638 | struct GNUNET_MESSENGER_Message *message, | 654 | struct GNUNET_MESSENGER_Message *message, |
639 | const struct GNUNET_CRYPTO_PrivateKey *key, | 655 | const struct GNUNET_CRYPTO_PrivateKey *key, |
@@ -669,12 +685,15 @@ send_message_to_room (struct GNUNET_MESSENGER_Room *room, | |||
669 | hash_message (message, msg_length, msg_buffer, hash); | 685 | hash_message (message, msg_length, msg_buffer, hash); |
670 | sign_message (message, msg_length, msg_buffer, hash, key); | 686 | sign_message (message, msg_length, msg_buffer, hash, key); |
671 | 687 | ||
672 | update_room_last_message (room, hash); | 688 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send message (%s)!\n", |
689 | GNUNET_h2s (hash)); | ||
673 | 690 | ||
674 | GNUNET_MQ_send (room->handle->mq, env); | 691 | update_room_last_message (room, hash); |
675 | 692 | ||
676 | if (GNUNET_MESSENGER_KIND_LEAVE == message->header.kind) | 693 | if (GNUNET_MESSENGER_KIND_LEAVE == message->header.kind) |
677 | send_close_room (room->handle, room); | 694 | GNUNET_MQ_notify_sent (env, callback_leave_message_sent, room); |
695 | |||
696 | GNUNET_MQ_send (room->handle->mq, env); | ||
678 | } | 697 | } |
679 | 698 | ||
680 | 699 | ||
@@ -726,25 +745,33 @@ dequeue_messages_from_room (struct GNUNET_MESSENGER_Room *room) | |||
726 | if (message) | 745 | if (message) |
727 | destroy_message (message); | 746 | destroy_message (message); |
728 | 747 | ||
748 | memset (&key, 0, sizeof(key)); | ||
729 | message = dequeue_from_messages (&(room->queue), &key, &transcript); | 749 | message = dequeue_from_messages (&(room->queue), &key, &transcript); |
730 | 750 | ||
731 | if (! message) | 751 | if (! message) |
732 | { | 752 | { |
733 | message = transcript; | 753 | message = transcript; |
754 | transcript = NULL; | ||
734 | continue; | 755 | continue; |
735 | } | 756 | } |
736 | 757 | ||
737 | send_message_to_room (room, message, &key, &hash); | 758 | send_message_to_room (room, message, &key, &hash); |
738 | 759 | ||
739 | if (! transcript) | 760 | if (! transcript) |
761 | { | ||
762 | GNUNET_CRYPTO_private_key_clear (&key); | ||
740 | continue; | 763 | continue; |
764 | } | ||
741 | 765 | ||
742 | GNUNET_memcpy (&(transcript->body.transcript.hash), &hash, sizeof(hash)); | 766 | GNUNET_memcpy (&(transcript->body.transcript.hash), &hash, sizeof(hash)); |
767 | |||
768 | memset (&pubkey, 0, sizeof(pubkey)); | ||
743 | GNUNET_CRYPTO_key_get_public (&key, &pubkey); | 769 | GNUNET_CRYPTO_key_get_public (&key, &pubkey); |
744 | 770 | ||
745 | if (GNUNET_YES == encrypt_message (transcript, &pubkey)) | 771 | if (GNUNET_YES == encrypt_message (transcript, &pubkey)) |
746 | { | 772 | { |
747 | send_message_to_room (room, transcript, &key, &other); | 773 | send_message_to_room (room, transcript, &key, &other); |
774 | GNUNET_CRYPTO_private_key_clear (&key); | ||
748 | 775 | ||
749 | link_room_message (room, &hash, &other); | 776 | link_room_message (room, &hash, &other); |
750 | link_room_message (room, &other, &hash); | 777 | link_room_message (room, &other, &hash); |
@@ -752,8 +779,9 @@ dequeue_messages_from_room (struct GNUNET_MESSENGER_Room *room) | |||
752 | else | 779 | else |
753 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 780 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
754 | "Sending transcript aborted: Encryption failed!\n"); | 781 | "Sending transcript aborted: Encryption failed!\n"); |
755 | 782 | ||
756 | destroy_message (transcript); | 783 | destroy_message (transcript); |
784 | transcript = NULL; | ||
757 | } while (message); | 785 | } while (message); |
758 | 786 | ||
759 | return GNUNET_YES; | 787 | return GNUNET_YES; |
@@ -866,7 +894,9 @@ GNUNET_MESSENGER_set_key (struct GNUNET_MESSENGER_Handle *handle, | |||
866 | GNUNET_memcpy (&priv, key, sizeof (priv)); | 894 | GNUNET_memcpy (&priv, key, sizeof (priv)); |
867 | 895 | ||
868 | GNUNET_MESSENGER_find_rooms (handle, NULL, iterate_send_key_to_room, &priv); | 896 | GNUNET_MESSENGER_find_rooms (handle, NULL, iterate_send_key_to_room, &priv); |
869 | set_handle_key (handle, &priv); | 897 | GNUNET_CRYPTO_private_key_clear (&priv); |
898 | |||
899 | set_handle_key (handle, key); | ||
870 | return GNUNET_YES; | 900 | return GNUNET_YES; |
871 | } | 901 | } |
872 | 902 | ||
@@ -936,8 +966,10 @@ GNUNET_MESSENGER_close_room (struct GNUNET_MESSENGER_Room *room) | |||
936 | 966 | ||
937 | struct GNUNET_MESSENGER_Message *message = create_message_leave (); | 967 | struct GNUNET_MESSENGER_Message *message = create_message_leave (); |
938 | 968 | ||
939 | if (message) | 969 | if (! message) |
940 | enqueue_message_to_room (room, message, NULL); | 970 | return; |
971 | |||
972 | enqueue_message_to_room (room, message, NULL); | ||
941 | } | 973 | } |
942 | 974 | ||
943 | 975 | ||
@@ -960,7 +992,8 @@ iterate_find_room (void *cls, | |||
960 | if ((find->counter > 0) && ((! find->contact) || (GNUNET_YES == | 992 | if ((find->counter > 0) && ((! find->contact) || (GNUNET_YES == |
961 | find_room_member (room, | 993 | find_room_member (room, |
962 | find-> | 994 | find-> |
963 | contact)))) | 995 | contact))) |
996 | ) | ||
964 | { | 997 | { |
965 | find->counter--; | 998 | find->counter--; |
966 | 999 | ||
@@ -1202,6 +1235,9 @@ GNUNET_MESSENGER_get_message (const struct GNUNET_MESSENGER_Room *room, | |||
1202 | 1235 | ||
1203 | if (! message) | 1236 | if (! message) |
1204 | { | 1237 | { |
1238 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request message (%s)!\n", | ||
1239 | GNUNET_h2s (hash)); | ||
1240 | |||
1205 | struct GNUNET_MESSENGER_GetMessage *msg; | 1241 | struct GNUNET_MESSENGER_GetMessage *msg; |
1206 | struct GNUNET_MQ_Envelope *env; | 1242 | struct GNUNET_MQ_Envelope *env; |
1207 | 1243 | ||
@@ -1225,78 +1261,3 @@ GNUNET_MESSENGER_iterate_members (struct GNUNET_MESSENGER_Room *room, | |||
1225 | 1261 | ||
1226 | return iterate_room_members (room, callback, cls); | 1262 | return iterate_room_members (room, callback, cls); |
1227 | } | 1263 | } |
1228 | |||
1229 | |||
1230 | struct GNUNET_MESSENGER_CheckTicket | ||
1231 | { | ||
1232 | const struct GNUNET_CRYPTO_PublicKey *audience; | ||
1233 | enum GNUNET_GenericReturnValue result; | ||
1234 | }; | ||
1235 | |||
1236 | |||
1237 | static enum GNUNET_GenericReturnValue | ||
1238 | check_ticket_audience (void *cls, | ||
1239 | struct GNUNET_MESSENGER_Room *room, | ||
1240 | const struct GNUNET_MESSENGER_Contact *contact) | ||
1241 | { | ||
1242 | struct GNUNET_MESSENGER_CheckTicket *check = cls; | ||
1243 | |||
1244 | const struct GNUNET_CRYPTO_PublicKey *key; | ||
1245 | key = get_non_anonymous_key (get_contact_key (contact)); | ||
1246 | |||
1247 | if ((key) && (0 == GNUNET_memcmp (key, check->audience))) | ||
1248 | { | ||
1249 | check->result = GNUNET_YES; | ||
1250 | return GNUNET_NO; | ||
1251 | } | ||
1252 | |||
1253 | return GNUNET_YES; | ||
1254 | } | ||
1255 | |||
1256 | |||
1257 | void | ||
1258 | GNUNET_MESSENGER_send_ticket (struct GNUNET_MESSENGER_Room *room, | ||
1259 | const struct GNUNET_RECLAIM_Ticket *ticket) | ||
1260 | { | ||
1261 | if ((! room) || (! ticket)) | ||
1262 | return; | ||
1263 | |||
1264 | const struct GNUNET_CRYPTO_PublicKey *pubkey; | ||
1265 | pubkey = get_handle_pubkey (room->handle); | ||
1266 | |||
1267 | if (0 != GNUNET_memcmp (pubkey, &(ticket->identity))) | ||
1268 | { | ||
1269 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1270 | "Sending ticket aborted: Invalid identity!\n"); | ||
1271 | return; | ||
1272 | } | ||
1273 | |||
1274 | struct GNUNET_MESSENGER_CheckTicket check; | ||
1275 | check.audience = &(ticket->audience); | ||
1276 | check.result = GNUNET_NO; | ||
1277 | |||
1278 | const int members = iterate_room_members ( | ||
1279 | room, | ||
1280 | check_ticket_audience, | ||
1281 | &check); | ||
1282 | |||
1283 | if ((! members) || (GNUNET_YES != check.result)) | ||
1284 | { | ||
1285 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1286 | "Sending ticket aborted: Audience not found!\n"); | ||
1287 | return; | ||
1288 | } | ||
1289 | |||
1290 | struct GNUNET_MESSENGER_Message *message = create_message_ticket ( | ||
1291 | &(ticket->rnd) | ||
1292 | ); | ||
1293 | |||
1294 | if (! message) | ||
1295 | { | ||
1296 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1297 | "Sending ticket aborted: Message creation failed!\n"); | ||
1298 | return; | ||
1299 | } | ||
1300 | |||
1301 | send_message_to_room_with_key (room, message, &(ticket->audience)); | ||
1302 | } | ||
diff --git a/src/service/messenger/messenger_api_cmd_join_room.c b/src/service/messenger/messenger_api_cmd_join_room.c index 8151dc88e..dc0e9a882 100644 --- a/src/service/messenger/messenger_api_cmd_join_room.c +++ b/src/service/messenger/messenger_api_cmd_join_room.c | |||
@@ -177,6 +177,5 @@ GNUNET_MESSENGER_cmd_join_room (const char *label, | |||
177 | label, | 177 | label, |
178 | &join_room_run, | 178 | &join_room_run, |
179 | &join_room_cleanup, | 179 | &join_room_cleanup, |
180 | NULL, | ||
181 | NULL); | 180 | NULL); |
182 | } | 181 | } |
diff --git a/src/service/messenger/messenger_api_cmd_start_service.c b/src/service/messenger/messenger_api_cmd_start_service.c index 49e20eac4..f764d31c2 100644 --- a/src/service/messenger/messenger_api_cmd_start_service.c +++ b/src/service/messenger/messenger_api_cmd_start_service.c | |||
@@ -58,7 +58,8 @@ on_message_cb (void *cls, | |||
58 | return; | 58 | return; |
59 | 59 | ||
60 | if (GNUNET_OK != GNUNET_CONTAINER_multipeermap_put (rs->doors, | 60 | if (GNUNET_OK != GNUNET_CONTAINER_multipeermap_put (rs->doors, |
61 | &(message->body.peer.peer), | 61 | &(message->body.peer.peer) |
62 | , | ||
62 | NULL, | 63 | NULL, |
63 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)) | 64 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)) |
64 | { | 65 | { |
@@ -167,6 +168,5 @@ GNUNET_MESSENGER_cmd_start_service (const char *label, | |||
167 | label, | 168 | label, |
168 | &start_service_run, | 169 | &start_service_run, |
169 | &start_service_cleanup, | 170 | &start_service_cleanup, |
170 | &start_service_traits, | 171 | &start_service_traits); |
171 | NULL); | ||
172 | } | 172 | } |
diff --git a/src/service/messenger/messenger_api_cmd_stop_service.c b/src/service/messenger/messenger_api_cmd_stop_service.c index 774237d25..b10de7661 100644 --- a/src/service/messenger/messenger_api_cmd_stop_service.c +++ b/src/service/messenger/messenger_api_cmd_stop_service.c | |||
@@ -91,6 +91,5 @@ GNUNET_MESSENGER_cmd_stop_service (const char *label, | |||
91 | label, | 91 | label, |
92 | &stop_service_run, | 92 | &stop_service_run, |
93 | &stop_service_cleanup, | 93 | &stop_service_cleanup, |
94 | NULL, | ||
95 | NULL); | 94 | NULL); |
96 | } | 95 | } |
diff --git a/src/service/messenger/messenger_api_contact_store.c b/src/service/messenger/messenger_api_contact_store.c index e60a8d5ca..081a8c6e9 100644 --- a/src/service/messenger/messenger_api_contact_store.c +++ b/src/service/messenger/messenger_api_contact_store.c | |||
@@ -143,6 +143,7 @@ get_store_contact (struct GNUNET_MESSENGER_ContactStore *store, | |||
143 | 143 | ||
144 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (map, &hash, contact, | 144 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (map, &hash, contact, |
145 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 145 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
146 | |||
146 | return contact; | 147 | return contact; |
147 | 148 | ||
148 | destroy_contact (contact); | 149 | destroy_contact (contact); |
@@ -183,6 +184,7 @@ update_store_contact (struct GNUNET_MESSENGER_ContactStore *store, | |||
183 | 184 | ||
184 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (map, &hash, contact, | 185 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (map, &hash, contact, |
185 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 186 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
187 | |||
186 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Updating a contact failed: %s\n", | 188 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Updating a contact failed: %s\n", |
187 | GNUNET_h2s (&hash)); | 189 | GNUNET_h2s (&hash)); |
188 | } | 190 | } |
diff --git a/src/service/messenger/messenger_api_list_tunnels.c b/src/service/messenger/messenger_api_list_tunnels.c index 8f5b4788d..bb500233b 100644 --- a/src/service/messenger/messenger_api_list_tunnels.c +++ b/src/service/messenger/messenger_api_list_tunnels.c | |||
@@ -233,7 +233,8 @@ load_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | |||
233 | path); | 233 | path); |
234 | 234 | ||
235 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | 235 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ |
236 | | GNUNET_DISK_PERM_USER_WRITE); | 236 | | GNUNET_DISK_PERM_USER_WRITE |
237 | ); | ||
237 | 238 | ||
238 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( | 239 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( |
239 | path, GNUNET_DISK_OPEN_READ, permission | 240 | path, GNUNET_DISK_OPEN_READ, permission |
@@ -270,7 +271,8 @@ save_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | |||
270 | path); | 271 | path); |
271 | 272 | ||
272 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | 273 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ |
273 | | GNUNET_DISK_PERM_USER_WRITE); | 274 | | GNUNET_DISK_PERM_USER_WRITE |
275 | ); | ||
274 | 276 | ||
275 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( | 277 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open ( |
276 | path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission | 278 | path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission |
diff --git a/src/service/messenger/messenger_api_message.c b/src/service/messenger/messenger_api_message.c index 68b6c7d20..fa281cb37 100644 --- a/src/service/messenger/messenger_api_message.c +++ b/src/service/messenger/messenger_api_message.c | |||
@@ -32,7 +32,7 @@ | |||
32 | struct GNUNET_MESSENGER_MessageSignature | 32 | struct GNUNET_MESSENGER_MessageSignature |
33 | { | 33 | { |
34 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | 34 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; |
35 | struct GNUNET_HashCode hash; | 35 | struct GNUNET_HashCode hash GNUNET_PACKED; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | struct GNUNET_MESSENGER_ShortMessage | 38 | struct GNUNET_MESSENGER_ShortMessage |
@@ -64,6 +64,9 @@ create_message (enum GNUNET_MESSENGER_MessageKind kind) | |||
64 | message->body.privacy.length = 0; | 64 | message->body.privacy.length = 0; |
65 | message->body.privacy.data = NULL; | 65 | message->body.privacy.data = NULL; |
66 | break; | 66 | break; |
67 | case GNUNET_MESSENGER_KIND_TICKET: | ||
68 | message->body.ticket.identifier = NULL; | ||
69 | break; | ||
67 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: | 70 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: |
68 | message->body.transcript.length = 0; | 71 | message->body.transcript.length = 0; |
69 | message->body.transcript.data = NULL; | 72 | message->body.transcript.data = NULL; |
@@ -112,6 +115,11 @@ copy_message (const struct GNUNET_MESSENGER_Message *message) | |||
112 | copy->body.privacy.length); | 115 | copy->body.privacy.length); |
113 | 116 | ||
114 | break; | 117 | break; |
118 | case GNUNET_MESSENGER_KIND_TICKET: | ||
119 | copy->body.ticket.identifier = message->body.ticket.identifier? | ||
120 | GNUNET_strdup ( | ||
121 | message->body.ticket.identifier) : NULL; | ||
122 | break; | ||
115 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: | 123 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: |
116 | copy->body.transcript.data = copy->body.transcript.length ? GNUNET_malloc ( | 124 | copy->body.transcript.data = copy->body.transcript.length ? GNUNET_malloc ( |
117 | copy->body.transcript.length) : NULL; | 125 | copy->body.transcript.length) : NULL; |
@@ -169,6 +177,10 @@ destroy_message_body (enum GNUNET_MESSENGER_MessageKind kind, | |||
169 | case GNUNET_MESSENGER_KIND_PRIVATE: | 177 | case GNUNET_MESSENGER_KIND_PRIVATE: |
170 | GNUNET_free (body->privacy.data); | 178 | GNUNET_free (body->privacy.data); |
171 | break; | 179 | break; |
180 | case GNUNET_MESSENGER_KIND_TICKET: | ||
181 | if (body->ticket.identifier) | ||
182 | GNUNET_free (body->ticket.identifier); | ||
183 | break; | ||
172 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: | 184 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: |
173 | GNUNET_free (body->transcript.data); | 185 | GNUNET_free (body->transcript.data); |
174 | break; | 186 | break; |
@@ -294,10 +306,6 @@ get_message_body_kind_size (enum GNUNET_MESSENGER_MessageKind kind) | |||
294 | length += member_size (struct GNUNET_MESSENGER_Message, | 306 | length += member_size (struct GNUNET_MESSENGER_Message, |
295 | body.connection.flags); | 307 | body.connection.flags); |
296 | break; | 308 | break; |
297 | case GNUNET_MESSENGER_KIND_TICKET: | ||
298 | length += member_size (struct GNUNET_MESSENGER_Message, | ||
299 | body.ticket.identifier); | ||
300 | break; | ||
301 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: | 309 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: |
302 | length += member_size (struct GNUNET_MESSENGER_Message, | 310 | length += member_size (struct GNUNET_MESSENGER_Message, |
303 | body.transcript.hash); | 311 | body.transcript.hash); |
@@ -360,6 +368,9 @@ get_message_body_size (enum GNUNET_MESSENGER_MessageKind kind, | |||
360 | case GNUNET_MESSENGER_KIND_PRIVATE: | 368 | case GNUNET_MESSENGER_KIND_PRIVATE: |
361 | length += body->privacy.length; | 369 | length += body->privacy.length; |
362 | break; | 370 | break; |
371 | case GNUNET_MESSENGER_KIND_TICKET: | ||
372 | length += (body->ticket.identifier ? strlen (body->ticket.identifier) : 0); | ||
373 | break; | ||
363 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: | 374 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: |
364 | length += GNUNET_CRYPTO_public_key_get_length (&(body->transcript.key)); | 375 | length += GNUNET_CRYPTO_public_key_get_length (&(body->transcript.key)); |
365 | length += body->transcript.length; | 376 | length += body->transcript.length; |
@@ -506,11 +517,14 @@ encode_message_body (enum GNUNET_MESSENGER_MessageKind kind, | |||
506 | case GNUNET_MESSENGER_KIND_JOIN: | 517 | case GNUNET_MESSENGER_KIND_JOIN: |
507 | encode_step_key (buffer, offset, &(body->join.key), length); | 518 | encode_step_key (buffer, offset, &(body->join.key), length); |
508 | break; | 519 | break; |
520 | case GNUNET_MESSENGER_KIND_LEAVE: | ||
521 | break; | ||
509 | case GNUNET_MESSENGER_KIND_NAME: | 522 | case GNUNET_MESSENGER_KIND_NAME: |
510 | if (body->name.name) | 523 | if (body->name.name) |
511 | encode_step_ext (buffer, offset, body->name.name, min (length - offset, | 524 | encode_step_ext (buffer, offset, body->name.name, min (length - offset, |
512 | strlen ( | 525 | strlen ( |
513 | body->name.name))); | 526 | body->name.name)) |
527 | ); | ||
514 | break; | 528 | break; |
515 | case GNUNET_MESSENGER_KIND_KEY: | 529 | case GNUNET_MESSENGER_KIND_KEY: |
516 | encode_step_key (buffer, offset, &(body->key.key), length); | 530 | encode_step_key (buffer, offset, &(body->key.key), length); |
@@ -538,7 +552,8 @@ encode_message_body (enum GNUNET_MESSENGER_MessageKind kind, | |||
538 | if (body->text.text) | 552 | if (body->text.text) |
539 | encode_step_ext (buffer, offset, body->text.text, min (length - offset, | 553 | encode_step_ext (buffer, offset, body->text.text, min (length - offset, |
540 | strlen ( | 554 | strlen ( |
541 | body->text.text))); | 555 | body->text.text)) |
556 | ); | ||
542 | break; | 557 | break; |
543 | case GNUNET_MESSENGER_KIND_FILE: | 558 | case GNUNET_MESSENGER_KIND_FILE: |
544 | encode_step (buffer, offset, &(body->file.key)); | 559 | encode_step (buffer, offset, &(body->file.key)); |
@@ -567,7 +582,8 @@ encode_message_body (enum GNUNET_MESSENGER_MessageKind kind, | |||
567 | encode_step (buffer, offset, &value1); | 582 | encode_step (buffer, offset, &value1); |
568 | break; | 583 | break; |
569 | case GNUNET_MESSENGER_KIND_TICKET: | 584 | case GNUNET_MESSENGER_KIND_TICKET: |
570 | encode_step (buffer, offset, &(body->ticket.identifier)); | 585 | encode_step_ext (buffer, offset, body->ticket.identifier, |
586 | min (length - offset, strlen (body->ticket.identifier))); | ||
571 | break; | 587 | break; |
572 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: | 588 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: |
573 | encode_step (buffer, offset, &(body->transcript.hash)); | 589 | encode_step (buffer, offset, &(body->transcript.hash)); |
@@ -711,15 +727,17 @@ decode_message_body (enum GNUNET_MESSENGER_MessageKind *kind, | |||
711 | uint32_t value0, value1; | 727 | uint32_t value0, value1; |
712 | switch (*kind) | 728 | switch (*kind) |
713 | { | 729 | { |
714 | case GNUNET_MESSENGER_KIND_INFO: { | 730 | case GNUNET_MESSENGER_KIND_INFO: |
715 | decode_step (buffer, offset, &value0); | 731 | decode_step (buffer, offset, &value0); |
716 | 732 | ||
717 | body->info.messenger_version = GNUNET_be32toh (value0); | 733 | body->info.messenger_version = GNUNET_be32toh (value0); |
718 | break; | 734 | break; |
719 | } case GNUNET_MESSENGER_KIND_JOIN: { | 735 | case GNUNET_MESSENGER_KIND_JOIN: |
720 | decode_step_key (buffer, offset, &(body->join.key), length); | 736 | decode_step_key (buffer, offset, &(body->join.key), length); |
721 | break; | 737 | break; |
722 | } case GNUNET_MESSENGER_KIND_NAME: | 738 | case GNUNET_MESSENGER_KIND_LEAVE: |
739 | break; | ||
740 | case GNUNET_MESSENGER_KIND_NAME: | ||
723 | if (length > offset) | 741 | if (length > offset) |
724 | decode_step_malloc (buffer, offset, body->name.name, length - offset, 1); | 742 | decode_step_malloc (buffer, offset, body->name.name, length - offset, 1); |
725 | else | 743 | else |
@@ -780,7 +798,11 @@ decode_message_body (enum GNUNET_MESSENGER_MessageKind *kind, | |||
780 | body->connection.flags = GNUNET_be32toh (value1); | 798 | body->connection.flags = GNUNET_be32toh (value1); |
781 | break; | 799 | break; |
782 | case GNUNET_MESSENGER_KIND_TICKET: | 800 | case GNUNET_MESSENGER_KIND_TICKET: |
783 | decode_step (buffer, offset, &(body->ticket.identifier)); | 801 | if (length > offset) |
802 | decode_step_malloc (buffer, offset, body->ticket.identifier, length | ||
803 | - offset, 1); | ||
804 | else | ||
805 | body->ticket.identifier = NULL; | ||
784 | break; | 806 | break; |
785 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: | 807 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: |
786 | decode_step (buffer, offset, &(body->transcript.hash)); | 808 | decode_step (buffer, offset, &(body->transcript.hash)); |
@@ -942,7 +964,7 @@ sign_message (struct GNUNET_MESSENGER_Message *message, | |||
942 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); | 964 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); |
943 | signature.purpose.size = htonl (sizeof(signature)); | 965 | signature.purpose.size = htonl (sizeof(signature)); |
944 | 966 | ||
945 | GNUNET_memcpy (&(signature.hash), hash, sizeof(struct GNUNET_HashCode)); | 967 | GNUNET_memcpy (&(signature.hash), hash, sizeof(signature.hash)); |
946 | GNUNET_CRYPTO_sign (key, &signature, &(message->header.signature)); | 968 | GNUNET_CRYPTO_sign (key, &signature, &(message->header.signature)); |
947 | 969 | ||
948 | message->header.signature.type = key->type; | 970 | message->header.signature.type = key->type; |
@@ -969,8 +991,8 @@ sign_message_by_peer (struct GNUNET_MESSENGER_Message *message, | |||
969 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); | 991 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); |
970 | signature.purpose.size = htonl (sizeof(signature)); | 992 | signature.purpose.size = htonl (sizeof(signature)); |
971 | 993 | ||
972 | GNUNET_memcpy (&(signature.hash), hash, sizeof(struct GNUNET_HashCode)); | 994 | GNUNET_memcpy (&(signature.hash), hash, sizeof(signature.hash)); |
973 | GNUNET_CRYPTO_sign_by_peer_identity (cfg, &signature.purpose, | 995 | GNUNET_CRYPTO_sign_by_peer_identity (cfg, &(signature.purpose), |
974 | &(message->header.signature. | 996 | &(message->header.signature. |
975 | eddsa_signature)); | 997 | eddsa_signature)); |
976 | 998 | ||
@@ -996,7 +1018,7 @@ verify_message (const struct GNUNET_MESSENGER_Message *message, | |||
996 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); | 1018 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); |
997 | signature.purpose.size = htonl (sizeof(signature)); | 1019 | signature.purpose.size = htonl (sizeof(signature)); |
998 | 1020 | ||
999 | GNUNET_memcpy (&(signature.hash), hash, sizeof(struct GNUNET_HashCode)); | 1021 | GNUNET_memcpy (&(signature.hash), hash, sizeof(signature.hash)); |
1000 | 1022 | ||
1001 | return GNUNET_CRYPTO_signature_verify ( | 1023 | return GNUNET_CRYPTO_signature_verify ( |
1002 | GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE, &signature, | 1024 | GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE, &signature, |
@@ -1019,10 +1041,10 @@ verify_message_by_peer (const struct GNUNET_MESSENGER_Message *message, | |||
1019 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); | 1041 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); |
1020 | signature.purpose.size = htonl (sizeof(signature)); | 1042 | signature.purpose.size = htonl (sizeof(signature)); |
1021 | 1043 | ||
1022 | GNUNET_memcpy (&(signature.hash), hash, sizeof(struct GNUNET_HashCode)); | 1044 | GNUNET_memcpy (&(signature.hash), hash, sizeof(signature.hash)); |
1023 | 1045 | ||
1024 | return GNUNET_CRYPTO_verify_peer_identity ( | 1046 | return GNUNET_CRYPTO_verify_peer_identity ( |
1025 | GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE, &signature.purpose, | 1047 | GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE, &(signature.purpose), |
1026 | &(message->header.signature. | 1048 | &(message->header.signature. |
1027 | eddsa_signature), identity); | 1049 | eddsa_signature), identity); |
1028 | } | 1050 | } |
@@ -1347,7 +1369,7 @@ filter_message_sending (const struct GNUNET_MESSENGER_Message *message) | |||
1347 | case GNUNET_MESSENGER_KIND_CONNECTION: | 1369 | case GNUNET_MESSENGER_KIND_CONNECTION: |
1348 | return GNUNET_SYSERR; // Reserved for connection handling only! | 1370 | return GNUNET_SYSERR; // Reserved for connection handling only! |
1349 | case GNUNET_MESSENGER_KIND_TICKET: | 1371 | case GNUNET_MESSENGER_KIND_TICKET: |
1350 | return GNUNET_NO; // Use #GNUNET_MESSENGER_send_ticket(...) instead! | 1372 | return GNUNET_YES; |
1351 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: | 1373 | case GNUNET_MESSENGER_KIND_TRANSCRIPT: |
1352 | return GNUNET_NO; // Use #GNUNET_MESSENGER_send_message(...) with a contact instead! | 1374 | return GNUNET_NO; // Use #GNUNET_MESSENGER_send_message(...) with a contact instead! |
1353 | case GNUNET_MESSENGER_KIND_TAG: | 1375 | case GNUNET_MESSENGER_KIND_TAG: |
diff --git a/src/service/messenger/messenger_api_message_control.c b/src/service/messenger/messenger_api_message_control.c index c46c047c4..e8d0333dc 100644 --- a/src/service/messenger/messenger_api_message_control.c +++ b/src/service/messenger/messenger_api_message_control.c | |||
@@ -222,7 +222,7 @@ process_message_control (struct GNUNET_MESSENGER_MessageControl *control, | |||
222 | struct GNUNET_CONTAINER_MultiShortmap *map = NULL; | 222 | struct GNUNET_CONTAINER_MultiShortmap *map = NULL; |
223 | const struct GNUNET_ShortHashCode *id = &(message->header.sender_id); | 223 | const struct GNUNET_ShortHashCode *id = &(message->header.sender_id); |
224 | 224 | ||
225 | if (GNUNET_YES == is_peer_message(message)) | 225 | if (GNUNET_YES == is_peer_message (message)) |
226 | map = control->peer_messages; | 226 | map = control->peer_messages; |
227 | 227 | ||
228 | switch (message->header.kind) | 228 | switch (message->header.kind) |
diff --git a/src/service/messenger/messenger_api_message_kind.c b/src/service/messenger/messenger_api_message_kind.c index 33338af9d..d423c5dda 100644 --- a/src/service/messenger/messenger_api_message_kind.c +++ b/src/service/messenger/messenger_api_message_kind.c | |||
@@ -98,7 +98,8 @@ create_message_id (const struct GNUNET_ShortHashCode *unique_id) | |||
98 | return NULL; | 98 | return NULL; |
99 | 99 | ||
100 | GNUNET_memcpy (&(message->body.id.id), unique_id, sizeof(struct | 100 | GNUNET_memcpy (&(message->body.id.id), unique_id, sizeof(struct |
101 | GNUNET_ShortHashCode)); | 101 | GNUNET_ShortHashCode) |
102 | ); | ||
102 | 103 | ||
103 | return message; | 104 | return message; |
104 | } | 105 | } |
@@ -143,7 +144,8 @@ create_message_invite (const struct GNUNET_PeerIdentity *door, | |||
143 | return NULL; | 144 | return NULL; |
144 | 145 | ||
145 | GNUNET_memcpy (&(message->body.invite.door), door, sizeof(struct | 146 | GNUNET_memcpy (&(message->body.invite.door), door, sizeof(struct |
146 | GNUNET_PeerIdentity)); | 147 | GNUNET_PeerIdentity) |
148 | ); | ||
147 | GNUNET_memcpy (&(message->body.invite.key), key, sizeof(struct | 149 | GNUNET_memcpy (&(message->body.invite.key), key, sizeof(struct |
148 | GNUNET_HashCode)); | 150 | GNUNET_HashCode)); |
149 | 151 | ||
@@ -190,9 +192,9 @@ create_message_delete (const struct GNUNET_HashCode *hash, | |||
190 | 192 | ||
191 | 193 | ||
192 | struct GNUNET_MESSENGER_Message* | 194 | struct GNUNET_MESSENGER_Message* |
193 | create_message_ticket (const struct GNUNET_RECLAIM_Identifier *identifier) | 195 | create_message_ticket (const struct GNUNET_RECLAIM_Ticket *ticket) |
194 | { | 196 | { |
195 | if (! identifier) | 197 | if (! ticket) |
196 | return NULL; | 198 | return NULL; |
197 | 199 | ||
198 | struct GNUNET_MESSENGER_Message *message = create_message ( | 200 | struct GNUNET_MESSENGER_Message *message = create_message ( |
@@ -201,8 +203,7 @@ create_message_ticket (const struct GNUNET_RECLAIM_Identifier *identifier) | |||
201 | if (! message) | 203 | if (! message) |
202 | return NULL; | 204 | return NULL; |
203 | 205 | ||
204 | GNUNET_memcpy (&(message->body.ticket.identifier), identifier, | 206 | message->body.ticket.identifier = GNUNET_strdup (ticket->gns_name); |
205 | sizeof(struct GNUNET_RECLAIM_Identifier)); | ||
206 | 207 | ||
207 | return message; | 208 | return message; |
208 | } | 209 | } |
diff --git a/src/service/messenger/messenger_api_message_kind.h b/src/service/messenger/messenger_api_message_kind.h index a5bb12947..5f4107f61 100644 --- a/src/service/messenger/messenger_api_message_kind.h +++ b/src/service/messenger/messenger_api_message_kind.h | |||
@@ -27,9 +27,8 @@ | |||
27 | #define GNUNET_MESSENGER_API_MESSAGE_KIND_H | 27 | #define GNUNET_MESSENGER_API_MESSAGE_KIND_H |
28 | 28 | ||
29 | #include "gnunet_messenger_service.h" | 29 | #include "gnunet_messenger_service.h" |
30 | #include "gnunet_reclaim_lib.h" | 30 | #include "gnunet_reclaim_service.h" |
31 | #include "gnunet_util_lib.h" | 31 | #include "gnunet_util_lib.h" |
32 | #include "gnunet_time_lib.h" | ||
33 | 32 | ||
34 | /** | 33 | /** |
35 | * Creates and allocates a new join message containing the clients public <i>key</i>. | 34 | * Creates and allocates a new join message containing the clients public <i>key</i>. |
@@ -134,6 +133,6 @@ create_message_delete (const struct GNUNET_HashCode *hash, | |||
134 | * @return New message | 133 | * @return New message |
135 | */ | 134 | */ |
136 | struct GNUNET_MESSENGER_Message* | 135 | struct GNUNET_MESSENGER_Message* |
137 | create_message_ticket (const struct GNUNET_RECLAIM_Identifier *identifier); | 136 | create_message_ticket (const struct GNUNET_RECLAIM_Ticket *ticket); |
138 | 137 | ||
139 | #endif //GNUNET_MESSENGER_API_MESSAGE_KIND_H | 138 | #endif //GNUNET_MESSENGER_API_MESSAGE_KIND_H |
diff --git a/src/service/messenger/messenger_api_queue_messages.c b/src/service/messenger/messenger_api_queue_messages.c index f29de368b..33e591da3 100644 --- a/src/service/messenger/messenger_api_queue_messages.c +++ b/src/service/messenger/messenger_api_queue_messages.c | |||
@@ -86,7 +86,7 @@ enqueue_to_messages (struct GNUNET_MESSENGER_QueueMessages *messages, | |||
86 | if (! element->message) | 86 | if (! element->message) |
87 | { | 87 | { |
88 | if (element->transcript) | 88 | if (element->transcript) |
89 | destroy_message(element->transcript); | 89 | destroy_message (element->transcript); |
90 | 90 | ||
91 | GNUNET_free (element); | 91 | GNUNET_free (element); |
92 | return; | 92 | return; |
@@ -121,7 +121,7 @@ dequeue_from_messages (struct GNUNET_MESSENGER_QueueMessages *messages, | |||
121 | if (transcript) | 121 | if (transcript) |
122 | *transcript = element->transcript; | 122 | *transcript = element->transcript; |
123 | else if (element->transcript) | 123 | else if (element->transcript) |
124 | destroy_message(element->transcript); | 124 | destroy_message (element->transcript); |
125 | 125 | ||
126 | GNUNET_CONTAINER_DLL_remove (messages->head, messages->tail, element); | 126 | GNUNET_CONTAINER_DLL_remove (messages->head, messages->tail, element); |
127 | 127 | ||
diff --git a/src/service/messenger/messenger_api_room.c b/src/service/messenger/messenger_api_room.c index e1970b668..cddd43b22 100644 --- a/src/service/messenger/messenger_api_room.c +++ b/src/service/messenger/messenger_api_room.c | |||
@@ -300,6 +300,7 @@ handle_join_message (struct GNUNET_MESSENGER_Room *room, | |||
300 | .sender_id), | 300 | .sender_id), |
301 | entry->sender, | 301 | entry->sender, |
302 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))) | 302 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))) |
303 | |||
303 | increase_contact_rc (entry->sender); | 304 | increase_contact_rc (entry->sender); |
304 | } | 305 | } |
305 | 306 | ||
@@ -393,6 +394,7 @@ handle_id_message (struct GNUNET_MESSENGER_Room *room, | |||
393 | id.id), | 394 | id.id), |
394 | entry->sender, | 395 | entry->sender, |
395 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))) | 396 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))) |
397 | |||
396 | return; | 398 | return; |
397 | 399 | ||
398 | struct GNUNET_HashCode context, next_context; | 400 | struct GNUNET_HashCode context, next_context; |
@@ -574,7 +576,8 @@ read_transcript: | |||
574 | 576 | ||
575 | original->recipient = get_store_contact (store, | 577 | original->recipient = get_store_contact (store, |
576 | NULL, | 578 | NULL, |
577 | &(entry->message->body.transcript.key)); | 579 | &(entry->message->body.transcript.key |
580 | )); | ||
578 | 581 | ||
579 | if (original->message) | 582 | if (original->message) |
580 | { | 583 | { |
@@ -826,12 +829,14 @@ link_room_message (struct GNUNET_MESSENGER_Room *room, | |||
826 | return; | 829 | return; |
827 | 830 | ||
828 | struct GNUNET_HashCode *value = GNUNET_memdup (other, sizeof(struct | 831 | struct GNUNET_HashCode *value = GNUNET_memdup (other, sizeof(struct |
829 | GNUNET_HashCode)); | 832 | GNUNET_HashCode)) |
833 | ; | ||
830 | if (! value) | 834 | if (! value) |
831 | return; | 835 | return; |
832 | 836 | ||
833 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (room->links, hash, value, | 837 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (room->links, hash, value, |
834 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)) | 838 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)) |
839 | |||
835 | GNUNET_free (value); | 840 | GNUNET_free (value); |
836 | } | 841 | } |
837 | 842 | ||
diff --git a/src/service/messenger/test_messenger.c b/src/service/messenger/test_messenger.c index 3c3dbd14d..4f7a51e34 100644 --- a/src/service/messenger/test_messenger.c +++ b/src/service/messenger/test_messenger.c | |||
@@ -74,6 +74,7 @@ end (void *cls) | |||
74 | messenger = NULL; | 74 | messenger = NULL; |
75 | } | 75 | } |
76 | 76 | ||
77 | GNUNET_CRYPTO_private_key_clear (&identity); | ||
77 | status = 0; | 78 | status = 0; |
78 | } | 79 | } |
79 | 80 | ||
diff --git a/src/service/namestore/gnunet-service-namestore.c b/src/service/namestore/gnunet-service-namestore.c index f29058d0e..6f3a77b84 100644 --- a/src/service/namestore/gnunet-service-namestore.c +++ b/src/service/namestore/gnunet-service-namestore.c | |||
@@ -1091,7 +1091,7 @@ struct RecordLookupContext | |||
1091 | /** | 1091 | /** |
1092 | * The editor hint for set | 1092 | * The editor hint for set |
1093 | */ | 1093 | */ |
1094 | const char *editor_hint; | 1094 | char *editor_hint; |
1095 | 1095 | ||
1096 | /** | 1096 | /** |
1097 | * The record result. | 1097 | * The record result. |
@@ -1157,7 +1157,8 @@ lookup_it (void *cls, | |||
1157 | if (0 != strcmp (label, rlc->label)) | 1157 | if (0 != strcmp (label, rlc->label)) |
1158 | return; | 1158 | return; |
1159 | rlc->found = GNUNET_YES; | 1159 | rlc->found = GNUNET_YES; |
1160 | rlc->editor_hint = editor_hint; | 1160 | if (NULL == rlc->editor_hint) |
1161 | rlc->editor_hint = GNUNET_strdup (editor_hint); | ||
1161 | if (GNUNET_OK != GNUNET_GNSRECORD_normalize_record_set (rlc->label, | 1162 | if (GNUNET_OK != GNUNET_GNSRECORD_normalize_record_set (rlc->label, |
1162 | rd_nf, | 1163 | rd_nf, |
1163 | rd_count_nf, | 1164 | rd_count_nf, |
@@ -1332,6 +1333,7 @@ handle_edit_record_set (void *cls, const struct EditRecordSetMessage *er_msg) | |||
1332 | return; | 1333 | return; |
1333 | } | 1334 | } |
1334 | name_len = strlen (conv_name) + 1; | 1335 | name_len = strlen (conv_name) + 1; |
1336 | rlc.editor_hint = NULL; | ||
1335 | rlc.label = conv_name; | 1337 | rlc.label = conv_name; |
1336 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1338 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1337 | "Looking up without filter\n"); | 1339 | "Looking up without filter\n"); |
@@ -1370,6 +1372,7 @@ handle_edit_record_set (void *cls, const struct EditRecordSetMessage *er_msg) | |||
1370 | GNUNET_memcpy ((char*) &rer_msg[1] + old_editor_hint_len, rlc.res_rd, | 1372 | GNUNET_memcpy ((char*) &rer_msg[1] + old_editor_hint_len, rlc.res_rd, |
1371 | rlc.rd_ser_len); | 1373 | rlc.rd_ser_len); |
1372 | GNUNET_MQ_send (nc->mq, env); | 1374 | GNUNET_MQ_send (nc->mq, env); |
1375 | GNUNET_free (rlc.editor_hint); | ||
1373 | GNUNET_free (rlc.res_rd); | 1376 | GNUNET_free (rlc.res_rd); |
1374 | GNUNET_free (conv_name); | 1377 | GNUNET_free (conv_name); |
1375 | } | 1378 | } |
@@ -1566,6 +1569,7 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1566 | return; | 1569 | return; |
1567 | } | 1570 | } |
1568 | name_len = strlen (conv_name) + 1; | 1571 | name_len = strlen (conv_name) + 1; |
1572 | rlc.editor_hint = NULL; | ||
1569 | rlc.label = conv_name; | 1573 | rlc.label = conv_name; |
1570 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1574 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1571 | "Looking up with filter %u\n", ntohs (ll_msg->filter)); | 1575 | "Looking up with filter %u\n", ntohs (ll_msg->filter)); |
@@ -1601,6 +1605,7 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1601 | GNUNET_memcpy (res_name, conv_name, name_len); | 1605 | GNUNET_memcpy (res_name, conv_name, name_len); |
1602 | GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len); | 1606 | GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len); |
1603 | GNUNET_MQ_send (nc->mq, env); | 1607 | GNUNET_MQ_send (nc->mq, env); |
1608 | GNUNET_free (rlc.editor_hint); | ||
1604 | GNUNET_free (rlc.res_rd); | 1609 | GNUNET_free (rlc.res_rd); |
1605 | GNUNET_free (conv_name); | 1610 | GNUNET_free (conv_name); |
1606 | } | 1611 | } |
diff --git a/src/service/nat/gnunet-service-nat.c b/src/service/nat/gnunet-service-nat.c index 00584ab8a..a36e8da1c 100644 --- a/src/service/nat/gnunet-service-nat.c +++ b/src/service/nat/gnunet-service-nat.c | |||
@@ -1816,10 +1816,9 @@ check_request_connection_reversal (void *cls, | |||
1816 | * @param message the message received | 1816 | * @param message the message received |
1817 | */ | 1817 | */ |
1818 | static void | 1818 | static void |
1819 | handle_request_connection_reversal (void *cls, | 1819 | handle_request_connection_reversal ( |
1820 | const struct | 1820 | void *cls, |
1821 | GNUNET_NAT_RequestConnectionReversalMessage | 1821 | const struct GNUNET_NAT_RequestConnectionReversalMessage *message) |
1822 | *message) | ||
1823 | { | 1822 | { |
1824 | struct ClientHandle *ch = cls; | 1823 | struct ClientHandle *ch = cls; |
1825 | const char *buf = (const char *) &message[1]; | 1824 | const char *buf = (const char *) &message[1]; |
@@ -1871,47 +1870,29 @@ handle_request_connection_reversal (void *cls, | |||
1871 | * @param message the message received | 1870 | * @param message the message received |
1872 | * @return #GNUNET_OK if message is well-formed | 1871 | * @return #GNUNET_OK if message is well-formed |
1873 | */ | 1872 | */ |
1874 | static int | 1873 | static enum GNUNET_GenericReturnValue |
1875 | check_add_global_address(void *cls, | 1874 | check_add_global_address ( |
1876 | const struct GNUNET_NAT_AddGlobalAddressMessage *message) | 1875 | void *cls, |
1876 | const struct GNUNET_NAT_AddGlobalAddressMessage *message) | ||
1877 | { | 1877 | { |
1878 | char *addr = GNUNET_malloc (ntohs (message->address_length)); | 1878 | const char *buf = (const char *) &message[1]; |
1879 | uint16_t blen = ntohs (message->address_length); | ||
1879 | size_t left = ntohs (message->header.size) - sizeof(*message); | 1880 | size_t left = ntohs (message->header.size) - sizeof(*message); |
1880 | 1881 | ||
1881 | GNUNET_memcpy (addr, (const char *) &message[1], ntohs (message->address_length)); | ||
1882 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1883 | "message size %u natting address %s length %u left %u\n", | ||
1884 | ntohs (message->header.size), | ||
1885 | addr, | ||
1886 | ntohs (message->address_length), | ||
1887 | left); | ||
1888 | |||
1889 | if (left != ntohs (message->address_length)) | 1882 | if (left != ntohs (message->address_length)) |
1890 | { | 1883 | { |
1891 | GNUNET_break (0); | 1884 | GNUNET_break_op (0); |
1885 | return GNUNET_SYSERR; | ||
1886 | } | ||
1887 | if ('\0' != buf[blen - 1]) | ||
1888 | { | ||
1889 | GNUNET_break_op (0); | ||
1892 | return GNUNET_SYSERR; | 1890 | return GNUNET_SYSERR; |
1893 | } | 1891 | } |
1894 | GNUNET_free (addr); | ||
1895 | return GNUNET_OK; | 1892 | return GNUNET_OK; |
1896 | } | 1893 | } |
1897 | 1894 | ||
1898 | 1895 | ||
1899 | static int | ||
1900 | is_nat_v4 (const struct in_addr *ip); | ||
1901 | |||
1902 | |||
1903 | static int | ||
1904 | is_nat_v6 (const struct in6_addr *ip); | ||
1905 | |||
1906 | |||
1907 | static void | ||
1908 | notify_client (enum GNUNET_NAT_AddressClass ac, | ||
1909 | struct ClientHandle *ch, | ||
1910 | int add, | ||
1911 | const void *addr, | ||
1912 | size_t addr_len); | ||
1913 | |||
1914 | |||
1915 | /** | 1896 | /** |
1916 | * Handle #GNUNET_MESSAGE_TYPE_NAT_ADD_GLOBAL_ADDRESS message from | 1897 | * Handle #GNUNET_MESSAGE_TYPE_NAT_ADD_GLOBAL_ADDRESS message from |
1917 | * client. | 1898 | * client. |
@@ -1920,72 +1901,29 @@ notify_client (enum GNUNET_NAT_AddressClass ac, | |||
1920 | * @param message the message received | 1901 | * @param message the message received |
1921 | */ | 1902 | */ |
1922 | static void | 1903 | static void |
1923 | handle_add_global_address(void *cls, | 1904 | handle_add_global_address ( |
1924 | const struct GNUNET_NAT_AddGlobalAddressMessage *message) | 1905 | void *cls, |
1906 | const struct GNUNET_NAT_AddGlobalAddressMessage *message) | ||
1925 | { | 1907 | { |
1926 | struct ClientHandle *ch = cls; | 1908 | struct ClientHandle *ch = cls; |
1927 | char *buf = GNUNET_malloc (ntohs (message->address_length)); | 1909 | const char *buf = (const char *) &message[1]; |
1928 | //= (const char *) &message[1]; | 1910 | uint16_t blen = ntohs (message->address_length); |
1929 | struct sockaddr *sockaddr = NULL; | 1911 | struct sockaddr_in sockaddr_ipv4 = { |
1930 | socklen_t addr_len; | 1912 | .sin_family = AF_INET |
1931 | struct sockaddr_in *sockaddr_ipv4 = GNUNET_malloc(sizeof(struct sockaddr_in)); | 1913 | }; |
1932 | enum GNUNET_NAT_AddressClass ac; | 1914 | |
1933 | 1915 | GNUNET_assert ('\0' == buf[blen - 1]); | |
1934 | GNUNET_memcpy (buf, (const char *) &message[1], ntohs (message->address_length)); | 1916 | if (1 != inet_pton (AF_INET, |
1935 | memset(sockaddr_ipv4, 0, sizeof(struct sockaddr_in)); | 1917 | buf, |
1936 | sockaddr_ipv4->sin_family = AF_INET; | 1918 | &sockaddr_ipv4.sin_addr)) |
1937 | |||
1938 | if (1 == inet_pton(AF_INET, buf, &(sockaddr_ipv4->sin_addr))) | ||
1939 | { | ||
1940 | sockaddr = (struct sockaddr *)sockaddr_ipv4; | ||
1941 | addr_len = sizeof(struct sockaddr_in); | ||
1942 | ac = is_nat_v4 (&((const struct sockaddr_in *)sockaddr_ipv4)->sin_addr) | ||
1943 | ? GNUNET_NAT_AC_LAN | ||
1944 | : GNUNET_NAT_AC_EXTERN; | ||
1945 | } | ||
1946 | else | ||
1947 | { | ||
1948 | GNUNET_free(sockaddr_ipv4); | ||
1949 | sockaddr_ipv4 = NULL; | ||
1950 | } | ||
1951 | |||
1952 | if (NULL == sockaddr) | ||
1953 | { | ||
1954 | struct sockaddr_in6 *sockaddr_ipv6 = malloc(sizeof(struct sockaddr_in6)); | ||
1955 | |||
1956 | if (sockaddr_ipv6 != NULL) | ||
1957 | { | ||
1958 | memset(sockaddr_ipv6, 0, sizeof(struct sockaddr_in6)); | ||
1959 | sockaddr_ipv6->sin6_family = AF_INET6; | ||
1960 | |||
1961 | if (1 == inet_pton(AF_INET6, buf, &(sockaddr_ipv6->sin6_addr))) | ||
1962 | { | ||
1963 | GNUNET_break (0); | ||
1964 | GNUNET_SERVICE_client_continue (ch->client); | ||
1965 | GNUNET_free (buf); | ||
1966 | return; | ||
1967 | } | ||
1968 | else | ||
1969 | { | ||
1970 | GNUNET_free(sockaddr_ipv6); | ||
1971 | sockaddr_ipv6 = NULL; | ||
1972 | } | ||
1973 | } | ||
1974 | } | ||
1975 | |||
1976 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1977 | "3 natting address %s\n", | ||
1978 | buf); | ||
1979 | if (NULL == sockaddr) | ||
1980 | { | 1919 | { |
1981 | GNUNET_break (0); | 1920 | GNUNET_break (0); |
1982 | GNUNET_SERVICE_client_continue (ch->client); | 1921 | GNUNET_SERVICE_client_continue (ch->client); |
1983 | GNUNET_free (buf); | ||
1984 | return; | 1922 | return; |
1985 | } | 1923 | } |
1986 | notify_clients_stun_change (sockaddr_ipv4, GNUNET_YES); | 1924 | notify_clients_stun_change (&sockaddr_ipv4, |
1925 | GNUNET_YES); | ||
1987 | GNUNET_SERVICE_client_continue (ch->client); | 1926 | GNUNET_SERVICE_client_continue (ch->client); |
1988 | GNUNET_free (buf); | ||
1989 | } | 1927 | } |
1990 | 1928 | ||
1991 | 1929 | ||
diff --git a/src/service/nat/nat_api.c b/src/service/nat/nat_api.c index 219a11e81..52c74d5db 100644 --- a/src/service/nat/nat_api.c +++ b/src/service/nat/nat_api.c | |||
@@ -455,31 +455,6 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
455 | return nh; | 455 | return nh; |
456 | } | 456 | } |
457 | 457 | ||
458 | |||
459 | /** | ||
460 | * Get the IP address without the port number. | ||
461 | * | ||
462 | * @param address The string contains a communicator prefix, IP address and port | ||
463 | * like this 'tcp-92.68.150.1:55452'. | ||
464 | * @return String with prefix and IP address only. | ||
465 | */ | ||
466 | static char * | ||
467 | get_address_without_port (const char *address) | ||
468 | { | ||
469 | const char *colon; | ||
470 | char *colon_rest; | ||
471 | size_t colon_rest_length; | ||
472 | char *address_without_port; | ||
473 | |||
474 | colon = strchr (address,':'); | ||
475 | colon_rest = GNUNET_strndup (address, colon - address); | ||
476 | colon_rest_length = strlen (colon_rest); | ||
477 | address_without_port = GNUNET_strndup (&colon_rest[4], colon_rest_length - 4); | ||
478 | GNUNET_free (colon_rest); | ||
479 | |||
480 | return address_without_port; | ||
481 | } | ||
482 | |||
483 | void | 458 | void |
484 | GNUNET_NAT_add_global_address (struct GNUNET_NAT_Handle *nh, | 459 | GNUNET_NAT_add_global_address (struct GNUNET_NAT_Handle *nh, |
485 | char *addr, | 460 | char *addr, |
diff --git a/src/service/peerstore/gnunet-service-peerstore.c b/src/service/peerstore/gnunet-service-peerstore.c index 37af3af56..9f3eb9bde 100644 --- a/src/service/peerstore/gnunet-service-peerstore.c +++ b/src/service/peerstore/gnunet-service-peerstore.c | |||
@@ -23,9 +23,9 @@ | |||
23 | * @brief peerstore service implementation | 23 | * @brief peerstore service implementation |
24 | * @author Omar Tarabai | 24 | * @author Omar Tarabai |
25 | */ | 25 | */ |
26 | #include "platform.h" | ||
26 | #include "gnunet_peerstore_service.h" | 27 | #include "gnunet_peerstore_service.h" |
27 | #include "gnunet_protocols.h" | 28 | #include "gnunet_protocols.h" |
28 | #include "platform.h" | ||
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | #include "peerstore.h" | 30 | #include "peerstore.h" |
31 | #include "gnunet_peerstore_plugin.h" | 31 | #include "gnunet_peerstore_plugin.h" |
@@ -491,6 +491,16 @@ iterate_proc (void *cls, | |||
491 | proc->limit--; | 491 | proc->limit--; |
492 | } | 492 | } |
493 | 493 | ||
494 | |||
495 | static void | ||
496 | destroy_iteration (struct Iteration *ic) | ||
497 | { | ||
498 | GNUNET_free (ic->key); | ||
499 | GNUNET_free (ic->sub_system); | ||
500 | GNUNET_free (ic); | ||
501 | } | ||
502 | |||
503 | |||
494 | /** | 504 | /** |
495 | * Function called once we are done with the iteration and | 505 | * Function called once we are done with the iteration and |
496 | * allow the zone iteration client to send us more messages. | 506 | * allow the zone iteration client to send us more messages. |
@@ -512,15 +522,12 @@ iteration_done_client_continue (struct Iteration *ic) | |||
512 | endmsg->rid = htons (ic->request_id); | 522 | endmsg->rid = htons (ic->request_id); |
513 | endmsg->result = htonl (GNUNET_OK); | 523 | endmsg->result = htonl (GNUNET_OK); |
514 | GNUNET_MQ_send (ic->pc->mq, env); | 524 | GNUNET_MQ_send (ic->pc->mq, env); |
515 | GNUNET_free (ic->key); | ||
516 | GNUNET_free (ic->sub_system); | ||
517 | GNUNET_CONTAINER_DLL_remove (ic->pc->op_head, ic->pc->op_tail, ic); | 525 | GNUNET_CONTAINER_DLL_remove (ic->pc->op_head, ic->pc->op_tail, ic); |
518 | GNUNET_free (ic); | 526 | destroy_iteration (ic); |
519 | return; | 527 | return; |
520 | } | 528 | } |
521 | 529 | ||
522 | 530 | ||
523 | |||
524 | /** | 531 | /** |
525 | * Perform the next round of the zone iteration. | 532 | * Perform the next round of the zone iteration. |
526 | * | 533 | * |
@@ -657,7 +664,7 @@ handle_iterate_stop (void *cls, | |||
657 | return; | 664 | return; |
658 | } | 665 | } |
659 | GNUNET_CONTAINER_DLL_remove (pc->op_head, pc->op_tail, ic); | 666 | GNUNET_CONTAINER_DLL_remove (pc->op_head, pc->op_tail, ic); |
660 | GNUNET_free (ic); | 667 | destroy_iteration (ic); |
661 | GNUNET_SERVICE_client_continue (pc->client); | 668 | GNUNET_SERVICE_client_continue (pc->client); |
662 | } | 669 | } |
663 | 670 | ||
@@ -803,8 +810,8 @@ monitor_iteration_next (void *cls) | |||
803 | { | 810 | { |
804 | GNUNET_free (mc->key); | 811 | GNUNET_free (mc->key); |
805 | GNUNET_free (mc->sub_system); | 812 | GNUNET_free (mc->sub_system); |
806 | GNUNET_free (mc); | ||
807 | GNUNET_SERVICE_client_drop (mc->pc->client); | 813 | GNUNET_SERVICE_client_drop (mc->pc->client); |
814 | GNUNET_free (mc); | ||
808 | return; | 815 | return; |
809 | } | 816 | } |
810 | if (GNUNET_NO == ret) | 817 | if (GNUNET_NO == ret) |
@@ -1090,13 +1097,15 @@ client_disconnect_cb (void *cls, | |||
1090 | GNUNET_SCHEDULER_cancel (mo->sa_wait_warning); | 1097 | GNUNET_SCHEDULER_cancel (mo->sa_wait_warning); |
1091 | mo->sa_wait_warning = NULL; | 1098 | mo->sa_wait_warning = NULL; |
1092 | } | 1099 | } |
1100 | GNUNET_free (mo->sub_system); | ||
1101 | GNUNET_free (mo->key); | ||
1093 | GNUNET_free (mo); | 1102 | GNUNET_free (mo); |
1094 | break; | 1103 | break; |
1095 | } | 1104 | } |
1096 | while (NULL != (iter = pc->op_head)) | 1105 | while (NULL != (iter = pc->op_head)) |
1097 | { | 1106 | { |
1098 | GNUNET_CONTAINER_DLL_remove (pc->op_head, pc->op_tail, iter); | 1107 | GNUNET_CONTAINER_DLL_remove (pc->op_head, pc->op_tail, iter); |
1099 | GNUNET_free (iter); | 1108 | destroy_iteration (iter); |
1100 | } | 1109 | } |
1101 | GNUNET_free (pc); | 1110 | GNUNET_free (pc); |
1102 | } | 1111 | } |
diff --git a/src/service/peerstore/peerstore_api.c b/src/service/peerstore/peerstore_api.c index 19cb1213e..45f347b6a 100644 --- a/src/service/peerstore/peerstore_api.c +++ b/src/service/peerstore/peerstore_api.c | |||
@@ -23,11 +23,9 @@ | |||
23 | * @author Omar Tarabai | 23 | * @author Omar Tarabai |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | */ | 25 | */ |
26 | #include "gnunet_time_lib.h" | ||
27 | #include "platform.h" | 26 | #include "platform.h" |
28 | #include "gnunet_common.h" | ||
29 | #include "gnunet_protocols.h" | ||
30 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_protocols.h" | ||
31 | #include "gnunet_hello_uri_lib.h" | 29 | #include "gnunet_hello_uri_lib.h" |
32 | #include "peerstore.h" | 30 | #include "peerstore.h" |
33 | #include "peerstore_common.h" | 31 | #include "peerstore_common.h" |
@@ -446,6 +444,7 @@ GNUNET_PEERSTORE_disconnect (struct GNUNET_PEERSTORE_Handle *h) | |||
446 | { | 444 | { |
447 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnect initiated from client.\n"); | 445 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnect initiated from client.\n"); |
448 | disconnect (h); | 446 | disconnect (h); |
447 | GNUNET_free (h); | ||
449 | } | 448 | } |
450 | 449 | ||
451 | 450 | ||
@@ -453,6 +452,16 @@ GNUNET_PEERSTORE_disconnect (struct GNUNET_PEERSTORE_Handle *h) | |||
453 | /******************* STORE FUNCTIONS *********************/ | 452 | /******************* STORE FUNCTIONS *********************/ |
454 | /******************************************************************************/ | 453 | /******************************************************************************/ |
455 | 454 | ||
455 | static void | ||
456 | destroy_storecontext (struct GNUNET_PEERSTORE_StoreContext *sc) | ||
457 | { | ||
458 | GNUNET_CONTAINER_DLL_remove (sc->h->store_head, sc->h->store_tail, sc); | ||
459 | GNUNET_free (sc->sub_system); | ||
460 | GNUNET_free (sc->value); | ||
461 | GNUNET_free (sc->key); | ||
462 | GNUNET_free (sc); | ||
463 | } | ||
464 | |||
456 | 465 | ||
457 | /** | 466 | /** |
458 | * Cancel a store request | 467 | * Cancel a store request |
@@ -465,11 +474,7 @@ GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc) | |||
465 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 474 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
466 | "store cancel with sc %p \n", | 475 | "store cancel with sc %p \n", |
467 | sc); | 476 | sc); |
468 | GNUNET_CONTAINER_DLL_remove (sc->h->store_head, sc->h->store_tail, sc); | 477 | destroy_storecontext (sc); |
469 | GNUNET_free (sc->sub_system); | ||
470 | GNUNET_free (sc->value); | ||
471 | GNUNET_free (sc->key); | ||
472 | GNUNET_free (sc); | ||
473 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 478 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
474 | "store cancel with sc %p is null\n", | 479 | "store cancel with sc %p is null\n", |
475 | sc); | 480 | sc); |
@@ -576,7 +581,7 @@ handle_store_result (void *cls, const struct PeerstoreResultMessage *msg) | |||
576 | } | 581 | } |
577 | if (NULL != sc->cont) | 582 | if (NULL != sc->cont) |
578 | sc->cont (sc->cont_cls, ntohl (msg->result)); | 583 | sc->cont (sc->cont_cls, ntohl (msg->result)); |
579 | GNUNET_CONTAINER_DLL_remove (h->store_head, h->store_tail, sc); | 584 | destroy_storecontext (sc); |
580 | } | 585 | } |
581 | 586 | ||
582 | 587 | ||
@@ -584,6 +589,15 @@ handle_store_result (void *cls, const struct PeerstoreResultMessage *msg) | |||
584 | /******************* ITERATE FUNCTIONS *********************/ | 589 | /******************* ITERATE FUNCTIONS *********************/ |
585 | /******************************************************************************/ | 590 | /******************************************************************************/ |
586 | 591 | ||
592 | static void | ||
593 | destroy_iteratecontext (struct GNUNET_PEERSTORE_IterateContext *ic) | ||
594 | { | ||
595 | GNUNET_CONTAINER_DLL_remove (ic->h->iterate_head, ic->h->iterate_tail, ic); | ||
596 | GNUNET_free (ic->sub_system); | ||
597 | GNUNET_free (ic->key); | ||
598 | GNUNET_free (ic); | ||
599 | } | ||
600 | |||
587 | 601 | ||
588 | /** | 602 | /** |
589 | * When a response for iterate request is received | 603 | * When a response for iterate request is received |
@@ -609,7 +623,7 @@ handle_iterate_end (void *cls, const struct PeerstoreResultMessage *msg) | |||
609 | if (NULL != ic->callback) | 623 | if (NULL != ic->callback) |
610 | ic->callback (ic->callback_cls, NULL, NULL); | 624 | ic->callback (ic->callback_cls, NULL, NULL); |
611 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up iteration with rid %u\n", ic->rid); | 625 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up iteration with rid %u\n", ic->rid); |
612 | GNUNET_CONTAINER_DLL_remove (h->iterate_head, h->iterate_tail, ic); | 626 | destroy_iteratecontext (ic); |
613 | } | 627 | } |
614 | 628 | ||
615 | 629 | ||
@@ -719,10 +733,7 @@ GNUNET_PEERSTORE_iteration_stop (struct GNUNET_PEERSTORE_IterateContext *ic) | |||
719 | if (NULL != ic->h->mq) | 733 | if (NULL != ic->h->mq) |
720 | GNUNET_MQ_send (ic->h->mq, ev); | 734 | GNUNET_MQ_send (ic->h->mq, ev); |
721 | } | 735 | } |
722 | GNUNET_CONTAINER_DLL_remove (ic->h->iterate_head, ic->h->iterate_tail, ic); | 736 | destroy_iteratecontext (ic); |
723 | GNUNET_free (ic->sub_system); | ||
724 | GNUNET_free (ic->key); | ||
725 | GNUNET_free (ic); | ||
726 | } | 737 | } |
727 | 738 | ||
728 | 739 | ||
diff --git a/src/service/peerstore/peerstore_api_monitor.c b/src/service/peerstore/peerstore_api_monitor.c index fff0b3eb0..2c527103c 100644 --- a/src/service/peerstore/peerstore_api_monitor.c +++ b/src/service/peerstore/peerstore_api_monitor.c | |||
@@ -22,10 +22,9 @@ | |||
22 | * @brief API for peerstore | 22 | * @brief API for peerstore |
23 | * @author Martin Schanzenbach | 23 | * @author Martin Schanzenbach |
24 | */ | 24 | */ |
25 | #include "gnunet_common.h" | ||
26 | #include "gnunet_protocols.h" | ||
27 | #include "platform.h" | 25 | #include "platform.h" |
28 | #include "gnunet_util_lib.h" | 26 | #include "gnunet_util_lib.h" |
27 | #include "gnunet_protocols.h" | ||
29 | #include "peerstore.h" | 28 | #include "peerstore.h" |
30 | #include "peerstore_common.h" | 29 | #include "peerstore_common.h" |
31 | #include "gnunet_peerstore_service.h" | 30 | #include "gnunet_peerstore_service.h" |
@@ -85,7 +84,7 @@ struct GNUNET_PEERSTORE_Monitor | |||
85 | /** | 84 | /** |
86 | * The sub system requested the watch. | 85 | * The sub system requested the watch. |
87 | */ | 86 | */ |
88 | const char *sub_system; | 87 | char *sub_system; |
89 | 88 | ||
90 | /** | 89 | /** |
91 | * Request ID | 90 | * Request ID |
@@ -237,17 +236,18 @@ reconnect (struct GNUNET_PEERSTORE_Monitor *mc) | |||
237 | 236 | ||
238 | 237 | ||
239 | struct GNUNET_PEERSTORE_Monitor * | 238 | struct GNUNET_PEERSTORE_Monitor * |
240 | GNUNET_PEERSTORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | 239 | GNUNET_PEERSTORE_monitor_start ( |
241 | int iterate_first, | 240 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
242 | const char *sub_system, | 241 | int iterate_first, |
243 | const struct GNUNET_PeerIdentity *peer, | 242 | const char *sub_system, |
244 | const char *key, | 243 | const struct GNUNET_PeerIdentity *peer, |
245 | GNUNET_SCHEDULER_TaskCallback error_cb, | 244 | const char *key, |
246 | void *error_cb_cls, | 245 | GNUNET_SCHEDULER_TaskCallback error_cb, |
247 | GNUNET_SCHEDULER_TaskCallback sync_cb, | 246 | void *error_cb_cls, |
248 | void *sync_cb_cls, | 247 | GNUNET_SCHEDULER_TaskCallback sync_cb, |
249 | GNUNET_PEERSTORE_Processor callback, | 248 | void *sync_cb_cls, |
250 | void *callback_cls) | 249 | GNUNET_PEERSTORE_Processor callback, |
250 | void *callback_cls) | ||
251 | { | 251 | { |
252 | struct GNUNET_PEERSTORE_Monitor *mc; | 252 | struct GNUNET_PEERSTORE_Monitor *mc; |
253 | 253 | ||
@@ -286,6 +286,7 @@ GNUNET_PEERSTORE_monitor_stop (struct GNUNET_PEERSTORE_Monitor *zm) | |||
286 | GNUNET_MQ_destroy (zm->mq); | 286 | GNUNET_MQ_destroy (zm->mq); |
287 | zm->mq = NULL; | 287 | zm->mq = NULL; |
288 | } | 288 | } |
289 | GNUNET_free (zm->sub_system); | ||
289 | GNUNET_free (zm); | 290 | GNUNET_free (zm); |
290 | } | 291 | } |
291 | 292 | ||
diff --git a/src/service/peerstore/peerstore_common.c b/src/service/peerstore/peerstore_common.c index 435444917..a326392ea 100644 --- a/src/service/peerstore/peerstore_common.c +++ b/src/service/peerstore/peerstore_common.c | |||
@@ -22,7 +22,6 @@ | |||
22 | * @brief Helper peerstore functions | 22 | * @brief Helper peerstore functions |
23 | * @author Omar Tarabai | 23 | * @author Omar Tarabai |
24 | */ | 24 | */ |
25 | |||
26 | #include "platform.h" | 25 | #include "platform.h" |
27 | #include "peerstore_common.h" | 26 | #include "peerstore_common.h" |
28 | 27 | ||
diff --git a/src/service/reclaim/gnunet-service-reclaim.c b/src/service/reclaim/gnunet-service-reclaim.c index 6edd93341..c381a5aaf 100644 --- a/src/service/reclaim/gnunet-service-reclaim.c +++ b/src/service/reclaim/gnunet-service-reclaim.c | |||
@@ -655,7 +655,6 @@ send_ticket_result (const struct IdpClient *client, | |||
655 | struct GNUNET_MQ_Envelope *env; | 655 | struct GNUNET_MQ_Envelope *env; |
656 | size_t pres_len = 0; | 656 | size_t pres_len = 0; |
657 | size_t tkt_len = 0; | 657 | size_t tkt_len = 0; |
658 | ssize_t written; | ||
659 | char *buf; | 658 | char *buf; |
660 | 659 | ||
661 | if (NULL != presentations) | 660 | if (NULL != presentations) |
@@ -664,20 +663,20 @@ send_ticket_result (const struct IdpClient *client, | |||
664 | GNUNET_RECLAIM_presentation_list_serialize_get_size (presentations); | 663 | GNUNET_RECLAIM_presentation_list_serialize_get_size (presentations); |
665 | } | 664 | } |
666 | if (NULL != ticket) | 665 | if (NULL != ticket) |
667 | tkt_len = GNUNET_RECLAIM_ticket_serialize_get_size (ticket); | 666 | tkt_len = strlen (ticket->gns_name) + 1; |
668 | env = GNUNET_MQ_msg_extra (irm, | 667 | env = GNUNET_MQ_msg_extra (irm, |
669 | pres_len + tkt_len, | 668 | pres_len + tkt_len, |
670 | GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); | 669 | GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); |
671 | buf = (char*) &irm[1]; | 670 | buf = (char*) &irm[1]; |
672 | if (NULL != ticket) | 671 | if (NULL != ticket) |
673 | { | 672 | { |
674 | written = GNUNET_RECLAIM_write_ticket_to_buffer (ticket, buf, tkt_len); | 673 | memcpy (buf, ticket, tkt_len); |
675 | GNUNET_assert (0 <= written); | 674 | buf += tkt_len; |
676 | buf += written; | ||
677 | } | 675 | } |
678 | // TODO add success member | 676 | // TODO add success member |
679 | irm->id = htonl (r_id); | 677 | irm->id = htonl (r_id); |
680 | irm->tkt_len = htons (tkt_len); | 678 | irm->tkt_len = htons (tkt_len); |
679 | irm->rp_uri_len = htons (0); | ||
681 | irm->presentations_len = htons (pres_len); | 680 | irm->presentations_len = htons (pres_len); |
682 | if (NULL != presentations) | 681 | if (NULL != presentations) |
683 | { | 682 | { |
@@ -739,14 +738,14 @@ check_issue_ticket_message (void *cls, const struct IssueTicketMessage *im) | |||
739 | uint16_t size; | 738 | uint16_t size; |
740 | size_t attrs_len; | 739 | size_t attrs_len; |
741 | size_t key_len; | 740 | size_t key_len; |
742 | size_t pkey_len; | 741 | size_t rp_len; |
743 | 742 | ||
744 | size = ntohs (im->header.size); | 743 | size = ntohs (im->header.size); |
745 | attrs_len = ntohs (im->attr_len); | 744 | attrs_len = ntohs (im->attr_len); |
746 | key_len = ntohs (im->key_len); | 745 | key_len = ntohs (im->key_len); |
747 | pkey_len = ntohs (im->pkey_len); | 746 | rp_len = ntohs (im->rp_uri_len); |
748 | if (size != attrs_len + key_len + pkey_len + sizeof(struct | 747 | if (size != attrs_len + key_len + rp_len + sizeof(struct |
749 | IssueTicketMessage)) | 748 | IssueTicketMessage)) |
750 | { | 749 | { |
751 | GNUNET_break (0); | 750 | GNUNET_break (0); |
752 | return GNUNET_SYSERR; | 751 | return GNUNET_SYSERR; |
@@ -769,10 +768,10 @@ handle_issue_ticket_message (void *cls, const struct IssueTicketMessage *im) | |||
769 | struct GNUNET_RECLAIM_AttributeList *attrs; | 768 | struct GNUNET_RECLAIM_AttributeList *attrs; |
770 | struct GNUNET_RECLAIM_AttributeListEntry *le; | 769 | struct GNUNET_RECLAIM_AttributeListEntry *le; |
771 | struct GNUNET_CRYPTO_PrivateKey identity; | 770 | struct GNUNET_CRYPTO_PrivateKey identity; |
772 | struct GNUNET_CRYPTO_PublicKey rp; | 771 | const char *rp; |
773 | size_t attrs_len; | 772 | size_t attrs_len; |
774 | size_t key_len; | 773 | size_t key_len; |
775 | size_t pkey_len; | 774 | size_t rp_len; |
776 | size_t read; | 775 | size_t read; |
777 | char *buf; | 776 | char *buf; |
778 | 777 | ||
@@ -790,18 +789,9 @@ handle_issue_ticket_message (void *cls, const struct IssueTicketMessage *im) | |||
790 | return; | 789 | return; |
791 | } | 790 | } |
792 | buf += read; | 791 | buf += read; |
793 | pkey_len = ntohs (im->pkey_len); | 792 | rp_len = ntohs (im->rp_uri_len); |
794 | if ((GNUNET_SYSERR == | 793 | rp = buf; |
795 | GNUNET_CRYPTO_read_public_key_from_buffer (buf, pkey_len, | 794 | buf += rp_len; |
796 | &rp, &read)) || | ||
797 | (read != pkey_len)) | ||
798 | { | ||
799 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
800 | "Failed to read public key\n"); | ||
801 | GNUNET_SERVICE_client_drop (idp->client); | ||
802 | return; | ||
803 | } | ||
804 | buf += read; | ||
805 | tio = GNUNET_new (struct TicketIssueOperation); | 795 | tio = GNUNET_new (struct TicketIssueOperation); |
806 | attrs_len = ntohs (im->attr_len); | 796 | attrs_len = ntohs (im->attr_len); |
807 | attrs = GNUNET_RECLAIM_attribute_list_deserialize (buf, | 797 | attrs = GNUNET_RECLAIM_attribute_list_deserialize (buf, |
@@ -815,7 +805,7 @@ handle_issue_ticket_message (void *cls, const struct IssueTicketMessage *im) | |||
815 | GNUNET_CONTAINER_DLL_insert (idp->issue_op_head, idp->issue_op_tail, tio); | 805 | GNUNET_CONTAINER_DLL_insert (idp->issue_op_head, idp->issue_op_tail, tio); |
816 | RECLAIM_TICKETS_issue (&identity, | 806 | RECLAIM_TICKETS_issue (&identity, |
817 | attrs, | 807 | attrs, |
818 | &rp, | 808 | rp, |
819 | &issue_ticket_result_cb, | 809 | &issue_ticket_result_cb, |
820 | tio); | 810 | tio); |
821 | GNUNET_SERVICE_client_continue (idp->client); | 811 | GNUNET_SERVICE_client_continue (idp->client); |
@@ -893,9 +883,8 @@ handle_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *rm) | |||
893 | struct TicketRevocationOperation *rop; | 883 | struct TicketRevocationOperation *rop; |
894 | struct IdpClient *idp = cls; | 884 | struct IdpClient *idp = cls; |
895 | struct GNUNET_CRYPTO_PrivateKey identity; | 885 | struct GNUNET_CRYPTO_PrivateKey identity; |
896 | struct GNUNET_RECLAIM_Ticket ticket; | 886 | struct GNUNET_RECLAIM_Ticket *ticket; |
897 | size_t key_len; | 887 | size_t key_len; |
898 | size_t tkt_len; | ||
899 | size_t read; | 888 | size_t read; |
900 | char *buf; | 889 | char *buf; |
901 | 890 | ||
@@ -913,23 +902,13 @@ handle_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *rm) | |||
913 | return; | 902 | return; |
914 | } | 903 | } |
915 | buf += read; | 904 | buf += read; |
916 | tkt_len = ntohs (rm->tkt_len); | 905 | ticket = (struct GNUNET_RECLAIM_Ticket *) buf; |
917 | if ((GNUNET_SYSERR == | ||
918 | GNUNET_RECLAIM_read_ticket_from_buffer (buf, tkt_len, | ||
919 | &ticket, &read)) || | ||
920 | (read != tkt_len)) | ||
921 | { | ||
922 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
923 | "Failed to read ticket\n"); | ||
924 | GNUNET_SERVICE_client_drop (idp->client); | ||
925 | return; | ||
926 | } | ||
927 | rop = GNUNET_new (struct TicketRevocationOperation); | 906 | rop = GNUNET_new (struct TicketRevocationOperation); |
928 | rop->r_id = ntohl (rm->id); | 907 | rop->r_id = ntohl (rm->id); |
929 | rop->client = idp; | 908 | rop->client = idp; |
930 | GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head, idp->revoke_op_tail, rop); | 909 | GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head, idp->revoke_op_tail, rop); |
931 | rop->rh | 910 | rop->rh |
932 | = RECLAIM_TICKETS_revoke (&ticket, &identity, &revoke_result_cb, rop); | 911 | = RECLAIM_TICKETS_revoke (ticket, &identity, &revoke_result_cb, rop); |
933 | GNUNET_SERVICE_client_continue (idp->client); | 912 | GNUNET_SERVICE_client_continue (idp->client); |
934 | } | 913 | } |
935 | 914 | ||
@@ -1005,9 +984,13 @@ static int | |||
1005 | check_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm) | 984 | check_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm) |
1006 | { | 985 | { |
1007 | uint16_t size; | 986 | uint16_t size; |
987 | uint16_t tkt_size; | ||
988 | uint16_t rp_uri_size; | ||
1008 | 989 | ||
1009 | size = ntohs (cm->header.size); | 990 | size = ntohs (cm->header.size); |
1010 | if (size <= sizeof(struct ConsumeTicketMessage)) | 991 | tkt_size = ntohs (cm->tkt_len); |
992 | rp_uri_size = ntohs (cm->rp_uri_len); | ||
993 | if (size < sizeof(struct ConsumeTicketMessage) + tkt_size + rp_uri_size) | ||
1011 | { | 994 | { |
1012 | GNUNET_break (0); | 995 | GNUNET_break (0); |
1013 | return GNUNET_SYSERR; | 996 | return GNUNET_SYSERR; |
@@ -1027,43 +1010,21 @@ handle_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm) | |||
1027 | { | 1010 | { |
1028 | struct ConsumeTicketOperation *cop; | 1011 | struct ConsumeTicketOperation *cop; |
1029 | struct IdpClient *idp = cls; | 1012 | struct IdpClient *idp = cls; |
1030 | struct GNUNET_CRYPTO_PrivateKey identity; | 1013 | struct GNUNET_RECLAIM_Ticket *ticket; |
1031 | struct GNUNET_RECLAIM_Ticket ticket; | ||
1032 | size_t key_len; | ||
1033 | size_t tkt_len; | ||
1034 | size_t read; | ||
1035 | char *buf; | 1014 | char *buf; |
1015 | const char *rp_uri; | ||
1036 | 1016 | ||
1037 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CONSUME_TICKET message\n"); | 1017 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CONSUME_TICKET message\n"); |
1038 | key_len = ntohs (cm->key_len); | 1018 | buf = (char*) &cm[1]; |
1039 | buf = (char *) &cm[1]; | 1019 | ticket = (struct GNUNET_RECLAIM_Ticket *) buf; |
1040 | if ((GNUNET_SYSERR == | 1020 | rp_uri = buf + ntohs (cm->tkt_len); |
1041 | GNUNET_CRYPTO_read_private_key_from_buffer (buf, key_len, | ||
1042 | &identity, &read)) || | ||
1043 | (read != key_len)) | ||
1044 | { | ||
1045 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1046 | "Failed to read private key\n"); | ||
1047 | GNUNET_SERVICE_client_drop (idp->client); | ||
1048 | return; | ||
1049 | } | ||
1050 | buf += read; | ||
1051 | tkt_len = ntohs (cm->tkt_len); | ||
1052 | if ((GNUNET_SYSERR == | ||
1053 | GNUNET_RECLAIM_read_ticket_from_buffer (buf, tkt_len, | ||
1054 | &ticket, &read)) || | ||
1055 | (read != tkt_len)) | ||
1056 | { | ||
1057 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1058 | "Failed to read ticket\n"); | ||
1059 | GNUNET_SERVICE_client_drop (idp->client); | ||
1060 | return; | ||
1061 | } | ||
1062 | cop = GNUNET_new (struct ConsumeTicketOperation); | 1021 | cop = GNUNET_new (struct ConsumeTicketOperation); |
1063 | cop->r_id = ntohl (cm->id); | 1022 | cop->r_id = ntohl (cm->id); |
1064 | cop->client = idp; | 1023 | cop->client = idp; |
1065 | cop->ch | 1024 | cop->ch |
1066 | = RECLAIM_TICKETS_consume (&identity, &ticket, &consume_result_cb, | 1025 | = RECLAIM_TICKETS_consume (ticket, |
1026 | rp_uri, | ||
1027 | &consume_result_cb, | ||
1067 | cop); | 1028 | cop); |
1068 | GNUNET_CONTAINER_DLL_insert (idp->consume_op_head, idp->consume_op_tail, cop); | 1029 | GNUNET_CONTAINER_DLL_insert (idp->consume_op_head, idp->consume_op_tail, cop); |
1069 | GNUNET_SERVICE_client_continue (idp->client); | 1030 | GNUNET_SERVICE_client_continue (idp->client); |
@@ -2485,27 +2446,27 @@ handle_credential_iteration_next (void *cls, | |||
2485 | * Ticket iteration | 2446 | * Ticket iteration |
2486 | ******************************************************/ | 2447 | ******************************************************/ |
2487 | 2448 | ||
2488 | /** | ||
2489 | * Got a ticket. Return to client | ||
2490 | * | ||
2491 | * @param cls our ticket iterator | ||
2492 | * @param ticket the ticket | ||
2493 | */ | ||
2494 | static void | 2449 | static void |
2495 | ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket) | 2450 | ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket, const char* |
2451 | rp_uri) | ||
2496 | { | 2452 | { |
2497 | struct TicketIteration *ti = cls; | 2453 | struct TicketIteration *ti = cls; |
2498 | struct GNUNET_MQ_Envelope *env; | 2454 | struct GNUNET_MQ_Envelope *env; |
2499 | struct TicketResultMessage *trm; | 2455 | struct TicketResultMessage *trm; |
2500 | size_t tkt_len; | 2456 | size_t tkt_len; |
2457 | size_t rp_uri_len; | ||
2501 | 2458 | ||
2502 | if (NULL == ticket) | 2459 | if (NULL == ticket) |
2503 | tkt_len = 0; | 2460 | tkt_len = 0; |
2504 | else | 2461 | else |
2505 | tkt_len = GNUNET_RECLAIM_ticket_serialize_get_size (ticket); | 2462 | tkt_len = strlen (ticket->gns_name) + 1; |
2506 | 2463 | ||
2464 | if (NULL == rp_uri) | ||
2465 | rp_uri_len = 0; | ||
2466 | else | ||
2467 | rp_uri_len = strlen (rp_uri) + 1; | ||
2507 | env = GNUNET_MQ_msg_extra (trm, | 2468 | env = GNUNET_MQ_msg_extra (trm, |
2508 | tkt_len, | 2469 | tkt_len + rp_uri_len, |
2509 | GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); | 2470 | GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); |
2510 | if (NULL == ticket) | 2471 | if (NULL == ticket) |
2511 | { | 2472 | { |
@@ -2516,13 +2477,13 @@ ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket) | |||
2516 | } | 2477 | } |
2517 | else | 2478 | else |
2518 | { | 2479 | { |
2519 | GNUNET_RECLAIM_write_ticket_to_buffer (ticket, | 2480 | memcpy (&trm[1], ticket, tkt_len); |
2520 | &trm[1], | ||
2521 | tkt_len); | ||
2522 | } | 2481 | } |
2482 | memcpy ((char*) &trm[1] + tkt_len, rp_uri, rp_uri_len); | ||
2523 | trm->id = htonl (ti->r_id); | 2483 | trm->id = htonl (ti->r_id); |
2524 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n"); | 2484 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n"); |
2525 | trm->tkt_len = htons (tkt_len); | 2485 | trm->tkt_len = htons (tkt_len); |
2486 | trm->rp_uri_len = htons (rp_uri_len); | ||
2526 | trm->presentations_len = htons (0); | 2487 | trm->presentations_len = htons (0); |
2527 | GNUNET_MQ_send (ti->client->mq, env); | 2488 | GNUNET_MQ_send (ti->client->mq, env); |
2528 | if (NULL == ticket) | 2489 | if (NULL == ticket) |
diff --git a/src/service/reclaim/gnunet-service-reclaim_tickets.c b/src/service/reclaim/gnunet-service-reclaim_tickets.c index acd2b6859..e7e32eec3 100644 --- a/src/service/reclaim/gnunet-service-reclaim_tickets.c +++ b/src/service/reclaim/gnunet-service-reclaim_tickets.c | |||
@@ -25,6 +25,11 @@ | |||
25 | * | 25 | * |
26 | */ | 26 | */ |
27 | #include "gnunet-service-reclaim_tickets.h" | 27 | #include "gnunet-service-reclaim_tickets.h" |
28 | #include "gnunet_common.h" | ||
29 | #include "gnunet_gns_service.h" | ||
30 | #include "gnunet_gnsrecord_lib.h" | ||
31 | #include "gnunet_reclaim_service.h" | ||
32 | #include <string.h> | ||
28 | 33 | ||
29 | 34 | ||
30 | /** | 35 | /** |
@@ -80,17 +85,7 @@ struct RECLAIM_TICKETS_ConsumeHandle | |||
80 | /** | 85 | /** |
81 | * LookupRequest | 86 | * LookupRequest |
82 | */ | 87 | */ |
83 | struct GNUNET_GNS_LookupRequest *lookup_request; | 88 | struct GNUNET_GNS_LookupWithTldRequest *lookup_request; |
84 | |||
85 | /** | ||
86 | * Audience Key | ||
87 | */ | ||
88 | struct GNUNET_CRYPTO_PrivateKey identity; | ||
89 | |||
90 | /** | ||
91 | * Audience Key | ||
92 | */ | ||
93 | struct GNUNET_CRYPTO_PublicKey identity_pub; | ||
94 | 89 | ||
95 | /** | 90 | /** |
96 | * Lookup DLL | 91 | * Lookup DLL |
@@ -131,6 +126,13 @@ struct RECLAIM_TICKETS_ConsumeHandle | |||
131 | * Callback closure | 126 | * Callback closure |
132 | */ | 127 | */ |
133 | void *cb_cls; | 128 | void *cb_cls; |
129 | |||
130 | /** | ||
131 | * The ticket audience (= relying party) URI. | ||
132 | * 0-terminated string. | ||
133 | * Example: "urn:gns:000G002B4RF1XPBXDPGZA0PT16BHQCS427YQK4NC84KZMK7TK8C2Z5GMK8" | ||
134 | */ | ||
135 | char rp_uri[GNUNET_RECLAIM_TICKET_RP_URI_MAX_LEN]; | ||
134 | }; | 136 | }; |
135 | 137 | ||
136 | 138 | ||
@@ -205,6 +207,18 @@ struct TicketIssueHandle | |||
205 | * Callback cls | 207 | * Callback cls |
206 | */ | 208 | */ |
207 | void *cb_cls; | 209 | void *cb_cls; |
210 | |||
211 | /** | ||
212 | * The ticket audience (= relying party) URI. | ||
213 | * 0-terminated string. | ||
214 | * Example: "urn:gns:000G002B4RF1XPBXDPGZA0PT16BHQCS427YQK4NC84KZMK7TK8C2Z5GMK8" | ||
215 | */ | ||
216 | char rp_uri[GNUNET_RECLAIM_TICKET_RP_URI_MAX_LEN]; | ||
217 | |||
218 | /** | ||
219 | * The ticket random identifier | ||
220 | */ | ||
221 | struct GNUNET_RECLAIM_Identifier rnd; | ||
208 | }; | 222 | }; |
209 | 223 | ||
210 | 224 | ||
@@ -913,17 +927,17 @@ RECLAIM_TICKETS_revoke (const struct GNUNET_RECLAIM_Ticket *ticket, | |||
913 | { | 927 | { |
914 | struct RECLAIM_TICKETS_RevokeHandle *rvk; | 928 | struct RECLAIM_TICKETS_RevokeHandle *rvk; |
915 | char *label; | 929 | char *label; |
930 | char *tmp; | ||
916 | 931 | ||
917 | rvk = GNUNET_new (struct RECLAIM_TICKETS_RevokeHandle); | 932 | rvk = GNUNET_new (struct RECLAIM_TICKETS_RevokeHandle); |
918 | rvk->cb = cb; | 933 | rvk->cb = cb; |
919 | rvk->cb_cls = cb_cls; | 934 | rvk->cb_cls = cb_cls; |
920 | rvk->identity = *identity; | 935 | rvk->identity = *identity; |
921 | rvk->ticket = *ticket; | 936 | rvk->ticket = *ticket; |
922 | GNUNET_CRYPTO_key_get_public (&rvk->identity, &rvk->ticket.identity); | 937 | tmp = GNUNET_strdup (ticket->gns_name); |
923 | /** Get shared attributes **/ | 938 | label = strtok (tmp, "."); |
924 | label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, | ||
925 | sizeof(ticket->rnd)); | ||
926 | GNUNET_assert (NULL != label); | 939 | GNUNET_assert (NULL != label); |
940 | /** Get shared attributes **/ | ||
927 | rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh, | 941 | rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh, |
928 | identity, | 942 | identity, |
929 | label, | 943 | label, |
@@ -931,7 +945,7 @@ RECLAIM_TICKETS_revoke (const struct GNUNET_RECLAIM_Ticket *ticket, | |||
931 | rvk, | 945 | rvk, |
932 | &revoke_attrs_cb, | 946 | &revoke_attrs_cb, |
933 | rvk); | 947 | rvk); |
934 | GNUNET_free (label); | 948 | GNUNET_free (tmp); |
935 | return rvk; | 949 | return rvk; |
936 | } | 950 | } |
937 | 951 | ||
@@ -964,7 +978,7 @@ cleanup_cth (struct RECLAIM_TICKETS_ConsumeHandle *cth) | |||
964 | struct ParallelLookup *lu; | 978 | struct ParallelLookup *lu; |
965 | 979 | ||
966 | if (NULL != cth->lookup_request) | 980 | if (NULL != cth->lookup_request) |
967 | GNUNET_GNS_lookup_cancel (cth->lookup_request); | 981 | GNUNET_GNS_lookup_with_tld_cancel (cth->lookup_request); |
968 | if (NULL != cth->kill_task) | 982 | if (NULL != cth->kill_task) |
969 | GNUNET_SCHEDULER_cancel (cth->kill_task); | 983 | GNUNET_SCHEDULER_cancel (cth->kill_task); |
970 | while (NULL != (lu = cth->parallel_lookups_head)) | 984 | while (NULL != (lu = cth->parallel_lookups_head)) |
@@ -986,13 +1000,6 @@ cleanup_cth (struct RECLAIM_TICKETS_ConsumeHandle *cth) | |||
986 | } | 1000 | } |
987 | 1001 | ||
988 | 1002 | ||
989 | /** | ||
990 | * We found an attribute record. | ||
991 | * | ||
992 | * @param cls handle to the operation | ||
993 | * @param rd_count size of record set | ||
994 | * @param rd record set | ||
995 | */ | ||
996 | static void | 1003 | static void |
997 | process_parallel_lookup_result (void *cls, | 1004 | process_parallel_lookup_result (void *cls, |
998 | uint32_t rd_count, | 1005 | uint32_t rd_count, |
@@ -1001,6 +1008,7 @@ process_parallel_lookup_result (void *cls, | |||
1001 | struct ParallelLookup *parallel_lookup = cls; | 1008 | struct ParallelLookup *parallel_lookup = cls; |
1002 | struct RECLAIM_TICKETS_ConsumeHandle *cth = parallel_lookup->handle; | 1009 | struct RECLAIM_TICKETS_ConsumeHandle *cth = parallel_lookup->handle; |
1003 | struct GNUNET_RECLAIM_AttributeListEntry *attr_le; | 1010 | struct GNUNET_RECLAIM_AttributeListEntry *attr_le; |
1011 | struct GNUNET_CRYPTO_PublicKey iss; | ||
1004 | 1012 | ||
1005 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1013 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1006 | "Parallel lookup finished (count=%u)\n", | 1014 | "Parallel lookup finished (count=%u)\n", |
@@ -1038,7 +1046,9 @@ process_parallel_lookup_result (void *cls, | |||
1038 | if (NULL != cth->parallel_lookups_head) | 1046 | if (NULL != cth->parallel_lookups_head) |
1039 | return; // Wait for more | 1047 | return; // Wait for more |
1040 | /* Else we are done */ | 1048 | /* Else we are done */ |
1041 | cth->cb (cth->cb_cls, &cth->ticket.identity, | 1049 | GNUNET_assert (GNUNET_OK == GNUNET_GNS_parse_ztld (cth->ticket.gns_name, &iss) |
1050 | ); | ||
1051 | cth->cb (cth->cb_cls, &iss, | ||
1042 | cth->attrs, cth->presentations, GNUNET_OK, NULL); | 1052 | cth->attrs, cth->presentations, GNUNET_OK, NULL); |
1043 | cleanup_cth (cth); | 1053 | cleanup_cth (cth); |
1044 | } | 1054 | } |
@@ -1072,27 +1082,22 @@ abort_parallel_lookups (void *cls) | |||
1072 | } | 1082 | } |
1073 | 1083 | ||
1074 | 1084 | ||
1075 | /** | ||
1076 | * GNS result with attribute references. | ||
1077 | * For each result, we start a (parallel) lookup of the actual | ||
1078 | * attribute record under the referenced label. | ||
1079 | * | ||
1080 | * @param cls handle to the operation | ||
1081 | * @param rd_count size of the record set | ||
1082 | * @param rd record set | ||
1083 | */ | ||
1084 | static void | 1085 | static void |
1085 | lookup_authz_cb (void *cls, | 1086 | lookup_authz_cb (void *cls, |
1087 | int is_gns, | ||
1086 | uint32_t rd_count, | 1088 | uint32_t rd_count, |
1087 | const struct GNUNET_GNSRECORD_Data *rd) | 1089 | const struct GNUNET_GNSRECORD_Data *rd) |
1088 | { | 1090 | { |
1089 | struct RECLAIM_TICKETS_ConsumeHandle *cth = cls; | 1091 | struct RECLAIM_TICKETS_ConsumeHandle *cth = cls; |
1092 | struct GNUNET_CRYPTO_PublicKey iss; | ||
1090 | struct ParallelLookup *parallel_lookup; | 1093 | struct ParallelLookup *parallel_lookup; |
1094 | const char *rp_uri = NULL; | ||
1091 | char *lbl; | 1095 | char *lbl; |
1092 | struct GNUNET_RECLAIM_PresentationListEntry *ale; | 1096 | struct GNUNET_RECLAIM_PresentationListEntry *ale; |
1093 | 1097 | ||
1094 | cth->lookup_request = NULL; | 1098 | cth->lookup_request = NULL; |
1095 | 1099 | ||
1100 | GNUNET_assert (GNUNET_YES == is_gns); | ||
1096 | GNUNET_STATISTICS_update (stats, | 1101 | GNUNET_STATISTICS_update (stats, |
1097 | "reclaim_authz_lookup_time_total", | 1102 | "reclaim_authz_lookup_time_total", |
1098 | GNUNET_TIME_absolute_get_duration ( | 1103 | GNUNET_TIME_absolute_get_duration ( |
@@ -1104,6 +1109,8 @@ lookup_authz_cb (void *cls, | |||
1104 | 1, | 1109 | 1, |
1105 | GNUNET_YES); | 1110 | GNUNET_YES); |
1106 | 1111 | ||
1112 | GNUNET_assert (GNUNET_OK | ||
1113 | == GNUNET_GNS_parse_ztld (cth->ticket.gns_name, &iss)); | ||
1107 | for (int i = 0; i < rd_count; i++) | 1114 | for (int i = 0; i < rd_count; i++) |
1108 | { | 1115 | { |
1109 | /** | 1116 | /** |
@@ -1112,6 +1119,9 @@ lookup_authz_cb (void *cls, | |||
1112 | */ | 1119 | */ |
1113 | switch (rd[i].record_type) | 1120 | switch (rd[i].record_type) |
1114 | { | 1121 | { |
1122 | case GNUNET_DNSPARSER_TYPE_TXT: | ||
1123 | rp_uri = rd[i].data; | ||
1124 | break; | ||
1115 | case GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION: | 1125 | case GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION: |
1116 | ale = GNUNET_new (struct GNUNET_RECLAIM_PresentationListEntry); | 1126 | ale = GNUNET_new (struct GNUNET_RECLAIM_PresentationListEntry); |
1117 | ale->presentation = | 1127 | ale->presentation = |
@@ -1131,7 +1141,7 @@ lookup_authz_cb (void *cls, | |||
1131 | parallel_lookup->lookup_request = | 1141 | parallel_lookup->lookup_request = |
1132 | GNUNET_GNS_lookup (gns, | 1142 | GNUNET_GNS_lookup (gns, |
1133 | lbl, | 1143 | lbl, |
1134 | &cth->ticket.identity, | 1144 | &iss, |
1135 | GNUNET_GNSRECORD_TYPE_ANY, | 1145 | GNUNET_GNSRECORD_TYPE_ANY, |
1136 | GNUNET_GNS_LO_DEFAULT, | 1146 | GNUNET_GNS_LO_DEFAULT, |
1137 | &process_parallel_lookup_result, | 1147 | &process_parallel_lookup_result, |
@@ -1145,6 +1155,31 @@ lookup_authz_cb (void *cls, | |||
1145 | "Ignoring unknown record type %d", rd[i].record_type); | 1155 | "Ignoring unknown record type %d", rd[i].record_type); |
1146 | } | 1156 | } |
1147 | } | 1157 | } |
1158 | if (NULL == rp_uri) | ||
1159 | { | ||
1160 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1161 | "RP URI not found along references, ignoring...\n"); | ||
1162 | /** | ||
1163 | * Return error | ||
1164 | */ | ||
1165 | cth->cb (cth->cb_cls, &iss, | ||
1166 | cth->attrs, NULL, GNUNET_NO, NULL); | ||
1167 | cleanup_cth (cth); | ||
1168 | return; | ||
1169 | } | ||
1170 | if (0 != strcmp (rp_uri, cth->rp_uri)) | ||
1171 | { | ||
1172 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1173 | "RP URI does not match consume request: `%s' != `%s'\n", | ||
1174 | rp_uri, cth->rp_uri); | ||
1175 | /** | ||
1176 | * Return error | ||
1177 | */ | ||
1178 | cth->cb (cth->cb_cls, &iss, | ||
1179 | cth->attrs, NULL, GNUNET_NO, NULL); | ||
1180 | cleanup_cth (cth); | ||
1181 | return; | ||
1182 | } | ||
1148 | /** | 1183 | /** |
1149 | * We started lookups. Add a timeout task. | 1184 | * We started lookups. Add a timeout task. |
1150 | * FIXME: Really needed here? | 1185 | * FIXME: Really needed here? |
@@ -1160,7 +1195,7 @@ lookup_authz_cb (void *cls, | |||
1160 | /** | 1195 | /** |
1161 | * No references found, return empty attribute list | 1196 | * No references found, return empty attribute list |
1162 | */ | 1197 | */ |
1163 | cth->cb (cth->cb_cls, &cth->ticket.identity, | 1198 | cth->cb (cth->cb_cls, &iss, |
1164 | cth->attrs, NULL, GNUNET_OK, NULL); | 1199 | cth->attrs, NULL, GNUNET_OK, NULL); |
1165 | cleanup_cth (cth); | 1200 | cleanup_cth (cth); |
1166 | } | 1201 | } |
@@ -1178,41 +1213,29 @@ lookup_authz_cb (void *cls, | |||
1178 | * @return handle to the operation | 1213 | * @return handle to the operation |
1179 | */ | 1214 | */ |
1180 | struct RECLAIM_TICKETS_ConsumeHandle * | 1215 | struct RECLAIM_TICKETS_ConsumeHandle * |
1181 | RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_PrivateKey *id, | 1216 | RECLAIM_TICKETS_consume (const struct GNUNET_RECLAIM_Ticket *ticket, |
1182 | const struct GNUNET_RECLAIM_Ticket *ticket, | 1217 | const char *rp_uri, |
1183 | RECLAIM_TICKETS_ConsumeCallback cb, | 1218 | RECLAIM_TICKETS_ConsumeCallback cb, |
1184 | void *cb_cls) | 1219 | void *cb_cls) |
1185 | { | 1220 | { |
1186 | struct RECLAIM_TICKETS_ConsumeHandle *cth; | 1221 | struct RECLAIM_TICKETS_ConsumeHandle *cth; |
1187 | char *label; | ||
1188 | 1222 | ||
1189 | cth = GNUNET_new (struct RECLAIM_TICKETS_ConsumeHandle); | 1223 | cth = GNUNET_new (struct RECLAIM_TICKETS_ConsumeHandle); |
1190 | 1224 | ||
1191 | cth->identity = *id; | ||
1192 | GNUNET_CRYPTO_key_get_public (&cth->identity, &cth->identity_pub); | ||
1193 | cth->attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); | 1225 | cth->attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); |
1194 | cth->presentations = GNUNET_new (struct GNUNET_RECLAIM_PresentationList); | 1226 | cth->presentations = GNUNET_new (struct GNUNET_RECLAIM_PresentationList); |
1195 | cth->ticket = *ticket; | 1227 | cth->ticket = *ticket; |
1228 | memcpy (cth->rp_uri, rp_uri, strlen (rp_uri) + 1); | ||
1196 | cth->cb = cb; | 1229 | cth->cb = cb; |
1197 | cth->cb_cls = cb_cls; | 1230 | cth->cb_cls = cb_cls; |
1198 | label = | ||
1199 | GNUNET_STRINGS_data_to_string_alloc (&cth->ticket.rnd, | ||
1200 | sizeof(cth->ticket.rnd)); | ||
1201 | char *str = GNUNET_CRYPTO_public_key_to_string (&cth->ticket.identity); | ||
1202 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1203 | "Looking for AuthZ info under %s in %s\n", | ||
1204 | label, str); | ||
1205 | GNUNET_free (str); | ||
1206 | cth->lookup_start_time = GNUNET_TIME_absolute_get (); | 1231 | cth->lookup_start_time = GNUNET_TIME_absolute_get (); |
1207 | cth->lookup_request = | 1232 | cth->lookup_request = |
1208 | GNUNET_GNS_lookup (gns, | 1233 | GNUNET_GNS_lookup_with_tld (gns, |
1209 | label, | 1234 | ticket->gns_name, |
1210 | &cth->ticket.identity, | 1235 | GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF, |
1211 | GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF, | 1236 | GNUNET_GNS_LO_DEFAULT, |
1212 | GNUNET_GNS_LO_DEFAULT, | 1237 | &lookup_authz_cb, |
1213 | &lookup_authz_cb, | 1238 | cth); |
1214 | cth); | ||
1215 | GNUNET_free (label); | ||
1216 | return cth; | 1239 | return cth; |
1217 | } | 1240 | } |
1218 | 1241 | ||
@@ -1300,9 +1323,11 @@ issue_ticket (struct TicketIssueHandle *ih) | |||
1300 | for (le = ih->attrs->list_head; NULL != le; le = le->next) | 1323 | for (le = ih->attrs->list_head; NULL != le; le = le->next) |
1301 | attrs_count++; | 1324 | attrs_count++; |
1302 | 1325 | ||
1303 | // Worst case we have one presentation per attribute | 1326 | // Worst case we have one presentation per attribute plus the ticket |
1327 | // plus the RP URI record | ||
1304 | attrs_record = | 1328 | attrs_record = |
1305 | GNUNET_malloc (2 * attrs_count * sizeof(struct GNUNET_GNSRECORD_Data)); | 1329 | GNUNET_malloc ((2 * attrs_count + 2) * sizeof(struct GNUNET_GNSRECORD_Data)) |
1330 | ; | ||
1306 | i = 0; | 1331 | i = 0; |
1307 | for (le = ih->attrs->list_head; NULL != le; le = le->next) | 1332 | for (le = ih->attrs->list_head; NULL != le; le = le->next) |
1308 | { | 1333 | { |
@@ -1380,29 +1405,39 @@ issue_ticket (struct TicketIssueHandle *ih) | |||
1380 | } | 1405 | } |
1381 | } | 1406 | } |
1382 | } | 1407 | } |
1383 | attrs_record[i].data_size = | ||
1384 | GNUNET_RECLAIM_ticket_serialize_get_size (&ih->ticket); | ||
1385 | tkt_data = GNUNET_malloc (attrs_record[i].data_size); | ||
1386 | GNUNET_RECLAIM_write_ticket_to_buffer (&ih->ticket, | ||
1387 | tkt_data, | ||
1388 | attrs_record[i].data_size); | ||
1389 | attrs_record[i].data = tkt_data; | ||
1390 | attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us; | ||
1391 | attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET; | ||
1392 | attrs_record[i].flags = | ||
1393 | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE; | ||
1394 | i++; | ||
1395 | 1408 | ||
1396 | label = | 1409 | label = |
1397 | GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, | 1410 | GNUNET_STRINGS_data_to_string_alloc (&ih->rnd, |
1398 | sizeof(ih->ticket.rnd)); | 1411 | sizeof(ih->rnd)); |
1399 | struct GNUNET_CRYPTO_PublicKey pub; | 1412 | struct GNUNET_CRYPTO_PublicKey pub; |
1400 | GNUNET_CRYPTO_key_get_public (&ih->identity, | 1413 | GNUNET_CRYPTO_key_get_public (&ih->identity, |
1401 | &pub); | 1414 | &pub); |
1402 | char *str = GNUNET_CRYPTO_public_key_to_string (&pub); | 1415 | char *str = GNUNET_CRYPTO_public_key_to_string (&pub); |
1403 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1416 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1404 | "Storing AuthZ information under %s in %s\n", label, str); | 1417 | "Storing AuthZ information under %s in %s\n", label, str); |
1418 | sprintf (ih->ticket.gns_name, "%s.%s", label, str); | ||
1405 | GNUNET_free (str); | 1419 | GNUNET_free (str); |
1420 | |||
1421 | attrs_record[i].data_size = | ||
1422 | strlen (ih->ticket.gns_name) + 1; | ||
1423 | tkt_data = GNUNET_malloc (attrs_record[i].data_size); | ||
1424 | memcpy (tkt_data, &ih->ticket, attrs_record[i].data_size); | ||
1425 | // The ticket: Could be removed? | ||
1426 | attrs_record[i].data = tkt_data; | ||
1427 | attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us; | ||
1428 | attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET; | ||
1429 | attrs_record[i].flags = | ||
1430 | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE; | ||
1431 | i++; | ||
1432 | // The RP URI | ||
1433 | attrs_record[i].data_size = strlen (ih->rp_uri); | ||
1434 | attrs_record[i].data = ih->rp_uri; | ||
1435 | attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us; | ||
1436 | attrs_record[i].record_type = GNUNET_DNSPARSER_TYPE_TXT; | ||
1437 | attrs_record[i].flags = | ||
1438 | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
1439 | i++; | ||
1440 | |||
1406 | // Publish record | 1441 | // Publish record |
1407 | ih->ns_qe = GNUNET_NAMESTORE_record_set_store (nsh, | 1442 | ih->ns_qe = GNUNET_NAMESTORE_record_set_store (nsh, |
1408 | &ih->identity, | 1443 | &ih->identity, |
@@ -1471,7 +1506,7 @@ filter_tickets_cb (void *cls, | |||
1471 | const struct GNUNET_GNSRECORD_Data *rd) | 1506 | const struct GNUNET_GNSRECORD_Data *rd) |
1472 | { | 1507 | { |
1473 | struct TicketIssueHandle *tih = cls; | 1508 | struct TicketIssueHandle *tih = cls; |
1474 | struct GNUNET_RECLAIM_Ticket ticket; | 1509 | struct GNUNET_RECLAIM_Ticket *ticket; |
1475 | struct GNUNET_RECLAIM_Presentation *presentation; | 1510 | struct GNUNET_RECLAIM_Presentation *presentation; |
1476 | struct GNUNET_RECLAIM_PresentationList *ticket_presentations; | 1511 | struct GNUNET_RECLAIM_PresentationList *ticket_presentations; |
1477 | struct GNUNET_RECLAIM_Credential *cred; | 1512 | struct GNUNET_RECLAIM_Credential *cred; |
@@ -1480,6 +1515,7 @@ filter_tickets_cb (void *cls, | |||
1480 | unsigned int attr_cnt = 0; | 1515 | unsigned int attr_cnt = 0; |
1481 | unsigned int pres_cnt = 0; | 1516 | unsigned int pres_cnt = 0; |
1482 | int ticket_found = GNUNET_NO; | 1517 | int ticket_found = GNUNET_NO; |
1518 | int rp_uri_matches = GNUNET_NO; | ||
1483 | 1519 | ||
1484 | for (le = tih->attrs->list_head; NULL != le; le = le->next) | 1520 | for (le = tih->attrs->list_head; NULL != le; le = le->next) |
1485 | { | 1521 | { |
@@ -1491,7 +1527,6 @@ filter_tickets_cb (void *cls, | |||
1491 | // ticket search | 1527 | // ticket search |
1492 | unsigned int found_attrs_cnt = 0; | 1528 | unsigned int found_attrs_cnt = 0; |
1493 | unsigned int found_pres_cnt = 0; | 1529 | unsigned int found_pres_cnt = 0; |
1494 | size_t read; | ||
1495 | ticket_presentations = GNUNET_new (struct GNUNET_RECLAIM_PresentationList); | 1530 | ticket_presentations = GNUNET_new (struct GNUNET_RECLAIM_PresentationList); |
1496 | 1531 | ||
1497 | for (int i = 0; i < rd_count; i++) | 1532 | for (int i = 0; i < rd_count; i++) |
@@ -1499,30 +1534,19 @@ filter_tickets_cb (void *cls, | |||
1499 | // found ticket | 1534 | // found ticket |
1500 | if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET == rd[i].record_type) | 1535 | if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET == rd[i].record_type) |
1501 | { | 1536 | { |
1502 | if ((GNUNET_SYSERR == | 1537 | ticket = (struct GNUNET_RECLAIM_Ticket *) rd[i].data; |
1503 | GNUNET_RECLAIM_read_ticket_from_buffer (rd[i].data, | 1538 | tih->ticket = *ticket; |
1504 | rd[i].data_size, | 1539 | ticket_found = GNUNET_YES; |
1505 | &ticket, | 1540 | } |
1506 | &read)) || | 1541 | if (GNUNET_DNSPARSER_TYPE_TXT == rd[i].record_type) |
1507 | (read != rd[i].data_size)) | 1542 | { |
1508 | { | ||
1509 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1510 | "Failed to deserialize ticket from record\n"); | ||
1511 | continue; | ||
1512 | } | ||
1513 | // cmp audience | 1543 | // cmp audience |
1514 | // FIXME this is ugly, GNUNET_CRYPTO_PublicKey cannot be compared | 1544 | if (0 != strncmp (tih->rp_uri, |
1515 | // like this | 1545 | rd[i].data, |
1516 | if (0 == memcmp (&tih->ticket.audience, | 1546 | rd[i].data_size)) |
1517 | &ticket.audience, | ||
1518 | sizeof(struct GNUNET_CRYPTO_PublicKey))) | ||
1519 | { | ||
1520 | tih->ticket = ticket; | ||
1521 | ticket_found = GNUNET_YES; | ||
1522 | continue; | 1547 | continue; |
1523 | } | 1548 | rp_uri_matches = GNUNET_YES; |
1524 | } | 1549 | } |
1525 | |||
1526 | // cmp requested attributes with ticket attributes | 1550 | // cmp requested attributes with ticket attributes |
1527 | if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF == rd[i].record_type) | 1551 | if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF == rd[i].record_type) |
1528 | { | 1552 | { |
@@ -1543,7 +1567,8 @@ filter_tickets_cb (void *cls, | |||
1543 | cred = GNUNET_RECLAIM_credential_deserialize (rd[i].data, | 1567 | cred = GNUNET_RECLAIM_credential_deserialize (rd[i].data, |
1544 | rd[i].data_size); | 1568 | rd[i].data_size); |
1545 | if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (&cred->id, | 1569 | if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (&cred->id, |
1546 | &le->attribute->credential)) | 1570 | &le->attribute->credential |
1571 | )) | ||
1547 | { | 1572 | { |
1548 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1573 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1549 | "No match.\n"); | 1574 | "No match.\n"); |
@@ -1576,7 +1601,8 @@ filter_tickets_cb (void *cls, | |||
1576 | for (le = tih->attrs->list_head; NULL != le; le = le->next) | 1601 | for (le = tih->attrs->list_head; NULL != le; le = le->next) |
1577 | { | 1602 | { |
1578 | presentation = GNUNET_RECLAIM_presentation_deserialize (rd[i].data, | 1603 | presentation = GNUNET_RECLAIM_presentation_deserialize (rd[i].data, |
1579 | rd[i].data_size); | 1604 | rd[i].data_size) |
1605 | ; | ||
1580 | if (NULL == presentation) | 1606 | if (NULL == presentation) |
1581 | { | 1607 | { |
1582 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1608 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
@@ -1604,7 +1630,8 @@ filter_tickets_cb (void *cls, | |||
1604 | */ | 1630 | */ |
1605 | if ((attr_cnt == found_attrs_cnt) && | 1631 | if ((attr_cnt == found_attrs_cnt) && |
1606 | (pres_cnt == found_pres_cnt) && | 1632 | (pres_cnt == found_pres_cnt) && |
1607 | (GNUNET_YES == ticket_found)) | 1633 | (GNUNET_YES == ticket_found) && |
1634 | (GNUNET_YES == rp_uri_matches)) | ||
1608 | { | 1635 | { |
1609 | GNUNET_NAMESTORE_zone_iteration_stop (tih->ns_it); | 1636 | GNUNET_NAMESTORE_zone_iteration_stop (tih->ns_it); |
1610 | tih->cb (tih->cb_cls, &tih->ticket, ticket_presentations, GNUNET_OK, NULL); | 1637 | tih->cb (tih->cb_cls, &tih->ticket, ticket_presentations, GNUNET_OK, NULL); |
@@ -1630,8 +1657,7 @@ filter_tickets_finished_cb (void *cls) | |||
1630 | { | 1657 | { |
1631 | struct TicketIssueHandle *tih = cls; | 1658 | struct TicketIssueHandle *tih = cls; |
1632 | 1659 | ||
1633 | GNUNET_CRYPTO_key_get_public (&tih->identity, &tih->ticket.identity); | 1660 | GNUNET_RECLAIM_id_generate (&tih->rnd); |
1634 | GNUNET_RECLAIM_id_generate (&tih->ticket.rnd); | ||
1635 | issue_ticket (tih); | 1661 | issue_ticket (tih); |
1636 | } | 1662 | } |
1637 | 1663 | ||
@@ -1650,7 +1676,7 @@ filter_tickets_finished_cb (void *cls) | |||
1650 | void | 1676 | void |
1651 | RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_PrivateKey *identity, | 1677 | RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_PrivateKey *identity, |
1652 | const struct GNUNET_RECLAIM_AttributeList *attrs, | 1678 | const struct GNUNET_RECLAIM_AttributeList *attrs, |
1653 | const struct GNUNET_CRYPTO_PublicKey *audience, | 1679 | const char *rp, |
1654 | RECLAIM_TICKETS_TicketResult cb, | 1680 | RECLAIM_TICKETS_TicketResult cb, |
1655 | void *cb_cls) | 1681 | void *cb_cls) |
1656 | { | 1682 | { |
@@ -1662,7 +1688,7 @@ RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_PrivateKey *identity, | |||
1662 | tih->attrs = GNUNET_RECLAIM_attribute_list_dup (attrs); | 1688 | tih->attrs = GNUNET_RECLAIM_attribute_list_dup (attrs); |
1663 | tih->presentations = GNUNET_new (struct GNUNET_RECLAIM_PresentationList); | 1689 | tih->presentations = GNUNET_new (struct GNUNET_RECLAIM_PresentationList); |
1664 | tih->identity = *identity; | 1690 | tih->identity = *identity; |
1665 | tih->ticket.audience = *audience; | 1691 | memcpy (tih->rp_uri, rp, strlen (rp) + 1); |
1666 | 1692 | ||
1667 | // First check whether the ticket has already been issued | 1693 | // First check whether the ticket has already been issued |
1668 | tih->ns_it = | 1694 | tih->ns_it = |
@@ -1714,27 +1740,23 @@ collect_tickets_cb (void *cls, | |||
1714 | const struct GNUNET_GNSRECORD_Data *rd) | 1740 | const struct GNUNET_GNSRECORD_Data *rd) |
1715 | { | 1741 | { |
1716 | struct RECLAIM_TICKETS_Iterator *iter = cls; | 1742 | struct RECLAIM_TICKETS_Iterator *iter = cls; |
1717 | struct GNUNET_RECLAIM_Ticket ticket; | 1743 | struct GNUNET_RECLAIM_Ticket *ticket; |
1718 | size_t read; | 1744 | int ticket_found = GNUNET_NO; |
1745 | const char *rp_uri = NULL; | ||
1719 | 1746 | ||
1720 | for (int i = 0; i < rd_count; i++) | 1747 | for (int i = 0; i < rd_count; i++) |
1721 | { | 1748 | { |
1749 | if (GNUNET_DNSPARSER_TYPE_TXT == rd[i].record_type) | ||
1750 | rp_uri = rd[i].data; | ||
1722 | if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET != rd[i].record_type) | 1751 | if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET != rd[i].record_type) |
1723 | continue; | 1752 | continue; |
1724 | if ((GNUNET_SYSERR == | 1753 | if ((GNUNET_YES == ticket_found) && (NULL != rp_uri)) |
1725 | GNUNET_RECLAIM_read_ticket_from_buffer (rd[i].data, | 1754 | break; |
1726 | rd[i].data_size, | 1755 | ticket = (struct GNUNET_RECLAIM_Ticket *) rd[i].data; |
1727 | &ticket, | 1756 | ticket_found = GNUNET_YES; |
1728 | &read)) || | ||
1729 | (read != rd[i].data_size)) | ||
1730 | { | ||
1731 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1732 | "Failed to deserialize ticket from record\n"); | ||
1733 | continue; | ||
1734 | } | ||
1735 | iter->cb (iter->cb_cls, &ticket); | ||
1736 | return; | ||
1737 | } | 1757 | } |
1758 | if ((GNUNET_YES == ticket_found) && (NULL != rp_uri)) | ||
1759 | iter->cb (iter->cb_cls, ticket, rp_uri); | ||
1738 | GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1); | 1760 | GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1); |
1739 | } | 1761 | } |
1740 | 1762 | ||
@@ -1750,7 +1772,7 @@ collect_tickets_finished_cb (void *cls) | |||
1750 | struct RECLAIM_TICKETS_Iterator *iter = cls; | 1772 | struct RECLAIM_TICKETS_Iterator *iter = cls; |
1751 | 1773 | ||
1752 | iter->ns_it = NULL; | 1774 | iter->ns_it = NULL; |
1753 | iter->cb (iter->cb_cls, NULL); | 1775 | iter->cb (iter->cb_cls, NULL, NULL); |
1754 | cleanup_iter (iter); | 1776 | cleanup_iter (iter); |
1755 | } | 1777 | } |
1756 | 1778 | ||
@@ -1766,7 +1788,7 @@ collect_tickets_error_cb (void *cls) | |||
1766 | struct RECLAIM_TICKETS_Iterator *iter = cls; | 1788 | struct RECLAIM_TICKETS_Iterator *iter = cls; |
1767 | 1789 | ||
1768 | iter->ns_it = NULL; | 1790 | iter->ns_it = NULL; |
1769 | iter->cb (iter->cb_cls, NULL); | 1791 | iter->cb (iter->cb_cls, NULL, NULL); |
1770 | cleanup_iter (iter); | 1792 | cleanup_iter (iter); |
1771 | } | 1793 | } |
1772 | 1794 | ||
diff --git a/src/service/reclaim/gnunet-service-reclaim_tickets.h b/src/service/reclaim/gnunet-service-reclaim_tickets.h index 0ec232f49..b425a3dba 100644 --- a/src/service/reclaim/gnunet-service-reclaim_tickets.h +++ b/src/service/reclaim/gnunet-service-reclaim_tickets.h | |||
@@ -102,10 +102,12 @@ struct TicketRecordsEntry | |||
102 | * | 102 | * |
103 | * @param cls closure | 103 | * @param cls closure |
104 | * @param ticket the ticket | 104 | * @param ticket the ticket |
105 | * @param rp_uri the RP URI associated with the ticket | ||
105 | */ | 106 | */ |
106 | typedef void (*RECLAIM_TICKETS_TicketIter) ( | 107 | typedef void (*RECLAIM_TICKETS_TicketIter) ( |
107 | void *cls, | 108 | void *cls, |
108 | struct GNUNET_RECLAIM_Ticket *ticket); | 109 | struct GNUNET_RECLAIM_Ticket *ticket, |
110 | const char* rp_uri); | ||
109 | 111 | ||
110 | 112 | ||
111 | /** | 113 | /** |
@@ -186,15 +188,15 @@ RECLAIM_TICKETS_revoke_cancel (struct RECLAIM_TICKETS_RevokeHandle *rh); | |||
186 | * We first looking attribute references under the label | 188 | * We first looking attribute references under the label |
187 | * ticket.rnd in GNS. | 189 | * ticket.rnd in GNS. |
188 | * | 190 | * |
189 | * @param id the audience of the ticket | ||
190 | * @param ticket the ticket to consume | 191 | * @param ticket the ticket to consume |
192 | * @param rp_uri the expected RP URI | ||
191 | * @param cb callback to call with attributes of ticket | 193 | * @param cb callback to call with attributes of ticket |
192 | * @param cb_cls callback closure | 194 | * @param cb_cls callback closure |
193 | * @return handle to the operation | 195 | * @return handle to the operation |
194 | */ | 196 | */ |
195 | struct RECLAIM_TICKETS_ConsumeHandle * | 197 | struct RECLAIM_TICKETS_ConsumeHandle * |
196 | RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_PrivateKey *id, | 198 | RECLAIM_TICKETS_consume (const struct GNUNET_RECLAIM_Ticket *ticket, |
197 | const struct GNUNET_RECLAIM_Ticket *ticket, | 199 | const char *rp_uri, |
198 | RECLAIM_TICKETS_ConsumeCallback cb, | 200 | RECLAIM_TICKETS_ConsumeCallback cb, |
199 | void *cb_cls); | 201 | void *cb_cls); |
200 | 202 | ||
@@ -214,7 +216,7 @@ RECLAIM_TICKETS_consume_cancel (struct RECLAIM_TICKETS_ConsumeHandle *cth); | |||
214 | * | 216 | * |
215 | * @param identity the issuer | 217 | * @param identity the issuer |
216 | * @param attrs the attributes to share | 218 | * @param attrs the attributes to share |
217 | * @param audience the audience to share the attributes with | 219 | * @param rp the RP URI |
218 | * @param cb the callback to call with the ticket result | 220 | * @param cb the callback to call with the ticket result |
219 | * @param cb_cls the callback closure | 221 | * @param cb_cls the callback closure |
220 | * FIXME: Return handle?? | 222 | * FIXME: Return handle?? |
@@ -222,7 +224,7 @@ RECLAIM_TICKETS_consume_cancel (struct RECLAIM_TICKETS_ConsumeHandle *cth); | |||
222 | void | 224 | void |
223 | RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_PrivateKey *identity, | 225 | RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_PrivateKey *identity, |
224 | const struct GNUNET_RECLAIM_AttributeList *attrs, | 226 | const struct GNUNET_RECLAIM_AttributeList *attrs, |
225 | const struct GNUNET_CRYPTO_PublicKey *audience, | 227 | const char *rp, |
226 | RECLAIM_TICKETS_TicketResult cb, | 228 | RECLAIM_TICKETS_TicketResult cb, |
227 | void *cb_cls); | 229 | void *cb_cls); |
228 | 230 | ||
diff --git a/src/service/reclaim/reclaim.h b/src/service/reclaim/reclaim.h index 9d5118269..1fb50eafe 100644 --- a/src/service/reclaim/reclaim.h +++ b/src/service/reclaim/reclaim.h | |||
@@ -420,13 +420,13 @@ struct IssueTicketMessage | |||
420 | uint16_t key_len GNUNET_PACKED; | 420 | uint16_t key_len GNUNET_PACKED; |
421 | 421 | ||
422 | /** | 422 | /** |
423 | * The length of the relying party public key | 423 | * The length of the relying party URI |
424 | */ | 424 | */ |
425 | uint16_t pkey_len GNUNET_PACKED; | 425 | uint16_t rp_uri_len GNUNET_PACKED; |
426 | 426 | ||
427 | /** | 427 | /** |
428 | * Followed by the private key. | 428 | * Followed by the private key. |
429 | * Followed by the public key. | 429 | * Followed by the RP URI. |
430 | * Followed by a serialized attribute list | 430 | * Followed by a serialized attribute list |
431 | */ | 431 | */ |
432 | }; | 432 | }; |
@@ -506,12 +506,18 @@ struct TicketResultMessage | |||
506 | uint16_t tkt_len GNUNET_PACKED; | 506 | uint16_t tkt_len GNUNET_PACKED; |
507 | 507 | ||
508 | /** | 508 | /** |
509 | * RP URI length | ||
510 | */ | ||
511 | uint16_t rp_uri_len GNUNET_PACKED; | ||
512 | |||
513 | /** | ||
509 | * Length of new presentations created | 514 | * Length of new presentations created |
510 | */ | 515 | */ |
511 | uint16_t presentations_len GNUNET_PACKED; | 516 | uint16_t presentations_len GNUNET_PACKED; |
512 | 517 | ||
513 | /* | 518 | /* |
514 | * Followed by the serialized ticket | 519 | * Followed by the serialized ticket |
520 | * Followed by the RP URI | ||
515 | * Followed by the serialized GNUNET_RECLAIM_PresentationList | 521 | * Followed by the serialized GNUNET_RECLAIM_PresentationList |
516 | */ | 522 | */ |
517 | }; | 523 | }; |
@@ -532,18 +538,18 @@ struct ConsumeTicketMessage | |||
532 | uint32_t id GNUNET_PACKED; | 538 | uint32_t id GNUNET_PACKED; |
533 | 539 | ||
534 | /** | 540 | /** |
535 | * The length of the private key | 541 | * The length of the ticket |
536 | */ | 542 | */ |
537 | uint16_t key_len GNUNET_PACKED; | 543 | uint16_t tkt_len GNUNET_PACKED; |
538 | 544 | ||
539 | /** | 545 | /** |
540 | * The length of the ticket | 546 | * RP URI length |
541 | */ | 547 | */ |
542 | uint16_t tkt_len GNUNET_PACKED; | 548 | uint16_t rp_uri_len GNUNET_PACKED; |
543 | 549 | ||
544 | /** | 550 | /** |
545 | * Followed by the private key. | ||
546 | * Followed by the serialized ticket. | 551 | * Followed by the serialized ticket. |
552 | * Followed by the RP URI | ||
547 | */ | 553 | */ |
548 | }; | 554 | }; |
549 | 555 | ||
@@ -583,12 +589,12 @@ struct ConsumeTicketResultMessage | |||
583 | uint16_t presentations_len; | 589 | uint16_t presentations_len; |
584 | 590 | ||
585 | /** | 591 | /** |
586 | * The length of the private key | 592 | * The length of the identity public key |
587 | */ | 593 | */ |
588 | uint16_t key_len GNUNET_PACKED; | 594 | uint16_t key_len GNUNET_PACKED; |
589 | 595 | ||
590 | /** | 596 | /** |
591 | * Followed by the private key. | 597 | * Followed by the identity public key. |
592 | * followed by: | 598 | * followed by: |
593 | * serialized attributes data | 599 | * serialized attributes data |
594 | */ | 600 | */ |
diff --git a/src/service/reclaim/reclaim_api.c b/src/service/reclaim/reclaim_api.c index d865f0050..f1819614c 100644 --- a/src/service/reclaim/reclaim_api.c +++ b/src/service/reclaim/reclaim_api.c | |||
@@ -621,9 +621,9 @@ handle_consume_ticket_result (void *cls, | |||
621 | read_ptr = (char *) &msg[1]; | 621 | read_ptr = (char *) &msg[1]; |
622 | GNUNET_assert (GNUNET_SYSERR != | 622 | GNUNET_assert (GNUNET_SYSERR != |
623 | GNUNET_CRYPTO_read_public_key_from_buffer (read_ptr, | 623 | GNUNET_CRYPTO_read_public_key_from_buffer (read_ptr, |
624 | key_len, | 624 | key_len, |
625 | &identity, | 625 | &identity, |
626 | &read)); | 626 | &read)); |
627 | read_ptr += read; | 627 | read_ptr += read; |
628 | attrs = | 628 | attrs = |
629 | GNUNET_RECLAIM_attribute_list_deserialize (read_ptr, attrs_len); | 629 | GNUNET_RECLAIM_attribute_list_deserialize (read_ptr, attrs_len); |
@@ -646,7 +646,8 @@ handle_consume_ticket_result (void *cls, | |||
646 | { | 646 | { |
647 | if (GNUNET_YES == | 647 | if (GNUNET_YES == |
648 | GNUNET_RECLAIM_id_is_equal (&le->attribute->credential, | 648 | GNUNET_RECLAIM_id_is_equal (&le->attribute->credential, |
649 | &ple->presentation->credential_id)) | 649 | &ple->presentation->credential_id) |
650 | ) | ||
650 | { | 651 | { |
651 | op->atr_cb (op->cls, &identity, | 652 | op->atr_cb (op->cls, &identity, |
652 | le->attribute, ple->presentation); | 653 | le->attribute, ple->presentation); |
@@ -765,9 +766,9 @@ handle_attribute_result (void *cls, const struct AttributeResultMessage *msg) | |||
765 | struct GNUNET_RECLAIM_Attribute *attr; | 766 | struct GNUNET_RECLAIM_Attribute *attr; |
766 | GNUNET_assert (GNUNET_SYSERR != | 767 | GNUNET_assert (GNUNET_SYSERR != |
767 | GNUNET_CRYPTO_read_public_key_from_buffer (buf, | 768 | GNUNET_CRYPTO_read_public_key_from_buffer (buf, |
768 | key_len, | 769 | key_len, |
769 | &identity, | 770 | &identity, |
770 | &read)); | 771 | &read)); |
771 | buf += read; | 772 | buf += read; |
772 | GNUNET_RECLAIM_attribute_deserialize (buf, attr_len, &attr); | 773 | GNUNET_RECLAIM_attribute_deserialize (buf, attr_len, &attr); |
773 | if (NULL != it) | 774 | if (NULL != it) |
@@ -854,9 +855,9 @@ handle_credential_result (void *cls, const struct | |||
854 | { | 855 | { |
855 | GNUNET_assert (GNUNET_SYSERR != | 856 | GNUNET_assert (GNUNET_SYSERR != |
856 | GNUNET_CRYPTO_read_public_key_from_buffer (buf, | 857 | GNUNET_CRYPTO_read_public_key_from_buffer (buf, |
857 | key_len, | 858 | key_len, |
858 | &identity, | 859 | &identity, |
859 | &read)); | 860 | &read)); |
860 | buf += read; | 861 | buf += read; |
861 | } | 862 | } |
862 | if (0 == key_len) | 863 | if (0 == key_len) |
@@ -918,11 +919,13 @@ check_ticket_result (void *cls, const struct TicketResultMessage *msg) | |||
918 | size_t msg_len; | 919 | size_t msg_len; |
919 | size_t pres_len; | 920 | size_t pres_len; |
920 | size_t tkt_len; | 921 | size_t tkt_len; |
922 | size_t rp_uri_len; | ||
921 | 923 | ||
922 | msg_len = ntohs (msg->header.size); | 924 | msg_len = ntohs (msg->header.size); |
923 | pres_len = ntohs (msg->presentations_len); | 925 | pres_len = ntohs (msg->presentations_len); |
924 | tkt_len = ntohs (msg->tkt_len); | 926 | tkt_len = ntohs (msg->tkt_len); |
925 | if (msg_len != sizeof(*msg) + pres_len + tkt_len) | 927 | rp_uri_len = ntohs (msg->rp_uri_len); |
928 | if (msg_len != sizeof(*msg) + pres_len + tkt_len + rp_uri_len) | ||
926 | { | 929 | { |
927 | GNUNET_break (0); | 930 | GNUNET_break (0); |
928 | return GNUNET_SYSERR; | 931 | return GNUNET_SYSERR; |
@@ -946,13 +949,16 @@ handle_ticket_result (void *cls, const struct TicketResultMessage *msg) | |||
946 | struct GNUNET_RECLAIM_TicketIterator *it; | 949 | struct GNUNET_RECLAIM_TicketIterator *it; |
947 | struct GNUNET_RECLAIM_PresentationList *presentation; | 950 | struct GNUNET_RECLAIM_PresentationList *presentation; |
948 | uint32_t r_id = ntohl (msg->id); | 951 | uint32_t r_id = ntohl (msg->id); |
949 | struct GNUNET_RECLAIM_Ticket ticket; | 952 | struct GNUNET_RECLAIM_Ticket *ticket = NULL; |
950 | size_t pres_len; | 953 | size_t pres_len; |
951 | size_t tkt_len; | 954 | size_t tkt_len; |
952 | size_t tb_read; | 955 | size_t rp_uri_len; |
956 | size_t tb_read = 0; | ||
953 | char *buf; | 957 | char *buf; |
958 | char *rp_uri = NULL; | ||
954 | 959 | ||
955 | tkt_len = ntohs (msg->tkt_len); | 960 | tkt_len = ntohs (msg->tkt_len); |
961 | rp_uri_len = ntohs (msg->rp_uri_len); | ||
956 | pres_len = ntohs (msg->presentations_len); | 962 | pres_len = ntohs (msg->presentations_len); |
957 | for (op = handle->op_head; NULL != op; op = op->next) | 963 | for (op = handle->op_head; NULL != op; op = op->next) |
958 | if (op->r_id == r_id) | 964 | if (op->r_id == r_id) |
@@ -965,13 +971,12 @@ handle_ticket_result (void *cls, const struct TicketResultMessage *msg) | |||
965 | buf = (char*) &msg[1]; | 971 | buf = (char*) &msg[1]; |
966 | if (0 < tkt_len) | 972 | if (0 < tkt_len) |
967 | { | 973 | { |
968 | GNUNET_assert (GNUNET_SYSERR != | 974 | ticket = (struct GNUNET_RECLAIM_Ticket*) buf; |
969 | GNUNET_RECLAIM_read_ticket_from_buffer (buf, | 975 | buf += tkt_len; |
970 | tkt_len, | 976 | tb_read += tkt_len; |
971 | &ticket, | ||
972 | &tb_read)); | ||
973 | buf += tb_read; | ||
974 | } | 977 | } |
978 | if (0 < rp_uri_len) | ||
979 | rp_uri = buf; | ||
975 | if (NULL != op) | 980 | if (NULL != op) |
976 | { | 981 | { |
977 | if (0 < pres_len) | 982 | if (0 < pres_len) |
@@ -988,7 +993,7 @@ handle_ticket_result (void *cls, const struct TicketResultMessage *msg) | |||
988 | { | 993 | { |
989 | if (NULL != op->ti_cb) | 994 | if (NULL != op->ti_cb) |
990 | op->ti_cb (op->cls, | 995 | op->ti_cb (op->cls, |
991 | &ticket, | 996 | ticket, |
992 | (0 < pres_len) ? presentation : NULL); | 997 | (0 < pres_len) ? presentation : NULL); |
993 | } | 998 | } |
994 | if (0 < pres_len) | 999 | if (0 < pres_len) |
@@ -1009,7 +1014,7 @@ handle_ticket_result (void *cls, const struct TicketResultMessage *msg) | |||
1009 | else | 1014 | else |
1010 | { | 1015 | { |
1011 | if (NULL != it->tr_cb) | 1016 | if (NULL != it->tr_cb) |
1012 | it->tr_cb (it->cls, &ticket); | 1017 | it->tr_cb (it->cls, ticket, rp_uri); |
1013 | } | 1018 | } |
1014 | return; | 1019 | return; |
1015 | } | 1020 | } |
@@ -1440,7 +1445,8 @@ GNUNET_RECLAIM_get_credentials_start ( | |||
1440 | env = | 1445 | env = |
1441 | GNUNET_MQ_msg_extra (msg, | 1446 | GNUNET_MQ_msg_extra (msg, |
1442 | key_len, | 1447 | key_len, |
1443 | GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_START); | 1448 | GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_START) |
1449 | ; | ||
1444 | msg->id = htonl (rid); | 1450 | msg->id = htonl (rid); |
1445 | msg->key_len = htons (key_len); | 1451 | msg->key_len = htons (key_len); |
1446 | GNUNET_CRYPTO_write_private_key_to_buffer (identity, &msg[1], key_len); | 1452 | GNUNET_CRYPTO_write_private_key_to_buffer (identity, &msg[1], key_len); |
@@ -1491,7 +1497,7 @@ struct GNUNET_RECLAIM_Operation * | |||
1491 | GNUNET_RECLAIM_ticket_issue ( | 1497 | GNUNET_RECLAIM_ticket_issue ( |
1492 | struct GNUNET_RECLAIM_Handle *h, | 1498 | struct GNUNET_RECLAIM_Handle *h, |
1493 | const struct GNUNET_CRYPTO_PrivateKey *iss, | 1499 | const struct GNUNET_CRYPTO_PrivateKey *iss, |
1494 | const struct GNUNET_CRYPTO_PublicKey *rp, | 1500 | const char *rp, |
1495 | const struct GNUNET_RECLAIM_AttributeList *attrs, | 1501 | const struct GNUNET_RECLAIM_AttributeList *attrs, |
1496 | GNUNET_RECLAIM_IssueTicketCallback cb, | 1502 | GNUNET_RECLAIM_IssueTicketCallback cb, |
1497 | void *cb_cls) | 1503 | void *cb_cls) |
@@ -1510,19 +1516,20 @@ GNUNET_RECLAIM_ticket_issue ( | |||
1510 | op->cls = cb_cls; | 1516 | op->cls = cb_cls; |
1511 | op->r_id = h->r_id_gen++; | 1517 | op->r_id = h->r_id_gen++; |
1512 | key_len = GNUNET_CRYPTO_private_key_get_length (iss); | 1518 | key_len = GNUNET_CRYPTO_private_key_get_length (iss); |
1513 | rpk_len = GNUNET_CRYPTO_public_key_get_length (rp); | 1519 | rpk_len = strlen (rp) + 1; |
1514 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op); | 1520 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op); |
1515 | attr_len = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs); | 1521 | attr_len = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs); |
1516 | op->env = GNUNET_MQ_msg_extra (tim, | 1522 | op->env = GNUNET_MQ_msg_extra (tim, |
1517 | attr_len + key_len + rpk_len, | 1523 | attr_len + key_len + rpk_len, |
1518 | GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET); | 1524 | GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET); |
1519 | tim->key_len = htons (key_len); | 1525 | tim->key_len = htons (key_len); |
1520 | tim->pkey_len = htons (rpk_len); | 1526 | tim->rp_uri_len = htons (rpk_len); |
1521 | buf = (char *) &tim[1]; | 1527 | buf = (char *) &tim[1]; |
1522 | written = GNUNET_CRYPTO_write_private_key_to_buffer (iss, buf, key_len); | 1528 | written = GNUNET_CRYPTO_write_private_key_to_buffer (iss, buf, key_len); |
1523 | GNUNET_assert (0 <= written); | 1529 | GNUNET_assert (0 <= written); |
1524 | buf += written; | 1530 | buf += written; |
1525 | written = GNUNET_CRYPTO_write_public_key_to_buffer (rp, buf, rpk_len); | 1531 | memcpy (buf, rp, rpk_len); |
1532 | written = rpk_len; | ||
1526 | GNUNET_assert (0 <= written); | 1533 | GNUNET_assert (0 <= written); |
1527 | buf += written; | 1534 | buf += written; |
1528 | tim->id = htonl (op->r_id); | 1535 | tim->id = htonl (op->r_id); |
@@ -1535,30 +1542,18 @@ GNUNET_RECLAIM_ticket_issue ( | |||
1535 | } | 1542 | } |
1536 | 1543 | ||
1537 | 1544 | ||
1538 | /** | ||
1539 | * Consumes an issued ticket. The ticket is persisted | ||
1540 | * and used to retrieve identity information from the issuer | ||
1541 | * | ||
1542 | * @param h the reclaim to use | ||
1543 | * @param identity the identity that is the subject of the issued ticket (the | ||
1544 | * relying party) | ||
1545 | * @param ticket the issued ticket to consume | ||
1546 | * @param cb the callback to call | ||
1547 | * @param cb_cls the callback closure | ||
1548 | * @return handle to abort the operation | ||
1549 | */ | ||
1550 | struct GNUNET_RECLAIM_Operation * | 1545 | struct GNUNET_RECLAIM_Operation * |
1551 | GNUNET_RECLAIM_ticket_consume ( | 1546 | GNUNET_RECLAIM_ticket_consume ( |
1552 | struct GNUNET_RECLAIM_Handle *h, | 1547 | struct GNUNET_RECLAIM_Handle *h, |
1553 | const struct GNUNET_CRYPTO_PrivateKey *identity, | ||
1554 | const struct GNUNET_RECLAIM_Ticket *ticket, | 1548 | const struct GNUNET_RECLAIM_Ticket *ticket, |
1549 | const char *rp_uri, | ||
1555 | GNUNET_RECLAIM_AttributeTicketResult cb, | 1550 | GNUNET_RECLAIM_AttributeTicketResult cb, |
1556 | void *cb_cls) | 1551 | void *cb_cls) |
1557 | { | 1552 | { |
1558 | struct GNUNET_RECLAIM_Operation *op; | 1553 | struct GNUNET_RECLAIM_Operation *op; |
1559 | struct ConsumeTicketMessage *ctm; | 1554 | struct ConsumeTicketMessage *ctm; |
1560 | size_t key_len; | ||
1561 | size_t tkt_len; | 1555 | size_t tkt_len; |
1556 | size_t rp_uri_len; | ||
1562 | char *buf; | 1557 | char *buf; |
1563 | 1558 | ||
1564 | op = GNUNET_new (struct GNUNET_RECLAIM_Operation); | 1559 | op = GNUNET_new (struct GNUNET_RECLAIM_Operation); |
@@ -1566,18 +1561,18 @@ GNUNET_RECLAIM_ticket_consume ( | |||
1566 | op->atr_cb = cb; | 1561 | op->atr_cb = cb; |
1567 | op->cls = cb_cls; | 1562 | op->cls = cb_cls; |
1568 | op->r_id = h->r_id_gen++; | 1563 | op->r_id = h->r_id_gen++; |
1569 | key_len = GNUNET_CRYPTO_private_key_get_length (identity); | 1564 | tkt_len = strlen (ticket->gns_name) + 1; |
1570 | tkt_len = GNUNET_RECLAIM_ticket_serialize_get_size (ticket); | 1565 | rp_uri_len = strlen (rp_uri) + 1; |
1571 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op); | 1566 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op); |
1572 | op->env = GNUNET_MQ_msg_extra (ctm, | 1567 | op->env = GNUNET_MQ_msg_extra (ctm, |
1573 | key_len + tkt_len, | 1568 | tkt_len + rp_uri_len, |
1574 | GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET); | 1569 | GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET); |
1575 | ctm->key_len = htons (key_len); | ||
1576 | buf = (char*) &ctm[1]; | 1570 | buf = (char*) &ctm[1]; |
1577 | GNUNET_CRYPTO_write_private_key_to_buffer (identity, buf, key_len); | 1571 | ctm->rp_uri_len = htons (rp_uri_len); |
1578 | buf += key_len; | ||
1579 | ctm->tkt_len = htons (tkt_len); | 1572 | ctm->tkt_len = htons (tkt_len); |
1580 | GNUNET_RECLAIM_write_ticket_to_buffer (ticket, buf, tkt_len); | 1573 | memcpy (buf, ticket, tkt_len); |
1574 | buf += tkt_len; | ||
1575 | memcpy (buf, rp_uri, rp_uri_len); | ||
1581 | ctm->id = htonl (op->r_id); | 1576 | ctm->id = htonl (op->r_id); |
1582 | if (NULL != h->mq) | 1577 | if (NULL != h->mq) |
1583 | GNUNET_MQ_send_copy (h->mq, op->env); | 1578 | GNUNET_MQ_send_copy (h->mq, op->env); |
@@ -1619,12 +1614,13 @@ GNUNET_RECLAIM_ticket_iteration_start ( | |||
1619 | GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head, h->ticket_it_tail, it); | 1614 | GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head, h->ticket_it_tail, it); |
1620 | env = GNUNET_MQ_msg_extra (msg, | 1615 | env = GNUNET_MQ_msg_extra (msg, |
1621 | key_len, | 1616 | key_len, |
1622 | GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START); | 1617 | GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START) |
1618 | ; | ||
1623 | msg->id = htonl (rid); | 1619 | msg->id = htonl (rid); |
1624 | msg->key_len = htons (key_len); | 1620 | msg->key_len = htons (key_len); |
1625 | GNUNET_CRYPTO_write_private_key_to_buffer (identity, | 1621 | GNUNET_CRYPTO_write_private_key_to_buffer (identity, |
1626 | &msg[1], | 1622 | &msg[1], |
1627 | key_len); | 1623 | key_len); |
1628 | if (NULL == h->mq) | 1624 | if (NULL == h->mq) |
1629 | it->env = env; | 1625 | it->env = env; |
1630 | else | 1626 | else |
@@ -1714,7 +1710,7 @@ GNUNET_RECLAIM_ticket_revoke ( | |||
1714 | op->r_id = rid; | 1710 | op->r_id = rid; |
1715 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op); | 1711 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op); |
1716 | key_len = GNUNET_CRYPTO_private_key_get_length (identity); | 1712 | key_len = GNUNET_CRYPTO_private_key_get_length (identity); |
1717 | tkt_len = GNUNET_RECLAIM_ticket_serialize_get_size (ticket); | 1713 | tkt_len = strlen (ticket->gns_name) + 1; |
1718 | op->env = GNUNET_MQ_msg_extra (msg, | 1714 | op->env = GNUNET_MQ_msg_extra (msg, |
1719 | key_len + tkt_len, | 1715 | key_len + tkt_len, |
1720 | GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET); | 1716 | GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET); |
@@ -1723,13 +1719,11 @@ GNUNET_RECLAIM_ticket_revoke ( | |||
1723 | msg->tkt_len = htons (tkt_len); | 1719 | msg->tkt_len = htons (tkt_len); |
1724 | buf = (char*) &msg[1]; | 1720 | buf = (char*) &msg[1]; |
1725 | written = GNUNET_CRYPTO_write_private_key_to_buffer (identity, | 1721 | written = GNUNET_CRYPTO_write_private_key_to_buffer (identity, |
1726 | buf, | 1722 | buf, |
1727 | key_len); | 1723 | key_len); |
1728 | GNUNET_assert (0 <= written); | 1724 | GNUNET_assert (0 <= written); |
1729 | buf += written; | 1725 | buf += written; |
1730 | GNUNET_RECLAIM_write_ticket_to_buffer (ticket, | 1726 | memcpy (buf, ticket, tkt_len); |
1731 | buf, | ||
1732 | tkt_len); | ||
1733 | if (NULL != h->mq) | 1727 | if (NULL != h->mq) |
1734 | { | 1728 | { |
1735 | GNUNET_MQ_send (h->mq, op->env); | 1729 | GNUNET_MQ_send (h->mq, op->env); |
@@ -1738,78 +1732,5 @@ GNUNET_RECLAIM_ticket_revoke ( | |||
1738 | return op; | 1732 | return op; |
1739 | } | 1733 | } |
1740 | 1734 | ||
1741 | size_t | ||
1742 | GNUNET_RECLAIM_ticket_serialize_get_size (const struct | ||
1743 | GNUNET_RECLAIM_Ticket *tkt) | ||
1744 | { | ||
1745 | size_t size = sizeof (tkt->rnd); | ||
1746 | size += GNUNET_CRYPTO_public_key_get_length (&tkt->identity); | ||
1747 | size += GNUNET_CRYPTO_public_key_get_length (&tkt->audience); | ||
1748 | return size; | ||
1749 | } | ||
1750 | |||
1751 | enum GNUNET_GenericReturnValue | ||
1752 | GNUNET_RECLAIM_read_ticket_from_buffer (const void *buffer, | ||
1753 | size_t len, | ||
1754 | struct GNUNET_RECLAIM_Ticket *tkt, | ||
1755 | size_t *tb_read) | ||
1756 | { | ||
1757 | const char *tmp = buffer; | ||
1758 | size_t read = 0; | ||
1759 | size_t left = len; | ||
1760 | if (GNUNET_SYSERR == | ||
1761 | GNUNET_CRYPTO_read_public_key_from_buffer (tmp, | ||
1762 | left, | ||
1763 | &tkt->identity, | ||
1764 | &read)) | ||
1765 | return GNUNET_SYSERR; | ||
1766 | left -= read; | ||
1767 | tmp += read; | ||
1768 | if (GNUNET_SYSERR == | ||
1769 | GNUNET_CRYPTO_read_public_key_from_buffer (tmp, | ||
1770 | left, | ||
1771 | &tkt->audience, | ||
1772 | &read)) | ||
1773 | return GNUNET_SYSERR; | ||
1774 | left -= read; | ||
1775 | tmp += read; | ||
1776 | if (left < sizeof (tkt->rnd)) | ||
1777 | return GNUNET_SYSERR; | ||
1778 | memcpy (&tkt->rnd, tmp, sizeof (tkt->rnd)); | ||
1779 | *tb_read = tmp - (char*) buffer + sizeof (tkt->rnd); | ||
1780 | return GNUNET_OK; | ||
1781 | } | ||
1782 | |||
1783 | |||
1784 | ssize_t | ||
1785 | GNUNET_RECLAIM_write_ticket_to_buffer (const struct | ||
1786 | GNUNET_RECLAIM_Ticket *tkt, | ||
1787 | void *buffer, | ||
1788 | size_t len) | ||
1789 | { | ||
1790 | char *tmp = buffer; | ||
1791 | size_t left = len; | ||
1792 | ssize_t written = 0; | ||
1793 | written = GNUNET_CRYPTO_write_public_key_to_buffer (&tkt->identity, | ||
1794 | buffer, | ||
1795 | left); | ||
1796 | if (0 > written) | ||
1797 | return written; | ||
1798 | left -= written; | ||
1799 | tmp += written; | ||
1800 | written = GNUNET_CRYPTO_write_public_key_to_buffer (&tkt->audience, | ||
1801 | tmp, | ||
1802 | left); | ||
1803 | if (0 > written) | ||
1804 | return written; | ||
1805 | left -= written; | ||
1806 | tmp += written; | ||
1807 | if (left < sizeof (tkt->rnd)) | ||
1808 | return -1; | ||
1809 | memcpy (tmp, &tkt->rnd, sizeof (tkt->rnd)); | ||
1810 | return tmp - (char*) buffer + sizeof (tkt->rnd); | ||
1811 | } | ||
1812 | |||
1813 | |||
1814 | 1735 | ||
1815 | /* end of reclaim_api.c */ | 1736 | /* end of reclaim_api.c */ |
diff --git a/src/service/rest/json_reclaim.c b/src/service/rest/json_reclaim.c index b1ca7a4a5..3b43a37e4 100644 --- a/src/service/rest/json_reclaim.c +++ b/src/service/rest/json_reclaim.c | |||
@@ -170,9 +170,7 @@ static int | |||
170 | parse_ticket (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec) | 170 | parse_ticket (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec) |
171 | { | 171 | { |
172 | struct GNUNET_RECLAIM_Ticket *ticket; | 172 | struct GNUNET_RECLAIM_Ticket *ticket; |
173 | const char *rnd_str; | 173 | const char *gns_str; |
174 | const char *aud_str; | ||
175 | const char *id_str; | ||
176 | int unpack_state; | 174 | int unpack_state; |
177 | 175 | ||
178 | GNUNET_assert (NULL != root); | 176 | GNUNET_assert (NULL != root); |
@@ -185,13 +183,9 @@ parse_ticket (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec) | |||
185 | } | 183 | } |
186 | // interpret single ticket | 184 | // interpret single ticket |
187 | unpack_state = json_unpack (root, | 185 | unpack_state = json_unpack (root, |
188 | "{s:s, s:s, s:s!}", | 186 | "{s:s}", |
189 | "rnd", | 187 | "gns_name", |
190 | &rnd_str, | 188 | &gns_str); |
191 | "audience", | ||
192 | &aud_str, | ||
193 | "issuer", | ||
194 | &id_str); | ||
195 | if (0 != unpack_state) | 189 | if (0 != unpack_state) |
196 | { | 190 | { |
197 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 191 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -199,36 +193,7 @@ parse_ticket (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec) | |||
199 | return GNUNET_SYSERR; | 193 | return GNUNET_SYSERR; |
200 | } | 194 | } |
201 | ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket); | 195 | ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket); |
202 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (rnd_str, | 196 | strncpy (ticket->gns_name, gns_str, sizeof (ticket->gns_name)); |
203 | strlen (rnd_str), | ||
204 | &ticket->rnd, | ||
205 | sizeof(ticket->rnd))) | ||
206 | { | ||
207 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Rnd invalid\n"); | ||
208 | GNUNET_free (ticket); | ||
209 | return GNUNET_SYSERR; | ||
210 | } | ||
211 | if (GNUNET_OK != | ||
212 | GNUNET_STRINGS_string_to_data (id_str, | ||
213 | strlen (id_str), | ||
214 | &ticket->identity, | ||
215 | sizeof(ticket->identity))) | ||
216 | { | ||
217 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Identity invalid\n"); | ||
218 | GNUNET_free (ticket); | ||
219 | return GNUNET_SYSERR; | ||
220 | } | ||
221 | |||
222 | if (GNUNET_OK != | ||
223 | GNUNET_STRINGS_string_to_data (aud_str, | ||
224 | strlen (aud_str), | ||
225 | &ticket->audience, | ||
226 | sizeof(ticket->audience))) | ||
227 | { | ||
228 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Audience invalid\n"); | ||
229 | GNUNET_free (ticket); | ||
230 | return GNUNET_SYSERR; | ||
231 | } | ||
232 | 197 | ||
233 | *(struct GNUNET_RECLAIM_Ticket **) spec->ptr = ticket; | 198 | *(struct GNUNET_RECLAIM_Ticket **) spec->ptr = ticket; |
234 | return GNUNET_OK; | 199 | return GNUNET_OK; |
@@ -286,7 +251,8 @@ GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket) | |||
286 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | 251 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error |
287 | */ | 252 | */ |
288 | static int | 253 | static int |
289 | parse_credential (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec) | 254 | parse_credential (void *cls, json_t *root, struct GNUNET_JSON_Specification * |
255 | spec) | ||
290 | { | 256 | { |
291 | struct GNUNET_RECLAIM_Credential *cred; | 257 | struct GNUNET_RECLAIM_Credential *cred; |
292 | const char *name_str = NULL; | 258 | const char *name_str = NULL; |
@@ -325,9 +291,12 @@ parse_credential (void *cls, json_t *root, struct GNUNET_JSON_Specification *spe | |||
325 | "Error json object has a wrong format!\n"); | 291 | "Error json object has a wrong format!\n"); |
326 | return GNUNET_SYSERR; | 292 | return GNUNET_SYSERR; |
327 | } | 293 | } |
328 | if (json_is_string (val_json)) { | 294 | if (json_is_string (val_json)) |
295 | { | ||
329 | val_str = GNUNET_strdup (json_string_value (val_json)); | 296 | val_str = GNUNET_strdup (json_string_value (val_json)); |
330 | } else { | 297 | } |
298 | else | ||
299 | { | ||
331 | val_str = json_dumps (val_json, JSON_COMPACT); | 300 | val_str = json_dumps (val_json, JSON_COMPACT); |
332 | } | 301 | } |
333 | type = GNUNET_RECLAIM_credential_typename_to_number (type_str); | 302 | type = GNUNET_RECLAIM_credential_typename_to_number (type_str); |
diff --git a/src/service/rest/oidc_helper.c b/src/service/rest/oidc_helper.c index a2da7312b..08c99dc8b 100644 --- a/src/service/rest/oidc_helper.c +++ b/src/service/rest/oidc_helper.c | |||
@@ -24,10 +24,11 @@ | |||
24 | * @author Martin Schanzenbach | 24 | * @author Martin Schanzenbach |
25 | * @author Tristan Schwieren | 25 | * @author Tristan Schwieren |
26 | */ | 26 | */ |
27 | #include "platform.h" | ||
28 | #include <inttypes.h> | 27 | #include <inttypes.h> |
29 | #include <jansson.h> | 28 | #include <jansson.h> |
30 | #include <jose/jose.h> | 29 | #include <jose/jose.h> |
30 | #include "gnunet_gns_service.h" | ||
31 | #include "gnunet_gnsrecord_lib.h" | ||
31 | #include "gnunet_util_lib.h" | 32 | #include "gnunet_util_lib.h" |
32 | #include "gnunet_reclaim_lib.h" | 33 | #include "gnunet_reclaim_lib.h" |
33 | #include "gnunet_reclaim_service.h" | 34 | #include "gnunet_reclaim_service.h" |
@@ -211,7 +212,8 @@ generate_userinfo_json (const struct GNUNET_CRYPTO_PublicKey *sub_key, | |||
211 | pres_val_str = | 212 | pres_val_str = |
212 | GNUNET_RECLAIM_presentation_value_to_string (ple->presentation->type, | 213 | GNUNET_RECLAIM_presentation_value_to_string (ple->presentation->type, |
213 | ple->presentation->data, | 214 | ple->presentation->data, |
214 | ple->presentation->data_size); | 215 | ple->presentation->data_size) |
216 | ; | ||
215 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 217 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
216 | "Presentation is: %s\n", pres_val_str); | 218 | "Presentation is: %s\n", pres_val_str); |
217 | json_object_set_new (aggr_sources_jwt, | 219 | json_object_set_new (aggr_sources_jwt, |
@@ -359,7 +361,7 @@ OIDC_generate_userinfo (const struct GNUNET_CRYPTO_PublicKey *sub_key, | |||
359 | 361 | ||
360 | 362 | ||
361 | char * | 363 | char * |
362 | generate_id_token_body (const struct GNUNET_CRYPTO_PublicKey *aud_key, | 364 | generate_id_token_body (const char *rp_uri, |
363 | const struct GNUNET_CRYPTO_PublicKey *sub_key, | 365 | const struct GNUNET_CRYPTO_PublicKey *sub_key, |
364 | const struct GNUNET_RECLAIM_AttributeList *attrs, | 366 | const struct GNUNET_RECLAIM_AttributeList *attrs, |
365 | const struct | 367 | const struct |
@@ -370,7 +372,6 @@ generate_id_token_body (const struct GNUNET_CRYPTO_PublicKey *aud_key, | |||
370 | struct GNUNET_TIME_Absolute exp_time; | 372 | struct GNUNET_TIME_Absolute exp_time; |
371 | struct GNUNET_TIME_Absolute time_now; | 373 | struct GNUNET_TIME_Absolute time_now; |
372 | json_t *body; | 374 | json_t *body; |
373 | char *audience; | ||
374 | char *subject; | 375 | char *subject; |
375 | char *body_str; | 376 | char *body_str; |
376 | 377 | ||
@@ -388,13 +389,9 @@ generate_id_token_body (const struct GNUNET_CRYPTO_PublicKey *aud_key, | |||
388 | GNUNET_STRINGS_data_to_string_alloc (sub_key, | 389 | GNUNET_STRINGS_data_to_string_alloc (sub_key, |
389 | sizeof(struct | 390 | sizeof(struct |
390 | GNUNET_CRYPTO_PublicKey)); | 391 | GNUNET_CRYPTO_PublicKey)); |
391 | audience = | ||
392 | GNUNET_STRINGS_data_to_string_alloc (aud_key, | ||
393 | sizeof(struct | ||
394 | GNUNET_CRYPTO_PublicKey)); | ||
395 | 392 | ||
396 | // aud REQUIRED public key client_id must be there | 393 | // aud REQUIRED public key client_id must be there |
397 | json_object_set_new (body, "aud", json_string (audience)); | 394 | json_object_set_new (body, "aud", json_string (rp_uri)); |
398 | // iat | 395 | // iat |
399 | json_object_set_new (body, | 396 | json_object_set_new (body, |
400 | "iat", | 397 | "iat", |
@@ -417,14 +414,13 @@ generate_id_token_body (const struct GNUNET_CRYPTO_PublicKey *aud_key, | |||
417 | 414 | ||
418 | json_decref (body); | 415 | json_decref (body); |
419 | GNUNET_free (subject); | 416 | GNUNET_free (subject); |
420 | GNUNET_free (audience); | ||
421 | 417 | ||
422 | return body_str; | 418 | return body_str; |
423 | } | 419 | } |
424 | 420 | ||
425 | 421 | ||
426 | char * | 422 | char * |
427 | OIDC_generate_id_token_rsa (const struct GNUNET_CRYPTO_PublicKey *aud_key, | 423 | OIDC_generate_id_token_rsa (const char *rp_uri, |
428 | const struct GNUNET_CRYPTO_PublicKey *sub_key, | 424 | const struct GNUNET_CRYPTO_PublicKey *sub_key, |
429 | const struct GNUNET_RECLAIM_AttributeList *attrs, | 425 | const struct GNUNET_RECLAIM_AttributeList *attrs, |
430 | const struct | 426 | const struct |
@@ -438,7 +434,7 @@ OIDC_generate_id_token_rsa (const struct GNUNET_CRYPTO_PublicKey *aud_key, | |||
438 | char *result; | 434 | char *result; |
439 | 435 | ||
440 | // Generate the body of the JSON Web Signature | 436 | // Generate the body of the JSON Web Signature |
441 | body_str = generate_id_token_body (aud_key, | 437 | body_str = generate_id_token_body (rp_uri, |
442 | sub_key, | 438 | sub_key, |
443 | attrs, | 439 | attrs, |
444 | presentations, | 440 | presentations, |
@@ -474,19 +470,9 @@ OIDC_generate_id_token_rsa (const struct GNUNET_CRYPTO_PublicKey *aud_key, | |||
474 | return result; | 470 | return result; |
475 | } | 471 | } |
476 | 472 | ||
477 | /** | 473 | |
478 | * Create a JWT using HMAC (HS256) from attributes | ||
479 | * | ||
480 | * @param aud_key the public of the audience | ||
481 | * @param sub_key the public key of the subject | ||
482 | * @param attrs the attribute list | ||
483 | * @param presentations credential presentation list (may be empty) | ||
484 | * @param expiration_time the validity of the token | ||
485 | * @param secret_key the key used to sign the JWT | ||
486 | * @return a new base64-encoded JWT string. | ||
487 | */ | ||
488 | char * | 474 | char * |
489 | OIDC_generate_id_token_hmac (const struct GNUNET_CRYPTO_PublicKey *aud_key, | 475 | OIDC_generate_id_token_hmac (const char *rp_uri, |
490 | const struct GNUNET_CRYPTO_PublicKey *sub_key, | 476 | const struct GNUNET_CRYPTO_PublicKey *sub_key, |
491 | const struct GNUNET_RECLAIM_AttributeList *attrs, | 477 | const struct GNUNET_RECLAIM_AttributeList *attrs, |
492 | const struct | 478 | const struct |
@@ -517,7 +503,7 @@ OIDC_generate_id_token_hmac (const struct GNUNET_CRYPTO_PublicKey *aud_key, | |||
517 | fix_base64 (header_base64); | 503 | fix_base64 (header_base64); |
518 | 504 | ||
519 | // Generate and encode the body of the JSON Web Signature | 505 | // Generate and encode the body of the JSON Web Signature |
520 | body_str = generate_id_token_body (aud_key, | 506 | body_str = generate_id_token_body (rp_uri, |
521 | sub_key, | 507 | sub_key, |
522 | attrs, | 508 | attrs, |
523 | presentations, | 509 | presentations, |
@@ -603,7 +589,8 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_PrivateKey *issuer, | |||
603 | /** PLAINTEXT **/ | 589 | /** PLAINTEXT **/ |
604 | // Assign ticket | 590 | // Assign ticket |
605 | memset (¶ms, 0, sizeof(params)); | 591 | memset (¶ms, 0, sizeof(params)); |
606 | params.ticket = *ticket; | 592 | memcpy (params.ticket.gns_name, ticket->gns_name, strlen (ticket->gns_name) |
593 | + 1); | ||
607 | // Assign nonce | 594 | // Assign nonce |
608 | payload_len = sizeof(struct OIDC_Parameters); | 595 | payload_len = sizeof(struct OIDC_Parameters); |
609 | if ((NULL != nonce_str) && (strcmp ("", nonce_str) != 0)) | 596 | if ((NULL != nonce_str) && (strcmp ("", nonce_str) != 0)) |
@@ -691,9 +678,9 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_PrivateKey *issuer, | |||
691 | // Sign and store signature | 678 | // Sign and store signature |
692 | if (GNUNET_SYSERR == | 679 | if (GNUNET_SYSERR == |
693 | GNUNET_CRYPTO_sign_ (issuer, | 680 | GNUNET_CRYPTO_sign_ (issuer, |
694 | purpose, | 681 | purpose, |
695 | (struct GNUNET_CRYPTO_Signature *) | 682 | (struct GNUNET_CRYPTO_Signature *) |
696 | buf_ptr)) | 683 | buf_ptr)) |
697 | { | 684 | { |
698 | GNUNET_break (0); | 685 | GNUNET_break (0); |
699 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n"); | 686 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n"); |
@@ -764,14 +751,15 @@ check_code_challenge (const char *code_challenge, | |||
764 | * @return GNUNET_OK if successful, else GNUNET_SYSERR | 751 | * @return GNUNET_OK if successful, else GNUNET_SYSERR |
765 | */ | 752 | */ |
766 | int | 753 | int |
767 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_PublicKey *audience, | 754 | OIDC_parse_authz_code (const char *rp_uri, |
755 | const struct GNUNET_CRYPTO_PublicKey *cid, | ||
768 | const char *code, | 756 | const char *code, |
769 | const char *code_verifier, | 757 | const char *code_verifier, |
770 | struct GNUNET_RECLAIM_Ticket *ticket, | 758 | struct GNUNET_RECLAIM_Ticket *ticket, |
771 | struct GNUNET_RECLAIM_AttributeList **attrs, | 759 | struct GNUNET_RECLAIM_AttributeList **attrs, |
772 | struct GNUNET_RECLAIM_PresentationList **presentations, | 760 | struct GNUNET_RECLAIM_PresentationList **presentations, |
773 | char **nonce_str, | 761 | char **nonce_str, |
774 | enum OIDC_VerificationOptions opts) | 762 | enum OIDC_VerificationOptions opts, char **emsg) |
775 | { | 763 | { |
776 | char *code_payload; | 764 | char *code_payload; |
777 | char *ptr; | 765 | char *ptr; |
@@ -781,6 +769,7 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_PublicKey *audience, | |||
781 | char *code_challenge; | 769 | char *code_challenge; |
782 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | 770 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; |
783 | struct GNUNET_CRYPTO_Signature *signature; | 771 | struct GNUNET_CRYPTO_Signature *signature; |
772 | struct GNUNET_CRYPTO_PublicKey iss; | ||
784 | uint32_t code_challenge_len; | 773 | uint32_t code_challenge_len; |
785 | uint32_t attrs_ser_len; | 774 | uint32_t attrs_ser_len; |
786 | uint32_t pres_ser_len; | 775 | uint32_t pres_ser_len; |
@@ -789,6 +778,8 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_PublicKey *audience, | |||
789 | uint32_t nonce_len = 0; | 778 | uint32_t nonce_len = 0; |
790 | struct OIDC_Parameters *params; | 779 | struct OIDC_Parameters *params; |
791 | 780 | ||
781 | |||
782 | GNUNET_GNS_parse_ztld (ticket->gns_name, &iss); | ||
792 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); | 783 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); |
793 | code_payload = NULL; | 784 | code_payload = NULL; |
794 | code_payload_len = | 785 | code_payload_len = |
@@ -822,6 +813,8 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_PublicKey *audience, | |||
822 | code_challenge_len, | 813 | code_challenge_len, |
823 | code_verifier)) | 814 | code_verifier)) |
824 | { | 815 | { |
816 | GNUNET_asprintf (emsg, "Code verifier `%s' invalid for challenge `%s'", | ||
817 | code_verifier, code_challenge); | ||
825 | GNUNET_free (code_payload); | 818 | GNUNET_free (code_payload); |
826 | return GNUNET_SYSERR; | 819 | return GNUNET_SYSERR; |
827 | } | 820 | } |
@@ -838,26 +831,18 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_PublicKey *audience, | |||
838 | memcpy (ticket, ¶ms->ticket, sizeof(params->ticket)); | 831 | memcpy (ticket, ¶ms->ticket, sizeof(params->ticket)); |
839 | // Signature | 832 | // Signature |
840 | // GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); | 833 | // GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); |
841 | if (0 != GNUNET_memcmp (audience, &ticket->audience)) | ||
842 | { | ||
843 | GNUNET_free (code_payload); | ||
844 | if (NULL != *nonce_str) | ||
845 | GNUNET_free (*nonce_str); | ||
846 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
847 | "Audience in ticket does not match client!\n"); | ||
848 | return GNUNET_SYSERR; | ||
849 | } | ||
850 | if (GNUNET_OK != | 834 | if (GNUNET_OK != |
851 | GNUNET_CRYPTO_signature_verify_ ( | 835 | GNUNET_CRYPTO_signature_verify_ ( |
852 | GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN, | 836 | GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN, |
853 | purpose, | 837 | purpose, |
854 | signature, | 838 | signature, |
855 | &(ticket->identity))) | 839 | &iss)) |
856 | { | 840 | { |
857 | GNUNET_free (code_payload); | 841 | GNUNET_free (code_payload); |
858 | if (NULL != *nonce_str) | 842 | if (NULL != *nonce_str) |
859 | GNUNET_free (*nonce_str); | 843 | GNUNET_free (*nonce_str); |
860 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); | 844 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); |
845 | *emsg = GNUNET_strdup ("Signature verification failed"); | ||
861 | return GNUNET_SYSERR; | 846 | return GNUNET_SYSERR; |
862 | } | 847 | } |
863 | // Attributes | 848 | // Attributes |
@@ -913,13 +898,17 @@ OIDC_build_token_response (const char *access_token, | |||
913 | * Generate a new access token | 898 | * Generate a new access token |
914 | */ | 899 | */ |
915 | char * | 900 | char * |
916 | OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket) | 901 | OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket, |
902 | const char *rp_uri) | ||
917 | { | 903 | { |
918 | char *access_token; | 904 | char *access_token; |
905 | char *tkt_b64; | ||
919 | 906 | ||
920 | GNUNET_STRINGS_base64_encode (ticket, | 907 | GNUNET_STRINGS_base64_encode (ticket, |
921 | sizeof(*ticket), | 908 | sizeof(*ticket), |
922 | &access_token); | 909 | &tkt_b64); |
910 | GNUNET_asprintf (&access_token, "%s-%s", tkt_b64, rp_uri); | ||
911 | GNUNET_free (tkt_b64); | ||
923 | return access_token; | 912 | return access_token; |
924 | } | 913 | } |
925 | 914 | ||
@@ -929,19 +918,31 @@ OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket) | |||
929 | */ | 918 | */ |
930 | int | 919 | int |
931 | OIDC_access_token_parse (const char *token, | 920 | OIDC_access_token_parse (const char *token, |
932 | struct GNUNET_RECLAIM_Ticket **ticket) | 921 | struct GNUNET_RECLAIM_Ticket **ticket, |
922 | char **rp_uri) | ||
933 | { | 923 | { |
934 | size_t sret; | 924 | size_t sret; |
935 | char *decoded; | 925 | char *decoded; |
936 | sret = GNUNET_STRINGS_base64_decode (token, | 926 | char *tmp; |
937 | strlen (token), | 927 | char *tkt_str; |
928 | char *rp_uri_str; | ||
929 | tmp = GNUNET_strdup (token); | ||
930 | tkt_str = strtok (tmp, "-"); | ||
931 | GNUNET_assert (NULL != tkt_str); // FIXME handle | ||
932 | rp_uri_str = strtok (NULL, "-"); | ||
933 | GNUNET_assert (NULL != rp_uri_str); // FIXME handle | ||
934 | sret = GNUNET_STRINGS_base64_decode (tkt_str, | ||
935 | strlen (tkt_str), | ||
938 | (void**) &decoded); | 936 | (void**) &decoded); |
939 | if (sizeof (struct GNUNET_RECLAIM_Ticket) != sret) | 937 | if (sizeof (struct GNUNET_RECLAIM_Ticket) != sret) |
940 | { | 938 | { |
941 | GNUNET_free (decoded); | 939 | GNUNET_free (decoded); |
940 | GNUNET_free (tmp); | ||
942 | return GNUNET_SYSERR; | 941 | return GNUNET_SYSERR; |
943 | } | 942 | } |
944 | *ticket = (struct GNUNET_RECLAIM_Ticket *) decoded; | 943 | *ticket = (struct GNUNET_RECLAIM_Ticket *) decoded; |
944 | *rp_uri = GNUNET_strdup (rp_uri_str); | ||
945 | GNUNET_free (tmp); | ||
945 | return GNUNET_OK; | 946 | return GNUNET_OK; |
946 | } | 947 | } |
947 | 948 | ||
diff --git a/src/service/rest/oidc_helper.h b/src/service/rest/oidc_helper.h index de788fbdb..d706daa6b 100644 --- a/src/service/rest/oidc_helper.h +++ b/src/service/rest/oidc_helper.h | |||
@@ -27,6 +27,8 @@ | |||
27 | #ifndef JWT_H | 27 | #ifndef JWT_H |
28 | #define JWT_H | 28 | #define JWT_H |
29 | 29 | ||
30 | #include "gnunet_util_lib.h" | ||
31 | #include "gnunet_reclaim_service.h" | ||
30 | #define JWT_ALG "alg" | 32 | #define JWT_ALG "alg" |
31 | #define JWT_TYP "typ" | 33 | #define JWT_TYP "typ" |
32 | #define JWT_TYP_VALUE "jwt" | 34 | #define JWT_TYP_VALUE "jwt" |
@@ -52,7 +54,7 @@ enum OIDC_VerificationOptions | |||
52 | /** | 54 | /** |
53 | * Create a JWT using RSA256 algorithm from attributes | 55 | * Create a JWT using RSA256 algorithm from attributes |
54 | * | 56 | * |
55 | * @param aud_key the public of the audience | 57 | * @param rp_uri the RP URI |
56 | * @param sub_key the public key of the subject | 58 | * @param sub_key the public key of the subject |
57 | * @param attrs the attribute list | 59 | * @param attrs the attribute list |
58 | * @param presentations credential presentation list (may be empty) | 60 | * @param presentations credential presentation list (may be empty) |
@@ -61,7 +63,7 @@ enum OIDC_VerificationOptions | |||
61 | * @return a new base64-encoded JWT string. | 63 | * @return a new base64-encoded JWT string. |
62 | */ | 64 | */ |
63 | char * | 65 | char * |
64 | OIDC_generate_id_token_rsa (const struct GNUNET_CRYPTO_PublicKey *aud_key, | 66 | OIDC_generate_id_token_rsa (const char *rp_uri, |
65 | const struct GNUNET_CRYPTO_PublicKey *sub_key, | 67 | const struct GNUNET_CRYPTO_PublicKey *sub_key, |
66 | const struct GNUNET_RECLAIM_AttributeList *attrs, | 68 | const struct GNUNET_RECLAIM_AttributeList *attrs, |
67 | const struct | 69 | const struct |
@@ -73,7 +75,7 @@ OIDC_generate_id_token_rsa (const struct GNUNET_CRYPTO_PublicKey *aud_key, | |||
73 | /** | 75 | /** |
74 | * Create a JWT using HMAC (HS256) from attributes | 76 | * Create a JWT using HMAC (HS256) from attributes |
75 | * | 77 | * |
76 | * @param aud_key the public of the audience | 78 | * @param rp_uri the RP URI |
77 | * @param sub_key the public key of the subject | 79 | * @param sub_key the public key of the subject |
78 | * @param attrs the attribute list | 80 | * @param attrs the attribute list |
79 | * @param presentations credential presentation list (may be empty) | 81 | * @param presentations credential presentation list (may be empty) |
@@ -82,7 +84,7 @@ OIDC_generate_id_token_rsa (const struct GNUNET_CRYPTO_PublicKey *aud_key, | |||
82 | * @return a new base64-encoded JWT string. | 84 | * @return a new base64-encoded JWT string. |
83 | */ | 85 | */ |
84 | char* | 86 | char* |
85 | OIDC_generate_id_token_hmac (const struct GNUNET_CRYPTO_PublicKey *aud_key, | 87 | OIDC_generate_id_token_hmac (const char *rp_uri, |
86 | const struct GNUNET_CRYPTO_PublicKey *sub_key, | 88 | const struct GNUNET_CRYPTO_PublicKey *sub_key, |
87 | const struct GNUNET_RECLAIM_AttributeList *attrs, | 89 | const struct GNUNET_RECLAIM_AttributeList *attrs, |
88 | const struct | 90 | const struct |
@@ -95,7 +97,7 @@ OIDC_generate_id_token_hmac (const struct GNUNET_CRYPTO_PublicKey *aud_key, | |||
95 | * Builds an OIDC authorization code including | 97 | * Builds an OIDC authorization code including |
96 | * a reclaim ticket and nonce | 98 | * a reclaim ticket and nonce |
97 | * | 99 | * |
98 | * @param issuer the issuer of the ticket, used to sign the ticket and nonce | 100 | * @param issuer the issuer |
99 | * @param ticket the ticket to include in the code | 101 | * @param ticket the ticket to include in the code |
100 | * @param attrs list of attributes to share | 102 | * @param attrs list of attributes to share |
101 | * @param presentations credential presentation list | 103 | * @param presentations credential presentation list |
@@ -118,7 +120,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_PrivateKey *issuer, | |||
118 | * authorization code. | 120 | * authorization code. |
119 | * This also verifies the signature in the code. | 121 | * This also verifies the signature in the code. |
120 | * | 122 | * |
121 | * @param ecdsa_priv the audience of the ticket | 123 | * @param rp_uri the RP URI |
122 | * @param code the string representation of the code | 124 | * @param code the string representation of the code |
123 | * @param code_verfier PKCE code verifier | 125 | * @param code_verfier PKCE code verifier |
124 | * @param ticket where to store the ticket | 126 | * @param ticket where to store the ticket |
@@ -128,14 +130,15 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_PrivateKey *issuer, | |||
128 | * @return GNUNET_OK if successful, else GNUNET_SYSERR | 130 | * @return GNUNET_OK if successful, else GNUNET_SYSERR |
129 | */ | 131 | */ |
130 | int | 132 | int |
131 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_PublicKey *ecdsa_pub, | 133 | OIDC_parse_authz_code (const char *rp_uri, |
134 | const struct GNUNET_CRYPTO_PublicKey *cid, | ||
132 | const char *code, | 135 | const char *code, |
133 | const char *code_verifier, | 136 | const char *code_verifier, |
134 | struct GNUNET_RECLAIM_Ticket *ticket, | 137 | struct GNUNET_RECLAIM_Ticket *ticket, |
135 | struct GNUNET_RECLAIM_AttributeList **attrs, | 138 | struct GNUNET_RECLAIM_AttributeList **attrs, |
136 | struct GNUNET_RECLAIM_PresentationList **presentations, | 139 | struct GNUNET_RECLAIM_PresentationList **presentations, |
137 | char **nonce, | 140 | char **nonce, |
138 | enum OIDC_VerificationOptions opts); | 141 | enum OIDC_VerificationOptions opts, char **emsg); |
139 | 142 | ||
140 | /** | 143 | /** |
141 | * Build a token response for a token request | 144 | * Build a token response for a token request |
@@ -156,14 +159,16 @@ OIDC_build_token_response (const char *access_token, | |||
156 | * Generate a new access token | 159 | * Generate a new access token |
157 | */ | 160 | */ |
158 | char* | 161 | char* |
159 | OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket); | 162 | OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket, |
163 | const char *rp_uri); | ||
160 | 164 | ||
161 | /** | 165 | /** |
162 | * Parse an access token | 166 | * Parse an access token |
163 | */ | 167 | */ |
164 | int | 168 | int |
165 | OIDC_access_token_parse (const char *token, | 169 | OIDC_access_token_parse (const char *token, |
166 | struct GNUNET_RECLAIM_Ticket **ticket); | 170 | struct GNUNET_RECLAIM_Ticket **ticket, |
171 | char **rp_uri); | ||
167 | 172 | ||
168 | 173 | ||
169 | /** | 174 | /** |
diff --git a/src/service/rest/openid_plugin.c b/src/service/rest/openid_plugin.c index 61904494b..fc1125690 100644 --- a/src/service/rest/openid_plugin.c +++ b/src/service/rest/openid_plugin.c | |||
@@ -34,12 +34,10 @@ | |||
34 | #include "gnunet_gns_service.h" | 34 | #include "gnunet_gns_service.h" |
35 | #include "gnunet_gnsrecord_lib.h" | 35 | #include "gnunet_gnsrecord_lib.h" |
36 | #include "gnunet_identity_service.h" | 36 | #include "gnunet_identity_service.h" |
37 | #include "gnunet_namestore_service.h" | ||
38 | #include "gnunet_reclaim_lib.h" | 37 | #include "gnunet_reclaim_lib.h" |
39 | #include "gnunet_reclaim_service.h" | 38 | #include "gnunet_reclaim_service.h" |
40 | #include "gnunet_rest_lib.h" | 39 | #include "gnunet_rest_lib.h" |
41 | #include "gnunet_rest_plugin.h" | 40 | #include "gnunet_rest_plugin.h" |
42 | #include "gnunet_signatures.h" | ||
43 | #include "microhttpd.h" | 41 | #include "microhttpd.h" |
44 | #include "oidc_helper.h" | 42 | #include "oidc_helper.h" |
45 | 43 | ||
@@ -242,7 +240,7 @@ | |||
242 | * How long to wait for a consume in userinfo endpoint | 240 | * How long to wait for a consume in userinfo endpoint |
243 | */ | 241 | */ |
244 | #define CONSUME_TIMEOUT GNUNET_TIME_relative_multiply ( \ | 242 | #define CONSUME_TIMEOUT GNUNET_TIME_relative_multiply ( \ |
245 | GNUNET_TIME_UNIT_SECONDS,2) | 243 | GNUNET_TIME_UNIT_SECONDS,2) |
246 | 244 | ||
247 | /** | 245 | /** |
248 | * OIDC ignored parameter array | 246 | * OIDC ignored parameter array |
@@ -1248,7 +1246,7 @@ oidc_cred_collect_finished_cb (void *cls) | |||
1248 | le_m->attribute->name); | 1246 | le_m->attribute->name); |
1249 | handle->idp_op = GNUNET_RECLAIM_ticket_issue (idp, | 1247 | handle->idp_op = GNUNET_RECLAIM_ticket_issue (idp, |
1250 | &handle->priv_key, | 1248 | &handle->priv_key, |
1251 | &handle->oidc->client_pkey, | 1249 | handle->oidc->client_id, |
1252 | merged_list, | 1250 | merged_list, |
1253 | &oidc_ticket_issue_cb, | 1251 | &oidc_ticket_issue_cb, |
1254 | handle); | 1252 | handle); |
@@ -2193,6 +2191,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2193 | char *oidc_jwk_path = NULL; | 2191 | char *oidc_jwk_path = NULL; |
2194 | char *oidc_directory = NULL; | 2192 | char *oidc_directory = NULL; |
2195 | char *tmp_at = NULL; | 2193 | char *tmp_at = NULL; |
2194 | char *received_cid = NULL; | ||
2196 | 2195 | ||
2197 | /* | 2196 | /* |
2198 | * Check Authorization | 2197 | * Check Authorization |
@@ -2204,6 +2203,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2204 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 2203 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
2205 | return; | 2204 | return; |
2206 | } | 2205 | } |
2206 | received_cid = get_url_parameter_copy (handle, OIDC_CLIENT_ID_KEY); | ||
2207 | 2207 | ||
2208 | /* | 2208 | /* |
2209 | * Check parameter | 2209 | * Check parameter |
@@ -2265,12 +2265,16 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2265 | } | 2265 | } |
2266 | 2266 | ||
2267 | // decode code | 2267 | // decode code |
2268 | if (GNUNET_OK != OIDC_parse_authz_code (&cid, code, code_verifier, &ticket, | 2268 | char *emsg = NULL; |
2269 | if (GNUNET_OK != OIDC_parse_authz_code (received_cid, &cid, code, | ||
2270 | code_verifier, | ||
2271 | &ticket, | ||
2269 | &cl, &pl, &nonce, | 2272 | &cl, &pl, &nonce, |
2270 | OIDC_VERIFICATION_DEFAULT)) | 2273 | OIDC_VERIFICATION_DEFAULT, |
2274 | &emsg)) | ||
2271 | { | 2275 | { |
2272 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); | 2276 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); |
2273 | handle->edesc = GNUNET_strdup ("invalid code"); | 2277 | handle->edesc = emsg; |
2274 | handle->response_code = MHD_HTTP_BAD_REQUEST; | 2278 | handle->response_code = MHD_HTTP_BAD_REQUEST; |
2275 | GNUNET_free (code); | 2279 | GNUNET_free (code); |
2276 | if (NULL != code_verifier) | 2280 | if (NULL != code_verifier) |
@@ -2311,6 +2315,9 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2311 | jwa = JWT_ALG_VALUE_RSA; | 2315 | jwa = JWT_ALG_VALUE_RSA; |
2312 | } | 2316 | } |
2313 | 2317 | ||
2318 | struct GNUNET_CRYPTO_PublicKey issuer; | ||
2319 | GNUNET_GNS_parse_ztld (ticket.gns_name, &issuer); | ||
2320 | |||
2314 | if (! strcmp (jwa, JWT_ALG_VALUE_RSA)) | 2321 | if (! strcmp (jwa, JWT_ALG_VALUE_RSA)) |
2315 | { | 2322 | { |
2316 | // Replace for now | 2323 | // Replace for now |
@@ -2338,8 +2345,8 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2338 | } | 2345 | } |
2339 | 2346 | ||
2340 | // Generate oidc token | 2347 | // Generate oidc token |
2341 | id_token = OIDC_generate_id_token_rsa (&ticket.audience, | 2348 | id_token = OIDC_generate_id_token_rsa (received_cid, |
2342 | &ticket.identity, | 2349 | &issuer, |
2343 | cl, | 2350 | cl, |
2344 | pl, | 2351 | pl, |
2345 | &expiration_time, | 2352 | &expiration_time, |
@@ -2366,8 +2373,8 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2366 | return; | 2373 | return; |
2367 | } | 2374 | } |
2368 | 2375 | ||
2369 | id_token = OIDC_generate_id_token_hmac (&ticket.audience, | 2376 | id_token = OIDC_generate_id_token_hmac (received_cid, |
2370 | &ticket.identity, | 2377 | &issuer, |
2371 | cl, | 2378 | cl, |
2372 | pl, | 2379 | pl, |
2373 | &expiration_time, | 2380 | &expiration_time, |
@@ -2383,7 +2390,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2383 | 2390 | ||
2384 | if (NULL != nonce) | 2391 | if (NULL != nonce) |
2385 | GNUNET_free (nonce); | 2392 | GNUNET_free (nonce); |
2386 | access_token = OIDC_access_token_new (&ticket); | 2393 | access_token = OIDC_access_token_new (&ticket, handle->oidc->redirect_uri); |
2387 | /** | 2394 | /** |
2388 | * Store mapping from access token to code so we can later | 2395 | * Store mapping from access token to code so we can later |
2389 | * fall back on the provided attributes in userinfo one time. | 2396 | * fall back on the provided attributes in userinfo one time. |
@@ -2481,7 +2488,15 @@ consume_ticket (void *cls, | |||
2481 | 2488 | ||
2482 | if (NULL == identity) | 2489 | if (NULL == identity) |
2483 | { | 2490 | { |
2484 | result_str = OIDC_generate_userinfo (&handle->ticket.identity, | 2491 | char *tmp = GNUNET_strdup (handle->ticket.gns_name); |
2492 | GNUNET_assert (NULL != strtok (tmp, ".")); | ||
2493 | char *key = strtok (NULL, "."); | ||
2494 | struct GNUNET_CRYPTO_PublicKey issuer; | ||
2495 | GNUNET_assert (NULL != key); | ||
2496 | GNUNET_assert (GNUNET_OK == | ||
2497 | GNUNET_CRYPTO_public_key_from_string (key, &issuer)); | ||
2498 | GNUNET_free (tmp); | ||
2499 | result_str = OIDC_generate_userinfo (&issuer, | ||
2485 | handle->attr_userinfo_list, | 2500 | handle->attr_userinfo_list, |
2486 | handle->presentations); | 2501 | handle->presentations); |
2487 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str); | 2502 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str); |
@@ -2538,11 +2553,12 @@ consume_fail (void *cls) | |||
2538 | struct GNUNET_RECLAIM_AttributeList *cl = NULL; | 2553 | struct GNUNET_RECLAIM_AttributeList *cl = NULL; |
2539 | struct GNUNET_RECLAIM_PresentationList *pl = NULL; | 2554 | struct GNUNET_RECLAIM_PresentationList *pl = NULL; |
2540 | struct GNUNET_RECLAIM_Ticket ticket; | 2555 | struct GNUNET_RECLAIM_Ticket ticket; |
2556 | struct GNUNET_CRYPTO_PublicKey cid; | ||
2541 | struct MHD_Response *resp; | 2557 | struct MHD_Response *resp; |
2542 | char *nonce; | 2558 | char *nonce; |
2543 | char *cached_code; | 2559 | char *cached_code; |
2544 | char *result_str; | 2560 | char *result_str; |
2545 | 2561 | char *received_cid; | |
2546 | 2562 | ||
2547 | handle->consume_timeout_op = NULL; | 2563 | handle->consume_timeout_op = NULL; |
2548 | if (NULL != handle->idp_op) | 2564 | if (NULL != handle->idp_op) |
@@ -2571,15 +2587,21 @@ consume_fail (void *cls) | |||
2571 | GNUNET_CONTAINER_multihashmap_remove (oidc_code_cache, | 2587 | GNUNET_CONTAINER_multihashmap_remove (oidc_code_cache, |
2572 | &cache_key, | 2588 | &cache_key, |
2573 | cached_code)); | 2589 | cached_code)); |
2590 | received_cid = get_url_parameter_copy (handle, OIDC_CLIENT_ID_KEY); | ||
2591 | GNUNET_STRINGS_string_to_data (received_cid, | ||
2592 | strlen (received_cid), | ||
2593 | &cid, | ||
2594 | sizeof(struct GNUNET_CRYPTO_PublicKey)); | ||
2574 | 2595 | ||
2575 | // decode code | 2596 | // decode code |
2576 | if (GNUNET_OK != OIDC_parse_authz_code (&handle->ticket.audience, | 2597 | char *emsg; |
2598 | if (GNUNET_OK != OIDC_parse_authz_code (received_cid, &cid, | ||
2577 | cached_code, NULL, &ticket, | 2599 | cached_code, NULL, &ticket, |
2578 | &cl, &pl, &nonce, | 2600 | &cl, &pl, &nonce, |
2579 | OIDC_VERIFICATION_NO_CODE_VERIFIER)) | 2601 | OIDC_VERIFICATION_NO_CODE_VERIFIER, &emsg)) |
2580 | { | 2602 | { |
2581 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); | 2603 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); |
2582 | handle->edesc = GNUNET_strdup ("invalid code"); | 2604 | handle->edesc = emsg; |
2583 | handle->response_code = MHD_HTTP_BAD_REQUEST; | 2605 | handle->response_code = MHD_HTTP_BAD_REQUEST; |
2584 | GNUNET_free (cached_code); | 2606 | GNUNET_free (cached_code); |
2585 | if (NULL != nonce) | 2607 | if (NULL != nonce) |
@@ -2590,7 +2612,15 @@ consume_fail (void *cls) | |||
2590 | 2612 | ||
2591 | GNUNET_free (cached_code); | 2613 | GNUNET_free (cached_code); |
2592 | 2614 | ||
2593 | result_str = OIDC_generate_userinfo (&handle->ticket.identity, | 2615 | char *tmp = GNUNET_strdup (handle->ticket.gns_name); |
2616 | GNUNET_assert (NULL != strtok (tmp, ".")); | ||
2617 | char *key = strtok (NULL, "."); | ||
2618 | struct GNUNET_CRYPTO_PublicKey issuer; | ||
2619 | GNUNET_assert (NULL != key); | ||
2620 | GNUNET_assert (GNUNET_OK == | ||
2621 | GNUNET_CRYPTO_public_key_from_string (key, &issuer)); | ||
2622 | GNUNET_free (tmp); | ||
2623 | result_str = OIDC_generate_userinfo (&issuer, | ||
2594 | cl, | 2624 | cl, |
2595 | pl); | 2625 | pl); |
2596 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str); | 2626 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str); |
@@ -2624,8 +2654,6 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2624 | char *authorization; | 2654 | char *authorization; |
2625 | char *authorization_type; | 2655 | char *authorization_type; |
2626 | char *authorization_access_token; | 2656 | char *authorization_access_token; |
2627 | const struct EgoEntry *aud_ego; | ||
2628 | const struct GNUNET_CRYPTO_PrivateKey *privkey; | ||
2629 | 2657 | ||
2630 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting userinfo\n"); | 2658 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting userinfo\n"); |
2631 | GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, | 2659 | GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, |
@@ -2669,8 +2697,9 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2669 | return; | 2697 | return; |
2670 | } | 2698 | } |
2671 | 2699 | ||
2700 | char *rp_uri; | ||
2672 | if (GNUNET_OK != OIDC_access_token_parse (authorization_access_token, | 2701 | if (GNUNET_OK != OIDC_access_token_parse (authorization_access_token, |
2673 | &ticket)) | 2702 | &ticket, &rp_uri)) |
2674 | { | 2703 | { |
2675 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); | 2704 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); |
2676 | handle->edesc = GNUNET_strdup ("The access token is invalid"); | 2705 | handle->edesc = GNUNET_strdup ("The access token is invalid"); |
@@ -2683,18 +2712,7 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2683 | GNUNET_assert (NULL != ticket); | 2712 | GNUNET_assert (NULL != ticket); |
2684 | handle->ticket = *ticket; | 2713 | handle->ticket = *ticket; |
2685 | GNUNET_free (ticket); | 2714 | GNUNET_free (ticket); |
2686 | aud_ego = find_ego (handle, &handle->ticket.audience); | ||
2687 | if (NULL == aud_ego) | ||
2688 | { | ||
2689 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); | ||
2690 | handle->edesc = GNUNET_strdup ("The access token expired"); | ||
2691 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
2692 | GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle); | ||
2693 | GNUNET_free (authorization); | ||
2694 | return; | ||
2695 | } | ||
2696 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Consuming ticket\n"); | 2715 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Consuming ticket\n"); |
2697 | privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego); | ||
2698 | handle->attr_userinfo_list = | 2716 | handle->attr_userinfo_list = |
2699 | GNUNET_new (struct GNUNET_RECLAIM_AttributeList); | 2717 | GNUNET_new (struct GNUNET_RECLAIM_AttributeList); |
2700 | handle->presentations = | 2718 | handle->presentations = |
@@ -2706,11 +2724,12 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2706 | &consume_fail, | 2724 | &consume_fail, |
2707 | handle); | 2725 | handle); |
2708 | handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, | 2726 | handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, |
2709 | privkey, | ||
2710 | &handle->ticket, | 2727 | &handle->ticket, |
2728 | rp_uri, | ||
2711 | &consume_ticket, | 2729 | &consume_ticket, |
2712 | handle); | 2730 | handle); |
2713 | GNUNET_free (authorization); | 2731 | GNUNET_free (authorization); |
2732 | GNUNET_free (rp_uri); | ||
2714 | } | 2733 | } |
2715 | 2734 | ||
2716 | 2735 | ||
diff --git a/src/service/rest/reclaim_plugin.c b/src/service/rest/reclaim_plugin.c index e1afce00b..10b6b7bdc 100644 --- a/src/service/rest/reclaim_plugin.c +++ b/src/service/rest/reclaim_plugin.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * | 25 | * |
26 | */ | 26 | */ |
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_json_lib.h" | ||
28 | #include "microhttpd.h" | 29 | #include "microhttpd.h" |
29 | #include <inttypes.h> | 30 | #include <inttypes.h> |
30 | #include <jansson.h> | 31 | #include <jansson.h> |
@@ -434,37 +435,19 @@ collect_finished_cb (void *cls) | |||
434 | * | 435 | * |
435 | */ | 436 | */ |
436 | static void | 437 | static void |
437 | ticket_collect (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) | 438 | ticket_collect (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket, |
439 | const char *rp_uri) | ||
438 | { | 440 | { |
439 | json_t *json_resource; | 441 | json_t *json_resource; |
440 | struct RequestHandle *handle = cls; | 442 | struct RequestHandle *handle = cls; |
441 | json_t *value; | ||
442 | char *tmp; | ||
443 | 443 | ||
444 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding ticket\n"); | 444 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding ticket\n"); |
445 | tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof(ticket->rnd)); | ||
446 | json_resource = json_object (); | 445 | json_resource = json_object (); |
447 | GNUNET_free (tmp); | ||
448 | json_array_append (handle->resp_object, json_resource); | 446 | json_array_append (handle->resp_object, json_resource); |
449 | 447 | ||
450 | tmp = | 448 | json_object_set_new (json_resource, "gns_name", json_string (ticket->gns_name) |
451 | GNUNET_STRINGS_data_to_string_alloc (&ticket->identity, | 449 | ); |
452 | sizeof(struct | 450 | json_object_set_new (json_resource, "rp_uri", json_string (rp_uri)); |
453 | GNUNET_CRYPTO_PublicKey)); | ||
454 | value = json_string (tmp); | ||
455 | json_object_set_new (json_resource, "issuer", value); | ||
456 | GNUNET_free (tmp); | ||
457 | tmp = | ||
458 | GNUNET_STRINGS_data_to_string_alloc (&ticket->audience, | ||
459 | sizeof(struct | ||
460 | GNUNET_CRYPTO_PublicKey)); | ||
461 | value = json_string (tmp); | ||
462 | json_object_set_new (json_resource, "audience", value); | ||
463 | GNUNET_free (tmp); | ||
464 | tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof(ticket->rnd)); | ||
465 | value = json_string (tmp); | ||
466 | json_object_set_new (json_resource, "rnd", value); | ||
467 | GNUNET_free (tmp); | ||
468 | GNUNET_RECLAIM_ticket_iteration_next (handle->ticket_it); | 451 | GNUNET_RECLAIM_ticket_iteration_next (handle->ticket_it); |
469 | } | 452 | } |
470 | 453 | ||
@@ -937,7 +920,8 @@ parse_jwt (const struct GNUNET_RECLAIM_Credential *cred, | |||
937 | type_str = "String"; | 920 | type_str = "String"; |
938 | type = GNUNET_RECLAIM_attribute_typename_to_number (type_str); | 921 | type = GNUNET_RECLAIM_attribute_typename_to_number (type_str); |
939 | if (GNUNET_SYSERR == GNUNET_RECLAIM_attribute_string_to_value (type,val_str, | 922 | if (GNUNET_SYSERR == GNUNET_RECLAIM_attribute_string_to_value (type,val_str, |
940 | (void **) &data, | 923 | (void **) &data |
924 | , | ||
941 | &data_size)) | 925 | &data_size)) |
942 | { | 926 | { |
943 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 927 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1133,6 +1117,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1133 | struct RequestHandle *handle = cls; | 1117 | struct RequestHandle *handle = cls; |
1134 | struct EgoEntry *ego_entry; | 1118 | struct EgoEntry *ego_entry; |
1135 | struct GNUNET_RECLAIM_Ticket *ticket = NULL; | 1119 | struct GNUNET_RECLAIM_Ticket *ticket = NULL; |
1120 | struct GNUNET_CRYPTO_PublicKey iss; | ||
1136 | struct GNUNET_CRYPTO_PublicKey tmp_pk; | 1121 | struct GNUNET_CRYPTO_PublicKey tmp_pk; |
1137 | char term_data[handle->rest_handle->data_size + 1]; | 1122 | char term_data[handle->rest_handle->data_size + 1]; |
1138 | json_t *data_json; | 1123 | json_t *data_json; |
@@ -1171,11 +1156,13 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1171 | return; | 1156 | return; |
1172 | } | 1157 | } |
1173 | 1158 | ||
1159 | GNUNET_assert (GNUNET_OK == GNUNET_GNS_parse_ztld (ticket->gns_name, &iss)); | ||
1160 | |||
1174 | for (ego_entry = ego_head; NULL != ego_entry; | 1161 | for (ego_entry = ego_head; NULL != ego_entry; |
1175 | ego_entry = ego_entry->next) | 1162 | ego_entry = ego_entry->next) |
1176 | { | 1163 | { |
1177 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); | 1164 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); |
1178 | if (0 == memcmp (&ticket->identity, | 1165 | if (0 == memcmp (&iss, |
1179 | &tmp_pk, | 1166 | &tmp_pk, |
1180 | sizeof(struct GNUNET_CRYPTO_PublicKey))) | 1167 | sizeof(struct GNUNET_CRYPTO_PublicKey))) |
1181 | break; | 1168 | break; |
@@ -1236,16 +1223,16 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1236 | const char *url, | 1223 | const char *url, |
1237 | void *cls) | 1224 | void *cls) |
1238 | { | 1225 | { |
1239 | const struct GNUNET_CRYPTO_PrivateKey *identity_priv; | ||
1240 | struct RequestHandle *handle = cls; | 1226 | struct RequestHandle *handle = cls; |
1241 | struct EgoEntry *ego_entry; | ||
1242 | struct GNUNET_RECLAIM_Ticket *ticket; | 1227 | struct GNUNET_RECLAIM_Ticket *ticket; |
1243 | struct GNUNET_CRYPTO_PublicKey tmp_pk; | ||
1244 | char term_data[handle->rest_handle->data_size + 1]; | 1228 | char term_data[handle->rest_handle->data_size + 1]; |
1229 | const char *rp_uri; | ||
1245 | json_t *data_json; | 1230 | json_t *data_json; |
1246 | json_error_t err; | 1231 | json_error_t err; |
1247 | struct GNUNET_JSON_Specification tktspec[] = | 1232 | struct GNUNET_JSON_Specification tktspec[] = |
1248 | { GNUNET_RECLAIM_JSON_spec_ticket (&ticket), GNUNET_JSON_spec_end () }; | 1233 | { GNUNET_RECLAIM_JSON_spec_ticket (&ticket), |
1234 | GNUNET_JSON_spec_string ("rp_uri", &rp_uri), | ||
1235 | GNUNET_JSON_spec_end () }; | ||
1249 | 1236 | ||
1250 | if (0 >= handle->rest_handle->data_size) | 1237 | if (0 >= handle->rest_handle->data_size) |
1251 | { | 1238 | { |
@@ -1274,26 +1261,10 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1274 | json_decref (data_json); | 1261 | json_decref (data_json); |
1275 | return; | 1262 | return; |
1276 | } | 1263 | } |
1277 | for (ego_entry = ego_head; NULL != ego_entry; | ||
1278 | ego_entry = ego_entry->next) | ||
1279 | { | ||
1280 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); | ||
1281 | if (0 == memcmp (&ticket->audience, | ||
1282 | &tmp_pk, | ||
1283 | sizeof(struct GNUNET_CRYPTO_PublicKey))) | ||
1284 | break; | ||
1285 | } | ||
1286 | if (NULL == ego_entry) | ||
1287 | { | ||
1288 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown\n"); | ||
1289 | GNUNET_JSON_parse_free (tktspec); | ||
1290 | return; | ||
1291 | } | ||
1292 | identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | ||
1293 | handle->resp_object = json_object (); | 1264 | handle->resp_object = json_object (); |
1294 | handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, | 1265 | handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, |
1295 | identity_priv, | ||
1296 | ticket, | 1266 | ticket, |
1267 | rp_uri, | ||
1297 | &consume_cont, | 1268 | &consume_cont, |
1298 | handle); | 1269 | handle); |
1299 | GNUNET_JSON_parse_free (tktspec); | 1270 | GNUNET_JSON_parse_free (tktspec); |
diff --git a/src/service/setu/gnunet-service-setu_strata_estimator.c b/src/service/setu/gnunet-service-setu_strata_estimator.c index 43ccf3afd..e5af92980 100644 --- a/src/service/setu/gnunet-service-setu_strata_estimator.c +++ b/src/service/setu/gnunet-service-setu_strata_estimator.c | |||
@@ -331,6 +331,12 @@ strata_estimator_create (unsigned int strata_count, | |||
331 | "Failed to allocate memory for strata estimator\n"); | 331 | "Failed to allocate memory for strata estimator\n"); |
332 | for (j = 0; j < i; j++) | 332 | for (j = 0; j < i; j++) |
333 | ibf_destroy (se->stratas[strata_ctr]->strata[i]); | 333 | ibf_destroy (se->stratas[strata_ctr]->strata[i]); |
334 | for (j = 0; j <= strata_ctr; j++) | ||
335 | { | ||
336 | GNUNET_free (se->stratas[j]->strata); | ||
337 | GNUNET_free (se->stratas[j]); | ||
338 | } | ||
339 | GNUNET_free (se->stratas); | ||
334 | GNUNET_free (se); | 340 | GNUNET_free (se); |
335 | return NULL; | 341 | return NULL; |
336 | } | 342 | } |
@@ -463,6 +469,8 @@ strata_estimator_destroy (struct MultiStrataEstimator *se) | |||
463 | for (i = 0; i < se->stratas[strata_ctr]->strata_count; i++) | 469 | for (i = 0; i < se->stratas[strata_ctr]->strata_count; i++) |
464 | ibf_destroy (se->stratas[strata_ctr]->strata[i]); | 470 | ibf_destroy (se->stratas[strata_ctr]->strata[i]); |
465 | GNUNET_free (se->stratas[strata_ctr]->strata); | 471 | GNUNET_free (se->stratas[strata_ctr]->strata); |
472 | GNUNET_free (se->stratas[strata_ctr]); | ||
466 | } | 473 | } |
474 | GNUNET_free (se->stratas); | ||
467 | GNUNET_free (se); | 475 | GNUNET_free (se); |
468 | } | 476 | } |
diff --git a/src/service/testbed/.gitignore b/src/service/testbed/.gitignore new file mode 100644 index 000000000..a5fa57a36 --- /dev/null +++ b/src/service/testbed/.gitignore | |||
@@ -0,0 +1 @@ | |||
gnunet-testbed | |||
diff --git a/src/service/testbed/Makefile.am b/src/service/testbed/Makefile.am new file mode 100644 index 000000000..6ba64ffbc --- /dev/null +++ b/src/service/testbed/Makefile.am | |||
@@ -0,0 +1,53 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | ||
3 | |||
4 | if USE_COVERAGE | ||
5 | AM_CFLAGS = --coverage -O0 | ||
6 | XLIB = -lgcov | ||
7 | endif | ||
8 | |||
9 | libexecdir= $(pkglibdir)/libexec/ | ||
10 | |||
11 | pkgcfgdir= $(pkgdatadir)/config.d/ | ||
12 | |||
13 | lib_LTLIBRARIES = \ | ||
14 | libgnunettestbed.la \ | ||
15 | libgnunettestingtestbed.la | ||
16 | |||
17 | libgnunettestbed_la_SOURCES = \ | ||
18 | testbed.c | ||
19 | libgnunettestbed_la_LIBADD = \ | ||
20 | $(top_builddir)/src/lib/util/libgnunetutil.la | ||
21 | |||
22 | libgnunettestingtestbed_la_SOURCES = \ | ||
23 | testbed_api_cmd_system_create.c \ | ||
24 | testing_testbed_traits.c | ||
25 | libgnunettestingtestbed_la_LIBADD = \ | ||
26 | libgnunettestbed.la \ | ||
27 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ | ||
28 | $(top_builddir)/src/lib/util/libgnunetutil.la | ||
29 | |||
30 | |||
31 | bin_PROGRAMS = \ | ||
32 | gnunet-testbed | ||
33 | |||
34 | gnunet_testbed_SOURCES = \ | ||
35 | gnunet-testbed.c | ||
36 | gnunet_testbed_LDADD = \ | ||
37 | libgnunettestbed.la \ | ||
38 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
39 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ | ||
40 | $(GN_LIBINTL) | ||
41 | |||
42 | check_PROGRAMS = \ | ||
43 | test_testbed_portreservation | ||
44 | |||
45 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | ||
46 | # TESTS = \ | ||
47 | # test_testbed_portreservation | ||
48 | |||
49 | test_testbed_portreservation_SOURCES = \ | ||
50 | test_testbed_portreservation.c | ||
51 | test_testbed_portreservation_LDADD = \ | ||
52 | libgnunettestbed.la \ | ||
53 | $(top_builddir)/src/lib/util/libgnunetutil.la | ||
diff --git a/src/service/testbed/gnunet-testbed.c b/src/service/testbed/gnunet-testbed.c new file mode 100644 index 000000000..91f18cc2c --- /dev/null +++ b/src/service/testbed/gnunet-testbed.c | |||
@@ -0,0 +1,223 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009 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 FORp 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 testbed/gnunet-testbed.c | ||
23 | * @brief tool to use testing functionality from cmd line | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testbed_lib.h" | ||
29 | |||
30 | |||
31 | #define LOG(kind, ...) GNUNET_log_from (kind, "gnunet-testbed", __VA_ARGS__) | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Final status code. | ||
36 | */ | ||
37 | static int ret; | ||
38 | |||
39 | /** | ||
40 | * Number of config files to create. | ||
41 | */ | ||
42 | static unsigned int create_no; | ||
43 | |||
44 | /** | ||
45 | * Filename of the config template to be written. | ||
46 | */ | ||
47 | static char *create_cfg_template; | ||
48 | |||
49 | |||
50 | static int | ||
51 | create_unique_cfgs (const char *template, | ||
52 | const unsigned int no) | ||
53 | { | ||
54 | struct GNUNET_TESTBED_System *system; | ||
55 | int fail; | ||
56 | char *cur_file; | ||
57 | struct GNUNET_CONFIGURATION_Handle *cfg_new; | ||
58 | struct GNUNET_CONFIGURATION_Handle *cfg_tmpl; | ||
59 | |||
60 | if (GNUNET_NO == GNUNET_DISK_file_test (template)) | ||
61 | { | ||
62 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
63 | "Configuration template `%s': file not found\n", | ||
64 | create_cfg_template); | ||
65 | return 1; | ||
66 | } | ||
67 | cfg_tmpl = GNUNET_CONFIGURATION_create (); | ||
68 | |||
69 | /* load template */ | ||
70 | if ((create_cfg_template != NULL) && | ||
71 | (GNUNET_OK != | ||
72 | GNUNET_CONFIGURATION_load (cfg_tmpl, | ||
73 | create_cfg_template))) | ||
74 | { | ||
75 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
76 | "Could not load template `%s'\n", | ||
77 | create_cfg_template); | ||
78 | GNUNET_CONFIGURATION_destroy (cfg_tmpl); | ||
79 | |||
80 | return 1; | ||
81 | } | ||
82 | /* load defaults */ | ||
83 | if (GNUNET_OK != | ||
84 | GNUNET_CONFIGURATION_load (cfg_tmpl, | ||
85 | NULL)) | ||
86 | { | ||
87 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
88 | "Could not load template `%s'\n", | ||
89 | create_cfg_template); | ||
90 | GNUNET_CONFIGURATION_destroy (cfg_tmpl); | ||
91 | return 1; | ||
92 | } | ||
93 | |||
94 | fail = GNUNET_NO; | ||
95 | system = | ||
96 | GNUNET_TESTBED_system_create ("testing", | ||
97 | NULL /* controller */, | ||
98 | NULL); | ||
99 | for (unsigned int cur = 0; cur < no; cur++) | ||
100 | { | ||
101 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
102 | "Creating configuration no. %u \n", | ||
103 | cur); | ||
104 | if (create_cfg_template != NULL) | ||
105 | GNUNET_asprintf (&cur_file, "%04u-%s", cur, create_cfg_template); | ||
106 | else | ||
107 | GNUNET_asprintf (&cur_file, "%04u%s", cur, ".conf"); | ||
108 | |||
109 | cfg_new = GNUNET_CONFIGURATION_dup (cfg_tmpl); | ||
110 | if (GNUNET_OK != GNUNET_TESTBED_configuration_create (system, cfg_new)) | ||
111 | { | ||
112 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
113 | "Could not create another configuration\n"); | ||
114 | GNUNET_CONFIGURATION_destroy (cfg_new); | ||
115 | fail = GNUNET_YES; | ||
116 | break; | ||
117 | } | ||
118 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
119 | "Writing configuration no. %u to file `%s' \n", | ||
120 | cur, | ||
121 | cur_file); | ||
122 | if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg_new, cur_file)) | ||
123 | { | ||
124 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
125 | "Failed to write configuration no. %u \n", | ||
126 | cur); | ||
127 | fail = GNUNET_YES; | ||
128 | } | ||
129 | GNUNET_CONFIGURATION_destroy (cfg_new); | ||
130 | GNUNET_free (cur_file); | ||
131 | if (GNUNET_YES == fail) | ||
132 | break; | ||
133 | } | ||
134 | GNUNET_CONFIGURATION_destroy (cfg_tmpl); | ||
135 | GNUNET_TESTBED_system_destroy (system, GNUNET_NO); | ||
136 | if (GNUNET_YES == fail) | ||
137 | return 1; | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | |||
142 | /** | ||
143 | * Main function that will be running without scheduler. | ||
144 | * | ||
145 | * @param cls closure | ||
146 | * @param args remaining command-line arguments | ||
147 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
148 | * @param cfg configuration | ||
149 | */ | ||
150 | static void | ||
151 | run_no_scheduler (void *cls, | ||
152 | char *const *args, | ||
153 | const char *cfgfile, | ||
154 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
155 | { | ||
156 | if (create_no > 0) | ||
157 | { | ||
158 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
159 | "Creating %u configuration files based on template `%s'\n", | ||
160 | create_no, | ||
161 | create_cfg_template); | ||
162 | ret = create_unique_cfgs (create_cfg_template, | ||
163 | create_no); | ||
164 | } | ||
165 | else | ||
166 | { | ||
167 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
168 | "Missing arguments!\n"); | ||
169 | ret = 1; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | |||
174 | /** | ||
175 | * The main function. | ||
176 | * | ||
177 | * @param argc number of arguments from the command line | ||
178 | * @param argv command line arguments | ||
179 | * @return 0 ok, 1 on error | ||
180 | */ | ||
181 | int | ||
182 | main (int argc, char *const *argv) | ||
183 | { | ||
184 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
185 | GNUNET_GETOPT_option_uint ( | ||
186 | 'n', | ||
187 | "number", | ||
188 | "NUMBER", | ||
189 | gettext_noop ("number of unique configuration files to create"), | ||
190 | &create_no), | ||
191 | GNUNET_GETOPT_option_string ( | ||
192 | 't', | ||
193 | "template", | ||
194 | "FILENAME", | ||
195 | gettext_noop ("configuration template"), | ||
196 | &create_cfg_template), | ||
197 | GNUNET_GETOPT_OPTION_END | ||
198 | }; | ||
199 | |||
200 | if (GNUNET_OK != | ||
201 | GNUNET_STRINGS_get_utf8_args (argc, argv, | ||
202 | &argc, &argv)) | ||
203 | return 2; | ||
204 | |||
205 | ret = | ||
206 | (GNUNET_OK == | ||
207 | GNUNET_PROGRAM_run2 (argc, | ||
208 | argv, | ||
209 | "gnunet-testing", | ||
210 | gettext_noop ( | ||
211 | "Command line tool to access the testing library"), | ||
212 | options, | ||
213 | &run_no_scheduler, | ||
214 | NULL, | ||
215 | GNUNET_YES)) | ||
216 | ? ret | ||
217 | : 1; | ||
218 | GNUNET_free_nz ((void *) argv); | ||
219 | return ret; | ||
220 | } | ||
221 | |||
222 | |||
223 | /* end of gnunet-testbed.c */ | ||
diff --git a/src/service/testing/test_testing_portreservation.c b/src/service/testbed/test_testbed_portreservation.c index df3d8d523..f42b81150 100644 --- a/src/service/testing/test_testing_portreservation.c +++ b/src/service/testbed/test_testbed_portreservation.c | |||
@@ -19,7 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file testing/test_testing_new_portreservation.c | 22 | * @file testing/test_testbed_portreservation.c |
23 | * @brief test case for testing port reservation routines from the new testing | 23 | * @brief test case for testing port reservation routines from the new testing |
24 | * library API | 24 | * library API |
25 | * @author Sree Harsha Totakura | 25 | * @author Sree Harsha Totakura |
@@ -27,10 +27,10 @@ | |||
27 | 27 | ||
28 | #include "platform.h" | 28 | #include "platform.h" |
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | #include "gnunet_testing_lib.h" | 30 | #include "gnunet_testbed_lib.h" |
31 | 31 | ||
32 | #define LOG(kind, ...) \ | 32 | #define LOG(kind, ...) \ |
33 | GNUNET_log (kind, __VA_ARGS__) | 33 | GNUNET_log (kind, __VA_ARGS__) |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * The status of the test | 36 | * The status of the test |
@@ -44,39 +44,39 @@ static void | |||
44 | run (void *cls, char *const *args, const char *cfgfile, | 44 | run (void *cls, char *const *args, const char *cfgfile, |
45 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 45 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
46 | { | 46 | { |
47 | struct GNUNET_TESTING_System *system; | 47 | struct GNUNET_TESTBED_System *system; |
48 | uint16_t new_port1; | 48 | uint16_t new_port1; |
49 | uint16_t new_port2; | 49 | uint16_t new_port2; |
50 | uint16_t old_port1; | 50 | uint16_t old_port1; |
51 | 51 | ||
52 | system = GNUNET_TESTING_system_create ("/tmp/gnunet-testing-new", | 52 | system = GNUNET_TESTBED_system_create ("/tmp/gnunet-testing-new", |
53 | "localhost", NULL, NULL); | 53 | "localhost", NULL, NULL); |
54 | GNUNET_assert (NULL != system); | 54 | GNUNET_assert (NULL != system); |
55 | new_port1 = GNUNET_TESTING_reserve_port (system); | 55 | new_port1 = GNUNET_TESTBED_reserve_port (system); |
56 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 56 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
57 | "Reserved TCP port %u\n", new_port1); | 57 | "Reserved TCP port %u\n", new_port1); |
58 | if (0 == new_port1) | 58 | if (0 == new_port1) |
59 | goto end; | 59 | goto end; |
60 | new_port2 = GNUNET_TESTING_reserve_port (system); | 60 | new_port2 = GNUNET_TESTBED_reserve_port (system); |
61 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 61 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
62 | "Reserved TCP port %u\n", new_port2); | 62 | "Reserved TCP port %u\n", new_port2); |
63 | if (0 == new_port2) | 63 | if (0 == new_port2) |
64 | goto end; | 64 | goto end; |
65 | GNUNET_assert (new_port1 != new_port2); | 65 | GNUNET_assert (new_port1 != new_port2); |
66 | GNUNET_TESTING_release_port (system, new_port1); | 66 | GNUNET_TESTBED_release_port (system, new_port1); |
67 | old_port1 = new_port1; | 67 | old_port1 = new_port1; |
68 | new_port1 = 0; | 68 | new_port1 = 0; |
69 | new_port1 = GNUNET_TESTING_reserve_port (system); | 69 | new_port1 = GNUNET_TESTBED_reserve_port (system); |
70 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 70 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
71 | "Reserved TCP port %u\n", new_port1); | 71 | "Reserved TCP port %u\n", new_port1); |
72 | GNUNET_assert (0 != new_port1); | 72 | GNUNET_assert (0 != new_port1); |
73 | GNUNET_assert (old_port1 == new_port1); | 73 | GNUNET_assert (old_port1 == new_port1); |
74 | GNUNET_TESTING_release_port (system, new_port1); | 74 | GNUNET_TESTBED_release_port (system, new_port1); |
75 | GNUNET_TESTING_release_port (system, new_port2); | 75 | GNUNET_TESTBED_release_port (system, new_port2); |
76 | status = GNUNET_OK; | 76 | status = GNUNET_OK; |
77 | 77 | ||
78 | end: | 78 | end: |
79 | GNUNET_TESTING_system_destroy (system, GNUNET_YES); | 79 | GNUNET_TESTBED_system_destroy (system, GNUNET_YES); |
80 | } | 80 | } |
81 | 81 | ||
82 | 82 | ||
@@ -91,9 +91,9 @@ main (int argc, char *argv[]) | |||
91 | if (GNUNET_OK != | 91 | if (GNUNET_OK != |
92 | GNUNET_PROGRAM_run (argc, | 92 | GNUNET_PROGRAM_run (argc, |
93 | argv, | 93 | argv, |
94 | "test_testing_new_portreservation", | 94 | "test_testbed_new_portreservation", |
95 | "test case for testing port reservation routines" | 95 | "test case for testing port reservation routines" |
96 | " from the new testing library API", | 96 | " from the new testeb library API", |
97 | options, | 97 | options, |
98 | &run, | 98 | &run, |
99 | NULL)) | 99 | NULL)) |
@@ -102,4 +102,4 @@ main (int argc, char *argv[]) | |||
102 | } | 102 | } |
103 | 103 | ||
104 | 104 | ||
105 | /* end of test_testing_portreservation.c */ | 105 | /* end of test_testbed_portreservation.c */ |
diff --git a/src/service/testbed/testbed.c b/src/service/testbed/testbed.c new file mode 100644 index 000000000..7cf2d352a --- /dev/null +++ b/src/service/testbed/testbed.c | |||
@@ -0,0 +1,579 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2008, 2009, 2012 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 testbed.c | ||
23 | * @brief | ||
24 | * @author Christian Grothoff | ||
25 | * | ||
26 | */ | ||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_testbed_lib.h" | ||
30 | |||
31 | #define LOG(kind, ...) GNUNET_log_from (kind, "testing-api", __VA_ARGS__) | ||
32 | |||
33 | /** | ||
34 | * Lowest port used for GNUnet testing. Should be high enough to not | ||
35 | * conflict with other applications running on the hosts but be low | ||
36 | * enough to not conflict with client-ports (typically starting around | ||
37 | * 32k). | ||
38 | */ | ||
39 | #define LOW_PORT 12000 | ||
40 | |||
41 | /** | ||
42 | * Highest port used for GNUnet testing. Should be low enough to not | ||
43 | * conflict with the port range for "local" ports (client apps; see | ||
44 | * /proc/sys/net/ipv4/ip_local_port_range on Linux for example). | ||
45 | */ | ||
46 | #define HIGH_PORT 56000 | ||
47 | |||
48 | |||
49 | /** | ||
50 | * Handle for a system on which GNUnet peers are executed; | ||
51 | * a system is used for reserving unique paths and ports. | ||
52 | */ | ||
53 | struct GNUNET_TESTBED_System | ||
54 | { | ||
55 | /** | ||
56 | * Prefix (e.g. "/tmp/gnunet-testing/") we prepend to each | ||
57 | * GNUNET_HOME. | ||
58 | */ | ||
59 | char *tmppath; | ||
60 | |||
61 | /** | ||
62 | * The trusted ip. Can either be a single ip address or a network address in | ||
63 | * CIDR notation. | ||
64 | */ | ||
65 | char *trusted_ip; | ||
66 | |||
67 | /** | ||
68 | * our hostname | ||
69 | */ | ||
70 | char *hostname; | ||
71 | |||
72 | /** | ||
73 | * Bitmap where each port that has already been reserved for some GNUnet peer | ||
74 | * is recorded. Note that we make no distinction between TCP and UDP ports | ||
75 | * and test if a port is already in use before assigning it to a peer/service. | ||
76 | * If we detect that a port is already in use, we also mark it in this bitmap. | ||
77 | * So all the bits that are zero merely indicate ports that MIGHT be available | ||
78 | * for peers. | ||
79 | */ | ||
80 | uint32_t reserved_ports[65536 / 32]; | ||
81 | |||
82 | /** | ||
83 | * Counter we use to make service home paths unique on this system; | ||
84 | * the full path consists of the tmppath and this number. Each | ||
85 | * UNIXPATH for a peer is also modified to include the respective | ||
86 | * path counter to ensure uniqueness. This field is incremented | ||
87 | * by one for each configured peer. Even if peers are destroyed, | ||
88 | * we never re-use path counters. | ||
89 | */ | ||
90 | uint32_t path_counter; | ||
91 | |||
92 | /** | ||
93 | * Lowest port we are allowed to use. | ||
94 | */ | ||
95 | uint16_t lowport; | ||
96 | |||
97 | /** | ||
98 | * Highest port we are allowed to use. | ||
99 | */ | ||
100 | uint16_t highport; | ||
101 | }; | ||
102 | |||
103 | |||
104 | struct GNUNET_TESTBED_System * | ||
105 | GNUNET_TESTBED_system_create_with_portrange ( | ||
106 | const char *testdir, | ||
107 | const char *trusted_ip, | ||
108 | const char *hostname, | ||
109 | uint16_t lowport, | ||
110 | uint16_t highport) | ||
111 | { | ||
112 | struct GNUNET_TESTBED_System *system; | ||
113 | |||
114 | GNUNET_assert (NULL != testdir); | ||
115 | system = GNUNET_new (struct GNUNET_TESTBED_System); | ||
116 | if (NULL == (system->tmppath = getenv (GNUNET_TESTBED_PREFIX))) | ||
117 | system->tmppath = GNUNET_DISK_mkdtemp (testdir); | ||
118 | else | ||
119 | system->tmppath = GNUNET_strdup (system->tmppath); | ||
120 | system->lowport = lowport; | ||
121 | system->highport = highport; | ||
122 | if (NULL == system->tmppath) | ||
123 | { | ||
124 | GNUNET_free (system); | ||
125 | return NULL; | ||
126 | } | ||
127 | if (NULL != trusted_ip) | ||
128 | system->trusted_ip = GNUNET_strdup (trusted_ip); | ||
129 | if (NULL != hostname) | ||
130 | system->hostname = GNUNET_strdup (hostname); | ||
131 | return system; | ||
132 | } | ||
133 | |||
134 | |||
135 | struct GNUNET_TESTBED_System * | ||
136 | GNUNET_TESTBED_system_create ( | ||
137 | const char *testdir, | ||
138 | const char *trusted_ip, | ||
139 | const char *hostname) | ||
140 | { | ||
141 | return GNUNET_TESTBED_system_create_with_portrange (testdir, | ||
142 | trusted_ip, | ||
143 | hostname, | ||
144 | LOW_PORT, | ||
145 | HIGH_PORT); | ||
146 | } | ||
147 | |||
148 | |||
149 | void | ||
150 | GNUNET_TESTBED_system_destroy (struct GNUNET_TESTBED_System *system, | ||
151 | int remove_paths) | ||
152 | { | ||
153 | if (GNUNET_YES == remove_paths) | ||
154 | GNUNET_DISK_directory_remove (system->tmppath); | ||
155 | GNUNET_free (system->tmppath); | ||
156 | GNUNET_free (system->trusted_ip); | ||
157 | GNUNET_free (system->hostname); | ||
158 | GNUNET_free (system); | ||
159 | } | ||
160 | |||
161 | |||
162 | uint16_t | ||
163 | GNUNET_TESTBED_reserve_port (struct GNUNET_TESTBED_System *system) | ||
164 | { | ||
165 | struct GNUNET_NETWORK_Handle *socket; | ||
166 | struct addrinfo hint; | ||
167 | struct addrinfo *ret; | ||
168 | struct addrinfo *ai; | ||
169 | uint32_t *port_buckets; | ||
170 | char *open_port_str; | ||
171 | int bind_status; | ||
172 | uint32_t xor_image; | ||
173 | uint16_t index; | ||
174 | uint16_t open_port; | ||
175 | uint16_t pos; | ||
176 | |||
177 | /* | ||
178 | FIXME: Instead of using getaddrinfo we should try to determine the port | ||
179 | status by the following heurestics. | ||
180 | |||
181 | On systems which support both IPv4 and IPv6, only ports open on both | ||
182 | address families are considered open. | ||
183 | On system with either IPv4 or IPv6. A port is considered open if it's | ||
184 | open in the respective address family | ||
185 | */hint.ai_family = AF_UNSPEC; /* IPv4 and IPv6 */ | ||
186 | hint.ai_socktype = 0; | ||
187 | hint.ai_protocol = 0; | ||
188 | hint.ai_addrlen = 0; | ||
189 | hint.ai_addr = NULL; | ||
190 | hint.ai_canonname = NULL; | ||
191 | hint.ai_next = NULL; | ||
192 | hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* Wild card address */ | ||
193 | port_buckets = system->reserved_ports; | ||
194 | for (index = (system->lowport / 32) + 1; index < (system->highport / 32); | ||
195 | index++) | ||
196 | { | ||
197 | xor_image = (UINT32_MAX ^ port_buckets[index]); | ||
198 | if (0 == xor_image) /* Ports in the bucket are full */ | ||
199 | continue; | ||
200 | pos = system->lowport % 32; | ||
201 | while (pos < 32) | ||
202 | { | ||
203 | if (0 == ((xor_image >> pos) & 1U)) | ||
204 | { | ||
205 | pos++; | ||
206 | continue; | ||
207 | } | ||
208 | open_port = (index * 32) + pos; | ||
209 | if (open_port >= system->highport) | ||
210 | return 0; | ||
211 | GNUNET_asprintf (&open_port_str, "%u", (unsigned int) open_port); | ||
212 | ret = NULL; | ||
213 | GNUNET_assert (0 == getaddrinfo (NULL, open_port_str, &hint, &ret)); | ||
214 | GNUNET_free (open_port_str); | ||
215 | bind_status = GNUNET_NO; | ||
216 | for (ai = ret; NULL != ai; ai = ai->ai_next) | ||
217 | { | ||
218 | socket = GNUNET_NETWORK_socket_create (ai->ai_family, SOCK_STREAM, 0); | ||
219 | if (NULL == socket) | ||
220 | continue; | ||
221 | bind_status = | ||
222 | GNUNET_NETWORK_socket_bind (socket, ai->ai_addr, ai->ai_addrlen); | ||
223 | GNUNET_NETWORK_socket_close (socket); | ||
224 | if (GNUNET_OK != bind_status) | ||
225 | break; | ||
226 | socket = GNUNET_NETWORK_socket_create (ai->ai_family, SOCK_DGRAM, 0); | ||
227 | if (NULL == socket) | ||
228 | continue; | ||
229 | bind_status = | ||
230 | GNUNET_NETWORK_socket_bind (socket, ai->ai_addr, ai->ai_addrlen); | ||
231 | GNUNET_NETWORK_socket_close (socket); | ||
232 | if (GNUNET_OK != bind_status) | ||
233 | break; | ||
234 | } | ||
235 | port_buckets[index] |= (1U << pos); /* Set the port bit */ | ||
236 | freeaddrinfo (ret); | ||
237 | if (GNUNET_OK == bind_status) | ||
238 | { | ||
239 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
240 | "Found a free port %u\n", | ||
241 | (unsigned int) open_port); | ||
242 | return open_port; | ||
243 | } | ||
244 | pos++; | ||
245 | } | ||
246 | } | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | |||
251 | void | ||
252 | GNUNET_TESTBED_release_port (struct GNUNET_TESTBED_System *system, | ||
253 | uint16_t port) | ||
254 | { | ||
255 | uint32_t *port_buckets; | ||
256 | uint16_t bucket; | ||
257 | uint16_t pos; | ||
258 | |||
259 | port_buckets = system->reserved_ports; | ||
260 | bucket = port / 32; | ||
261 | pos = port % 32; | ||
262 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Releasing port %u\n", port); | ||
263 | if (0 == (port_buckets[bucket] & (1U << pos))) | ||
264 | { | ||
265 | GNUNET_break (0); /* Port was not reserved by us using reserve_port() */ | ||
266 | return; | ||
267 | } | ||
268 | port_buckets[bucket] &= ~(1U << pos); | ||
269 | } | ||
270 | |||
271 | |||
272 | /** | ||
273 | * Structure for holding data to build new configurations from a configuration | ||
274 | * template | ||
275 | */ | ||
276 | struct UpdateContext | ||
277 | { | ||
278 | /** | ||
279 | * The system for which we are building configurations | ||
280 | */ | ||
281 | struct GNUNET_TESTBED_System *system; | ||
282 | |||
283 | /** | ||
284 | * The configuration we are building | ||
285 | */ | ||
286 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
287 | |||
288 | /** | ||
289 | * The customized service home path for this peer | ||
290 | */ | ||
291 | char *gnunet_home; | ||
292 | |||
293 | /** | ||
294 | * Array of ports currently allocated to this peer. These ports will be | ||
295 | * released upon peer destroy and can be used by other peers which are | ||
296 | * configured after. | ||
297 | */ | ||
298 | uint16_t *ports; | ||
299 | |||
300 | /** | ||
301 | * The number of ports in the above array | ||
302 | */ | ||
303 | unsigned int nports; | ||
304 | |||
305 | /** | ||
306 | * build status - to signal error while building a configuration | ||
307 | */ | ||
308 | int status; | ||
309 | }; | ||
310 | |||
311 | |||
312 | /** | ||
313 | * Function to iterate over options. Copies | ||
314 | * the options to the target configuration, | ||
315 | * updating PORT values as needed. | ||
316 | * | ||
317 | * @param cls the UpdateContext | ||
318 | * @param section name of the section | ||
319 | * @param option name of the option | ||
320 | * @param value value of the option | ||
321 | */ | ||
322 | static void | ||
323 | update_config (void *cls, | ||
324 | const char *section, | ||
325 | const char *option, | ||
326 | const char *value) | ||
327 | { | ||
328 | struct UpdateContext *uc = cls; | ||
329 | unsigned int ival; | ||
330 | char cval[12]; | ||
331 | char uval[PATH_MAX]; | ||
332 | char *single_variable; | ||
333 | char *per_host_variable; | ||
334 | unsigned long long num_per_host; | ||
335 | uint16_t new_port; | ||
336 | |||
337 | if (GNUNET_OK != uc->status) | ||
338 | return; | ||
339 | if (! ((0 == strcmp (option, "PORT")) || (0 == strcmp (option, "UNIXPATH")) || | ||
340 | (0 == strcmp (option, "HOSTNAME")))) | ||
341 | return; | ||
342 | GNUNET_asprintf (&single_variable, "single_%s_per_host", section); | ||
343 | GNUNET_asprintf (&per_host_variable, "num_%s_per_host", section); | ||
344 | if ((0 == strcmp (option, "PORT")) && (1 == sscanf (value, "%u", &ival))) | ||
345 | { | ||
346 | if ((ival != 0) && | ||
347 | (GNUNET_YES != GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, | ||
348 | "testing", | ||
349 | single_variable))) | ||
350 | { | ||
351 | new_port = GNUNET_TESTBED_reserve_port (uc->system); | ||
352 | if (0 == new_port) | ||
353 | { | ||
354 | uc->status = GNUNET_SYSERR; | ||
355 | GNUNET_free (single_variable); | ||
356 | GNUNET_free (per_host_variable); | ||
357 | return; | ||
358 | } | ||
359 | GNUNET_snprintf (cval, sizeof(cval), "%u", new_port); | ||
360 | value = cval; | ||
361 | GNUNET_array_append (uc->ports, uc->nports, new_port); | ||
362 | } | ||
363 | else if ((ival != 0) && | ||
364 | (GNUNET_YES == | ||
365 | GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, | ||
366 | "testing", | ||
367 | single_variable)) && | ||
368 | GNUNET_CONFIGURATION_get_value_number (uc->cfg, | ||
369 | "testing", | ||
370 | per_host_variable, | ||
371 | &num_per_host)) | ||
372 | { | ||
373 | /* GNUNET_snprintf (cval, sizeof (cval), "%u", */ | ||
374 | /* ival + ctx->fdnum % num_per_host); */ | ||
375 | /* value = cval; */ | ||
376 | GNUNET_break (0); /* FIXME */ | ||
377 | } | ||
378 | } | ||
379 | if (0 == strcmp (option, "UNIXPATH")) | ||
380 | { | ||
381 | if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, | ||
382 | "testing", | ||
383 | single_variable)) | ||
384 | { | ||
385 | GNUNET_snprintf (uval, | ||
386 | sizeof(uval), | ||
387 | "%s/%s.sock", | ||
388 | uc->gnunet_home, | ||
389 | section); | ||
390 | value = uval; | ||
391 | } | ||
392 | else if ((GNUNET_YES == | ||
393 | GNUNET_CONFIGURATION_get_value_number (uc->cfg, | ||
394 | "testing", | ||
395 | per_host_variable, | ||
396 | &num_per_host)) && | ||
397 | (num_per_host > 0)) | ||
398 | { | ||
399 | GNUNET_break (0); /* FIXME */ | ||
400 | } | ||
401 | } | ||
402 | if (0 == strcmp (option, "HOSTNAME")) | ||
403 | { | ||
404 | value = (NULL == uc->system->hostname) ? "localhost" : uc->system->hostname; | ||
405 | } | ||
406 | GNUNET_free (single_variable); | ||
407 | GNUNET_free (per_host_variable); | ||
408 | GNUNET_CONFIGURATION_set_value_string (uc->cfg, section, option, value); | ||
409 | } | ||
410 | |||
411 | |||
412 | /** | ||
413 | * Section iterator to set ACCEPT_FROM/ACCEPT_FROM6 to include the address of | ||
414 | * 'trusted_hosts' in all sections | ||
415 | * | ||
416 | * @param cls the UpdateContext | ||
417 | * @param section name of the section | ||
418 | */ | ||
419 | static void | ||
420 | update_config_sections (void *cls, | ||
421 | const char *section) | ||
422 | { | ||
423 | struct UpdateContext *uc = cls; | ||
424 | char **ikeys; | ||
425 | char *val; | ||
426 | char *ptr; | ||
427 | char *orig_allowed_hosts; | ||
428 | char *allowed_hosts; | ||
429 | char *ACCEPT_FROM_key; | ||
430 | uint16_t ikeys_cnt; | ||
431 | uint16_t key; | ||
432 | |||
433 | ikeys_cnt = 0; | ||
434 | val = NULL; | ||
435 | /* Ignore certain options from sections. See | ||
436 | https://gnunet.org/bugs/view.php?id=2476 */ | ||
437 | if (GNUNET_YES == | ||
438 | GNUNET_CONFIGURATION_have_value (uc->cfg, | ||
439 | section, | ||
440 | "TESTBED_IGNORE_KEYS")) | ||
441 | { | ||
442 | GNUNET_assert (GNUNET_YES == | ||
443 | GNUNET_CONFIGURATION_get_value_string (uc->cfg, | ||
444 | section, | ||
445 | "TESTBED_IGNORE_KEYS", | ||
446 | &val)); | ||
447 | ptr = val; | ||
448 | for (ikeys_cnt = 0; NULL != (ptr = strstr (ptr, ";")); ikeys_cnt++) | ||
449 | ptr++; | ||
450 | if (0 == ikeys_cnt) | ||
451 | GNUNET_break (0); | ||
452 | else | ||
453 | { | ||
454 | ikeys = GNUNET_malloc ((sizeof(char *)) * ikeys_cnt); | ||
455 | ptr = val; | ||
456 | for (key = 0; key < ikeys_cnt; key++) | ||
457 | { | ||
458 | ikeys[key] = ptr; | ||
459 | ptr = strstr (ptr, ";"); | ||
460 | GNUNET_assert (NULL != ptr); /* worked just before... */ | ||
461 | *ptr = '\0'; | ||
462 | ptr++; | ||
463 | } | ||
464 | } | ||
465 | } | ||
466 | if (0 != ikeys_cnt) | ||
467 | { | ||
468 | for (key = 0; key < ikeys_cnt; key++) | ||
469 | { | ||
470 | if (NULL != strstr (ikeys[key], "ADVERTISED_PORT")) | ||
471 | break; | ||
472 | } | ||
473 | if ((key == ikeys_cnt) && | ||
474 | (GNUNET_YES == | ||
475 | GNUNET_CONFIGURATION_have_value (uc->cfg, | ||
476 | section, | ||
477 | "ADVERTISED_PORT"))) | ||
478 | { | ||
479 | if (GNUNET_OK == | ||
480 | GNUNET_CONFIGURATION_get_value_string (uc->cfg, | ||
481 | section, | ||
482 | "PORT", | ||
483 | &ptr)) | ||
484 | { | ||
485 | GNUNET_CONFIGURATION_set_value_string (uc->cfg, | ||
486 | section, | ||
487 | "ADVERTISED_PORT", | ||
488 | ptr); | ||
489 | GNUNET_free (ptr); | ||
490 | } | ||
491 | } | ||
492 | for (key = 0; key < ikeys_cnt; key++) | ||
493 | { | ||
494 | if (NULL != strstr (ikeys[key], "ACCEPT_FROM")) | ||
495 | { | ||
496 | GNUNET_free (ikeys); | ||
497 | GNUNET_free (val); | ||
498 | return; | ||
499 | } | ||
500 | } | ||
501 | GNUNET_free (ikeys); | ||
502 | } | ||
503 | GNUNET_free (val); | ||
504 | ACCEPT_FROM_key = "ACCEPT_FROM"; | ||
505 | if ((NULL != uc->system->trusted_ip) && | ||
506 | (NULL != strstr (uc->system->trusted_ip, ":"))) /* IPv6 in use */ | ||
507 | ACCEPT_FROM_key = "ACCEPT_FROM6"; | ||
508 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (uc->cfg, | ||
509 | section, | ||
510 | ACCEPT_FROM_key, | ||
511 | &orig_allowed_hosts)) | ||
512 | { | ||
513 | orig_allowed_hosts = GNUNET_strdup ("127.0.0.1;"); | ||
514 | } | ||
515 | if (NULL == uc->system->trusted_ip) | ||
516 | allowed_hosts = GNUNET_strdup (orig_allowed_hosts); | ||
517 | else | ||
518 | GNUNET_asprintf (&allowed_hosts, | ||
519 | "%s%s;", | ||
520 | orig_allowed_hosts, | ||
521 | uc->system->trusted_ip); | ||
522 | GNUNET_free (orig_allowed_hosts); | ||
523 | GNUNET_CONFIGURATION_set_value_string (uc->cfg, | ||
524 | section, | ||
525 | ACCEPT_FROM_key, | ||
526 | allowed_hosts); | ||
527 | GNUNET_free (allowed_hosts); | ||
528 | } | ||
529 | |||
530 | |||
531 | enum GNUNET_GenericReturnValue | ||
532 | GNUNET_TESTBED_configuration_create ( | ||
533 | struct GNUNET_TESTBED_System *system, | ||
534 | struct GNUNET_CONFIGURATION_Handle *cfg, | ||
535 | uint16_t **ports, | ||
536 | unsigned int *nports) | ||
537 | { | ||
538 | struct UpdateContext uc; | ||
539 | char *default_config; | ||
540 | |||
541 | uc.system = system; | ||
542 | uc.cfg = cfg; | ||
543 | uc.status = GNUNET_OK; | ||
544 | uc.ports = NULL; | ||
545 | uc.nports = 0; | ||
546 | GNUNET_asprintf (&uc.gnunet_home, | ||
547 | "%s/%u", | ||
548 | system->tmppath, | ||
549 | system->path_counter++); | ||
550 | GNUNET_asprintf (&default_config, "%s/config", uc.gnunet_home); | ||
551 | GNUNET_CONFIGURATION_set_value_string (cfg, | ||
552 | "PATHS", | ||
553 | "DEFAULTCONFIG", | ||
554 | default_config); | ||
555 | GNUNET_CONFIGURATION_set_value_string (cfg, "arm", "CONFIG", default_config); | ||
556 | GNUNET_free (default_config); | ||
557 | GNUNET_CONFIGURATION_set_value_string (cfg, | ||
558 | "PATHS", | ||
559 | "GNUNET_HOME", | ||
560 | uc.gnunet_home); | ||
561 | /* make PORTs and UNIXPATHs unique */ | ||
562 | GNUNET_CONFIGURATION_iterate (cfg, &update_config, &uc); | ||
563 | /* allow connections to services from system trusted_ip host */ | ||
564 | GNUNET_CONFIGURATION_iterate_sections (cfg, &update_config_sections, &uc); | ||
565 | /* enable loopback-based connections between peers */ | ||
566 | GNUNET_CONFIGURATION_set_value_string (cfg, "nat", "USE_LOCALADDR", "YES"); | ||
567 | GNUNET_free (uc.gnunet_home); | ||
568 | if ((NULL != ports) && (NULL != nports)) | ||
569 | { | ||
570 | *ports = uc.ports; | ||
571 | *nports = uc.nports; | ||
572 | } | ||
573 | else | ||
574 | GNUNET_free (uc.ports); | ||
575 | return uc.status; | ||
576 | } | ||
577 | |||
578 | |||
579 | /* end of testbed.c */ | ||
diff --git a/src/service/testing/testing_api_cmd_system_create.c b/src/service/testbed/testbed_api_cmd_system_create.c index 46fbd706e..2f780ec73 100644 --- a/src/service/testing/testing_api_cmd_system_create.c +++ b/src/service/testbed/testbed_api_cmd_system_create.c | |||
@@ -25,10 +25,9 @@ | |||
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_testing_ng_lib.h" | ||
29 | #include "gnunet_testing_plugin.h" | ||
30 | #include "gnunet_testing_netjail_lib.h" | ||
31 | #include "gnunet_testing_lib.h" | 28 | #include "gnunet_testing_lib.h" |
29 | #include "gnunet_testbed_lib.h" | ||
30 | #include "gnunet_testing_testbed_lib.h" | ||
32 | 31 | ||
33 | /** | 32 | /** |
34 | * Struct to hold information for callbacks. | 33 | * Struct to hold information for callbacks. |
@@ -36,7 +35,7 @@ | |||
36 | */ | 35 | */ |
37 | struct TestSystemState | 36 | struct TestSystemState |
38 | { | 37 | { |
39 | struct GNUNET_TESTING_System *test_system; | 38 | struct GNUNET_TESTBED_System *test_system; |
40 | 39 | ||
41 | const char *testdir; | 40 | const char *testdir; |
42 | }; | 41 | }; |
@@ -52,15 +51,9 @@ system_create_run (void *cls, | |||
52 | { | 51 | { |
53 | struct TestSystemState *tss = cls; | 52 | struct TestSystemState *tss = cls; |
54 | 53 | ||
55 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 54 | tss->test_system = GNUNET_TESTBED_system_create (tss->testdir, |
56 | "system create\n"); | ||
57 | |||
58 | tss->test_system = GNUNET_TESTING_system_create (tss->testdir, | ||
59 | NULL, | ||
60 | NULL, | 55 | NULL, |
61 | NULL); | 56 | NULL); |
62 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
63 | "system created\n"); | ||
64 | } | 57 | } |
65 | 58 | ||
66 | 59 | ||
@@ -75,10 +68,9 @@ system_create_traits (void *cls, | |||
75 | unsigned int index) | 68 | unsigned int index) |
76 | { | 69 | { |
77 | struct TestSystemState *tss = cls; | 70 | struct TestSystemState *tss = cls; |
78 | struct GNUNET_TESTING_System *test_system = tss->test_system; | ||
79 | |||
80 | struct GNUNET_TESTING_Trait traits[] = { | 71 | struct GNUNET_TESTING_Trait traits[] = { |
81 | GNUNET_TESTING_make_trait_test_system ((const void *) test_system), | 72 | GNUNET_TESTING_TESTBED_make_trait_test_system ( |
73 | tss->test_system), | ||
82 | GNUNET_TESTING_trait_end () | 74 | GNUNET_TESTING_trait_end () |
83 | }; | 75 | }; |
84 | 76 | ||
@@ -98,6 +90,9 @@ system_create_cleanup (void *cls) | |||
98 | { | 90 | { |
99 | struct TestSystemState *tss = cls; | 91 | struct TestSystemState *tss = cls; |
100 | 92 | ||
93 | GNUNET_TESTBED_system_destroy (tss->test_system, | ||
94 | GNUNET_YES); | ||
95 | |||
101 | GNUNET_free (tss); | 96 | GNUNET_free (tss); |
102 | } | 97 | } |
103 | 98 | ||
@@ -110,7 +105,7 @@ system_create_cleanup (void *cls) | |||
110 | * @return command. | 105 | * @return command. |
111 | */ | 106 | */ |
112 | struct GNUNET_TESTING_Command | 107 | struct GNUNET_TESTING_Command |
113 | GNUNET_TESTING_cmd_system_create (const char *label, | 108 | GNUNET_TESTBED_cmd_system_create (const char *label, |
114 | const char *testdir) | 109 | const char *testdir) |
115 | { | 110 | { |
116 | struct TestSystemState *tss; | 111 | struct TestSystemState *tss; |
@@ -118,7 +113,9 @@ GNUNET_TESTING_cmd_system_create (const char *label, | |||
118 | tss = GNUNET_new (struct TestSystemState); | 113 | tss = GNUNET_new (struct TestSystemState); |
119 | tss->testdir = testdir; | 114 | tss->testdir = testdir; |
120 | 115 | ||
121 | return GNUNET_TESTING_command_new (tss, label, &system_create_run, | 116 | return GNUNET_TESTING_command_new (tss, |
117 | label, | ||
118 | &system_create_run, | ||
122 | &system_create_cleanup, | 119 | &system_create_cleanup, |
123 | &system_create_traits, NULL); | 120 | &system_create_traits); |
124 | } | 121 | } |
diff --git a/src/service/transport/transport_api_traits.c b/src/service/testbed/testing_testbed_traits.c index ec53f6f2b..b7fd605e5 100644 --- a/src/service/transport/transport_api_traits.c +++ b/src/service/testbed/testing_testbed_traits.c | |||
@@ -24,9 +24,11 @@ | |||
24 | * @author t3sserakt | 24 | * @author t3sserakt |
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_testing_ng_lib.h" | ||
28 | #include "gnunet_testing_netjail_lib.h" | ||
29 | #include "transport-testing-cmds.h" | ||
30 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_testing_lib.h" | ||
29 | #include "gnunet_testing_testbed_lib.h" | ||
31 | 30 | ||
32 | GNUNET_TRANSPORT_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, GNUNET_TRANSPORT_TESTING) | 31 | |
32 | GNUNET_TESTING_TESTBED_SIMPLE_TRAITS ( | ||
33 | GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, | ||
34 | GNUNET_TESTING_TESTBED) | ||
diff --git a/src/service/testing/Makefile.am b/src/service/testing/Makefile.am deleted file mode 100644 index 5cd4aae9b..000000000 --- a/src/service/testing/Makefile.am +++ /dev/null | |||
@@ -1,134 +0,0 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | ||
3 | |||
4 | if USE_COVERAGE | ||
5 | AM_CFLAGS = --coverage -O0 | ||
6 | XLIB = -lgcov | ||
7 | endif | ||
8 | |||
9 | libexecdir= $(pkglibdir)/libexec/ | ||
10 | |||
11 | pkgcfgdir= $(pkgdatadir)/config.d/ | ||
12 | |||
13 | dist_pkgcfg_DATA = \ | ||
14 | testing.conf | ||
15 | |||
16 | libexec_PROGRAMS = \ | ||
17 | test_testing_start_with_config \ | ||
18 | gnunet-cmds-helper | ||
19 | |||
20 | plugindir = $(libdir)/gnunet | ||
21 | |||
22 | lib_LTLIBRARIES = \ | ||
23 | libgnunettesting.la | ||
24 | |||
25 | gnunet_cmds_helper_SOURCES = \ | ||
26 | gnunet-cmds-helper.c | ||
27 | gnunet_cmds_helper_LDADD = $(XLIB) \ | ||
28 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
29 | libgnunettesting.la \ | ||
30 | $(LTLIBINTL) $(Z_LIBS) | ||
31 | |||
32 | libgnunettesting_la_SOURCES = \ | ||
33 | testing_api_cmd_exec_bash_script.c \ | ||
34 | testing_api_cmd_barrier.c \ | ||
35 | testing_api_cmd_barrier_reached.c \ | ||
36 | testing_api_cmd_finish.c \ | ||
37 | testing_api_cmd_local_test_prepared.c \ | ||
38 | testing_api_cmd_send_peer_ready.c \ | ||
39 | testing_api_cmd_block_until_external_trigger.c \ | ||
40 | testing_api_cmd_netjail_start.c \ | ||
41 | testing_api_cmd_netjail_start_cmds_helper.c \ | ||
42 | testing_api_cmd_netjail_stop_cmds_helper.c \ | ||
43 | testing_api_cmd_netjail_stop.c \ | ||
44 | testing.c testing.h \ | ||
45 | testing_api_cmd_system_create.c \ | ||
46 | testing_api_cmd_system_destroy.c \ | ||
47 | testing_api_cmd_batch.c \ | ||
48 | testing_api_loop.c \ | ||
49 | testing_api_traits.c | ||
50 | libgnunettesting_la_LIBADD = \ | ||
51 | $(top_builddir)/src/service/arm/libgnunetarm.la \ | ||
52 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
53 | $(LTLIBINTL) | ||
54 | libgnunettesting_la_LDFLAGS = \ | ||
55 | $(GN_LIB_LDFLAGS) \ | ||
56 | -version-info 2:0:1 | ||
57 | |||
58 | bin_PROGRAMS = \ | ||
59 | gnunet-testing | ||
60 | |||
61 | noinst_PROGRAMS = \ | ||
62 | list-keys | ||
63 | |||
64 | gnunet_testing_SOURCES = \ | ||
65 | gnunet-testing.c | ||
66 | gnunet_testing_LDADD = \ | ||
67 | libgnunettesting.la \ | ||
68 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
69 | $(GN_LIBINTL) | ||
70 | |||
71 | list_keys_SOURCES = \ | ||
72 | list-keys.c | ||
73 | list_keys_LDADD = \ | ||
74 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
75 | $(GN_LIBINTL) | ||
76 | |||
77 | |||
78 | check_PROGRAMS = \ | ||
79 | test_testing_portreservation \ | ||
80 | test_testing_servicestartup \ | ||
81 | test_testing_peerstartup \ | ||
82 | test_testing_peerstartup2 \ | ||
83 | test_testing_sharedservices | ||
84 | |||
85 | # if ENABLE_TEST_RUN_TESTING | ||
86 | # AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | ||
87 | # TESTS = \ | ||
88 | # test_testing_portreservation \ | ||
89 | # test_testing_peerstartup \ | ||
90 | # test_testing_peerstartup2 \ | ||
91 | # test_testing_servicestartup | ||
92 | # endif | ||
93 | |||
94 | test_testing_start_with_config_SOURCES = \ | ||
95 | test_testing_start_with_config.c | ||
96 | test_testing_start_with_config_LDADD = \ | ||
97 | libgnunettesting.la \ | ||
98 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
99 | $(top_builddir)/src/lib/hello/libgnunethello.la | ||
100 | |||
101 | test_testing_portreservation_SOURCES = \ | ||
102 | test_testing_portreservation.c | ||
103 | test_testing_portreservation_LDADD = \ | ||
104 | libgnunettesting.la \ | ||
105 | $(top_builddir)/src/lib/util/libgnunetutil.la | ||
106 | |||
107 | test_testing_peerstartup_SOURCES = \ | ||
108 | test_testing_peerstartup.c | ||
109 | test_testing_peerstartup_LDADD = \ | ||
110 | libgnunettesting.la \ | ||
111 | $(top_builddir)/src/lib/util/libgnunetutil.la | ||
112 | |||
113 | test_testing_peerstartup2_SOURCES = \ | ||
114 | test_testing_peerstartup2.c | ||
115 | test_testing_peerstartup2_LDADD = \ | ||
116 | libgnunettesting.la \ | ||
117 | $(top_builddir)/src/lib/util/libgnunetutil.la | ||
118 | |||
119 | test_testing_servicestartup_SOURCES = \ | ||
120 | test_testing_servicestartup.c | ||
121 | test_testing_servicestartup_LDADD = \ | ||
122 | libgnunettesting.la \ | ||
123 | $(top_builddir)/src/lib/util/libgnunetutil.la | ||
124 | |||
125 | test_testing_sharedservices_SOURCES = \ | ||
126 | test_testing_sharedservices.c | ||
127 | test_testing_sharedservices_LDADD = \ | ||
128 | libgnunettesting.la \ | ||
129 | $(top_builddir)/src/lib/util/libgnunetutil.la | ||
130 | |||
131 | EXTRA_DIST = \ | ||
132 | test_testing_defaults.conf \ | ||
133 | test_testing_sharedservices.conf \ | ||
134 | testing_cmds.h | ||
diff --git a/src/service/testing/gnunet-cmds-helper.c b/src/service/testing/gnunet-cmds-helper.c deleted file mode 100644 index a54191abf..000000000 --- a/src/service/testing/gnunet-cmds-helper.c +++ /dev/null | |||
@@ -1,713 +0,0 @@ | |||
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 testbed/gnunet-cmds-helper.c | ||
23 | * @brief Helper binary that is started from a remote interpreter loop to start | ||
24 | * a local interpreter loop. | ||
25 | * | ||
26 | * This helper monitors for three termination events. They are: (1)The | ||
27 | * stdin of the helper is closed for reading; (2)the helper received | ||
28 | * SIGTERM/SIGINT; (3)the local loop crashed. In case of events 1 and 2 | ||
29 | * the helper kills the interpreter loop. When the interpreter loop | ||
30 | * crashed (event 3), the helper should send a SIGTERM to its own process | ||
31 | * group; this behaviour will help terminate any child processes the loop | ||
32 | * has started and prevents them from leaking and running forever. | ||
33 | * | ||
34 | * @author t3sserakt | ||
35 | * @author Sree Harsha Totakura <sreeharsha@totakura.in> | ||
36 | */ | ||
37 | |||
38 | |||
39 | #include "platform.h" | ||
40 | #include "gnunet_util_lib.h" | ||
41 | #include "gnunet_testing_lib.h" | ||
42 | #include "gnunet_testing_ng_lib.h" | ||
43 | #include "gnunet_testing_plugin.h" | ||
44 | #include "gnunet_testing_netjail_lib.h" | ||
45 | #include "testing.h" | ||
46 | #include "testing_cmds.h" | ||
47 | #include "gnunet_testing_plugin.h" | ||
48 | #include "gnunet_testing_barrier.h" | ||
49 | #include <zlib.h> | ||
50 | |||
51 | |||
52 | /** | ||
53 | * Generic logging shortcut | ||
54 | */ | ||
55 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | ||
56 | |||
57 | /** | ||
58 | * Debug logging shorthand | ||
59 | */ | ||
60 | #define LOG_DEBUG(...) LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) | ||
61 | |||
62 | #define NODE_BASE_IP "192.168.15." | ||
63 | |||
64 | #define KNOWN_BASE_IP "92.68.151." | ||
65 | |||
66 | #define ROUTER_BASE_IP "92.68.150." | ||
67 | |||
68 | /* Use the IP addresses below instead of the public ones, | ||
69 | * if the start script was not started from within a new namespace | ||
70 | * created by unshare. The UPNP test case needs public IP | ||
71 | * addresse for miniupnpd to function. | ||
72 | * FIXME We should introduce a switch indicating if public | ||
73 | * addresses should be used or not. This info has to be | ||
74 | * propagated from the start script to the c code. | ||
75 | #define KNOWN_BASE_IP "172.16.151." | ||
76 | |||
77 | #define ROUTER_BASE_IP "172.16.150." | ||
78 | */ | ||
79 | |||
80 | struct GNUNET_SCHEDULER_Task *finished_task; | ||
81 | |||
82 | struct GNUNET_TESTING_Interpreter *is; | ||
83 | |||
84 | /** | ||
85 | * Struct with information about a specific node and the whole network namespace setup. | ||
86 | * | ||
87 | */ | ||
88 | struct NodeIdentifier | ||
89 | { | ||
90 | /** | ||
91 | * The number of the namespace this node is in. | ||
92 | * | ||
93 | */ | ||
94 | char *n; | ||
95 | |||
96 | /** | ||
97 | * The number of the node in the namespace. | ||
98 | * | ||
99 | */ | ||
100 | char *m; | ||
101 | |||
102 | /** | ||
103 | * The number of namespaces | ||
104 | * | ||
105 | */ | ||
106 | char *global_n; | ||
107 | |||
108 | /** | ||
109 | * The number of local nodes per namespace. | ||
110 | * | ||
111 | */ | ||
112 | char *local_m; | ||
113 | |||
114 | /** | ||
115 | * Shall we read the topology from file, or from a string. | ||
116 | */ | ||
117 | unsigned int *read_file; | ||
118 | |||
119 | /** | ||
120 | * String with topology data or name of topology file. | ||
121 | */ | ||
122 | char *topology_data; | ||
123 | }; | ||
124 | |||
125 | /** | ||
126 | * Context for a single write on a chunk of memory | ||
127 | */ | ||
128 | struct WriteContext | ||
129 | { | ||
130 | /** | ||
131 | * The data to write | ||
132 | */ | ||
133 | void *data; | ||
134 | |||
135 | /** | ||
136 | * The length of the data | ||
137 | */ | ||
138 | size_t length; | ||
139 | |||
140 | /** | ||
141 | * The current position from where the write operation should begin | ||
142 | */ | ||
143 | size_t pos; | ||
144 | }; | ||
145 | |||
146 | /** | ||
147 | * The process handle to the testbed service | ||
148 | |||
149 | static struct GNUNET_OS_Process *cmd_binary_process;*/ | ||
150 | |||
151 | /** | ||
152 | * Plugin to dynamically load a test case. | ||
153 | */ | ||
154 | struct TestcasePlugin *plugin; | ||
155 | |||
156 | /** | ||
157 | * Our message stream tokenizer | ||
158 | */ | ||
159 | struct GNUNET_MessageStreamTokenizer *tokenizer; | ||
160 | |||
161 | /** | ||
162 | * Disk handle from stdin | ||
163 | */ | ||
164 | static struct GNUNET_DISK_FileHandle *stdin_fd; | ||
165 | |||
166 | /** | ||
167 | * Disk handle for stdout | ||
168 | */ | ||
169 | static struct GNUNET_DISK_FileHandle *stdout_fd; | ||
170 | |||
171 | /** | ||
172 | * Pipe used to communicate shutdown via signal. | ||
173 | */ | ||
174 | static struct GNUNET_DISK_PipeHandle *sigpipe; | ||
175 | |||
176 | /** | ||
177 | * Task identifier for the read task | ||
178 | */ | ||
179 | static struct GNUNET_SCHEDULER_Task *read_task_id; | ||
180 | |||
181 | /** | ||
182 | * Task identifier for the write task | ||
183 | */ | ||
184 | static struct GNUNET_SCHEDULER_Task *write_task_id; | ||
185 | |||
186 | /** | ||
187 | * Are we done reading messages from stdin? | ||
188 | */ | ||
189 | static int done_reading; | ||
190 | |||
191 | /** | ||
192 | * Result to return in case we fail | ||
193 | */ | ||
194 | static int status; | ||
195 | |||
196 | |||
197 | /** | ||
198 | * Task to shut down cleanly | ||
199 | * | ||
200 | * @param cls NULL | ||
201 | */ | ||
202 | static void | ||
203 | do_shutdown (void *cls) | ||
204 | { | ||
205 | |||
206 | LOG_DEBUG ("Shutting down.\n"); | ||
207 | |||
208 | if (NULL != read_task_id) | ||
209 | { | ||
210 | GNUNET_SCHEDULER_cancel (read_task_id); | ||
211 | read_task_id = NULL; | ||
212 | } | ||
213 | if (NULL != write_task_id) | ||
214 | { | ||
215 | struct WriteContext *wc; | ||
216 | |||
217 | wc = GNUNET_SCHEDULER_cancel (write_task_id); | ||
218 | write_task_id = NULL; | ||
219 | GNUNET_free (wc->data); | ||
220 | GNUNET_free (wc); | ||
221 | } | ||
222 | if (NULL != stdin_fd) | ||
223 | (void) GNUNET_DISK_file_close (stdin_fd); | ||
224 | if (NULL != stdout_fd) | ||
225 | (void) GNUNET_DISK_file_close (stdout_fd); | ||
226 | GNUNET_MST_destroy (tokenizer); | ||
227 | tokenizer = NULL; | ||
228 | GNUNET_PLUGIN_unload (plugin->library_name, | ||
229 | NULL); | ||
230 | GNUNET_free (plugin); | ||
231 | } | ||
232 | |||
233 | |||
234 | /** | ||
235 | * Task to write to the standard out | ||
236 | * | ||
237 | * @param cls the WriteContext | ||
238 | */ | ||
239 | static void | ||
240 | write_task (void *cls) | ||
241 | { | ||
242 | struct WriteContext *wc = cls; | ||
243 | ssize_t bytes_wrote; | ||
244 | |||
245 | GNUNET_assert (NULL != wc); | ||
246 | write_task_id = NULL; | ||
247 | bytes_wrote = GNUNET_DISK_file_write (stdout_fd, | ||
248 | wc->data + wc->pos, | ||
249 | wc->length - wc->pos); | ||
250 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
251 | "message send to master loop\n"); | ||
252 | if (GNUNET_SYSERR == bytes_wrote) | ||
253 | { | ||
254 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
255 | "Cannot reply back successful initialization\n"); | ||
256 | GNUNET_free (wc->data); | ||
257 | GNUNET_free (wc); | ||
258 | return; | ||
259 | } | ||
260 | wc->pos += bytes_wrote; | ||
261 | if (wc->pos == wc->length) | ||
262 | { | ||
263 | GNUNET_free (wc->data); | ||
264 | GNUNET_free (wc); | ||
265 | return; | ||
266 | } | ||
267 | write_task_id = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
268 | stdout_fd, | ||
269 | &write_task, | ||
270 | wc); | ||
271 | } | ||
272 | |||
273 | |||
274 | /** | ||
275 | * Callback to write a message to the master loop. | ||
276 | * | ||
277 | */ | ||
278 | static void | ||
279 | write_message (struct GNUNET_MessageHeader *message, | ||
280 | size_t msg_length) | ||
281 | { | ||
282 | struct WriteContext *wc; | ||
283 | |||
284 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
285 | "write message to master loop\n"); | ||
286 | wc = GNUNET_new (struct WriteContext); | ||
287 | wc->length = msg_length; | ||
288 | wc->data = message; | ||
289 | write_task_id = GNUNET_SCHEDULER_add_write_file ( | ||
290 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
291 | stdout_fd, | ||
292 | &write_task, | ||
293 | wc); | ||
294 | } | ||
295 | |||
296 | |||
297 | static void | ||
298 | delay_shutdown_cb () | ||
299 | { | ||
300 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
301 | "doing shutdown after delay\n"); | ||
302 | GNUNET_SCHEDULER_shutdown (); | ||
303 | } | ||
304 | |||
305 | |||
306 | struct GNUNET_MessageHeader * | ||
307 | GNUNET_TESTING_send_local_test_finished_msg () | ||
308 | { | ||
309 | struct GNUNET_TESTING_CommandLocalFinished *reply; | ||
310 | size_t msg_length; | ||
311 | |||
312 | msg_length = sizeof(struct GNUNET_TESTING_CommandLocalFinished); | ||
313 | reply = GNUNET_new (struct GNUNET_TESTING_CommandLocalFinished); | ||
314 | reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED); | ||
315 | reply->header.size = htons ((uint16_t) msg_length); | ||
316 | |||
317 | return (struct GNUNET_MessageHeader *) reply; | ||
318 | } | ||
319 | |||
320 | |||
321 | static void | ||
322 | finished_cb (enum GNUNET_GenericReturnValue rv) | ||
323 | { | ||
324 | struct GNUNET_TESTING_CommandLocalFinished *reply; | ||
325 | size_t msg_length; | ||
326 | |||
327 | msg_length = sizeof(struct GNUNET_TESTING_CommandLocalFinished); | ||
328 | reply = GNUNET_new (struct GNUNET_TESTING_CommandLocalFinished); | ||
329 | reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED); | ||
330 | reply->header.size = htons ((uint16_t) msg_length); | ||
331 | reply->rv = rv; | ||
332 | |||
333 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
334 | "message prepared\n"); | ||
335 | write_message ((struct GNUNET_MessageHeader *) reply, msg_length); | ||
336 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
337 | "message send\n"); | ||
338 | // FIXME: bad hack, do not write 1s, have continuation after write_message() is done! | ||
339 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
340 | "delaying shutdown\n"); | ||
341 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | ||
342 | &delay_shutdown_cb, | ||
343 | NULL); | ||
344 | } | ||
345 | |||
346 | |||
347 | /** | ||
348 | * Functions with this signature are called whenever a | ||
349 | * complete message is received by the tokenizer. | ||
350 | * | ||
351 | * Do not call #GNUNET_mst_destroy() in this callback | ||
352 | * | ||
353 | * @param cls identification of the client | ||
354 | * @param message the actual message | ||
355 | * @return #GNUNET_OK on success, | ||
356 | * #GNUNET_NO to stop further processing (no error) | ||
357 | * #GNUNET_SYSERR to stop further processing with error | ||
358 | */ | ||
359 | static enum GNUNET_GenericReturnValue | ||
360 | tokenizer_cb (void *cls, | ||
361 | const struct GNUNET_MessageHeader *message) | ||
362 | { | ||
363 | struct NodeIdentifier *ni = cls; | ||
364 | const struct GNUNET_TESTING_CommandHelperInit *msg; | ||
365 | struct GNUNET_TESTING_CommandHelperReply *reply; | ||
366 | char *binary; | ||
367 | char *plugin_name; | ||
368 | size_t plugin_name_size; | ||
369 | uint16_t msize; | ||
370 | uint16_t type; | ||
371 | size_t msg_length; | ||
372 | char *router_ip; | ||
373 | char *node_ip; | ||
374 | unsigned int namespace_n; | ||
375 | |||
376 | type = ntohs (message->type); | ||
377 | msize = ntohs (message->size); | ||
378 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
379 | "Received message type %u and size %u\n", | ||
380 | type, | ||
381 | msize); | ||
382 | switch (type) | ||
383 | { | ||
384 | case GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT: | ||
385 | { | ||
386 | msg = (const struct GNUNET_TESTING_CommandHelperInit *) message; | ||
387 | plugin_name_size = ntohs (msg->plugin_name_size); | ||
388 | if ((sizeof(struct GNUNET_TESTING_CommandHelperInit) + plugin_name_size) > | ||
389 | msize) | ||
390 | { | ||
391 | GNUNET_break (0); | ||
392 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
393 | "Received unexpected message -- exiting\n"); | ||
394 | goto error; | ||
395 | } | ||
396 | plugin_name = GNUNET_malloc (plugin_name_size + 1); | ||
397 | GNUNET_strlcpy (plugin_name, | ||
398 | ((char *) &msg[1]), | ||
399 | plugin_name_size + 1); | ||
400 | |||
401 | binary = GNUNET_OS_get_libexec_binary_path ("gnunet-cmd"); | ||
402 | |||
403 | plugin = GNUNET_new (struct TestcasePlugin); | ||
404 | plugin->api = GNUNET_PLUGIN_load (plugin_name, | ||
405 | NULL); | ||
406 | plugin->library_name = GNUNET_strdup (basename (plugin_name)); | ||
407 | |||
408 | plugin->global_n = ni->global_n; | ||
409 | plugin->local_m = ni->local_m; | ||
410 | plugin->n = ni->n; | ||
411 | plugin->m = ni->m; | ||
412 | |||
413 | GNUNET_asprintf (&router_ip, | ||
414 | ROUTER_BASE_IP "%s", | ||
415 | plugin->n); | ||
416 | { | ||
417 | char dummy; | ||
418 | |||
419 | if (1 != | ||
420 | sscanf (plugin->n, | ||
421 | "%u%c", | ||
422 | &namespace_n, | ||
423 | &dummy)) | ||
424 | { | ||
425 | // FIXME: how to handle error nicely? | ||
426 | GNUNET_break (0); | ||
427 | namespace_n = 0; | ||
428 | } | ||
429 | } | ||
430 | |||
431 | if (0 == namespace_n) | ||
432 | { | ||
433 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
434 | "known node n: %s\n", | ||
435 | plugin->n); | ||
436 | GNUNET_asprintf (&node_ip, | ||
437 | KNOWN_BASE_IP "%s", | ||
438 | plugin->m); | ||
439 | } | ||
440 | else | ||
441 | { | ||
442 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
443 | "subnet node n: %s\n", | ||
444 | plugin->n); | ||
445 | GNUNET_asprintf (&node_ip, | ||
446 | NODE_BASE_IP "%s", | ||
447 | plugin->m); | ||
448 | } | ||
449 | |||
450 | is = plugin->api->start_testcase (&write_message, | ||
451 | router_ip, | ||
452 | node_ip, | ||
453 | plugin->m, | ||
454 | plugin->n, | ||
455 | plugin->local_m, | ||
456 | ni->topology_data, | ||
457 | ni->read_file, | ||
458 | &finished_cb); | ||
459 | GNUNET_free (node_ip); | ||
460 | GNUNET_free (binary); | ||
461 | GNUNET_free (router_ip); | ||
462 | GNUNET_free (plugin_name); | ||
463 | |||
464 | msg_length = sizeof(struct GNUNET_TESTING_CommandHelperReply); | ||
465 | reply = GNUNET_new (struct GNUNET_TESTING_CommandHelperReply); | ||
466 | reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY); | ||
467 | reply->header.size = htons ((uint16_t) msg_length); | ||
468 | write_message (&reply->header, | ||
469 | msg_length); | ||
470 | return GNUNET_OK; | ||
471 | } | ||
472 | case GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_CROSSABLE: | ||
473 | { | ||
474 | const char *barrier_name; | ||
475 | struct CommandBarrierCrossable *adm = (struct | ||
476 | CommandBarrierCrossable *) message; | ||
477 | |||
478 | barrier_name = (const char *) &adm[1]; | ||
479 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
480 | "cross barrier %s\n", | ||
481 | barrier_name); | ||
482 | GNUNET_TESTING_finish_barrier_ (is, | ||
483 | barrier_name); | ||
484 | return GNUNET_OK; | ||
485 | } | ||
486 | case GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED: | ||
487 | { | ||
488 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
489 | "all peers started\n"); | ||
490 | plugin->api->all_peers_started (); | ||
491 | return GNUNET_OK; | ||
492 | } | ||
493 | case GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED: | ||
494 | { | ||
495 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
496 | "all local tests prepared\n"); | ||
497 | plugin->api->all_local_tests_prepared (); | ||
498 | return GNUNET_OK; | ||
499 | } | ||
500 | default: | ||
501 | LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n"); | ||
502 | goto error; | ||
503 | } | ||
504 | |||
505 | error: | ||
506 | status = GNUNET_SYSERR; | ||
507 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
508 | "tokenizer shutting down!\n"); | ||
509 | GNUNET_SCHEDULER_shutdown (); | ||
510 | return GNUNET_SYSERR; | ||
511 | } | ||
512 | |||
513 | |||
514 | /** | ||
515 | * Task to read from stdin | ||
516 | * | ||
517 | * @param cls NULL | ||
518 | */ | ||
519 | static void | ||
520 | read_task (void *cls) | ||
521 | { | ||
522 | char buf[GNUNET_MAX_MESSAGE_SIZE]; | ||
523 | ssize_t sread; | ||
524 | |||
525 | read_task_id = NULL; | ||
526 | sread = GNUNET_DISK_file_read (stdin_fd, buf, sizeof(buf)); | ||
527 | if ((GNUNET_SYSERR == sread) || (0 == sread)) | ||
528 | { | ||
529 | LOG_DEBUG ("STDIN closed\n"); | ||
530 | GNUNET_SCHEDULER_shutdown (); | ||
531 | return; | ||
532 | } | ||
533 | if (GNUNET_YES == done_reading) | ||
534 | { | ||
535 | /* didn't expect any more data! */ | ||
536 | GNUNET_break_op (0); | ||
537 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
538 | "tokenizer shutting down during reading, didn't expect any more data!\n"); | ||
539 | GNUNET_SCHEDULER_shutdown (); | ||
540 | return; | ||
541 | } | ||
542 | LOG_DEBUG ("Read %u bytes\n", (unsigned int) sread); | ||
543 | /* FIXME: could introduce a GNUNET_MST_read2 to read | ||
544 | directly from 'stdin_fd' and save a memcpy() here */ | ||
545 | if (GNUNET_OK != | ||
546 | GNUNET_MST_from_buffer (tokenizer, buf, sread, GNUNET_NO, GNUNET_NO)) | ||
547 | { | ||
548 | GNUNET_break (0); | ||
549 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
550 | "tokenizer shutting down during reading, writing to buffer failed!\n"); | ||
551 | GNUNET_SCHEDULER_shutdown (); | ||
552 | return; | ||
553 | } | ||
554 | read_task_id /* No timeout while reading */ | ||
555 | = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
556 | stdin_fd, | ||
557 | &read_task, | ||
558 | NULL); | ||
559 | } | ||
560 | |||
561 | |||
562 | /** | ||
563 | * Main function that will be run. | ||
564 | * | ||
565 | * @param cls closure | ||
566 | * @param args remaining command-line arguments | ||
567 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
568 | * @param cfg configuration | ||
569 | */ | ||
570 | static void | ||
571 | run (void *cls, | ||
572 | char *const *args, | ||
573 | const char *cfgfile, | ||
574 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
575 | { | ||
576 | struct NodeIdentifier *ni = cls; | ||
577 | |||
578 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
579 | "Starting interpreter loop helper...\n"); | ||
580 | |||
581 | tokenizer = GNUNET_MST_create (&tokenizer_cb, | ||
582 | ni); | ||
583 | stdin_fd = GNUNET_DISK_get_handle_from_native (stdin); | ||
584 | stdout_fd = GNUNET_DISK_get_handle_from_native (stdout); | ||
585 | read_task_id = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
586 | stdin_fd, | ||
587 | &read_task, | ||
588 | NULL); | ||
589 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | ||
590 | NULL); | ||
591 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
592 | "Interpreter loop helper started.\n"); | ||
593 | } | ||
594 | |||
595 | |||
596 | /** | ||
597 | * Signal handler called for SIGCHLD. | ||
598 | */ | ||
599 | static void | ||
600 | sighandler_child_death () | ||
601 | { | ||
602 | static char c; | ||
603 | int old_errno; /* back-up errno */ | ||
604 | |||
605 | old_errno = errno; | ||
606 | GNUNET_break ( | ||
607 | 1 == | ||
608 | GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe, | ||
609 | GNUNET_DISK_PIPE_END_WRITE), | ||
610 | &c, | ||
611 | sizeof(c))); | ||
612 | errno = old_errno; | ||
613 | } | ||
614 | |||
615 | |||
616 | /** | ||
617 | * Main function | ||
618 | * | ||
619 | * @param argc the number of command line arguments | ||
620 | * @param argv command line arg array | ||
621 | * @return return code | ||
622 | */ | ||
623 | int | ||
624 | main (int argc, char **argv) | ||
625 | { | ||
626 | struct NodeIdentifier *ni; | ||
627 | struct GNUNET_SIGNAL_Context *shc_chld; | ||
628 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
629 | GNUNET_GETOPT_OPTION_END | ||
630 | }; | ||
631 | int ret; | ||
632 | unsigned int sscanf_ret; | ||
633 | int i; | ||
634 | size_t topology_data_length = 0; | ||
635 | unsigned int read_file; | ||
636 | char cr[2] = "\n\0"; | ||
637 | |||
638 | GNUNET_log_setup ("gnunet-cmds-helper", | ||
639 | "DEBUG", | ||
640 | NULL); | ||
641 | ni = GNUNET_new (struct NodeIdentifier); | ||
642 | ni->global_n = argv[1]; | ||
643 | ni->local_m = argv[2]; | ||
644 | ni->m = argv[3]; | ||
645 | ni->n = argv[4]; | ||
646 | |||
647 | errno = 0; | ||
648 | sscanf_ret = sscanf (argv[5], "%u", &read_file); | ||
649 | |||
650 | if (errno != 0) | ||
651 | { | ||
652 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sscanf"); | ||
653 | } | ||
654 | else if (1 == read_file) | ||
655 | ni->topology_data = argv[6]; | ||
656 | else if (0 == read_file) | ||
657 | { | ||
658 | for (i = 6; i<argc; i++) | ||
659 | topology_data_length += strlen (argv[i]) + 1; | ||
660 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
661 | "topo data length %llu\n", | ||
662 | (unsigned long long) topology_data_length); | ||
663 | ni->topology_data = GNUNET_malloc (topology_data_length); | ||
664 | memset (ni->topology_data, '\0', topology_data_length); | ||
665 | for (i = 6; i<argc; i++) | ||
666 | { | ||
667 | strcat (ni->topology_data, argv[i]); | ||
668 | strcat (ni->topology_data, cr); | ||
669 | } | ||
670 | } | ||
671 | else | ||
672 | { | ||
673 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
674 | "Wrong input for the fourth argument\n"); | ||
675 | } | ||
676 | GNUNET_assert (0 < sscanf_ret); | ||
677 | ni->read_file = &read_file; | ||
678 | ni->topology_data[topology_data_length - 1] = '\0'; | ||
679 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
680 | "topo data %s\n", | ||
681 | ni->topology_data); | ||
682 | |||
683 | status = GNUNET_OK; | ||
684 | if (NULL == | ||
685 | (sigpipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE))) | ||
686 | { | ||
687 | GNUNET_break (0); | ||
688 | return 1; | ||
689 | } | ||
690 | shc_chld = | ||
691 | GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, | ||
692 | &sighandler_child_death); | ||
693 | ret = GNUNET_PROGRAM_run (argc, | ||
694 | argv, | ||
695 | "gnunet-cmds-helper", | ||
696 | "Helper for starting a local interpreter loop", | ||
697 | options, | ||
698 | &run, | ||
699 | ni); | ||
700 | |||
701 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
702 | "Finishing helper\n"); | ||
703 | GNUNET_SIGNAL_handler_uninstall (shc_chld); | ||
704 | shc_chld = NULL; | ||
705 | GNUNET_DISK_pipe_close (sigpipe); | ||
706 | GNUNET_free (ni); | ||
707 | if (GNUNET_OK != ret) | ||
708 | return 1; | ||
709 | return (GNUNET_OK == status) ? 0 : 1; | ||
710 | } | ||
711 | |||
712 | |||
713 | /* end of gnunet-cmds-helper.c */ | ||
diff --git a/src/service/testing/gnunet-testing.c b/src/service/testing/gnunet-testing.c deleted file mode 100644 index 88906e5fa..000000000 --- a/src/service/testing/gnunet-testing.c +++ /dev/null | |||
@@ -1,444 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009 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/gnunet-testing.c | ||
23 | * @brief tool to use testing functionality from cmd line | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_lib.h" | ||
29 | |||
30 | |||
31 | #define LOG(kind, ...) GNUNET_log_from (kind, "gnunet-testing", __VA_ARGS__) | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Final status code. | ||
36 | */ | ||
37 | static int ret; | ||
38 | |||
39 | /** | ||
40 | * Filename of the hostkey file we should write, | ||
41 | * null if we should not write a hostkey file. | ||
42 | */ | ||
43 | static char *create_hostkey; | ||
44 | |||
45 | /** | ||
46 | * Non-zero if we should create config files. | ||
47 | */ | ||
48 | static int create_cfg; | ||
49 | |||
50 | /** | ||
51 | * Number of config files to create. | ||
52 | */ | ||
53 | static unsigned int create_no; | ||
54 | |||
55 | /** | ||
56 | * Filename of the config template to be written. | ||
57 | */ | ||
58 | static char *create_cfg_template; | ||
59 | |||
60 | /** | ||
61 | * Service we are supposed to run. | ||
62 | */ | ||
63 | static char *run_service_name; | ||
64 | |||
65 | /** | ||
66 | * File handle to STDIN, for reading restart/quit commands. | ||
67 | */ | ||
68 | static struct GNUNET_DISK_FileHandle *fh; | ||
69 | |||
70 | /** | ||
71 | * Temporary filename, used with '-r' to write the configuration to. | ||
72 | */ | ||
73 | static char *tmpfilename; | ||
74 | |||
75 | /** | ||
76 | * Task identifier of the task that waits for stdin. | ||
77 | */ | ||
78 | static struct GNUNET_SCHEDULER_Task *tid; | ||
79 | |||
80 | /** | ||
81 | * Peer started for '-r'. | ||
82 | */ | ||
83 | static struct GNUNET_TESTING_Peer *my_peer; | ||
84 | |||
85 | |||
86 | static int | ||
87 | create_unique_cfgs (const char *template, const unsigned int no) | ||
88 | { | ||
89 | struct GNUNET_TESTING_System *system; | ||
90 | int fail; | ||
91 | unsigned int cur; | ||
92 | char *cur_file; | ||
93 | struct GNUNET_CONFIGURATION_Handle *cfg_new; | ||
94 | struct GNUNET_CONFIGURATION_Handle *cfg_tmpl; | ||
95 | |||
96 | if (GNUNET_NO == GNUNET_DISK_file_test (template)) | ||
97 | { | ||
98 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
99 | "Configuration template `%s': file not found\n", | ||
100 | create_cfg_template); | ||
101 | return 1; | ||
102 | } | ||
103 | cfg_tmpl = GNUNET_CONFIGURATION_create (); | ||
104 | |||
105 | /* load template */ | ||
106 | if ((create_cfg_template != NULL) && | ||
107 | (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg_tmpl, create_cfg_template))) | ||
108 | { | ||
109 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
110 | "Could not load template `%s'\n", | ||
111 | create_cfg_template); | ||
112 | GNUNET_CONFIGURATION_destroy (cfg_tmpl); | ||
113 | |||
114 | return 1; | ||
115 | } | ||
116 | /* load defaults */ | ||
117 | if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg_tmpl, NULL)) | ||
118 | { | ||
119 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
120 | "Could not load template `%s'\n", | ||
121 | create_cfg_template); | ||
122 | GNUNET_CONFIGURATION_destroy (cfg_tmpl); | ||
123 | return 1; | ||
124 | } | ||
125 | |||
126 | fail = GNUNET_NO; | ||
127 | system = | ||
128 | GNUNET_TESTING_system_create ("testing", NULL /* controller */, NULL, NULL); | ||
129 | for (cur = 0; cur < no; cur++) | ||
130 | { | ||
131 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
132 | "Creating configuration no. %u \n", | ||
133 | cur); | ||
134 | if (create_cfg_template != NULL) | ||
135 | GNUNET_asprintf (&cur_file, "%04u-%s", cur, create_cfg_template); | ||
136 | else | ||
137 | GNUNET_asprintf (&cur_file, "%04u%s", cur, ".conf"); | ||
138 | |||
139 | cfg_new = GNUNET_CONFIGURATION_dup (cfg_tmpl); | ||
140 | if (GNUNET_OK != GNUNET_TESTING_configuration_create (system, cfg_new)) | ||
141 | { | ||
142 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
143 | "Could not create another configuration\n"); | ||
144 | GNUNET_CONFIGURATION_destroy (cfg_new); | ||
145 | fail = GNUNET_YES; | ||
146 | break; | ||
147 | } | ||
148 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
149 | "Writing configuration no. %u to file `%s' \n", | ||
150 | cur, | ||
151 | cur_file); | ||
152 | if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg_new, cur_file)) | ||
153 | { | ||
154 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
155 | "Failed to write configuration no. %u \n", | ||
156 | cur); | ||
157 | fail = GNUNET_YES; | ||
158 | } | ||
159 | GNUNET_CONFIGURATION_destroy (cfg_new); | ||
160 | GNUNET_free (cur_file); | ||
161 | if (GNUNET_YES == fail) | ||
162 | break; | ||
163 | } | ||
164 | GNUNET_CONFIGURATION_destroy (cfg_tmpl); | ||
165 | GNUNET_TESTING_system_destroy (system, GNUNET_NO); | ||
166 | if (GNUNET_YES == fail) | ||
167 | return 1; | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | |||
172 | static int | ||
173 | create_hostkeys (const unsigned int no) | ||
174 | { | ||
175 | struct GNUNET_TESTING_System *system; | ||
176 | struct GNUNET_PeerIdentity id; | ||
177 | struct GNUNET_DISK_FileHandle *fd; | ||
178 | struct GNUNET_CRYPTO_EddsaPrivateKey *pk; | ||
179 | |||
180 | system = GNUNET_TESTING_system_create ("testing", NULL, NULL, NULL); | ||
181 | pk = GNUNET_TESTING_hostkey_get (system, create_no, &id); | ||
182 | if (NULL == pk) | ||
183 | { | ||
184 | fprintf (stderr, | ||
185 | _ ("Could not extract hostkey %u (offset too large?)\n"), | ||
186 | create_no); | ||
187 | GNUNET_TESTING_system_destroy (system, GNUNET_YES); | ||
188 | return 1; | ||
189 | } | ||
190 | (void) GNUNET_DISK_directory_create_for_file (create_hostkey); | ||
191 | fd = | ||
192 | GNUNET_DISK_file_open (create_hostkey, | ||
193 | GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE, | ||
194 | GNUNET_DISK_PERM_USER_READ | ||
195 | | GNUNET_DISK_PERM_USER_WRITE); | ||
196 | GNUNET_assert (fd != NULL); | ||
197 | ret = GNUNET_DISK_file_write (fd, | ||
198 | pk, | ||
199 | sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)); | ||
200 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); | ||
201 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
202 | "transport-testing", | ||
203 | "Wrote hostkey to file: `%s'\n", | ||
204 | create_hostkey); | ||
205 | GNUNET_free (pk); | ||
206 | GNUNET_TESTING_system_destroy (system, GNUNET_YES); | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | |||
211 | /** | ||
212 | * Cleanup called by signal handlers and when stdin is closed. | ||
213 | * Removes the temporary file. | ||
214 | * | ||
215 | * @param cls unused | ||
216 | */ | ||
217 | static void | ||
218 | cleanup (void *cls) | ||
219 | { | ||
220 | if (NULL != tmpfilename) | ||
221 | { | ||
222 | if (0 != unlink (tmpfilename)) | ||
223 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | ||
224 | "unlink", | ||
225 | tmpfilename); | ||
226 | } | ||
227 | if (NULL != tid) | ||
228 | { | ||
229 | GNUNET_SCHEDULER_cancel (tid); | ||
230 | tid = NULL; | ||
231 | } | ||
232 | if (NULL != fh) | ||
233 | { | ||
234 | GNUNET_DISK_file_close (fh); | ||
235 | fh = NULL; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | |||
240 | /** | ||
241 | * Called whenever we can read stdin non-blocking | ||
242 | * | ||
243 | * @param cls unused | ||
244 | */ | ||
245 | static void | ||
246 | stdin_cb (void *cls) | ||
247 | { | ||
248 | int c; | ||
249 | |||
250 | tid = NULL; | ||
251 | c = getchar (); | ||
252 | switch (c) | ||
253 | { | ||
254 | case EOF: | ||
255 | case 'q': | ||
256 | GNUNET_SCHEDULER_shutdown (); | ||
257 | return; | ||
258 | |||
259 | case 'r': | ||
260 | if (GNUNET_OK != GNUNET_TESTING_peer_stop (my_peer)) | ||
261 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to stop the peer\n"); | ||
262 | if (GNUNET_OK != GNUNET_TESTING_peer_start (my_peer)) | ||
263 | LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to start the peer\n"); | ||
264 | printf ("restarted\n"); | ||
265 | fflush (stdout); | ||
266 | break; | ||
267 | |||
268 | case '\n': | ||
269 | case '\r': | ||
270 | /* ignore whitespace */ | ||
271 | break; | ||
272 | |||
273 | default: | ||
274 | fprintf (stderr, | ||
275 | _ ("Unknown command, use 'q' to quit or 'r' to restart peer\n")); | ||
276 | break; | ||
277 | } | ||
278 | tid = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
279 | fh, | ||
280 | &stdin_cb, | ||
281 | NULL); | ||
282 | } | ||
283 | |||
284 | |||
285 | /** | ||
286 | * Main function called by the testing library. | ||
287 | * Executed inside a running scheduler. | ||
288 | * | ||
289 | * @param cls unused | ||
290 | * @param cfg configuration of the peer that was started | ||
291 | * @param peer handle to the peer | ||
292 | */ | ||
293 | static void | ||
294 | testing_main (void *cls, | ||
295 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
296 | struct GNUNET_TESTING_Peer *peer) | ||
297 | { | ||
298 | my_peer = peer; | ||
299 | if (NULL == (tmpfilename = GNUNET_DISK_mktemp ("gnunet-testing"))) | ||
300 | { | ||
301 | GNUNET_break (0); | ||
302 | GNUNET_SCHEDULER_shutdown (); | ||
303 | return; | ||
304 | } | ||
305 | if (GNUNET_SYSERR == | ||
306 | GNUNET_CONFIGURATION_write ((struct GNUNET_CONFIGURATION_Handle *) cfg, | ||
307 | tmpfilename)) | ||
308 | { | ||
309 | GNUNET_break (0); | ||
310 | return; | ||
311 | } | ||
312 | printf ("ok\n%s\n", tmpfilename); | ||
313 | fflush (stdout); | ||
314 | GNUNET_SCHEDULER_add_shutdown (&cleanup, NULL); | ||
315 | fh = GNUNET_DISK_get_handle_from_native (stdin); | ||
316 | tid = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
317 | fh, | ||
318 | &stdin_cb, | ||
319 | NULL); | ||
320 | } | ||
321 | |||
322 | |||
323 | /** | ||
324 | * Main function that will be running without scheduler. | ||
325 | * | ||
326 | * @param cls closure | ||
327 | * @param args remaining command-line arguments | ||
328 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
329 | * @param cfg configuration | ||
330 | */ | ||
331 | static void | ||
332 | run_no_scheduler (void *cls, | ||
333 | char *const *args, | ||
334 | const char *cfgfile, | ||
335 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
336 | { | ||
337 | if (NULL != run_service_name) | ||
338 | { | ||
339 | ret = GNUNET_TESTING_service_run ("gnunet_service_test", | ||
340 | run_service_name, | ||
341 | cfgfile, | ||
342 | &testing_main, | ||
343 | NULL); | ||
344 | return; | ||
345 | } | ||
346 | |||
347 | if (GNUNET_YES == create_cfg) | ||
348 | { | ||
349 | if (create_no > 0) | ||
350 | { | ||
351 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
352 | "Creating %u configuration files based on template `%s'\n", | ||
353 | create_no, | ||
354 | create_cfg_template); | ||
355 | ret = create_unique_cfgs (create_cfg_template, create_no); | ||
356 | } | ||
357 | else | ||
358 | { | ||
359 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Missing arguments! \n"); | ||
360 | ret = 1; | ||
361 | } | ||
362 | } | ||
363 | if (NULL != create_hostkey) | ||
364 | { | ||
365 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Extracting hostkey %u\n", create_no); | ||
366 | ret = create_hostkeys (create_no); | ||
367 | } | ||
368 | GNUNET_free (create_cfg_template); | ||
369 | } | ||
370 | |||
371 | |||
372 | /** | ||
373 | * The main function. | ||
374 | * | ||
375 | * @param argc number of arguments from the command line | ||
376 | * @param argv command line arguments | ||
377 | * @return 0 ok, 1 on error | ||
378 | */ | ||
379 | int | ||
380 | main (int argc, char *const *argv) | ||
381 | { | ||
382 | struct GNUNET_GETOPT_CommandLineOption options[] = | ||
383 | { GNUNET_GETOPT_option_flag ('C', | ||
384 | "cfg", | ||
385 | gettext_noop ( | ||
386 | "create unique configuration files"), | ||
387 | &create_cfg), | ||
388 | GNUNET_GETOPT_option_string ( | ||
389 | 'k', | ||
390 | "key", | ||
391 | "FILENAME", | ||
392 | gettext_noop ("extract hostkey file from pre-computed hostkey list"), | ||
393 | &create_hostkey), | ||
394 | |||
395 | GNUNET_GETOPT_option_uint ( | ||
396 | 'n', | ||
397 | "number", | ||
398 | "NUMBER", | ||
399 | gettext_noop ( | ||
400 | "number of unique configuration files to create, or number of the hostkey to extract"), | ||
401 | &create_no), | ||
402 | |||
403 | |||
404 | GNUNET_GETOPT_option_string ('t', | ||
405 | "template", | ||
406 | "FILENAME", | ||
407 | gettext_noop ("configuration template"), | ||
408 | &create_cfg_template), | ||
409 | |||
410 | GNUNET_GETOPT_option_string ( | ||
411 | 'r', | ||
412 | "run", | ||
413 | "SERVICE", | ||
414 | gettext_noop ( | ||
415 | "run the given service, wait on stdin for 'r' (restart) or 'q' (quit)"), | ||
416 | &run_service_name), | ||
417 | GNUNET_GETOPT_OPTION_END }; | ||
418 | |||
419 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | ||
420 | return 2; | ||
421 | |||
422 | /* Run without scheduler, because we may want to call | ||
423 | * GNUNET_TESTING_service_run, which starts the scheduler on its own. | ||
424 | * Furthermore, the other functionality currently does not require the scheduler, too, | ||
425 | * but beware when extending gnunet-testing. */ | ||
426 | ret = | ||
427 | (GNUNET_OK == | ||
428 | GNUNET_PROGRAM_run2 (argc, | ||
429 | argv, | ||
430 | "gnunet-testing", | ||
431 | gettext_noop ( | ||
432 | "Command line tool to access the testing library"), | ||
433 | options, | ||
434 | &run_no_scheduler, | ||
435 | NULL, | ||
436 | GNUNET_YES)) | ||
437 | ? ret | ||
438 | : 1; | ||
439 | GNUNET_free_nz ((void *) argv); | ||
440 | return ret; | ||
441 | } | ||
442 | |||
443 | |||
444 | /* end of gnunet-testing.c */ | ||
diff --git a/src/service/testing/list-keys.c b/src/service/testing/list-keys.c deleted file mode 100644 index f65b45a77..000000000 --- a/src/service/testing/list-keys.c +++ /dev/null | |||
@@ -1,112 +0,0 @@ | |||
1 | #include "platform.h" | ||
2 | #include "gnunet_util_lib.h" | ||
3 | #include "gnunet_testing_lib.h" | ||
4 | |||
5 | static unsigned int nkeys; | ||
6 | static unsigned int nskip; | ||
7 | static int result; | ||
8 | |||
9 | /** | ||
10 | * Main run function. | ||
11 | * | ||
12 | * @param cls NULL | ||
13 | * @param args arguments passed to GNUNET_PROGRAM_run | ||
14 | * @param cfgfile the path to configuration file | ||
15 | * @param cfg the configuration file handle | ||
16 | */ | ||
17 | static void | ||
18 | run (void *cls, | ||
19 | char *const *args, | ||
20 | const char *cfgfile, | ||
21 | const struct GNUNET_CONFIGURATION_Handle *config) | ||
22 | { | ||
23 | char *idfile; | ||
24 | struct GNUNET_DISK_FileHandle *f; | ||
25 | void *data; | ||
26 | struct GNUNET_DISK_MapHandle *map; | ||
27 | struct GNUNET_CRYPTO_EddsaPrivateKey pkey; | ||
28 | struct GNUNET_PeerIdentity id; | ||
29 | unsigned int cnt; | ||
30 | uint64_t fsize; | ||
31 | unsigned int nmax; | ||
32 | |||
33 | if ((NULL == args) || (NULL == args[0])) | ||
34 | { | ||
35 | fprintf (stderr, "Need the hostkey file\n"); | ||
36 | return; | ||
37 | } | ||
38 | idfile = args[0]; | ||
39 | if (GNUNET_OK != | ||
40 | GNUNET_DISK_file_size (idfile, &fsize, GNUNET_YES, GNUNET_YES)) | ||
41 | { | ||
42 | GNUNET_break (0); | ||
43 | return; | ||
44 | } | ||
45 | if (0 != (fsize % GNUNET_TESTING_HOSTKEYFILESIZE)) | ||
46 | { | ||
47 | fprintf (stderr, _ ("Incorrect hostkey file format: %s\n"), idfile); | ||
48 | return; | ||
49 | } | ||
50 | f = GNUNET_DISK_file_open (idfile, | ||
51 | GNUNET_DISK_OPEN_READ, | ||
52 | GNUNET_DISK_PERM_NONE); | ||
53 | if (NULL == f) | ||
54 | { | ||
55 | GNUNET_break (0); | ||
56 | return; | ||
57 | } | ||
58 | data = GNUNET_DISK_file_map (f, &map, GNUNET_DISK_MAP_TYPE_READ, fsize); | ||
59 | if (NULL == data) | ||
60 | { | ||
61 | GNUNET_break (0); | ||
62 | GNUNET_DISK_file_close (f); | ||
63 | return; | ||
64 | } | ||
65 | nmax = fsize / GNUNET_TESTING_HOSTKEYFILESIZE; | ||
66 | for (cnt = nskip; cnt < (nskip + nkeys); cnt++) | ||
67 | { | ||
68 | if (nskip + cnt >= nmax) | ||
69 | { | ||
70 | printf ("Max keys %u reached\n", nmax); | ||
71 | break; | ||
72 | } | ||
73 | GNUNET_memcpy (&pkey, | ||
74 | data + (cnt * GNUNET_TESTING_HOSTKEYFILESIZE), | ||
75 | GNUNET_TESTING_HOSTKEYFILESIZE); | ||
76 | GNUNET_CRYPTO_eddsa_key_get_public (&pkey, &id.public_key); | ||
77 | printf ("Key %u: %s\n", cnt, GNUNET_i2s_full (&id)); | ||
78 | } | ||
79 | result = GNUNET_OK; | ||
80 | GNUNET_DISK_file_unmap (map); | ||
81 | GNUNET_DISK_file_close (f); | ||
82 | } | ||
83 | |||
84 | |||
85 | int | ||
86 | main (int argc, char *argv[]) | ||
87 | { | ||
88 | struct GNUNET_GETOPT_CommandLineOption option[] = | ||
89 | { GNUNET_GETOPT_option_uint ('n', | ||
90 | "num-keys", | ||
91 | "COUNT", | ||
92 | gettext_noop ("list COUNT number of keys"), | ||
93 | &nkeys), | ||
94 | GNUNET_GETOPT_OPTION_END }; | ||
95 | int ret; | ||
96 | |||
97 | result = GNUNET_SYSERR; | ||
98 | nkeys = 10; | ||
99 | ret = | ||
100 | GNUNET_PROGRAM_run (argc, | ||
101 | argv, | ||
102 | "list-keys", | ||
103 | "Lists the peer IDs corresponding to the given keys file\n", | ||
104 | option, | ||
105 | &run, | ||
106 | NULL); | ||
107 | if (GNUNET_OK != ret) | ||
108 | return 1; | ||
109 | if (GNUNET_SYSERR == result) | ||
110 | return 1; | ||
111 | return 0; | ||
112 | } | ||
diff --git a/src/service/testing/test_testing_defaults.conf b/src/service/testing/test_testing_defaults.conf deleted file mode 100644 index 2e7c39113..000000000 --- a/src/service/testing/test_testing_defaults.conf +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | [PATHS] | ||
2 | GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-testing/ | ||
3 | |||
4 | [transport] | ||
5 | PLUGINS = tcp | ||
6 | |||
7 | [transport-tcp] | ||
8 | TESTING_IGNORE_KEYS = SOMETHING;KEY1;ACCEPT_FROM; | ||
9 | |||
10 | [transport-tcp] | ||
11 | BINDTO = 127.0.0.1 | ||
12 | |||
13 | [nat] | ||
14 | DISABLEV6 = YES | ||
15 | ENABLE_UPNP = NO | ||
16 | BEHIND_NAT = NO | ||
17 | ALLOW_NAT = NO | ||
18 | INTERNAL_ADDRESS = 127.0.0.1 | ||
19 | EXTERNAL_ADDRESS = 127.0.0.1 | ||
20 | USE_LOCALADDR = NO | ||
21 | |||
22 | |||
23 | [rps] | ||
24 | START_ON_DEMAND = NO | ||
25 | IMMEDIATE_START = NO | ||
diff --git a/src/service/testing/test_testing_peerstartup.c b/src/service/testing/test_testing_peerstartup.c deleted file mode 100644 index 25cbb2a9f..000000000 --- a/src/service/testing/test_testing_peerstartup.c +++ /dev/null | |||
@@ -1,143 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2008, 2009, 2012 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_new_peerstartup.c | ||
23 | * @brief test case for testing peer startup and shutdown using new testing | ||
24 | * library | ||
25 | * @author Sree Harsha Totakura | ||
26 | */ | ||
27 | |||
28 | #include "platform.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_testing_lib.h" | ||
31 | |||
32 | #define LOG(kind, ...) \ | ||
33 | GNUNET_log (kind, __VA_ARGS__) | ||
34 | |||
35 | /** | ||
36 | * The status of the test | ||
37 | */ | ||
38 | int status; | ||
39 | |||
40 | /** | ||
41 | * The testing context | ||
42 | */ | ||
43 | struct TestingContext | ||
44 | { | ||
45 | /** | ||
46 | * The testing system | ||
47 | */ | ||
48 | struct GNUNET_TESTING_System *system; | ||
49 | |||
50 | /** | ||
51 | * The peer which has been started by the testing system | ||
52 | */ | ||
53 | struct GNUNET_TESTING_Peer *peer; | ||
54 | |||
55 | /** | ||
56 | * The running configuration of the peer | ||
57 | */ | ||
58 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
59 | }; | ||
60 | |||
61 | |||
62 | /** | ||
63 | * Task for shutdown | ||
64 | * | ||
65 | * @param cls the testing context | ||
66 | */ | ||
67 | static void | ||
68 | do_shutdown (void *cls) | ||
69 | { | ||
70 | struct TestingContext *test_ctx = cls; | ||
71 | |||
72 | GNUNET_assert (NULL != test_ctx); | ||
73 | if (NULL != test_ctx->peer) | ||
74 | { | ||
75 | (void) GNUNET_TESTING_peer_stop (test_ctx->peer); | ||
76 | GNUNET_TESTING_peer_destroy (test_ctx->peer); | ||
77 | } | ||
78 | if (NULL != test_ctx->cfg) | ||
79 | GNUNET_CONFIGURATION_destroy (test_ctx->cfg); | ||
80 | if (NULL != test_ctx->system) | ||
81 | GNUNET_TESTING_system_destroy (test_ctx->system, GNUNET_YES); | ||
82 | GNUNET_free (test_ctx); | ||
83 | } | ||
84 | |||
85 | |||
86 | /** | ||
87 | * Main point of test execution | ||
88 | */ | ||
89 | static void | ||
90 | run (void *cls, char *const *args, const char *cfgfile, | ||
91 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
92 | { | ||
93 | struct TestingContext *test_ctx; | ||
94 | char *emsg; | ||
95 | struct GNUNET_PeerIdentity id; | ||
96 | |||
97 | test_ctx = GNUNET_new (struct TestingContext); | ||
98 | test_ctx->system = | ||
99 | GNUNET_TESTING_system_create ("test-gnunet-testing", | ||
100 | "127.0.0.1", NULL, NULL); | ||
101 | emsg = NULL; | ||
102 | if (NULL == test_ctx->system) | ||
103 | goto end; | ||
104 | test_ctx->cfg = GNUNET_CONFIGURATION_dup (cfg); | ||
105 | test_ctx->peer = | ||
106 | GNUNET_TESTING_peer_configure (test_ctx->system, | ||
107 | test_ctx->cfg, | ||
108 | 0, &id, &emsg); | ||
109 | if (NULL == test_ctx->peer) | ||
110 | { | ||
111 | if (NULL != emsg) | ||
112 | printf ("Test failed upon error: %s", emsg); | ||
113 | goto end; | ||
114 | } | ||
115 | if (GNUNET_OK != GNUNET_TESTING_peer_start (test_ctx->peer)) | ||
116 | goto end; | ||
117 | status = GNUNET_OK; | ||
118 | |||
119 | end: | ||
120 | GNUNET_SCHEDULER_add_now (&do_shutdown, test_ctx); | ||
121 | GNUNET_free (emsg); | ||
122 | } | ||
123 | |||
124 | |||
125 | int | ||
126 | main (int argc, char *argv[]) | ||
127 | { | ||
128 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
129 | GNUNET_GETOPT_OPTION_END | ||
130 | }; | ||
131 | |||
132 | status = GNUNET_SYSERR; | ||
133 | if (GNUNET_OK != | ||
134 | GNUNET_PROGRAM_run (argc, argv, | ||
135 | "test_testing_peerstartup", | ||
136 | "test case for peerstartup using new testing library", | ||
137 | options, &run, NULL)) | ||
138 | return 1; | ||
139 | return (GNUNET_OK == status) ? 0 : 1; | ||
140 | } | ||
141 | |||
142 | |||
143 | /* end of test_testing_peerstartup.c */ | ||
diff --git a/src/service/testing/test_testing_peerstartup2.c b/src/service/testing/test_testing_peerstartup2.c deleted file mode 100644 index 8d357cb08..000000000 --- a/src/service/testing/test_testing_peerstartup2.c +++ /dev/null | |||
@@ -1,222 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2008, 2009, 2012 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_new_peerstartup.c | ||
23 | * @brief test case for testing peer startup and shutdown using new testing | ||
24 | * library | ||
25 | * @author Sree Harsha Totakura | ||
26 | */ | ||
27 | |||
28 | #include "platform.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_testing_lib.h" | ||
31 | |||
32 | #define LOG(kind, ...) \ | ||
33 | GNUNET_log (kind, __VA_ARGS__) | ||
34 | |||
35 | |||
36 | #define FAIL_TEST(cond) \ | ||
37 | do { \ | ||
38 | if (! (cond)) { \ | ||
39 | GNUNET_break (0); \ | ||
40 | if (GNUNET_OK == status) { \ | ||
41 | status = GNUNET_SYSERR; \ | ||
42 | } \ | ||
43 | } \ | ||
44 | } while (0) \ | ||
45 | |||
46 | |||
47 | /** | ||
48 | * The status of the test | ||
49 | */ | ||
50 | int status; | ||
51 | |||
52 | /** | ||
53 | * The testing context | ||
54 | */ | ||
55 | struct TestingContext | ||
56 | { | ||
57 | /** | ||
58 | * The testing system | ||
59 | */ | ||
60 | struct GNUNET_TESTING_System *system; | ||
61 | |||
62 | /** | ||
63 | * The peer which has been started by the testing system | ||
64 | */ | ||
65 | struct GNUNET_TESTING_Peer *peer; | ||
66 | |||
67 | /** | ||
68 | * The running configuration of the peer | ||
69 | */ | ||
70 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
71 | |||
72 | /** | ||
73 | * State | ||
74 | */ | ||
75 | enum | ||
76 | { | ||
77 | PEER_INIT, | ||
78 | |||
79 | PEER_STARTED, | ||
80 | |||
81 | PEER_STOPPED | ||
82 | } state; | ||
83 | }; | ||
84 | |||
85 | |||
86 | static void | ||
87 | do_shutdown2 (void *cls) | ||
88 | { | ||
89 | struct TestingContext *test_ctx = cls; | ||
90 | |||
91 | if (NULL != test_ctx->peer) | ||
92 | GNUNET_TESTING_peer_destroy (test_ctx->peer); | ||
93 | if (NULL != test_ctx->cfg) | ||
94 | GNUNET_CONFIGURATION_destroy (test_ctx->cfg); | ||
95 | if (NULL != test_ctx->system) | ||
96 | GNUNET_TESTING_system_destroy (test_ctx->system, GNUNET_YES); | ||
97 | GNUNET_free (test_ctx); | ||
98 | } | ||
99 | |||
100 | |||
101 | /** | ||
102 | * Task for shutdown | ||
103 | * | ||
104 | * @param cls the testing context | ||
105 | */ | ||
106 | static void | ||
107 | do_shutdown (void *cls); | ||
108 | |||
109 | |||
110 | static void | ||
111 | peer_status_cb (void *cls, struct GNUNET_TESTING_Peer *peer, int success) | ||
112 | { | ||
113 | struct TestingContext *test_ctx = cls; | ||
114 | |||
115 | switch (test_ctx->state) | ||
116 | { | ||
117 | case PEER_INIT: | ||
118 | FAIL_TEST (0); | ||
119 | break; | ||
120 | |||
121 | case PEER_STARTED: | ||
122 | FAIL_TEST (GNUNET_YES == success); | ||
123 | test_ctx->state = PEER_STOPPED; | ||
124 | GNUNET_SCHEDULER_add_now (&do_shutdown2, cls); | ||
125 | break; | ||
126 | |||
127 | case PEER_STOPPED: | ||
128 | FAIL_TEST (0); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | |||
133 | /** | ||
134 | * Task for shutdown | ||
135 | * | ||
136 | * @param cls the testing context | ||
137 | */ | ||
138 | static void | ||
139 | do_shutdown (void *cls) | ||
140 | { | ||
141 | struct TestingContext *test_ctx = cls; | ||
142 | |||
143 | GNUNET_assert (NULL != test_ctx); | ||
144 | if (NULL != test_ctx->peer) | ||
145 | { | ||
146 | FAIL_TEST (GNUNET_OK == | ||
147 | GNUNET_TESTING_peer_stop_async (test_ctx->peer, | ||
148 | &peer_status_cb, | ||
149 | test_ctx)); | ||
150 | } | ||
151 | else | ||
152 | do_shutdown2 (test_ctx); | ||
153 | } | ||
154 | |||
155 | |||
156 | /** | ||
157 | * Main point of test execution | ||
158 | */ | ||
159 | static void | ||
160 | run (void *cls, char *const *args, const char *cfgfile, | ||
161 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
162 | { | ||
163 | struct TestingContext *test_ctx; | ||
164 | char *emsg; | ||
165 | struct GNUNET_PeerIdentity id; | ||
166 | |||
167 | test_ctx = GNUNET_new (struct TestingContext); | ||
168 | test_ctx->system = | ||
169 | GNUNET_TESTING_system_create ("test-gnunet-testing", | ||
170 | "127.0.0.1", NULL, NULL); | ||
171 | emsg = NULL; | ||
172 | if (NULL == test_ctx->system) | ||
173 | goto end; | ||
174 | test_ctx->cfg = GNUNET_CONFIGURATION_dup (cfg); | ||
175 | test_ctx->peer = | ||
176 | GNUNET_TESTING_peer_configure (test_ctx->system, | ||
177 | test_ctx->cfg, | ||
178 | 0, &id, &emsg); | ||
179 | if (NULL == test_ctx->peer) | ||
180 | { | ||
181 | if (NULL != emsg) | ||
182 | printf ("Test failed upon error: %s", emsg); | ||
183 | goto end; | ||
184 | } | ||
185 | if (GNUNET_OK != GNUNET_TESTING_peer_start (test_ctx->peer)) | ||
186 | goto end; | ||
187 | test_ctx->state = PEER_STARTED; | ||
188 | FAIL_TEST (GNUNET_OK == | ||
189 | GNUNET_TESTING_peer_stop_async (test_ctx->peer, | ||
190 | &peer_status_cb, | ||
191 | test_ctx)); | ||
192 | GNUNET_TESTING_peer_stop_async_cancel (test_ctx->peer); | ||
193 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | ||
194 | &do_shutdown, test_ctx); | ||
195 | return; | ||
196 | |||
197 | end: | ||
198 | FAIL_TEST (0); | ||
199 | GNUNET_SCHEDULER_add_now (&do_shutdown, test_ctx); | ||
200 | GNUNET_free (emsg); | ||
201 | } | ||
202 | |||
203 | |||
204 | int | ||
205 | main (int argc, char *argv[]) | ||
206 | { | ||
207 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
208 | GNUNET_GETOPT_OPTION_END | ||
209 | }; | ||
210 | |||
211 | status = GNUNET_OK; | ||
212 | if (GNUNET_OK != | ||
213 | GNUNET_PROGRAM_run (argc, argv, | ||
214 | "test_testing_new_peerstartup", | ||
215 | "test case for peerstartup using new testing library", | ||
216 | options, &run, NULL)) | ||
217 | return 1; | ||
218 | return (GNUNET_OK == status) ? 0 : 1; | ||
219 | } | ||
220 | |||
221 | |||
222 | /* end of test_testing_peerstartup.c */ | ||
diff --git a/src/service/testing/test_testing_servicestartup.c b/src/service/testing/test_testing_servicestartup.c deleted file mode 100644 index 83458898b..000000000 --- a/src/service/testing/test_testing_servicestartup.c +++ /dev/null | |||
@@ -1,75 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2008, 2009, 2012 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_new_servicestartup.c | ||
23 | * @brief test case for testing service startup using new testing API | ||
24 | * @author Sree Harsha Totakura | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_lib.h" | ||
29 | |||
30 | |||
31 | #define LOG(kind, ...) \ | ||
32 | GNUNET_log (kind, __VA_ARGS__) | ||
33 | |||
34 | |||
35 | /** | ||
36 | * Global test status | ||
37 | */ | ||
38 | static int test_success; | ||
39 | |||
40 | |||
41 | /** | ||
42 | * The testing callback function | ||
43 | * | ||
44 | * @param cls NULL | ||
45 | * @param cfg the configuration with which the current testing service is run | ||
46 | */ | ||
47 | static void | ||
48 | test_run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
49 | struct GNUNET_TESTING_Peer *peer) | ||
50 | { | ||
51 | GNUNET_assert (NULL == cls); | ||
52 | GNUNET_assert (NULL != cfg); | ||
53 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Service arm started successfully\n"); | ||
54 | test_success = GNUNET_YES; | ||
55 | GNUNET_SCHEDULER_shutdown (); | ||
56 | } | ||
57 | |||
58 | |||
59 | /** | ||
60 | * The main point of execution | ||
61 | */ | ||
62 | int | ||
63 | main (int argc, char *argv[]) | ||
64 | { | ||
65 | test_success = GNUNET_NO; | ||
66 | GNUNET_assert (0 == GNUNET_TESTING_service_run ("test-testing-servicestartup", | ||
67 | "arm", | ||
68 | "test_testing_defaults.conf", | ||
69 | &test_run, | ||
70 | NULL)); | ||
71 | return (GNUNET_YES == test_success) ? 0 : 1; | ||
72 | } | ||
73 | |||
74 | |||
75 | /* end of test_testing_servicestartup.c */ | ||
diff --git a/src/service/testing/test_testing_sharedservices.c b/src/service/testing/test_testing_sharedservices.c deleted file mode 100644 index d2f760d7a..000000000 --- a/src/service/testing/test_testing_sharedservices.c +++ /dev/null | |||
@@ -1,167 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2008, 2009, 2012 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_sharedservices.c | ||
23 | * @brief test case for testing service sharing among peers started by testing | ||
24 | * @author Sree Harsha Totakura <sreeharsha@totakura.in> | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_testing_lib.h" | ||
30 | |||
31 | #define LOG(kind, ...) \ | ||
32 | GNUNET_log (kind, __VA_ARGS__) | ||
33 | |||
34 | #define NUM_PEERS 4 | ||
35 | |||
36 | /** | ||
37 | * The status of the test | ||
38 | */ | ||
39 | int status; | ||
40 | |||
41 | /** | ||
42 | * The testing context | ||
43 | */ | ||
44 | struct TestingContext | ||
45 | { | ||
46 | /** | ||
47 | * The testing system | ||
48 | */ | ||
49 | struct GNUNET_TESTING_System *system; | ||
50 | |||
51 | /** | ||
52 | * The peer which has been started by the testing system | ||
53 | */ | ||
54 | struct GNUNET_TESTING_Peer *peers[NUM_PEERS]; | ||
55 | |||
56 | /** | ||
57 | * The running configuration of the peer | ||
58 | */ | ||
59 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
60 | }; | ||
61 | |||
62 | |||
63 | /** | ||
64 | * Task for shutdown | ||
65 | * | ||
66 | * @param cls the testing context | ||
67 | */ | ||
68 | static void | ||
69 | do_shutdown (void *cls) | ||
70 | { | ||
71 | struct TestingContext *test_ctx = cls; | ||
72 | struct GNUNET_TESTING_Peer *peer; | ||
73 | unsigned int cnt; | ||
74 | |||
75 | GNUNET_assert (NULL != test_ctx); | ||
76 | for (cnt = 0; cnt < NUM_PEERS; cnt++) | ||
77 | { | ||
78 | peer = test_ctx->peers[cnt]; | ||
79 | if (NULL == peer) | ||
80 | continue; | ||
81 | (void) GNUNET_TESTING_peer_stop (peer); | ||
82 | GNUNET_TESTING_peer_destroy (peer); | ||
83 | } | ||
84 | if (NULL != test_ctx->cfg) | ||
85 | GNUNET_CONFIGURATION_destroy (test_ctx->cfg); | ||
86 | if (NULL != test_ctx->system) | ||
87 | GNUNET_TESTING_system_destroy (test_ctx->system, GNUNET_YES); | ||
88 | GNUNET_free (test_ctx); | ||
89 | } | ||
90 | |||
91 | |||
92 | /** | ||
93 | * Main point of test execution | ||
94 | */ | ||
95 | static void | ||
96 | run (void *cls, char *const *args, const char *cfgfile, | ||
97 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
98 | { | ||
99 | struct TestingContext *test_ctx; | ||
100 | char *emsg; | ||
101 | struct GNUNET_PeerIdentity id; | ||
102 | struct GNUNET_TESTING_SharedService ss[] = { | ||
103 | { "peerinfo", cfg, 2 }, | ||
104 | { NULL, NULL, 0 } | ||
105 | }; | ||
106 | struct GNUNET_TESTING_Peer *peer; | ||
107 | unsigned int cnt; | ||
108 | |||
109 | test_ctx = GNUNET_new (struct TestingContext); | ||
110 | test_ctx->system = | ||
111 | GNUNET_TESTING_system_create ("test-gnunet-testing", | ||
112 | "127.0.0.1", NULL, ss); | ||
113 | emsg = NULL; | ||
114 | if (NULL == test_ctx->system) | ||
115 | goto end; | ||
116 | test_ctx->cfg = GNUNET_CONFIGURATION_dup (cfg); | ||
117 | for (cnt = 0; cnt < NUM_PEERS; cnt++) | ||
118 | { | ||
119 | peer = GNUNET_TESTING_peer_configure (test_ctx->system, | ||
120 | test_ctx->cfg, | ||
121 | 0, &id, &emsg); | ||
122 | if (NULL == peer) | ||
123 | { | ||
124 | if (NULL != emsg) | ||
125 | printf ("Test failed upon error: %s", emsg); | ||
126 | goto end; | ||
127 | } | ||
128 | if (GNUNET_OK != GNUNET_TESTING_peer_start (peer)) | ||
129 | { | ||
130 | GNUNET_TESTING_peer_destroy (peer); | ||
131 | goto end; | ||
132 | } | ||
133 | test_ctx->peers[cnt] = peer; | ||
134 | } | ||
135 | status = GNUNET_OK; | ||
136 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | ||
137 | &do_shutdown, test_ctx); | ||
138 | return; | ||
139 | |||
140 | end: | ||
141 | GNUNET_SCHEDULER_add_now (&do_shutdown, test_ctx); | ||
142 | GNUNET_free (emsg); | ||
143 | } | ||
144 | |||
145 | |||
146 | int | ||
147 | main (int argc, char *argv[]) | ||
148 | { | ||
149 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
150 | GNUNET_GETOPT_OPTION_END | ||
151 | }; | ||
152 | char *const argv2[] = { "test_testing_sharedservices", | ||
153 | "-c", "test_testing_sharedservices.conf", | ||
154 | NULL }; | ||
155 | |||
156 | status = GNUNET_SYSERR; | ||
157 | if (GNUNET_OK != | ||
158 | GNUNET_PROGRAM_run ((sizeof(argv2) / sizeof(char *)) - 1, argv2, | ||
159 | "test_testing_sharedservices", | ||
160 | "test case for testing service sharing among peers started by testing", | ||
161 | options, &run, NULL)) | ||
162 | return 1; | ||
163 | return (GNUNET_OK == status) ? 0 : 3; | ||
164 | } | ||
165 | |||
166 | |||
167 | /* end of test_testing_sharedservices.c */ | ||
diff --git a/src/service/testing/test_testing_sharedservices.conf b/src/service/testing/test_testing_sharedservices.conf deleted file mode 100644 index 92eac7e71..000000000 --- a/src/service/testing/test_testing_sharedservices.conf +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | [PATHS] | ||
2 | GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-testing/ | ||
3 | |||
4 | [testbed-logger] | ||
5 | PORT = 59132 | ||
6 | UNIXPATH = $GNUNET_RUNTIME_DIR/testbed-logger.sock | ||
7 | DIR = $GNUNET_TMP/testbed-logger | ||
8 | |||
9 | [transport] | ||
10 | PLUGINS = tcp | ||
11 | |||
12 | [transport-tcp] | ||
13 | TESTING_IGNORE_KEYS = SOMETHING;KEY1;ACCEPT_FROM; | ||
14 | |||
15 | [transport-tcp] | ||
16 | BINDTO = 127.0.0.1 | ||
17 | |||
18 | [nat] | ||
19 | DISABLEV6 = YES | ||
20 | ENABLE_UPNP = NO | ||
21 | BEHIND_NAT = NO | ||
22 | ALLOW_NAT = NO | ||
23 | INTERNAL_ADDRESS = 127.0.0.1 | ||
24 | EXTERNAL_ADDRESS = 127.0.0.1 | ||
25 | USE_LOCALADDR = NO | ||
26 | |||
27 | |||
28 | [rps] | ||
29 | START_ON_DEMAND = NO | ||
30 | IMMEDIATE_START = NO | ||
diff --git a/src/service/testing/test_testing_start_with_config.c b/src/service/testing/test_testing_start_with_config.c deleted file mode 100644 index a2c692dbc..000000000 --- a/src/service/testing/test_testing_start_with_config.c +++ /dev/null | |||
@@ -1,121 +0,0 @@ | |||
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 transport/test_transport_start_with_config.c | ||
23 | * @brief Generic program to start testcases in an configurable topology. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_testing_ng_lib.h" | ||
28 | #include "gnunet_testing_netjail_lib.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | |||
31 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600) | ||
32 | |||
33 | |||
34 | int | ||
35 | main (int argc, | ||
36 | char *const *argv) | ||
37 | { | ||
38 | char *topology_data; | ||
39 | char *topology_data_script; | ||
40 | struct GNUNET_TESTING_NetjailTopology *topology; | ||
41 | unsigned int read_file = GNUNET_YES; | ||
42 | int ret; | ||
43 | char *rest = NULL; | ||
44 | char *token; | ||
45 | size_t single_line_len; | ||
46 | size_t data_len; | ||
47 | |||
48 | GNUNET_log_setup ("test-netjail", | ||
49 | "INFO", | ||
50 | NULL); | ||
51 | |||
52 | if (0 == strcmp ("-s", argv[1])) | ||
53 | { | ||
54 | data_len = strlen (argv[2]); | ||
55 | topology_data = GNUNET_malloc (data_len); | ||
56 | topology_data_script = GNUNET_malloc (data_len); | ||
57 | token = strtok_r (argv[2], "\n", &rest); | ||
58 | while (NULL != token) | ||
59 | { | ||
60 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
61 | "token1 %s\n", | ||
62 | token); | ||
63 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
64 | "token2 %s\n", | ||
65 | token); | ||
66 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
67 | "topology_data %s\n", | ||
68 | topology_data); | ||
69 | strcat (topology_data_script, token); | ||
70 | strcat (topology_data_script, " "); | ||
71 | strcat (topology_data, token); | ||
72 | strcat (topology_data, "\n"); | ||
73 | token = strtok_r (NULL, "\n", &rest); | ||
74 | } | ||
75 | single_line_len = strlen (topology_data); | ||
76 | topology_data_script [single_line_len - 1] = '\0'; | ||
77 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
78 | "read from string\n"); | ||
79 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
80 | "topology_data %s\n", | ||
81 | topology_data); | ||
82 | read_file = GNUNET_NO; | ||
83 | topology = GNUNET_TESTING_get_topo_from_string (topology_data); | ||
84 | } | ||
85 | else | ||
86 | { | ||
87 | topology_data = argv[1]; | ||
88 | topology_data_script = argv[1]; | ||
89 | topology = GNUNET_TESTING_get_topo_from_file (topology_data); | ||
90 | } | ||
91 | |||
92 | struct GNUNET_TESTING_Command commands[] = { | ||
93 | GNUNET_TESTING_cmd_netjail_start ("netjail-start", | ||
94 | topology_data_script, | ||
95 | &read_file), | ||
96 | GNUNET_TESTING_cmd_netjail_start_cmds_helper ("netjail-start-testbed", | ||
97 | topology, | ||
98 | &read_file, | ||
99 | topology_data_script, | ||
100 | TIMEOUT), | ||
101 | GNUNET_TESTING_cmd_stop_cmds_helper ("stop-testbed", | ||
102 | "netjail-start-testbed", | ||
103 | topology), | ||
104 | GNUNET_TESTING_cmd_netjail_stop ("netjail-stop", | ||
105 | topology_data_script, | ||
106 | &read_file), | ||
107 | GNUNET_TESTING_cmd_end () | ||
108 | }; | ||
109 | |||
110 | ret = GNUNET_TESTING_main (commands, | ||
111 | TIMEOUT); | ||
112 | |||
113 | if (0 == strcmp ("-s", argv[1])) | ||
114 | { | ||
115 | GNUNET_free (topology_data_script); | ||
116 | GNUNET_free (topology_data); | ||
117 | } | ||
118 | GNUNET_TESTING_free_topology (topology); | ||
119 | |||
120 | return ret; | ||
121 | } | ||
diff --git a/src/service/testing/testing.c b/src/service/testing/testing.c deleted file mode 100644 index fdfa80d87..000000000 --- a/src/service/testing/testing.c +++ /dev/null | |||
@@ -1,2830 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2008, 2009, 2012 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.c | ||
23 | * @brief convenience API for writing testcases for GNUnet | ||
24 | * Many testcases need to start and stop a peer/service | ||
25 | * and this library is supposed to make that easier | ||
26 | * for TESTCASES. Normal programs should always | ||
27 | * use functions from gnunet_{util,arm}_lib.h. This API is | ||
28 | * ONLY for writing testcases (or internal use of the testbed). | ||
29 | * @author Christian Grothoff | ||
30 | * | ||
31 | */ | ||
32 | #include "platform.h" | ||
33 | #include "gnunet_util_lib.h" | ||
34 | #include "gnunet_arm_service.h" | ||
35 | #include "gnunet_testing_lib.h" | ||
36 | #include "gnunet_testing_ng_lib.h" | ||
37 | #include "gnunet_testing_plugin.h" | ||
38 | #include "gnunet_testing_barrier.h" | ||
39 | #include "gnunet_testing_netjail_lib.h" | ||
40 | #include "testing_cmds.h" | ||
41 | |||
42 | #define LOG(kind, ...) GNUNET_log_from (kind, "testing-api", __VA_ARGS__) | ||
43 | |||
44 | #define CONNECT_ADDRESS_TEMPLATE "%s-192.168.15.%u" | ||
45 | |||
46 | #define ROUTER_CONNECT_ADDRESS_TEMPLATE "%s-92.68.150.%u" | ||
47 | |||
48 | #define KNOWN_CONNECT_ADDRESS_TEMPLATE "%s-92.68.151.%u" | ||
49 | |||
50 | /* Use the IP addresses below instead of the public ones, | ||
51 | * if the start script was not started from within a new namespace | ||
52 | * created by unshare. The UPNP test case needs public IP | ||
53 | * addresse for miniupnpd to function. | ||
54 | * FIXME We should introduce a switch indicating if public | ||
55 | * addresses should be used or not. This info has to be | ||
56 | * propagated from the start script to the c code. | ||
57 | #define ROUTER_CONNECT_ADDRESS_TEMPLATE "%s-172.16.150.%u" | ||
58 | |||
59 | #define KNOWN_CONNECT_ADDRESS_TEMPLATE "%s-172.16.151.%u" | ||
60 | */ | ||
61 | |||
62 | #define PREFIX_TCP "tcp" | ||
63 | |||
64 | #define PREFIX_UDP "udp" | ||
65 | |||
66 | #define PREFIX_TCP_NATTED "tcp_natted" | ||
67 | |||
68 | #define PREFIX_UDP_NATTED "udp_natted" | ||
69 | |||
70 | /** | ||
71 | * Lowest port used for GNUnet testing. Should be high enough to not | ||
72 | * conflict with other applications running on the hosts but be low | ||
73 | * enough to not conflict with client-ports (typically starting around | ||
74 | * 32k). | ||
75 | */ | ||
76 | #define LOW_PORT 12000 | ||
77 | |||
78 | /** | ||
79 | * Highest port used for GNUnet testing. Should be low enough to not | ||
80 | * conflict with the port range for "local" ports (client apps; see | ||
81 | * /proc/sys/net/ipv4/ip_local_port_range on Linux for example). | ||
82 | */ | ||
83 | #define HIGH_PORT 56000 | ||
84 | |||
85 | |||
86 | struct SharedServiceInstance | ||
87 | { | ||
88 | struct SharedService *ss; | ||
89 | |||
90 | char *cfg_fn; | ||
91 | |||
92 | struct GNUNET_OS_Process *proc; | ||
93 | |||
94 | char *unix_sock; | ||
95 | |||
96 | char *port_str; | ||
97 | |||
98 | unsigned int n_refs; | ||
99 | }; | ||
100 | |||
101 | struct SharedService | ||
102 | { | ||
103 | char *sname; | ||
104 | |||
105 | struct SharedServiceInstance **instances; | ||
106 | |||
107 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
108 | |||
109 | unsigned int n_peers; | ||
110 | |||
111 | unsigned int share; | ||
112 | |||
113 | unsigned int n_instances; | ||
114 | }; | ||
115 | |||
116 | |||
117 | /** | ||
118 | * Handle for a system on which GNUnet peers are executed; | ||
119 | * a system is used for reserving unique paths and ports. | ||
120 | */ | ||
121 | struct GNUNET_TESTING_System | ||
122 | { | ||
123 | /** | ||
124 | * Prefix (e.g. "/tmp/gnunet-testing/") we prepend to each | ||
125 | * GNUNET_HOME. | ||
126 | */ | ||
127 | char *tmppath; | ||
128 | |||
129 | /** | ||
130 | * The trusted ip. Can either be a single ip address or a network address in | ||
131 | * CIDR notation. | ||
132 | */ | ||
133 | char *trusted_ip; | ||
134 | |||
135 | /** | ||
136 | * our hostname | ||
137 | */ | ||
138 | char *hostname; | ||
139 | |||
140 | /** | ||
141 | * Hostkeys data, contains "GNUNET_TESTING_HOSTKEYFILESIZE * total_hostkeys" bytes. | ||
142 | */ | ||
143 | char *hostkeys_data; | ||
144 | |||
145 | /** | ||
146 | * memory map for @e hostkeys_data. | ||
147 | */ | ||
148 | struct GNUNET_DISK_MapHandle *map; | ||
149 | |||
150 | struct SharedService *shared_services; | ||
151 | |||
152 | unsigned int n_shared_services; | ||
153 | |||
154 | /** | ||
155 | * Bitmap where each port that has already been reserved for some GNUnet peer | ||
156 | * is recorded. Note that we make no distinction between TCP and UDP ports | ||
157 | * and test if a port is already in use before assigning it to a peer/service. | ||
158 | * If we detect that a port is already in use, we also mark it in this bitmap. | ||
159 | * So all the bits that are zero merely indicate ports that MIGHT be available | ||
160 | * for peers. | ||
161 | */ | ||
162 | uint32_t reserved_ports[65536 / 32]; | ||
163 | |||
164 | /** | ||
165 | * Counter we use to make service home paths unique on this system; | ||
166 | * the full path consists of the tmppath and this number. Each | ||
167 | * UNIXPATH for a peer is also modified to include the respective | ||
168 | * path counter to ensure uniqueness. This field is incremented | ||
169 | * by one for each configured peer. Even if peers are destroyed, | ||
170 | * we never re-use path counters. | ||
171 | */ | ||
172 | uint32_t path_counter; | ||
173 | |||
174 | /** | ||
175 | * The number of hostkeys | ||
176 | */ | ||
177 | uint32_t total_hostkeys; | ||
178 | |||
179 | /** | ||
180 | * Lowest port we are allowed to use. | ||
181 | */ | ||
182 | uint16_t lowport; | ||
183 | |||
184 | /** | ||
185 | * Highest port we are allowed to use. | ||
186 | */ | ||
187 | uint16_t highport; | ||
188 | }; | ||
189 | |||
190 | |||
191 | /** | ||
192 | * Handle for a GNUnet peer controlled by testing. | ||
193 | */ | ||
194 | struct GNUNET_TESTING_Peer | ||
195 | { | ||
196 | /** | ||
197 | * The TESTING system associated with this peer | ||
198 | */ | ||
199 | struct GNUNET_TESTING_System *system; | ||
200 | |||
201 | /** | ||
202 | * Path to the configuration file for this peer. | ||
203 | */ | ||
204 | char *cfgfile; | ||
205 | |||
206 | /** | ||
207 | * Binary to be executed during 'GNUNET_TESTING_peer_start'. | ||
208 | * Typically 'gnunet-service-arm' (but can be set to a | ||
209 | * specific service by 'GNUNET_TESTING_service_run' if | ||
210 | * necessary). | ||
211 | */ | ||
212 | char *main_binary; | ||
213 | char *args; | ||
214 | |||
215 | /** | ||
216 | * Handle to the running binary of the service, NULL if the | ||
217 | * peer/service is currently not running. | ||
218 | */ | ||
219 | struct GNUNET_OS_Process *main_process; | ||
220 | |||
221 | /** | ||
222 | * The handle to the peer's ARM service | ||
223 | */ | ||
224 | struct GNUNET_ARM_Handle *ah; | ||
225 | |||
226 | /** | ||
227 | * The config of the peer | ||
228 | */ | ||
229 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
230 | |||
231 | /** | ||
232 | * The callback to call asynchronously when a peer is stopped | ||
233 | */ | ||
234 | GNUNET_TESTING_PeerStopCallback cb; | ||
235 | |||
236 | /** | ||
237 | * The closure for the above callback | ||
238 | */ | ||
239 | void *cb_cls; | ||
240 | |||
241 | /** | ||
242 | * The cached identity of this peer. Will be populated on call to | ||
243 | * GNUNET_TESTING_peer_get_identity() | ||
244 | */ | ||
245 | struct GNUNET_PeerIdentity *id; | ||
246 | |||
247 | struct SharedServiceInstance **ss_instances; | ||
248 | |||
249 | /** | ||
250 | * Array of ports currently allocated to this peer. These ports will be | ||
251 | * released upon peer destroy and can be used by other peers which are | ||
252 | * configured after. | ||
253 | */ | ||
254 | uint16_t *ports; | ||
255 | |||
256 | /** | ||
257 | * The number of ports in the above array | ||
258 | */ | ||
259 | unsigned int nports; | ||
260 | |||
261 | /** | ||
262 | * The keynumber of this peer's hostkey | ||
263 | */ | ||
264 | uint32_t key_number; | ||
265 | }; | ||
266 | |||
267 | |||
268 | /** | ||
269 | * Testing includes a number of pre-created hostkeys for faster peer | ||
270 | * startup. This function loads such keys into memory from a file. | ||
271 | * | ||
272 | * @param system the testing system handle | ||
273 | * @return #GNUNET_OK on success; #GNUNET_SYSERR on error | ||
274 | */ | ||
275 | static enum GNUNET_GenericReturnValue | ||
276 | hostkeys_load (struct GNUNET_TESTING_System *system) | ||
277 | { | ||
278 | uint64_t fs; | ||
279 | char *data_dir; | ||
280 | char *filename; | ||
281 | struct GNUNET_DISK_FileHandle *fd; | ||
282 | |||
283 | GNUNET_assert (NULL == system->hostkeys_data); | ||
284 | data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); | ||
285 | GNUNET_asprintf (&filename, "%s/testing_hostkeys.ecc", data_dir); | ||
286 | GNUNET_free (data_dir); | ||
287 | |||
288 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
289 | { | ||
290 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
291 | _ ("Hostkeys file not found: %s\n"), | ||
292 | filename); | ||
293 | GNUNET_free (filename); | ||
294 | return GNUNET_SYSERR; | ||
295 | } | ||
296 | /* Check hostkey file size, read entire thing into memory */ | ||
297 | if (GNUNET_OK != | ||
298 | GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) | ||
299 | fs = 0; | ||
300 | if (0 == fs) | ||
301 | { | ||
302 | GNUNET_free (filename); | ||
303 | return GNUNET_SYSERR; /* File is empty */ | ||
304 | } | ||
305 | if (0 != (fs % GNUNET_TESTING_HOSTKEYFILESIZE)) | ||
306 | { | ||
307 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
308 | _ ("Incorrect hostkey file format: %s\n"), | ||
309 | filename); | ||
310 | GNUNET_free (filename); | ||
311 | return GNUNET_SYSERR; | ||
312 | } | ||
313 | fd = GNUNET_DISK_file_open (filename, | ||
314 | GNUNET_DISK_OPEN_READ, | ||
315 | GNUNET_DISK_PERM_NONE); | ||
316 | if (NULL == fd) | ||
317 | { | ||
318 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", filename); | ||
319 | GNUNET_free (filename); | ||
320 | return GNUNET_SYSERR; | ||
321 | } | ||
322 | GNUNET_free (filename); | ||
323 | system->hostkeys_data = | ||
324 | GNUNET_DISK_file_map (fd, &system->map, GNUNET_DISK_MAP_TYPE_READ, fs); | ||
325 | GNUNET_DISK_file_close (fd); | ||
326 | if (NULL == system->hostkeys_data) | ||
327 | return GNUNET_SYSERR; | ||
328 | system->total_hostkeys = fs / GNUNET_TESTING_HOSTKEYFILESIZE; | ||
329 | return GNUNET_OK; | ||
330 | } | ||
331 | |||
332 | |||
333 | /** | ||
334 | * Function to remove the loaded hostkeys | ||
335 | * | ||
336 | * @param system the testing system handle | ||
337 | */ | ||
338 | static void | ||
339 | hostkeys_unload (struct GNUNET_TESTING_System *system) | ||
340 | { | ||
341 | GNUNET_break (NULL != system->hostkeys_data); | ||
342 | system->hostkeys_data = NULL; | ||
343 | GNUNET_DISK_file_unmap (system->map); | ||
344 | system->map = NULL; | ||
345 | system->hostkeys_data = NULL; | ||
346 | system->total_hostkeys = 0; | ||
347 | } | ||
348 | |||
349 | |||
350 | /** | ||
351 | * Function to iterate over options. | ||
352 | * | ||
353 | * @param cls closure | ||
354 | * @param section name of the section | ||
355 | * @param option name of the option | ||
356 | * @param value value of the option | ||
357 | */ | ||
358 | static void | ||
359 | cfg_copy_iterator (void *cls, | ||
360 | const char *section, | ||
361 | const char *option, | ||
362 | const char *value) | ||
363 | { | ||
364 | struct GNUNET_CONFIGURATION_Handle *cfg2 = cls; | ||
365 | |||
366 | GNUNET_CONFIGURATION_set_value_string (cfg2, section, option, value); | ||
367 | } | ||
368 | |||
369 | |||
370 | /** | ||
371 | * Create a system handle. There must only be one system | ||
372 | * handle per operating system. | ||
373 | * | ||
374 | * @param testdir only the directory name without any path. This is used for | ||
375 | * all service homes; the directory will be created in a temporary | ||
376 | * location depending on the underlying OS. This variable will be | ||
377 | * overridden with the value of the environmental variable | ||
378 | * GNUNET_TESTING_PREFIX, if it exists. | ||
379 | * @param trusted_ip the ip address which will be set as TRUSTED HOST in all | ||
380 | * service configurations generated to allow control connections from | ||
381 | * this ip. This can either be a single ip address or a network address | ||
382 | * in CIDR notation. | ||
383 | * @param hostname the hostname of the system we are using for testing; NULL for | ||
384 | * localhost | ||
385 | * @param shared_services NULL terminated array describing services that are to | ||
386 | * be shared among peers | ||
387 | * @param lowport lowest port number this system is allowed to allocate (inclusive) | ||
388 | * @param highport highest port number this system is allowed to allocate (exclusive) | ||
389 | * @return handle to this system, NULL on error | ||
390 | */ | ||
391 | struct GNUNET_TESTING_System * | ||
392 | GNUNET_TESTING_system_create_with_portrange ( | ||
393 | const char *testdir, | ||
394 | const char *trusted_ip, | ||
395 | const char *hostname, | ||
396 | const struct GNUNET_TESTING_SharedService *shared_services, | ||
397 | uint16_t lowport, | ||
398 | uint16_t highport) | ||
399 | { | ||
400 | struct GNUNET_TESTING_System *system; | ||
401 | struct GNUNET_TESTING_SharedService tss; | ||
402 | struct SharedService ss; | ||
403 | unsigned int cnt; | ||
404 | |||
405 | GNUNET_assert (NULL != testdir); | ||
406 | system = GNUNET_new (struct GNUNET_TESTING_System); | ||
407 | if (NULL == (system->tmppath = getenv (GNUNET_TESTING_PREFIX))) | ||
408 | system->tmppath = GNUNET_DISK_mkdtemp (testdir); | ||
409 | else | ||
410 | system->tmppath = GNUNET_strdup (system->tmppath); | ||
411 | system->lowport = lowport; | ||
412 | system->highport = highport; | ||
413 | if (NULL == system->tmppath) | ||
414 | { | ||
415 | GNUNET_free (system); | ||
416 | return NULL; | ||
417 | } | ||
418 | if (NULL != trusted_ip) | ||
419 | system->trusted_ip = GNUNET_strdup (trusted_ip); | ||
420 | if (NULL != hostname) | ||
421 | system->hostname = GNUNET_strdup (hostname); | ||
422 | if (GNUNET_OK != hostkeys_load (system)) | ||
423 | { | ||
424 | GNUNET_TESTING_system_destroy (system, GNUNET_YES); | ||
425 | return NULL; | ||
426 | } | ||
427 | if (NULL == shared_services) | ||
428 | return system; | ||
429 | for (cnt = 0; NULL != shared_services[cnt].service; cnt++) | ||
430 | { | ||
431 | tss = shared_services[cnt]; | ||
432 | memset (&ss, 0, sizeof (ss)); | ||
433 | ss.sname = GNUNET_strdup (tss.service); | ||
434 | ss.cfg = GNUNET_CONFIGURATION_create (); | ||
435 | GNUNET_CONFIGURATION_iterate_section_values (tss.cfg, | ||
436 | ss.sname, | ||
437 | &cfg_copy_iterator, | ||
438 | ss.cfg); | ||
439 | GNUNET_CONFIGURATION_iterate_section_values (tss.cfg, | ||
440 | "TESTING", | ||
441 | &cfg_copy_iterator, | ||
442 | ss.cfg); | ||
443 | GNUNET_CONFIGURATION_iterate_section_values (tss.cfg, | ||
444 | "PATHS", | ||
445 | &cfg_copy_iterator, | ||
446 | ss.cfg); | ||
447 | ss.share = tss.share; | ||
448 | GNUNET_array_append (system->shared_services, | ||
449 | system->n_shared_services, | ||
450 | ss); | ||
451 | } | ||
452 | return system; | ||
453 | } | ||
454 | |||
455 | |||
456 | /** | ||
457 | * Create a system handle. There must only be one system handle per operating | ||
458 | * system. Uses a default range for allowed ports. Ports are still tested for | ||
459 | * availability. | ||
460 | * | ||
461 | * @param testdir only the directory name without any path. This is used for all | ||
462 | * service homes; the directory will be created in a temporary location | ||
463 | * depending on the underlying OS. This variable will be | ||
464 | * overridden with the value of the environmental variable | ||
465 | * GNUNET_TESTING_PREFIX, if it exists. | ||
466 | * @param trusted_ip the ip address which will be set as TRUSTED HOST in all | ||
467 | * service configurations generated to allow control connections from | ||
468 | * this ip. This can either be a single ip address or a network address | ||
469 | * in CIDR notation. | ||
470 | * @param hostname the hostname of the system we are using for testing; NULL for | ||
471 | * localhost | ||
472 | * @param shared_services NULL terminated array describing services that are to | ||
473 | * be shared among peers | ||
474 | * @return handle to this system, NULL on error | ||
475 | */ | ||
476 | struct GNUNET_TESTING_System * | ||
477 | GNUNET_TESTING_system_create ( | ||
478 | const char *testdir, | ||
479 | const char *trusted_ip, | ||
480 | const char *hostname, | ||
481 | const struct GNUNET_TESTING_SharedService *shared_services) | ||
482 | { | ||
483 | return GNUNET_TESTING_system_create_with_portrange (testdir, | ||
484 | trusted_ip, | ||
485 | hostname, | ||
486 | shared_services, | ||
487 | LOW_PORT, | ||
488 | HIGH_PORT); | ||
489 | } | ||
490 | |||
491 | |||
492 | static void | ||
493 | cleanup_shared_service_instance (struct SharedServiceInstance *i) | ||
494 | { | ||
495 | if (NULL != i->cfg_fn) | ||
496 | { | ||
497 | (void) unlink (i->cfg_fn); | ||
498 | GNUNET_free (i->cfg_fn); | ||
499 | } | ||
500 | GNUNET_free (i->unix_sock); | ||
501 | GNUNET_free (i->port_str); | ||
502 | GNUNET_break (NULL == i->proc); | ||
503 | GNUNET_break (0 == i->n_refs); | ||
504 | GNUNET_free (i); | ||
505 | } | ||
506 | |||
507 | |||
508 | static enum GNUNET_GenericReturnValue | ||
509 | start_shared_service_instance (struct SharedServiceInstance *i) | ||
510 | { | ||
511 | char *binary; | ||
512 | char *libexec_binary; | ||
513 | |||
514 | GNUNET_assert (NULL == i->proc); | ||
515 | GNUNET_assert (NULL != i->cfg_fn); | ||
516 | (void) GNUNET_asprintf (&binary, "gnunet-service-%s", i->ss->sname); | ||
517 | libexec_binary = GNUNET_OS_get_libexec_binary_path (binary); | ||
518 | GNUNET_free (binary); | ||
519 | i->proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | ||
520 | NULL, | ||
521 | NULL, | ||
522 | NULL, | ||
523 | libexec_binary, | ||
524 | libexec_binary, | ||
525 | "-c", | ||
526 | i->cfg_fn, | ||
527 | NULL); | ||
528 | GNUNET_free (libexec_binary); | ||
529 | if (NULL == i->proc) | ||
530 | return GNUNET_SYSERR; | ||
531 | return GNUNET_OK; | ||
532 | } | ||
533 | |||
534 | |||
535 | static void | ||
536 | stop_shared_service_instance (struct SharedServiceInstance *i) | ||
537 | { | ||
538 | GNUNET_break (0 == i->n_refs); | ||
539 | if (0 != GNUNET_OS_process_kill (i->proc, GNUNET_TERM_SIG)) | ||
540 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
541 | "Killing shared service instance (%s) failed\n", | ||
542 | i->ss->sname); | ||
543 | (void) GNUNET_OS_process_wait (i->proc); | ||
544 | GNUNET_OS_process_destroy (i->proc); | ||
545 | i->proc = NULL; | ||
546 | } | ||
547 | |||
548 | |||
549 | /** | ||
550 | * Free system resources. | ||
551 | * | ||
552 | * @param system system to be freed | ||
553 | * @param remove_paths should the 'testdir' and all subdirectories | ||
554 | * be removed (clean up on shutdown)? | ||
555 | */ | ||
556 | void | ||
557 | GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system, | ||
558 | int remove_paths) | ||
559 | { | ||
560 | struct SharedService *ss; | ||
561 | struct SharedServiceInstance *i; | ||
562 | unsigned int ss_cnt; | ||
563 | unsigned int i_cnt; | ||
564 | |||
565 | if (NULL != system->hostkeys_data) | ||
566 | hostkeys_unload (system); | ||
567 | for (ss_cnt = 0; ss_cnt < system->n_shared_services; ss_cnt++) | ||
568 | { | ||
569 | ss = &system->shared_services[ss_cnt]; | ||
570 | for (i_cnt = 0; i_cnt < ss->n_instances; i_cnt++) | ||
571 | { | ||
572 | i = ss->instances[i_cnt]; | ||
573 | if (NULL != i->proc) | ||
574 | stop_shared_service_instance (i); | ||
575 | cleanup_shared_service_instance (i); | ||
576 | } | ||
577 | GNUNET_free (ss->instances); | ||
578 | GNUNET_CONFIGURATION_destroy (ss->cfg); | ||
579 | GNUNET_free (ss->sname); | ||
580 | } | ||
581 | GNUNET_free (system->shared_services); | ||
582 | if (GNUNET_YES == remove_paths) | ||
583 | GNUNET_DISK_directory_remove (system->tmppath); | ||
584 | GNUNET_free (system->tmppath); | ||
585 | GNUNET_free (system->trusted_ip); | ||
586 | GNUNET_free (system->hostname); | ||
587 | GNUNET_free (system); | ||
588 | } | ||
589 | |||
590 | |||
591 | /** | ||
592 | * Reserve a TCP or UDP port for a peer. | ||
593 | * | ||
594 | * @param system system to use for reservation tracking | ||
595 | * @return 0 if no free port was available | ||
596 | */ | ||
597 | uint16_t | ||
598 | GNUNET_TESTING_reserve_port (struct GNUNET_TESTING_System *system) | ||
599 | { | ||
600 | struct GNUNET_NETWORK_Handle *socket; | ||
601 | struct addrinfo hint; | ||
602 | struct addrinfo *ret; | ||
603 | struct addrinfo *ai; | ||
604 | uint32_t *port_buckets; | ||
605 | char *open_port_str; | ||
606 | int bind_status; | ||
607 | uint32_t xor_image; | ||
608 | uint16_t index; | ||
609 | uint16_t open_port; | ||
610 | uint16_t pos; | ||
611 | |||
612 | /* | ||
613 | FIXME: Instead of using getaddrinfo we should try to determine the port | ||
614 | status by the following heurestics. | ||
615 | |||
616 | On systems which support both IPv4 and IPv6, only ports open on both | ||
617 | address families are considered open. | ||
618 | On system with either IPv4 or IPv6. A port is considered open if it's | ||
619 | open in the respective address family | ||
620 | */hint.ai_family = AF_UNSPEC; /* IPv4 and IPv6 */ | ||
621 | hint.ai_socktype = 0; | ||
622 | hint.ai_protocol = 0; | ||
623 | hint.ai_addrlen = 0; | ||
624 | hint.ai_addr = NULL; | ||
625 | hint.ai_canonname = NULL; | ||
626 | hint.ai_next = NULL; | ||
627 | hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* Wild card address */ | ||
628 | port_buckets = system->reserved_ports; | ||
629 | for (index = (system->lowport / 32) + 1; index < (system->highport / 32); | ||
630 | index++) | ||
631 | { | ||
632 | xor_image = (UINT32_MAX ^ port_buckets[index]); | ||
633 | if (0 == xor_image) /* Ports in the bucket are full */ | ||
634 | continue; | ||
635 | pos = system->lowport % 32; | ||
636 | while (pos < 32) | ||
637 | { | ||
638 | if (0 == ((xor_image >> pos) & 1U)) | ||
639 | { | ||
640 | pos++; | ||
641 | continue; | ||
642 | } | ||
643 | open_port = (index * 32) + pos; | ||
644 | if (open_port >= system->highport) | ||
645 | return 0; | ||
646 | GNUNET_asprintf (&open_port_str, "%u", (unsigned int) open_port); | ||
647 | ret = NULL; | ||
648 | GNUNET_assert (0 == getaddrinfo (NULL, open_port_str, &hint, &ret)); | ||
649 | GNUNET_free (open_port_str); | ||
650 | bind_status = GNUNET_NO; | ||
651 | for (ai = ret; NULL != ai; ai = ai->ai_next) | ||
652 | { | ||
653 | socket = GNUNET_NETWORK_socket_create (ai->ai_family, SOCK_STREAM, 0); | ||
654 | if (NULL == socket) | ||
655 | continue; | ||
656 | bind_status = | ||
657 | GNUNET_NETWORK_socket_bind (socket, ai->ai_addr, ai->ai_addrlen); | ||
658 | GNUNET_NETWORK_socket_close (socket); | ||
659 | if (GNUNET_OK != bind_status) | ||
660 | break; | ||
661 | socket = GNUNET_NETWORK_socket_create (ai->ai_family, SOCK_DGRAM, 0); | ||
662 | if (NULL == socket) | ||
663 | continue; | ||
664 | bind_status = | ||
665 | GNUNET_NETWORK_socket_bind (socket, ai->ai_addr, ai->ai_addrlen); | ||
666 | GNUNET_NETWORK_socket_close (socket); | ||
667 | if (GNUNET_OK != bind_status) | ||
668 | break; | ||
669 | } | ||
670 | port_buckets[index] |= (1U << pos); /* Set the port bit */ | ||
671 | freeaddrinfo (ret); | ||
672 | if (GNUNET_OK == bind_status) | ||
673 | { | ||
674 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
675 | "Found a free port %u\n", | ||
676 | (unsigned int) open_port); | ||
677 | return open_port; | ||
678 | } | ||
679 | pos++; | ||
680 | } | ||
681 | } | ||
682 | return 0; | ||
683 | } | ||
684 | |||
685 | |||
686 | /** | ||
687 | * Release reservation of a TCP or UDP port for a peer | ||
688 | * (used during #GNUNET_TESTING_peer_destroy()). | ||
689 | * | ||
690 | * @param system system to use for reservation tracking | ||
691 | * @param port reserved port to release | ||
692 | */ | ||
693 | void | ||
694 | GNUNET_TESTING_release_port (struct GNUNET_TESTING_System *system, | ||
695 | uint16_t port) | ||
696 | { | ||
697 | uint32_t *port_buckets; | ||
698 | uint16_t bucket; | ||
699 | uint16_t pos; | ||
700 | |||
701 | port_buckets = system->reserved_ports; | ||
702 | bucket = port / 32; | ||
703 | pos = port % 32; | ||
704 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Releasing port %u\n", port); | ||
705 | if (0 == (port_buckets[bucket] & (1U << pos))) | ||
706 | { | ||
707 | GNUNET_break (0); /* Port was not reserved by us using reserve_port() */ | ||
708 | return; | ||
709 | } | ||
710 | port_buckets[bucket] &= ~(1U << pos); | ||
711 | } | ||
712 | |||
713 | |||
714 | /** | ||
715 | * Testing includes a number of pre-created hostkeys for | ||
716 | * faster peer startup. This function can be used to | ||
717 | * access the n-th key of those pre-created hostkeys; note | ||
718 | * that these keys are ONLY useful for testing and not | ||
719 | * secure as the private keys are part of the public | ||
720 | * GNUnet source code. | ||
721 | * | ||
722 | * This is primarily a helper function used internally | ||
723 | * by #GNUNET_TESTING_peer_configure. | ||
724 | * | ||
725 | * @param system the testing system handle | ||
726 | * @param key_number desired pre-created hostkey to obtain | ||
727 | * @param id set to the peer's identity (hash of the public | ||
728 | * key; if NULL, NULL is returned immediately | ||
729 | * @return NULL on error (not enough keys) | ||
730 | */ | ||
731 | struct GNUNET_CRYPTO_EddsaPrivateKey * | ||
732 | GNUNET_TESTING_hostkey_get (const struct GNUNET_TESTING_System *system, | ||
733 | uint32_t key_number, | ||
734 | struct GNUNET_PeerIdentity *id) | ||
735 | { | ||
736 | struct GNUNET_CRYPTO_EddsaPrivateKey *private_key; | ||
737 | |||
738 | if ((NULL == id) || (NULL == system->hostkeys_data)) | ||
739 | return NULL; | ||
740 | if (key_number >= system->total_hostkeys) | ||
741 | { | ||
742 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
743 | _ ("Key number %u does not exist\n"), | ||
744 | key_number); | ||
745 | return NULL; | ||
746 | } | ||
747 | private_key = GNUNET_new (struct GNUNET_CRYPTO_EddsaPrivateKey); | ||
748 | GNUNET_memcpy (private_key, | ||
749 | system->hostkeys_data | ||
750 | + (key_number * GNUNET_TESTING_HOSTKEYFILESIZE), | ||
751 | GNUNET_TESTING_HOSTKEYFILESIZE); | ||
752 | GNUNET_CRYPTO_eddsa_key_get_public (private_key, &id->public_key); | ||
753 | return private_key; | ||
754 | } | ||
755 | |||
756 | |||
757 | /** | ||
758 | * Structure for holding data to build new configurations from a configuration | ||
759 | * template | ||
760 | */ | ||
761 | struct UpdateContext | ||
762 | { | ||
763 | /** | ||
764 | * The system for which we are building configurations | ||
765 | */ | ||
766 | struct GNUNET_TESTING_System *system; | ||
767 | |||
768 | /** | ||
769 | * The configuration we are building | ||
770 | */ | ||
771 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
772 | |||
773 | /** | ||
774 | * The customized service home path for this peer | ||
775 | */ | ||
776 | char *gnunet_home; | ||
777 | |||
778 | /** | ||
779 | * Array of ports currently allocated to this peer. These ports will be | ||
780 | * released upon peer destroy and can be used by other peers which are | ||
781 | * configured after. | ||
782 | */ | ||
783 | uint16_t *ports; | ||
784 | |||
785 | /** | ||
786 | * The number of ports in the above array | ||
787 | */ | ||
788 | unsigned int nports; | ||
789 | |||
790 | /** | ||
791 | * build status - to signal error while building a configuration | ||
792 | */ | ||
793 | int status; | ||
794 | }; | ||
795 | |||
796 | |||
797 | /** | ||
798 | * Function to iterate over options. Copies | ||
799 | * the options to the target configuration, | ||
800 | * updating PORT values as needed. | ||
801 | * | ||
802 | * @param cls the UpdateContext | ||
803 | * @param section name of the section | ||
804 | * @param option name of the option | ||
805 | * @param value value of the option | ||
806 | */ | ||
807 | static void | ||
808 | update_config (void *cls, | ||
809 | const char *section, | ||
810 | const char *option, | ||
811 | const char *value) | ||
812 | { | ||
813 | struct UpdateContext *uc = cls; | ||
814 | unsigned int ival; | ||
815 | char cval[12]; | ||
816 | char uval[PATH_MAX]; | ||
817 | char *single_variable; | ||
818 | char *per_host_variable; | ||
819 | unsigned long long num_per_host; | ||
820 | uint16_t new_port; | ||
821 | |||
822 | if (GNUNET_OK != uc->status) | ||
823 | return; | ||
824 | if (! ((0 == strcmp (option, "PORT")) || (0 == strcmp (option, "UNIXPATH")) || | ||
825 | (0 == strcmp (option, "HOSTNAME")))) | ||
826 | return; | ||
827 | GNUNET_asprintf (&single_variable, "single_%s_per_host", section); | ||
828 | GNUNET_asprintf (&per_host_variable, "num_%s_per_host", section); | ||
829 | if ((0 == strcmp (option, "PORT")) && (1 == sscanf (value, "%u", &ival))) | ||
830 | { | ||
831 | if ((ival != 0) && | ||
832 | (GNUNET_YES != GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, | ||
833 | "testing", | ||
834 | single_variable))) | ||
835 | { | ||
836 | new_port = GNUNET_TESTING_reserve_port (uc->system); | ||
837 | if (0 == new_port) | ||
838 | { | ||
839 | uc->status = GNUNET_SYSERR; | ||
840 | GNUNET_free (single_variable); | ||
841 | GNUNET_free (per_host_variable); | ||
842 | return; | ||
843 | } | ||
844 | GNUNET_snprintf (cval, sizeof(cval), "%u", new_port); | ||
845 | value = cval; | ||
846 | GNUNET_array_append (uc->ports, uc->nports, new_port); | ||
847 | } | ||
848 | else if ((ival != 0) && | ||
849 | (GNUNET_YES == | ||
850 | GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, | ||
851 | "testing", | ||
852 | single_variable)) && | ||
853 | GNUNET_CONFIGURATION_get_value_number (uc->cfg, | ||
854 | "testing", | ||
855 | per_host_variable, | ||
856 | &num_per_host)) | ||
857 | { | ||
858 | /* GNUNET_snprintf (cval, sizeof (cval), "%u", */ | ||
859 | /* ival + ctx->fdnum % num_per_host); */ | ||
860 | /* value = cval; */ | ||
861 | GNUNET_break (0); /* FIXME */ | ||
862 | } | ||
863 | } | ||
864 | if (0 == strcmp (option, "UNIXPATH")) | ||
865 | { | ||
866 | if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, | ||
867 | "testing", | ||
868 | single_variable)) | ||
869 | { | ||
870 | GNUNET_snprintf (uval, | ||
871 | sizeof(uval), | ||
872 | "%s/%s.sock", | ||
873 | uc->gnunet_home, | ||
874 | section); | ||
875 | value = uval; | ||
876 | } | ||
877 | else if ((GNUNET_YES == | ||
878 | GNUNET_CONFIGURATION_get_value_number (uc->cfg, | ||
879 | "testing", | ||
880 | per_host_variable, | ||
881 | &num_per_host)) && | ||
882 | (num_per_host > 0)) | ||
883 | { | ||
884 | GNUNET_break (0); /* FIXME */ | ||
885 | } | ||
886 | } | ||
887 | if (0 == strcmp (option, "HOSTNAME")) | ||
888 | { | ||
889 | value = (NULL == uc->system->hostname) ? "localhost" : uc->system->hostname; | ||
890 | } | ||
891 | GNUNET_free (single_variable); | ||
892 | GNUNET_free (per_host_variable); | ||
893 | GNUNET_CONFIGURATION_set_value_string (uc->cfg, section, option, value); | ||
894 | } | ||
895 | |||
896 | |||
897 | /** | ||
898 | * Section iterator to set ACCEPT_FROM/ACCEPT_FROM6 to include the address of | ||
899 | * 'trusted_hosts' in all sections | ||
900 | * | ||
901 | * @param cls the UpdateContext | ||
902 | * @param section name of the section | ||
903 | */ | ||
904 | static void | ||
905 | update_config_sections (void *cls, const char *section) | ||
906 | { | ||
907 | struct UpdateContext *uc = cls; | ||
908 | char **ikeys; | ||
909 | char *val; | ||
910 | char *ptr; | ||
911 | char *orig_allowed_hosts; | ||
912 | char *allowed_hosts; | ||
913 | char *ACCEPT_FROM_key; | ||
914 | uint16_t ikeys_cnt; | ||
915 | uint16_t key; | ||
916 | |||
917 | ikeys_cnt = 0; | ||
918 | val = NULL; | ||
919 | /* Ignore certain options from sections. See | ||
920 | https://gnunet.org/bugs/view.php?id=2476 */ | ||
921 | if (GNUNET_YES == | ||
922 | GNUNET_CONFIGURATION_have_value (uc->cfg, section, "TESTING_IGNORE_KEYS")) | ||
923 | { | ||
924 | GNUNET_assert (GNUNET_YES == | ||
925 | GNUNET_CONFIGURATION_get_value_string (uc->cfg, | ||
926 | section, | ||
927 | "TESTING_IGNORE_KEYS", | ||
928 | &val)); | ||
929 | ptr = val; | ||
930 | for (ikeys_cnt = 0; NULL != (ptr = strstr (ptr, ";")); ikeys_cnt++) | ||
931 | ptr++; | ||
932 | if (0 == ikeys_cnt) | ||
933 | GNUNET_break (0); | ||
934 | else | ||
935 | { | ||
936 | ikeys = GNUNET_malloc ((sizeof(char *)) * ikeys_cnt); | ||
937 | ptr = val; | ||
938 | for (key = 0; key < ikeys_cnt; key++) | ||
939 | { | ||
940 | ikeys[key] = ptr; | ||
941 | ptr = strstr (ptr, ";"); | ||
942 | GNUNET_assert (NULL != ptr); /* worked just before... */ | ||
943 | *ptr = '\0'; | ||
944 | ptr++; | ||
945 | } | ||
946 | } | ||
947 | } | ||
948 | if (0 != ikeys_cnt) | ||
949 | { | ||
950 | for (key = 0; key < ikeys_cnt; key++) | ||
951 | { | ||
952 | if (NULL != strstr (ikeys[key], "ADVERTISED_PORT")) | ||
953 | break; | ||
954 | } | ||
955 | if ((key == ikeys_cnt) && | ||
956 | (GNUNET_YES == | ||
957 | GNUNET_CONFIGURATION_have_value (uc->cfg, section, "ADVERTISED_PORT"))) | ||
958 | { | ||
959 | if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (uc->cfg, | ||
960 | section, | ||
961 | "PORT", | ||
962 | &ptr)) | ||
963 | { | ||
964 | GNUNET_CONFIGURATION_set_value_string (uc->cfg, | ||
965 | section, | ||
966 | "ADVERTISED_PORT", | ||
967 | ptr); | ||
968 | GNUNET_free (ptr); | ||
969 | } | ||
970 | } | ||
971 | for (key = 0; key < ikeys_cnt; key++) | ||
972 | { | ||
973 | if (NULL != strstr (ikeys[key], "ACCEPT_FROM")) | ||
974 | { | ||
975 | GNUNET_free (ikeys); | ||
976 | GNUNET_free (val); | ||
977 | return; | ||
978 | } | ||
979 | } | ||
980 | GNUNET_free (ikeys); | ||
981 | } | ||
982 | GNUNET_free (val); | ||
983 | ACCEPT_FROM_key = "ACCEPT_FROM"; | ||
984 | if ((NULL != uc->system->trusted_ip) && | ||
985 | (NULL != strstr (uc->system->trusted_ip, ":"))) /* IPv6 in use */ | ||
986 | ACCEPT_FROM_key = "ACCEPT_FROM6"; | ||
987 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (uc->cfg, | ||
988 | section, | ||
989 | ACCEPT_FROM_key, | ||
990 | &orig_allowed_hosts)) | ||
991 | { | ||
992 | orig_allowed_hosts = GNUNET_strdup ("127.0.0.1;"); | ||
993 | } | ||
994 | if (NULL == uc->system->trusted_ip) | ||
995 | allowed_hosts = GNUNET_strdup (orig_allowed_hosts); | ||
996 | else | ||
997 | GNUNET_asprintf (&allowed_hosts, | ||
998 | "%s%s;", | ||
999 | orig_allowed_hosts, | ||
1000 | uc->system->trusted_ip); | ||
1001 | GNUNET_free (orig_allowed_hosts); | ||
1002 | GNUNET_CONFIGURATION_set_value_string (uc->cfg, | ||
1003 | section, | ||
1004 | ACCEPT_FROM_key, | ||
1005 | allowed_hosts); | ||
1006 | GNUNET_free (allowed_hosts); | ||
1007 | } | ||
1008 | |||
1009 | |||
1010 | static struct SharedServiceInstance * | ||
1011 | associate_shared_service (struct GNUNET_TESTING_System *system, | ||
1012 | struct SharedService *ss, | ||
1013 | struct GNUNET_CONFIGURATION_Handle *cfg) | ||
1014 | { | ||
1015 | struct SharedServiceInstance *i; | ||
1016 | struct GNUNET_CONFIGURATION_Handle *temp; | ||
1017 | char *gnunet_home; | ||
1018 | uint32_t port; | ||
1019 | |||
1020 | ss->n_peers++; | ||
1021 | if (((0 == ss->share) && (NULL == ss->instances)) || | ||
1022 | ((0 != ss->share) && | ||
1023 | (ss->n_instances < ((ss->n_peers + ss->share - 1) / ss->share)))) | ||
1024 | { | ||
1025 | i = GNUNET_new (struct SharedServiceInstance); | ||
1026 | i->ss = ss; | ||
1027 | (void) GNUNET_asprintf (&gnunet_home, | ||
1028 | "%s/shared/%s/%u", | ||
1029 | system->tmppath, | ||
1030 | ss->sname, | ||
1031 | ss->n_instances); | ||
1032 | (void) GNUNET_asprintf (&i->unix_sock, "%s/sock", gnunet_home); | ||
1033 | port = GNUNET_TESTING_reserve_port (system); | ||
1034 | if (0 == port) | ||
1035 | { | ||
1036 | GNUNET_free (gnunet_home); | ||
1037 | cleanup_shared_service_instance (i); | ||
1038 | return NULL; | ||
1039 | } | ||
1040 | GNUNET_array_append (ss->instances, ss->n_instances, i); | ||
1041 | temp = GNUNET_CONFIGURATION_dup (ss->cfg); | ||
1042 | (void) GNUNET_asprintf (&i->port_str, "%u", port); | ||
1043 | (void) GNUNET_asprintf (&i->cfg_fn, "%s/config", gnunet_home); | ||
1044 | GNUNET_CONFIGURATION_set_value_string (temp, | ||
1045 | "PATHS", | ||
1046 | "GNUNET_HOME", | ||
1047 | gnunet_home); | ||
1048 | GNUNET_free (gnunet_home); | ||
1049 | GNUNET_CONFIGURATION_set_value_string (temp, | ||
1050 | ss->sname, | ||
1051 | "UNIXPATH", | ||
1052 | i->unix_sock); | ||
1053 | GNUNET_CONFIGURATION_set_value_string (temp, | ||
1054 | ss->sname, | ||
1055 | "PORT", | ||
1056 | i->port_str); | ||
1057 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_write (temp, i->cfg_fn)) | ||
1058 | { | ||
1059 | GNUNET_CONFIGURATION_destroy (temp); | ||
1060 | cleanup_shared_service_instance (i); | ||
1061 | return NULL; | ||
1062 | } | ||
1063 | GNUNET_CONFIGURATION_destroy (temp); | ||
1064 | } | ||
1065 | else | ||
1066 | { | ||
1067 | GNUNET_assert (NULL != ss->instances); | ||
1068 | GNUNET_assert (0 < ss->n_instances); | ||
1069 | i = ss->instances[ss->n_instances - 1]; | ||
1070 | } | ||
1071 | GNUNET_CONFIGURATION_iterate_section_values (ss->cfg, | ||
1072 | ss->sname, | ||
1073 | &cfg_copy_iterator, | ||
1074 | cfg); | ||
1075 | GNUNET_CONFIGURATION_set_value_string (cfg, | ||
1076 | ss->sname, | ||
1077 | "UNIXPATH", | ||
1078 | i->unix_sock); | ||
1079 | GNUNET_CONFIGURATION_set_value_string (cfg, ss->sname, "PORT", i->port_str); | ||
1080 | return i; | ||
1081 | } | ||
1082 | |||
1083 | |||
1084 | /** | ||
1085 | * Create a new configuration using the given configuration as a template; | ||
1086 | * ports and paths will be modified to select available ports on the local | ||
1087 | * system. The default configuration will be available in PATHS section under | ||
1088 | * the option DEFAULTCONFIG after the call. GNUNET_HOME is also set in PATHS | ||
1089 | * section to the temporary directory specific to this configuration. If we run | ||
1090 | * out of "*port" numbers, return #GNUNET_SYSERR. | ||
1091 | * | ||
1092 | * This is primarily a helper function used internally | ||
1093 | * by 'GNUNET_TESTING_peer_configure'. | ||
1094 | * | ||
1095 | * @param system system to use to coordinate resource usage | ||
1096 | * @param cfg template configuration to update | ||
1097 | * @param ports array with port numbers used in the created configuration. | ||
1098 | * Will be updated upon successful return. Can be NULL | ||
1099 | * @param nports the size of the `ports' array. Will be updated. | ||
1100 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - the configuration will | ||
1101 | * be incomplete and should not be used there upon | ||
1102 | */ | ||
1103 | static int | ||
1104 | GNUNET_TESTING_configuration_create_ (struct GNUNET_TESTING_System *system, | ||
1105 | struct GNUNET_CONFIGURATION_Handle *cfg, | ||
1106 | uint16_t **ports, | ||
1107 | unsigned int *nports) | ||
1108 | { | ||
1109 | struct UpdateContext uc; | ||
1110 | char *default_config; | ||
1111 | |||
1112 | uc.system = system; | ||
1113 | uc.cfg = cfg; | ||
1114 | uc.status = GNUNET_OK; | ||
1115 | uc.ports = NULL; | ||
1116 | uc.nports = 0; | ||
1117 | GNUNET_asprintf (&uc.gnunet_home, | ||
1118 | "%s/%u", | ||
1119 | system->tmppath, | ||
1120 | system->path_counter++); | ||
1121 | GNUNET_asprintf (&default_config, "%s/config", uc.gnunet_home); | ||
1122 | GNUNET_CONFIGURATION_set_value_string (cfg, | ||
1123 | "PATHS", | ||
1124 | "DEFAULTCONFIG", | ||
1125 | default_config); | ||
1126 | GNUNET_CONFIGURATION_set_value_string (cfg, "arm", "CONFIG", default_config); | ||
1127 | GNUNET_free (default_config); | ||
1128 | GNUNET_CONFIGURATION_set_value_string (cfg, | ||
1129 | "PATHS", | ||
1130 | "GNUNET_HOME", | ||
1131 | uc.gnunet_home); | ||
1132 | /* make PORTs and UNIXPATHs unique */ | ||
1133 | GNUNET_CONFIGURATION_iterate (cfg, &update_config, &uc); | ||
1134 | /* allow connections to services from system trusted_ip host */ | ||
1135 | GNUNET_CONFIGURATION_iterate_sections (cfg, &update_config_sections, &uc); | ||
1136 | /* enable loopback-based connections between peers */ | ||
1137 | GNUNET_CONFIGURATION_set_value_string (cfg, "nat", "USE_LOCALADDR", "YES"); | ||
1138 | GNUNET_free (uc.gnunet_home); | ||
1139 | if ((NULL != ports) && (NULL != nports)) | ||
1140 | { | ||
1141 | *ports = uc.ports; | ||
1142 | *nports = uc.nports; | ||
1143 | } | ||
1144 | else | ||
1145 | GNUNET_free (uc.ports); | ||
1146 | return uc.status; | ||
1147 | } | ||
1148 | |||
1149 | |||
1150 | /** | ||
1151 | * Create a new configuration using the given configuration as a template; | ||
1152 | * ports and paths will be modified to select available ports on the local | ||
1153 | * system. The default configuration will be available in PATHS section under | ||
1154 | * the option DEFAULTCONFIG after the call. GNUNET_HOME is also set in PATHS | ||
1155 | * section to the temporary directory specific to this configuration. If we run | ||
1156 | * out of "*port" numbers, return #GNUNET_SYSERR. | ||
1157 | * | ||
1158 | * This is primarily a helper function used internally | ||
1159 | * by #GNUNET_TESTING_peer_configure(). | ||
1160 | * | ||
1161 | * @param system system to use to coordinate resource usage | ||
1162 | * @param cfg template configuration to update | ||
1163 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - the configuration will | ||
1164 | * be incomplete and should not be used there upon | ||
1165 | */ | ||
1166 | int | ||
1167 | GNUNET_TESTING_configuration_create (struct GNUNET_TESTING_System *system, | ||
1168 | struct GNUNET_CONFIGURATION_Handle *cfg) | ||
1169 | { | ||
1170 | return GNUNET_TESTING_configuration_create_ (system, cfg, NULL, NULL); | ||
1171 | } | ||
1172 | |||
1173 | |||
1174 | /** | ||
1175 | * Configure a GNUnet peer. GNUnet must be installed on the local | ||
1176 | * system and available in the PATH. | ||
1177 | * | ||
1178 | * @param system system to use to coordinate resource usage | ||
1179 | * @param cfg configuration to use; will be UPDATED (to reflect needed | ||
1180 | * changes in port numbers and paths) | ||
1181 | * @param key_number number of the hostkey to use for the peer | ||
1182 | * @param id identifier for the daemon, will be set, can be NULL | ||
1183 | * @param emsg set to freshly allocated error message (set to NULL on success), | ||
1184 | * can be NULL | ||
1185 | * @return handle to the peer, NULL on error | ||
1186 | */ | ||
1187 | struct GNUNET_TESTING_Peer * | ||
1188 | GNUNET_TESTING_peer_configure (struct GNUNET_TESTING_System *system, | ||
1189 | struct GNUNET_CONFIGURATION_Handle *cfg, | ||
1190 | uint32_t key_number, | ||
1191 | struct GNUNET_PeerIdentity *id, | ||
1192 | char **emsg) | ||
1193 | { | ||
1194 | struct GNUNET_TESTING_Peer *peer; | ||
1195 | struct GNUNET_DISK_FileHandle *fd; | ||
1196 | char *hostkey_filename; | ||
1197 | char *config_filename; | ||
1198 | char *libexec_binary; | ||
1199 | char *emsg_; | ||
1200 | struct GNUNET_CRYPTO_EddsaPrivateKey *pk; | ||
1201 | uint16_t *ports; | ||
1202 | struct SharedService *ss; | ||
1203 | struct SharedServiceInstance **ss_instances; | ||
1204 | unsigned int cnt; | ||
1205 | unsigned int nports; | ||
1206 | |||
1207 | ports = NULL; | ||
1208 | nports = 0; | ||
1209 | ss_instances = NULL; | ||
1210 | if (NULL != emsg) | ||
1211 | *emsg = NULL; | ||
1212 | if (key_number >= system->total_hostkeys) | ||
1213 | { | ||
1214 | GNUNET_asprintf ( | ||
1215 | &emsg_, | ||
1216 | _ ( | ||
1217 | "You attempted to create a testbed with more than %u hosts. Please precompute more hostkeys first.\n"), | ||
1218 | (unsigned int) system->total_hostkeys); | ||
1219 | goto err_ret; | ||
1220 | } | ||
1221 | pk = NULL; | ||
1222 | if ((NULL != id) && | ||
1223 | (NULL == (pk = GNUNET_TESTING_hostkey_get (system, key_number, id)))) | ||
1224 | { | ||
1225 | GNUNET_asprintf (&emsg_, | ||
1226 | _ ("Failed to initialize hostkey for peer %u\n"), | ||
1227 | (unsigned int) key_number); | ||
1228 | goto err_ret; | ||
1229 | } | ||
1230 | if (NULL != pk) | ||
1231 | GNUNET_free (pk); | ||
1232 | if (GNUNET_NO == GNUNET_CONFIGURATION_have_value (cfg, "PEER", "PRIVATE_KEY")) | ||
1233 | { | ||
1234 | GNUNET_asprintf ( | ||
1235 | &emsg_, | ||
1236 | _ ("PRIVATE_KEY option in PEER section missing in configuration\n")); | ||
1237 | goto err_ret; | ||
1238 | } | ||
1239 | /* Remove sections for shared services */ | ||
1240 | for (cnt = 0; cnt < system->n_shared_services; cnt++) | ||
1241 | { | ||
1242 | ss = &system->shared_services[cnt]; | ||
1243 | GNUNET_CONFIGURATION_remove_section (cfg, ss->sname); | ||
1244 | } | ||
1245 | if (GNUNET_OK != | ||
1246 | GNUNET_TESTING_configuration_create_ (system, cfg, &ports, &nports)) | ||
1247 | { | ||
1248 | GNUNET_asprintf (&emsg_, | ||
1249 | _ ("Failed to create configuration for peer " | ||
1250 | "(not enough free ports?)\n")); | ||
1251 | goto err_ret; | ||
1252 | } | ||
1253 | GNUNET_assert (GNUNET_OK == | ||
1254 | GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
1255 | "PEER", | ||
1256 | "PRIVATE_KEY", | ||
1257 | &hostkey_filename)); | ||
1258 | fd = GNUNET_DISK_file_open (hostkey_filename, | ||
1259 | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, | ||
1260 | GNUNET_DISK_PERM_USER_READ | ||
1261 | | GNUNET_DISK_PERM_USER_WRITE); | ||
1262 | if (NULL == fd) | ||
1263 | { | ||
1264 | GNUNET_asprintf (&emsg_, | ||
1265 | _ ("Cannot open hostkey file `%s': %s\n"), | ||
1266 | hostkey_filename, | ||
1267 | strerror (errno)); | ||
1268 | GNUNET_free (hostkey_filename); | ||
1269 | goto err_ret; | ||
1270 | } | ||
1271 | GNUNET_free (hostkey_filename); | ||
1272 | if (GNUNET_TESTING_HOSTKEYFILESIZE != | ||
1273 | GNUNET_DISK_file_write (fd, | ||
1274 | system->hostkeys_data | ||
1275 | + (key_number * GNUNET_TESTING_HOSTKEYFILESIZE), | ||
1276 | GNUNET_TESTING_HOSTKEYFILESIZE)) | ||
1277 | { | ||
1278 | GNUNET_asprintf (&emsg_, | ||
1279 | _ ("Failed to write hostkey file for peer %u: %s\n"), | ||
1280 | (unsigned int) key_number, | ||
1281 | strerror (errno)); | ||
1282 | GNUNET_DISK_file_close (fd); | ||
1283 | goto err_ret; | ||
1284 | } | ||
1285 | GNUNET_DISK_file_close (fd); | ||
1286 | ss_instances = GNUNET_new_array (system->n_shared_services, | ||
1287 | struct SharedServiceInstance*); | ||
1288 | for (cnt = 0; cnt < system->n_shared_services; cnt++) | ||
1289 | { | ||
1290 | ss = &system->shared_services[cnt]; | ||
1291 | ss_instances[cnt] = associate_shared_service (system, ss, cfg); | ||
1292 | if (NULL == ss_instances[cnt]) | ||
1293 | { | ||
1294 | emsg_ = GNUNET_strdup ("FIXME"); | ||
1295 | goto err_ret; | ||
1296 | } | ||
1297 | } | ||
1298 | GNUNET_assert (GNUNET_OK == | ||
1299 | GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
1300 | "PATHS", | ||
1301 | "DEFAULTCONFIG", | ||
1302 | &config_filename)); | ||
1303 | if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, config_filename)) | ||
1304 | { | ||
1305 | GNUNET_asprintf (&emsg_, | ||
1306 | _ ( | ||
1307 | "Failed to write configuration file `%s' for peer %u: %s\n"), | ||
1308 | config_filename, | ||
1309 | (unsigned int) key_number, | ||
1310 | strerror (errno)); | ||
1311 | GNUNET_free (config_filename); | ||
1312 | goto err_ret; | ||
1313 | } | ||
1314 | peer = GNUNET_new (struct GNUNET_TESTING_Peer); | ||
1315 | peer->ss_instances = ss_instances; | ||
1316 | peer->cfgfile = config_filename; /* Free in peer_destroy */ | ||
1317 | peer->cfg = GNUNET_CONFIGURATION_dup (cfg); | ||
1318 | libexec_binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm"); | ||
1319 | if (GNUNET_SYSERR == | ||
1320 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
1321 | "arm", | ||
1322 | "PREFIX", | ||
1323 | &peer->main_binary)) | ||
1324 | { | ||
1325 | /* No prefix */ | ||
1326 | GNUNET_asprintf (&peer->main_binary, "%s", libexec_binary); | ||
1327 | peer->args = GNUNET_strdup (""); | ||
1328 | } | ||
1329 | else | ||
1330 | { | ||
1331 | peer->args = GNUNET_strdup (libexec_binary); | ||
1332 | } | ||
1333 | peer->system = system; | ||
1334 | peer->key_number = key_number; | ||
1335 | GNUNET_free (libexec_binary); | ||
1336 | peer->ports = ports; /* Free in peer_destroy */ | ||
1337 | peer->nports = nports; | ||
1338 | return peer; | ||
1339 | |||
1340 | err_ret: | ||
1341 | GNUNET_free (ss_instances); | ||
1342 | GNUNET_free (ports); | ||
1343 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", emsg_); | ||
1344 | if (NULL != emsg) | ||
1345 | *emsg = emsg_; | ||
1346 | else | ||
1347 | GNUNET_free (emsg_); | ||
1348 | return NULL; | ||
1349 | } | ||
1350 | |||
1351 | |||
1352 | /** | ||
1353 | * Obtain the peer identity from a peer handle. | ||
1354 | * | ||
1355 | * @param peer peer handle for which we want the peer's identity | ||
1356 | * @param id identifier for the daemon, will be set | ||
1357 | */ | ||
1358 | void | ||
1359 | GNUNET_TESTING_peer_get_identity (struct GNUNET_TESTING_Peer *peer, | ||
1360 | struct GNUNET_PeerIdentity *id) | ||
1361 | { | ||
1362 | if (NULL != peer->id) | ||
1363 | { | ||
1364 | GNUNET_memcpy (id, peer->id, sizeof(struct GNUNET_PeerIdentity)); | ||
1365 | return; | ||
1366 | } | ||
1367 | peer->id = GNUNET_new (struct GNUNET_PeerIdentity); | ||
1368 | GNUNET_free_nz ( | ||
1369 | GNUNET_TESTING_hostkey_get (peer->system, peer->key_number, peer->id)); | ||
1370 | GNUNET_memcpy (id, peer->id, sizeof(struct GNUNET_PeerIdentity)); | ||
1371 | } | ||
1372 | |||
1373 | |||
1374 | /** | ||
1375 | * Start the peer. | ||
1376 | * | ||
1377 | * @param peer peer to start | ||
1378 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (i.e. peer already running) | ||
1379 | */ | ||
1380 | int | ||
1381 | GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer) | ||
1382 | { | ||
1383 | struct SharedServiceInstance *i; | ||
1384 | unsigned int cnt; | ||
1385 | |||
1386 | if (NULL != peer->main_process) | ||
1387 | { | ||
1388 | GNUNET_break (0); | ||
1389 | return GNUNET_SYSERR; | ||
1390 | } | ||
1391 | GNUNET_assert (NULL != peer->cfgfile); | ||
1392 | for (cnt = 0; cnt < peer->system->n_shared_services; cnt++) | ||
1393 | { | ||
1394 | i = peer->ss_instances[cnt]; | ||
1395 | if ((0 == i->n_refs) && | ||
1396 | (GNUNET_SYSERR == start_shared_service_instance (i))) | ||
1397 | return GNUNET_SYSERR; | ||
1398 | i->n_refs++; | ||
1399 | } | ||
1400 | peer->main_binary = | ||
1401 | GNUNET_CONFIGURATION_expand_dollar (peer->cfg, peer->main_binary); | ||
1402 | peer->main_process = | ||
1403 | GNUNET_OS_start_process_s (GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | ||
1404 | NULL, | ||
1405 | peer->main_binary, | ||
1406 | peer->args, | ||
1407 | "-c", | ||
1408 | peer->cfgfile, | ||
1409 | NULL); | ||
1410 | if (NULL == peer->main_process) | ||
1411 | { | ||
1412 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1413 | _ ("Failed to start `%s': %s\n"), | ||
1414 | peer->main_binary, | ||
1415 | strerror (errno)); | ||
1416 | return GNUNET_SYSERR; | ||
1417 | } | ||
1418 | return GNUNET_OK; | ||
1419 | } | ||
1420 | |||
1421 | |||
1422 | /** | ||
1423 | * Sends SIGTERM to the peer's main process | ||
1424 | * | ||
1425 | * @param peer the handle to the peer | ||
1426 | * @return #GNUNET_OK if successful; #GNUNET_SYSERR if the main process is NULL | ||
1427 | * or upon any error while sending SIGTERM | ||
1428 | */ | ||
1429 | int | ||
1430 | GNUNET_TESTING_peer_kill (struct GNUNET_TESTING_Peer *peer) | ||
1431 | { | ||
1432 | struct SharedServiceInstance *i; | ||
1433 | unsigned int cnt; | ||
1434 | |||
1435 | if (NULL == peer->main_process) | ||
1436 | { | ||
1437 | GNUNET_break (0); | ||
1438 | return GNUNET_SYSERR; | ||
1439 | } | ||
1440 | if (0 != GNUNET_OS_process_kill (peer->main_process, GNUNET_TERM_SIG)) | ||
1441 | return GNUNET_SYSERR; | ||
1442 | for (cnt = 0; cnt < peer->system->n_shared_services; cnt++) | ||
1443 | { | ||
1444 | i = peer->ss_instances[cnt]; | ||
1445 | GNUNET_assert (0 != i->n_refs); | ||
1446 | i->n_refs--; | ||
1447 | if (0 == i->n_refs) | ||
1448 | stop_shared_service_instance (i); | ||
1449 | } | ||
1450 | return GNUNET_OK; | ||
1451 | } | ||
1452 | |||
1453 | |||
1454 | /** | ||
1455 | * Waits for a peer to terminate. The peer's main process will also be destroyed. | ||
1456 | * | ||
1457 | * @param peer the handle to the peer | ||
1458 | * @return #GNUNET_OK if successful; #GNUNET_SYSERR if the main process is NULL | ||
1459 | * or upon any error while waiting | ||
1460 | */ | ||
1461 | int | ||
1462 | GNUNET_TESTING_peer_wait (struct GNUNET_TESTING_Peer *peer) | ||
1463 | { | ||
1464 | int ret; | ||
1465 | |||
1466 | if (NULL == peer->main_process) | ||
1467 | { | ||
1468 | GNUNET_break (0); | ||
1469 | return GNUNET_SYSERR; | ||
1470 | } | ||
1471 | ret = GNUNET_OS_process_wait (peer->main_process); | ||
1472 | GNUNET_OS_process_destroy (peer->main_process); | ||
1473 | peer->main_process = NULL; | ||
1474 | return ret; | ||
1475 | } | ||
1476 | |||
1477 | |||
1478 | /** | ||
1479 | * Stop the peer. | ||
1480 | * | ||
1481 | * @param peer peer to stop | ||
1482 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
1483 | */ | ||
1484 | int | ||
1485 | GNUNET_TESTING_peer_stop (struct GNUNET_TESTING_Peer *peer) | ||
1486 | { | ||
1487 | if (GNUNET_SYSERR == GNUNET_TESTING_peer_kill (peer)) | ||
1488 | return GNUNET_SYSERR; | ||
1489 | if (GNUNET_SYSERR == GNUNET_TESTING_peer_wait (peer)) | ||
1490 | return GNUNET_SYSERR; | ||
1491 | return GNUNET_OK; | ||
1492 | } | ||
1493 | |||
1494 | |||
1495 | /** | ||
1496 | * Function called whenever we connect to or disconnect from ARM. | ||
1497 | * | ||
1498 | * @param cls closure | ||
1499 | * @param connected #GNUNET_YES if connected, #GNUNET_NO if disconnected, | ||
1500 | * #GNUNET_SYSERR on error. | ||
1501 | */ | ||
1502 | static void | ||
1503 | disconn_status (void *cls, int connected) | ||
1504 | { | ||
1505 | struct GNUNET_TESTING_Peer *peer = cls; | ||
1506 | |||
1507 | if (GNUNET_SYSERR == connected) | ||
1508 | { | ||
1509 | peer->cb (peer->cb_cls, peer, connected); | ||
1510 | return; | ||
1511 | } | ||
1512 | if (GNUNET_YES == connected) | ||
1513 | { | ||
1514 | GNUNET_break (GNUNET_OK == GNUNET_TESTING_peer_kill (peer)); | ||
1515 | return; | ||
1516 | } | ||
1517 | GNUNET_break (GNUNET_OK == GNUNET_TESTING_peer_wait (peer)); | ||
1518 | GNUNET_ARM_disconnect (peer->ah); | ||
1519 | peer->ah = NULL; | ||
1520 | peer->cb (peer->cb_cls, peer, GNUNET_YES); | ||
1521 | } | ||
1522 | |||
1523 | |||
1524 | int | ||
1525 | GNUNET_TESTING_peer_stop_async (struct GNUNET_TESTING_Peer *peer, | ||
1526 | GNUNET_TESTING_PeerStopCallback cb, | ||
1527 | void *cb_cls) | ||
1528 | { | ||
1529 | if (NULL == peer->main_process) | ||
1530 | return GNUNET_SYSERR; | ||
1531 | peer->ah = GNUNET_ARM_connect (peer->cfg, &disconn_status, peer); | ||
1532 | if (NULL == peer->ah) | ||
1533 | return GNUNET_SYSERR; | ||
1534 | peer->cb = cb; | ||
1535 | peer->cb_cls = cb_cls; | ||
1536 | return GNUNET_OK; | ||
1537 | } | ||
1538 | |||
1539 | |||
1540 | /** | ||
1541 | * Cancel a previous asynchronous peer stop request. | ||
1542 | * GNUNET_TESTING_peer_stop_async() should have been called before on the given | ||
1543 | * peer. It is an error to call this function if the peer stop callback was | ||
1544 | * already called | ||
1545 | * | ||
1546 | * @param peer the peer on which GNUNET_TESTING_peer_stop_async() was called | ||
1547 | * before. | ||
1548 | */ | ||
1549 | void | ||
1550 | GNUNET_TESTING_peer_stop_async_cancel (struct GNUNET_TESTING_Peer *peer) | ||
1551 | { | ||
1552 | GNUNET_assert (NULL != peer->ah); | ||
1553 | GNUNET_ARM_disconnect (peer->ah); | ||
1554 | peer->ah = NULL; | ||
1555 | } | ||
1556 | |||
1557 | |||
1558 | /** | ||
1559 | * Destroy the peer. Releases resources locked during peer configuration. | ||
1560 | * If the peer is still running, it will be stopped AND a warning will be | ||
1561 | * printed (users of the API should stop the peer explicitly first). | ||
1562 | * | ||
1563 | * @param peer peer to destroy | ||
1564 | */ | ||
1565 | void | ||
1566 | GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer) | ||
1567 | { | ||
1568 | unsigned int cnt; | ||
1569 | |||
1570 | if (NULL != peer->main_process) | ||
1571 | GNUNET_TESTING_peer_stop (peer); | ||
1572 | if (NULL != peer->ah) | ||
1573 | GNUNET_ARM_disconnect (peer->ah); | ||
1574 | GNUNET_free (peer->cfgfile); | ||
1575 | if (NULL != peer->cfg) | ||
1576 | GNUNET_CONFIGURATION_destroy (peer->cfg); | ||
1577 | GNUNET_free (peer->main_binary); | ||
1578 | GNUNET_free (peer->args); | ||
1579 | GNUNET_free (peer->id); | ||
1580 | GNUNET_free (peer->ss_instances); | ||
1581 | if (NULL != peer->ports) | ||
1582 | { | ||
1583 | for (cnt = 0; cnt < peer->nports; cnt++) | ||
1584 | GNUNET_TESTING_release_port (peer->system, peer->ports[cnt]); | ||
1585 | GNUNET_free (peer->ports); | ||
1586 | } | ||
1587 | GNUNET_free (peer); | ||
1588 | } | ||
1589 | |||
1590 | |||
1591 | int | ||
1592 | GNUNET_TESTING_peer_run (const char *testdir, | ||
1593 | const char *cfgfilename, | ||
1594 | GNUNET_TESTING_TestMain tm, | ||
1595 | void *tm_cls) | ||
1596 | { | ||
1597 | return GNUNET_TESTING_service_run (testdir, "arm", cfgfilename, tm, tm_cls); | ||
1598 | } | ||
1599 | |||
1600 | |||
1601 | /** | ||
1602 | * Structure for holding service data | ||
1603 | */ | ||
1604 | struct ServiceContext | ||
1605 | { | ||
1606 | /** | ||
1607 | * The configuration of the peer in which the service is run | ||
1608 | */ | ||
1609 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
1610 | |||
1611 | /** | ||
1612 | * Callback to signal service startup | ||
1613 | */ | ||
1614 | GNUNET_TESTING_TestMain tm; | ||
1615 | |||
1616 | /** | ||
1617 | * The peer in which the service is run. | ||
1618 | */ | ||
1619 | struct GNUNET_TESTING_Peer *peer; | ||
1620 | |||
1621 | /** | ||
1622 | * Closure for the above callback | ||
1623 | */ | ||
1624 | void *tm_cls; | ||
1625 | }; | ||
1626 | |||
1627 | |||
1628 | /** | ||
1629 | * Callback to be called when SCHEDULER has been started | ||
1630 | * | ||
1631 | * @param cls the ServiceContext | ||
1632 | */ | ||
1633 | static void | ||
1634 | service_run_main (void *cls) | ||
1635 | { | ||
1636 | struct ServiceContext *sc = cls; | ||
1637 | |||
1638 | sc->tm (sc->tm_cls, sc->cfg, sc->peer); | ||
1639 | } | ||
1640 | |||
1641 | |||
1642 | int | ||
1643 | GNUNET_TESTING_service_run (const char *testdir, | ||
1644 | const char *service_name, | ||
1645 | const char *cfgfilename, | ||
1646 | GNUNET_TESTING_TestMain tm, | ||
1647 | void *tm_cls) | ||
1648 | { | ||
1649 | struct ServiceContext sc; | ||
1650 | struct GNUNET_TESTING_System *system; | ||
1651 | struct GNUNET_TESTING_Peer *peer; | ||
1652 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
1653 | char *binary; | ||
1654 | char *libexec_binary; | ||
1655 | |||
1656 | GNUNET_log_setup (testdir, "WARNING", NULL); | ||
1657 | system = GNUNET_TESTING_system_create (testdir, "127.0.0.1", NULL, NULL); | ||
1658 | if (NULL == system) | ||
1659 | return 1; | ||
1660 | cfg = GNUNET_CONFIGURATION_create (); | ||
1661 | if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, cfgfilename)) | ||
1662 | { | ||
1663 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1664 | _ ("Failed to load configuration from %s\n"), | ||
1665 | cfgfilename); | ||
1666 | GNUNET_CONFIGURATION_destroy (cfg); | ||
1667 | GNUNET_TESTING_system_destroy (system, GNUNET_YES); | ||
1668 | return 1; | ||
1669 | } | ||
1670 | peer = GNUNET_TESTING_peer_configure (system, cfg, 0, NULL, NULL); | ||
1671 | if (NULL == peer) | ||
1672 | { | ||
1673 | GNUNET_CONFIGURATION_destroy (cfg); | ||
1674 | hostkeys_unload (system); | ||
1675 | GNUNET_TESTING_system_destroy (system, GNUNET_YES); | ||
1676 | return 1; | ||
1677 | } | ||
1678 | GNUNET_free (peer->main_binary); | ||
1679 | GNUNET_free (peer->args); | ||
1680 | GNUNET_asprintf (&binary, "gnunet-service-%s", service_name); | ||
1681 | libexec_binary = GNUNET_OS_get_libexec_binary_path (binary); | ||
1682 | if (GNUNET_SYSERR == | ||
1683 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
1684 | service_name, | ||
1685 | "PREFIX", | ||
1686 | &peer->main_binary)) | ||
1687 | { | ||
1688 | /* No prefix */ | ||
1689 | GNUNET_asprintf (&peer->main_binary, "%s", libexec_binary); | ||
1690 | peer->args = GNUNET_strdup (""); | ||
1691 | } | ||
1692 | else | ||
1693 | peer->args = GNUNET_strdup (libexec_binary); | ||
1694 | |||
1695 | GNUNET_free (libexec_binary); | ||
1696 | GNUNET_free (binary); | ||
1697 | if (GNUNET_OK != GNUNET_TESTING_peer_start (peer)) | ||
1698 | { | ||
1699 | GNUNET_TESTING_peer_destroy (peer); | ||
1700 | GNUNET_CONFIGURATION_destroy (cfg); | ||
1701 | GNUNET_TESTING_system_destroy (system, GNUNET_YES); | ||
1702 | return 1; | ||
1703 | } | ||
1704 | sc.cfg = cfg; | ||
1705 | sc.tm = tm; | ||
1706 | sc.tm_cls = tm_cls; | ||
1707 | sc.peer = peer; | ||
1708 | GNUNET_SCHEDULER_run (&service_run_main, &sc); /* Scheduler loop */ | ||
1709 | if ((NULL != peer->main_process) && | ||
1710 | (GNUNET_OK != GNUNET_TESTING_peer_stop (peer))) | ||
1711 | { | ||
1712 | GNUNET_TESTING_peer_destroy (peer); | ||
1713 | GNUNET_CONFIGURATION_destroy (cfg); | ||
1714 | GNUNET_TESTING_system_destroy (system, GNUNET_YES); | ||
1715 | return 1; | ||
1716 | } | ||
1717 | GNUNET_TESTING_peer_destroy (peer); | ||
1718 | GNUNET_CONFIGURATION_destroy (cfg); | ||
1719 | GNUNET_TESTING_system_destroy (system, GNUNET_YES); | ||
1720 | return 0; | ||
1721 | } | ||
1722 | |||
1723 | |||
1724 | /** | ||
1725 | * Every line in the topology configuration starts with a string indicating which | ||
1726 | * kind of information will be configured with this line. Configuration values following | ||
1727 | * this string are seperated by special sequences of characters. An integer value seperated | ||
1728 | * by ':' is returned by this function. | ||
1729 | * | ||
1730 | * @param line The line of configuration. | ||
1731 | * @return An integer value. | ||
1732 | */ | ||
1733 | static unsigned int | ||
1734 | get_first_value (const char *line) | ||
1735 | { | ||
1736 | char *copy; | ||
1737 | size_t slen; | ||
1738 | char *token; | ||
1739 | unsigned int ret; | ||
1740 | char *rest = NULL; | ||
1741 | |||
1742 | slen = strlen (line) + 1; | ||
1743 | copy = GNUNET_malloc (slen); | ||
1744 | memcpy (copy, line, slen); | ||
1745 | token = strtok_r (copy, ":", &rest); | ||
1746 | token = strtok_r (NULL, ":", &rest); | ||
1747 | GNUNET_assert (1 == sscanf (token, "%u", &ret)); | ||
1748 | GNUNET_free (copy); | ||
1749 | return ret; | ||
1750 | } | ||
1751 | |||
1752 | |||
1753 | /** | ||
1754 | * Every line in the topology configuration starts with a string indicating which | ||
1755 | * kind of information will be configured with this line. This string is returned by this function. | ||
1756 | * | ||
1757 | * @param line The line of configuration. | ||
1758 | * @return The leading string of this configuration line. | ||
1759 | */ | ||
1760 | static char * | ||
1761 | get_key (const char *line) | ||
1762 | { | ||
1763 | char *copy; | ||
1764 | size_t slen; | ||
1765 | size_t tlen; | ||
1766 | char *token; | ||
1767 | char *ret; | ||
1768 | char *rest = NULL; | ||
1769 | |||
1770 | slen = strlen (line) + 1; | ||
1771 | copy = GNUNET_malloc (slen); | ||
1772 | memcpy (copy, line, slen); | ||
1773 | token = strtok_r (copy, ":", &rest); | ||
1774 | tlen = strlen (token) + 1; | ||
1775 | ret = GNUNET_malloc (tlen); | ||
1776 | memcpy (ret, token, tlen); | ||
1777 | GNUNET_free (copy); | ||
1778 | return ret; | ||
1779 | } | ||
1780 | |||
1781 | |||
1782 | /** | ||
1783 | * Every line in the topology configuration starts with a string indicating which | ||
1784 | * kind of information will be configured with this line. Configuration values following | ||
1785 | * this string are seperated by special sequences of characters. A string value seperated | ||
1786 | * by ':' is returned by this function. | ||
1787 | * | ||
1788 | * @param line The line of configuration. | ||
1789 | * @return A string value. | ||
1790 | */ | ||
1791 | static char * | ||
1792 | get_first_string_value (const char *line) | ||
1793 | { | ||
1794 | char *copy; | ||
1795 | size_t slen, slen_token; | ||
1796 | char *token; | ||
1797 | char *ret; | ||
1798 | char *rest = NULL; | ||
1799 | |||
1800 | slen = strlen (line) + 1; | ||
1801 | copy = GNUNET_malloc (slen); | ||
1802 | memcpy (copy, line, slen); | ||
1803 | token = strtok_r (copy, ":", &rest); | ||
1804 | token = strtok_r (NULL, ":", &rest); | ||
1805 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1806 | "first token %s\n", | ||
1807 | token); | ||
1808 | slen_token = strlen (token); | ||
1809 | ret = GNUNET_malloc (slen_token + 1); | ||
1810 | memcpy (ret, token, slen_token + 1); | ||
1811 | GNUNET_free (copy); | ||
1812 | return ret; | ||
1813 | } | ||
1814 | |||
1815 | |||
1816 | /** | ||
1817 | * Every line in the topology configuration starts with a string indicating which | ||
1818 | * kind of information will be configured with this line. Configuration values following | ||
1819 | * this string are seperated by special sequences of characters. A second integer value | ||
1820 | * seperated by ':' from a first value is returned by this function. | ||
1821 | * | ||
1822 | * @param line The line of configuration. | ||
1823 | * @return An integer value. | ||
1824 | */ | ||
1825 | static unsigned int | ||
1826 | get_second_value (const char *line) | ||
1827 | { | ||
1828 | char *copy; | ||
1829 | char *token; | ||
1830 | unsigned int ret; | ||
1831 | char *rest = NULL; | ||
1832 | |||
1833 | copy = GNUNET_strdup (line); | ||
1834 | token = strtok_r (copy, ":", &rest); | ||
1835 | token = strtok_r (NULL, ":", &rest); | ||
1836 | token = strtok_r (NULL, ":", &rest); | ||
1837 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1838 | "Format error in configuration line: %s\n", | ||
1839 | line); | ||
1840 | GNUNET_assert (1 == sscanf (token, "%u", &ret)); | ||
1841 | GNUNET_free (copy); | ||
1842 | return ret; | ||
1843 | } | ||
1844 | |||
1845 | |||
1846 | /** | ||
1847 | * Every line in the topology configuration starts with a string indicating which | ||
1848 | * kind of information will be configured with this line. Configuration values following | ||
1849 | * this string are seperated by special sequences of characters. A value might be | ||
1850 | * a key value pair. | ||
1851 | * This function returns the value for a specific key in a configuration line. | ||
1852 | * | ||
1853 | * @param key The key of the key value pair. | ||
1854 | * @return The value of the key value pair. | ||
1855 | */ | ||
1856 | static char * | ||
1857 | get_value (const char *key, const char *line) | ||
1858 | { | ||
1859 | char copy[strlen (line) + 1]; | ||
1860 | size_t slen; | ||
1861 | char *token; | ||
1862 | char *token2; | ||
1863 | char *temp; | ||
1864 | char *rest = NULL; | ||
1865 | |||
1866 | slen = strlen (line) + 1; | ||
1867 | memcpy (copy, line, slen); | ||
1868 | temp = strstr (copy, key); | ||
1869 | if (NULL == temp) | ||
1870 | return NULL; | ||
1871 | token = strtok_r (temp, ":", &rest); | ||
1872 | if (NULL == token) | ||
1873 | return NULL; | ||
1874 | token = strtok_r (NULL, ":", &rest); | ||
1875 | if (NULL == token) | ||
1876 | return NULL; | ||
1877 | token2 = strtok_r (token, "}", &rest); | ||
1878 | if (NULL == token2) | ||
1879 | return NULL; | ||
1880 | return GNUNET_strdup (token2); | ||
1881 | } | ||
1882 | |||
1883 | |||
1884 | /** | ||
1885 | * Every line in the topology configuration starts with a string indicating which | ||
1886 | * kind of information will be configured with this line. Configuration values following | ||
1887 | * this string are seperated by special sequences of characters. A value might be | ||
1888 | * a key value pair. A special key is the 'connect' key which can appear more than once. | ||
1889 | * The value is the information about a connection via some protocol to some other node. | ||
1890 | * This function returns the struct GNUNET_TESTING_NodeConnection which holds the information | ||
1891 | * of the connect value. | ||
1892 | * | ||
1893 | * @param value The value of the connect key value pair. | ||
1894 | * @return The struct GNUNET_TESTING_NodeConnection. | ||
1895 | */ | ||
1896 | static struct GNUNET_TESTING_NodeConnection * | ||
1897 | get_connect_value (const char *line, | ||
1898 | struct GNUNET_TESTING_NetjailNode *node) | ||
1899 | { | ||
1900 | struct GNUNET_TESTING_NodeConnection *node_connection; | ||
1901 | char *copy; | ||
1902 | char *token; | ||
1903 | char *token2; | ||
1904 | unsigned int node_n; | ||
1905 | unsigned int namespace_n; | ||
1906 | char *rest = NULL; | ||
1907 | char *rest2 = NULL; | ||
1908 | struct GNUNET_TESTING_AddressPrefix *prefix; | ||
1909 | unsigned int sscanf_ret; | ||
1910 | |||
1911 | node_connection = GNUNET_new (struct GNUNET_TESTING_NodeConnection); | ||
1912 | node_connection->node = node; | ||
1913 | |||
1914 | copy = GNUNET_strdup (line); | ||
1915 | token = strtok_r (copy, ":", &rest); | ||
1916 | if (0 == strcmp ("{K", token)) | ||
1917 | { | ||
1918 | node_connection->node_type = GNUNET_TESTING_GLOBAL_NODE; | ||
1919 | token = strtok_r (NULL, ":", &rest); | ||
1920 | GNUNET_assert (1 == sscanf (token, "%u", &node_n)); | ||
1921 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1922 | "node_n %u\n", | ||
1923 | node_n); | ||
1924 | node_connection->node_n = node_n; | ||
1925 | node_connection->namespace_n = 0; | ||
1926 | } | ||
1927 | else if (0 == strcmp ("{P", token)) | ||
1928 | { | ||
1929 | node_connection->node_type = GNUNET_TESTING_SUBNET_NODE; | ||
1930 | token = strtok_r (NULL, ":", &rest); | ||
1931 | errno = 0; | ||
1932 | sscanf_ret = sscanf (token, "%u", &namespace_n); | ||
1933 | if (errno != 0) | ||
1934 | { | ||
1935 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sscanf"); | ||
1936 | } | ||
1937 | GNUNET_assert (0 < sscanf_ret); | ||
1938 | node_connection->namespace_n = namespace_n; | ||
1939 | token = strtok_r (NULL, ":", &rest); | ||
1940 | errno = 0; | ||
1941 | sscanf_ret = sscanf (token, "%u", &node_n); | ||
1942 | if (errno != 0) | ||
1943 | { | ||
1944 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sscanf"); | ||
1945 | } | ||
1946 | GNUNET_assert (0 < sscanf_ret); | ||
1947 | node_connection->node_n = node_n; | ||
1948 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1949 | "node_n %u namespace_n %u node->node_n %u node->namespace_n %u\n", | ||
1950 | node_n, | ||
1951 | namespace_n, | ||
1952 | node->node_n, | ||
1953 | node->namespace_n); | ||
1954 | } | ||
1955 | else | ||
1956 | { | ||
1957 | GNUNET_break (0); | ||
1958 | GNUNET_free (node_connection); | ||
1959 | GNUNET_free (copy); | ||
1960 | return NULL; | ||
1961 | } | ||
1962 | |||
1963 | while (NULL != (token = strtok_r (NULL, ":", &rest))) | ||
1964 | { | ||
1965 | prefix = GNUNET_new (struct GNUNET_TESTING_AddressPrefix); | ||
1966 | token2 = strtok_r (token, "}", &rest2); | ||
1967 | if (NULL != token2) | ||
1968 | prefix->address_prefix = GNUNET_strdup (token2); | ||
1969 | else | ||
1970 | prefix->address_prefix = GNUNET_strdup (token); | ||
1971 | |||
1972 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1973 | "address_prefix %s\n", | ||
1974 | prefix->address_prefix); | ||
1975 | |||
1976 | GNUNET_CONTAINER_DLL_insert (node_connection->address_prefixes_head, | ||
1977 | node_connection->address_prefixes_tail, | ||
1978 | prefix); | ||
1979 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1980 | "address_prefix %s\n", | ||
1981 | prefix->address_prefix); | ||
1982 | } | ||
1983 | |||
1984 | GNUNET_free (copy); | ||
1985 | return node_connection; | ||
1986 | } | ||
1987 | |||
1988 | |||
1989 | /** | ||
1990 | * Every line in the topology configuration starts with a string indicating which | ||
1991 | * kind of information will be configured with this line. Configuration values following | ||
1992 | * this string are seperated by special sequences of characters. A value might be | ||
1993 | * a key value pair. A special key is the 'connect' key. | ||
1994 | * The value is the information about a connections via some protocol to other nodes. | ||
1995 | * Each connection itself is a key value pair separated by the character '|' and | ||
1996 | * surrounded by the characters '{' and '}'. | ||
1997 | * The struct GNUNET_TESTING_NodeConnection holds the information of each connection value. | ||
1998 | * This function extracts the values of each connection into a DLL of | ||
1999 | * struct GNUNET_TESTING_NodeConnection which will be added to a node. | ||
2000 | * | ||
2001 | * @param line The line of configuration. | ||
2002 | * @param node The struct GNUNET_TESTING_NetjailNode to which the DLL of | ||
2003 | * struct GNUNET_TESTING_NodeConnection will be added. | ||
2004 | */ | ||
2005 | static void | ||
2006 | node_connections (const char *line, struct GNUNET_TESTING_NetjailNode *node) | ||
2007 | { | ||
2008 | char *value, *value2; | ||
2009 | char *temp; | ||
2010 | char *copy; | ||
2011 | char *rest = NULL; | ||
2012 | char *rest2 = NULL; | ||
2013 | struct GNUNET_TESTING_NodeConnection *node_connection; | ||
2014 | |||
2015 | |||
2016 | temp = strstr (line, "connect"); | ||
2017 | if (NULL != temp) | ||
2018 | { | ||
2019 | copy = GNUNET_strdup (temp); | ||
2020 | strtok_r (copy, ":", &rest); | ||
2021 | value = strtok_r (rest, "|", &rest2); | ||
2022 | |||
2023 | while (NULL != value) | ||
2024 | { | ||
2025 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2026 | "node_connections value %s\n", | ||
2027 | value); | ||
2028 | node_connection = get_connect_value (value, node); | ||
2029 | if (NULL == node_connection) | ||
2030 | { | ||
2031 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2032 | "connect key was not expected in this configuration line: %s\n", | ||
2033 | line); | ||
2034 | break; | ||
2035 | } | ||
2036 | GNUNET_CONTAINER_DLL_insert (node->node_connections_head, | ||
2037 | node->node_connections_tail, | ||
2038 | node_connection); | ||
2039 | value2 = strstr (value, "}}"); | ||
2040 | if (NULL != value2) | ||
2041 | break; | ||
2042 | value = strtok_r (NULL, "|", &rest2); | ||
2043 | |||
2044 | } | ||
2045 | GNUNET_free (copy); | ||
2046 | } | ||
2047 | } | ||
2048 | |||
2049 | |||
2050 | /** | ||
2051 | * A helper function to log information about individual nodes. | ||
2052 | * | ||
2053 | * @param cls This is not used actually. | ||
2054 | * @param id The key of this value in the map. | ||
2055 | * @param value A struct GNUNET_TESTING_NetjailNode which holds information about a node. | ||
2056 | * return GNUNET_YES to continue with iterating, GNUNET_NO otherwise. | ||
2057 | */ | ||
2058 | static int | ||
2059 | log_nodes (void *cls, const struct GNUNET_ShortHashCode *id, void *value) | ||
2060 | { | ||
2061 | struct GNUNET_TESTING_NetjailNode *node = value; | ||
2062 | struct GNUNET_TESTING_NodeConnection *pos_connection; | ||
2063 | struct GNUNET_TESTING_AddressPrefix *pos_prefix; | ||
2064 | |||
2065 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2066 | "plugin: %s space: %u node: %u global: %u\n", | ||
2067 | node->plugin, | ||
2068 | node->namespace_n, | ||
2069 | node->node_n, | ||
2070 | node->is_global); | ||
2071 | |||
2072 | for (pos_connection = node->node_connections_head; NULL != pos_connection; | ||
2073 | pos_connection = pos_connection->next) | ||
2074 | { | ||
2075 | |||
2076 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2077 | "namespace_n: %u node_n: %u node_type: %u\n", | ||
2078 | pos_connection->namespace_n, | ||
2079 | pos_connection->node_n, | ||
2080 | pos_connection->node_type); | ||
2081 | |||
2082 | for (pos_prefix = pos_connection->address_prefixes_head; NULL != pos_prefix; | ||
2083 | pos_prefix = | ||
2084 | pos_prefix->next) | ||
2085 | { | ||
2086 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2087 | "prefix: %s\n", | ||
2088 | pos_prefix->address_prefix); | ||
2089 | } | ||
2090 | } | ||
2091 | return GNUNET_YES; | ||
2092 | } | ||
2093 | |||
2094 | |||
2095 | /** | ||
2096 | * Helper function to log information about namespaces. | ||
2097 | * | ||
2098 | * @param cls This is not used actually. | ||
2099 | * @param id The key of this value in the map. | ||
2100 | * @param value A struct GNUNET_TESTING_NetjailNamespace which holds information about a subnet. | ||
2101 | * return GNUNET_YES to continue with iterating, GNUNET_NO otherwise. | ||
2102 | */ | ||
2103 | static int | ||
2104 | log_namespaces (void *cls, const struct GNUNET_ShortHashCode *id, void *value) | ||
2105 | { | ||
2106 | struct GNUNET_TESTING_NetjailNamespace *namespace = value; | ||
2107 | |||
2108 | GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes, &log_nodes, NULL); | ||
2109 | return GNUNET_YES; | ||
2110 | } | ||
2111 | |||
2112 | |||
2113 | /** | ||
2114 | * Helper function to log the configuration in case of a problem with configuration. | ||
2115 | * | ||
2116 | * @param topology The struct GNUNET_TESTING_NetjailTopology holding the configuration information. | ||
2117 | */ | ||
2118 | static int | ||
2119 | log_topo (const struct GNUNET_TESTING_NetjailTopology *topology) | ||
2120 | { | ||
2121 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2122 | "plugin: %s spaces: %u nodes: %u known: %u\n", | ||
2123 | topology->plugin, | ||
2124 | topology->namespaces_n, | ||
2125 | topology->nodes_m, | ||
2126 | topology->nodes_x); | ||
2127 | |||
2128 | GNUNET_CONTAINER_multishortmap_iterate (topology->map_namespaces, | ||
2129 | log_namespaces, NULL); | ||
2130 | GNUNET_CONTAINER_multishortmap_iterate (topology->map_globals, &log_nodes, | ||
2131 | NULL); | ||
2132 | return GNUNET_YES; | ||
2133 | } | ||
2134 | |||
2135 | |||
2136 | /** | ||
2137 | * This function extracts information about a specific node from the topology. | ||
2138 | * | ||
2139 | * @param num The global index number of the node. | ||
2140 | * @param[out] node_ex A struct GNUNET_TESTING_NetjailNode with information about the node. | ||
2141 | * @param[out] namespace_ex A struct GNUNET_TESTING_NetjailNamespace with information about the namespace | ||
2142 | the node is in or NULL, if the node is a global node. | ||
2143 | * @param[out] node_connections_ex A struct GNUNET_TESTING_NodeConnection with information about the connection | ||
2144 | of this node to other nodes. | ||
2145 | */ | ||
2146 | static void | ||
2147 | get_node_info (unsigned int num, | ||
2148 | const struct GNUNET_TESTING_NetjailTopology *topology, | ||
2149 | struct GNUNET_TESTING_NetjailNode **node_ex, | ||
2150 | struct GNUNET_TESTING_NetjailNamespace **namespace_ex, | ||
2151 | struct GNUNET_TESTING_NodeConnection **node_connections_ex) | ||
2152 | { | ||
2153 | struct GNUNET_ShortHashCode hkey; | ||
2154 | struct GNUNET_HashCode hc; | ||
2155 | unsigned int namespace_n; | ||
2156 | unsigned int node_m; | ||
2157 | struct GNUNET_TESTING_NetjailNode *node; | ||
2158 | struct GNUNET_TESTING_NetjailNamespace *namespace; | ||
2159 | struct GNUNET_TESTING_NodeConnection *node_connections = NULL; | ||
2160 | |||
2161 | log_topo (topology); | ||
2162 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2163 | "num: %u \n", | ||
2164 | num); | ||
2165 | if (topology->nodes_x >= num) | ||
2166 | { | ||
2167 | |||
2168 | GNUNET_CRYPTO_hash (&num, sizeof(num), &hc); | ||
2169 | memcpy (&hkey, | ||
2170 | &hc, | ||
2171 | sizeof (hkey)); | ||
2172 | node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals, | ||
2173 | &hkey); | ||
2174 | if (NULL != node) | ||
2175 | { | ||
2176 | *node_ex = node; | ||
2177 | *node_connections_ex = node->node_connections_head; | ||
2178 | } | ||
2179 | } | ||
2180 | else | ||
2181 | { | ||
2182 | namespace_n = (unsigned int) ceil ((double) (num - topology->nodes_x) | ||
2183 | / topology->nodes_m); | ||
2184 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2185 | "ceil num: %u nodes_x: %u nodes_m: %u namespace_n: %u\n", | ||
2186 | num, | ||
2187 | topology->nodes_x, | ||
2188 | topology->nodes_m, | ||
2189 | namespace_n); | ||
2190 | GNUNET_CRYPTO_hash (&namespace_n, sizeof(namespace_n), &hc); | ||
2191 | memcpy (&hkey, | ||
2192 | &hc, | ||
2193 | sizeof (hkey)); | ||
2194 | namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces, | ||
2195 | &hkey); | ||
2196 | if (NULL != namespace) | ||
2197 | { | ||
2198 | node_m = num - topology->nodes_x - topology->nodes_m * (namespace_n - 1); | ||
2199 | GNUNET_CRYPTO_hash (&node_m, sizeof(node_m), &hc); | ||
2200 | memcpy (&hkey, | ||
2201 | &hc, | ||
2202 | sizeof (hkey)); | ||
2203 | node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes, | ||
2204 | &hkey); | ||
2205 | if (NULL != node) | ||
2206 | { | ||
2207 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2208 | "node additional_connects: %u %p\n", | ||
2209 | node->additional_connects, | ||
2210 | node); | ||
2211 | node_connections = node->node_connections_head; | ||
2212 | } | ||
2213 | *node_ex = node; | ||
2214 | *namespace_ex = namespace; | ||
2215 | *node_connections_ex = node_connections; | ||
2216 | } | ||
2217 | } | ||
2218 | } | ||
2219 | |||
2220 | |||
2221 | /** | ||
2222 | * Get a node from the topology. | ||
2223 | * | ||
2224 | * @param num The specific node we want the connections for. | ||
2225 | * @param topology The topology we get the connections from. | ||
2226 | * @return The connections of the node. | ||
2227 | */ | ||
2228 | struct GNUNET_TESTING_NetjailNode * | ||
2229 | GNUNET_TESTING_get_node (unsigned int num, | ||
2230 | struct GNUNET_TESTING_NetjailTopology *topology) | ||
2231 | { | ||
2232 | struct GNUNET_TESTING_NetjailNode *node; | ||
2233 | struct GNUNET_TESTING_NetjailNamespace *namespace; | ||
2234 | struct GNUNET_TESTING_NodeConnection *node_connections; | ||
2235 | |||
2236 | get_node_info (num, topology, &node, &namespace, &node_connections); | ||
2237 | |||
2238 | return node; | ||
2239 | |||
2240 | } | ||
2241 | |||
2242 | |||
2243 | /** | ||
2244 | * Get the connections to other nodes for a specific node. | ||
2245 | * | ||
2246 | * @param num The specific node we want the connections for. | ||
2247 | * @param topology The topology we get the connections from. | ||
2248 | * @return The connections of the node. | ||
2249 | */ | ||
2250 | struct GNUNET_TESTING_NodeConnection * | ||
2251 | GNUNET_TESTING_get_connections (unsigned int num, | ||
2252 | const struct | ||
2253 | GNUNET_TESTING_NetjailTopology *topology) | ||
2254 | { | ||
2255 | struct GNUNET_TESTING_NetjailNode *node; | ||
2256 | struct GNUNET_TESTING_NetjailNamespace *namespace; | ||
2257 | struct GNUNET_TESTING_NodeConnection *node_connections; | ||
2258 | |||
2259 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2260 | "get_connections\n"); | ||
2261 | |||
2262 | get_node_info (num, topology, &node, &namespace, &node_connections); | ||
2263 | |||
2264 | return node_connections; | ||
2265 | } | ||
2266 | |||
2267 | |||
2268 | /** | ||
2269 | * Retrieve the peer identity from the test system with the unique node id. | ||
2270 | * | ||
2271 | * @param num The unique node id. | ||
2272 | * @param tl_system The test system. | ||
2273 | * @return The peer identity wrapping the public key. | ||
2274 | */ | ||
2275 | struct GNUNET_PeerIdentity * | ||
2276 | GNUNET_TESTING_get_peer (unsigned int num, | ||
2277 | const struct GNUNET_TESTING_System *tl_system) | ||
2278 | { | ||
2279 | struct GNUNET_PeerIdentity *peer = GNUNET_new (struct GNUNET_PeerIdentity); | ||
2280 | struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key; | ||
2281 | |||
2282 | priv_key = GNUNET_TESTING_hostkey_get (tl_system, | ||
2283 | num, | ||
2284 | peer); | ||
2285 | |||
2286 | GNUNET_CRYPTO_eddsa_key_get_public (priv_key, | ||
2287 | &peer->public_key); | ||
2288 | GNUNET_free (priv_key); | ||
2289 | return peer; | ||
2290 | } | ||
2291 | |||
2292 | |||
2293 | int | ||
2294 | free_nodes_cb (void *cls, | ||
2295 | const struct GNUNET_ShortHashCode *key, | ||
2296 | void *value) | ||
2297 | { | ||
2298 | (void) cls; | ||
2299 | struct GNUNET_TESTING_NetjailNode *node = value; | ||
2300 | struct GNUNET_TESTING_NodeConnection *pos_connection; | ||
2301 | struct GNUNET_TESTING_AddressPrefix *pos_prefix; | ||
2302 | |||
2303 | while (NULL != (pos_connection = node->node_connections_head)) | ||
2304 | { | ||
2305 | while (NULL != (pos_prefix = pos_connection->address_prefixes_head)) | ||
2306 | { | ||
2307 | GNUNET_CONTAINER_DLL_remove (pos_connection->address_prefixes_head, | ||
2308 | pos_connection->address_prefixes_tail, | ||
2309 | pos_prefix); | ||
2310 | GNUNET_free (pos_prefix->address_prefix); | ||
2311 | GNUNET_free (pos_prefix); | ||
2312 | } | ||
2313 | GNUNET_CONTAINER_DLL_remove (node->node_connections_head, | ||
2314 | node->node_connections_tail, | ||
2315 | pos_connection); | ||
2316 | GNUNET_free (pos_connection); | ||
2317 | } | ||
2318 | |||
2319 | GNUNET_free (node->plugin); | ||
2320 | GNUNET_free (node); | ||
2321 | return GNUNET_OK; | ||
2322 | } | ||
2323 | |||
2324 | |||
2325 | int | ||
2326 | free_namespaces_cb (void *cls, | ||
2327 | const struct GNUNET_ShortHashCode *key, | ||
2328 | void *value) | ||
2329 | { | ||
2330 | (void) cls; | ||
2331 | struct GNUNET_TESTING_NetjailNamespace *namespace = value; | ||
2332 | |||
2333 | GNUNET_free (namespace->router); | ||
2334 | GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes, free_nodes_cb, | ||
2335 | namespace->nodes); | ||
2336 | return GNUNET_OK; | ||
2337 | |||
2338 | } | ||
2339 | |||
2340 | |||
2341 | /** | ||
2342 | * Deallocate memory of the struct GNUNET_TESTING_NetjailTopology. | ||
2343 | * | ||
2344 | * @param topology The GNUNET_TESTING_NetjailTopology to be deallocated. | ||
2345 | */ | ||
2346 | void | ||
2347 | GNUNET_TESTING_free_topology (struct GNUNET_TESTING_NetjailTopology *topology) | ||
2348 | { | ||
2349 | GNUNET_CONTAINER_multishortmap_iterate (topology->map_namespaces, | ||
2350 | free_namespaces_cb, NULL); | ||
2351 | GNUNET_CONTAINER_multishortmap_destroy (topology->map_namespaces); | ||
2352 | GNUNET_CONTAINER_multishortmap_iterate (topology->map_globals, free_nodes_cb, | ||
2353 | NULL); | ||
2354 | GNUNET_CONTAINER_multishortmap_destroy (topology->map_globals); | ||
2355 | GNUNET_free (topology->plugin); | ||
2356 | GNUNET_free (topology); | ||
2357 | } | ||
2358 | |||
2359 | |||
2360 | unsigned int | ||
2361 | GNUNET_TESTING_calculate_num ( | ||
2362 | struct GNUNET_TESTING_NodeConnection *node_connection, | ||
2363 | struct GNUNET_TESTING_NetjailTopology *topology) | ||
2364 | { | ||
2365 | unsigned int n, m, num; | ||
2366 | |||
2367 | n = node_connection->namespace_n; | ||
2368 | m = node_connection->node_n; | ||
2369 | |||
2370 | if (0 == n) | ||
2371 | num = m; | ||
2372 | else | ||
2373 | num = (n - 1) * topology->nodes_m + m + topology->nodes_x; | ||
2374 | |||
2375 | return num; | ||
2376 | } | ||
2377 | |||
2378 | |||
2379 | /** | ||
2380 | * Get the address for a specific communicator from a connection. | ||
2381 | * | ||
2382 | * @param connection The connection we like to have the address from. | ||
2383 | * @param prefix The communicator protocol prefix. | ||
2384 | * @return The address of the communicator. | ||
2385 | */ | ||
2386 | char * | ||
2387 | GNUNET_TESTING_get_address (struct GNUNET_TESTING_NodeConnection *connection, | ||
2388 | const char *prefix) | ||
2389 | { | ||
2390 | struct GNUNET_TESTING_NetjailNode *node; | ||
2391 | char *addr; | ||
2392 | char *template; | ||
2393 | unsigned int node_n; | ||
2394 | |||
2395 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2396 | "get address prefix: %s node_n: %u\n", | ||
2397 | prefix, | ||
2398 | connection->node_n); | ||
2399 | |||
2400 | node = connection->node; | ||
2401 | if (connection->namespace_n == node->namespace_n) | ||
2402 | { | ||
2403 | template = CONNECT_ADDRESS_TEMPLATE; | ||
2404 | node_n = connection->node_n; | ||
2405 | } | ||
2406 | else if (0 == connection->namespace_n) | ||
2407 | { | ||
2408 | template = KNOWN_CONNECT_ADDRESS_TEMPLATE; | ||
2409 | node_n = connection->node_n; | ||
2410 | } | ||
2411 | else if (1 == connection->node_n) | ||
2412 | { | ||
2413 | template = ROUTER_CONNECT_ADDRESS_TEMPLATE; | ||
2414 | node_n = connection->namespace_n; | ||
2415 | } | ||
2416 | else | ||
2417 | { | ||
2418 | return NULL; | ||
2419 | } | ||
2420 | |||
2421 | if (0 == strcmp (PREFIX_TCP, prefix) || | ||
2422 | 0 == strcmp (PREFIX_UDP, prefix) || | ||
2423 | 0 == strcmp (PREFIX_UDP_NATTED, prefix) || | ||
2424 | 0 == strcmp (PREFIX_TCP_NATTED, prefix)) | ||
2425 | { | ||
2426 | GNUNET_asprintf (&addr, | ||
2427 | template, | ||
2428 | prefix, | ||
2429 | node_n); | ||
2430 | } | ||
2431 | else | ||
2432 | { | ||
2433 | GNUNET_assert (0); | ||
2434 | } | ||
2435 | |||
2436 | return addr; | ||
2437 | } | ||
2438 | |||
2439 | |||
2440 | /** | ||
2441 | * Get the number of unintentional additional connections the node waits for. | ||
2442 | * | ||
2443 | * @param num The specific node we want the additional connects for. | ||
2444 | * @return The number of additional connects | ||
2445 | */ | ||
2446 | unsigned int | ||
2447 | GNUNET_TESTING_get_additional_connects (unsigned int num, | ||
2448 | struct GNUNET_TESTING_NetjailTopology * | ||
2449 | topology) | ||
2450 | { | ||
2451 | struct GNUNET_TESTING_NetjailNode *node; | ||
2452 | struct GNUNET_TESTING_NetjailNamespace *namespace; | ||
2453 | struct GNUNET_TESTING_NodeConnection *node_connections; | ||
2454 | |||
2455 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2456 | "get_additional_connects\n"); | ||
2457 | |||
2458 | get_node_info (num, topology, &node, &namespace, &node_connections); | ||
2459 | |||
2460 | if (NULL == node) | ||
2461 | { | ||
2462 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2463 | "No info found for node %d\n", num); | ||
2464 | return 0; | ||
2465 | } | ||
2466 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2467 | "node additional_connects for node %p\n", | ||
2468 | node); | ||
2469 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2470 | "node additional_connects: %u\n", | ||
2471 | node->additional_connects); | ||
2472 | |||
2473 | return node->additional_connects; | ||
2474 | } | ||
2475 | |||
2476 | |||
2477 | static void | ||
2478 | parse_ac (struct GNUNET_TESTING_NetjailNode *p_node, const char *token) | ||
2479 | { | ||
2480 | char *ac_value; | ||
2481 | int ret; | ||
2482 | |||
2483 | ac_value = get_value ("AC", token); | ||
2484 | if (NULL != ac_value) | ||
2485 | { | ||
2486 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2487 | "ac value: %s\n", | ||
2488 | ac_value); | ||
2489 | errno = 0; | ||
2490 | ret = sscanf (ac_value, "%u", &p_node->additional_connects); | ||
2491 | if (errno != 0) | ||
2492 | { | ||
2493 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sscanf"); | ||
2494 | } | ||
2495 | GNUNET_assert (0 < ret); | ||
2496 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2497 | "AC %u\n", | ||
2498 | p_node->additional_connects); | ||
2499 | } | ||
2500 | else | ||
2501 | { | ||
2502 | p_node->additional_connects = 0; | ||
2503 | } | ||
2504 | GNUNET_free (ac_value); | ||
2505 | } | ||
2506 | |||
2507 | |||
2508 | /** | ||
2509 | * Parse the topology data. | ||
2510 | * | ||
2511 | * @param data The topology data. | ||
2512 | * @return The GNUNET_TESTING_NetjailTopology | ||
2513 | */ | ||
2514 | struct GNUNET_TESTING_NetjailTopology * | ||
2515 | GNUNET_TESTING_get_topo_from_string (const char *input) | ||
2516 | { | ||
2517 | char *token; | ||
2518 | char *key = NULL; | ||
2519 | unsigned int out; | ||
2520 | char *rest = NULL; | ||
2521 | char *value = NULL; | ||
2522 | char *value2; | ||
2523 | char *data; | ||
2524 | int ret; | ||
2525 | struct GNUNET_TESTING_NetjailTopology *topo; | ||
2526 | struct GNUNET_TESTING_NetjailRouter *router; | ||
2527 | struct GNUNET_TESTING_NetjailNamespace *namespace; | ||
2528 | struct GNUNET_HashCode hc; | ||
2529 | |||
2530 | data = GNUNET_strdup (input); | ||
2531 | token = strtok_r (data, "\n", &rest); | ||
2532 | topo = GNUNET_new (struct GNUNET_TESTING_NetjailTopology); | ||
2533 | topo->map_namespaces = | ||
2534 | GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO); | ||
2535 | topo->map_globals = | ||
2536 | GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO); | ||
2537 | |||
2538 | while (NULL != token) | ||
2539 | { | ||
2540 | if (NULL != key) | ||
2541 | GNUNET_free (key); | ||
2542 | key = get_key (token); | ||
2543 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2544 | "In the loop with token: %s beginning with %s\n", | ||
2545 | token, | ||
2546 | key); | ||
2547 | if (0 == strcmp (key, "M")) | ||
2548 | { | ||
2549 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2550 | "Get first Value for M.\n"); | ||
2551 | out = get_first_value (token); | ||
2552 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2553 | "M: %u\n", | ||
2554 | out); | ||
2555 | topo->nodes_m = out; | ||
2556 | } | ||
2557 | else if (0 == strcmp (key, "N")) | ||
2558 | { | ||
2559 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2560 | "Get first Value for N.\n"); | ||
2561 | out = get_first_value (token); | ||
2562 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2563 | "N: %u\n", | ||
2564 | out); | ||
2565 | topo->namespaces_n = out; | ||
2566 | } | ||
2567 | else if (0 == strcmp (key, "X")) | ||
2568 | { | ||
2569 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2570 | "Get first Value for X.\n"); | ||
2571 | out = get_first_value (token); | ||
2572 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2573 | "X: %u\n", | ||
2574 | out); | ||
2575 | topo->nodes_x = out; | ||
2576 | } | ||
2577 | else if (0 == strcmp (key, "AC")) | ||
2578 | { | ||
2579 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2580 | "Get first Value for AC.\n"); | ||
2581 | out = get_first_value (token); | ||
2582 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2583 | "AC: %u\n", | ||
2584 | out); | ||
2585 | topo->additional_connects = out; | ||
2586 | } | ||
2587 | else if (0 == strcmp (key, "T")) | ||
2588 | { | ||
2589 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2590 | "Get first string value for T.\n"); | ||
2591 | value = get_first_string_value (token); | ||
2592 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2593 | "value: %s\n", | ||
2594 | value); | ||
2595 | topo->plugin = value; | ||
2596 | } | ||
2597 | else if (0 == strcmp (key, "K")) | ||
2598 | { | ||
2599 | struct GNUNET_ShortHashCode hkey_k; | ||
2600 | struct GNUNET_TESTING_NetjailNode *k_node = GNUNET_new (struct | ||
2601 | GNUNET_TESTING_NetjailNode); | ||
2602 | |||
2603 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2604 | "Get first Value for K.\n"); | ||
2605 | out = get_first_value (token); | ||
2606 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2607 | "K: %u\n", | ||
2608 | out); | ||
2609 | k_node->node_n = out; | ||
2610 | GNUNET_CRYPTO_hash (&out, sizeof(out), &hc); | ||
2611 | memcpy (&hkey_k, | ||
2612 | &hc, | ||
2613 | sizeof (hkey_k)); | ||
2614 | k_node->is_global = GNUNET_YES; | ||
2615 | |||
2616 | if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains ( | ||
2617 | topo->map_globals, | ||
2618 | &hkey_k)) | ||
2619 | GNUNET_break (0); | ||
2620 | else | ||
2621 | GNUNET_CONTAINER_multishortmap_put (topo->map_globals, | ||
2622 | &hkey_k, | ||
2623 | k_node, | ||
2624 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
2625 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2626 | "Get value for key value on K.\n"); | ||
2627 | value = get_value ("plugin", token); | ||
2628 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2629 | "value: %s\n", | ||
2630 | value); | ||
2631 | k_node->plugin = value; | ||
2632 | parse_ac (k_node, token); | ||
2633 | node_connections (token, k_node); | ||
2634 | GNUNET_free (value); | ||
2635 | } | ||
2636 | else if (0 == strcmp (key, "R")) | ||
2637 | { | ||
2638 | struct GNUNET_ShortHashCode hkey_r; | ||
2639 | router = GNUNET_new (struct GNUNET_TESTING_NetjailRouter); | ||
2640 | |||
2641 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2642 | "Get first Value for R.\n"); | ||
2643 | out = get_first_value (token); | ||
2644 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2645 | "R: %u\n", | ||
2646 | out); | ||
2647 | GNUNET_CRYPTO_hash (&out, sizeof(out), &hc); | ||
2648 | memcpy (&hkey_r, | ||
2649 | &hc, | ||
2650 | sizeof (hkey_r)); | ||
2651 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2652 | "Get value for key tcp_port on R.\n"); | ||
2653 | value = get_value ("tcp_port", token); | ||
2654 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2655 | "tcp_port: %s\n", | ||
2656 | value); | ||
2657 | ret = sscanf (value, "%u", &(router->tcp_port)); | ||
2658 | GNUNET_free (value); | ||
2659 | GNUNET_break (0 != ret && 1 >= router->tcp_port); | ||
2660 | |||
2661 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2662 | "Get value for key udp_port on R.\n"); | ||
2663 | value2 = get_value ("udp_port", token); | ||
2664 | ret = sscanf (value2, "%u", &(router->udp_port)); | ||
2665 | GNUNET_free (value2); | ||
2666 | GNUNET_break (0 != ret && 1 >= router->udp_port); | ||
2667 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2668 | "udp_port: %s\n", | ||
2669 | value2); | ||
2670 | GNUNET_free (value2); | ||
2671 | if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains ( | ||
2672 | topo->map_namespaces, | ||
2673 | &hkey_r)) | ||
2674 | { | ||
2675 | namespace = GNUNET_CONTAINER_multishortmap_get (topo->map_namespaces, | ||
2676 | &hkey_r); | ||
2677 | } | ||
2678 | else | ||
2679 | { | ||
2680 | namespace = GNUNET_new (struct GNUNET_TESTING_NetjailNamespace); | ||
2681 | namespace->namespace_n = out; | ||
2682 | namespace->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO); | ||
2683 | GNUNET_CONTAINER_multishortmap_put (topo->map_namespaces, | ||
2684 | &hkey_r, | ||
2685 | namespace, | ||
2686 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
2687 | } | ||
2688 | namespace->router = router; | ||
2689 | |||
2690 | } | ||
2691 | else if (0 == strcmp (key, "P")) | ||
2692 | { | ||
2693 | struct GNUNET_TESTING_NetjailNode *p_node = GNUNET_new (struct | ||
2694 | GNUNET_TESTING_NetjailNode); | ||
2695 | struct GNUNET_ShortHashCode hkey_p; | ||
2696 | |||
2697 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2698 | "Get first Value for P.\n"); | ||
2699 | out = get_first_value (token); | ||
2700 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2701 | "P: %u\n", | ||
2702 | out); | ||
2703 | GNUNET_CRYPTO_hash (&out, sizeof(out), &hc); | ||
2704 | memcpy (&hkey_p, | ||
2705 | &hc, | ||
2706 | sizeof (hkey_p)); | ||
2707 | |||
2708 | if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains ( | ||
2709 | topo->map_namespaces, | ||
2710 | &hkey_p)) | ||
2711 | { | ||
2712 | namespace = GNUNET_CONTAINER_multishortmap_get (topo->map_namespaces, | ||
2713 | &hkey_p); | ||
2714 | } | ||
2715 | else | ||
2716 | { | ||
2717 | namespace = GNUNET_new (struct GNUNET_TESTING_NetjailNamespace); | ||
2718 | namespace->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO); | ||
2719 | namespace->namespace_n = out; | ||
2720 | GNUNET_CONTAINER_multishortmap_put (topo->map_namespaces, | ||
2721 | &hkey_p, | ||
2722 | namespace, | ||
2723 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
2724 | } | ||
2725 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2726 | "Get second Value for P.\n"); | ||
2727 | out = get_second_value (token); | ||
2728 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2729 | "P: %u\n", | ||
2730 | out); | ||
2731 | GNUNET_CRYPTO_hash (&out, sizeof(out), &hc); | ||
2732 | memcpy (&hkey_p, | ||
2733 | &hc, | ||
2734 | sizeof (hkey_p)); | ||
2735 | if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains ( | ||
2736 | namespace->nodes, | ||
2737 | &hkey_p)) | ||
2738 | { | ||
2739 | GNUNET_break (0); | ||
2740 | } | ||
2741 | else | ||
2742 | { | ||
2743 | |||
2744 | GNUNET_CONTAINER_multishortmap_put (namespace->nodes, | ||
2745 | &hkey_p, | ||
2746 | p_node, | ||
2747 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
2748 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2749 | "Get value for key plugin on P.\n"); | ||
2750 | value = get_value ("plugin", token); | ||
2751 | if (NULL != value) | ||
2752 | { | ||
2753 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2754 | "plugin: %s\n", | ||
2755 | value); | ||
2756 | p_node->plugin = value; | ||
2757 | } | ||
2758 | p_node->node_n = out; | ||
2759 | p_node->namespace_n = namespace->namespace_n; | ||
2760 | } | ||
2761 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2762 | "Get AC Value for P.\n"); | ||
2763 | parse_ac (p_node, token); | ||
2764 | node_connections (token, p_node); | ||
2765 | } | ||
2766 | token = strtok_r (NULL, "\n", &rest); | ||
2767 | if (NULL != token) | ||
2768 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2769 | "Next token %s\n", | ||
2770 | token); | ||
2771 | } | ||
2772 | if (NULL != key) | ||
2773 | GNUNET_free (key); | ||
2774 | GNUNET_free (data); | ||
2775 | return topo; | ||
2776 | } | ||
2777 | |||
2778 | |||
2779 | /** | ||
2780 | * Getting the topology from file. | ||
2781 | * | ||
2782 | * @param filename The name of the topology file. | ||
2783 | * @return The GNUNET_TESTING_NetjailTopology | ||
2784 | */ | ||
2785 | struct GNUNET_TESTING_NetjailTopology * | ||
2786 | GNUNET_TESTING_get_topo_from_file (const char *filename) | ||
2787 | { | ||
2788 | uint64_t fs; | ||
2789 | char *data; | ||
2790 | struct GNUNET_TESTING_NetjailTopology *topo; | ||
2791 | |||
2792 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
2793 | { | ||
2794 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
2795 | _ ("Topology file %s not found\n"), | ||
2796 | filename); | ||
2797 | return NULL; | ||
2798 | } | ||
2799 | if (GNUNET_OK != | ||
2800 | GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) | ||
2801 | { | ||
2802 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
2803 | _ ("Topology file %s has no data\n"), | ||
2804 | filename); | ||
2805 | return NULL; | ||
2806 | } | ||
2807 | data = GNUNET_malloc (fs + 1); | ||
2808 | if (fs != GNUNET_DISK_fn_read (filename, data, fs)) | ||
2809 | { | ||
2810 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
2811 | _ ("Topology file %s cannot be read\n"), | ||
2812 | filename); | ||
2813 | GNUNET_free (data); | ||
2814 | return NULL; | ||
2815 | } | ||
2816 | |||
2817 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2818 | "file length %" PRIu64 "\n", | ||
2819 | fs); | ||
2820 | data[fs] = '\0'; | ||
2821 | |||
2822 | topo = GNUNET_TESTING_get_topo_from_string (data); | ||
2823 | |||
2824 | GNUNET_free (data); | ||
2825 | |||
2826 | return topo; | ||
2827 | } | ||
2828 | |||
2829 | |||
2830 | /* end of testing.c */ | ||
diff --git a/src/service/testing/testing.h b/src/service/testing/testing.h deleted file mode 100644 index 43c8ad45a..000000000 --- a/src/service/testing/testing.h +++ /dev/null | |||
@@ -1,339 +0,0 @@ | |||
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 | * @author t3sserakt | ||
23 | */ | ||
24 | #ifndef TESTING_H | ||
25 | #define TESTING_H | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include "gnunet_testing_plugin.h" | ||
28 | |||
29 | GNUNET_NETWORK_STRUCT_BEGIN | ||
30 | |||
31 | /** | ||
32 | * Message send to a child loop to inform the child loop about a barrier being advanced. | ||
33 | */ | ||
34 | struct CommandBarrierCrossable | ||
35 | { | ||
36 | /** | ||
37 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_CROSSABLE | ||
38 | */ | ||
39 | struct GNUNET_MessageHeader header; | ||
40 | |||
41 | /* followed by 0-terminated barrier name */ | ||
42 | }; | ||
43 | |||
44 | /** | ||
45 | * Message send by a child loop to inform the master loop how much | ||
46 | * GNUNET_CMDS_BARRIER_REACHED messages the child will send. | ||
47 | */ | ||
48 | struct CommandBarrierAttached | ||
49 | { | ||
50 | /** | ||
51 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ATTACHED | ||
52 | */ | ||
53 | struct GNUNET_MessageHeader header; | ||
54 | |||
55 | /** | ||
56 | * How often the child loop will reach the barrier. | ||
57 | */ | ||
58 | uint32_t expected_reaches GNUNET_PACKED; | ||
59 | |||
60 | /** | ||
61 | * The number of the node the barrier is running on. | ||
62 | */ | ||
63 | uint32_t node_number GNUNET_PACKED; | ||
64 | |||
65 | /* followed by 0-terminated barrier name */ | ||
66 | }; | ||
67 | |||
68 | struct GNUNET_TESTING_CommandBarrierReached | ||
69 | { | ||
70 | /** | ||
71 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_REACHED | ||
72 | */ | ||
73 | struct GNUNET_MessageHeader header; | ||
74 | |||
75 | /** | ||
76 | * The number of the node the barrier is reached. | ||
77 | */ | ||
78 | uint32_t node_number GNUNET_PACKED; | ||
79 | |||
80 | /** | ||
81 | * The number of reach messages which most likely will send. | ||
82 | */ | ||
83 | uint32_t expected_number_of_reached_messages GNUNET_PACKED; | ||
84 | |||
85 | /* followed by 0-terminated barrier name */ | ||
86 | }; | ||
87 | |||
88 | GNUNET_NETWORK_STRUCT_END | ||
89 | |||
90 | /** | ||
91 | * Handle for a plugin. | ||
92 | */ | ||
93 | struct TestcasePlugin | ||
94 | { | ||
95 | /** | ||
96 | * Name of the shared library. | ||
97 | */ | ||
98 | char *library_name; | ||
99 | |||
100 | /** | ||
101 | * Plugin API. | ||
102 | */ | ||
103 | struct GNUNET_TESTING_PluginFunctions *api; | ||
104 | |||
105 | /** | ||
106 | * IP address of the specific node the helper is running for. | ||
107 | * | ||
108 | */ | ||
109 | char *node_ip; | ||
110 | |||
111 | /** | ||
112 | * Name of the test case plugin. | ||
113 | * | ||
114 | */ | ||
115 | char *plugin_name; | ||
116 | |||
117 | /** | ||
118 | * The number of namespaces | ||
119 | * | ||
120 | */ | ||
121 | char *global_n; | ||
122 | |||
123 | /** | ||
124 | * The number of local nodes per namespace. | ||
125 | * | ||
126 | */ | ||
127 | char *local_m; | ||
128 | |||
129 | /** | ||
130 | * The number of the namespace this node is in. | ||
131 | * | ||
132 | */ | ||
133 | char *n; | ||
134 | |||
135 | /** | ||
136 | * The number of the node in the namespace. | ||
137 | * | ||
138 | */ | ||
139 | char *m; | ||
140 | }; | ||
141 | |||
142 | struct CommandListEntry | ||
143 | { | ||
144 | struct CommandListEntry *next; | ||
145 | |||
146 | struct CommandListEntry *prev; | ||
147 | |||
148 | struct GNUNET_TESTING_Command *command; | ||
149 | }; | ||
150 | |||
151 | |||
152 | struct GNUNET_TESTING_Barrier | ||
153 | { | ||
154 | /** | ||
155 | * Pointer to the previous prefix in the DLL. | ||
156 | */ | ||
157 | struct GNUNET_TESTING_Barrier *prev; | ||
158 | |||
159 | /** | ||
160 | * Pointer to the next prefix in the DLL. | ||
161 | */ | ||
162 | struct GNUNET_TESTING_Barrier *next; | ||
163 | |||
164 | /** | ||
165 | * Head of the DLL with local commands the barrier is attached too. | ||
166 | */ | ||
167 | struct CommandListEntry *cmds_head; | ||
168 | |||
169 | /** | ||
170 | * Tail of the DLL with local commands the barrier is attached too. | ||
171 | */ | ||
172 | struct CommandListEntry *cmds_tail; | ||
173 | |||
174 | /** | ||
175 | * Hash map containing the global known nodes which are not natted. | ||
176 | */ | ||
177 | struct GNUNET_CONTAINER_MultiShortmap *nodes; | ||
178 | |||
179 | /** | ||
180 | * Name of the barrier. | ||
181 | */ | ||
182 | const char *name; | ||
183 | |||
184 | /** | ||
185 | * Is this barrier running on the master. | ||
186 | */ | ||
187 | unsigned int running_on_master; | ||
188 | |||
189 | /** | ||
190 | * Number of commands attached to this barrier. | ||
191 | */ | ||
192 | unsigned int expected_reaches; | ||
193 | |||
194 | /** | ||
195 | * Number of commands which reached this barrier. | ||
196 | */ | ||
197 | unsigned int reached; | ||
198 | |||
199 | /** | ||
200 | * Percentage of of commands which need to reach the barrier to change state. | ||
201 | * Can not be used together with to_be_reached; | ||
202 | */ | ||
203 | double percentage_to_be_reached; | ||
204 | |||
205 | /** | ||
206 | * Number of commands which need to reach the barrier to change state. | ||
207 | * Can not be used together with percentage_to_be_reached; | ||
208 | */ | ||
209 | unsigned int number_to_be_reached; | ||
210 | |||
211 | /* | ||
212 | * No barrier locally. Shadow created. Real barrier created elsewhere. | ||
213 | */ | ||
214 | unsigned int shadow; | ||
215 | }; | ||
216 | |||
217 | |||
218 | /** | ||
219 | * Advance internal pointer to next command. | ||
220 | * | ||
221 | * @param cls batch internal state | ||
222 | * @return true if we could advance, false if the batch | ||
223 | * has completed and cannot advance anymore | ||
224 | */ | ||
225 | bool | ||
226 | GNUNET_TESTING_cmd_batch_next_ (void *cls); | ||
227 | |||
228 | |||
229 | /** | ||
230 | * Test if this command is a batch command. | ||
231 | * | ||
232 | * @return false if not, true if it is a batch command | ||
233 | */ | ||
234 | bool | ||
235 | GNUNET_TESTING_cmd_is_batch_ (const struct GNUNET_TESTING_Command *cmd); | ||
236 | |||
237 | |||
238 | /** | ||
239 | * Obtain what command the batch is at. | ||
240 | * | ||
241 | * @return cmd current batch command | ||
242 | */ | ||
243 | struct GNUNET_TESTING_Command * | ||
244 | GNUNET_TESTING_cmd_batch_get_current_ (const struct GNUNET_TESTING_Command *cmd); | ||
245 | |||
246 | |||
247 | /** | ||
248 | * Set what command the batch should be at. Needed for | ||
249 | * loops. We may want to change this to take a label | ||
250 | * and/or expose it in the public API in the future. | ||
251 | * Not used for now. | ||
252 | * | ||
253 | * @param cmd current batch command | ||
254 | * @param new_ip where to move the IP | ||
255 | */ | ||
256 | void | ||
257 | GNUNET_TESTING_cmd_batch_set_current_ (const struct GNUNET_TESTING_Command *cmd, | ||
258 | unsigned int new_ip); | ||
259 | |||
260 | |||
261 | /** | ||
262 | * This function checks, if a barrier can be crossed, which actually means that | ||
263 | * the cmd representing the barrier is finished. | ||
264 | * | ||
265 | * @param barrier The barrier in question. | ||
266 | * @return true if we can cross the barrier, false if not. | ||
267 | */ | ||
268 | bool | ||
269 | GNUNET_TESTING_barrier_crossable_ (struct GNUNET_TESTING_Barrier *barrier); | ||
270 | |||
271 | |||
272 | /** | ||
273 | * Finish all "barrier reached" commands attached to this barrier. | ||
274 | * | ||
275 | * @param barrier The barrier in question. | ||
276 | */ | ||
277 | void | ||
278 | GNUNET_TESTING_finish_barrier_ (struct GNUNET_TESTING_Interpreter *is, | ||
279 | const char *barrier_name); | ||
280 | |||
281 | |||
282 | /** | ||
283 | * Send message to master loop that cmds being attached to a barrier. | ||
284 | * FIXME: Unused function | ||
285 | * | ||
286 | * @param is The interpreter loop. | ||
287 | * @param barrier_name The name of the barrier to attach to. | ||
288 | * @param subnet_number The number of the subnet. | ||
289 | * @param node_number The node to inform. | ||
290 | * @param write_message Callback to write messages to the master loop. | ||
291 | */ | ||
292 | void | ||
293 | GNUNET_TESTING_send_barrier_attach_ (struct GNUNET_TESTING_Interpreter *is, | ||
294 | const char *barrier_name, | ||
295 | unsigned int global_node_number, | ||
296 | unsigned int expected_reaches, | ||
297 | GNUNET_TESTING_cmd_helper_write_cb write_message); | ||
298 | |||
299 | |||
300 | /** | ||
301 | * Getting a node from a map by global node number. | ||
302 | * FIXME: This is a barrier helper function not related to a command but it is | ||
303 | * implemented in the *_cmd_barrier.c file. | ||
304 | * Maybe move into a separate file like testing_barrier.c; see also can | ||
305 | * barrier advance above | ||
306 | * | ||
307 | * @param nodes The map. | ||
308 | * @param node_number The global node number. | ||
309 | * @return The node. | ||
310 | */ | ||
311 | struct GNUNET_TESTING_NetjailNode * | ||
312 | GNUNET_TESTING_barrier_get_node (struct GNUNET_TESTING_Barrier *barrier, | ||
313 | unsigned int node_number); | ||
314 | |||
315 | |||
316 | /** | ||
317 | * Getting a barrier from the interpreter. | ||
318 | * | ||
319 | * @param is The interpreter. | ||
320 | * @param barrier_name The name of the barrier. | ||
321 | * @return The barrier. | ||
322 | */ | ||
323 | struct GNUNET_TESTING_Barrier * | ||
324 | GNUNET_TESTING_get_barrier_ (struct GNUNET_TESTING_Interpreter *is, | ||
325 | const char *barrier_name); | ||
326 | |||
327 | |||
328 | /** | ||
329 | * Add a barrier to the loop. | ||
330 | * | ||
331 | * @param is The interpreter. | ||
332 | * @param barrier The barrier to add. | ||
333 | */ | ||
334 | void | ||
335 | GNUNET_TESTING_add_barrier_ (struct GNUNET_TESTING_Interpreter *is, | ||
336 | struct GNUNET_TESTING_Barrier *barrier); | ||
337 | |||
338 | |||
339 | #endif | ||
diff --git a/src/service/testing/testing_api_cmd_barrier.c b/src/service/testing/testing_api_cmd_barrier.c deleted file mode 100644 index ee074f35b..000000000 --- a/src/service/testing/testing_api_cmd_barrier.c +++ /dev/null | |||
@@ -1,206 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2022 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_barrier.c | ||
23 | * @brief Barrier functionality. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "testing.h" | ||
28 | #include "gnunet_testing_ng_lib.h" | ||
29 | #include "gnunet_testing_plugin.h" | ||
30 | #include "gnunet_testing_netjail_lib.h" | ||
31 | #include "gnunet_testing_barrier.h" | ||
32 | |||
33 | /** | ||
34 | * Generic logging shortcut | ||
35 | */ | ||
36 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | ||
37 | |||
38 | |||
39 | struct BarrierState | ||
40 | { | ||
41 | /** | ||
42 | * Our barrier, set to NULL once the barrier is active. | ||
43 | */ | ||
44 | struct GNUNET_TESTING_Barrier *barrier; | ||
45 | |||
46 | /** | ||
47 | * Our label. | ||
48 | */ | ||
49 | const char *label; | ||
50 | }; | ||
51 | |||
52 | |||
53 | // FIXME Unused function | ||
54 | void | ||
55 | GNUNET_TESTING_send_barrier_attach_ ( | ||
56 | struct GNUNET_TESTING_Interpreter *is, | ||
57 | const char *barrier_name, | ||
58 | unsigned int global_node_number, | ||
59 | unsigned int expected_reaches, | ||
60 | GNUNET_TESTING_cmd_helper_write_cb write_message) | ||
61 | { | ||
62 | // FIXME: avoid useless malloc! | ||
63 | struct CommandBarrierAttached *atm = GNUNET_new (struct | ||
64 | CommandBarrierAttached); | ||
65 | size_t msg_length = sizeof(struct CommandBarrierAttached); | ||
66 | size_t name_len; | ||
67 | |||
68 | name_len = strlen (barrier_name) + 1; | ||
69 | atm->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ATTACHED); | ||
70 | atm->header.size = htons ((uint16_t) msg_length); | ||
71 | atm->expected_reaches = expected_reaches; | ||
72 | atm->node_number = global_node_number; | ||
73 | memcpy (&atm[1], barrier_name, name_len); | ||
74 | write_message ((struct GNUNET_MessageHeader *) atm, msg_length); | ||
75 | |||
76 | GNUNET_free (atm); | ||
77 | } | ||
78 | |||
79 | |||
80 | bool | ||
81 | GNUNET_TESTING_barrier_crossable_ (struct GNUNET_TESTING_Barrier *barrier) | ||
82 | { | ||
83 | unsigned int expected_reaches = barrier->expected_reaches; | ||
84 | unsigned int reached = barrier->reached; | ||
85 | double percentage_to_be_reached = barrier->percentage_to_be_reached; | ||
86 | unsigned int number_to_be_reached = barrier->number_to_be_reached; | ||
87 | double percentage_reached = (double) reached / expected_reaches * 100; | ||
88 | |||
89 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
90 | "%u %f %f %u %u\n", | ||
91 | expected_reaches, | ||
92 | percentage_to_be_reached, | ||
93 | percentage_reached, | ||
94 | number_to_be_reached, | ||
95 | reached); | ||
96 | |||
97 | return ( ( (0 < percentage_to_be_reached) && | ||
98 | (percentage_reached >= percentage_to_be_reached) ) || | ||
99 | ( (0 < number_to_be_reached) && | ||
100 | (reached >= number_to_be_reached) ) ); | ||
101 | } | ||
102 | |||
103 | |||
104 | /** | ||
105 | * Offer internal data from a "barrier" CMD, to other commands. | ||
106 | * | ||
107 | * @param cls closure. | ||
108 | * @param[out] ret result. | ||
109 | * @param trait name of the trait. | ||
110 | * @param index index number of the object to offer. | ||
111 | * @return #GNUNET_OK on success. | ||
112 | */ | ||
113 | static enum GNUNET_GenericReturnValue | ||
114 | barrier_traits (void *cls, | ||
115 | const void **ret, | ||
116 | const char *trait, | ||
117 | unsigned int index) | ||
118 | { | ||
119 | struct GNUNET_TESTING_Trait traits[] = { | ||
120 | GNUNET_TESTING_trait_end () | ||
121 | }; | ||
122 | |||
123 | return GNUNET_TESTING_get_trait (traits, | ||
124 | ret, | ||
125 | trait, | ||
126 | index); | ||
127 | } | ||
128 | |||
129 | |||
130 | /** | ||
131 | * Cleanup the state from a "barrier" CMD, and possibly | ||
132 | * cancel a pending operation thereof. | ||
133 | * | ||
134 | * @param cls closure. | ||
135 | */ | ||
136 | static void | ||
137 | barrier_cleanup (void *cls) | ||
138 | { | ||
139 | struct BarrierState *brs = cls; | ||
140 | |||
141 | GNUNET_free (brs->barrier); | ||
142 | GNUNET_free (brs); | ||
143 | } | ||
144 | |||
145 | |||
146 | /** | ||
147 | * Run the command. | ||
148 | * | ||
149 | * @param cls closure. | ||
150 | * @param is the interpreter state. | ||
151 | */ | ||
152 | static void | ||
153 | barrier_run (void *cls, | ||
154 | struct GNUNET_TESTING_Interpreter *is) | ||
155 | { | ||
156 | struct BarrierState *brs = cls; | ||
157 | |||
158 | GNUNET_TESTING_add_barrier_ (is, | ||
159 | brs->barrier); | ||
160 | brs->barrier = NULL; | ||
161 | } | ||
162 | |||
163 | |||
164 | struct GNUNET_TESTING_NetjailNode * | ||
165 | GNUNET_TESTING_barrier_get_node (struct GNUNET_TESTING_Barrier *barrier, | ||
166 | unsigned int node_number) | ||
167 | { | ||
168 | struct GNUNET_HashCode hc; | ||
169 | struct GNUNET_ShortHashCode key; | ||
170 | |||
171 | GNUNET_CRYPTO_hash (&node_number, | ||
172 | sizeof(node_number), | ||
173 | &hc); | ||
174 | memcpy (&key, | ||
175 | &hc, | ||
176 | sizeof (key)); | ||
177 | return GNUNET_CONTAINER_multishortmap_get (barrier->nodes, | ||
178 | &key); | ||
179 | } | ||
180 | |||
181 | |||
182 | struct GNUNET_TESTING_Command | ||
183 | GNUNET_TESTING_cmd_barrier_create (const char *label, | ||
184 | double percentage_to_be_reached, | ||
185 | unsigned int number_to_be_reached) | ||
186 | { | ||
187 | struct GNUNET_TESTING_Barrier *barrier; | ||
188 | struct BarrierState *bs; | ||
189 | |||
190 | bs = GNUNET_new (struct BarrierState); | ||
191 | bs->label = label; | ||
192 | barrier = GNUNET_new (struct GNUNET_TESTING_Barrier); | ||
193 | barrier->name = label; | ||
194 | barrier->percentage_to_be_reached = percentage_to_be_reached; | ||
195 | barrier->number_to_be_reached = number_to_be_reached; | ||
196 | GNUNET_assert ((0 < percentage_to_be_reached && | ||
197 | 0 == number_to_be_reached) || | ||
198 | (0 == percentage_to_be_reached && | ||
199 | 0 < number_to_be_reached)); | ||
200 | bs->barrier = barrier; | ||
201 | return GNUNET_TESTING_command_new (bs, label, | ||
202 | &barrier_run, | ||
203 | &barrier_cleanup, | ||
204 | &barrier_traits, | ||
205 | NULL); | ||
206 | } | ||
diff --git a/src/service/testing/testing_api_cmd_barrier_reached.c b/src/service/testing/testing_api_cmd_barrier_reached.c deleted file mode 100644 index 54a36b91c..000000000 --- a/src/service/testing/testing_api_cmd_barrier_reached.c +++ /dev/null | |||
@@ -1,229 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2022 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_barrier_reached.c | ||
23 | * @brief Command to signal barrier was reached. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_testing_lib.h" | ||
28 | #include "testing_cmds.h" | ||
29 | #include "gnunet_testing_plugin.h" | ||
30 | #include "gnunet_testing_barrier.h" | ||
31 | #include "gnunet_testing_netjail_lib.h" | ||
32 | #include "testing.h" | ||
33 | |||
34 | /** | ||
35 | * Generic logging shortcut | ||
36 | */ | ||
37 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | ||
38 | |||
39 | /** | ||
40 | * Struct with information for callbacks. | ||
41 | * | ||
42 | */ | ||
43 | struct BarrierReachedState | ||
44 | { | ||
45 | /** | ||
46 | * Callback to write messages to the master loop. | ||
47 | * | ||
48 | */ | ||
49 | GNUNET_TESTING_cmd_helper_write_cb write_message; | ||
50 | |||
51 | /** | ||
52 | * Context for our asynchronous completion. | ||
53 | */ | ||
54 | struct GNUNET_TESTING_AsyncContext ac; | ||
55 | |||
56 | /** | ||
57 | * The label of this command. | ||
58 | */ | ||
59 | const char *label; | ||
60 | |||
61 | /** | ||
62 | * The name of the barrier this commands wait (if finishing asynchronous) for or/and reaches. | ||
63 | */ | ||
64 | const char *barrier_name; | ||
65 | |||
66 | /* | ||
67 | * The global numer of the node the cmd runs on. | ||
68 | */ | ||
69 | unsigned int node_number; | ||
70 | |||
71 | /** | ||
72 | * If this command will block. | ||
73 | */ | ||
74 | unsigned int asynchronous_finish; | ||
75 | |||
76 | /** | ||
77 | * Is this cmd running on the master loop. | ||
78 | */ | ||
79 | unsigned int running_on_master; | ||
80 | }; | ||
81 | |||
82 | |||
83 | /** | ||
84 | * Run the command. | ||
85 | * | ||
86 | * @param cls closure. | ||
87 | * @param is the interpreter state. | ||
88 | */ | ||
89 | static void | ||
90 | barrier_reached_run (void *cls, | ||
91 | struct GNUNET_TESTING_Interpreter *is) | ||
92 | { | ||
93 | struct BarrierReachedState *brs = cls; | ||
94 | struct GNUNET_TESTING_Barrier *barrier; | ||
95 | struct GNUNET_TESTING_Command *cmd = | ||
96 | GNUNET_TESTING_interpreter_get_current_command (is); | ||
97 | struct CommandListEntry *cle; | ||
98 | size_t msg_length; | ||
99 | struct GNUNET_TESTING_CommandBarrierReached *msg; | ||
100 | size_t name_len; | ||
101 | |||
102 | barrier = GNUNET_TESTING_get_barrier_ (is, | ||
103 | brs->barrier_name); | ||
104 | if (NULL == barrier) | ||
105 | { | ||
106 | barrier = GNUNET_new (struct GNUNET_TESTING_Barrier); | ||
107 | barrier->name = brs->barrier_name; | ||
108 | GNUNET_TESTING_add_barrier_ (is, | ||
109 | barrier); | ||
110 | } | ||
111 | barrier->reached++; | ||
112 | if (GNUNET_TESTING_barrier_crossable_ (barrier)) | ||
113 | { | ||
114 | GNUNET_assert (NULL != cmd); | ||
115 | cmd->asynchronous_finish = GNUNET_YES; | ||
116 | GNUNET_TESTING_finish_barrier_ (is, | ||
117 | barrier->name); | ||
118 | } | ||
119 | else if (GNUNET_NO == brs->asynchronous_finish) | ||
120 | { | ||
121 | cle = GNUNET_new (struct CommandListEntry); | ||
122 | cle->command = cmd; | ||
123 | GNUNET_CONTAINER_DLL_insert (barrier->cmds_head, | ||
124 | barrier->cmds_tail, | ||
125 | cle); | ||
126 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
127 | "added cle for %p %s\n", | ||
128 | barrier, | ||
129 | barrier->name); | ||
130 | } | ||
131 | |||
132 | if (GNUNET_NO == brs->running_on_master) | ||
133 | { | ||
134 | char *terminator = "\0"; | ||
135 | |||
136 | name_len = strlen (barrier->name); | ||
137 | msg_length = sizeof(struct GNUNET_TESTING_CommandBarrierReached) | ||
138 | + name_len + 1; | ||
139 | msg = GNUNET_malloc (msg_length); | ||
140 | msg->header.size = htons ((uint16_t) msg_length); | ||
141 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_REACHED); | ||
142 | msg->node_number = brs->node_number; | ||
143 | memcpy (&msg[1], barrier->name, name_len + 1); | ||
144 | memcpy (&msg[name_len + 1],terminator,1); | ||
145 | brs->write_message ((struct GNUNET_MessageHeader *) msg, msg_length); | ||
146 | } | ||
147 | } | ||
148 | |||
149 | |||
150 | /** | ||
151 | * Cleanup the state from a "barrier reached" CMD, and possibly | ||
152 | * cancel a pending operation thereof. | ||
153 | * | ||
154 | * @param cls closure. | ||
155 | */ | ||
156 | static void | ||
157 | barrier_reached_cleanup (void *cls) | ||
158 | { | ||
159 | struct BarrierReachedState *brs = cls; | ||
160 | |||
161 | GNUNET_free (brs); | ||
162 | } | ||
163 | |||
164 | |||
165 | /** | ||
166 | * Offer internal data from a "batch" CMD, to other commands. | ||
167 | * | ||
168 | * @param cls closure. | ||
169 | * @param[out] ret result. | ||
170 | * @param trait name of the trait. | ||
171 | * @param index index number of the object to offer. | ||
172 | * @return #GNUNET_OK on success. | ||
173 | */ | ||
174 | static enum GNUNET_GenericReturnValue | ||
175 | barrier_reached_traits (void *cls, | ||
176 | const void **ret, | ||
177 | const char *trait, | ||
178 | unsigned int index) | ||
179 | { | ||
180 | struct BarrierReachedState *brs = cls; | ||
181 | struct GNUNET_TESTING_AsyncContext *ac = &brs->ac; | ||
182 | |||
183 | struct GNUNET_TESTING_Trait traits[] = { | ||
184 | GNUNET_TESTING_make_trait_async_context (ac), | ||
185 | GNUNET_TESTING_trait_end () | ||
186 | }; | ||
187 | |||
188 | return GNUNET_TESTING_get_trait (traits, | ||
189 | ret, | ||
190 | trait, | ||
191 | index); | ||
192 | } | ||
193 | |||
194 | |||
195 | /** | ||
196 | * Create command. | ||
197 | * | ||
198 | * @param label name for command. | ||
199 | * @param barrier_label The name of the barrier we wait for (if finishing asynchronous) and which will be reached. | ||
200 | * @param asynchronous_finish If GNUNET_YES this command will not block. | ||
201 | * @param node_number The global numer of the node the cmd runs on. | ||
202 | * @param running_on_master Is this cmd running on the master loop. | ||
203 | * @param write_message Callback to write messages to the master loop. | ||
204 | * @return command. | ||
205 | */ | ||
206 | struct GNUNET_TESTING_Command | ||
207 | GNUNET_TESTING_cmd_barrier_reached ( | ||
208 | const char *label, | ||
209 | const char *barrier_label, | ||
210 | unsigned int asynchronous_finish, | ||
211 | unsigned int node_number, | ||
212 | unsigned int running_on_master, | ||
213 | GNUNET_TESTING_cmd_helper_write_cb write_message) | ||
214 | { | ||
215 | struct BarrierReachedState *brs; | ||
216 | |||
217 | brs = GNUNET_new (struct BarrierReachedState); | ||
218 | brs->label = label; | ||
219 | brs->barrier_name = barrier_label; | ||
220 | brs->asynchronous_finish = asynchronous_finish; | ||
221 | brs->node_number = node_number; | ||
222 | brs->running_on_master = running_on_master; | ||
223 | brs->write_message = write_message; | ||
224 | return GNUNET_TESTING_command_new (brs, label, | ||
225 | &barrier_reached_run, | ||
226 | &barrier_reached_cleanup, | ||
227 | &barrier_reached_traits, | ||
228 | &brs->ac); | ||
229 | } | ||
diff --git a/src/service/testing/testing_api_cmd_block_until_external_trigger.c b/src/service/testing/testing_api_cmd_block_until_external_trigger.c deleted file mode 100644 index fc312cdc9..000000000 --- a/src/service/testing/testing_api_cmd_block_until_external_trigger.c +++ /dev/null | |||
@@ -1,119 +0,0 @@ | |||
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_api_cmd_block_until_all_peers_started.c | ||
23 | * @brief cmd to block the interpreter loop until all peers started. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "testing_cmds.h" | ||
29 | #include "gnunet_testing_plugin.h" | ||
30 | #include "gnunet_testing_barrier.h" | ||
31 | #include "gnunet_testing_netjail_lib.h" | ||
32 | |||
33 | /** | ||
34 | * Generic logging shortcut | ||
35 | */ | ||
36 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | ||
37 | |||
38 | |||
39 | /** | ||
40 | * The cleanup function of this cmd frees resources the cmd allocated. | ||
41 | * | ||
42 | */ | ||
43 | static void | ||
44 | block_until_all_peers_started_cleanup (void *cls) | ||
45 | { | ||
46 | struct BlockState *bs = cls; | ||
47 | |||
48 | GNUNET_free (bs); | ||
49 | } | ||
50 | |||
51 | |||
52 | static int | ||
53 | block_until_external_trigger_traits (void *cls, | ||
54 | const void **ret, | ||
55 | const char *trait, | ||
56 | unsigned int index) | ||
57 | { | ||
58 | struct GNUNET_TESTING_BlockState *bs = cls; | ||
59 | struct GNUNET_TESTING_AsyncContext *ac = &bs->ac; | ||
60 | struct GNUNET_TESTING_Trait traits[] = { | ||
61 | GNUNET_TESTING_make_trait_async_context (ac), | ||
62 | GNUNET_TESTING_make_trait_block_state (bs), | ||
63 | GNUNET_TESTING_trait_end () | ||
64 | }; | ||
65 | |||
66 | return GNUNET_TESTING_get_trait (traits, | ||
67 | ret, | ||
68 | trait, | ||
69 | index); | ||
70 | } | ||
71 | |||
72 | |||
73 | /** | ||
74 | * This function does nothing but to start the cmd. | ||
75 | * | ||
76 | */ | ||
77 | static void | ||
78 | block_until_all_peers_started_run (void *cls, | ||
79 | struct GNUNET_TESTING_Interpreter *is) | ||
80 | { | ||
81 | struct GNUNET_TESTING_BlockState *bs = cls; | ||
82 | struct GNUNET_TESTING_Command *cmd = | ||
83 | GNUNET_TESTING_interpreter_get_current_command (is); | ||
84 | |||
85 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
86 | "block %s running %u!\n", | ||
87 | bs->label, | ||
88 | bs->asynchronous_finish); | ||
89 | if (GNUNET_YES == bs->asynchronous_finish) | ||
90 | { | ||
91 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
92 | "block %s running asynchronous!\n", | ||
93 | bs->label); | ||
94 | cmd->asynchronous_finish = bs->asynchronous_finish; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | |||
99 | /** | ||
100 | * Create command. | ||
101 | * | ||
102 | * @param label name for command. | ||
103 | * @return command. | ||
104 | */ | ||
105 | struct GNUNET_TESTING_Command | ||
106 | GNUNET_TESTING_cmd_block_until_external_trigger ( | ||
107 | const char *label) | ||
108 | { | ||
109 | struct GNUNET_TESTING_BlockState *bs; | ||
110 | |||
111 | bs = GNUNET_new (struct GNUNET_TESTING_BlockState); | ||
112 | bs->label = label; | ||
113 | return GNUNET_TESTING_command_new (bs, | ||
114 | label, | ||
115 | &block_until_all_peers_started_run, | ||
116 | &block_until_all_peers_started_cleanup, | ||
117 | &block_until_external_trigger_traits, | ||
118 | &bs->ac); | ||
119 | } | ||
diff --git a/src/service/testing/testing_api_cmd_exec_bash_script.c b/src/service/testing/testing_api_cmd_exec_bash_script.c deleted file mode 100644 index 171a2baac..000000000 --- a/src/service/testing/testing_api_cmd_exec_bash_script.c +++ /dev/null | |||
@@ -1,216 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2023 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_api_cmd_local_test_prepared.c | ||
23 | * @brief cmd to block the interpreter loop until all peers started. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_ng_lib.h" | ||
29 | |||
30 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | ||
31 | |||
32 | struct BashScriptState | ||
33 | { | ||
34 | /** | ||
35 | * Context for our asynchronous completion. | ||
36 | */ | ||
37 | struct GNUNET_TESTING_AsyncContext ac; | ||
38 | |||
39 | /** | ||
40 | * Callback handed over to the command, which should | ||
41 | * be called upon death or completion of the script. | ||
42 | */ | ||
43 | GNUNET_ChildCompletedCallback cb; | ||
44 | |||
45 | // Child Wait handle | ||
46 | struct GNUNET_ChildWaitHandle *cwh; | ||
47 | |||
48 | /** | ||
49 | * The process id of the script. | ||
50 | */ | ||
51 | struct GNUNET_OS_Process *start_proc; | ||
52 | |||
53 | /** | ||
54 | * Script this cmd will execute. | ||
55 | */ | ||
56 | const char *script; | ||
57 | |||
58 | |||
59 | /** | ||
60 | * Arguments for the script | ||
61 | */ | ||
62 | char *const*script_argv; | ||
63 | |||
64 | /** | ||
65 | * Size of script_argv. | ||
66 | */ | ||
67 | int argc; | ||
68 | }; | ||
69 | |||
70 | /** | ||
71 | * The cleanup function of this cmd frees resources the cmd allocated. | ||
72 | * | ||
73 | */ | ||
74 | static void | ||
75 | exec_bash_script_cleanup (void *cls) | ||
76 | { | ||
77 | struct BashScriptState *bss = cls; | ||
78 | |||
79 | if (NULL != bss->cwh) | ||
80 | { | ||
81 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
82 | "Cancel child\n"); | ||
83 | GNUNET_wait_child_cancel (bss->cwh); | ||
84 | bss->cwh = NULL; | ||
85 | } | ||
86 | if (NULL != bss->start_proc) | ||
87 | { | ||
88 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
89 | "Kill process\n"); | ||
90 | GNUNET_assert (0 == | ||
91 | GNUNET_OS_process_kill (bss->start_proc, | ||
92 | SIGKILL)); | ||
93 | GNUNET_assert (GNUNET_OK == | ||
94 | GNUNET_OS_process_wait (bss->start_proc)); | ||
95 | GNUNET_OS_process_destroy (bss->start_proc); | ||
96 | bss->start_proc = NULL; | ||
97 | } | ||
98 | GNUNET_free (bss); | ||
99 | } | ||
100 | |||
101 | /** | ||
102 | * Callback which will be called if the setup script finished. | ||
103 | * | ||
104 | */ | ||
105 | static void | ||
106 | child_completed_callback (void *cls, | ||
107 | enum GNUNET_OS_ProcessStatusType type, | ||
108 | long unsigned int exit_code) | ||
109 | { | ||
110 | struct BashScriptState *bss = cls; | ||
111 | |||
112 | GNUNET_OS_process_destroy (bss->start_proc); | ||
113 | bss->start_proc = NULL; | ||
114 | bss->cwh = NULL; | ||
115 | if (0 == exit_code) | ||
116 | { | ||
117 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
118 | "Child succeeded!\n"); | ||
119 | GNUNET_TESTING_async_finish (&bss->ac); | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
124 | "Child failed with error %lu!\n", | ||
125 | exit_code); | ||
126 | GNUNET_TESTING_async_fail (&bss->ac); | ||
127 | } | ||
128 | bss->cb (cls, type, exit_code); | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * Run method of the command created by the interpreter to wait for another | ||
133 | * command to finish. | ||
134 | * | ||
135 | */ | ||
136 | static void | ||
137 | exec_bash_script_run (void *cls, | ||
138 | struct GNUNET_TESTING_Interpreter *is) | ||
139 | { | ||
140 | struct BashScriptState *bss = cls; | ||
141 | enum GNUNET_GenericReturnValue helper_check; | ||
142 | char *argv[bss->argc + 2]; | ||
143 | |||
144 | char *data_dir; | ||
145 | char *script_name; | ||
146 | |||
147 | data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); | ||
148 | GNUNET_asprintf (&script_name, "%s%s", data_dir, bss->script); | ||
149 | |||
150 | helper_check = GNUNET_OS_check_helper_binary ( | ||
151 | script_name, | ||
152 | GNUNET_YES, | ||
153 | NULL); | ||
154 | |||
155 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
156 | "script_name %s\n", | ||
157 | script_name); | ||
158 | |||
159 | if (GNUNET_NO == helper_check) | ||
160 | { | ||
161 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
162 | "No SUID for %s!\n", | ||
163 | script_name); | ||
164 | GNUNET_TESTING_interpreter_fail (is); | ||
165 | return; | ||
166 | } | ||
167 | if (GNUNET_SYSERR == helper_check) | ||
168 | { | ||
169 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
170 | "%s not found!\n", | ||
171 | script_name); | ||
172 | GNUNET_TESTING_interpreter_fail (is); | ||
173 | return; | ||
174 | } | ||
175 | argv[0] = script_name; | ||
176 | if (NULL != bss->script_argv) | ||
177 | { | ||
178 | for (int i = 0; i < bss->argc;i++) | ||
179 | argv[i + 1] = bss->script_argv[i]; | ||
180 | } | ||
181 | argv[bss->argc] = NULL; | ||
182 | |||
183 | bss->start_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR, | ||
184 | NULL, | ||
185 | NULL, | ||
186 | NULL, | ||
187 | script_name, | ||
188 | argv); | ||
189 | bss->cwh = GNUNET_wait_child (bss->start_proc, | ||
190 | &child_completed_callback, | ||
191 | bss); | ||
192 | GNUNET_break (NULL != bss->cwh); | ||
193 | } | ||
194 | |||
195 | const struct GNUNET_TESTING_Command | ||
196 | GNUNET_TESTING_cmd_exec_bash_script (const char *label, | ||
197 | const char *script, | ||
198 | char *const script_argv[], | ||
199 | int argc, | ||
200 | GNUNET_ChildCompletedCallback cb) | ||
201 | { | ||
202 | struct BashScriptState *bss; | ||
203 | |||
204 | bss = GNUNET_new (struct BashScriptState); | ||
205 | bss->script = script; | ||
206 | bss->script_argv = script_argv; // FIXME this is not just a cast to fix | ||
207 | bss->argc = argc; | ||
208 | bss->cb = cb; | ||
209 | |||
210 | return GNUNET_TESTING_command_new (bss, | ||
211 | label, | ||
212 | &exec_bash_script_run, | ||
213 | &exec_bash_script_cleanup, | ||
214 | NULL, | ||
215 | &bss->ac); | ||
216 | } | ||
diff --git a/src/service/testing/testing_api_cmd_local_test_prepared.c b/src/service/testing/testing_api_cmd_local_test_prepared.c deleted file mode 100644 index 2b1525077..000000000 --- a/src/service/testing/testing_api_cmd_local_test_prepared.c +++ /dev/null | |||
@@ -1,112 +0,0 @@ | |||
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_api_cmd_local_test_prepared.c | ||
23 | * @brief cmd to block the interpreter loop until all peers started. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_ng_lib.h" | ||
29 | #include "gnunet_testing_plugin.h" | ||
30 | #include "gnunet_testing_barrier.h" | ||
31 | #include "gnunet_testing_netjail_lib.h" | ||
32 | #include "testing_cmds.h" | ||
33 | |||
34 | /** | ||
35 | * Generic logging shortcut | ||
36 | */ | ||
37 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | ||
38 | |||
39 | |||
40 | /** | ||
41 | * This function prepares an array with traits. | ||
42 | * | ||
43 | */ | ||
44 | enum GNUNET_GenericReturnValue | ||
45 | local_test_prepared_traits (void *cls, | ||
46 | const void **ret, | ||
47 | const char *trait, | ||
48 | unsigned int index) | ||
49 | { | ||
50 | struct LocalPreparedState *lfs = cls; | ||
51 | struct GNUNET_TESTING_Trait traits[] = { | ||
52 | GNUNET_TESTING_make_trait_local_prepared_state ((const void *) lfs), | ||
53 | GNUNET_TESTING_trait_end () | ||
54 | }; | ||
55 | return GNUNET_TESTING_get_trait (traits, | ||
56 | ret, | ||
57 | trait, | ||
58 | index); | ||
59 | } | ||
60 | |||
61 | |||
62 | /** | ||
63 | * The cleanup function of this cmd frees resources the cmd allocated. | ||
64 | * | ||
65 | */ | ||
66 | static void | ||
67 | local_test_prepared_cleanup (void *cls) | ||
68 | { | ||
69 | struct LocalPreparedState *lfs = cls; | ||
70 | |||
71 | GNUNET_free (lfs); | ||
72 | } | ||
73 | |||
74 | |||
75 | /** | ||
76 | * This function sends a GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TESTS_PREPARED message to the master loop. | ||
77 | * | ||
78 | */ | ||
79 | static void | ||
80 | local_test_prepared_run (void *cls, | ||
81 | struct GNUNET_TESTING_Interpreter *is) | ||
82 | { | ||
83 | struct GNUNET_TESTING_LocalPreparedState *lfs = cls; | ||
84 | |||
85 | struct GNUNET_TESTING_CommandLocalTestPrepared *reply; | ||
86 | size_t msg_length; | ||
87 | |||
88 | msg_length = sizeof(struct GNUNET_TESTING_CommandLocalTestPrepared); | ||
89 | reply = GNUNET_new (struct GNUNET_TESTING_CommandLocalTestPrepared); | ||
90 | reply->header.type = htons ( | ||
91 | GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED); | ||
92 | reply->header.size = htons ((uint16_t) msg_length); | ||
93 | lfs->write_message ((struct GNUNET_MessageHeader *) reply, msg_length); | ||
94 | } | ||
95 | |||
96 | |||
97 | struct GNUNET_TESTING_Command | ||
98 | GNUNET_TESTING_cmd_local_test_prepared (const char *label, | ||
99 | GNUNET_TESTING_cmd_helper_write_cb | ||
100 | write_message) | ||
101 | { | ||
102 | struct GNUNET_TESTING_LocalPreparedState *lfs; | ||
103 | |||
104 | lfs = GNUNET_new (struct GNUNET_TESTING_LocalPreparedState); | ||
105 | lfs->write_message = write_message; | ||
106 | |||
107 | return GNUNET_TESTING_command_new (lfs, label, | ||
108 | &local_test_prepared_run, | ||
109 | &local_test_prepared_cleanup, | ||
110 | &local_test_prepared_traits, | ||
111 | &lfs->ac); | ||
112 | } | ||
diff --git a/src/service/testing/testing_api_cmd_netjail_start_cmds_helper.c b/src/service/testing/testing_api_cmd_netjail_start_cmds_helper.c deleted file mode 100644 index 792d7a8cf..000000000 --- a/src/service/testing/testing_api_cmd_netjail_start_cmds_helper.c +++ /dev/null | |||
@@ -1,917 +0,0 @@ | |||
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_testing_plugin.h" | ||
29 | #include "gnunet_testing_barrier.h" | ||
30 | #include "gnunet_testing_netjail_lib.h" | ||
31 | #include "testing.h" | ||
32 | #include "testing_cmds.h" | ||
33 | |||
34 | #define NETJAIL_EXEC_SCRIPT "netjail_exec.sh" | ||
35 | |||
36 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) | ||
37 | |||
38 | /** | ||
39 | * Generic logging shortcut | ||
40 | */ | ||
41 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | ||
42 | |||
43 | /** | ||
44 | * Struct to store messages send/received by the helper into a DLL | ||
45 | * | ||
46 | */ | ||
47 | struct HelperMessage | ||
48 | { | ||
49 | |||
50 | /** | ||
51 | * Kept in a DLL. | ||
52 | */ | ||
53 | struct HelperMessage *next; | ||
54 | |||
55 | /** | ||
56 | * Kept in a DLL. | ||
57 | */ | ||
58 | struct HelperMessage *prev; | ||
59 | |||
60 | /** | ||
61 | * Size of the original message. | ||
62 | */ | ||
63 | uint16_t bytes_msg; | ||
64 | |||
65 | /* Followed by @e bytes_msg of msg.*/ | ||
66 | }; | ||
67 | |||
68 | |||
69 | /** | ||
70 | * Struct to store information handed over to callbacks. | ||
71 | * | ||
72 | */ | ||
73 | struct NetJailState | ||
74 | { | ||
75 | /** | ||
76 | * Global state of the interpreter, used by a command | ||
77 | * to access information about other commands. | ||
78 | */ | ||
79 | struct GNUNET_TESTING_Interpreter *is; | ||
80 | |||
81 | /** | ||
82 | * Context for our asynchronous completion. | ||
83 | */ | ||
84 | struct GNUNET_TESTING_AsyncContext ac; | ||
85 | |||
86 | /** | ||
87 | * The complete topology information. | ||
88 | */ | ||
89 | struct GNUNET_TESTING_NetjailTopology *topology; | ||
90 | |||
91 | /** | ||
92 | * Array with handles of helper processes. | ||
93 | */ | ||
94 | const struct GNUNET_HELPER_Handle **helper; | ||
95 | |||
96 | /** | ||
97 | * Size of the array NetJailState#helper. | ||
98 | * | ||
99 | */ | ||
100 | unsigned int n_helper; | ||
101 | |||
102 | /** | ||
103 | * Number of nodes in a natted subnet. | ||
104 | * | ||
105 | */ | ||
106 | unsigned int local_m; | ||
107 | |||
108 | /** | ||
109 | * Number of natted subnets. | ||
110 | * | ||
111 | */ | ||
112 | unsigned int global_n; | ||
113 | |||
114 | /** | ||
115 | * Number of global known nodes. | ||
116 | * | ||
117 | */ | ||
118 | unsigned int known; | ||
119 | |||
120 | |||
121 | /** | ||
122 | * Number of test environments started. | ||
123 | * | ||
124 | */ | ||
125 | unsigned int number_of_testsystems_started; | ||
126 | |||
127 | /** | ||
128 | * Number of peers started. | ||
129 | * | ||
130 | */ | ||
131 | unsigned int number_of_peers_started; | ||
132 | |||
133 | /** | ||
134 | * Number of local tests finished. | ||
135 | * | ||
136 | */ | ||
137 | unsigned int number_of_local_tests_finished; | ||
138 | |||
139 | /** | ||
140 | * Number of local tests prepared to finish. | ||
141 | * | ||
142 | */ | ||
143 | unsigned int number_of_local_tests_prepared; | ||
144 | |||
145 | /** | ||
146 | * Name of the test case plugin the helper will load. | ||
147 | * | ||
148 | */ | ||
149 | char *plugin_name; | ||
150 | |||
151 | /** | ||
152 | * Shall we read the topology from file, or from a string. | ||
153 | */ | ||
154 | unsigned int *read_file; | ||
155 | |||
156 | /** | ||
157 | * String with topology data or name of topology file. | ||
158 | */ | ||
159 | char *topology_data; | ||
160 | |||
161 | /** | ||
162 | * Time after this cmd has to finish. | ||
163 | */ | ||
164 | struct GNUNET_TIME_Relative timeout; | ||
165 | |||
166 | /** | ||
167 | * Timeout task. | ||
168 | */ | ||
169 | struct GNUNET_SCHEDULER_Task *timeout_task; | ||
170 | }; | ||
171 | |||
172 | /** | ||
173 | * Struct containing the number of the netjail node and the NetJailState which | ||
174 | * will be handed to callbacks specific to a test environment. | ||
175 | */ | ||
176 | struct TestingSystemCount | ||
177 | { | ||
178 | /** | ||
179 | * The plugin correlated to this netjail node. | ||
180 | */ | ||
181 | struct TestcasePlugin *plugin; | ||
182 | |||
183 | /** | ||
184 | * Kept in a DLL. | ||
185 | */ | ||
186 | struct TestingSystemCount *next; | ||
187 | |||
188 | /** | ||
189 | * Kept in a DLL. | ||
190 | */ | ||
191 | struct TestingSystemCount *prev; | ||
192 | |||
193 | /** | ||
194 | * The send handle for the helper | ||
195 | */ | ||
196 | struct GNUNET_HELPER_SendHandle *shandle; | ||
197 | |||
198 | /** | ||
199 | * Struct to store information handed over to callbacks. | ||
200 | * | ||
201 | */ | ||
202 | struct NetJailState *ns; | ||
203 | |||
204 | /** | ||
205 | * The messages send to the helper. | ||
206 | */ | ||
207 | struct GNUNET_MessageHeader *msg; | ||
208 | }; | ||
209 | |||
210 | |||
211 | /** | ||
212 | * Code to clean up resource this cmd used. | ||
213 | * | ||
214 | * @param cls closure | ||
215 | */ | ||
216 | static void | ||
217 | netjail_exec_cleanup (void *cls) | ||
218 | { | ||
219 | struct NetJailState *ns = cls; | ||
220 | GNUNET_free (ns); | ||
221 | } | ||
222 | |||
223 | |||
224 | /** | ||
225 | * This function prepares an array with traits. | ||
226 | * | ||
227 | */ | ||
228 | static enum GNUNET_GenericReturnValue | ||
229 | netjail_exec_traits (void *cls, | ||
230 | const void **ret, | ||
231 | const char *trait, | ||
232 | unsigned int index) | ||
233 | { | ||
234 | struct NetJailState *ns = cls; | ||
235 | const struct GNUNET_HELPER_Handle **helper = ns->helper; | ||
236 | |||
237 | |||
238 | struct GNUNET_TESTING_Trait traits[] = { | ||
239 | GNUNET_TESTING_make_trait_helper_handles (helper), | ||
240 | GNUNET_TESTING_trait_end () | ||
241 | }; | ||
242 | |||
243 | return GNUNET_TESTING_get_trait (traits, | ||
244 | ret, | ||
245 | trait, | ||
246 | index); | ||
247 | } | ||
248 | |||
249 | |||
250 | /** | ||
251 | * Continuation function from GNUNET_HELPER_send() | ||
252 | * | ||
253 | * @param cls closure | ||
254 | * @param result GNUNET_OK on success, | ||
255 | * GNUNET_NO if helper process died | ||
256 | * GNUNET_SYSERR during GNUNET_HELPER_stop | ||
257 | */ | ||
258 | static void | ||
259 | clear_msg (void *cls, int result) | ||
260 | { | ||
261 | struct TestingSystemCount *tbc = cls; | ||
262 | |||
263 | GNUNET_assert (NULL != tbc->shandle); | ||
264 | // GNUNET_free (tbc->shandle); | ||
265 | GNUNET_free (tbc->plugin); | ||
266 | tbc->shandle = NULL; | ||
267 | GNUNET_free (tbc); | ||
268 | } | ||
269 | |||
270 | |||
271 | static void | ||
272 | send_message_to_locals ( | ||
273 | unsigned int i, | ||
274 | unsigned int j, | ||
275 | struct NetJailState *ns, | ||
276 | struct GNUNET_MessageHeader *header | ||
277 | ) | ||
278 | { | ||
279 | const struct GNUNET_HELPER_Handle *helper; | ||
280 | struct TestingSystemCount *tbc; | ||
281 | unsigned int count; | ||
282 | |||
283 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
284 | "send message of type %u to locals\n", | ||
285 | header->type); | ||
286 | tbc = GNUNET_new (struct TestingSystemCount); | ||
287 | tbc->ns = ns; | ||
288 | if (0 == i) | ||
289 | count = j; | ||
290 | else | ||
291 | count = (i - 1) * ns->local_m + j + ns->known; | ||
292 | |||
293 | helper = ns->helper[count - 1]; | ||
294 | |||
295 | |||
296 | struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send ( | ||
297 | (struct GNUNET_HELPER_Handle *) helper, | ||
298 | header, | ||
299 | GNUNET_NO, | ||
300 | &clear_msg, | ||
301 | tbc); | ||
302 | |||
303 | tbc->shandle = sh; | ||
304 | } | ||
305 | |||
306 | |||
307 | static void | ||
308 | send_all_local_tests_prepared (unsigned int i, unsigned int j, struct | ||
309 | NetJailState *ns) | ||
310 | { | ||
311 | struct GNUNET_TESTING_CommandAllLocalTestsPrepared *reply; | ||
312 | size_t msg_length; | ||
313 | |||
314 | |||
315 | msg_length = sizeof(struct GNUNET_TESTING_CommandAllLocalTestsPrepared); | ||
316 | reply = GNUNET_new (struct GNUNET_TESTING_CommandAllLocalTestsPrepared); | ||
317 | reply->header.type = htons ( | ||
318 | GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED); | ||
319 | reply->header.size = htons ((uint16_t) msg_length); | ||
320 | |||
321 | send_message_to_locals (i, j, ns, &reply->header); | ||
322 | GNUNET_free (reply); | ||
323 | } | ||
324 | |||
325 | |||
326 | static void | ||
327 | send_all_peers_started (unsigned int i, unsigned int j, struct NetJailState *ns) | ||
328 | { | ||
329 | struct GNUNET_TESTING_CommandAllPeersStarted *reply; | ||
330 | size_t msg_length; | ||
331 | |||
332 | msg_length = sizeof(struct GNUNET_TESTING_CommandAllPeersStarted); | ||
333 | reply = GNUNET_new (struct GNUNET_TESTING_CommandAllPeersStarted); | ||
334 | reply->header.type = htons ( | ||
335 | GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED); | ||
336 | reply->header.size = htons ((uint16_t) msg_length); | ||
337 | |||
338 | send_message_to_locals (i, j, ns, &reply->header); | ||
339 | GNUNET_free (reply); | ||
340 | } | ||
341 | |||
342 | |||
343 | void | ||
344 | barrier_attached (struct NetJailState *ns, const struct | ||
345 | GNUNET_MessageHeader *message) | ||
346 | { | ||
347 | struct CommandBarrierAttached *am; | ||
348 | struct GNUNET_TESTING_NetjailNode *node; | ||
349 | struct GNUNET_TESTING_Barrier *barrier; | ||
350 | struct GNUNET_ShortHashCode key; | ||
351 | struct GNUNET_HashCode hc; | ||
352 | const char *barrier_name; | ||
353 | |||
354 | am = (struct CommandBarrierAttached *) message; | ||
355 | barrier_name = (const char *) &am[1]; | ||
356 | barrier = GNUNET_TESTING_get_barrier_ (ns->is, | ||
357 | barrier_name); | ||
358 | GNUNET_assert (NULL != barrier); | ||
359 | node = GNUNET_TESTING_barrier_get_node (barrier, | ||
360 | am->node_number); | ||
361 | if (NULL == node) | ||
362 | { | ||
363 | node = GNUNET_new (struct GNUNET_TESTING_NetjailNode); | ||
364 | node->node_number = am->node_number; | ||
365 | |||
366 | GNUNET_CRYPTO_hash (&(node->node_number), sizeof(node->node_number), &hc); | ||
367 | memcpy (&key, &hc, sizeof (key)); | ||
368 | GNUNET_CONTAINER_multishortmap_put (barrier->nodes, | ||
369 | &key, | ||
370 | node, | ||
371 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
372 | } | ||
373 | node->expected_reaches = node->expected_reaches + am->expected_reaches; | ||
374 | barrier->expected_reaches = barrier->expected_reaches + am->expected_reaches; | ||
375 | } | ||
376 | |||
377 | |||
378 | void | ||
379 | barrier_reached (struct NetJailState *ns, | ||
380 | const struct GNUNET_MessageHeader *message) | ||
381 | { | ||
382 | struct GNUNET_TESTING_Barrier *barrier; | ||
383 | const char *barrier_name; | ||
384 | const struct GNUNET_TESTING_CommandBarrierReached *rm; | ||
385 | |||
386 | rm = (const struct GNUNET_TESTING_CommandBarrierReached *) message; | ||
387 | barrier_name = (const char *) &rm[1]; | ||
388 | barrier = GNUNET_TESTING_get_barrier_ (ns->is, | ||
389 | barrier_name); | ||
390 | GNUNET_assert (NULL != barrier); | ||
391 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
392 | "barrier %s reached %p %u\n", | ||
393 | barrier_name, | ||
394 | barrier, | ||
395 | barrier->reached); | ||
396 | barrier->reached++; | ||
397 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
398 | "%u %p\n", | ||
399 | barrier->reached, | ||
400 | barrier); | ||
401 | if (GNUNET_TESTING_barrier_crossable_ (barrier)) | ||
402 | { | ||
403 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
404 | "%s can be crossed\n", | ||
405 | barrier_name); | ||
406 | GNUNET_TESTING_finish_barrier_ (ns->is, | ||
407 | barrier->name); | ||
408 | } | ||
409 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
410 | "barrier %s reached finished\n", | ||
411 | barrier_name); | ||
412 | } | ||
413 | |||
414 | |||
415 | /** | ||
416 | * Functions with this signature are called whenever a | ||
417 | * complete message is received by the tokenizer. | ||
418 | * | ||
419 | * Do not call GNUNET_SERVER_mst_destroy in callback | ||
420 | * | ||
421 | * @param cls closure | ||
422 | * @param client identification of the client | ||
423 | * @param message the actual message | ||
424 | * | ||
425 | * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing | ||
426 | */ | ||
427 | static int | ||
428 | helper_mst (void *cls, const struct GNUNET_MessageHeader *message) | ||
429 | { | ||
430 | struct NetJailState *ns = cls; | ||
431 | unsigned int total_number = ns->local_m * ns->global_n + ns->known; | ||
432 | uint16_t message_type = ntohs (message->type); | ||
433 | struct GNUNET_TESTING_CommandLocalFinished *lf; | ||
434 | |||
435 | switch (message_type) | ||
436 | { | ||
437 | case GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ATTACHED: | ||
438 | barrier_attached (ns, message); | ||
439 | break; | ||
440 | case GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_REACHED: | ||
441 | barrier_reached (ns, message); | ||
442 | break; | ||
443 | case GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY: | ||
444 | ns->number_of_testsystems_started++; | ||
445 | break; | ||
446 | case GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED: | ||
447 | ns->number_of_peers_started++; | ||
448 | if (ns->number_of_peers_started == total_number) | ||
449 | { | ||
450 | for (int i = 1; i <= ns->known; i++) | ||
451 | { | ||
452 | send_all_peers_started (0,i, ns); | ||
453 | } | ||
454 | for (int i = 1; i <= ns->global_n; i++) | ||
455 | { | ||
456 | for (int j = 1; j <= ns->local_m; j++) | ||
457 | { | ||
458 | send_all_peers_started (i,j, ns); | ||
459 | } | ||
460 | } | ||
461 | ns->number_of_peers_started = 0; | ||
462 | } | ||
463 | break; | ||
464 | case GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED: | ||
465 | ns->number_of_local_tests_prepared++; | ||
466 | if (ns->number_of_local_tests_prepared == total_number) | ||
467 | { | ||
468 | for (int i = 1; i <= ns->known; i++) | ||
469 | { | ||
470 | send_all_local_tests_prepared (0,i, ns); | ||
471 | } | ||
472 | |||
473 | for (int i = 1; i <= ns->global_n; i++) | ||
474 | { | ||
475 | for (int j = 1; j <= ns->local_m; j++) | ||
476 | { | ||
477 | send_all_local_tests_prepared (i,j, ns); | ||
478 | } | ||
479 | } | ||
480 | } | ||
481 | break; | ||
482 | case GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED: | ||
483 | lf = (struct GNUNET_TESTING_CommandLocalFinished *) message; | ||
484 | |||
485 | ns->number_of_local_tests_finished++; | ||
486 | if (GNUNET_OK != lf->rv) | ||
487 | { | ||
488 | GNUNET_TESTING_async_fail (&(ns->ac)); | ||
489 | } | ||
490 | else if (ns->number_of_local_tests_finished == total_number) | ||
491 | { | ||
492 | GNUNET_SCHEDULER_cancel (ns->timeout_task); | ||
493 | ns->timeout_task = NULL; | ||
494 | GNUNET_TESTING_async_finish (&ns->ac); | ||
495 | } | ||
496 | break; | ||
497 | default: | ||
498 | // We received a message we can not handle. | ||
499 | GNUNET_assert (0); | ||
500 | } | ||
501 | |||
502 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
503 | "total %u sysstarted %u peersstarted %u prep %u finished %u %u %u %u\n", | ||
504 | total_number, | ||
505 | ns->number_of_testsystems_started, | ||
506 | ns->number_of_peers_started, | ||
507 | ns->number_of_local_tests_prepared, | ||
508 | ns->number_of_local_tests_finished, | ||
509 | ns->local_m, | ||
510 | ns->global_n, | ||
511 | ns->known); | ||
512 | |||
513 | |||
514 | return GNUNET_OK; | ||
515 | } | ||
516 | |||
517 | |||
518 | /** | ||
519 | * Callback called if there was an exception during execution of the helper. | ||
520 | * | ||
521 | */ | ||
522 | static void | ||
523 | exp_cb (void *cls) | ||
524 | { | ||
525 | struct NetJailState *ns = cls; | ||
526 | |||
527 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n"); | ||
528 | if (NULL != ns->timeout_task) | ||
529 | GNUNET_SCHEDULER_cancel (ns->timeout_task); | ||
530 | GNUNET_TESTING_async_fail (&(ns->ac)); | ||
531 | } | ||
532 | |||
533 | |||
534 | /** | ||
535 | * Function to initialize a init message for the helper. | ||
536 | * | ||
537 | * @param plugin_name Name of the test case plugin the helper will load. | ||
538 | * | ||
539 | */ | ||
540 | static struct GNUNET_TESTING_CommandHelperInit * | ||
541 | create_helper_init_msg_ (const char *plugin_name) | ||
542 | { | ||
543 | struct GNUNET_TESTING_CommandHelperInit *msg; | ||
544 | uint16_t plugin_name_len; | ||
545 | uint16_t msg_size; | ||
546 | |||
547 | GNUNET_assert (NULL != plugin_name); | ||
548 | plugin_name_len = strlen (plugin_name); | ||
549 | msg_size = sizeof(struct GNUNET_TESTING_CommandHelperInit) + plugin_name_len; | ||
550 | msg = GNUNET_malloc (msg_size); | ||
551 | msg->header.size = htons (msg_size); | ||
552 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT); | ||
553 | msg->plugin_name_size = htons (plugin_name_len); | ||
554 | GNUNET_memcpy ((char *) &msg[1], | ||
555 | plugin_name, | ||
556 | plugin_name_len); | ||
557 | return msg; | ||
558 | } | ||
559 | |||
560 | |||
561 | /** | ||
562 | * Function which start a single helper process. | ||
563 | * | ||
564 | */ | ||
565 | static void | ||
566 | start_helper (struct NetJailState *ns, | ||
567 | unsigned int m, | ||
568 | unsigned int n) | ||
569 | { | ||
570 | struct TestcasePlugin *plugin; | ||
571 | struct GNUNET_HELPER_Handle *helper; | ||
572 | struct GNUNET_TESTING_CommandHelperInit *msg; | ||
573 | struct TestingSystemCount *tbc; | ||
574 | char *m_char; | ||
575 | char *n_char; | ||
576 | char *global_n_char; | ||
577 | char *local_m_char; | ||
578 | char *known_char; | ||
579 | char *node_id; | ||
580 | char *plugin_name; | ||
581 | char *read_file; | ||
582 | pid_t pid; | ||
583 | unsigned int script_num; | ||
584 | struct GNUNET_ShortHashCode *hkey; | ||
585 | struct GNUNET_ShortHashCode key; | ||
586 | struct GNUNET_HashCode hc; | ||
587 | struct GNUNET_TESTING_NetjailTopology *topology = ns->topology; | ||
588 | struct GNUNET_TESTING_NetjailNode *node; | ||
589 | struct GNUNET_TESTING_NetjailNode *barrier_node; | ||
590 | struct GNUNET_TESTING_NetjailNamespace *namespace; | ||
591 | char *data_dir; | ||
592 | char *script_name; | ||
593 | struct GNUNET_TESTING_BarrierListEntry *pos; | ||
594 | struct GNUNET_TESTING_Barrier *barrier; | ||
595 | struct GNUNET_TESTING_BarrierList *barriers; | ||
596 | unsigned int node_num; | ||
597 | char *binary_path; | ||
598 | |||
599 | if (0 == n) | ||
600 | { | ||
601 | node_num = m; | ||
602 | script_num = m - 1; | ||
603 | } | ||
604 | else | ||
605 | { | ||
606 | node_num = (n - 1) * ns->local_m + m + ns->known; | ||
607 | script_num = n - 1 + (n - 1) * ns->local_m + m + ns->known; | ||
608 | } | ||
609 | pid = getpid (); | ||
610 | |||
611 | GNUNET_asprintf (&m_char, "%u", m); | ||
612 | GNUNET_asprintf (&n_char, "%u", n); | ||
613 | GNUNET_asprintf (&local_m_char, "%u", ns->local_m); | ||
614 | GNUNET_asprintf (&global_n_char, "%u",ns->global_n); | ||
615 | GNUNET_asprintf (&known_char, "%u",ns->known); | ||
616 | GNUNET_asprintf (&node_id, "%s%06x-%06x\n", | ||
617 | "if", | ||
618 | pid, | ||
619 | script_num); | ||
620 | // GNUNET_asprintf (&topology_data, "'%s'", ns->topology_data); | ||
621 | GNUNET_asprintf (&read_file, | ||
622 | "%u", | ||
623 | *(ns->read_file)); | ||
624 | |||
625 | data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); | ||
626 | GNUNET_asprintf (&script_name, | ||
627 | "%s%s", | ||
628 | data_dir, | ||
629 | NETJAIL_EXEC_SCRIPT); | ||
630 | unsigned int helper_check = GNUNET_OS_check_helper_binary ( | ||
631 | script_name, | ||
632 | GNUNET_YES, | ||
633 | NULL); | ||
634 | |||
635 | tbc = GNUNET_new (struct TestingSystemCount); | ||
636 | tbc->ns = ns; | ||
637 | |||
638 | if (GNUNET_NO == helper_check) | ||
639 | { | ||
640 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
641 | "No SUID for %s!\n", | ||
642 | script_name); | ||
643 | GNUNET_TESTING_interpreter_fail (ns->is); | ||
644 | // FIXME: why continue here, instead of returning? | ||
645 | } | ||
646 | else if (GNUNET_NO == helper_check) | ||
647 | { | ||
648 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
649 | "%s not found!\n", | ||
650 | script_name); | ||
651 | GNUNET_TESTING_interpreter_fail (ns->is); | ||
652 | } | ||
653 | |||
654 | binary_path = GNUNET_OS_get_libexec_binary_path (HELPER_CMDS_BINARY); | ||
655 | |||
656 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
657 | "sysstarted %u peersstarted %u prep %u finished %u %u %u %u\n", | ||
658 | ns->number_of_testsystems_started, | ||
659 | ns->number_of_peers_started, | ||
660 | ns->number_of_local_tests_prepared, | ||
661 | ns->number_of_local_tests_finished, | ||
662 | ns->local_m, | ||
663 | ns->global_n, | ||
664 | ns->known); | ||
665 | { | ||
666 | char *const script_argv[] = {script_name, | ||
667 | m_char, | ||
668 | n_char, | ||
669 | binary_path, | ||
670 | global_n_char, | ||
671 | local_m_char, | ||
672 | node_id, | ||
673 | read_file, | ||
674 | ns->topology_data, | ||
675 | NULL}; | ||
676 | helper = GNUNET_HELPER_start ( | ||
677 | GNUNET_YES, | ||
678 | script_name, | ||
679 | script_argv, | ||
680 | &helper_mst, | ||
681 | &exp_cb, | ||
682 | ns); | ||
683 | GNUNET_array_append (ns->helper, | ||
684 | ns->n_helper, | ||
685 | helper); | ||
686 | } | ||
687 | GNUNET_TESTING_add_netjail_helper_ (ns->is, | ||
688 | helper); | ||
689 | plugin_name = topology->plugin; | ||
690 | |||
691 | hkey = GNUNET_new (struct GNUNET_ShortHashCode); | ||
692 | node = NULL; | ||
693 | if (0 == n) | ||
694 | { | ||
695 | GNUNET_CRYPTO_hash (&m, | ||
696 | sizeof(m), | ||
697 | &hc); | ||
698 | memcpy (hkey, | ||
699 | &hc, | ||
700 | sizeof (*hkey)); | ||
701 | if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_globals, | ||
702 | hkey)) | ||
703 | { | ||
704 | node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals, | ||
705 | hkey); | ||
706 | if (NULL != node->plugin) | ||
707 | plugin_name = node->plugin; | ||
708 | } | ||
709 | } | ||
710 | else | ||
711 | { | ||
712 | GNUNET_CRYPTO_hash (&n, sizeof(n), &hc); | ||
713 | memcpy (hkey, | ||
714 | &hc, | ||
715 | sizeof (*hkey)); | ||
716 | if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_namespaces, | ||
717 | hkey)) | ||
718 | { | ||
719 | namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces, | ||
720 | hkey); | ||
721 | GNUNET_CRYPTO_hash (&m, sizeof(m), &hc); | ||
722 | memcpy (hkey, | ||
723 | &hc, | ||
724 | sizeof (*hkey)); | ||
725 | if (1 == GNUNET_CONTAINER_multishortmap_contains (namespace->nodes, | ||
726 | hkey)) | ||
727 | { | ||
728 | node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes, | ||
729 | hkey); | ||
730 | if (NULL != node->plugin) | ||
731 | plugin_name = node->plugin; | ||
732 | } | ||
733 | } | ||
734 | |||
735 | |||
736 | } | ||
737 | GNUNET_assert (NULL != node); | ||
738 | node->node_number = node_num; | ||
739 | plugin = GNUNET_new (struct TestcasePlugin); | ||
740 | plugin->api = GNUNET_PLUGIN_load (plugin_name, | ||
741 | NULL); | ||
742 | barriers = plugin->api->get_waiting_for_barriers (); | ||
743 | |||
744 | |||
745 | for (pos = barriers->head; NULL != pos; pos = pos->next) | ||
746 | { | ||
747 | barrier = GNUNET_TESTING_get_barrier_ (ns->is, | ||
748 | pos->barrier_name); | ||
749 | if (NULL == barrier) | ||
750 | { | ||
751 | barrier = GNUNET_new (struct GNUNET_TESTING_Barrier); | ||
752 | barrier->name = pos->barrier_name; | ||
753 | barrier->shadow = GNUNET_YES; | ||
754 | GNUNET_TESTING_add_barrier_ (ns->is, | ||
755 | barrier); | ||
756 | } | ||
757 | barrier_node = GNUNET_new (struct GNUNET_TESTING_NetjailNode); | ||
758 | barrier_node->node_number = node->node_number; | ||
759 | barrier_node->expected_reaches = pos->expected_reaches; | ||
760 | barrier->expected_reaches = barrier->expected_reaches | ||
761 | + pos->expected_reaches; | ||
762 | if (GNUNET_YES == barrier->shadow) | ||
763 | barrier->number_to_be_reached++; | ||
764 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
765 | "Adding barrier %p %s node %u with reach target %u\n", | ||
766 | barrier, | ||
767 | pos->barrier_name, | ||
768 | node->node_number, | ||
769 | barrier->number_to_be_reached); | ||
770 | GNUNET_CRYPTO_hash (&node->node_number, | ||
771 | sizeof(node->node_number), | ||
772 | &hc); | ||
773 | memcpy (&key, &hc, sizeof (key)); | ||
774 | if (NULL == barrier->nodes) | ||
775 | barrier->nodes | ||
776 | = GNUNET_CONTAINER_multishortmap_create (16, | ||
777 | GNUNET_NO); | ||
778 | GNUNET_CONTAINER_multishortmap_put (barrier->nodes, | ||
779 | &key, | ||
780 | barrier_node, | ||
781 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
782 | } | ||
783 | |||
784 | tbc->plugin = plugin; | ||
785 | msg = create_helper_init_msg_ (plugin_name); | ||
786 | tbc->shandle = GNUNET_HELPER_send ( | ||
787 | helper, | ||
788 | &msg->header, | ||
789 | GNUNET_NO, | ||
790 | &clear_msg, | ||
791 | tbc); | ||
792 | |||
793 | if (NULL == tbc->shandle) | ||
794 | { | ||
795 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
796 | "Send handle is NULL!\n"); | ||
797 | GNUNET_TESTING_interpreter_fail (ns->is); | ||
798 | } | ||
799 | GNUNET_free (pos); | ||
800 | GNUNET_free (binary_path); | ||
801 | GNUNET_free (hkey); | ||
802 | GNUNET_free (msg); | ||
803 | GNUNET_free (m_char); | ||
804 | GNUNET_free (n_char); | ||
805 | GNUNET_free (local_m_char); | ||
806 | GNUNET_free (global_n_char); | ||
807 | GNUNET_free (known_char); | ||
808 | GNUNET_free (node_id); | ||
809 | GNUNET_free (read_file); | ||
810 | GNUNET_free (data_dir); | ||
811 | GNUNET_free (script_name); | ||
812 | GNUNET_free (barriers); | ||
813 | } | ||
814 | |||
815 | |||
816 | /** | ||
817 | * Function run when the cmd terminates (good or bad) with timeout. | ||
818 | * | ||
819 | * @param cls the interpreter state | ||
820 | */ | ||
821 | static void | ||
822 | do_timeout (void *cls) | ||
823 | { | ||
824 | struct NetJailState *ns = cls; | ||
825 | struct GNUNET_TESTING_Command *cmd; | ||
826 | |||
827 | ns->timeout_task = NULL; | ||
828 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
829 | "Terminating cmd due to global timeout\n"); | ||
830 | cmd = GNUNET_TESTING_interpreter_get_current_command (ns->is); | ||
831 | GNUNET_TESTING_async_finish (cmd->ac); | ||
832 | } | ||
833 | |||
834 | |||
835 | /** | ||
836 | * This function starts a helper process for each node. | ||
837 | * | ||
838 | * @param cls closure. | ||
839 | * @param cmd CMD being run. | ||
840 | * @param is interpreter state. | ||
841 | */ | ||
842 | static void | ||
843 | netjail_exec_run (void *cls, | ||
844 | struct GNUNET_TESTING_Interpreter *is) | ||
845 | { | ||
846 | struct NetJailState *ns = cls; | ||
847 | |||
848 | ns->is = is; | ||
849 | for (int i = 1; i <= ns->known; i++) | ||
850 | { | ||
851 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
852 | "i %u\n", | ||
853 | i); | ||
854 | start_helper (ns, | ||
855 | i, | ||
856 | 0); | ||
857 | } | ||
858 | |||
859 | for (int i = 1; i <= ns->global_n; i++) | ||
860 | { | ||
861 | for (int j = 1; j <= ns->local_m; j++) | ||
862 | { | ||
863 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
864 | "i %u j %u\n", | ||
865 | i, | ||
866 | j); | ||
867 | start_helper (ns, | ||
868 | j, | ||
869 | i); | ||
870 | } | ||
871 | } | ||
872 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
873 | "Adding timeout %s\n", | ||
874 | GNUNET_STRINGS_relative_time_to_string (ns->timeout, GNUNET_NO)); | ||
875 | ns->timeout_task | ||
876 | = GNUNET_SCHEDULER_add_delayed (ns->timeout, | ||
877 | &do_timeout, | ||
878 | ns); | ||
879 | } | ||
880 | |||
881 | |||
882 | /** | ||
883 | * Create command. | ||
884 | * | ||
885 | * @param label Name for the command. | ||
886 | * @param topology The complete topology information. | ||
887 | * @param read_file Flag indicating if the the name of the topology file is send to the helper, or a string with the topology data. | ||
888 | * @param topology_data If read_file is GNUNET_NO, topology_data holds the string with the topology. | ||
889 | * @param timeout Before this timeout is reached this cmd MUST finish. | ||
890 | * @return command. | ||
891 | */ | ||
892 | struct GNUNET_TESTING_Command | ||
893 | GNUNET_TESTING_cmd_netjail_start_cmds_helper ( | ||
894 | const char *label, | ||
895 | struct GNUNET_TESTING_NetjailTopology *topology, | ||
896 | unsigned int *read_file, | ||
897 | char *topology_data, | ||
898 | struct GNUNET_TIME_Relative timeout) | ||
899 | { | ||
900 | struct NetJailState *ns; | ||
901 | |||
902 | ns = GNUNET_new (struct NetJailState); | ||
903 | ns->local_m = topology->nodes_m; | ||
904 | ns->global_n = topology->namespaces_n; | ||
905 | ns->known = topology->nodes_x; | ||
906 | ns->plugin_name = topology->plugin; | ||
907 | ns->topology = topology; | ||
908 | ns->read_file = read_file; | ||
909 | ns->topology_data = topology_data; | ||
910 | ns->timeout = GNUNET_TIME_relative_subtract (timeout, TIMEOUT); | ||
911 | |||
912 | return GNUNET_TESTING_command_new (ns, label, | ||
913 | &netjail_exec_run, | ||
914 | &netjail_exec_cleanup, | ||
915 | &netjail_exec_traits, | ||
916 | &ns->ac); | ||
917 | } | ||
diff --git a/src/service/testing/testing_api_cmd_netjail_stop.c b/src/service/testing/testing_api_cmd_netjail_stop.c deleted file mode 100644 index cc05617f7..000000000 --- a/src/service/testing/testing_api_cmd_netjail_stop.c +++ /dev/null | |||
@@ -1,200 +0,0 @@ | |||
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_netjail_stop.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_testing_plugin.h" | ||
30 | #include "gnunet_testing_barrier.h" | ||
31 | #include "gnunet_testing_netjail_lib.h" | ||
32 | |||
33 | |||
34 | #define NETJAIL_STOP_SCRIPT "netjail_stop.sh" | ||
35 | |||
36 | /** | ||
37 | * Struct to hold information for callbacks. | ||
38 | * | ||
39 | */ | ||
40 | struct NetJailState | ||
41 | { | ||
42 | /** | ||
43 | * Context for our asynchronous completion. | ||
44 | */ | ||
45 | struct GNUNET_TESTING_AsyncContext ac; | ||
46 | |||
47 | // Child Wait handle | ||
48 | struct GNUNET_ChildWaitHandle *cwh; | ||
49 | |||
50 | /** | ||
51 | * Configuration file for the test topology. | ||
52 | */ | ||
53 | char *topology_config; | ||
54 | |||
55 | /** | ||
56 | * The process id of the start script. | ||
57 | */ | ||
58 | struct GNUNET_OS_Process *stop_proc; | ||
59 | |||
60 | /** | ||
61 | * Shall we read the topology from file, or from a string. | ||
62 | */ | ||
63 | unsigned int *read_file; | ||
64 | |||
65 | }; | ||
66 | |||
67 | |||
68 | /** | ||
69 | * The cleanup function of this cmd frees resources the cmd allocated. | ||
70 | * | ||
71 | */ | ||
72 | static void | ||
73 | netjail_stop_cleanup (void *cls) | ||
74 | { | ||
75 | struct NetJailState *ns = cls; | ||
76 | |||
77 | if (NULL != ns->cwh) | ||
78 | { | ||
79 | GNUNET_wait_child_cancel (ns->cwh); | ||
80 | ns->cwh = NULL; | ||
81 | } | ||
82 | if (NULL != ns->stop_proc) | ||
83 | { | ||
84 | GNUNET_assert (0 == | ||
85 | GNUNET_OS_process_kill (ns->stop_proc, | ||
86 | SIGKILL)); | ||
87 | GNUNET_assert (GNUNET_OK == | ||
88 | GNUNET_OS_process_wait (ns->stop_proc)); | ||
89 | GNUNET_OS_process_destroy (ns->stop_proc); | ||
90 | ns->stop_proc = NULL; | ||
91 | } | ||
92 | GNUNET_free (ns); | ||
93 | } | ||
94 | |||
95 | |||
96 | /** | ||
97 | * Callback which will be called if the setup script finished. | ||
98 | * | ||
99 | */ | ||
100 | static void | ||
101 | child_completed_callback (void *cls, | ||
102 | enum GNUNET_OS_ProcessStatusType type, | ||
103 | long unsigned int exit_code) | ||
104 | { | ||
105 | struct NetJailState *ns = cls; | ||
106 | |||
107 | ns->cwh = NULL; | ||
108 | GNUNET_OS_process_destroy (ns->stop_proc); | ||
109 | ns->stop_proc = NULL; | ||
110 | if (0 == exit_code) | ||
111 | { | ||
112 | GNUNET_TESTING_async_finish (&ns->ac); | ||
113 | } | ||
114 | else | ||
115 | { | ||
116 | GNUNET_TESTING_async_fail (&ns->ac); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | |||
121 | /** | ||
122 | * The run method starts the script which deletes the network namespaces. | ||
123 | * | ||
124 | * @param cls closure. | ||
125 | * @param is interpreter state. | ||
126 | */ | ||
127 | static void | ||
128 | netjail_stop_run (void *cls, | ||
129 | struct GNUNET_TESTING_Interpreter *is) | ||
130 | { | ||
131 | struct NetJailState *ns = cls; | ||
132 | char *pid; | ||
133 | char *data_dir; | ||
134 | char *script_name; | ||
135 | char *read_file; | ||
136 | |||
137 | |||
138 | data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); | ||
139 | GNUNET_asprintf (&script_name, "%s%s", data_dir, NETJAIL_STOP_SCRIPT); | ||
140 | GNUNET_asprintf (&read_file, "%u", *(ns->read_file)); | ||
141 | unsigned int helper_check = GNUNET_OS_check_helper_binary ( | ||
142 | script_name, | ||
143 | GNUNET_YES, | ||
144 | NULL); | ||
145 | |||
146 | if (GNUNET_NO == helper_check) | ||
147 | { | ||
148 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
149 | "No SUID for %s!\n", | ||
150 | script_name); | ||
151 | GNUNET_TESTING_interpreter_fail (is); | ||
152 | } | ||
153 | else if (GNUNET_NO == helper_check) | ||
154 | { | ||
155 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
156 | "%s not found!\n", | ||
157 | script_name); | ||
158 | GNUNET_TESTING_interpreter_fail (is); | ||
159 | } | ||
160 | |||
161 | GNUNET_asprintf (&pid, | ||
162 | "%u", | ||
163 | getpid ()); | ||
164 | { | ||
165 | char *const script_argv[] = {script_name, | ||
166 | ns->topology_config, | ||
167 | pid, | ||
168 | read_file, | ||
169 | NULL}; | ||
170 | ns->stop_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR, | ||
171 | NULL, | ||
172 | NULL, | ||
173 | NULL, | ||
174 | script_name, | ||
175 | script_argv); | ||
176 | } | ||
177 | ns->cwh = GNUNET_wait_child (ns->stop_proc, | ||
178 | &child_completed_callback, | ||
179 | ns); | ||
180 | GNUNET_break (NULL != ns->cwh); | ||
181 | GNUNET_free (read_file); | ||
182 | GNUNET_free (pid); | ||
183 | } | ||
184 | |||
185 | |||
186 | struct GNUNET_TESTING_Command | ||
187 | GNUNET_TESTING_cmd_netjail_stop (const char *label, | ||
188 | char *topology_config, | ||
189 | unsigned int *read_file) | ||
190 | { | ||
191 | struct NetJailState *ns; | ||
192 | |||
193 | ns = GNUNET_new (struct NetJailState); | ||
194 | ns->topology_config = topology_config; | ||
195 | ns->read_file = read_file; | ||
196 | return GNUNET_TESTING_command_new (ns, label, | ||
197 | &netjail_stop_run, | ||
198 | &netjail_stop_cleanup, | ||
199 | NULL, &ns->ac); | ||
200 | } | ||
diff --git a/src/service/testing/testing_api_cmd_netjail_stop_cmds_helper.c b/src/service/testing/testing_api_cmd_netjail_stop_cmds_helper.c deleted file mode 100644 index c6bb0ab52..000000000 --- a/src/service/testing/testing_api_cmd_netjail_stop_cmds_helper.c +++ /dev/null | |||
@@ -1,157 +0,0 @@ | |||
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_testing_plugin.h" | ||
29 | #include "gnunet_testing_barrier.h" | ||
30 | #include "gnunet_testing_netjail_lib.h" | ||
31 | #include "testing_cmds.h" | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Struct to store information handed over to callbacks. | ||
36 | * | ||
37 | */ | ||
38 | struct StopHelperState | ||
39 | { | ||
40 | |||
41 | /** | ||
42 | * The complete topology information. | ||
43 | */ | ||
44 | struct GNUNET_TESTING_NetjailTopology *topology; | ||
45 | |||
46 | const char *helper_start_label; | ||
47 | |||
48 | /** | ||
49 | * The process handle | ||
50 | */ | ||
51 | struct GNUNET_HELPER_Handle **helper; | ||
52 | |||
53 | unsigned int local_m; | ||
54 | |||
55 | unsigned int global_n; | ||
56 | |||
57 | /** | ||
58 | * Number of global known nodes. | ||
59 | * | ||
60 | */ | ||
61 | unsigned int known; | ||
62 | }; | ||
63 | |||
64 | |||
65 | /** | ||
66 | * Code to clean up resource this cmd used. | ||
67 | * | ||
68 | * @param cls closure | ||
69 | * @param cmd current CMD being cleaned up. | ||
70 | */ | ||
71 | static void | ||
72 | stop_testing_system_cleanup (void *cls) | ||
73 | { | ||
74 | struct StopHelperState *shs = cls; | ||
75 | |||
76 | GNUNET_free (shs); | ||
77 | } | ||
78 | |||
79 | |||
80 | /** | ||
81 | * This function stops the helper process for each node. | ||
82 | * | ||
83 | * @param cls closure. | ||
84 | * @param is interpreter state. | ||
85 | */ | ||
86 | static void | ||
87 | stop_testing_system_run (void *cls, | ||
88 | struct GNUNET_TESTING_Interpreter *is) | ||
89 | { | ||
90 | struct StopHelperState *shs = cls; | ||
91 | const struct GNUNET_HELPER_Handle **helper; | ||
92 | const struct GNUNET_TESTING_Command *start_helper_cmd; | ||
93 | |||
94 | start_helper_cmd = GNUNET_TESTING_interpreter_lookup_command (is, | ||
95 | shs-> | ||
96 | helper_start_label); | ||
97 | GNUNET_TESTING_get_trait_helper_handles (start_helper_cmd, | ||
98 | &helper); | ||
99 | |||
100 | for (int i = 1; i <= shs->known; i++) | ||
101 | { | ||
102 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
103 | "i: %u\n", | ||
104 | i); | ||
105 | GNUNET_HELPER_stop ( | ||
106 | (struct GNUNET_HELPER_Handle *) helper[i - 1], | ||
107 | GNUNET_YES); | ||
108 | } | ||
109 | |||
110 | for (int i = 1; i <= shs->global_n; i++) | ||
111 | { | ||
112 | for (int j = 1; j <= shs->local_m; j++) | ||
113 | { | ||
114 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
115 | "i: %u j: %u\n", | ||
116 | i, | ||
117 | j); | ||
118 | GNUNET_HELPER_stop ((struct GNUNET_HELPER_Handle *) helper[(i - 1) | ||
119 | * shs->local_m | ||
120 | + j | ||
121 | + shs->known | ||
122 | - 1], | ||
123 | GNUNET_YES); | ||
124 | } | ||
125 | } | ||
126 | GNUNET_free (helper); | ||
127 | } | ||
128 | |||
129 | |||
130 | /** | ||
131 | * Create command. | ||
132 | * | ||
133 | * @param label name for command. | ||
134 | * @param helper_start_label label of the cmd to start the test system. | ||
135 | * @param topology The complete topology information. | ||
136 | * @return command. | ||
137 | */ | ||
138 | struct GNUNET_TESTING_Command | ||
139 | GNUNET_TESTING_cmd_stop_cmds_helper ( | ||
140 | const char *label, | ||
141 | const char *helper_start_label, | ||
142 | struct GNUNET_TESTING_NetjailTopology *topology) | ||
143 | { | ||
144 | struct StopHelperState *shs; | ||
145 | |||
146 | shs = GNUNET_new (struct StopHelperState); | ||
147 | shs->helper_start_label = helper_start_label; | ||
148 | shs->local_m = topology->nodes_m; | ||
149 | shs->global_n = topology->namespaces_n; | ||
150 | shs->known = topology->nodes_x; | ||
151 | shs->topology = topology; | ||
152 | |||
153 | return GNUNET_TESTING_command_new (shs, label, | ||
154 | &stop_testing_system_run, | ||
155 | &stop_testing_system_cleanup, | ||
156 | NULL, NULL); | ||
157 | } | ||
diff --git a/src/service/testing/testing_api_cmd_send_peer_ready.c b/src/service/testing/testing_api_cmd_send_peer_ready.c deleted file mode 100644 index f615a1cee..000000000 --- a/src/service/testing/testing_api_cmd_send_peer_ready.c +++ /dev/null | |||
@@ -1,123 +0,0 @@ | |||
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_api_cmd_send_peer_ready.c | ||
23 | * @brief cmd to send a helper message if peer is ready. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_ng_lib.h" | ||
29 | #include "gnunet_testing_plugin.h" | ||
30 | #include "gnunet_testing_barrier.h" | ||
31 | #include "gnunet_testing_netjail_lib.h" | ||
32 | #include "testing_cmds.h" | ||
33 | |||
34 | |||
35 | /** | ||
36 | * Struct to hold information for callbacks. | ||
37 | * | ||
38 | */ | ||
39 | struct SendPeerReadyState | ||
40 | { | ||
41 | /** | ||
42 | * Callback to write messages to the master loop. | ||
43 | * | ||
44 | */ | ||
45 | GNUNET_TESTING_cmd_helper_write_cb write_message; | ||
46 | |||
47 | /** | ||
48 | * The message send back to the master loop. | ||
49 | * | ||
50 | */ | ||
51 | struct GNUNET_TESTING_CommandPeerStarted *reply; | ||
52 | }; | ||
53 | |||
54 | |||
55 | /** | ||
56 | * Trait function of this cmd does nothing. | ||
57 | * | ||
58 | */ | ||
59 | static enum GNUNET_GenericReturnValue | ||
60 | send_peer_ready_traits (void *cls, | ||
61 | const void **ret, | ||
62 | const char *trait, | ||
63 | unsigned int index) | ||
64 | { | ||
65 | return GNUNET_NO; | ||
66 | } | ||
67 | |||
68 | |||
69 | /** | ||
70 | * The cleanup function of this cmd frees resources the cmd allocated. | ||
71 | * | ||
72 | */ | ||
73 | static void | ||
74 | send_peer_ready_cleanup (void *cls) | ||
75 | { | ||
76 | struct SendPeerReadyState *sprs = cls; | ||
77 | |||
78 | GNUNET_free (sprs); | ||
79 | } | ||
80 | |||
81 | |||
82 | /** | ||
83 | * This function sends a GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED message to the master loop. | ||
84 | * | ||
85 | */ | ||
86 | static void | ||
87 | send_peer_ready_run (void *cls, | ||
88 | struct GNUNET_TESTING_Interpreter *is) | ||
89 | { | ||
90 | struct SendPeerReadyState *sprs = cls; | ||
91 | struct GNUNET_TESTING_CommandPeerStarted *reply; | ||
92 | size_t msg_length; | ||
93 | |||
94 | msg_length = sizeof(struct GNUNET_TESTING_CommandPeerStarted); | ||
95 | reply = GNUNET_new (struct GNUNET_TESTING_CommandPeerStarted); | ||
96 | reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED); | ||
97 | reply->header.size = htons ((uint16_t) msg_length); | ||
98 | sprs->reply = reply; | ||
99 | sprs->write_message ((struct GNUNET_MessageHeader *) reply, msg_length); | ||
100 | } | ||
101 | |||
102 | |||
103 | /** | ||
104 | * Create command. | ||
105 | * | ||
106 | * @param label name for command. | ||
107 | * @param write_message Callback to write messages to the master loop. | ||
108 | * @return command. | ||
109 | */ | ||
110 | struct GNUNET_TESTING_Command | ||
111 | GNUNET_TESTING_cmd_send_peer_ready (const char *label, | ||
112 | GNUNET_TESTING_cmd_helper_write_cb | ||
113 | write_message) | ||
114 | { | ||
115 | struct SendPeerReadyState *sprs; | ||
116 | |||
117 | sprs = GNUNET_new (struct SendPeerReadyState); | ||
118 | sprs->write_message = write_message; | ||
119 | return GNUNET_TESTING_command_new (sprs, label, | ||
120 | &send_peer_ready_run, | ||
121 | &send_peer_ready_cleanup, | ||
122 | &send_peer_ready_traits, NULL); | ||
123 | } | ||
diff --git a/src/service/testing/testing_api_cmd_system_destroy.c b/src/service/testing/testing_api_cmd_system_destroy.c deleted file mode 100644 index 45adfd0da..000000000 --- a/src/service/testing/testing_api_cmd_system_destroy.c +++ /dev/null | |||
@@ -1,111 +0,0 @@ | |||
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_api_cmd_system_destroy.c | ||
23 | * @brief cmd to destroy a testing system handle. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_ng_lib.h" | ||
29 | #include "gnunet_testing_plugin.h" | ||
30 | #include "gnunet_testing_netjail_lib.h" | ||
31 | #include "gnunet_testing_lib.h" | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Struct to hold information for callbacks. | ||
36 | * | ||
37 | */ | ||
38 | struct TestSystemState | ||
39 | { | ||
40 | // Label of the cmd which started the test system. | ||
41 | const char *create_label; | ||
42 | }; | ||
43 | |||
44 | |||
45 | /** | ||
46 | * The run method of this cmd will remove the test environment for a node. | ||
47 | * | ||
48 | */ | ||
49 | static void | ||
50 | system_destroy_run (void *cls, | ||
51 | struct GNUNET_TESTING_Interpreter *is) | ||
52 | { | ||
53 | struct TestSystemState *tss = cls; | ||
54 | const struct GNUNET_TESTING_Command *system_cmd; | ||
55 | const struct GNUNET_TESTING_System *tl_system; | ||
56 | |||
57 | system_cmd = GNUNET_TESTING_interpreter_lookup_command (is, | ||
58 | tss->create_label); | ||
59 | GNUNET_TESTING_get_trait_test_system (system_cmd, | ||
60 | &tl_system); | ||
61 | GNUNET_TESTING_system_destroy ((struct GNUNET_TESTING_System *) tl_system, | ||
62 | GNUNET_YES); | ||
63 | } | ||
64 | |||
65 | |||
66 | /** | ||
67 | * The cleanup function of this cmd frees resources the cmd allocated. | ||
68 | * | ||
69 | */ | ||
70 | static void | ||
71 | system_destroy_cleanup (void *cls) | ||
72 | { | ||
73 | struct TestSystemState *tss = cls; | ||
74 | |||
75 | GNUNET_free (tss); | ||
76 | } | ||
77 | |||
78 | |||
79 | /** | ||
80 | * Trait function of this cmd does nothing. | ||
81 | * | ||
82 | */ | ||
83 | static enum GNUNET_GenericReturnValue | ||
84 | system_destroy_traits (void *cls, | ||
85 | const void **ret, | ||
86 | const char *trait, | ||
87 | unsigned int index) | ||
88 | { | ||
89 | return GNUNET_OK; | ||
90 | } | ||
91 | |||
92 | |||
93 | /** | ||
94 | * Create command. | ||
95 | * | ||
96 | * @param label name for command. | ||
97 | * @param create_label Label of the cmd which started the test system. | ||
98 | * @return command. | ||
99 | */ | ||
100 | struct GNUNET_TESTING_Command | ||
101 | GNUNET_TESTING_cmd_system_destroy (const char *label, | ||
102 | const char *create_label) | ||
103 | { | ||
104 | struct TestSystemState *tss; | ||
105 | |||
106 | tss = GNUNET_new (struct TestSystemState); | ||
107 | tss->create_label = create_label; | ||
108 | return GNUNET_TESTING_command_new (tss, label, &system_destroy_run, | ||
109 | &system_destroy_cleanup, | ||
110 | &system_destroy_traits, NULL); | ||
111 | } | ||
diff --git a/src/service/testing/testing_api_loop.c b/src/service/testing/testing_api_loop.c deleted file mode 100644 index beb9b9060..000000000 --- a/src/service/testing/testing_api_loop.c +++ /dev/null | |||
@@ -1,893 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2021-2023 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_loop.c | ||
23 | * @brief main interpreter loop for testcases | ||
24 | * @author Christian Grothoff (GNU Taler testing) | ||
25 | * @author Marcello Stanisci (GNU Taler testing) | ||
26 | * @author t3sserakt | ||
27 | */ | ||
28 | #include "platform.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_testing_ng_lib.h" | ||
31 | #include "gnunet_testing_plugin.h" | ||
32 | #include "gnunet_testing_barrier.h" | ||
33 | #include "gnunet_testing_netjail_lib.h" | ||
34 | #include "testing.h" | ||
35 | |||
36 | /** | ||
37 | * Global state of the interpreter, used by a command | ||
38 | * to access information about other commands. | ||
39 | */ | ||
40 | struct GNUNET_TESTING_Interpreter | ||
41 | { | ||
42 | /** | ||
43 | * Array with handles of helper processes for communication with netjails. | ||
44 | */ | ||
45 | const struct GNUNET_HELPER_Handle **helper; | ||
46 | |||
47 | /** | ||
48 | * Handle to a send op | ||
49 | */ | ||
50 | struct GNUNET_HELPER_SendHandle *send_handle; | ||
51 | |||
52 | /** | ||
53 | * Function to call with the test result. | ||
54 | */ | ||
55 | GNUNET_TESTING_ResultCallback rc; | ||
56 | |||
57 | /** | ||
58 | * Closure for @e rc. | ||
59 | */ | ||
60 | void *rc_cls; | ||
61 | |||
62 | /** | ||
63 | * Commands the interpreter will run. | ||
64 | */ | ||
65 | struct GNUNET_TESTING_Command *commands; | ||
66 | |||
67 | /** | ||
68 | * Map with barriers for this loop. | ||
69 | */ | ||
70 | struct GNUNET_CONTAINER_MultiShortmap *barriers; | ||
71 | |||
72 | /** | ||
73 | * Interpreter task (if one is scheduled). | ||
74 | */ | ||
75 | struct GNUNET_SCHEDULER_Task *task; | ||
76 | |||
77 | /** | ||
78 | * Final task that returns the result. | ||
79 | */ | ||
80 | struct GNUNET_SCHEDULER_Task *final_task; | ||
81 | |||
82 | /** | ||
83 | * Task run on timeout. | ||
84 | */ | ||
85 | struct GNUNET_SCHEDULER_Task *timeout_task; | ||
86 | |||
87 | /** | ||
88 | * Number of GNUNET_TESTING_Command in @e commands. | ||
89 | */ | ||
90 | unsigned int cmds_n; | ||
91 | |||
92 | /** | ||
93 | * Size of the array @e helper. | ||
94 | */ | ||
95 | unsigned int n_helper; | ||
96 | |||
97 | /** | ||
98 | * Instruction pointer. Tells #interpreter_run() which instruction to run | ||
99 | * next. Need (signed) int because it gets -1 when rewinding the | ||
100 | * interpreter to the first CMD. | ||
101 | */ | ||
102 | int ip; | ||
103 | |||
104 | /** | ||
105 | * Result of the testcases, #GNUNET_OK on success | ||
106 | */ | ||
107 | enum GNUNET_GenericReturnValue result; | ||
108 | |||
109 | /** | ||
110 | * Is the interpreter finishing? | ||
111 | */ | ||
112 | bool finishing; | ||
113 | |||
114 | }; | ||
115 | |||
116 | |||
117 | /** | ||
118 | * Lookup command by label. | ||
119 | * | ||
120 | * @param is interpreter to lookup command in | ||
121 | * @param label label of the command to lookup. | ||
122 | * @param future true to look into the future, false to look into the past | ||
123 | * @return the command, if it is found, or NULL. | ||
124 | */ | ||
125 | static const struct GNUNET_TESTING_Command * | ||
126 | get_command (struct GNUNET_TESTING_Interpreter *is, | ||
127 | const char *label, | ||
128 | bool future) | ||
129 | { | ||
130 | int start_i = future ? is->cmds_n - 1 : is->ip; | ||
131 | int end_i = future ? is->ip + 1 : 0; | ||
132 | |||
133 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
134 | "start_i: %u end_i: %u\n", | ||
135 | start_i, | ||
136 | end_i); | ||
137 | if (NULL == label) | ||
138 | { | ||
139 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
140 | "Attempt to lookup command for empty label\n"); | ||
141 | return NULL; | ||
142 | } | ||
143 | for (int i = start_i; i >= end_i; i--) | ||
144 | { | ||
145 | const struct GNUNET_TESTING_Command *cmd = &is->commands[i]; | ||
146 | |||
147 | if (NULL != cmd->run) | ||
148 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
149 | "label to compare %s\n", | ||
150 | cmd->label.value); | ||
151 | /* Give precedence to top-level commands. */ | ||
152 | if ( (NULL != cmd->run) && | ||
153 | (0 == strcmp (cmd->label.value, | ||
154 | label)) ) | ||
155 | return cmd; | ||
156 | |||
157 | if (GNUNET_TESTING_cmd_is_batch_ (cmd)) | ||
158 | { | ||
159 | struct GNUNET_TESTING_Command **batch; | ||
160 | struct GNUNET_TESTING_Command *current; | ||
161 | const struct GNUNET_TESTING_Command *icmd; | ||
162 | const struct GNUNET_TESTING_Command *match; | ||
163 | |||
164 | current = GNUNET_TESTING_cmd_batch_get_current_ (cmd); | ||
165 | GNUNET_assert (GNUNET_OK == | ||
166 | GNUNET_TESTING_get_trait_batch_cmds (cmd, | ||
167 | &batch)); | ||
168 | /* We must do the loop forward, but we can find the last match */ | ||
169 | match = NULL; | ||
170 | for (unsigned int j = 0; | ||
171 | NULL != (icmd = &(*batch)[j])->run; | ||
172 | j++) | ||
173 | { | ||
174 | if (current == icmd) | ||
175 | break; /* do not go past current command */ | ||
176 | if ( (NULL != icmd->run) && | ||
177 | (0 == strcmp (icmd->label.value, | ||
178 | label)) ) | ||
179 | match = icmd; | ||
180 | } | ||
181 | if (NULL != match) | ||
182 | return match; | ||
183 | } | ||
184 | } | ||
185 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
186 | "Command `%s' not found\n", | ||
187 | label); | ||
188 | return NULL; | ||
189 | } | ||
190 | |||
191 | |||
192 | const struct GNUNET_TESTING_Command * | ||
193 | GNUNET_TESTING_interpreter_lookup_future_command ( | ||
194 | struct GNUNET_TESTING_Interpreter *is, | ||
195 | const char *label) | ||
196 | { | ||
197 | return get_command (is, | ||
198 | label, | ||
199 | true); | ||
200 | } | ||
201 | |||
202 | |||
203 | const struct GNUNET_TESTING_Command * | ||
204 | GNUNET_TESTING_interpreter_lookup_command ( | ||
205 | struct GNUNET_TESTING_Interpreter *is, | ||
206 | const char *label) | ||
207 | { | ||
208 | return get_command (is, | ||
209 | label, | ||
210 | false); | ||
211 | } | ||
212 | |||
213 | |||
214 | const struct GNUNET_TESTING_Command * | ||
215 | GNUNET_TESTING_interpreter_lookup_command_all ( | ||
216 | struct GNUNET_TESTING_Interpreter *is, | ||
217 | const char *label) | ||
218 | { | ||
219 | const struct GNUNET_TESTING_Command *cmd; | ||
220 | |||
221 | cmd = get_command (is, | ||
222 | label, | ||
223 | false); | ||
224 | if (NULL == cmd) | ||
225 | cmd = get_command (is, | ||
226 | label, | ||
227 | true); | ||
228 | return cmd; | ||
229 | } | ||
230 | |||
231 | |||
232 | /** | ||
233 | * Continuation function from GNUNET_HELPER_send() | ||
234 | * | ||
235 | * @param cls closure | ||
236 | * @param result #GNUNET_OK on success, | ||
237 | * #GNUNET_NO if helper process died | ||
238 | * #GNUNET_SYSERR during GNUNET_HELPER_stop() | ||
239 | */ | ||
240 | static void | ||
241 | clear_msg (void *cls, | ||
242 | enum GNUNET_GenericReturnValue result) | ||
243 | { | ||
244 | GNUNET_assert (GNUNET_YES == result); | ||
245 | } | ||
246 | |||
247 | |||
248 | /** | ||
249 | * Send message to a netjail node that a barrier can be crossed. | ||
250 | * | ||
251 | * @param is The interpreter loop. | ||
252 | * @param barrier_name The name of the barrier to cross. | ||
253 | * @param global_node_number The global number of the node to inform. | ||
254 | */ | ||
255 | static void | ||
256 | send_barrier_crossable (struct GNUNET_TESTING_Interpreter *is, | ||
257 | const char *barrier_name, | ||
258 | unsigned int global_node_number) | ||
259 | { | ||
260 | struct CommandBarrierCrossable *adm; | ||
261 | size_t msg_length; | ||
262 | size_t name_len; | ||
263 | |||
264 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
265 | "send barrier crossable for barrier `%s'\n", | ||
266 | barrier_name); | ||
267 | name_len = strlen (barrier_name); | ||
268 | msg_length = sizeof(struct CommandBarrierCrossable) + name_len + 1; | ||
269 | adm = GNUNET_malloc (msg_length); | ||
270 | adm->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_CROSSABLE); | ||
271 | adm->header.size = htons ((uint16_t) msg_length); | ||
272 | memcpy (&adm[1], barrier_name, name_len); | ||
273 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
274 | "send message of type %u to locals\n", | ||
275 | ntohs (adm->header.type)); | ||
276 | /** | ||
277 | FIXME: This should probably be put into a linked list | ||
278 | inside is and cleaned up at some point. | ||
279 | */ | ||
280 | is->send_handle = GNUNET_HELPER_send ( | ||
281 | (struct GNUNET_HELPER_Handle *) is->helper[global_node_number - 1], | ||
282 | &adm->header, | ||
283 | GNUNET_NO, | ||
284 | &clear_msg, | ||
285 | NULL); | ||
286 | GNUNET_free (adm); | ||
287 | } | ||
288 | |||
289 | |||
290 | /** | ||
291 | * Closure for #free_barrier_node_cb(). | ||
292 | */ | ||
293 | struct FreeBarrierNodeCbCls | ||
294 | { | ||
295 | /** | ||
296 | * The interpreter. | ||
297 | */ | ||
298 | struct GNUNET_TESTING_Interpreter *is; | ||
299 | |||
300 | /** | ||
301 | * The barrier from which the nodes are freed.. | ||
302 | */ | ||
303 | struct GNUNET_TESTING_Barrier *barrier; | ||
304 | }; | ||
305 | |||
306 | |||
307 | static enum GNUNET_GenericReturnValue | ||
308 | free_barrier_node_cb (void *cls, | ||
309 | const struct GNUNET_ShortHashCode *key, | ||
310 | void *value) | ||
311 | { | ||
312 | struct FreeBarrierNodeCbCls *free_barrier_node_cb_cls = cls; | ||
313 | struct GNUNET_TESTING_NetjailNode *node = value; | ||
314 | struct GNUNET_TESTING_Barrier *barrier = free_barrier_node_cb_cls->barrier; | ||
315 | struct GNUNET_TESTING_Interpreter *is = free_barrier_node_cb_cls->is; | ||
316 | |||
317 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
318 | "free_barrier_node_cb\n"); | ||
319 | if (! is->finishing) | ||
320 | { | ||
321 | send_barrier_crossable (is, | ||
322 | barrier->name, | ||
323 | node->node_number); | ||
324 | } | ||
325 | GNUNET_assert (GNUNET_YES == | ||
326 | GNUNET_CONTAINER_multishortmap_remove ( | ||
327 | barrier->nodes, | ||
328 | key, | ||
329 | node)); | ||
330 | return GNUNET_YES; | ||
331 | } | ||
332 | |||
333 | |||
334 | static void | ||
335 | free_barrier_nodes (struct GNUNET_TESTING_Interpreter *is, | ||
336 | struct GNUNET_TESTING_Barrier *barrier) | ||
337 | { | ||
338 | struct FreeBarrierNodeCbCls free_barrier_node_cb_cls = { | ||
339 | .barrier = barrier, | ||
340 | .is = is | ||
341 | }; | ||
342 | |||
343 | if (NULL == barrier->nodes) | ||
344 | return; | ||
345 | GNUNET_CONTAINER_multishortmap_iterate (barrier->nodes, | ||
346 | free_barrier_node_cb, | ||
347 | &free_barrier_node_cb_cls); | ||
348 | GNUNET_CONTAINER_multishortmap_destroy (barrier->nodes); | ||
349 | barrier->nodes = NULL; | ||
350 | } | ||
351 | |||
352 | |||
353 | static enum GNUNET_GenericReturnValue | ||
354 | free_barriers_cb (void *cls, | ||
355 | const struct GNUNET_ShortHashCode *key, | ||
356 | void *value) | ||
357 | { | ||
358 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
359 | struct GNUNET_TESTING_Barrier *barrier = value; | ||
360 | struct CommandListEntry *pos; | ||
361 | |||
362 | free_barrier_nodes (is, | ||
363 | barrier); | ||
364 | while (NULL != (pos = barrier->cmds_head)) | ||
365 | { | ||
366 | GNUNET_CONTAINER_DLL_remove (barrier->cmds_head, | ||
367 | barrier->cmds_tail, | ||
368 | pos); | ||
369 | GNUNET_free (pos); | ||
370 | } | ||
371 | GNUNET_free (barrier); | ||
372 | return GNUNET_YES; | ||
373 | } | ||
374 | |||
375 | |||
376 | /** | ||
377 | * Finish the test run, return the final result. | ||
378 | * | ||
379 | * @param cls the `struct GNUNET_TESTING_Interpreter` | ||
380 | */ | ||
381 | static void | ||
382 | finish_test (void *cls) | ||
383 | { | ||
384 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
385 | struct GNUNET_TESTING_Command *cmd; | ||
386 | const char *label; | ||
387 | |||
388 | is->finishing = true; | ||
389 | is->final_task = NULL; | ||
390 | label = is->commands[is->ip].label.value; | ||
391 | if (NULL == is->commands[is->ip].run) | ||
392 | label = "END"; | ||
393 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
394 | "Interpreter finishes at `%s' with status %d\n", | ||
395 | label, | ||
396 | is->result); | ||
397 | for (unsigned int j = 0; | ||
398 | NULL != (cmd = &is->commands[j])->run; | ||
399 | j++) | ||
400 | { | ||
401 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
402 | "Cleaning up cmd %s\n", | ||
403 | cmd->label.value); | ||
404 | cmd->cleanup (cmd->cls); | ||
405 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
406 | "Cleaned up cmd %s\n", | ||
407 | cmd->label.value); | ||
408 | } | ||
409 | if (NULL != is->task) | ||
410 | { | ||
411 | GNUNET_SCHEDULER_cancel (is->task); | ||
412 | is->task = NULL; | ||
413 | } | ||
414 | if (NULL != is->timeout_task) | ||
415 | { | ||
416 | GNUNET_SCHEDULER_cancel (is->timeout_task); | ||
417 | is->timeout_task = NULL; | ||
418 | } | ||
419 | if (NULL != is->send_handle) | ||
420 | { | ||
421 | GNUNET_HELPER_send_cancel (is->send_handle); | ||
422 | is->send_handle = NULL; | ||
423 | } | ||
424 | GNUNET_free (is->commands); | ||
425 | is->rc (is->rc_cls, | ||
426 | is->result); | ||
427 | GNUNET_CONTAINER_multishortmap_iterate (is->barriers, | ||
428 | free_barriers_cb, | ||
429 | is); | ||
430 | GNUNET_CONTAINER_multishortmap_destroy (is->barriers); | ||
431 | GNUNET_free (is->helper); | ||
432 | GNUNET_free (is); | ||
433 | } | ||
434 | |||
435 | |||
436 | /** | ||
437 | * Run the main interpreter loop that performs exchange operations. | ||
438 | * | ||
439 | * @param cls contains the `struct InterpreterState` | ||
440 | */ | ||
441 | static void | ||
442 | interpreter_run (void *cls); | ||
443 | |||
444 | |||
445 | /** | ||
446 | * Current command is done, run the next one. | ||
447 | */ | ||
448 | static void | ||
449 | interpreter_next (void *cls) | ||
450 | { | ||
451 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
452 | static unsigned long long ipc; | ||
453 | static struct GNUNET_TIME_Absolute last_report; | ||
454 | struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip]; | ||
455 | |||
456 | if (GNUNET_SYSERR == is->result) | ||
457 | return; /* ignore, we already failed! */ | ||
458 | cmd->finish_time = GNUNET_TIME_absolute_get (); | ||
459 | if ( (! GNUNET_TESTING_cmd_is_batch_ (cmd)) || | ||
460 | (! GNUNET_TESTING_cmd_batch_next_ (cmd->cls)) ) | ||
461 | is->ip++; | ||
462 | if (0 == (ipc % 1000)) | ||
463 | { | ||
464 | if (0 != ipc) | ||
465 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
466 | "Interpreter executed 1000 instructions in %s\n", | ||
467 | GNUNET_STRINGS_relative_time_to_string ( | ||
468 | GNUNET_TIME_absolute_get_duration (last_report), | ||
469 | GNUNET_YES)); | ||
470 | last_report = GNUNET_TIME_absolute_get (); | ||
471 | } | ||
472 | ipc++; | ||
473 | is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, | ||
474 | is); | ||
475 | } | ||
476 | |||
477 | |||
478 | void | ||
479 | GNUNET_TESTING_interpreter_fail (struct GNUNET_TESTING_Interpreter *is) | ||
480 | { | ||
481 | struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip]; | ||
482 | |||
483 | if (GNUNET_SYSERR == is->result) | ||
484 | { | ||
485 | GNUNET_break (0); | ||
486 | return; /* ignore, we already failed! */ | ||
487 | } | ||
488 | if (NULL != cmd) | ||
489 | { | ||
490 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
491 | "Failed at command `%s'\n", | ||
492 | cmd->label.value); | ||
493 | while (GNUNET_TESTING_cmd_is_batch_ (cmd)) | ||
494 | { | ||
495 | cmd = GNUNET_TESTING_cmd_batch_get_current_ (cmd); | ||
496 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
497 | "Failed in batch at command `%s'\n", | ||
498 | cmd->label.value); | ||
499 | } | ||
500 | } | ||
501 | else | ||
502 | { | ||
503 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
504 | "Failed with CMD being NULL!\n"); | ||
505 | } | ||
506 | is->result = GNUNET_SYSERR; | ||
507 | GNUNET_assert (NULL == is->final_task); | ||
508 | is->final_task = GNUNET_SCHEDULER_add_now (&finish_test, | ||
509 | is); | ||
510 | } | ||
511 | |||
512 | |||
513 | void | ||
514 | GNUNET_TESTING_async_fail (struct GNUNET_TESTING_AsyncContext *ac) | ||
515 | { | ||
516 | GNUNET_assert (GNUNET_NO == ac->finished); | ||
517 | ac->finished = GNUNET_SYSERR; | ||
518 | GNUNET_TESTING_interpreter_fail (ac->is); | ||
519 | if (NULL != ac->cont) | ||
520 | { | ||
521 | ac->cont (ac->cont_cls); | ||
522 | ac->cont = NULL; | ||
523 | } | ||
524 | } | ||
525 | |||
526 | |||
527 | void | ||
528 | GNUNET_TESTING_async_finish (struct GNUNET_TESTING_AsyncContext *ac) | ||
529 | { | ||
530 | GNUNET_assert (GNUNET_NO == ac->finished); | ||
531 | ac->finished = GNUNET_OK; | ||
532 | if (NULL != ac->cont) | ||
533 | { | ||
534 | ac->cont (ac->cont_cls); | ||
535 | ac->cont = NULL; | ||
536 | } | ||
537 | } | ||
538 | |||
539 | |||
540 | /** | ||
541 | * Returns the actual running command. | ||
542 | * | ||
543 | * @param is Global state of the interpreter, used by a command | ||
544 | * to access information about other commands. | ||
545 | * @return The actual running command. | ||
546 | */ | ||
547 | struct GNUNET_TESTING_Command * | ||
548 | GNUNET_TESTING_interpreter_get_current_command ( | ||
549 | struct GNUNET_TESTING_Interpreter *is) | ||
550 | { | ||
551 | return &is->commands[is->ip]; | ||
552 | } | ||
553 | |||
554 | |||
555 | /** | ||
556 | * Run the main interpreter loop. | ||
557 | * | ||
558 | * @param cls contains the `struct GNUNET_TESTING_Interpreter` | ||
559 | */ | ||
560 | static void | ||
561 | interpreter_run (void *cls) | ||
562 | { | ||
563 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
564 | struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip]; | ||
565 | |||
566 | is->task = NULL; | ||
567 | if (NULL == cmd->run) | ||
568 | { | ||
569 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
570 | "Running command END\n"); | ||
571 | is->result = GNUNET_OK; | ||
572 | finish_test (is); | ||
573 | return; | ||
574 | } | ||
575 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
576 | "Running command `%s'\n", | ||
577 | cmd->label.value); | ||
578 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
579 | "start time of %p expected 0 is `%" PRIu64 "'\n", | ||
580 | cmd, | ||
581 | cmd->start_time.abs_value_us); | ||
582 | cmd->start_time | ||
583 | = cmd->last_req_time | ||
584 | = GNUNET_TIME_absolute_get (); | ||
585 | cmd->num_tries = 1; | ||
586 | if (NULL != cmd->ac) | ||
587 | { | ||
588 | cmd->ac->is = is; | ||
589 | cmd->ac->cont = &interpreter_next; | ||
590 | cmd->ac->cont_cls = is; | ||
591 | cmd->ac->finished = false; | ||
592 | } | ||
593 | cmd->run (cmd->cls, | ||
594 | is); | ||
595 | if (NULL == cmd->ac) | ||
596 | { | ||
597 | interpreter_next (is); | ||
598 | } | ||
599 | else if ( (cmd->asynchronous_finish) && | ||
600 | (NULL != cmd->ac->cont) ) | ||
601 | { | ||
602 | cmd->ac->cont = NULL; | ||
603 | interpreter_next (is); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | |||
608 | /** | ||
609 | * Function run when the test terminates (good or bad) with timeout. | ||
610 | * | ||
611 | * @param cls the interpreter state | ||
612 | */ | ||
613 | static void | ||
614 | do_timeout (void *cls) | ||
615 | { | ||
616 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
617 | |||
618 | is->timeout_task = NULL; | ||
619 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
620 | "Terminating test due to global timeout\n"); | ||
621 | is->result = GNUNET_SYSERR; | ||
622 | finish_test (is); | ||
623 | } | ||
624 | |||
625 | |||
626 | struct GNUNET_TESTING_Interpreter * | ||
627 | GNUNET_TESTING_run (const struct GNUNET_TESTING_Command *commands, | ||
628 | struct GNUNET_TIME_Relative timeout, | ||
629 | GNUNET_TESTING_ResultCallback rc, | ||
630 | void *rc_cls) | ||
631 | { | ||
632 | struct GNUNET_TESTING_Interpreter *is; | ||
633 | unsigned int i; | ||
634 | |||
635 | is = GNUNET_new (struct GNUNET_TESTING_Interpreter); | ||
636 | is->rc = rc; | ||
637 | is->rc_cls = rc_cls; | ||
638 | is->barriers = GNUNET_CONTAINER_multishortmap_create (1, | ||
639 | false); | ||
640 | /* get the number of commands */ | ||
641 | for (i = 0; NULL != commands[i].run; i++) | ||
642 | ; | ||
643 | is->cmds_n = i + 1; | ||
644 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
645 | "Got %u commands\n", | ||
646 | i); | ||
647 | is->commands = GNUNET_malloc_large ( (i + 1) | ||
648 | * sizeof (struct | ||
649 | GNUNET_TESTING_Command)); | ||
650 | GNUNET_assert (NULL != is->commands); | ||
651 | memcpy (is->commands, | ||
652 | commands, | ||
653 | sizeof (struct GNUNET_TESTING_Command) * i); | ||
654 | is->timeout_task | ||
655 | = GNUNET_SCHEDULER_add_delayed (timeout, | ||
656 | &do_timeout, | ||
657 | is); | ||
658 | is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, | ||
659 | is); | ||
660 | |||
661 | return is; | ||
662 | } | ||
663 | |||
664 | |||
665 | struct GNUNET_TESTING_Command | ||
666 | GNUNET_TESTING_command_new (void *cls, | ||
667 | const char *label, | ||
668 | GNUNET_TESTING_CommandRunRoutine run, | ||
669 | GNUNET_TESTING_CommandCleanupRoutine cleanup, | ||
670 | GNUNET_TESTING_CommandGetTraits traits, | ||
671 | struct GNUNET_TESTING_AsyncContext *ac) | ||
672 | { | ||
673 | struct GNUNET_TESTING_Command cmd = { | ||
674 | .cls = cls, | ||
675 | .run = run, | ||
676 | .ac = ac, | ||
677 | .cleanup = cleanup, | ||
678 | .traits = traits | ||
679 | }; | ||
680 | |||
681 | GNUNET_assert (NULL != run); | ||
682 | if (NULL != label) | ||
683 | GNUNET_TESTING_set_label (&cmd.label, | ||
684 | label); | ||
685 | return cmd; | ||
686 | } | ||
687 | |||
688 | |||
689 | void | ||
690 | GNUNET_TESTING_set_label (struct GNUNET_TESTING_CommandLabel *label, | ||
691 | const char *value) | ||
692 | { | ||
693 | size_t len; | ||
694 | |||
695 | len = strlen (value); | ||
696 | GNUNET_assert (len <= | ||
697 | GNUNET_TESTING_CMD_MAX_LABEL_LENGTH); | ||
698 | memcpy (label->value, | ||
699 | value, | ||
700 | len + 1); | ||
701 | } | ||
702 | |||
703 | |||
704 | |||
705 | struct GNUNET_TESTING_Command | ||
706 | GNUNET_TESTING_cmd_end (void) | ||
707 | { | ||
708 | struct GNUNET_TESTING_Command cmd = { | ||
709 | .run = NULL | ||
710 | }; | ||
711 | |||
712 | return cmd; | ||
713 | } | ||
714 | |||
715 | |||
716 | /** | ||
717 | * Closure for #loop_run(). | ||
718 | */ | ||
719 | struct MainParams | ||
720 | { | ||
721 | |||
722 | /** | ||
723 | * NULL-label terminated array of commands. | ||
724 | */ | ||
725 | struct GNUNET_TESTING_Command *commands; | ||
726 | |||
727 | /** | ||
728 | * Global timeout for the test. | ||
729 | */ | ||
730 | struct GNUNET_TIME_Relative timeout; | ||
731 | |||
732 | /** | ||
733 | * Set to #EXIT_FAILURE on error. | ||
734 | */ | ||
735 | int rv; | ||
736 | }; | ||
737 | |||
738 | |||
739 | /** | ||
740 | * Function called with the final result of the test. | ||
741 | * | ||
742 | * @param cls the `struct MainParams` | ||
743 | * @param rv #GNUNET_OK if the test passed | ||
744 | */ | ||
745 | static void | ||
746 | handle_result (void *cls, | ||
747 | enum GNUNET_GenericReturnValue rv) | ||
748 | { | ||
749 | struct MainParams *mp = cls; | ||
750 | |||
751 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
752 | "Test exits with status %d\n", | ||
753 | rv); | ||
754 | if (GNUNET_OK != rv) | ||
755 | mp->rv = EXIT_FAILURE; | ||
756 | GNUNET_SCHEDULER_shutdown (); | ||
757 | } | ||
758 | |||
759 | |||
760 | /** | ||
761 | * Main function to run the test cases. | ||
762 | * | ||
763 | * @param cls a `struct MainParams *` | ||
764 | */ | ||
765 | static void | ||
766 | loop_run (void *cls) | ||
767 | { | ||
768 | struct MainParams *mp = cls; | ||
769 | |||
770 | GNUNET_TESTING_run (mp->commands, | ||
771 | mp->timeout, | ||
772 | &handle_result, | ||
773 | mp); | ||
774 | } | ||
775 | |||
776 | |||
777 | int | ||
778 | GNUNET_TESTING_main (struct GNUNET_TESTING_Command *commands, | ||
779 | struct GNUNET_TIME_Relative timeout) | ||
780 | { | ||
781 | struct MainParams mp = { | ||
782 | .commands = commands, | ||
783 | .timeout = timeout, | ||
784 | .rv = EXIT_SUCCESS | ||
785 | }; | ||
786 | |||
787 | GNUNET_SCHEDULER_run (&loop_run, | ||
788 | &mp); | ||
789 | return mp.rv; | ||
790 | } | ||
791 | |||
792 | |||
793 | void | ||
794 | GNUNET_TESTING_add_netjail_helper_ (struct GNUNET_TESTING_Interpreter *is, | ||
795 | const struct GNUNET_HELPER_Handle *helper) | ||
796 | { | ||
797 | GNUNET_array_append (is->helper, | ||
798 | is->n_helper, | ||
799 | helper); | ||
800 | } | ||
801 | |||
802 | |||
803 | struct GNUNET_TESTING_Barrier * | ||
804 | GNUNET_TESTING_get_barrier_ (struct GNUNET_TESTING_Interpreter *is, | ||
805 | const char *barrier_name) | ||
806 | { | ||
807 | struct GNUNET_HashCode hc; | ||
808 | struct GNUNET_ShortHashCode create_key; | ||
809 | |||
810 | GNUNET_CRYPTO_hash (barrier_name, | ||
811 | strlen (barrier_name), | ||
812 | &hc); | ||
813 | memcpy (&create_key, | ||
814 | &hc, | ||
815 | sizeof (create_key)); | ||
816 | return GNUNET_CONTAINER_multishortmap_get (is->barriers, | ||
817 | &create_key); | ||
818 | } | ||
819 | |||
820 | |||
821 | /** | ||
822 | * Add a barrier to the interpreter. | ||
823 | * | ||
824 | * @param is The interpreter. | ||
825 | * @param barrier The barrier to add. | ||
826 | */ | ||
827 | void | ||
828 | GNUNET_TESTING_add_barrier_ (struct GNUNET_TESTING_Interpreter *is, | ||
829 | struct GNUNET_TESTING_Barrier *barrier) | ||
830 | { | ||
831 | struct GNUNET_HashCode hc; | ||
832 | struct GNUNET_ShortHashCode create_key; | ||
833 | |||
834 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
835 | "Adding barrier %s locally\n", | ||
836 | barrier->name); | ||
837 | GNUNET_CRYPTO_hash (barrier->name, | ||
838 | strlen (barrier->name), | ||
839 | &hc); | ||
840 | memcpy (&create_key, | ||
841 | &hc, | ||
842 | sizeof (create_key)); | ||
843 | GNUNET_CONTAINER_multishortmap_put (is->barriers, | ||
844 | &create_key, | ||
845 | barrier, | ||
846 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
847 | } | ||
848 | |||
849 | |||
850 | void | ||
851 | GNUNET_TESTING_finish_barrier_ (struct GNUNET_TESTING_Interpreter *is, | ||
852 | const char *barrier_name) | ||
853 | { | ||
854 | struct CommandListEntry *pos; | ||
855 | struct GNUNET_TESTING_Barrier *barrier; | ||
856 | |||
857 | barrier = GNUNET_TESTING_get_barrier_ (is, | ||
858 | barrier_name); | ||
859 | if (NULL == barrier) | ||
860 | return; | ||
861 | while (NULL != (pos = barrier->cmds_head)) | ||
862 | { | ||
863 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
864 | "command label %s\n", | ||
865 | pos->command->label.value); | ||
866 | if ( (GNUNET_NO == pos->command->ac->finished) && | ||
867 | (GNUNET_NO == pos->command->asynchronous_finish) ) | ||
868 | { | ||
869 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
870 | "command label %s finish\n", | ||
871 | pos->command->label.value); | ||
872 | GNUNET_TESTING_async_finish (pos->command->ac); | ||
873 | } | ||
874 | else if (GNUNET_NO == pos->command->ac->finished) | ||
875 | { | ||
876 | pos->command->asynchronous_finish = GNUNET_YES; | ||
877 | } | ||
878 | GNUNET_CONTAINER_DLL_remove (barrier->cmds_head, | ||
879 | barrier->cmds_tail, | ||
880 | pos); | ||
881 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
882 | "command entry label %s removed\n", | ||
883 | pos->command->label.value); | ||
884 | GNUNET_free (pos); | ||
885 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
886 | "command entry freed\n"); | ||
887 | } | ||
888 | free_barrier_nodes (is, | ||
889 | barrier); | ||
890 | } | ||
891 | |||
892 | |||
893 | /* end of testing_api_loop.c */ | ||
diff --git a/src/service/testing/testing_cmds.h b/src/service/testing/testing_cmds.h deleted file mode 100644 index f4549477e..000000000 --- a/src/service/testing/testing_cmds.h +++ /dev/null | |||
@@ -1,143 +0,0 @@ | |||
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_cmds.h | ||
23 | * @brief Message formats for communication between testing cmds helper and testcase plugins. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | |||
27 | #ifndef TESTING_CMDS_H | ||
28 | #define TESTING_CMDS_H | ||
29 | |||
30 | #define HELPER_CMDS_BINARY "gnunet-cmds-helper" | ||
31 | #include "gnunet_common.h" | ||
32 | |||
33 | GNUNET_NETWORK_STRUCT_BEGIN | ||
34 | |||
35 | /** | ||
36 | * Initialization message for gnunet-cmds-testbed to start cmd binary. | ||
37 | */ | ||
38 | struct GNUNET_TESTING_CommandHelperInit | ||
39 | { | ||
40 | /** | ||
41 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT | ||
42 | */ | ||
43 | struct GNUNET_MessageHeader header; | ||
44 | |||
45 | /** | ||
46 | * | ||
47 | */ | ||
48 | uint16_t plugin_name_size GNUNET_PACKED; | ||
49 | |||
50 | /* Followed by plugin name of the plugin running the test case. This is not NULL | ||
51 | * terminated */ | ||
52 | }; | ||
53 | |||
54 | /** | ||
55 | * Reply message from cmds helper process | ||
56 | */ | ||
57 | struct GNUNET_TESTING_CommandHelperReply | ||
58 | { | ||
59 | /** | ||
60 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY | ||
61 | */ | ||
62 | struct GNUNET_MessageHeader header; | ||
63 | }; | ||
64 | |||
65 | struct GNUNET_TESTING_CommandPeerStarted | ||
66 | { | ||
67 | /** | ||
68 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED | ||
69 | */ | ||
70 | struct GNUNET_MessageHeader header; | ||
71 | }; | ||
72 | |||
73 | struct GNUNET_TESTING_CommandAllPeersStarted | ||
74 | { | ||
75 | /** | ||
76 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED | ||
77 | */ | ||
78 | struct GNUNET_MessageHeader header; | ||
79 | }; | ||
80 | |||
81 | struct GNUNET_TESTING_CommandLocalFinished | ||
82 | { | ||
83 | /** | ||
84 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED | ||
85 | */ | ||
86 | struct GNUNET_MessageHeader header; | ||
87 | |||
88 | /** | ||
89 | * The exit status local test return with. | ||
90 | */ | ||
91 | enum GNUNET_GenericReturnValue rv; | ||
92 | }; | ||
93 | |||
94 | |||
95 | struct GNUNET_TESTING_CommandLocalTestPrepared | ||
96 | { | ||
97 | /** | ||
98 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED | ||
99 | */ | ||
100 | struct GNUNET_MessageHeader header; | ||
101 | }; | ||
102 | |||
103 | struct GNUNET_TESTING_CommandAllLocalTestsPrepared | ||
104 | { | ||
105 | /** | ||
106 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED | ||
107 | */ | ||
108 | struct GNUNET_MessageHeader header; | ||
109 | }; | ||
110 | |||
111 | GNUNET_NETWORK_STRUCT_END | ||
112 | |||
113 | /** | ||
114 | * Global state of the interpreter, used by a command | ||
115 | * to access information about other commands. | ||
116 | */ | ||
117 | struct GNUNET_TESTING_Interpreter; | ||
118 | |||
119 | |||
120 | /** | ||
121 | * Returns the actual running command. | ||
122 | * | ||
123 | * @param is Global state of the interpreter, used by a command | ||
124 | * to access information about other commands. | ||
125 | * @return The actual running command. | ||
126 | */ | ||
127 | struct GNUNET_TESTING_Command * | ||
128 | GNUNET_TESTING_interpreter_get_current_command ( | ||
129 | struct GNUNET_TESTING_Interpreter *is); | ||
130 | |||
131 | |||
132 | /** | ||
133 | * Adding a helper handle to the interpreter. | ||
134 | * | ||
135 | * @param is The interpreter. | ||
136 | * @param helper The helper handle. | ||
137 | */ | ||
138 | void | ||
139 | GNUNET_TESTING_add_netjail_helper_ (struct GNUNET_TESTING_Interpreter *is, | ||
140 | const struct GNUNET_HELPER_Handle *helper); | ||
141 | |||
142 | #endif | ||
143 | /* end of testing_cmds.h */ | ||
diff --git a/src/service/testing/topo.sh b/src/service/testing/topo.sh deleted file mode 100755 index 0046622b6..000000000 --- a/src/service/testing/topo.sh +++ /dev/null | |||
@@ -1,99 +0,0 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | declare -A K_PLUGIN | ||
4 | declare -A R_TCP | ||
5 | declare -A R_UDP | ||
6 | declare -A P_PLUGIN | ||
7 | |||
8 | extract_attributes() | ||
9 | { | ||
10 | line_key=$1 | ||
11 | line=$2 | ||
12 | |||
13 | if [ "$line_key" = "P" ] | ||
14 | then | ||
15 | n=$(echo $line|cut -d \| -f 1|awk -F: '{print $2}') | ||
16 | echo $n | ||
17 | m=$(echo $line|cut -d \| -f 1|awk -F: '{print $3}') | ||
18 | echo $m | ||
19 | else | ||
20 | number=$(echo $line|cut -d \| -f 1| cut -c 2-|cut -d : -f 2 ) | ||
21 | echo $number | ||
22 | fi | ||
23 | |||
24 | nf=$(echo $line|awk -F: '{print NF}') | ||
25 | for ((i=2;i<=$nf;i++)) | ||
26 | do | ||
27 | entry=$(echo $line |awk -v i=$i -F\| '{print $i}') | ||
28 | key=$(echo $entry|cut -d { -f 2|cut -d } -f 1|cut -d : -f 1) | ||
29 | value=$(echo $entry|cut -d { -f 2|cut -d } -f 1|cut -d : -f 2) | ||
30 | if [ "$key" = "tcp_port" ] | ||
31 | then | ||
32 | echo tcp port: $value | ||
33 | R_TCP[$number]=$value | ||
34 | elif [ "$key" = "udp_port" ] | ||
35 | then | ||
36 | echo udp port: $value | ||
37 | R_UDP[$number]=$value | ||
38 | elif [ "$key" = "plugin" ] | ||
39 | then | ||
40 | echo plugin: $value | ||
41 | echo $line_key | ||
42 | if [ "$line_key" = "P" ] | ||
43 | then | ||
44 | P_PLUGIN[$n,$m]=$value | ||
45 | echo $n $m ${P_PLUGIN[$n,$m]} | ||
46 | elif [ "$line_key" = "K" ] | ||
47 | then | ||
48 | K_PLUGIN[$number]=$value | ||
49 | fi | ||
50 | fi | ||
51 | done | ||
52 | } | ||
53 | |||
54 | read_topology(){ | ||
55 | |||
56 | local filename=$1 | ||
57 | while read line; do | ||
58 | # reading each line | ||
59 | echo $line | ||
60 | key=$(cut -c -1 <<< $line) | ||
61 | if [ "$key" = "M" ] | ||
62 | then | ||
63 | LOCAL_M=$(cut -d : -f 2 <<< $line) | ||
64 | echo $LOCAL_M | ||
65 | elif [ "$key" = "N" ] | ||
66 | then | ||
67 | GLOBAL_N=$(cut -d : -f 2 <<< $line) | ||
68 | echo $GLOBAL_N | ||
69 | for ((i=1;i<=$GLOBAL_N;i++)) | ||
70 | do | ||
71 | R_TCP[$i]=0 | ||
72 | R_UDP[$i]=0 | ||
73 | done | ||
74 | elif [ "$key" = "X" ] | ||
75 | then | ||
76 | KNOWN=$(cut -d : -f 2 <<< $line) | ||
77 | echo $KNOWN | ||
78 | elif [ "$key" = "T" ] | ||
79 | then | ||
80 | PLUGIN=$(cut -d : -f 2 <<< $line) | ||
81 | echo $PLUGIN | ||
82 | elif [ "$key" = "K" ] | ||
83 | then | ||
84 | echo know node | ||
85 | extract_attributes $key $line | ||
86 | elif [ "$key" = "R" ] | ||
87 | then | ||
88 | echo router | ||
89 | extract_attributes $key $line | ||
90 | elif [ "$key" = "P" ] | ||
91 | then | ||
92 | echo node | ||
93 | extract_attributes $key $line | ||
94 | fi | ||
95 | done < $filename | ||
96 | } | ||
97 | |||
98 | |||
99 | |||
diff --git a/src/service/topology/gnunet-daemon-topology.c b/src/service/topology/gnunet-daemon-topology.c index 159ba2a07..a95b67908 100644 --- a/src/service/topology/gnunet-daemon-topology.c +++ b/src/service/topology/gnunet-daemon-topology.c | |||
@@ -699,6 +699,7 @@ consider_for_advertising (const struct GNUNET_MessageHeader *hello) | |||
699 | GNUNET_HELLO_builder_iterate (builder_old, | 699 | GNUNET_HELLO_builder_iterate (builder_old, |
700 | &address_iterator, | 700 | &address_iterator, |
701 | &num_addresses_old); | 701 | &num_addresses_old); |
702 | GNUNET_HELLO_builder_free (builder_old); | ||
702 | if (GNUNET_TIME_absolute_cmp (new_hello_exp, >, now) && | 703 | if (GNUNET_TIME_absolute_cmp (new_hello_exp, >, now) && |
703 | (GNUNET_TIME_absolute_cmp (new_hello_exp, >, old_hello_exp) || | 704 | (GNUNET_TIME_absolute_cmp (new_hello_exp, >, old_hello_exp) || |
704 | num_addresses_old < num_addresses_new)) | 705 | num_addresses_old < num_addresses_new)) |
diff --git a/src/service/transport/Makefile.am b/src/service/transport/Makefile.am index 56ed8fc13..36743e63f 100644 --- a/src/service/transport/Makefile.am +++ b/src/service/transport/Makefile.am | |||
@@ -15,11 +15,10 @@ if USE_COVERAGE | |||
15 | endif | 15 | endif |
16 | 16 | ||
17 | noinst_PROGRAMS = \ | 17 | noinst_PROGRAMS = \ |
18 | test_transport_start_with_config \ | ||
19 | gnunet-communicator-udp | 18 | gnunet-communicator-udp |
20 | 19 | ||
21 | TESTING_LIBS = \ | 20 | TESTING_LIBS = \ |
22 | libgnunettransporttesting2.la | 21 | libgnunettestingtransport.la |
23 | 22 | ||
24 | lib_LTLIBRARIES = \ | 23 | lib_LTLIBRARIES = \ |
25 | libgnunettransportapplication.la \ | 24 | libgnunettransportapplication.la \ |
@@ -28,28 +27,25 @@ lib_LTLIBRARIES = \ | |||
28 | libgnunettransportmonitor.la \ | 27 | libgnunettransportmonitor.la \ |
29 | $(TESTING_LIBS) | 28 | $(TESTING_LIBS) |
30 | 29 | ||
31 | libgnunettransporttesting2_la_SOURCES = \ | 30 | libgnunettestingtransport_la_SOURCES = \ |
32 | transport_api_traits.c \ | 31 | testing_api_traits.c \ |
33 | testing_api_cmd_stop_peer.c \ | 32 | # transport_api_cmd_connecting_peers.c \ |
34 | testing_api_cmd_start_peer.c \ | 33 | # transport_api_cmd_backchannel_check.c \ |
35 | transport_api_cmd_connecting_peers.c \ | 34 | # transport_api_cmd_send_simple.c \ |
36 | transport_api_cmd_backchannel_check.c \ | 35 | # transport_api_cmd_send_simple_performance.c \ |
37 | transport_api_cmd_start_peer.c \ | 36 | # transport-testing2.c transport-testing2.h \ |
38 | transport_api_cmd_stop_peer.c \ | 37 | # transport-testing-cmds.h \ |
39 | transport_api_cmd_send_simple.c \ | 38 | # transport-testing-filenames2.c \ |
40 | transport_api_cmd_send_simple_performance.c \ | 39 | # transport-testing-loggers2.c \ |
41 | transport-testing2.c transport-testing2.h \ | 40 | # transport-testing-main2.c \ |
42 | transport-testing-cmds.h \ | 41 | # transport-testing-send2.c \ |
43 | transport-testing-filenames2.c \ | 42 | # transport-testing-communicator.c transport-testing-communicator.h |
44 | transport-testing-loggers2.c \ | 43 | libgnunettestingtransport_la_LIBADD = \ |
45 | transport-testing-main2.c \ | ||
46 | transport-testing-send2.c \ | ||
47 | transport-testing-communicator.c transport-testing-communicator.h | ||
48 | libgnunettransporttesting2_la_LIBADD = \ | ||
49 | libgnunettransportapplication.la \ | 44 | libgnunettransportapplication.la \ |
50 | libgnunettransportcore.la \ | 45 | libgnunettransportcore.la \ |
46 | $(top_builddir)/src/service/testbed/libgnunettestbed.la \ | ||
51 | $(top_builddir)/src/service/arm/libgnunetarm.la \ | 47 | $(top_builddir)/src/service/arm/libgnunetarm.la \ |
52 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 48 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
53 | $(top_builddir)/src/lib/hello/libgnunethello.la \ | 49 | $(top_builddir)/src/lib/hello/libgnunethello.la \ |
54 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ | 50 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ |
55 | $(top_builddir)/src/lib/util/libgnunetutil.la | 51 | $(top_builddir)/src/lib/util/libgnunetutil.la |
@@ -189,13 +185,13 @@ gnunet_service_transport_LDADD = \ | |||
189 | $(LIBGCRYPT_LIBS) \ | 185 | $(LIBGCRYPT_LIBS) \ |
190 | $(GN_LIBINTL) | 186 | $(GN_LIBINTL) |
191 | 187 | ||
192 | plugin_LTLIBRARIES = \ | 188 | #plugin_LTLIBRARIES = \ |
193 | libgnunet_test_transport_plugin_cmd_simple_send_performance.la \ | 189 | # libgnunet_test_transport_plugin_cmd_simple_send_performance.la \ |
194 | libgnunet_test_transport_plugin_cmd_nat_upnp.la \ | 190 | # libgnunet_test_transport_plugin_cmd_nat_upnp.la \ |
195 | libgnunet_test_transport_plugin_cmd_simple_send.la \ | 191 | # libgnunet_test_transport_plugin_cmd_simple_send.la \ |
196 | libgnunet_test_transport_plugin_cmd_simple_send_broadcast.la \ | 192 | # libgnunet_test_transport_plugin_cmd_simple_send_broadcast.la \ |
197 | libgnunet_test_transport_plugin_cmd_simple_send_dv.la \ | 193 | # libgnunet_test_transport_plugin_cmd_simple_send_dv.la \ |
198 | libgnunet_test_transport_plugin_cmd_udp_backchannel.la | 194 | # libgnunet_test_transport_plugin_cmd_udp_backchannel.la |
199 | 195 | ||
200 | libgnunet_test_transport_plugin_cmd_nat_upnp_la_SOURCES = \ | 196 | libgnunet_test_transport_plugin_cmd_nat_upnp_la_SOURCES = \ |
201 | test_transport_plugin_cmd_nat_upnp.c | 197 | test_transport_plugin_cmd_nat_upnp.c |
@@ -203,7 +199,7 @@ libgnunet_test_transport_plugin_cmd_nat_upnp_la_LIBADD = \ | |||
203 | libgnunettransporttesting2.la \ | 199 | libgnunettransporttesting2.la \ |
204 | libgnunettransportapplication.la \ | 200 | libgnunettransportapplication.la \ |
205 | libgnunettransportcore.la \ | 201 | libgnunettransportcore.la \ |
206 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 202 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
207 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ | 203 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ |
208 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ | 204 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ |
209 | $(top_builddir)/src/lib/hello/libgnunethello.la \ | 205 | $(top_builddir)/src/lib/hello/libgnunethello.la \ |
@@ -219,7 +215,7 @@ libgnunet_test_transport_plugin_cmd_udp_backchannel_la_LIBADD = \ | |||
219 | libgnunettransporttesting2.la \ | 215 | libgnunettransporttesting2.la \ |
220 | libgnunettransportapplication.la \ | 216 | libgnunettransportapplication.la \ |
221 | libgnunettransportcore.la \ | 217 | libgnunettransportcore.la \ |
222 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 218 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
223 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ | 219 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ |
224 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ | 220 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ |
225 | $(top_builddir)/src/lib/hello/libgnunethello.la \ | 221 | $(top_builddir)/src/lib/hello/libgnunethello.la \ |
@@ -235,7 +231,7 @@ libgnunet_test_transport_plugin_cmd_simple_send_la_LIBADD = \ | |||
235 | libgnunettransporttesting2.la \ | 231 | libgnunettransporttesting2.la \ |
236 | libgnunettransportapplication.la \ | 232 | libgnunettransportapplication.la \ |
237 | libgnunettransportcore.la \ | 233 | libgnunettransportcore.la \ |
238 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 234 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
239 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ | 235 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ |
240 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ | 236 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ |
241 | $(top_builddir)/src/lib/hello/libgnunethello.la \ | 237 | $(top_builddir)/src/lib/hello/libgnunethello.la \ |
@@ -251,7 +247,7 @@ libgnunet_test_transport_plugin_cmd_simple_send_performance_la_LIBADD = \ | |||
251 | libgnunettransporttesting2.la \ | 247 | libgnunettransporttesting2.la \ |
252 | libgnunettransportapplication.la \ | 248 | libgnunettransportapplication.la \ |
253 | libgnunettransportcore.la \ | 249 | libgnunettransportcore.la \ |
254 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 250 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
255 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ | 251 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ |
256 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ | 252 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ |
257 | $(top_builddir)/src/lib/hello/libgnunethello.la \ | 253 | $(top_builddir)/src/lib/hello/libgnunethello.la \ |
@@ -267,7 +263,7 @@ libgnunet_test_transport_plugin_cmd_simple_send_broadcast_la_LIBADD = \ | |||
267 | libgnunettransporttesting2.la \ | 263 | libgnunettransporttesting2.la \ |
268 | libgnunettransportapplication.la \ | 264 | libgnunettransportapplication.la \ |
269 | libgnunettransportcore.la \ | 265 | libgnunettransportcore.la \ |
270 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 266 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
271 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ | 267 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ |
272 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ | 268 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ |
273 | $(top_builddir)/src/lib/hello/libgnunethello.la \ | 269 | $(top_builddir)/src/lib/hello/libgnunethello.la \ |
@@ -283,7 +279,7 @@ libgnunet_test_transport_plugin_cmd_simple_send_dv_la_LIBADD = \ | |||
283 | libgnunettransporttesting2.la \ | 279 | libgnunettransporttesting2.la \ |
284 | libgnunettransportapplication.la \ | 280 | libgnunettransportapplication.la \ |
285 | libgnunettransportcore.la \ | 281 | libgnunettransportcore.la \ |
286 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 282 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
287 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ | 283 | $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \ |
288 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ | 284 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la \ |
289 | $(top_builddir)/src/lib/hello/libgnunethello.la \ | 285 | $(top_builddir)/src/lib/hello/libgnunethello.la \ |
@@ -325,20 +321,12 @@ TESTS = \ | |||
325 | endif | 321 | endif |
326 | 322 | ||
327 | 323 | ||
328 | test_transport_start_with_config_SOURCES = \ | ||
329 | test_transport_start_with_config.c | ||
330 | test_transport_start_with_config_LDADD = \ | ||
331 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | ||
332 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
333 | $(top_builddir)/src/lib/hello/libgnunethello.la \ | ||
334 | libgnunettransportcore.la \ | ||
335 | libgnunettransporttesting2.la | ||
336 | 324 | ||
337 | test_communicator_basic_unix_SOURCES = \ | 325 | test_communicator_basic_unix_SOURCES = \ |
338 | test_communicator_basic.c | 326 | test_communicator_basic.c |
339 | test_communicator_basic_unix_LDADD = \ | 327 | test_communicator_basic_unix_LDADD = \ |
340 | libgnunettransporttesting2.la \ | 328 | libgnunettransporttesting2.la \ |
341 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 329 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
342 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | 330 | $(top_builddir)/src/lib/util/libgnunetutil.la \ |
343 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la | 331 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la |
344 | 332 | ||
@@ -346,7 +334,7 @@ test_communicator_basic_tcp_SOURCES = \ | |||
346 | test_communicator_basic.c | 334 | test_communicator_basic.c |
347 | test_communicator_basic_tcp_LDADD = \ | 335 | test_communicator_basic_tcp_LDADD = \ |
348 | libgnunettransporttesting2.la \ | 336 | libgnunettransporttesting2.la \ |
349 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 337 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
350 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | 338 | $(top_builddir)/src/lib/util/libgnunetutil.la \ |
351 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la | 339 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la |
352 | 340 | ||
@@ -354,7 +342,7 @@ test_communicator_basic_udp_SOURCES = \ | |||
354 | test_communicator_basic.c | 342 | test_communicator_basic.c |
355 | test_communicator_basic_udp_LDADD = \ | 343 | test_communicator_basic_udp_LDADD = \ |
356 | libgnunettransporttesting2.la \ | 344 | libgnunettransporttesting2.la \ |
357 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 345 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
358 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | 346 | $(top_builddir)/src/lib/util/libgnunetutil.la \ |
359 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la | 347 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la |
360 | 348 | ||
@@ -362,7 +350,7 @@ test_communicator_basic_quic_SOURCES = \ | |||
362 | test_communicator_basic.c | 350 | test_communicator_basic.c |
363 | test_communicator_basic_quic_LDADD = \ | 351 | test_communicator_basic_quic_LDADD = \ |
364 | libgnunettransporttesting2.la \ | 352 | libgnunettransporttesting2.la \ |
365 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 353 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
366 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | 354 | $(top_builddir)/src/lib/util/libgnunetutil.la \ |
367 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la | 355 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la |
368 | 356 | ||
@@ -370,7 +358,7 @@ test_communicator_rekey_tcp_SOURCES = \ | |||
370 | test_communicator_basic.c | 358 | test_communicator_basic.c |
371 | test_communicator_rekey_tcp_LDADD = \ | 359 | test_communicator_rekey_tcp_LDADD = \ |
372 | libgnunettransporttesting2.la \ | 360 | libgnunettransporttesting2.la \ |
373 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 361 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
374 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | 362 | $(top_builddir)/src/lib/util/libgnunetutil.la \ |
375 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la | 363 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la |
376 | 364 | ||
@@ -378,7 +366,7 @@ test_communicator_rekey_udp_SOURCES = \ | |||
378 | test_communicator_basic.c | 366 | test_communicator_basic.c |
379 | test_communicator_rekey_udp_LDADD = \ | 367 | test_communicator_rekey_udp_LDADD = \ |
380 | libgnunettransporttesting2.la \ | 368 | libgnunettransporttesting2.la \ |
381 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 369 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
382 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | 370 | $(top_builddir)/src/lib/util/libgnunetutil.la \ |
383 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la | 371 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la |
384 | 372 | ||
@@ -386,7 +374,7 @@ test_communicator_backchannel_udp_SOURCES = \ | |||
386 | test_communicator_basic.c | 374 | test_communicator_basic.c |
387 | test_communicator_backchannel_udp_LDADD = \ | 375 | test_communicator_backchannel_udp_LDADD = \ |
388 | libgnunettransporttesting2.la \ | 376 | libgnunettransporttesting2.la \ |
389 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 377 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
390 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | 378 | $(top_builddir)/src/lib/util/libgnunetutil.la \ |
391 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la | 379 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la |
392 | 380 | ||
@@ -394,7 +382,7 @@ test_communicator_bidirect_tcp_SOURCES = \ | |||
394 | test_communicator_basic.c | 382 | test_communicator_basic.c |
395 | test_communicator_bidirect_tcp_LDADD = \ | 383 | test_communicator_bidirect_tcp_LDADD = \ |
396 | libgnunettransporttesting2.la \ | 384 | libgnunettransporttesting2.la \ |
397 | $(top_builddir)/src/service/testing/libgnunettesting.la \ | 385 | $(top_builddir)/src/lib/testing/libgnunettesting.la \ |
398 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | 386 | $(top_builddir)/src/lib/util/libgnunetutil.la \ |
399 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la | 387 | $(top_builddir)/src/service/statistics/libgnunetstatistics.la |
400 | 388 | ||
diff --git a/src/service/transport/gnunet-communicator-tcp.c b/src/service/transport/gnunet-communicator-tcp.c index 02a547335..5d9b9055f 100644 --- a/src/service/transport/gnunet-communicator-tcp.c +++ b/src/service/transport/gnunet-communicator-tcp.c | |||
@@ -27,8 +27,8 @@ | |||
27 | * - support NAT connection reversal method (#5529) | 27 | * - support NAT connection reversal method (#5529) |
28 | * - support other TCP-specific NAT traversal methods (#5531) | 28 | * - support other TCP-specific NAT traversal methods (#5531) |
29 | */ | 29 | */ |
30 | #include "gnunet_common.h" | ||
31 | #include "platform.h" | 30 | #include "platform.h" |
31 | #include "gnunet_common.h" | ||
32 | #include "gnunet_util_lib.h" | 32 | #include "gnunet_util_lib.h" |
33 | #include "gnunet_core_service.h" | 33 | #include "gnunet_core_service.h" |
34 | #include "gnunet_peerstore_service.h" | 34 | #include "gnunet_peerstore_service.h" |
@@ -2369,7 +2369,6 @@ extract_address (const char *bindto) | |||
2369 | char *token; | 2369 | char *token; |
2370 | char *cp; | 2370 | char *cp; |
2371 | char *rest = NULL; | 2371 | char *rest = NULL; |
2372 | char *res; | ||
2373 | 2372 | ||
2374 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2373 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2375 | "extract address with bindto %s\n", | 2374 | "extract address with bindto %s\n", |
@@ -2402,8 +2401,7 @@ extract_address (const char *bindto) | |||
2402 | else | 2401 | else |
2403 | { | 2402 | { |
2404 | token++; | 2403 | token++; |
2405 | res = GNUNET_strdup (token); | 2404 | addr = GNUNET_strdup (token); |
2406 | addr = GNUNET_strdup (res); | ||
2407 | } | 2405 | } |
2408 | } | 2406 | } |
2409 | 2407 | ||
@@ -3349,6 +3347,7 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address) | |||
3349 | { | 3347 | { |
3350 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3348 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3351 | "Queue for %s already exists or is in construction\n", address); | 3349 | "Queue for %s already exists or is in construction\n", address); |
3350 | GNUNET_free (in); | ||
3352 | return GNUNET_NO; | 3351 | return GNUNET_NO; |
3353 | } | 3352 | } |
3354 | switch (in->sa_family) | 3353 | switch (in->sa_family) |
@@ -3799,7 +3798,8 @@ init_socket (struct sockaddr *addr, | |||
3799 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3798 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3800 | "Bound to `%s'\n", | 3799 | "Bound to `%s'\n", |
3801 | GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len)); | 3800 | GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len)); |
3802 | stats = GNUNET_STATISTICS_create ("communicator-tcp", cfg); | 3801 | if (NULL == stats) |
3802 | stats = GNUNET_STATISTICS_create ("communicator-tcp", cfg); | ||
3803 | 3803 | ||
3804 | if (NULL == is) | 3804 | if (NULL == is) |
3805 | is = GNUNET_NT_scanner_init (); | 3805 | is = GNUNET_NT_scanner_init (); |
diff --git a/src/service/transport/gnunet-communicator-udp.c b/src/service/transport/gnunet-communicator-udp.c index e9496c571..fa5294218 100644 --- a/src/service/transport/gnunet-communicator-udp.c +++ b/src/service/transport/gnunet-communicator-udp.c | |||
@@ -883,6 +883,8 @@ bi_destroy (struct BroadcastInterface *bi) | |||
883 | GNUNET_free (bi); | 883 | GNUNET_free (bi); |
884 | } | 884 | } |
885 | 885 | ||
886 | static int | ||
887 | secret_destroy (struct SharedSecret *ss); | ||
886 | 888 | ||
887 | /** | 889 | /** |
888 | * Destroys a receiving state due to timeout or shutdown. | 890 | * Destroys a receiving state due to timeout or shutdown. |
@@ -892,7 +894,7 @@ bi_destroy (struct BroadcastInterface *bi) | |||
892 | static void | 894 | static void |
893 | receiver_destroy (struct ReceiverAddress *receiver) | 895 | receiver_destroy (struct ReceiverAddress *receiver) |
894 | { | 896 | { |
895 | 897 | struct SharedSecret *ss; | |
896 | receiver->receiver_destroy_called = GNUNET_YES; | 898 | receiver->receiver_destroy_called = GNUNET_YES; |
897 | 899 | ||
898 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 900 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -909,6 +911,11 @@ receiver_destroy (struct ReceiverAddress *receiver) | |||
909 | GNUNET_TRANSPORT_communicator_mq_del (receiver->d_qh); | 911 | GNUNET_TRANSPORT_communicator_mq_del (receiver->d_qh); |
910 | receiver->d_qh = NULL; | 912 | receiver->d_qh = NULL; |
911 | } | 913 | } |
914 | else if (NULL != receiver->d_mq) | ||
915 | { | ||
916 | GNUNET_MQ_destroy (receiver->d_mq); | ||
917 | receiver->d_mq = NULL; | ||
918 | } | ||
912 | GNUNET_assert (GNUNET_YES == | 919 | GNUNET_assert (GNUNET_YES == |
913 | GNUNET_CONTAINER_multihashmap_remove (receivers, | 920 | GNUNET_CONTAINER_multihashmap_remove (receivers, |
914 | &receiver->key, | 921 | &receiver->key, |
@@ -918,6 +925,10 @@ receiver_destroy (struct ReceiverAddress *receiver) | |||
918 | "# receivers active", | 925 | "# receivers active", |
919 | GNUNET_CONTAINER_multihashmap_size (receivers), | 926 | GNUNET_CONTAINER_multihashmap_size (receivers), |
920 | GNUNET_NO); | 927 | GNUNET_NO); |
928 | while (NULL != (ss = receiver->ss_head)) | ||
929 | { | ||
930 | secret_destroy (ss); | ||
931 | } | ||
921 | GNUNET_free (receiver->address); | 932 | GNUNET_free (receiver->address); |
922 | GNUNET_free (receiver->foreign_addr); | 933 | GNUNET_free (receiver->foreign_addr); |
923 | GNUNET_free (receiver); | 934 | GNUNET_free (receiver); |
@@ -1065,6 +1076,7 @@ secret_destroy (struct SharedSecret *ss) | |||
1065 | static void | 1076 | static void |
1066 | sender_destroy (struct SenderAddress *sender) | 1077 | sender_destroy (struct SenderAddress *sender) |
1067 | { | 1078 | { |
1079 | struct SharedSecret *ss; | ||
1068 | sender->sender_destroy_called = GNUNET_YES; | 1080 | sender->sender_destroy_called = GNUNET_YES; |
1069 | GNUNET_assert ( | 1081 | GNUNET_assert ( |
1070 | GNUNET_YES == | 1082 | GNUNET_YES == |
@@ -1074,6 +1086,10 @@ sender_destroy (struct SenderAddress *sender) | |||
1074 | "# senders active", | 1086 | "# senders active", |
1075 | GNUNET_CONTAINER_multihashmap_size (senders), | 1087 | GNUNET_CONTAINER_multihashmap_size (senders), |
1076 | GNUNET_NO); | 1088 | GNUNET_NO); |
1089 | while (NULL != (ss = sender->ss_head)) | ||
1090 | { | ||
1091 | secret_destroy (ss); | ||
1092 | } | ||
1077 | GNUNET_free (sender->address); | 1093 | GNUNET_free (sender->address); |
1078 | GNUNET_free (sender); | 1094 | GNUNET_free (sender); |
1079 | } | 1095 | } |
@@ -2892,6 +2908,7 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address) | |||
2892 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2908 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2893 | "receiver %s already exist or is being connected to\n", | 2909 | "receiver %s already exist or is being connected to\n", |
2894 | address); | 2910 | address); |
2911 | GNUNET_free (in); | ||
2895 | return GNUNET_NO; | 2912 | return GNUNET_NO; |
2896 | } | 2913 | } |
2897 | 2914 | ||
diff --git a/src/service/transport/gnunet-service-transport.c b/src/service/transport/gnunet-service-transport.c index f4be5e759..91ce801db 100644 --- a/src/service/transport/gnunet-service-transport.c +++ b/src/service/transport/gnunet-service-transport.c | |||
@@ -920,7 +920,7 @@ struct TransportValidationResponseMessage | |||
920 | struct TransportGlobalNattedAddress | 920 | struct TransportGlobalNattedAddress |
921 | { | 921 | { |
922 | /** | 922 | /** |
923 | * Length of the address following the struct. | 923 | * Length of the address following the struct in NBO. |
924 | */ | 924 | */ |
925 | unsigned int address_length; | 925 | unsigned int address_length; |
926 | 926 | ||
@@ -3657,6 +3657,8 @@ remove_global_addresses (void *cls, | |||
3657 | struct TransportGlobalNattedAddress *tgna = value; | 3657 | struct TransportGlobalNattedAddress *tgna = value; |
3658 | 3658 | ||
3659 | GNUNET_free (tgna); | 3659 | GNUNET_free (tgna); |
3660 | |||
3661 | return GNUNET_OK; | ||
3660 | } | 3662 | } |
3661 | 3663 | ||
3662 | 3664 | ||
@@ -3681,6 +3683,7 @@ free_neighbour (struct Neighbour *neighbour) | |||
3681 | GNUNET_CONTAINER_multipeermap_iterate (neighbour->natted_addresses, | 3683 | GNUNET_CONTAINER_multipeermap_iterate (neighbour->natted_addresses, |
3682 | &remove_global_addresses, | 3684 | &remove_global_addresses, |
3683 | NULL); | 3685 | NULL); |
3686 | GNUNET_CONTAINER_multipeermap_destroy (neighbour->natted_addresses); | ||
3684 | while (NULL != (dvh = neighbour->dv_head)) | 3687 | while (NULL != (dvh = neighbour->dv_head)) |
3685 | { | 3688 | { |
3686 | struct DistanceVector *dv = dvh->dv; | 3689 | struct DistanceVector *dv = dvh->dv; |
@@ -5344,27 +5347,35 @@ static char * | |||
5344 | get_address_without_port (const char *address); | 5347 | get_address_without_port (const char *address); |
5345 | 5348 | ||
5346 | 5349 | ||
5350 | struct AddGlobalAddressesContext | ||
5351 | { | ||
5352 | size_t off; | ||
5353 | char *tgnas; | ||
5354 | }; | ||
5355 | |||
5356 | |||
5347 | static enum GNUNET_GenericReturnValue | 5357 | static enum GNUNET_GenericReturnValue |
5348 | add_global_addresses (void *cls, | 5358 | add_global_addresses (void *cls, |
5349 | const struct GNUNET_PeerIdentity *pid, | 5359 | const struct GNUNET_PeerIdentity *pid, |
5350 | void *value) | 5360 | void *value) |
5351 | { | 5361 | { |
5352 | char *tgnas = cls; | 5362 | struct AddGlobalAddressesContext *ctx = cls; |
5353 | struct TransportGlobalNattedAddress *tgna = value; | 5363 | struct TransportGlobalNattedAddress *tgna = value; |
5354 | char *addr = (char *) &tgna[1]; | 5364 | char *addr = (char *) &tgna[1]; |
5355 | size_t address_len = strlen (addr); | 5365 | size_t address_len = strlen (addr); |
5356 | unsigned int off = 0; | ||
5357 | 5366 | ||
5358 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 5367 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
5359 | "sending address %s length %u\n", | 5368 | "sending address %s length %lu\n", |
5360 | addr, | 5369 | addr, |
5361 | address_len); | 5370 | address_len); |
5362 | tgna = GNUNET_malloc (sizeof (struct TransportGlobalNattedAddress) + address_len); | 5371 | tgna = GNUNET_malloc (sizeof (struct TransportGlobalNattedAddress) + address_len); |
5363 | tgna->address_length = htonl (address_len); | 5372 | tgna->address_length = htonl (address_len); |
5364 | GNUNET_memcpy (&tgna[1], addr, address_len); | 5373 | GNUNET_memcpy (&tgna[1], addr, address_len); |
5365 | GNUNET_memcpy (&tgnas[off], tgna, sizeof (struct TransportGlobalNattedAddress) + address_len); | 5374 | GNUNET_memcpy (&(ctx->tgnas[ctx->off]), tgna, sizeof (struct TransportGlobalNattedAddress) + address_len); |
5366 | GNUNET_free (tgna); | 5375 | GNUNET_free (tgna); |
5367 | off += sizeof(struct TransportGlobalNattedAddress) + address_len; | 5376 | ctx->off += sizeof(struct TransportGlobalNattedAddress) + address_len; |
5377 | |||
5378 | return GNUNET_OK; | ||
5368 | } | 5379 | } |
5369 | 5380 | ||
5370 | 5381 | ||
@@ -5386,17 +5397,20 @@ consider_sending_fc (void *cls) | |||
5386 | 5397 | ||
5387 | if (0 < n->number_of_addresses) | 5398 | if (0 < n->number_of_addresses) |
5388 | { | 5399 | { |
5389 | char *tgnas = GNUNET_malloc (n->number_of_addresses * sizeof (struct TransportGlobalNattedAddress) + n->size_of_global_addresses); | 5400 | size_t addresses_size = |
5390 | size_t addresses_size; | 5401 | n->number_of_addresses * sizeof (struct TransportGlobalNattedAddress) + n->size_of_global_addresses; |
5402 | char *tgnas = GNUNET_malloc (addresses_size); | ||
5403 | struct AddGlobalAddressesContext ctx; | ||
5404 | ctx.off = 0; | ||
5405 | ctx.tgnas = tgnas; | ||
5391 | 5406 | ||
5392 | addresses_size = n->number_of_addresses * sizeof (struct TransportGlobalNattedAddress) + n->size_of_global_addresses; | ||
5393 | fc = GNUNET_malloc (sizeof (struct TransportFlowControlMessage) + addresses_size); | 5407 | fc = GNUNET_malloc (sizeof (struct TransportFlowControlMessage) + addresses_size); |
5394 | fc->header.size = htons (sizeof(struct TransportFlowControlMessage) + addresses_size); | 5408 | fc->header.size = htons (sizeof(struct TransportFlowControlMessage) + addresses_size); |
5395 | fc->size_of_addresses = htonl (n->size_of_global_addresses); | 5409 | fc->size_of_addresses = htonl (n->size_of_global_addresses); |
5396 | fc->number_of_addresses = htonl (n->number_of_addresses); | 5410 | fc->number_of_addresses = htonl (n->number_of_addresses); |
5397 | GNUNET_CONTAINER_multipeermap_iterate (n->natted_addresses, | 5411 | GNUNET_CONTAINER_multipeermap_iterate (n->natted_addresses, |
5398 | &add_global_addresses, | 5412 | &add_global_addresses, |
5399 | tgnas); | 5413 | &ctx); |
5400 | GNUNET_memcpy (&fc[1], tgnas, addresses_size); | 5414 | GNUNET_memcpy (&fc[1], tgnas, addresses_size); |
5401 | GNUNET_free (tgnas); | 5415 | GNUNET_free (tgnas); |
5402 | } | 5416 | } |
@@ -5939,19 +5953,16 @@ handle_add_address (void *cls, | |||
5939 | struct TransportClient *tc = cls; | 5953 | struct TransportClient *tc = cls; |
5940 | struct AddressListEntry *ale; | 5954 | struct AddressListEntry *ale; |
5941 | size_t slen; | 5955 | size_t slen; |
5942 | char *address; | ||
5943 | 5956 | ||
5944 | /* 0-termination of &aam[1] was checked in #check_add_address */ | 5957 | /* 0-termination of &aam[1] was checked in #check_add_address */ |
5945 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 5958 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
5946 | "Communicator added address `%s'!\n", | 5959 | "Communicator added address `%s'!\n", |
5947 | (const char *) &aam[1]); | 5960 | (const char *) &aam[1]); |
5948 | slen = ntohs (aam->header.size) - sizeof(*aam); | 5961 | slen = ntohs (aam->header.size) - sizeof(*aam); |
5949 | address = GNUNET_malloc (slen); | ||
5950 | memcpy (address, &aam[1], slen); | ||
5951 | ale = create_address_entry (tc, | 5962 | ale = create_address_entry (tc, |
5952 | GNUNET_TIME_relative_ntoh (aam->expiration), | 5963 | GNUNET_TIME_relative_ntoh (aam->expiration), |
5953 | (enum GNUNET_NetworkType) ntohl (aam->nt), | 5964 | (enum GNUNET_NetworkType) ntohl (aam->nt), |
5954 | address, | 5965 | (const char *) &aam[1], |
5955 | aam->aid, | 5966 | aam->aid, |
5956 | slen); | 5967 | slen); |
5957 | GNUNET_CONTAINER_DLL_insert (tc->details.communicator.addr_head, | 5968 | GNUNET_CONTAINER_DLL_insert (tc->details.communicator.addr_head, |
@@ -9610,11 +9621,10 @@ static int | |||
9610 | check_flow_control (void *cls, const struct TransportFlowControlMessage *fc) | 9621 | check_flow_control (void *cls, const struct TransportFlowControlMessage *fc) |
9611 | { | 9622 | { |
9612 | (void) cls; | 9623 | (void) cls; |
9613 | struct TransportGlobalNattedAddress *addresses = (struct TransportGlobalNattedAddress *) &fc[1]; | ||
9614 | unsigned int number_of_addresses = ntohl (fc->number_of_addresses); | 9624 | unsigned int number_of_addresses = ntohl (fc->number_of_addresses); |
9615 | 9625 | ||
9616 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 9626 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
9617 | "Flow control header size %u size of addresses %u number of addresses %u size of message struct %u second struct %u\n", | 9627 | "Flow control header size %u size of addresses %u number of addresses %u size of message struct %lu second struct %lu\n", |
9618 | ntohs (fc->header.size), | 9628 | ntohs (fc->header.size), |
9619 | ntohl (fc->size_of_addresses), | 9629 | ntohl (fc->size_of_addresses), |
9620 | ntohl (fc->number_of_addresses), | 9630 | ntohl (fc->number_of_addresses), |
@@ -11595,16 +11605,14 @@ iterate_address_and_compare_cb (void *cls, | |||
11595 | const char *uri) | 11605 | const char *uri) |
11596 | { | 11606 | { |
11597 | struct Queue *queue = cls; | 11607 | struct Queue *queue = cls; |
11598 | struct Neighbour *neighbour = queue->neighbour; | ||
11599 | const char *dash; | ||
11600 | const char *slash; | 11608 | const char *slash; |
11601 | char *address_uri; | 11609 | char *address_uri; |
11602 | char *prefix; | 11610 | char *prefix; |
11603 | char *uri_without_port; | 11611 | char *uri_without_port; |
11604 | char *address_uri_without_port = get_address_without_port (queue->address); | 11612 | char *address_uri_without_port; |
11605 | 11613 | ||
11606 | slash = strrchr (uri, '/'); | 11614 | slash = strrchr (uri, '/'); |
11607 | prefix = GNUNET_strndup (uri, (slash - uri) - 2); | 11615 | prefix = GNUNET_strndup (uri, (slash - uri) - 2); |
11608 | GNUNET_assert (NULL != slash); | 11616 | GNUNET_assert (NULL != slash); |
11609 | slash++; | 11617 | slash++; |
11610 | GNUNET_asprintf (&address_uri, | 11618 | GNUNET_asprintf (&address_uri, |
@@ -11674,7 +11682,8 @@ contains_address (void *cls, | |||
11674 | struct TransportGlobalNattedAddress *tgna = value; | 11682 | struct TransportGlobalNattedAddress *tgna = value; |
11675 | char *addr = (char *) &tgna[1]; | 11683 | char *addr = (char *) &tgna[1]; |
11676 | 11684 | ||
11677 | if (0 == GNUNET_memcmp (addr, tgna_cls->addr)) | 11685 | if (strlen(tgna_cls->addr) == ntohl (tgna->address_length) |
11686 | && 0 == strncmp (addr, tgna_cls->addr, ntohl (tgna->address_length))) | ||
11678 | { | 11687 | { |
11679 | tgna_cls->tgna = tgna; | 11688 | tgna_cls->tgna = tgna; |
11680 | return GNUNET_NO; | 11689 | return GNUNET_NO; |
@@ -11728,18 +11737,20 @@ check_for_global_natted (void *cls, | |||
11728 | GNUNET_HELLO_builder_free (builder); | 11737 | GNUNET_HELLO_builder_free (builder); |
11729 | 11738 | ||
11730 | tgna_cls.addr = get_address_without_port (queue->address); | 11739 | tgna_cls.addr = get_address_without_port (queue->address); |
11740 | tgna_cls.tgna = NULL; | ||
11731 | address_len_without_port = strlen (tgna_cls.addr); | 11741 | address_len_without_port = strlen (tgna_cls.addr); |
11732 | GNUNET_CONTAINER_multipeermap_get_multiple (neighbour->natted_addresses, | 11742 | GNUNET_CONTAINER_multipeermap_get_multiple (neighbour->natted_addresses, |
11733 | &neighbour->pid, | 11743 | &neighbour->pid, |
11734 | &contains_address, | 11744 | &contains_address, |
11735 | &tgna_cls); | 11745 | &tgna_cls); |
11736 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 11746 | if (NULL != tgna_cls.tgna) |
11737 | " tgna_cls.tgna tgna %p %u %u %u\n", | 11747 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
11738 | tgna_cls.tgna, | 11748 | " tgna_cls.tgna tgna %p %lu %u %u\n", |
11739 | neighbour->size_of_global_addresses, | 11749 | tgna_cls.tgna, |
11740 | tgna_cls.tgna->address_length, | 11750 | neighbour->size_of_global_addresses, |
11741 | neighbour->number_of_addresses); | 11751 | ntohl (tgna_cls.tgna->address_length), |
11742 | if (0 == tgna_cls.tgna->address_length && GNUNET_YES == queue->is_global_natted) | 11752 | neighbour->number_of_addresses); |
11753 | if (NULL == tgna_cls.tgna && GNUNET_YES == queue->is_global_natted) | ||
11743 | { | 11754 | { |
11744 | struct TransportGlobalNattedAddress *tgna; | 11755 | struct TransportGlobalNattedAddress *tgna; |
11745 | 11756 | ||
@@ -11756,7 +11767,7 @@ check_for_global_natted (void *cls, | |||
11756 | "Created tgna %p\n", | 11767 | "Created tgna %p\n", |
11757 | tgna); | 11768 | tgna); |
11758 | } | 11769 | } |
11759 | else if (0 != tgna_cls.tgna->address_length && GNUNET_NO == queue->is_global_natted) | 11770 | else if (NULL != tgna_cls.tgna && GNUNET_NO == queue->is_global_natted) |
11760 | { | 11771 | { |
11761 | GNUNET_CONTAINER_multipeermap_remove (neighbour->natted_addresses, | 11772 | GNUNET_CONTAINER_multipeermap_remove (neighbour->natted_addresses, |
11762 | &neighbour->pid, | 11773 | &neighbour->pid, |
diff --git a/src/service/transport/test_transport_plugin_cmd_simple_send_performance.c b/src/service/transport/test_transport_plugin_cmd_simple_send_performance.c index 33deb3323..fe92e0ad9 100644 --- a/src/service/transport/test_transport_plugin_cmd_simple_send_performance.c +++ b/src/service/transport/test_transport_plugin_cmd_simple_send_performance.c | |||
@@ -24,13 +24,11 @@ | |||
24 | * @author t3sserakt | 24 | * @author t3sserakt |
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_testing_barrier.h" | ||
28 | #include "gnunet_testing_netjail_lib.h" | ||
29 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_testing_lib.h" | ||
30 | #include "gnunet_transport_application_service.h" | 29 | #include "gnunet_transport_application_service.h" |
31 | #include "transport-testing2.h" | 30 | #include "transport-testing2.h" |
32 | #include "transport-testing-cmds.h" | 31 | #include "transport-testing-cmds.h" |
33 | #include "gnunet_testing_barrier.h" | ||
34 | 32 | ||
35 | /** | 33 | /** |
36 | * Generic logging shortcut | 34 | * Generic logging shortcut |
diff --git a/src/service/transport/test_transport_plugin_cmd_udp_backchannel.c b/src/service/transport/test_transport_plugin_cmd_udp_backchannel.c index 75fb85e66..7e67d6fad 100644 --- a/src/service/transport/test_transport_plugin_cmd_udp_backchannel.c +++ b/src/service/transport/test_transport_plugin_cmd_udp_backchannel.c | |||
@@ -176,26 +176,15 @@ all_local_tests_prepared () | |||
176 | 176 | ||
177 | 177 | ||
178 | /** | 178 | /** |
179 | * Function to start a local test case. | 179 | * Entry point for the plugin. |
180 | * | 180 | * |
181 | * @param write_message Callback to send a message to the master loop. | 181 | * @param cls NULL |
182 | * @param router_ip Global address of the network namespace. | 182 | * @return the exported block API |
183 | * @param node_ip The IP address of the node. | ||
184 | * @param m The number of the node in a network namespace. | ||
185 | * @param n The number of the network namespace. | ||
186 | * @param local_m The number of nodes in a network namespace. | ||
187 | */ | 183 | */ |
188 | static struct GNUNET_TESTING_Interpreter * | 184 | void * |
189 | start_testcase (GNUNET_TESTING_cmd_helper_write_cb write_message, | 185 | libgnunet_test_transport_plugin_cmd_udp_backchannel_init (void *cls) |
190 | const char *router_ip, | ||
191 | const char *node_ip, | ||
192 | const char *m, | ||
193 | const char *n, | ||
194 | const char *local_m, | ||
195 | const char *topology_data, | ||
196 | unsigned int *read_file, | ||
197 | GNUNET_TESTING_cmd_helper_finish_cb finished_cb) | ||
198 | { | 186 | { |
187 | struct GNUNET_TESTING_PluginFunctions *api; | ||
199 | 188 | ||
200 | unsigned int n_int; | 189 | unsigned int n_int; |
201 | unsigned int m_int; | 190 | unsigned int m_int; |
@@ -318,38 +307,42 @@ start_testcase (GNUNET_TESTING_cmd_helper_write_cb write_message, | |||
318 | GNUNET_TESTING_cmd_end () | 307 | GNUNET_TESTING_cmd_end () |
319 | }; | 308 | }; |
320 | 309 | ||
321 | ts->write_message = write_message; | 310 | return GNUNET_TESTING_make_plugin (commands); |
322 | |||
323 | is = GNUNET_TESTING_run (commands, | ||
324 | TIMEOUT, | ||
325 | &handle_result, | ||
326 | ts); | ||
327 | return is; | ||
328 | } | 311 | } |
329 | 312 | ||
330 | 313 | ||
331 | /** | 314 | GNUNET_TESTING_MAKE_PLUGIN ( |
332 | * Entry point for the plugin. | 315 | libgnunet, |
333 | * | 316 | udp_backchannel, |
334 | * @param cls NULL | 317 | GNUNET_TESTING_cmd_system_create ("system-create", |
335 | * @return the exported block API | 318 | ts->testdir), |
336 | */ | 319 | GNUNET_TRANSPORT_cmd_start_peer ("start-peer", |
337 | void * | 320 | "system-create", |
338 | libgnunet_test_transport_plugin_cmd_udp_backchannel_init (void *cls) | 321 | num, |
339 | { | 322 | node_ip, |
340 | struct GNUNET_TESTING_PluginFunctions *api; | 323 | handlers, |
341 | 324 | ts->cfgname, | |
342 | GNUNET_log_setup ("udp-backchannel", | 325 | notify_connect, |
343 | "DEBUG", | 326 | GNUNET_NO), |
344 | "plugin.out"); | 327 | GNUNET_TESTING_cmd_send_peer_ready ( |
345 | 328 | "send-peer-ready", | |
346 | api = GNUNET_new (struct GNUNET_TESTING_PluginFunctions); | 329 | write_message), |
347 | api->start_testcase = &start_testcase; | 330 | block_send, |
348 | api->all_peers_started = &all_peers_started; | 331 | connect_peers, |
349 | api->all_local_tests_prepared = all_local_tests_prepared; | 332 | GNUNET_TRANSPORT_cmd_backchannel_check ( |
350 | api->get_waiting_for_barriers = get_waiting_for_barriers; | 333 | "backchannel-check", |
351 | return api; | 334 | "start-peer", |
352 | } | 335 | "system-create", |
336 | num, | ||
337 | m_int, | ||
338 | n_int, | ||
339 | topology), | ||
340 | local_prepared, | ||
341 | GNUNET_TRANSPORT_cmd_stop_peer ("stop-peer", | ||
342 | "start-peer"), | ||
343 | GNUNET_TESTING_cmd_system_destroy ("system-destroy", | ||
344 | "system-create") | ||
345 | ); | ||
353 | 346 | ||
354 | 347 | ||
355 | /** | 348 | /** |
diff --git a/src/service/transport/test_transport_simple_send.sh b/src/service/transport/test_transport_simple_send.sh index 0250070be..af7515753 100755 --- a/src/service/transport/test_transport_simple_send.sh +++ b/src/service/transport/test_transport_simple_send.sh | |||
@@ -1,11 +1,4 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | if ! [ -d "/run/netns" ]; then | 2 | exec netjail_test_master.sh ./test_transport_start_with_config test_transport_simple_send_topo.conf |
3 | echo You have to create the directory /run/netns. | 3 | |
4 | fi | 4 | # exec netjail_test_master.sh gnunet-testing-netjail-launcher test_transport_simple_send_topo.conf |
5 | if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; then | ||
6 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" != 1 ]; then | ||
7 | echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" | ||
8 | exit 78 | ||
9 | fi | ||
10 | fi | ||
11 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; ./test_transport_start_with_config test_transport_simple_send_topo.conf" | ||
diff --git a/src/service/transport/test_transport_start_with_config.c b/src/service/transport/test_transport_start_with_config.c index 349cd65a5..2c00dde8a 100644 --- a/src/service/transport/test_transport_start_with_config.c +++ b/src/service/transport/test_transport_start_with_config.c | |||
@@ -24,8 +24,7 @@ | |||
24 | * @author t3sserakt | 24 | * @author t3sserakt |
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_testing_ng_lib.h" | 27 | #include "gnunet_testing_lib.h" |
28 | #include "gnunet_testing_netjail_lib.h" | ||
29 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
30 | 29 | ||
31 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600) | 30 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600) |
diff --git a/src/service/transport/testing_api_cmd_start_peer.c b/src/service/transport/testing_api_cmd_start_peer.c deleted file mode 100644 index 4454b2939..000000000 --- a/src/service/transport/testing_api_cmd_start_peer.c +++ /dev/null | |||
@@ -1,296 +0,0 @@ | |||
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_api_cmd_start_peer.c | ||
23 | * @brief cmd to start a peer. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "transport-testing-cmds.h" | ||
29 | #include "gnunet_testing_ng_lib.h" | ||
30 | #include "gnunet_transport_testing_ng_lib.h" | ||
31 | |||
32 | |||
33 | /** | ||
34 | * Generic logging shortcut | ||
35 | */ | ||
36 | #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) | ||
37 | |||
38 | |||
39 | /** | ||
40 | * The run method of this cmd will start all services of a peer to test the transport service. | ||
41 | * | ||
42 | */ | ||
43 | static void | ||
44 | start_peer_run (void *cls, | ||
45 | struct GNUNET_TESTING_Interpreter *is) | ||
46 | { | ||
47 | struct GNUNET_TESTING_StartPeerState *sps = cls; | ||
48 | char *emsg = NULL; | ||
49 | struct GNUNET_PeerIdentity dummy; | ||
50 | const struct GNUNET_TESTING_Command *system_cmd; | ||
51 | const struct GNUNET_TESTING_System *tl_system; | ||
52 | char *home; | ||
53 | char *transport_unix_path; | ||
54 | char *tcp_communicator_unix_path; | ||
55 | char *udp_communicator_unix_path; | ||
56 | char *bindto; | ||
57 | char *bindto_udp; | ||
58 | |||
59 | if (GNUNET_NO == GNUNET_DISK_file_test (sps->cfgname)) | ||
60 | { | ||
61 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
62 | "File not found: `%s'\n", | ||
63 | sps->cfgname); | ||
64 | GNUNET_TESTING_interpreter_fail (is); | ||
65 | return; | ||
66 | } | ||
67 | |||
68 | |||
69 | sps->cfg = GNUNET_CONFIGURATION_create (); | ||
70 | GNUNET_assert (GNUNET_OK == | ||
71 | GNUNET_CONFIGURATION_load (sps->cfg, sps->cfgname)); | ||
72 | |||
73 | GNUNET_asprintf (&home, | ||
74 | "$GNUNET_TMP/test-transport/api-tcp-p%u", | ||
75 | sps->no); | ||
76 | |||
77 | GNUNET_asprintf (&transport_unix_path, | ||
78 | "$GNUNET_RUNTIME_DIR/tng-p%u.sock", | ||
79 | sps->no); | ||
80 | |||
81 | GNUNET_asprintf (&tcp_communicator_unix_path, | ||
82 | "$GNUNET_RUNTIME_DIR/tcp-comm-p%u.sock", | ||
83 | sps->no); | ||
84 | |||
85 | GNUNET_asprintf (&udp_communicator_unix_path, | ||
86 | "$GNUNET_RUNTIME_DIR/tcp-comm-p%u.sock", | ||
87 | sps->no); | ||
88 | |||
89 | GNUNET_asprintf (&bindto, | ||
90 | "%s:60002", | ||
91 | sps->node_ip); | ||
92 | |||
93 | GNUNET_asprintf (&bindto_udp, | ||
94 | "2086"); | ||
95 | |||
96 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
97 | "node_ip %s\n", | ||
98 | bindto); | ||
99 | |||
100 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
101 | "bind_udp %s\n", | ||
102 | GNUNET_YES == sps->broadcast ? | ||
103 | bindto_udp : bindto); | ||
104 | |||
105 | GNUNET_CONFIGURATION_set_value_string (sps->cfg, "PATHS", "GNUNET_TEST_HOME", | ||
106 | home); | ||
107 | GNUNET_CONFIGURATION_set_value_string (sps->cfg, "transport", "UNIXPATH", | ||
108 | transport_unix_path); | ||
109 | GNUNET_CONFIGURATION_set_value_string (sps->cfg, "communicator-tcp", | ||
110 | "BINDTO", | ||
111 | bindto); | ||
112 | GNUNET_CONFIGURATION_set_value_string (sps->cfg, "communicator-udp", | ||
113 | "BINDTO", | ||
114 | GNUNET_YES == sps->broadcast ? | ||
115 | bindto_udp : bindto); | ||
116 | GNUNET_CONFIGURATION_set_value_string (sps->cfg, "communicator-tcp", | ||
117 | "UNIXPATH", | ||
118 | tcp_communicator_unix_path); | ||
119 | GNUNET_CONFIGURATION_set_value_string (sps->cfg, "communicator-udp", | ||
120 | "UNIXPATH", | ||
121 | udp_communicator_unix_path); | ||
122 | |||
123 | |||
124 | system_cmd = GNUNET_TESTING_interpreter_lookup_command (is, | ||
125 | sps->system_label); | ||
126 | GNUNET_TESTING_get_trait_test_system (system_cmd, | ||
127 | &tl_system); | ||
128 | |||
129 | sps->tl_system = tl_system; | ||
130 | |||
131 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
132 | "Creating testing library with key number %u\n", | ||
133 | sps->no); | ||
134 | |||
135 | if (GNUNET_SYSERR == | ||
136 | GNUNET_TESTING_configuration_create ((struct | ||
137 | GNUNET_TESTING_System *) tl_system, | ||
138 | sps->cfg)) | ||
139 | { | ||
140 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
141 | "Testing library failed to create unique configuration based on `%s'\n", | ||
142 | sps->cfgname); | ||
143 | GNUNET_CONFIGURATION_destroy (sps->cfg); | ||
144 | GNUNET_TESTING_interpreter_fail (is); | ||
145 | return; | ||
146 | } | ||
147 | |||
148 | sps->peer = GNUNET_TESTING_peer_configure ((struct | ||
149 | GNUNET_TESTING_System *) sps-> | ||
150 | tl_system, | ||
151 | sps->cfg, | ||
152 | sps->no, | ||
153 | NULL, | ||
154 | &emsg); | ||
155 | if (NULL == sps->peer) | ||
156 | { | ||
157 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
158 | "Testing library failed to create unique configuration based on `%s': `%s' with key number %u\n", | ||
159 | sps->cfgname, | ||
160 | emsg, | ||
161 | sps->no); | ||
162 | GNUNET_free (emsg); | ||
163 | GNUNET_TESTING_interpreter_fail (is); | ||
164 | return; | ||
165 | } | ||
166 | |||
167 | if (GNUNET_OK != GNUNET_TESTING_peer_start (sps->peer)) | ||
168 | { | ||
169 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
170 | "Testing library failed to create unique configuration based on `%s'\n", | ||
171 | sps->cfgname); | ||
172 | GNUNET_free (emsg); | ||
173 | GNUNET_TESTING_interpreter_fail (is); | ||
174 | return; | ||
175 | } | ||
176 | |||
177 | memset (&dummy, | ||
178 | '\0', | ||
179 | sizeof(dummy)); | ||
180 | |||
181 | GNUNET_TESTING_peer_get_identity (sps->peer, | ||
182 | &sps->id); | ||
183 | |||
184 | if (0 == memcmp (&dummy, | ||
185 | &sps->id, | ||
186 | sizeof(struct GNUNET_PeerIdentity))) | ||
187 | { | ||
188 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
189 | "Testing library failed to obtain peer identity for peer %u\n", | ||
190 | sps->no); | ||
191 | GNUNET_free (emsg); | ||
192 | GNUNET_TESTING_interpreter_fail (is); | ||
193 | return; | ||
194 | } | ||
195 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
196 | "Peer %u configured with identity `%s'\n", | ||
197 | sps->no, | ||
198 | GNUNET_i2s_full (&sps->id)); | ||
199 | |||
200 | GNUNET_free (home); | ||
201 | GNUNET_free (transport_unix_path); | ||
202 | GNUNET_free (tcp_communicator_unix_path); | ||
203 | GNUNET_free (udp_communicator_unix_path); | ||
204 | GNUNET_free (bindto); | ||
205 | GNUNET_free (bindto_udp); | ||
206 | } | ||
207 | |||
208 | |||
209 | /** | ||
210 | * The cleanup function of this cmd frees resources the cmd allocated. | ||
211 | * | ||
212 | */ | ||
213 | static void | ||
214 | start_peer_cleanup (void *cls) | ||
215 | { | ||
216 | struct GNUNET_TESTING_StartPeerState *sps = cls; | ||
217 | |||
218 | //TODO Investigate why this caused problems during shutdown. | ||
219 | /*if (NULL != sps->cfg) | ||
220 | { | ||
221 | GNUNET_CONFIGURATION_destroy (sps->cfg); | ||
222 | sps->cfg = NULL; | ||
223 | }*/ | ||
224 | GNUNET_free (sps->cfgname); | ||
225 | GNUNET_free (sps->node_ip); | ||
226 | GNUNET_free (sps->system_label); | ||
227 | GNUNET_free (sps->hello); | ||
228 | GNUNET_free (sps->connected_peers_map); | ||
229 | GNUNET_free (sps); | ||
230 | } | ||
231 | |||
232 | |||
233 | /** | ||
234 | * This function prepares an array with traits. | ||
235 | * | ||
236 | */ | ||
237 | static int | ||
238 | start_peer_traits (void *cls, | ||
239 | const void **ret, | ||
240 | const char *trait, | ||
241 | unsigned int index) | ||
242 | { | ||
243 | struct GNUNET_TESTING_StartPeerState *sps = cls; | ||
244 | struct GNUNET_TRANSPORT_ApplicationHandle *ah = sps->ah; | ||
245 | struct GNUNET_PeerIdentity *id = &sps->id; | ||
246 | struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map = | ||
247 | sps->connected_peers_map; | ||
248 | char *hello = sps->hello; | ||
249 | size_t hello_size = sps->hello_size; | ||
250 | struct GNUNET_TESTING_Trait traits[] = { | ||
251 | GNUNET_TRANSPORT_TESTING_make_trait_application_handle ((const void *) ah), | ||
252 | GNUNET_TRANSPORT_TESTING_make_trait_peer_id ((const void *) id), | ||
253 | GNUNET_TRANSPORT_TESTING_make_trait_connected_peers_map ((const | ||
254 | void *) | ||
255 | connected_peers_map), | ||
256 | GNUNET_TRANSPORT_TESTING_make_trait_hello ((const void *) hello), | ||
257 | GNUNET_TRANSPORT_TESTING_make_trait_hello_size ((const void *) hello_size), | ||
258 | GNUNET_TRANSPORT_TESTING_make_trait_state ((const void *) sps), | ||
259 | GNUNET_TRANSPORT_TESTING_make_trait_broadcast ((const void *) &sps->broadcast), | ||
260 | GNUNET_TESTING_trait_end () | ||
261 | }; | ||
262 | |||
263 | return GNUNET_TESTING_get_trait (traits, | ||
264 | ret, | ||
265 | trait, | ||
266 | index); | ||
267 | } | ||
268 | |||
269 | |||
270 | struct GNUNET_TESTING_Command | ||
271 | GNUNET_TESTING_cmd_start_peer (const char *label, | ||
272 | const char *system_label, | ||
273 | uint32_t no, | ||
274 | const char *node_ip, | ||
275 | const char *cfgname, | ||
276 | unsigned int broadcast) | ||
277 | { | ||
278 | struct GNUNET_TESTING_StartPeerState *sps; | ||
279 | struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map = | ||
280 | GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO); | ||
281 | |||
282 | sps = GNUNET_new (struct GNUNET_TESTING_StartPeerState); | ||
283 | sps->no = no; | ||
284 | sps->system_label = GNUNET_strdup (system_label); | ||
285 | sps->connected_peers_map = connected_peers_map; | ||
286 | sps->cfgname = GNUNET_strdup (cfgname); | ||
287 | sps->node_ip = GNUNET_strdup (node_ip); | ||
288 | sps->broadcast = broadcast; | ||
289 | |||
290 | return GNUNET_TESTING_command_new (sps, | ||
291 | label, | ||
292 | &start_peer_run, | ||
293 | &start_peer_cleanup, | ||
294 | &start_peer_traits, | ||
295 | NULL); | ||
296 | } | ||
diff --git a/src/service/transport/testing_api_traits.c b/src/service/transport/testing_api_traits.c new file mode 100644 index 000000000..131c42a5d --- /dev/null +++ b/src/service/transport/testing_api_traits.c | |||
@@ -0,0 +1,35 @@ | |||
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 transport/test_transport_start_with_config.c | ||
23 | * @brief Generic program to start testcases in an configurable topology. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_lib.h" | ||
29 | #include "transport-testing-cmds.h" | ||
30 | |||
31 | GNUNET_TRANSPORT_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, | ||
32 | GNUNET_TRANSPORT_TESTING) | ||
33 | |||
34 | GNUNET_TRANSPORT_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, | ||
35 | GNUNET_TRANSPORT_TESTING) | ||
diff --git a/src/service/transport/transport-testing-cmds.h b/src/service/transport/transport-testing-cmds.h index 7ebc84d11..28161223a 100644 --- a/src/service/transport/transport-testing-cmds.h +++ b/src/service/transport/transport-testing-cmds.h | |||
@@ -27,7 +27,7 @@ | |||
27 | #ifndef TRANSPORT_TESTING_CMDS_H | 27 | #ifndef TRANSPORT_TESTING_CMDS_H |
28 | #define TRANSPORT_TESTING_CMDS_H | 28 | #define TRANSPORT_TESTING_CMDS_H |
29 | 29 | ||
30 | #include "gnunet_testing_ng_lib.h" | 30 | #include "gnunet_testing_lib.h" |
31 | #include "gnunet_transport_testing_ng_lib.h" | 31 | #include "gnunet_transport_testing_ng_lib.h" |
32 | 32 | ||
33 | 33 | ||
@@ -48,7 +48,7 @@ struct ConnectPeersState | |||
48 | /** | 48 | /** |
49 | * The testing system of this node. | 49 | * The testing system of this node. |
50 | */ | 50 | */ |
51 | const struct GNUNET_TESTING_System *tl_system; | 51 | const struct GNUNET_TESTBED_System *tl_system; |
52 | 52 | ||
53 | // Label of the cmd which started the test system. | 53 | // Label of the cmd which started the test system. |
54 | const char *create_label; | 54 | const char *create_label; |
@@ -104,27 +104,14 @@ struct ConnectPeersState | |||
104 | }; | 104 | }; |
105 | 105 | ||
106 | 106 | ||
107 | |||
108 | typedef void * | 107 | typedef void * |
109 | (*GNUNET_TRANSPORT_notify_connect_cb) (struct GNUNET_TESTING_Interpreter *is, | 108 | (*GNUNET_TRANSPORT_notify_connect_cb) (struct GNUNET_TESTING_Interpreter *is, |
110 | const struct GNUNET_PeerIdentity *peer); | 109 | const struct GNUNET_PeerIdentity *peer); |
111 | 110 | ||
112 | 111 | ||
113 | |||
114 | struct TestState | 112 | struct TestState |
115 | { | 113 | { |
116 | /** | 114 | /** |
117 | * Callback to write messages to the master loop. | ||
118 | * | ||
119 | */ | ||
120 | GNUNET_TESTING_cmd_helper_write_cb write_message; | ||
121 | |||
122 | /** | ||
123 | * Callback to notify the helper test case has finished. | ||
124 | */ | ||
125 | GNUNET_TESTING_cmd_helper_finish_cb finished_cb; | ||
126 | |||
127 | /** | ||
128 | * The name for a specific test environment directory. | 115 | * The name for a specific test environment directory. |
129 | * | 116 | * |
130 | */ | 117 | */ |
@@ -214,7 +201,7 @@ GNUNET_TRANSPORT_cmd_send_simple (const char *label, | |||
214 | topology); | 201 | topology); |
215 | 202 | ||
216 | /** | 203 | /** |
217 | * | 204 | * |
218 | * | 205 | * |
219 | * @param label name for command. | 206 | * @param label name for command. |
220 | * @param start_peer_label Label of the cmd to start a peer. | 207 | * @param start_peer_label Label of the cmd to start a peer. |
@@ -227,13 +214,14 @@ GNUNET_TRANSPORT_cmd_send_simple (const char *label, | |||
227 | */ | 214 | */ |
228 | struct GNUNET_TESTING_Command | 215 | struct GNUNET_TESTING_Command |
229 | GNUNET_TRANSPORT_cmd_send_simple_performance (const char *label, | 216 | GNUNET_TRANSPORT_cmd_send_simple_performance (const char *label, |
230 | const char *start_peer_label, | 217 | const char *start_peer_label, |
231 | const char *create_label, | 218 | const char *create_label, |
232 | uint32_t num, | 219 | uint32_t num, |
233 | int size, | 220 | int size, |
234 | int max_send, | 221 | int max_send, |
235 | struct GNUNET_TESTING_NetjailTopology * | 222 | struct |
236 | topology); | 223 | GNUNET_TESTING_NetjailTopology * |
224 | topology); | ||
237 | 225 | ||
238 | 226 | ||
239 | /** | 227 | /** |
@@ -259,14 +247,14 @@ GNUNET_TRANSPORT_cmd_backchannel_check (const char *label, | |||
259 | topology); | 247 | topology); |
260 | 248 | ||
261 | 249 | ||
262 | |||
263 | /** | 250 | /** |
264 | * Call #op on all simple traits. | 251 | * Call #op on all simple traits. |
265 | */ | 252 | */ |
266 | #define GNUNET_TRANSPORT_SIMPLE_TRAITS(op, prefix) \ | 253 | #define GNUNET_TRANSPORT_SIMPLE_TRAITS(op, prefix) \ |
267 | op (prefix, connect_peer_state, const struct ConnectPeersState) | 254 | op (prefix, connect_peer_state, const struct ConnectPeersState) |
268 | 255 | ||
269 | GNUNET_TRANSPORT_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT, GNUNET_TRANSPORT_TESTING) | 256 | GNUNET_TRANSPORT_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT, |
257 | GNUNET_TRANSPORT_TESTING) | ||
270 | 258 | ||
271 | 259 | ||
272 | #endif | 260 | #endif |
diff --git a/src/service/transport/transport-testing-communicator.c b/src/service/transport/transport-testing-communicator.c index 7d8abbe1e..9ee70fe7b 100644 --- a/src/service/transport/transport-testing-communicator.c +++ b/src/service/transport/transport-testing-communicator.c | |||
@@ -186,6 +186,7 @@ handle_communicator_available ( | |||
186 | return; /* receive-only communicator */ | 186 | return; /* receive-only communicator */ |
187 | } | 187 | } |
188 | tc_h->c_characteristics = ntohl (msg->cc); | 188 | tc_h->c_characteristics = ntohl (msg->cc); |
189 | GNUNET_free (tc_h->c_addr_prefix); | ||
189 | tc_h->c_addr_prefix = GNUNET_strdup ((const char *) &msg[1]); | 190 | tc_h->c_addr_prefix = GNUNET_strdup ((const char *) &msg[1]); |
190 | if (NULL != tc_h->communicator_available_cb) | 191 | if (NULL != tc_h->communicator_available_cb) |
191 | { | 192 | { |
@@ -320,6 +321,7 @@ handle_add_address (void *cls, | |||
320 | if (0 == size) | 321 | if (0 == size) |
321 | return; /* receive-only communicator */ | 322 | return; /* receive-only communicator */ |
322 | LOG (GNUNET_ERROR_TYPE_DEBUG, "received add address cb %u\n", size); | 323 | LOG (GNUNET_ERROR_TYPE_DEBUG, "received add address cb %u\n", size); |
324 | GNUNET_free (tc_h->c_address); | ||
323 | tc_h->c_address = GNUNET_strdup ((const char *) &msg[1]); | 325 | tc_h->c_address = GNUNET_strdup ((const char *) &msg[1]); |
324 | if (NULL != tc_h->add_address_cb) | 326 | if (NULL != tc_h->add_address_cb) |
325 | { | 327 | { |
@@ -852,6 +854,7 @@ communicator_start ( | |||
852 | "-c", | 854 | "-c", |
853 | tc_h->cfg_filename, | 855 | tc_h->cfg_filename, |
854 | NULL); | 856 | NULL); |
857 | GNUNET_free (loprefix); | ||
855 | if (NULL == tc_h->c_proc) | 858 | if (NULL == tc_h->c_proc) |
856 | { | 859 | { |
857 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to start communicator!"); | 860 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to start communicator!"); |
@@ -1093,6 +1096,7 @@ void | |||
1093 | GNUNET_TRANSPORT_TESTING_transport_communicator_service_stop ( | 1096 | GNUNET_TRANSPORT_TESTING_transport_communicator_service_stop ( |
1094 | struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h) | 1097 | struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h) |
1095 | { | 1098 | { |
1099 | struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorQueue *queue; | ||
1096 | shutdown_communicator (tc_h->c_proc); | 1100 | shutdown_communicator (tc_h->c_proc); |
1097 | shutdown_service (tc_h->sh); | 1101 | shutdown_service (tc_h->sh); |
1098 | shutdown_nat (tc_h->nat_proc); | 1102 | shutdown_nat (tc_h->nat_proc); |
@@ -1100,6 +1104,14 @@ GNUNET_TRANSPORT_TESTING_transport_communicator_service_stop ( | |||
1100 | shutdown_peerstore (tc_h->ps_proc); | 1104 | shutdown_peerstore (tc_h->ps_proc); |
1101 | shutdown_statistics (tc_h->stat_proc); | 1105 | shutdown_statistics (tc_h->stat_proc); |
1102 | GNUNET_CONFIGURATION_destroy (tc_h->cfg); | 1106 | GNUNET_CONFIGURATION_destroy (tc_h->cfg); |
1107 | while (NULL != (queue = tc_h->queue_head)) | ||
1108 | { | ||
1109 | GNUNET_CONTAINER_DLL_remove (tc_h->queue_head, tc_h->queue_tail, queue); | ||
1110 | GNUNET_free (queue); | ||
1111 | } | ||
1112 | GNUNET_free (tc_h->c_address); | ||
1113 | GNUNET_free (tc_h->cfg_filename); | ||
1114 | GNUNET_free (tc_h->c_addr_prefix); | ||
1103 | GNUNET_free (tc_h); | 1115 | GNUNET_free (tc_h); |
1104 | } | 1116 | } |
1105 | 1117 | ||
diff --git a/src/service/transport/transport-testing2.h b/src/service/transport/transport-testing2.h index a68c9df38..42ffce3f2 100644 --- a/src/service/transport/transport-testing2.h +++ b/src/service/transport/transport-testing2.h | |||
@@ -234,7 +234,7 @@ struct GNUNET_TRANSPORT_TESTING_Handle | |||
234 | /** | 234 | /** |
235 | * Testing library system handle | 235 | * Testing library system handle |
236 | */ | 236 | */ |
237 | struct GNUNET_TESTING_System *tl_system; | 237 | struct GNUNET_TESTBED_System *tl_system; |
238 | 238 | ||
239 | /** | 239 | /** |
240 | * head DLL of connect contexts | 240 | * head DLL of connect contexts |
diff --git a/src/service/transport/transport_api_cmd_backchannel_check.c b/src/service/transport/transport_api_cmd_backchannel_check.c index f23230798..6fa61adb7 100644 --- a/src/service/transport/transport_api_cmd_backchannel_check.c +++ b/src/service/transport/transport_api_cmd_backchannel_check.c | |||
@@ -67,7 +67,7 @@ struct CheckState | |||
67 | /** | 67 | /** |
68 | * The testing system of this node. | 68 | * The testing system of this node. |
69 | */ | 69 | */ |
70 | const struct GNUNET_TESTING_System *tl_system; | 70 | const struct GNUNET_TESTBED_System *tl_system; |
71 | 71 | ||
72 | // Label of the cmd which started the test system. | 72 | // Label of the cmd which started the test system. |
73 | const char *create_label; | 73 | const char *create_label; |
@@ -402,7 +402,7 @@ backchannel_check_run (void *cls, | |||
402 | { | 402 | { |
403 | struct CheckState *cs = cls; | 403 | struct CheckState *cs = cls; |
404 | const struct GNUNET_TESTING_Command *system_cmd; | 404 | const struct GNUNET_TESTING_Command *system_cmd; |
405 | const struct GNUNET_TESTING_System *tl_system; | 405 | const struct GNUNET_TESTBED_System *tl_system; |
406 | const struct GNUNET_TESTING_Command *peer1_cmd; | 406 | const struct GNUNET_TESTING_Command *peer1_cmd; |
407 | const struct GNUNET_TRANSPORT_ApplicationHandle *ah; | 407 | const struct GNUNET_TRANSPORT_ApplicationHandle *ah; |
408 | struct GNUNET_CONTAINER_MultiShortmapIterator *node_it; | 408 | struct GNUNET_CONTAINER_MultiShortmapIterator *node_it; |
@@ -467,7 +467,8 @@ backchannel_check_run (void *cls, | |||
467 | node_it = GNUNET_CONTAINER_multishortmap_iterator_create ( | 467 | node_it = GNUNET_CONTAINER_multishortmap_iterator_create ( |
468 | namespace->nodes); | 468 | namespace->nodes); |
469 | while (GNUNET_YES == GNUNET_CONTAINER_multishortmap_iterator_next (node_it, | 469 | while (GNUNET_YES == GNUNET_CONTAINER_multishortmap_iterator_next (node_it, |
470 | &node_key, | 470 | &node_key |
471 | , | ||
471 | (const | 472 | (const |
472 | void**) | 473 | void**) |
473 | &node)) | 474 | &node)) |
@@ -544,10 +545,10 @@ GNUNET_TRANSPORT_cmd_backchannel_check (const char *label, | |||
544 | cs->node_n = node_n; | 545 | cs->node_n = node_n; |
545 | cs->namespace_n = namespace_n; | 546 | cs->namespace_n = namespace_n; |
546 | 547 | ||
547 | return GNUNET_TESTING_command_new (cs, | 548 | return GNUNET_TESTING_command_new_ac (cs, |
548 | label, | 549 | label, |
549 | &backchannel_check_run, | 550 | &backchannel_check_run, |
550 | &backchannel_check_cleanup, | 551 | &backchannel_check_cleanup, |
551 | &backchannel_check_traits, | 552 | &backchannel_check_traits, |
552 | &cs->ac); | 553 | &cs->ac); |
553 | } | 554 | } |
diff --git a/src/service/transport/transport_api_cmd_connecting_peers.c b/src/service/transport/transport_api_cmd_connecting_peers.c index b7c072169..280c0e9a2 100644 --- a/src/service/transport/transport_api_cmd_connecting_peers.c +++ b/src/service/transport/transport_api_cmd_connecting_peers.c | |||
@@ -25,7 +25,8 @@ | |||
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_testing_ng_lib.h" | 28 | #include "gnunet_testing_lib.h" |
29 | #include "gnunet_testbed_lib.h" | ||
29 | #include "gnunet_transport_testing_ng_lib.h" | 30 | #include "gnunet_transport_testing_ng_lib.h" |
30 | #include "transport-testing-cmds.h" | 31 | #include "transport-testing-cmds.h" |
31 | #include "gnunet_transport_application_service.h" | 32 | #include "gnunet_transport_application_service.h" |
@@ -45,7 +46,7 @@ connect_peers_run (void *cls, | |||
45 | { | 46 | { |
46 | struct ConnectPeersState *cps = cls; | 47 | struct ConnectPeersState *cps = cls; |
47 | const struct GNUNET_TESTING_Command *system_cmd; | 48 | const struct GNUNET_TESTING_Command *system_cmd; |
48 | const struct GNUNET_TESTING_System *tl_system; | 49 | const struct GNUNET_TESTBED_System *tl_system; |
49 | 50 | ||
50 | 51 | ||
51 | const struct GNUNET_TESTING_Command *peer1_cmd; | 52 | const struct GNUNET_TESTING_Command *peer1_cmd; |
@@ -83,7 +84,7 @@ connect_peers_run (void *cls, | |||
83 | 84 | ||
84 | system_cmd = GNUNET_TESTING_interpreter_lookup_command (is, | 85 | system_cmd = GNUNET_TESTING_interpreter_lookup_command (is, |
85 | cps->create_label); | 86 | cps->create_label); |
86 | GNUNET_TESTING_get_trait_test_system (system_cmd, | 87 | GNUNET_TESTBED_get_trait_test_system (system_cmd, |
87 | &tl_system); | 88 | &tl_system); |
88 | 89 | ||
89 | cps->tl_system = tl_system; | 90 | cps->tl_system = tl_system; |
@@ -292,22 +293,23 @@ GNUNET_TRANSPORT_cmd_connect_peers (const char *label, | |||
292 | cps->additional_connects = additional_connects; | 293 | cps->additional_connects = additional_connects; |
293 | cps->wait_for_connect = wait_for_connect; | 294 | cps->wait_for_connect = wait_for_connect; |
294 | 295 | ||
296 | // FIXME: wrap with cmd_make_unblocking! | ||
295 | if (GNUNET_YES == wait_for_connect) | 297 | if (GNUNET_YES == wait_for_connect) |
296 | return GNUNET_TESTING_command_new (cps, | 298 | return GNUNET_TESTING_command_new_ac (cps, |
297 | label, | 299 | label, |
298 | &connect_peers_run, | 300 | &connect_peers_run, |
299 | &connect_peers_cleanup, | 301 | &connect_peers_cleanup, |
300 | &connect_peers_traits, | 302 | &connect_peers_traits, |
301 | &cps->ac); | 303 | &cps->ac); |
302 | else | 304 | else |
303 | return GNUNET_TESTING_command_new (cps, | 305 | return GNUNET_TESTING_command_new (cps, |
304 | label, | 306 | label, |
305 | &connect_peers_run, | 307 | &connect_peers_run, |
306 | &connect_peers_cleanup, | 308 | &connect_peers_cleanup, |
307 | &connect_peers_traits, | 309 | &connect_peers_traits); |
308 | NULL); | ||
309 | } | 310 | } |
310 | 311 | ||
311 | 312 | ||
312 | // FIXME: likely not ideally placed here, move to its own file | 313 | // FIXME: likely not ideally placed here, move to its own file |
313 | GNUNET_TRANSPORT_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, GNUNET_TRANSPORT_TESTING) | 314 | GNUNET_TRANSPORT_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, |
315 | GNUNET_TRANSPORT_TESTING) | ||
diff --git a/src/service/transport/transport_api_cmd_send_simple.c b/src/service/transport/transport_api_cmd_send_simple.c index 3e732ffc9..b0f443584 100644 --- a/src/service/transport/transport_api_cmd_send_simple.c +++ b/src/service/transport/transport_api_cmd_send_simple.c | |||
@@ -118,12 +118,12 @@ send_simple_run (void *cls, | |||
118 | const struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map; | 118 | const struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map; |
119 | const struct GNUNET_TESTING_Command *peer1_cmd; | 119 | const struct GNUNET_TESTING_Command *peer1_cmd; |
120 | const struct GNUNET_TESTING_Command *system_cmd; | 120 | const struct GNUNET_TESTING_Command *system_cmd; |
121 | const struct GNUNET_TESTING_System *tl_system; | 121 | const struct GNUNET_TESTBED_System *tl_system; |
122 | 122 | ||
123 | peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (is, | 123 | peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (is, |
124 | sss->start_peer_label); | 124 | sss->start_peer_label); |
125 | GNUNET_TRANSPORT_TESTING_get_trait_connected_peers_map (peer1_cmd, | 125 | GNUNET_TRANSPORT_TESTING_get_trait_connected_peers_map (peer1_cmd, |
126 | &connected_peers_map); | 126 | &connected_peers_map); |
127 | 127 | ||
128 | system_cmd = GNUNET_TESTING_interpreter_lookup_command (is, | 128 | system_cmd = GNUNET_TESTING_interpreter_lookup_command (is, |
129 | sss->create_label); | 129 | sss->create_label); |
@@ -157,6 +157,5 @@ GNUNET_TRANSPORT_cmd_send_simple (const char *label, | |||
157 | label, | 157 | label, |
158 | &send_simple_run, | 158 | &send_simple_run, |
159 | &send_simple_cleanup, | 159 | &send_simple_cleanup, |
160 | NULL, | ||
161 | NULL); | 160 | NULL); |
162 | } | 161 | } |
diff --git a/src/service/transport/transport_api_cmd_send_simple_performance.c b/src/service/transport/transport_api_cmd_send_simple_performance.c index 5979e47fe..a3012d9cd 100644 --- a/src/service/transport/transport_api_cmd_send_simple_performance.c +++ b/src/service/transport/transport_api_cmd_send_simple_performance.c | |||
@@ -168,7 +168,7 @@ send_simple_run (void *cls, | |||
168 | const struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map; | 168 | const struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map; |
169 | const struct GNUNET_TESTING_Command *peer1_cmd; | 169 | const struct GNUNET_TESTING_Command *peer1_cmd; |
170 | const struct GNUNET_TESTING_Command *system_cmd; | 170 | const struct GNUNET_TESTING_Command *system_cmd; |
171 | const struct GNUNET_TESTING_System *tl_system; | 171 | const struct GNUNET_TESTBED_System *tl_system; |
172 | 172 | ||
173 | 173 | ||
174 | peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (is, | 174 | peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (is, |
@@ -208,13 +208,12 @@ GNUNET_TRANSPORT_cmd_send_simple_performance (const char *label, | |||
208 | sss->topology = topology; | 208 | sss->topology = topology; |
209 | sss->size = size; | 209 | sss->size = size; |
210 | sss->max_send = max_send; | 210 | sss->max_send = max_send; |
211 | 211 | cmd = GNUNET_TESTING_command_new_ac (sss, | |
212 | cmd = GNUNET_TESTING_command_new (sss, | 212 | label, |
213 | label, | 213 | &send_simple_run, |
214 | &send_simple_run, | 214 | &send_simple_cleanup, |
215 | &send_simple_cleanup, | 215 | NULL, |
216 | NULL, | 216 | &sss->ac); |
217 | &sss->ac); | ||
218 | cmd.asynchronous_finish = GNUNET_YES; | 217 | cmd.asynchronous_finish = GNUNET_YES; |
219 | return cmd; | 218 | return cmd; |
220 | } | 219 | } |
diff --git a/src/service/transport/transport_api_cmd_start_peer.c b/src/service/transport/transport_api_cmd_start_peer.c index 5afbb338b..862d28b4c 100644 --- a/src/service/transport/transport_api_cmd_start_peer.c +++ b/src/service/transport/transport_api_cmd_start_peer.c | |||
@@ -84,11 +84,11 @@ retrieve_hello (void *cls) | |||
84 | struct GNUNET_TESTING_StartPeerState *sps = cls; | 84 | struct GNUNET_TESTING_StartPeerState *sps = cls; |
85 | sps->rh_task = NULL; | 85 | sps->rh_task = NULL; |
86 | sps->pic = GNUNET_PEERSTORE_iteration_start (sps->ph, | 86 | sps->pic = GNUNET_PEERSTORE_iteration_start (sps->ph, |
87 | "transport", | 87 | "transport", |
88 | &sps->id, | 88 | &sps->id, |
89 | GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY, | 89 | GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY, |
90 | hello_iter_cb, | 90 | hello_iter_cb, |
91 | sps); | 91 | sps); |
92 | 92 | ||
93 | } | 93 | } |
94 | 94 | ||
@@ -172,7 +172,7 @@ start_peer_run (void *cls, | |||
172 | char *emsg = NULL; | 172 | char *emsg = NULL; |
173 | struct GNUNET_PeerIdentity dummy; | 173 | struct GNUNET_PeerIdentity dummy; |
174 | const struct GNUNET_TESTING_Command *system_cmd; | 174 | const struct GNUNET_TESTING_Command *system_cmd; |
175 | const struct GNUNET_TESTING_System *tl_system; | 175 | const struct GNUNET_TESTBED_System *tl_system; |
176 | char *home; | 176 | char *home; |
177 | char *transport_unix_path; | 177 | char *transport_unix_path; |
178 | char *tcp_communicator_unix_path; | 178 | char *tcp_communicator_unix_path; |
@@ -258,7 +258,7 @@ start_peer_run (void *cls, | |||
258 | 258 | ||
259 | if (GNUNET_SYSERR == | 259 | if (GNUNET_SYSERR == |
260 | GNUNET_TESTING_configuration_create ((struct | 260 | GNUNET_TESTING_configuration_create ((struct |
261 | GNUNET_TESTING_System *) tl_system, | 261 | GNUNET_TESTBED_System *) tl_system, |
262 | sps->cfg)) | 262 | sps->cfg)) |
263 | { | 263 | { |
264 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 264 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -270,7 +270,7 @@ start_peer_run (void *cls, | |||
270 | } | 270 | } |
271 | 271 | ||
272 | sps->peer = GNUNET_TESTING_peer_configure ((struct | 272 | sps->peer = GNUNET_TESTING_peer_configure ((struct |
273 | GNUNET_TESTING_System *) sps-> | 273 | GNUNET_TESTBED_System *) sps-> |
274 | tl_system, | 274 | tl_system, |
275 | sps->cfg, | 275 | sps->cfg, |
276 | sps->no, | 276 | sps->no, |
@@ -475,10 +475,10 @@ GNUNET_TRANSPORT_cmd_start_peer (const char *label, | |||
475 | handlers, | 475 | handlers, |
476 | i * sizeof(struct GNUNET_MQ_MessageHandler)); | 476 | i * sizeof(struct GNUNET_MQ_MessageHandler)); |
477 | } | 477 | } |
478 | return GNUNET_TESTING_command_new (sps, | 478 | return GNUNET_TESTING_command_new_ac (sps, |
479 | label, | 479 | label, |
480 | &start_peer_run, | 480 | &start_peer_run, |
481 | &start_peer_cleanup, | 481 | &start_peer_cleanup, |
482 | &start_peer_traits, | 482 | &start_peer_traits, |
483 | &sps->ac); | 483 | &sps->ac); |
484 | } | 484 | } |
diff --git a/src/service/transport/transport_api_cmd_stop_peer.c b/src/service/transport/transport_api_cmd_stop_peer.c index fbd2b1df3..76a30d638 100644 --- a/src/service/transport/transport_api_cmd_stop_peer.c +++ b/src/service/transport/transport_api_cmd_stop_peer.c | |||
@@ -149,6 +149,5 @@ GNUNET_TRANSPORT_cmd_stop_peer (const char *label, | |||
149 | label, | 149 | label, |
150 | &stop_peer_run, | 150 | &stop_peer_run, |
151 | &stop_peer_cleanup, | 151 | &stop_peer_cleanup, |
152 | &stop_peer_traits, | 152 | &stop_peer_traits); |
153 | NULL); | ||
154 | } | 153 | } |