aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbootstrap5
-rw-r--r--configure.ac3
-rw-r--r--debian/changelog6
-rw-r--r--meson.build3
-rw-r--r--scripts/Makefile.am14
-rw-r--r--scripts/meson.build2
-rwxr-xr-xscripts/netjail/netjail_core.sh28
-rwxr-xr-xscripts/netjail/netjail_exec.sh15
-rwxr-xr-xscripts/netjail/netjail_start.sh7
-rwxr-xr-xscripts/netjail/netjail_stop.sh2
-rwxr-xr-xscripts/netjail/netjail_test_master.sh18
-rw-r--r--src/cli/core/gnunet-core.c3
-rw-r--r--src/cli/dht/gnunet-dht-put.c21
-rw-r--r--src/cli/messenger/gnunet-messenger.c5
-rw-r--r--src/cli/reclaim/gnunet-reclaim.c78
-rw-r--r--src/cli/reclaim/test_reclaim.conf12
-rwxr-xr-xsrc/cli/reclaim/test_reclaim_consume.sh6
-rwxr-xr-xsrc/cli/reclaim/test_reclaim_issue.sh2
-rwxr-xr-xsrc/cli/reclaim/test_reclaim_oidc.sh57
-rw-r--r--src/cli/util/gnunet-config.c248
-rw-r--r--src/cli/util/gnunet-ecc.c24
-rw-r--r--src/include/Makefile.am12
-rw-r--r--src/include/gnunet_arm_service.h82
-rw-r--r--src/include/gnunet_common.h485
-rw-r--r--src/include/gnunet_configuration_lib.h174
-rw-r--r--src/include/gnunet_crypto_lib.h9
-rw-r--r--src/include/gnunet_getopt_lib.h20
-rw-r--r--src/include/gnunet_gns_service.h10
-rw-r--r--src/include/gnunet_helper_lib.h2
-rw-r--r--src/include/gnunet_json_lib.h71
-rw-r--r--src/include/gnunet_messenger_service.h35
-rw-r--r--src/include/gnunet_mq_lib.h79
-rw-r--r--src/include/gnunet_pq_lib.h4
-rw-r--r--src/include/gnunet_reclaim_service.h77
-rw-r--r--src/include/gnunet_testbed_lib.h130
-rw-r--r--src/include/gnunet_testing_arm_lib.h47
-rw-r--r--src/include/gnunet_testing_barrier.h122
-rw-r--r--src/include/gnunet_testing_core_lib.h (renamed from src/include/gnunet_core_testing_lib.h)0
-rw-r--r--src/include/gnunet_testing_lib.h1120
-rw-r--r--src/include/gnunet_testing_loop_lib.h697
-rw-r--r--src/include/gnunet_testing_netjail_lib.h546
-rw-r--r--src/include/gnunet_testing_ng_lib.h115
-rw-r--r--src/include/gnunet_testing_plugin.h145
-rw-r--r--src/include/gnunet_testing_testbed_lib.h42
-rw-r--r--src/include/gnunet_testing_transport_lib.h (renamed from src/include/gnunet_transport_testing_ng_lib.h)34
-rw-r--r--src/include/gnunet_transport_application_service.h2
-rw-r--r--src/lib/Makefile.am9
-rw-r--r--src/lib/gnsrecord/test_gnsrecord_block_expiration.c3
-rw-r--r--src/lib/gnsrecord/test_gnsrecord_testvectors.c8
-rw-r--r--src/lib/json/json_helper.c428
-rw-r--r--src/lib/json/json_pack.c115
-rw-r--r--src/lib/meson.build1
-rw-r--r--src/lib/pq/pq_result_helper.c72
-rw-r--r--src/lib/testing/.gitignore (renamed from src/service/testing/.gitignore)2
-rw-r--r--src/lib/testing/Makefile.am92
-rw-r--r--src/lib/testing/gnunet-cmds-helper.c530
-rw-r--r--src/lib/testing/gnunet-testing-netjail-launcher.c87
-rw-r--r--src/lib/testing/meson.build (renamed from src/service/testing/meson.build)42
-rwxr-xr-xsrc/lib/testing/test_netjail_api.sh2
-rw-r--r--src/lib/testing/test_netjail_topo.conf658
-rw-r--r--src/lib/testing/test_testing_api.c130
-rw-r--r--src/lib/testing/test_testing_plugin_ping.c54
-rw-r--r--src/lib/testing/testing.conf (renamed from src/service/testing/testing.conf)0
-rw-r--r--src/lib/testing/testing_api_barrier.c51
-rw-r--r--src/lib/testing/testing_api_barrier.h81
-rw-r--r--src/lib/testing/testing_api_cmd_barrier_create.c106
-rw-r--r--src/lib/testing/testing_api_cmd_barrier_reached.c189
-rw-r--r--src/lib/testing/testing_api_cmd_batch.c (renamed from src/service/testing/testing_api_cmd_batch.c)63
-rw-r--r--src/lib/testing/testing_api_cmd_batch.h72
-rw-r--r--src/lib/testing/testing_api_cmd_exec.c254
-rw-r--r--src/lib/testing/testing_api_cmd_finish.c (renamed from src/service/testing/testing_api_cmd_finish.c)68
-rw-r--r--src/lib/testing/testing_api_cmd_get_topo.c214
-rw-r--r--src/lib/testing/testing_api_cmd_netjail_start.c (renamed from src/service/testing/testing_api_cmd_netjail_start.c)100
-rw-r--r--src/lib/testing/testing_api_cmd_netjail_start_cmds_helper.c586
-rw-r--r--src/lib/testing/testing_api_cmd_signal.c120
-rw-r--r--src/lib/testing/testing_api_cmd_stat.c161
-rw-r--r--src/lib/testing/testing_api_cmds.c92
-rw-r--r--src/lib/testing/testing_api_loop.c1012
-rw-r--r--src/lib/testing/testing_api_loop.h163
-rw-r--r--src/lib/testing/testing_api_main.c140
-rw-r--r--src/lib/testing/testing_api_topology.c1083
-rw-r--r--src/lib/testing/testing_api_topology.h367
-rw-r--r--src/lib/testing/testing_api_traits.c (renamed from src/service/testing/testing_api_traits.c)18
-rw-r--r--src/lib/testing/testing_cmds.h106
-rw-r--r--src/lib/util/.gitignore2
-rw-r--r--src/lib/util/Makefile.am2
-rw-r--r--src/lib/util/common_allocation.c261
-rw-r--r--src/lib/util/crypto_ecc.c21
-rw-r--r--src/lib/util/crypto_ecc_setup.c5
-rw-r--r--src/lib/util/crypto_pkey.c17
-rw-r--r--src/lib/util/crypto_symmetric.c2
-rw-r--r--src/lib/util/helper.c4
-rw-r--r--src/lib/util/service.c596
-rw-r--r--src/lib/util/strings.c30
-rw-r--r--src/lib/util/test_crypto_blind.c1
-rw-r--r--src/plugin/reclaim/plugin_gnsrecord_reclaim.c4
-rw-r--r--src/service/Makefile.am3
-rw-r--r--src/service/arm/Makefile.am23
-rw-r--r--src/service/arm/testing_arm_cmd_start_peer.c293
-rw-r--r--src/service/arm/testing_arm_cmd_stop_peer.c (renamed from src/service/transport/testing_api_cmd_stop_peer.c)79
-rw-r--r--src/service/cadet/gnunet-service-cadet_dht.c1
-rw-r--r--src/service/core/Makefile.am10
-rw-r--r--src/service/core/core_api_cmd_connecting_peers.c29
-rw-r--r--src/service/dht/gnunet-service-dht.c7
-rw-r--r--src/service/dht/meson.build6
-rw-r--r--src/service/gns/gns_tld_api.c32
-rw-r--r--src/service/hostlist/gnunet-daemon-hostlist_server.c2
-rw-r--r--src/service/meson.build1
-rw-r--r--src/service/messenger/Makefile.am8
-rw-r--r--src/service/messenger/gnunet-service-messenger.c19
-rw-r--r--src/service/messenger/gnunet-service-messenger_handle.c9
-rw-r--r--src/service/messenger/gnunet-service-messenger_list_messages.c6
-rw-r--r--src/service/messenger/gnunet-service-messenger_member_session.c18
-rw-r--r--src/service/messenger/gnunet-service-messenger_message_recv.c1
-rw-r--r--src/service/messenger/gnunet-service-messenger_message_send.c1
-rw-r--r--src/service/messenger/gnunet-service-messenger_message_store.c9
-rw-r--r--src/service/messenger/gnunet-service-messenger_peer_store.c6
-rw-r--r--src/service/messenger/gnunet-service-messenger_room.c5
-rw-r--r--src/service/messenger/gnunet-service-messenger_service.c5
-rw-r--r--src/service/messenger/messenger_api.c127
-rw-r--r--src/service/messenger/messenger_api_cmd_join_room.c1
-rw-r--r--src/service/messenger/messenger_api_cmd_start_service.c6
-rw-r--r--src/service/messenger/messenger_api_cmd_stop_service.c1
-rw-r--r--src/service/messenger/messenger_api_contact_store.c2
-rw-r--r--src/service/messenger/messenger_api_list_tunnels.c6
-rw-r--r--src/service/messenger/messenger_api_message.c72
-rw-r--r--src/service/messenger/messenger_api_message_control.c2
-rw-r--r--src/service/messenger/messenger_api_message_kind.c13
-rw-r--r--src/service/messenger/messenger_api_message_kind.h5
-rw-r--r--src/service/messenger/messenger_api_queue_messages.c4
-rw-r--r--src/service/messenger/messenger_api_room.c9
-rw-r--r--src/service/messenger/test_messenger.c1
-rw-r--r--src/service/namestore/gnunet-service-namestore.c9
-rw-r--r--src/service/nat/gnunet-service-nat.c122
-rw-r--r--src/service/nat/nat_api.c25
-rw-r--r--src/service/peerstore/gnunet-service-peerstore.c25
-rw-r--r--src/service/peerstore/peerstore_api.c39
-rw-r--r--src/service/peerstore/peerstore_api_monitor.c29
-rw-r--r--src/service/peerstore/peerstore_common.c1
-rw-r--r--src/service/reclaim/gnunet-service-reclaim.c123
-rw-r--r--src/service/reclaim/gnunet-service-reclaim_tickets.c262
-rw-r--r--src/service/reclaim/gnunet-service-reclaim_tickets.h14
-rw-r--r--src/service/reclaim/reclaim.h26
-rw-r--r--src/service/reclaim/reclaim_api.c179
-rw-r--r--src/service/rest/json_reclaim.c55
-rw-r--r--src/service/rest/oidc_helper.c93
-rw-r--r--src/service/rest/oidc_helper.h25
-rw-r--r--src/service/rest/openid_plugin.c85
-rw-r--r--src/service/rest/reclaim_plugin.c63
-rw-r--r--src/service/setu/gnunet-service-setu_strata_estimator.c8
-rw-r--r--src/service/testbed/.gitignore1
-rw-r--r--src/service/testbed/Makefile.am53
-rw-r--r--src/service/testbed/gnunet-testbed.c223
-rw-r--r--src/service/testbed/test_testbed_portreservation.c (renamed from src/service/testing/test_testing_portreservation.c)30
-rw-r--r--src/service/testbed/testbed.c579
-rw-r--r--src/service/testbed/testbed_api_cmd_system_create.c (renamed from src/service/testing/testing_api_cmd_system_create.c)31
-rw-r--r--src/service/testbed/testing_testbed_traits.c (renamed from src/service/transport/transport_api_traits.c)10
-rw-r--r--src/service/testing/Makefile.am134
-rw-r--r--src/service/testing/gnunet-cmds-helper.c713
-rw-r--r--src/service/testing/gnunet-testing.c444
-rw-r--r--src/service/testing/list-keys.c112
-rw-r--r--src/service/testing/test_testing_defaults.conf25
-rw-r--r--src/service/testing/test_testing_peerstartup.c143
-rw-r--r--src/service/testing/test_testing_peerstartup2.c222
-rw-r--r--src/service/testing/test_testing_servicestartup.c75
-rw-r--r--src/service/testing/test_testing_sharedservices.c167
-rw-r--r--src/service/testing/test_testing_sharedservices.conf30
-rw-r--r--src/service/testing/test_testing_start_with_config.c121
-rw-r--r--src/service/testing/testing.c2830
-rw-r--r--src/service/testing/testing.h339
-rw-r--r--src/service/testing/testing_api_cmd_barrier.c206
-rw-r--r--src/service/testing/testing_api_cmd_barrier_reached.c229
-rw-r--r--src/service/testing/testing_api_cmd_block_until_external_trigger.c119
-rw-r--r--src/service/testing/testing_api_cmd_exec_bash_script.c216
-rw-r--r--src/service/testing/testing_api_cmd_local_test_prepared.c112
-rw-r--r--src/service/testing/testing_api_cmd_netjail_start_cmds_helper.c917
-rw-r--r--src/service/testing/testing_api_cmd_netjail_stop.c200
-rw-r--r--src/service/testing/testing_api_cmd_netjail_stop_cmds_helper.c157
-rw-r--r--src/service/testing/testing_api_cmd_send_peer_ready.c123
-rw-r--r--src/service/testing/testing_api_cmd_system_destroy.c111
-rw-r--r--src/service/testing/testing_api_loop.c893
-rw-r--r--src/service/testing/testing_cmds.h143
-rwxr-xr-xsrc/service/testing/topo.sh99
-rw-r--r--src/service/topology/gnunet-daemon-topology.c1
-rw-r--r--src/service/transport/Makefile.am88
-rw-r--r--src/service/transport/gnunet-communicator-tcp.c10
-rw-r--r--src/service/transport/gnunet-communicator-udp.c19
-rw-r--r--src/service/transport/gnunet-service-transport.c69
-rw-r--r--src/service/transport/test_transport_plugin_cmd_simple_send_performance.c4
-rw-r--r--src/service/transport/test_transport_plugin_cmd_udp_backchannel.c85
-rwxr-xr-xsrc/service/transport/test_transport_simple_send.sh13
-rw-r--r--src/service/transport/test_transport_start_with_config.c3
-rw-r--r--src/service/transport/testing_api_cmd_start_peer.c296
-rw-r--r--src/service/transport/testing_api_traits.c35
-rw-r--r--src/service/transport/transport-testing-cmds.h40
-rw-r--r--src/service/transport/transport-testing-communicator.c12
-rw-r--r--src/service/transport/transport-testing2.h2
-rw-r--r--src/service/transport/transport_api_cmd_backchannel_check.c19
-rw-r--r--src/service/transport/transport_api_cmd_connecting_peers.c26
-rw-r--r--src/service/transport/transport_api_cmd_send_simple.c5
-rw-r--r--src/service/transport/transport_api_cmd_send_simple_performance.c15
-rw-r--r--src/service/transport/transport_api_cmd_start_peer.c28
-rw-r--r--src/service/transport/transport_api_cmd_stop_peer.c3
203 files changed, 11740 insertions, 13688 deletions
diff --git a/bootstrap b/bootstrap
index d5bf30af4..fb47649a7 100755
--- a/bootstrap
+++ b/bootstrap
@@ -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
142main "$@" 145main "$@"
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
1235src/lib/json/Makefile 1235src/lib/json/Makefile
1236src/lib/pq/Makefile 1236src/lib/pq/Makefile
1237src/lib/sq/Makefile 1237src/lib/sq/Makefile
1238src/lib/testing/Makefile
1238src/plugin/Makefile 1239src/plugin/Makefile
1239src/plugin/block/Makefile 1240src/plugin/block/Makefile
1240src/plugin/datacache/Makefile 1241src/plugin/datacache/Makefile
@@ -1303,7 +1304,7 @@ src/service/setu/Makefile
1303src/service/setu/setu.conf 1304src/service/setu/setu.conf
1304src/service/statistics/Makefile 1305src/service/statistics/Makefile
1305src/service/statistics/statistics.conf 1306src/service/statistics/statistics.conf
1306src/service/testing/Makefile 1307src/service/testbed/Makefile
1307src/service/topology/Makefile 1308src/service/topology/Makefile
1308src/service/transport/Makefile 1309src/service/transport/Makefile
1309src/service/transport/transport.conf 1310src/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 @@
1gnunet (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
1gnunet (0.21.1-1) unstable; urgency=low 7gnunet (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
431if cc.has_function('explicit_bzero') 431if cc.has_function('explicit_bzero')
432 cdata.set('HAVE_EXPLICIT_BZERO', 1) 432 cdata.set('HAVE_EXPLICIT_BZERO', 1)
433endif 433endif
434if cc.has_function('getaddrinfo')
435 cdata.set('HAVE_GETADDRINFO', 1)
436endif
434if cc.has_function('gethostbyname') 437if cc.has_function('gethostbyname')
435 cdata.set('HAVE_GETHOSTBYNAME', 1) 438 cdata.set('HAVE_GETHOSTBYNAME', 1)
436endif 439endif
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
4dist_pkgdata_DATA = \ 4dist_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
22install-data-hook: 22install-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 @@
1install_data([ 1install_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)
27endforeach 26endforeach
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
218netjail_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
226netjail_node_exec_without_fds_and_sudo() {
227 NODE=$1
228 shift 1
229
230 ip netns exec $NODE $@
231}
232
233netjail_kill() { 218netjail_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
4set -eu
5set -x
6
7export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
8
9M=$1
10N=$2
11
12NODE=$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
15netjail_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
8export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 8export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
9 9
10filename=$1 10filename=$1
11PREFIX=$2 11PREFIX=$PPID
12readfile=$3 12readfile=$2
13 13
14BROADCAST=0 14BROADCAST=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
16if [ $readfile -eq 0 ] 19if [ $readfile -eq 0 ]
17then 20then
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
8export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 8export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
9 9
10filename=$1 10filename=$1
11PREFIX=$2 11PREFIX=$PPID
12readfile=$3 12readfile=$3
13 13
14if [ $readfile -eq 0 ] 14if [ $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
2if ! [ -d "/run/netns" ];
3then
4 echo "You have to create the directory '/run/netns'."
5 exit 77
6fi
7if [ -f /proc/sys/kernel/unprivileged_userns_clone ];
8then
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
14else
15 echo -e "Error during test setup: The kernel lacks the parameter 'kernel.unprivileged_userns_clone'\n"
16 exit 77
17fi
18exec 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
32const struct GNUNET_CONFIGURATION_Handle *config; 33const struct GNUNET_CONFIGURATION_Handle *config;
33struct GNUNET_MESSENGER_Handle *messenger; 34struct 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;
53static char *credential_id; 53static char *credential_id;
54 54
55/** 55/**
56 * The expected RP URI
57 */
58static char *ex_rp_uri;
59
60/**
56 * Credential ID 61 * Credential ID
57 */ 62 */
58static struct GNUNET_RECLAIM_Identifier credential; 63static struct GNUNET_RECLAIM_Identifier credential;
@@ -155,11 +160,6 @@ static struct GNUNET_RECLAIM_TicketIterator *ticket_iterator;
155static const struct GNUNET_CRYPTO_PrivateKey *pkey; 160static const struct GNUNET_CRYPTO_PrivateKey *pkey;
156 161
157/** 162/**
158 * rp public key
159 */
160static struct GNUNET_CRYPTO_PublicKey rp_key;
161
162/**
163 * Ticket to consume 163 * Ticket to consume
164 */ 164 */
165static struct GNUNET_RECLAIM_Ticket ticket; 165static 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
342static void 335static void
343ticket_iter (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) 336ticket_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]
10START_ON_DEMAND = YES 10START_ON_DEMAND = YES
11PREFIX = 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
12BASIC_AUTH_ENABLED = NO
12 13
13[transport] 14[transport]
14PLUGINS = 15PLUGINS =
@@ -18,6 +19,7 @@ START_ON_DEMAND = YES
18IMMEDIATE_START = YES 19IMMEDIATE_START = YES
19 20
20[reclaim] 21[reclaim]
22IMMEDIATE_START = YES
21START_ON_DEMAND = YES 23START_ON_DEMAND = YES
22TICKET_REFRESH_INTERVAL = 1 h 24TICKET_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
33DNS_ROOT=PD67SGHF3E0447TU9HADIVU9OM7V4QHTOG0EBU69TFRI2LG63DR0 35DNS_ROOT=PD67SGHF3E0447TU9HADIVU9OM7V4QHTOG0EBU69TFRI2LG63DR0
34 36
35[reclaim-rest-plugin] 37[reclaim-rest-plugin]
36address = http://localhost:8000/#/login
37psw = mysupersecretpassword
38expiration_time = 3600 38expiration_time = 3600
39JWT_SECRET = secret
40OIDC_USERINFO_CONSUME_TIMEOUT = 5s
41OIDC_DIR = $GNUNET_DATA_HOME/oidc
42OIDC_CLIENT_HMAC_SECRET = secret
43OIDC_JSON_WEB_ALGORITHM = RS256
44ADDRESS = 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)
32TEST_KEY=$(gnunet-identity -d -e testego -q -c test_reclaim.conf) 32TEST_KEY=$(gnunet-identity -d -e testego -q -c test_reclaim.conf)
33gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf 33gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf
34gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf 34gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf
35TICKET=$(gnunet-reclaim -e testego -i "email,name" -r $SUBJECT_KEY -c test_reclaim.conf | awk '{print $1}') 35TICKET=$(gnunet-reclaim -e testego -U "urn:gns:$TEST_KEY" -i "email,name" -r $SUBJECT_KEY -c test_reclaim.conf | awk '{print $1}')
36echo "Ticket: $TICKET"
37gnunet-gns -u $TICKET -c test_reclaim.conf
36gnunet-namestore -z testego -D -c test_reclaim.conf 38gnunet-namestore -z testego -D -c test_reclaim.conf
37gnunet-identity -d -c test_reclaim.conf 39gnunet-identity -d -c test_reclaim.conf
38sleep 1 40sleep 1
39gnunet-reclaim -e rpego -C $TICKET -c test_reclaim.conf 41gnunet-reclaim -e rpego -U "urn:gns:$TEST_KEY" -C $TICKET -c test_reclaim.conf
40 42
41RES=$? 43RES=$?
42gnunet-identity -D testego -c test_reclaim.conf 44gnunet-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)
32gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf 32gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf
33gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf 33gnunet-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
35gnunet-reclaim -e testego -i "email,name" -r $SUBJECT_KEY -c test_reclaim.conf > /dev/null 2>&1 35gnunet-reclaim -e testego -u "urn:gns:$TEST_KEY" -i "email,name" -r $SUBJECT_KEY -c test_reclaim.conf > /dev/null 2>&1
36if test $? != 0 36if test $? != 0
37then 37then
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
2trap "gnunet-arm -e -c test_reclaim.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1>/dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_reclaim.conf -s PATHS -o GNUNET_HOME -f`
17
18which timeout >/dev/null 2>&1 && DO_TIMEOUT="timeout 30"
19
20RES=0
21TEST_ATTR="test"
22REDIRECT_URI="https://example.gns.alt/my_cb"
23SCOPE="\"openid email name\""
24gnunet-arm -s -c test_reclaim.conf
25gnunet-arm -i rest -c test_reclaim.conf
26gnunet-arm -I
27gnunet-identity -C testego -c test_reclaim.conf
28gnunet-identity -C rpego -c test_reclaim.conf
29TEST_KEY=$(gnunet-identity -d -e rpego -q -c test_reclaim.conf)
30SUBJECT_KEY=$(gnunet-identity -d -e testego -q -c test_reclaim.conf)
31gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf
32gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf
33
34# Register client
35gnunet-namestore -z rpego -a -n @ -t RECLAIM_OIDC_CLIENT -V "My RP" -e 1d -p -c test_reclaim.conf
36gnunet-namestore -z rpego -a -n @ -t RECLAIM_OIDC_REDIRECT -V $REDIRECT_URI -e 1d -p -c test_reclaim.conf
37
38gnunet-gns -u @.$TEST_KEY -t RECLAIM_OIDC_REDIRECT -c test_reclaim.conf
39curl -v -X POST -H -v "http://localhost:7776/openid/login" --data "{\"identity\": \"$SUBJECT_KEY\"}"
40
41PKCE_CHALLENGE=$(echo -n secret | openssl dgst -binary -sha256 | openssl base64 | sed 's/\=//g' | sed 's/+/-/g' | sed 's/\//_/g')
42
43CODE=$(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
46echo "Code: $CODE"
47
48curl -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
50gnunet-identity -D testego -c test_reclaim.conf
51gnunet-identity -D rpego -c test_reclaim.conf
52gnunet-arm -e -c test_reclaim.conf
53if test $RES != 0
54then
55 echo "Failed."
56fi
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 */
36static char *backend_check; 36static 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 */
47static int is_experimental; 46static int is_experimental;
48 47
48/**
49 * Do not load default configuration
50 */
51static int no_defaults;
52
53/**
54 * Parse configuration from this memory.
55 */
56static 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 */
53static int libs; 61static 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 */
74static void
75run (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 */
246typedef void 246typedef 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 */
261typedef void 262typedef 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 */
278typedef void 280typedef 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 */
296struct GNUNET_ARM_Handle * 299struct GNUNET_ARM_Handle *
297GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, 300GNUNET_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 */
307void 311void
308GNUNET_ARM_disconnect (struct GNUNET_ARM_Handle *h); 312GNUNET_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 */
317void 322void
318GNUNET_ARM_operation_cancel (struct GNUNET_ARM_Operation *op); 323GNUNET_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 */
329struct GNUNET_ARM_Operation * 335struct GNUNET_ARM_Operation *
330GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h, 336GNUNET_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 */
349struct GNUNET_ARM_Operation * 356struct GNUNET_ARM_Operation *
350GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h, 357GNUNET_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 */
366struct GNUNET_ARM_Operation * 374struct GNUNET_ARM_Operation *
367GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, 375GNUNET_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 */
388typedef void 396typedef 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 */
406struct GNUNET_ARM_MonitorHandle * 414struct GNUNET_ARM_MonitorHandle *
407GNUNET_ARM_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 415GNUNET_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 */
417void 426void
418GNUNET_ARM_monitor_stop (struct GNUNET_ARM_MonitorHandle *h); 427GNUNET_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 */
491void 495void
492GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message, ...) 496GNUNET_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 */
643const char * 650const char *
644GNUNET_b2s (const void *buf, 651GNUNET_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 */
678enum GNUNET_GenericReturnValue 685enum GNUNET_GenericReturnValue
679GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile); 686GNUNET_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 */
692void 701void
693GNUNET_logger_add (GNUNET_Logger logger, void *logger_cls); 702GNUNET_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 */
703void 713void
704GNUNET_logger_remove (GNUNET_Logger logger, void *logger_cls); 714GNUNET_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 */
1263enum GNUNET_GenericReturnValue 1283bool
1264GNUNET_is_zero_ (const void *a, 1284GNUNET_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 */
1581void * 1605void *
1582GNUNET_xmalloc_ (size_t size, const char *filename, int linenumber); 1606GNUNET_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 */
1661void * 1687void *
1662GNUNET_xmalloc_unchecked_ (size_t size, const char *filename, int linenumber); 1688GNUNET_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 */
1669void * 1697void *
1670GNUNET_xrealloc_ (void *ptr, size_t n, const char *filename, int linenumber); 1698GNUNET_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 */
1682void 1713void
1683GNUNET_xfree_ (void *ptr, const char *filename, int linenumber); 1714GNUNET_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 */
1693char * 1726char *
1694GNUNET_xstrdup_ (const char *str, const char *filename, int linenumber); 1727GNUNET_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 */
68struct GNUNET_CONFIGURATION_Handle * 68struct GNUNET_CONFIGURATION_Handle *
69GNUNET_CONFIGURATION_dup (const struct GNUNET_CONFIGURATION_Handle *cfg); 69GNUNET_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 */
77void 78void
78GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg); 79GNUNET_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 */
90enum GNUNET_GenericReturnValue 92enum GNUNET_GenericReturnValue
91GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg, 93GNUNET_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 */
103enum GNUNET_GenericReturnValue 106enum GNUNET_GenericReturnValue
104GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg, 107GNUNET_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 */
140enum GNUNET_GenericReturnValue 144enum GNUNET_GenericReturnValue
141GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, 145GNUNET_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 */
153char * 158char *
154GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg, 159GNUNET_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 *
168GNUNET_CONFIGURATION_serialize_diagnostics ( 174GNUNET_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 */
181enum GNUNET_GenericReturnValue 188enum GNUNET_GenericReturnValue
182GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, 189GNUNET_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 */
195enum GNUNET_GenericReturnValue 203enum GNUNET_GenericReturnValue
196GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg, 204GNUNET_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 */
235enum GNUNET_GenericReturnValue 244enum GNUNET_GenericReturnValue
236GNUNET_CONFIGURATION_is_dirty (const struct GNUNET_CONFIGURATION_Handle *cfg); 245GNUNET_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 */
246typedef enum GNUNET_GenericReturnValue 256typedef 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 */
262enum GNUNET_GenericReturnValue 273enum GNUNET_GenericReturnValue
263GNUNET_CONFIGURATION_parse_and_run (const char *filename, 274GNUNET_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 */
311void 323void
312GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, 324GNUNET_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 */
337void 350void
338GNUNET_CONFIGURATION_remove_section (struct GNUNET_CONFIGURATION_Handle *cfg, 351GNUNET_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 */
598void 612void
599GNUNET_CONFIGURATION_set_value_string (struct GNUNET_CONFIGURATION_Handle *cfg, 613GNUNET_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);
1736void 1736void
1737GNUNET_CRYPTO_ecdhe_key_clear (struct GNUNET_CRYPTO_EcdhePrivateKey *pk); 1737GNUNET_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 */
1745void
1746GNUNET_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,
227void * 227void *
228GNUNET_GNS_lookup_with_tld_cancel (struct GNUNET_GNS_LookupWithTldRequest *ltr); 228GNUNET_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 */
237enum GNUNET_GenericReturnValue
238GNUNET_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;
173struct GNUNET_HELPER_SendHandle * 173struct GNUNET_HELPER_SendHandle *
174GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, 174GNUNET_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 */
439struct GNUNET_JSON_Specification
440GNUNET_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 */
450struct GNUNET_JSON_Specification
451GNUNET_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 */
461struct GNUNET_JSON_Specification
462GNUNET_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 */
1010struct GNUNET_JSON_PackSpec
1011GNUNET_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 */
1023struct GNUNET_JSON_PackSpec
1024GNUNET_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 */
1036struct GNUNET_JSON_PackSpec
1037GNUNET_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
97GNUNET_NETWORK_STRUCT_END 90GNUNET_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 */
541struct GNUNET_MESSENGER_MessageTicket 534struct 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 */
1025void
1026GNUNET_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 */
333typedef int 334typedef 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 (
1136struct GNUNET_PQ_ResultSpec 1136struct GNUNET_PQ_ResultSpec
1137GNUNET_PQ_result_spec_blind_sign_pub ( 1137GNUNET_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 (
1149struct GNUNET_PQ_ResultSpec 1149struct GNUNET_PQ_ResultSpec
1150GNUNET_PQ_result_spec_blind_sign_priv ( 1150GNUNET_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 */
63struct GNUNET_RECLAIM_Operation; 63struct 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;
72struct GNUNET_RECLAIM_Ticket 75struct 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 */
99typedef void (*GNUNET_RECLAIM_TicketCallback) ( 114typedef 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 *
386GNUNET_RECLAIM_ticket_issue ( 402GNUNET_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 (
427struct GNUNET_RECLAIM_Operation * 442struct GNUNET_RECLAIM_Operation *
428GNUNET_RECLAIM_ticket_consume ( 443GNUNET_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);
499void 514void
500GNUNET_RECLAIM_cancel (struct GNUNET_RECLAIM_Operation *op); 515GNUNET_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 */
508size_t
509GNUNET_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 */
520enum GNUNET_GenericReturnValue
521GNUNET_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 */
534ssize_t
535GNUNET_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 */
7struct 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 */
30struct GNUNET_TESTBED_System *
31GNUNET_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 */
59struct GNUNET_TESTBED_System *
60GNUNET_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 */
73void
74GNUNET_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 */
85uint16_t
86GNUNET_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 */
97void
98GNUNET_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 */
122enum GNUNET_GenericReturnValue
123GNUNET_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 */
14struct GNUNET_TESTING_Command
15GNUNET_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 */
28struct GNUNET_TESTING_Command
29GNUNET_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
43GNUNET_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
33struct 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 */
42struct 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 */
63struct 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 */
90struct GNUNET_TESTING_Command
91GNUNET_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 */
112struct GNUNET_TESTING_Command
113GNUNET_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 */
75struct GNUNET_TESTING_Interpreter;
76
77/**
78 * State each asynchronous command must have in its closure.
79 */
80struct 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 119void
36 * management or distributed testbed maintenance (those are provided by the 120GNUNET_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 */
129void
130GNUNET_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 */
145typedef 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 */
157typedef 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/**
53extern "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 */
171typedef 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 \ 189struct GNUNET_TESTING_Command
64 GNUNET_CRYPTO_EddsaPrivateKey) 190GNUNET_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 */
77struct GNUNET_TESTING_System; 216struct 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 */
83struct GNUNET_TESTING_Peer; 229void
230GNUNET_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 */
89struct GNUNET_TESTING_SharedService 238struct 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 350const struct GNUNET_TESTING_Command *
117 * overridden with the value of the environmental variable 351GNUNET_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 */
129struct GNUNET_TESTING_System * 363const struct GNUNET_TESTING_Command *
130GNUNET_TESTING_system_create (const char *testdir, 364GNUNET_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 */
161struct GNUNET_TESTING_System *
162GNUNET_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 */
179void 376void
180GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system, 377GNUNET_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 */
387void
388GNUNET_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 */
201struct GNUNET_CRYPTO_EddsaPrivateKey * 398const char *
202GNUNET_TESTING_hostkey_get (const struct GNUNET_TESTING_System *system, 399GNUNET_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 */
213uint16_t 408void
214GNUNET_TESTING_reserve_port (struct GNUNET_TESTING_System *system); 409GNUNET_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 */
224void 419void
225GNUNET_TESTING_release_port (struct GNUNET_TESTING_System *system, 420GNUNET_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 */
430typedef 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 */
246int 445void
247GNUNET_TESTING_configuration_create (struct GNUNET_TESTING_System *system, 446GNUNET_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 */
266struct GNUNET_TESTING_Peer * 461struct GNUNET_TESTING_Command
267GNUNET_TESTING_peer_configure (struct GNUNET_TESTING_System *system, 462GNUNET_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 */
280void 475struct GNUNET_TESTING_Command
281GNUNET_TESTING_peer_get_identity (struct GNUNET_TESTING_Peer *peer, 476GNUNET_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 */
484struct 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 */
292int 520struct GNUNET_TESTING_Command
293GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer); 521GNUNET_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 */
305int 534struct GNUNET_TESTING_Command
306GNUNET_TESTING_peer_stop (struct GNUNET_TESTING_Peer *peer); 535GNUNET_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 */
316void 548struct GNUNET_TESTING_Command
317GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer); 549GNUNET_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 */
327int 562struct GNUNET_TESTING_Command
328GNUNET_TESTING_peer_kill (struct GNUNET_TESTING_Peer *peer); 563GNUNET_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 */
338int 580struct GNUNET_TESTING_Command
339GNUNET_TESTING_peer_wait (struct GNUNET_TESTING_Peer *peer); 581GNUNET_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 */
350typedef void 596struct GNUNET_TESTING_Command
351(*GNUNET_TESTING_PeerStopCallback) (void *cls, 597GNUNET_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
603struct GNUNET_TESTING_Command
604GNUNET_TESTING_cmd_load_topology_from_file (
605 const char *label,
606 const char *filename);
607
608
609struct GNUNET_TESTING_Command
610GNUNET_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 */
367int 627struct GNUNET_TESTING_Command
368GNUNET_TESTING_peer_stop_async (struct GNUNET_TESTING_Peer *peer, 628GNUNET_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 */
382void 643const struct GNUNET_TESTING_Command
383GNUNET_TESTING_peer_stop_async_cancel (struct GNUNET_TESTING_Peer *peer); 644GNUNET_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 */
658struct GNUNET_TESTING_Command
659GNUNET_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 */
672struct GNUNET_TESTING_Command
673GNUNET_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*/
683const struct GNUNET_TESTING_Command
684GNUNET_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*/
696const struct GNUNET_TESTING_Command
697GNUNET_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 */
717struct GNUNET_TESTING_Command
718GNUNET_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 */
394typedef void 732typedef 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 */
416int 749struct GNUNET_TESTING_Interpreter *
417GNUNET_TESTING_peer_run (const char *testdir, 750GNUNET_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 */
444int 765int
445GNUNET_TESTING_service_run (const char *testdir, 766GNUNET_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 */
777struct GNUNET_TESTING_PluginFunctions;
778
779
780struct GNUNET_TESTING_PluginFunctions *
781GNUNET_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 */
813struct 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 */
839struct GNUNET_TESTING_Trait
840GNUNET_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 */
852enum GNUNET_GenericReturnValue
853GNUNET_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
973GNUNET_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 */
56struct GNUNET_TESTING_Interpreter;
57
58/**
59 * State each asynchronous command must have in its closure.
60 */
61struct 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 */
93void
94GNUNET_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 */
102void
103GNUNET_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 */
113typedef 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 */
124typedef 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 */
138typedef 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 */
155struct GNUNET_TESTING_Command
156GNUNET_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 */
167struct 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 */
180void
181GNUNET_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 */
188struct 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.
305const struct GNUNET_TESTING_Command *
306GNUNET_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 */
318const struct GNUNET_TESTING_Command *
319GNUNET_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 */
333const struct GNUNET_TESTING_Command *
334GNUNET_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 */
344void
345GNUNET_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 */
360struct GNUNET_TESTING_Command
361GNUNET_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 */
375const struct GNUNET_TESTING_Command
376GNUNET_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 */
390struct GNUNET_TESTING_Command
391GNUNET_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 */
404typedef 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 */
421struct GNUNET_TESTING_Interpreter *
422GNUNET_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 */
438int
439GNUNET_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 */
452struct GNUNET_TESTING_Command
453GNUNET_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 */
466struct GNUNET_TESTING_Command
467GNUNET_TESTING_cmd_batch (const char *label,
468 struct GNUNET_TESTING_Command *batch);
469
470
471/**
472 * Performance counter.
473 */
474struct 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 */
509struct GNUNET_TESTING_Command
510GNUNET_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 */
524struct 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 */
550struct GNUNET_TESTING_Trait
551GNUNET_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 */
563enum GNUNET_GenericReturnValue
564GNUNET_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
682GNUNET_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
694GNUNET_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 */
37struct 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 */
54enum 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 */
70struct 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 */
92struct GNUNET_TESTING_NetjailNode;
93
94/**
95 * Connection to another node.
96 */
97struct 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 */
144struct 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 */
196struct 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 */
217struct 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 */
262struct GNUNET_TESTING_NetjailTopology *
263GNUNET_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 */
273struct GNUNET_TESTING_NetjailTopology *
274GNUNET_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 */
283unsigned int
284GNUNET_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 */
295struct GNUNET_TESTING_NetjailNode *
296GNUNET_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 */
307struct GNUNET_TESTING_NodeConnection *
308GNUNET_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 */
319char *
320GNUNET_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 */
329void
330GNUNET_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 */
340unsigned int
341GNUNET_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 */
350struct 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 */
372struct 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 */
394struct GNUNET_TESTING_Command
395GNUNET_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 */
405struct GNUNET_TESTING_Command
406GNUNET_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 */
418struct GNUNET_TESTING_Command
419GNUNET_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 */
432struct GNUNET_TESTING_Command
433GNUNET_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 */
449struct GNUNET_TESTING_Command
450GNUNET_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 */
466struct GNUNET_TESTING_Command
467GNUNET_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 */
480struct GNUNET_TESTING_Command
481GNUNET_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 */
492struct GNUNET_TESTING_Command
493GNUNET_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 */
504struct GNUNET_TESTING_Command
505GNUNET_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 */
521struct GNUNET_TESTING_Command
522GNUNET_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
543GNUNET_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 */
49struct GNUNET_TESTING_Command
50GNUNET_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 */
62struct GNUNET_TESTING_Command
63GNUNET_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*/
76const struct GNUNET_TESTING_Command
77GNUNET_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
96GNUNET_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
112GNUNET_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
34extern "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 */
48typedef 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 */
55typedef 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 */
77typedef 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 */
97typedef 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 */
108typedef 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 */
119typedef 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 */
126struct 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 */
15struct GNUNET_TESTING_Command
16GNUNET_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 */
26struct GNUNET_TESTING_Command
27GNUNET_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
38GNUNET_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 */
35struct GNUNET_TRANSPORT_ApplicationHandle; 35struct GNUNET_TRANSPORT_ApplicationHandle;
36 36
37/**
38 * FIXME: what is this?
39 */
40struct GNUNET_TESTING_StartPeerState;
41
42 37
43// FIXME: breaks naming conventions 38// FIXME: breaks naming conventions
44typedef void * 39typedef 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?
51struct GNUNET_TESTING_StartPeerState 45struct 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)
209GNUNET_TRANSPORT_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT, GNUNET_TRANSPORT_TESTING) 200
201
202GNUNET_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
5SUBDIRS = \ 5SUBDIRS = \
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
31struct GNUNET_JSON_Specification 32struct 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 */
51static enum GNUNET_CRYPTO_BlindSignatureAlgorithm
52string_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 */
1215static enum GNUNET_GenericReturnValue
1216parse_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 */
1313static void
1314clean_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
1328struct GNUNET_JSON_Specification
1329GNUNET_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 */
1355static enum GNUNET_GenericReturnValue
1356parse_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 */
1447static void
1448clean_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
1463struct GNUNET_JSON_Specification
1464GNUNET_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 */
1486static enum GNUNET_GenericReturnValue
1487parse_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 */
1579static void
1580clean_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
1594struct GNUNET_JSON_Specification
1595GNUNET_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
29json_t * 28json_t *
30GNUNET_JSON_pack_ (struct GNUNET_JSON_PackSpec spec[]) 29GNUNET_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
366struct GNUNET_JSON_PackSpec
367GNUNET_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
403struct GNUNET_JSON_PackSpec
404GNUNET_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
444struct GNUNET_JSON_PackSpec
445GNUNET_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])
6subdir('sq', if_found : [sqlite_dep]) 6subdir('sq', if_found : [sqlite_dep])
7subdir('pq', if_found : [pq_dep]) 7subdir('pq', if_found : [pq_dep])
8subdir('gnsrecord') 8subdir('gnsrecord')
9subdir('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
1907clean_blind_sign_pub (void *cls, 1910clean_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
1918struct GNUNET_PQ_ResultSpec 1921struct GNUNET_PQ_ResultSpec
1919GNUNET_PQ_result_spec_blind_sign_pub (const char *name, 1922GNUNET_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
2036clean_blind_sign_priv (void *cls, 2042clean_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
2047struct GNUNET_PQ_ResultSpec 2053struct GNUNET_PQ_ResultSpec
2048GNUNET_PQ_result_spec_blind_sign_priv (const char *name, 2054GNUNET_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
7test_testing_servicestartup 7test_testing_servicestartup
8test_testing_sharedservices 8test_testing_sharedservices
9gnunet-cmds-helper 9gnunet-cmds-helper
10test_testing_api
11gnunet-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
2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3
4if USE_COVERAGE
5 AM_CFLAGS = --coverage -O0
6 XLIB = -lgcov
7endif
8
9libexecdir= $(pkglibdir)/libexec/
10
11libexec_PROGRAMS = \
12 gnunet-cmds-helper
13
14plugindir = $(libdir)/gnunet
15
16lib_LTLIBRARIES = \
17 libgnunettesting.la
18
19gnunet_cmds_helper_SOURCES = \
20 gnunet-cmds-helper.c
21gnunet_cmds_helper_LDADD = $(XLIB) \
22 libgnunettesting.la \
23 $(top_builddir)/src/lib/util/libgnunetutil.la \
24 $(LTLIBINTL)
25
26libgnunettesting_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
43libgnunettesting_la_LIBADD = \
44 $(top_builddir)/src/lib/util/libgnunetutil.la \
45 $(LTLIBINTL)
46libgnunettesting_la_LDFLAGS = \
47 $(GN_LIB_LDFLAGS) \
48 -version-info 3:0:0
49
50AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;
51
52
53bin_PROGRAMS = \
54 gnunet-testing-netjail-launcher
55
56gnunet_testing_netjail_launcher_SOURCES = \
57 gnunet-testing-netjail-launcher.c
58gnunet_testing_netjail_launcher_LDADD = $(XLIB) \
59 libgnunettesting.la \
60 $(top_builddir)/src/lib/util/libgnunetutil.la \
61 $(LTLIBINTL)
62
63check_PROGRAMS = \
64 test_testing_api
65
66check_SCRIPTS = \
67 test_netjail_api.sh
68
69TESTS = \
70 $(check_PROGRAMS) \
71 $(check_SCRIPTS)
72
73test_testing_api_SOURCES = \
74 test_testing_api.c
75test_testing_api_LDADD = \
76 libgnunettesting.la \
77 -lgnunetutil \
78 $(XLIB)
79
80EXTRA_DIST = \
81 $(check_SCRIPTS) \
82 test_netjail_topo.conf
83
84plugin_LTLIBRARIES = \
85 libgnunet_test_testing_plugin_ping.la
86
87libgnunet_test_testing_plugin_ping_la_SOURCES = \
88 test_testing_plugin_ping.c
89libgnunet_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 */
57struct 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
81static struct WriteContext *wc_head;
82
83static struct WriteContext *wc_tail;
84
85static struct GNUNET_TESTING_Interpreter *is;
86
87static const char *my_node_id;
88
89/**
90 * Plugin to dynamically load a test case.
91 */
92static struct GNUNET_TESTING_PluginFunctions *plugin;
93
94/**
95 * Name of our plugin.
96 */
97static char *plugin_name;
98
99/**
100 * Our message stream tokenizer
101 */
102static struct GNUNET_MessageStreamTokenizer *tokenizer;
103
104/**
105 * Disk handle from stdin
106 */
107static struct GNUNET_DISK_FileHandle *stdin_fd;
108
109/**
110 * Disk handle for stdout
111 */
112static struct GNUNET_DISK_FileHandle *stdout_fd;
113
114/**
115 * Task identifier for the read task
116 */
117static struct GNUNET_SCHEDULER_Task *read_task_id;
118
119/**
120 * Task identifier for the write task
121 */
122static struct GNUNET_SCHEDULER_Task *write_task_id;
123
124/**
125 * Result to return in case we fail
126 */
127static 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 */
133static bool finished;
134
135
136/**
137 * Task to shut down cleanly
138 *
139 * @param cls NULL
140 */
141static void
142do_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 */
183static void
184write_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 */
231static void
232write_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
257static void
258finished_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
273static enum GNUNET_GenericReturnValue
274check_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
300static void
301handle_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
347static void
348handle_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 */
395static enum GNUNET_GenericReturnValue
396tokenizer_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 */
423static void
424read_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 */
474static void
475run (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 */
508int
509main (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
32int
33main (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 @@
1libgnunettesting_src = [ 1libgnunettesting_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
21gnunettesting_src = ['gnunet-testing.c']
22gnunetservicetesting_src = ['gnunet-service-testing.c']
23
24configure_file(input : 'testing.conf',
25 output : 'testing.conf',
26 configuration : cdata,
27 install: true,
28 install_dir: pkgcfgdir)
29
30
31libgnunettesting = library('gnunettesting', 18libgnunettesting = 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)
42pkg.generate(libgnunettesting, url: 'https://www.gnunet.org', 28pkg.generate(libgnunettesting, url: 'https://www.gnunet.org',
43 description : 'Provides API for gnunet testing') 29 description : 'Provides API for gnunet testing')
44 30
45executable ('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
54executable ('gnunet-cmds-helper', 31executable ('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
2exec ../../../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]
2BINARY = gnunet-service-abd
3UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-abd.sock
4RUN_PER_USER = YES
5OPTIONS = -L DEBUG
6
7[arm]
8HOSTNAME = localhost
9BINARY = gnunet-service-arm
10ACCEPT_FROM = 127.0.0.1;
11ACCEPT_FROM6 = ::1;
12UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-arm.sock
13UNIX_MATCH_UID = YES
14UNIX_MATCH_GID = YES
15GLOBAL_PREFIX =
16OPTIONS = -l $GNUNET_CACHE_HOME/gnunet-%Y-%m-%d.log
17CONFIG = /home/user/Documents/gnunet/src/lib/testing/test_netjail_topo.conf
18
19[auction]
20START_ON_DEMAND = NO
21BINARY = gnunet-service-auction
22UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-auction.sock
23
24[cadet]
25IMMEDIATE_START = YES
26START_ON_DEMAND = YES
27HOSTNAME = localhost
28BINARY = gnunet-service-cadet
29ACCEPT_FROM = 127.0.0.1;
30ACCEPT_FROM6 = ::1;
31UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-cadet.sock
32UNIX_MATCH_UID = NO
33UNIX_MATCH_GID = YES
34REFRESH_CONNECTION_TIME = 5 min
35ID_ANNOUNCE_TIME = 1 h
36CONNECT_TIMEOUT = 30 s
37DHT_REPLICATION_LEVEL = 3
38MAX_CONNECTIONS = 1000
39MAX_ROUTES = 5000
40MAX_MSGS_QUEUE = 10000
41MAX_PEERS = 1000
42RATCHET_TIME = 1 h
43RATCHET_MESSAGES = 64
44
45[consensus]
46START_ON_DEMAND = YES
47HOSTNAME = localhost
48BINARY = gnunet-service-consensus
49ACCEPT_FROM = 127.0.0.1;
50ACCEPT_FROM6 = ::1;
51UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-consensus.sock
52UNIX_MATCH_UID = YES
53UNIX_MATCH_GID = YES
54
55[core]
56START_ON_DEMAND = YES
57HOSTNAME = localhost
58BINARY = gnunet-service-core
59ACCEPT_FROM = 127.0.0.1;
60ACCEPT_FROM6 = ::1;
61UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-core.sock
62UNIX_MATCH_UID = NO
63UNIX_MATCH_GID = YES
64USE_EPHEMERAL_KEYS = YES
65
66[datacache-postgres]
67CONFIG = postgres:///gnunet
68SQL_DIR = $DATADIR/sql/
69
70[datastore]
71START_ON_DEMAND = YES
72UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-datastore.sock
73UNIX_MATCH_UID = NO
74UNIX_MATCH_GID = YES
75HOSTNAME = localhost
76BINARY = gnunet-service-datastore
77ACCEPT_FROM = 127.0.0.1;
78ACCEPT_FROM6 = ::1;
79QUOTA = 5 GB
80BLOOMFILTER = $GNUNET_DATA_HOME/datastore/bloomfilter
81DATABASE = sqlite
82
83[datastore-sqlite]
84FILENAME = $GNUNET_DATA_HOME/datastore/sqlite.db
85
86[datastore-postgres]
87CONFIG = postgres:///gnunet
88SQL_DIR = ${DATADIR}/sql/
89
90[datastore-mysql]
91DATABASE = gnunet
92CONFIG = ~/.my.cnf
93
94[datastore-heap]
95HASHMAPSIZE = 1024
96
97[dht]
98IMMEDIATE_START = YES
99START_ON_DEMAND = YES
100HOSTNAME = localhost
101BINARY = gnunet-service-dht
102ACCEPT_FROM = 127.0.0.1;
103ACCEPT_FROM6 = ::1;
104BUCKET_SIZE = 4
105UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-dht.sock
106UNIX_MATCH_UID = NO
107UNIX_MATCH_GID = YES
108CACHE_RESULTS = YES
109DISABLE_TRY_CONNECT = NO
110
111[dhtcache]
112DATABASE = heap
113QUOTA = 50 MB
114DISABLE_BF_RC = NO
115
116[dhtu-gnunet]
117ENABLED = YES
118
119[dhtu-ip]
120ENABLED = NO
121NSE = 4
122UDP_PORT = 6666
123
124[dns]
125START_ON_DEMAND = YES
126HOSTNAME = localhost
127BINARY = gnunet-service-dns
128UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-dns.sock
129UNIX_MATCH_UID = YES
130UNIX_MATCH_GID = YES
131IFNAME = gnunet-dns
132IPV6ADDR = 2001:DB8::1
133IPV6PREFIX = 126
134IPV4ADDR = 169.254.1.1
135IPV4MASK = 255.255.0.0
136DNS_EXIT = 8.8.8.8
137
138[exit]
139BINARY = gnunet-daemon-exit
140IPV6ADDR = 2001:DB8::1
141IPV6PREFIX = 64
142IPV4ADDR = 169.254.86.1
143IPV4MASK = 255.255.255.0
144EXIT_RANGE_IPV4_POLICY = 0.0.0.0/0:!25;
145EXIT_RANGE_IPV6_POLICY = ::/0:!25;
146NOARMBIND = YES
147TUN_IFNAME = exit-gnunet
148EXIT_IFNAME = eth0
149EXIT_IPV4 = NO
150EXIT_IPV6 = NO
151EXIT_DNS = NO
152DNS_RESOLVER = 8.8.8.8
153ENABLE_IPV4 = YES
154ENABLE_IPV6 = YES
155MAX_CONNECTIONS = 256
156
157[fs]
158RUN_PER_USER = YES
159START_ON_DEMAND = YES
160IMMEDIATE_START = YES
161INDEXDB = $GNUNET_DATA_HOME/fs/idxinfo.lst
162RESPECT = $GNUNET_DATA_HOME/fs/credit/
163STATE_DIR = $GNUNET_DATA_HOME/fs/persistence/
164UPDATE_DIR = $GNUNET_DATA_HOME/fs/updates/
165HOSTNAME = localhost
166BINARY = gnunet-service-fs
167ACCEPT_FROM = 127.0.0.1;
168ACCEPT_FROM6 = ::1;
169DELAY = YES
170CONTENT_CACHING = YES
171CONTENT_PUSHING = YES
172UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-fs.sock
173UNIX_MATCH_UID = NO
174UNIX_MATCH_GID = YES
175MAX_PENDING_REQUESTS = 65536
176DATASTORE_QUEUE_SIZE = 32
177MIN_MIGRATION_DELAY = 100 ms
178EXPECTED_NEIGHBOUR_COUNT = 128
179DISABLE_ANON_TRANSFER = NO
180MAX_CADET_CLIENTS = 128
181
182[gns]
183START_ON_DEMAND = YES
184IMMEDIATE_START = YES
185HOSTNAME = localhost
186BINARY = gnunet-service-gns
187UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-gns.sock
188UNIX_MATCH_UID = NO
189UNIX_MATCH_GID = YES
190MAX_PARALLEL_BACKGROUND_QUERIES = 1000
191INTERCEPT_DNS = NO
192.pin.gns.alt = 000G0522TTKQESZ9KPRT2K0RA9ZC8YMD52D2XYVYVGPDCNPMWHH9QXXF4W
193.gnunet.gns.alt = 000G0522TTKQESZ9KPRT2K0RA9ZC8YMD52D2XYVYVGPDCNPMWHH9QXXF4W
194
195[gns-proxy]
196BINARY = gnunet-gns-proxy
197START_ON_DEMAND = NO
198RUN_PER_USER = YES
199BIND_TO = 127.0.0.1
200BIND_TO6 = ::1
201PROXY_CACERT = $GNUNET_DATA_HOME/gns/gns_ca_cert.pem
202PROXY_UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-gns-proxy.sock
203
204[bcd]
205BINARY = gnunet-bcd
206OPTIONS = -p 8888
207START_ON_DEMAND = NO
208RUN_PER_USER = YES
209
210[dns2gns]
211BINARY = gnunet-dns2gns
212START_ON_DEMAND = NO
213RUN_PER_USER = NO
214BIND_TO = 127.0.0.1
215BIND_TO6 = ::1
216OPTIONS = -d 9.9.9.9
217PORT = 15353
218ENABLE_RESOLVECTL_NMDISPATCHER = NO
219
220[hostlist]
221IMMEDIATE_START = YES
222NOARMBIND = YES
223BINARY = gnunet-daemon-hostlist
224HTTPPORT = 8080
225HOSTLISTFILE = $GNUNET_CONFIG_HOME/hostlist/learned.txt
226OPTIONS = -b
227SERVERS = https://v21.gnunet.org/hostlist
228
229[identity]
230START_ON_DEMAND = YES
231RUN_PER_USER = YES
232HOSTNAME = localhost
233BINARY = gnunet-service-identity
234ACCEPT_FROM = 127.0.0.1;
235ACCEPT_FROM6 = ::1;
236UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-identity.sock
237UNIX_MATCH_UID = NO
238UNIX_MATCH_GID = YES
239EGODIR = $GNUNET_DATA_HOME/identity/egos/
240SUBSYSTEM_CFG = $GNUNET_CONFIG_HOME/identity/subsystem_defaults.conf
241
242[messenger]
243START_ON_DEMAND = YES
244RUN_PER_USER = YES
245HOSTNAME = localhost
246BINARY = gnunet-service-messenger
247ACCEPT_FROM = 127.0.0.1;
248ACCEPT_FROM6 = ::1;
249UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-messenger.sock
250UNIX_MATCH_UID = NO
251UNIX_MATCH_GID = YES
252MESSENGER_DIR = $GNUNET_DATA_HOME/messenger/
253MESSENGER_AUTO_CONNECTING = YES
254MESSENGER_AUTO_ROUTING = YES
255MESSENGER_MIN_ROUTERS = 3
256
257[namecache]
258START_ON_DEMAND = YES
259RUN_PER_USER = NO
260UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-namecache.sock
261UNIX_MATCH_UID = NO
262UNIX_MATCH_GID = YES
263HOSTNAME = localhost
264BINARY = gnunet-service-namecache
265ACCEPT_FROM = 127.0.0.1;
266ACCEPT_FROM6 = ::1;
267DATABASE = sqlite
268DISABLE = NO
269
270[namecache-sqlite]
271FILENAME = $GNUNET_DATA_HOME/namecache/sqlite.db
272
273[namecache-flat]
274FILENAME = $GNUNET_DATA_HOME/namecache/flat.db
275
276[namecache-postgres]
277CONFIG = postgres:///gnunet
278SQL_DIR = ${DATADIR}/sql/
279
280[namestore]
281START_ON_DEMAND = YES
282RUN_PER_USER = YES
283UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-namestore.sock
284UNIX_MATCH_UID = NO
285UNIX_MATCH_GID = YES
286HOSTNAME = localhost
287BINARY = gnunet-service-namestore
288ACCEPT_FROM = 127.0.0.1;
289ACCEPT_FROM6 = ::1;
290DATABASE = sqlite
291CACHE_KEYS = YES
292
293[namestore-sqlite]
294INIT_ON_CONNECT = YES
295FILENAME = $GNUNET_DATA_HOME/namestore/sqlite.db
296
297[namestore-postgres]
298CONFIG = postgres:///gnunet
299ASYNC_COMMIT = NO
300INIT_ON_CONNECT = YES
301SQL_DIR = ${DATADIR}/sql/
302
303[uri]
304gns = gnunet-namestore -e 1a -u
305
306[nat-auto]
307START_ON_DEMAND = YES
308HOSTNAME = localhost
309BINARY = gnunet-service-nat-auto
310ACCEPT_FROM = 127.0.0.1;
311ACCEPT_FROM6 = ::1;
312UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-nat-auto.sock
313UNIX_MATCH_UID = YES
314UNIX_MATCH_GID = YES
315
316[gnunet-nat-server]
317HOSTNAME = gnunet.org
318PORT = 5724
319NOARMBIND = YES
320
321[nat]
322START_ON_DEMAND = YES
323HOSTNAME = localhost
324BINARY = gnunet-service-nat
325ACCEPT_FROM = 127.0.0.1;
326ACCEPT_FROM6 = ::1;
327UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-nat.sock
328UNIX_MATCH_UID = YES
329UNIX_MATCH_GID = YES
330ENABLE_UPNP = YES
331ENABLE_IPSCAN = YES
332DISABLEV6 = NO
333HOSTNAME_DNS_FREQUENCY = 20 min
334IFC_SCAN_FREQUENCY = 15 min
335DYNDNS_FREQUENCY = 7 min
336USE_STUN = YES
337STUN_FREQUENCY = 5 min
338STUN_SERVERS = stun.gnunet.org stun.services.mozilla.com:3478 stun.ekiga.net:3478
339STUN_STALE = 60 min
340
341[nse]
342START_ON_DEMAND = YES
343IMMEDIATE_START = YES
344HOSTNAME = localhost
345BINARY = gnunet-service-nse
346ACCEPT_FROM = 127.0.0.1;
347ACCEPT_FROM6 = ::1;
348UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-nse.sock
349UNIX_MATCH_UID = NO
350UNIX_MATCH_GID = YES
351PROOFFILE = $GNUNET_DATA_HOME/nse/proof.dat
352HISTOGRAM_DIR = $GNUNET_CACHE_HOME/nse/histogram
353WORKDELAY = 5 ms
354INTERVAL = 1 h
355WORKBITS = 15
356
357[peerstore]
358IMMEDIATE_START = YES
359USE_INCLUDED_HELLOS = YES
360HOSTNAME = localhost
361BINARY = gnunet-service-peerstore
362UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-peerstore.sock
363UNIX_MATCH_UID = NO
364UNIX_MATCH_GID = YES
365DATABASE = sqlite
366
367[peerstore-sqlite]
368FILENAME = $GNUNET_DATA_HOME/peerstore/sqlite.db
369
370[pt]
371BINARY = gnunet-daemon-pt
372NOARMBIND = YES
373TUNNEL_IPV4 = NO
374TUNNEL_IPV6 = NO
375TUNNEL_DNS = NO
376
377[reclaim]
378START_ON_DEMAND = YES
379RUN_PER_USER = YES
380HOSTNAME = localhost
381BINARY = gnunet-service-reclaim
382ACCEPT_FROM = 127.0.0.1;
383ACCEPT_FROM6 = ::1;
384UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-reclaim.sock
385UNIX_MATCH_UID = NO
386UNIX_MATCH_GID = YES
387TICKET_REFRESH_INTERVAL = 6h
388
389[reclaim-rest-plugin]
390ADDRESS = https://ui.reclaim/#/login
391OIDC_JSON_WEB_ALGORITHM = RS256
392OIDC_CLIENT_HMAC_SECRET = secret
393OIDC_DIR = $GNUNET_DATA_HOME/oidc
394OIDC_USERINFO_CONSUME_TIMEOUT = 5s
395JWT_SECRET = secret
396EXPIRATION_TIME = 1d
397
398[regex]
399START_ON_DEMAND = YES
400UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-regex.sock
401HOSTNAME = localhost
402BINARY = gnunet-service-regex
403ACCEPT_FROM = 127.0.0.1;
404ACCEPT_FROM6 = ::1;
405
406[resolver]
407START_ON_DEMAND = YES
408HOSTNAME = localhost
409BINARY = gnunet-service-resolver
410ACCEPT_FROM = 127.0.0.1;
411ACCEPT_FROM6 = ::1;
412UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver.sock
413UNIX_MATCH_UID = NO
414UNIX_MATCH_GID = NO
415
416[rest]
417UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-rest.sock
418BINARY = gnunet-rest-server
419IMMEDIATE_START = YES
420HTTP_PORT = 7776
421BIND_TO = 127.0.0.1
422BIND_TO6 = ::1
423REST_ALLOW_HEADERS = Authorization,Accept,Content-Type
424REST_ECHO_ORIGIN_WEBEXT = YES
425REST_ALLOW_ORIGIN = http://localhost:4200
426REST_ALLOW_CREDENTIALS = true
427RUN_PER_USER = NO
428BASIC_AUTH_SECRET_FILE = $GNUNET_DATA_HOME/rest/secret
429BASIC_AUTH_ENABLED = YES
430
431[revocation]
432START_ON_DEMAND = YES
433IMMEDIATE_START = YES
434HOSTNAME = localhost
435BINARY = gnunet-service-revocation
436ACCEPT_FROM = 127.0.0.1;
437ACCEPT_FROM6 = ::1;
438UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-revocation.sock
439UNIX_MATCH_UID = NO
440UNIX_MATCH_GID = YES
441WORKBITS = 22
442EPOCH_DURATION = 365 d
443DATABASE = $GNUNET_DATA_HOME/revocation.dat
444
445[rps]
446START_ON_DEMAND = YES
447IMMEDIATE_START = YES
448BINARY = gnunet-service-rps
449UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-rps.sock
450HOME = $SERVICEHOME
451UNIX_MATCH_UID = NO
452UNIX_MATCH_GID = YES
453HOSTNAME = localhost
454ACCEPT_FROM = 127.0.0.1;
455ACCEPT_FROM6 = ::1;
456ROUNDINTERVAL = 30 s
457FILENAME_VALID_PEERS = $GNUNET_DATA_HOME/rps/valid_peers.txt
458MINSIZE = 10
459DESIRED_PROBABILITY = 0.9
460DEFICIENCY_FACTOR = 0.4
461
462[scalarproduct-alice]
463START_ON_DEMAND = YES
464BINARY = gnunet-service-scalarproduct-ecc-alice
465UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-scalarproduct-alice.sock
466UNIX_MATCH_UID = NO
467UNIX_MATCH_GID = YES
468
469[scalarproduct-bob]
470START_ON_DEMAND = YES
471HOSTNAME = localhost
472BINARY = gnunet-service-scalarproduct-ecc-bob
473UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-scalarproduct-bob.sock
474UNIX_MATCH_UID = NO
475UNIX_MATCH_GID = YES
476
477[secretsharing]
478START_ON_DEMAND = NO
479HOSTNAME = localhost
480BINARY = gnunet-service-secretsharing
481ACCEPT_FROM = 127.0.0.1;
482ACCEPT_FROM6 = ::1;
483UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-secretsharing.sock
484UNIX_MATCH_UID = YES
485UNIX_MATCH_GID = YES
486
487[set]
488START_ON_DEMAND = YES
489HOSTNAME = localhost
490BINARY = gnunet-service-set
491ACCEPT_FROM = 127.0.0.1;
492ACCEPT_FROM6 = ::1;
493UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-set.sock
494UNIX_MATCH_UID = YES
495UNIX_MATCH_GID = YES
496
497[seti]
498START_ON_DEMAND = YES
499HOSTNAME = localhost
500BINARY = gnunet-service-seti
501ACCEPT_FROM = 127.0.0.1;
502ACCEPT_FROM6 = ::1;
503UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-seti.sock
504UNIX_MATCH_UID = YES
505UNIX_MATCH_GID = YES
506
507[setu]
508START_ON_DEMAND = YES
509HOSTNAME = localhost
510BINARY = gnunet-service-setu
511ACCEPT_FROM = 127.0.0.1;
512ACCEPT_FROM6 = ::1;
513UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-setu.sock
514UNIX_MATCH_UID = YES
515UNIX_MATCH_GID = YES
516
517[statistics]
518START_ON_DEMAND = YES
519HOSTNAME = localhost
520BINARY = gnunet-service-statistics
521ACCEPT_FROM = 127.0.0.1;
522ACCEPT_FROM6 = ::1;
523UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-statistics.sock
524UNIX_MATCH_UID = NO
525UNIX_MATCH_GID = YES
526DATABASE = $GNUNET_DATA_HOME/statistics.dat
527
528[template]
529START_ON_DEMAND = NO
530PORT = 99999
531HOSTNAME = localhost
532BINARY = gnunet-service-template
533ACCEPT_FROM = 127.0.0.1;
534ACCEPT_FROM6 = ::1;
535UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-template.sock
536UNIX_MATCH_UID = YES
537UNIX_MATCH_GID = YES
538
539[TESTING]
540CONNECT_TIMEOUT = 30 s
541CONNECT_ATTEMPTS = 3
542MAX_OUTSTANDING_CONNECTIONS = 50
543DELETE_FILES = YES
544SPEEDUP_INTERVAL = 0 ms
545SPEEDUP_DELTA = 0 ms
546USE_ABSTRACT_SOCKETS = NO
547
548[topology]
549IMMEDIATE_START = YES
550NOARMBIND = YES
551TARGET-CONNECTION-COUNT = 16
552BINARY = gnunet-daemon-topology
553
554[transport]
555START_ON_DEMAND = YES
556HOSTNAME = localhost
557BINARY = gnunet-service-transport
558ACCEPT_FROM = 127.0.0.1;
559ACCEPT_FROM6 = ::1;
560UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport.sock
561
562[communicator-tcp]
563BINDTO = 2086
564DISABLE_V6 = NO
565BINARY = gnunet-communicator-tcp
566IMMEDIATE_START = YES
567
568[communicator-udp]
569BINARY = gnunet-communicator-udp
570BINDTO = 2086
571DISABLE_V6 = NO
572IMMEDIATE_START = YES
573
574[communicator-quic]
575BINDTO = 127.0.0.1
576
577[PEER]
578PRIVATE_KEY = $GNUNET_DATA_HOME/private_key.ecc
579SYSTEM_TYPE = UNKNOWN
580
581[vpn]
582START_ON_DEMAND = YES
583HOSTNAME = localhost
584BINARY = gnunet-service-vpn
585ACCEPT_FROM = 127.0.0.1;
586ACCEPT_FROM6 = ::1;
587UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-vpn.sock
588UNIX_MATCH_UID = NO
589UNIX_MATCH_GID = YES
590IPV6ADDR = 1234::1
591IPV6PREFIX = 32
592IPV4ADDR = 10.11.10.1
593IPV4MASK = 255.255.0.0
594VIRTDNS = 10.11.10.2
595VIRTDNS6 = 1234::17
596IFNAME = vpn-gnunet
597
598[zonemaster]
599START_ON_DEMAND = YES
600RUN_PER_USER = YES
601IMMEDIATE_START = YES
602HOSTNAME = localhost
603BINARY = gnunet-service-zonemaster
604UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-zonemaster.sock
605WORKER_COUNT = 4
606UNIX_MATCH_UID = NO
607UNIX_MATCH_GID = NO
608MAX_PARALLEL_BACKGROUND_QUERIES = 1000
609ZONE_PUBLISH_TIME_WINDOW = 4 h
610
611[DEFAULTS]
612SUBNETS = 42
613CARRIER_SETUP_PROGRAMMS = iptables -A INPUT -p icmp -j DROP;tc qdisc add dev $UPLINK root netm delay 100ms 10ms;
614SUBNET_SETUP_PROGRAMMS = iptables -A INPUT -p icmp -j DROP;tc qdisc add dev $UPLINK root netm delay 100ms 10ms;
615PEER_SETUP_PROGRAMMS = iptables -A INPUT -p icmp -j DROP;tc qdisc add dev $UPLINK root netm delay 100ms 10ms;
616TESTBED_PLUGIN = normal
617PLUGIN_ENV = key=value;key=value;
618CARRIER_PEERS = 1
619SUBNET_PEERS = 4
620
621[BACKBONE]
622CARRIERS = 2
623BACKBONE_PEERS = 1
624
625[BACKBONE-PEER-1]
626TESTBED_PLUGIN = server
627
628[CARRIER-1]
629CARRIER_PEERS = 2
630SUBNETS = 2
631
632[CARRIER-2]
633TESTBED_PLUGIN = mobile_network
634
635[CARRIER-2-PEER-1]
636TESTBED_PLUGIN = mobile_network
637
638[CARRIER-1-SUBNET-1]
639SUBNET = 8.8.0.0/16
640SUBNET_PEERS = 2
641TESTBED_PLUGIN = pc
642
643[CARRIER-1-SUBNET-2]
644IPTABLES_ARGS = -A ... $UPLINK; -A ... $DOWNLINK;
645
646[CARRIER-1-SUBNET-1-PEER-1]
647TESTBED_PLUGIN = evil
648IPTABLES_ARGS = -A ... $DOWNLINK;
649
650[PATHS]
651GNUNET_HOME = ${GNUNET_TEST_HOME:-${HOME:-${USERPROFILE}}}
652GNUNET_DATA_HOME = ${XDG_DATA_HOME:-$GNUNET_HOME/.local/share}/gnunet/
653GNUNET_CONFIG_HOME = ${XDG_CONFIG_HOME:-$GNUNET_HOME/.config}/gnunet/
654GNUNET_CACHE_HOME = ${XDG_CACHE_HOME:-$GNUNET_HOME/.cache}/gnunet/
655GNUNET_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/gnunet-system-runtime/
656GNUNET_USER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/gnunet-${USERHOME:-${USER:-user}}-runtime/
657GNUNET_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
29int
30main (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
30GNUNET_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
38void
39GNUNET_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 */
33struct 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
74void
75GNUNET_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 */
41static enum GNUNET_GenericReturnValue
42barrier_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 */
64static void
65barrier_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 */
79static void
80barrier_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
90struct GNUNET_TESTING_Command
91GNUNET_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 */
40struct 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 */
66static void
67barrier_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 */
137static void
138barrier_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 */
155static enum GNUNET_GenericReturnValue
156barrier_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
172struct GNUNET_TESTING_Command
173GNUNET_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
183GNUNET_TESTING_cmd_batch_next_ (void *cls) 178GNUNET_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
213void 219void
214GNUNET_TESTING_cmd_batch_set_current_ (const struct GNUNET_TESTING_Command *cmd, 220GNUNET_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 */
35bool
36GNUNET_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 */
47bool
48GNUNET_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 */
56struct GNUNET_TESTING_Command *
57GNUNET_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 */
67void
68GNUNET_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
32struct 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 */
76static void
77exec_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 */
111static void
112child_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 */
142static void
143exec_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 */
167static enum GNUNET_GenericReturnValue
168traits (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
186const struct GNUNET_TESTING_Command
187GNUNET_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
216const struct GNUNET_TESTING_Command
217GNUNET_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 */
108static void 122static void
109run_finish (void *cls, 123run_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
170const struct GNUNET_TESTING_Command 187const struct GNUNET_TESTING_Command
171GNUNET_TESTING_cmd_finish (const char *finish_label, 188GNUNET_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
187struct GNUNET_TESTING_Command 208struct GNUNET_TESTING_Command
188GNUNET_TESTING_cmd_make_unblocking (struct GNUNET_TESTING_Command cmd) 209GNUNET_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
35struct 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 */
69static void
70cleanup (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 */
87static enum GNUNET_GenericReturnValue
88traits (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
107static char *
108get_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 */
155static void
156run (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
176struct GNUNET_TESTING_Command
177GNUNET_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
196struct GNUNET_TESTING_Command
197GNUNET_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 */
107static void 97static void
108child_completed_callback (void *cls, 98child_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 */
217struct GNUNET_TESTING_Command 203struct GNUNET_TESTING_Command
218GNUNET_TESTING_cmd_netjail_start (const char *label, 204GNUNET_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 */
44struct TestingSystemCount;
45
46
47/**
48 * Struct to store information handed over to callbacks.
49 */
50struct 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 */
118struct 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 */
153static void
154clear_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
175static void
176handle_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
230static void
231handle_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 */
264static enum GNUNET_GenericReturnValue
265helper_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 */
302static void
303exp_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
319static enum GNUNET_GenericReturnValue
320add_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 */
336static bool
337send_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 */
405static bool
406start_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 */
456static void
457do_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 */
475static void
476netjail_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 */
522static void
523netjail_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 */
542static enum GNUNET_GenericReturnValue
543netjail_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 */
569struct GNUNET_TESTING_Command
570GNUNET_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 */
31struct 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 */
51static void
52signal_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 */
87static void
88signal_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 */
104struct GNUNET_TESTING_Command
105GNUNET_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 */
34static void
35stat_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 */
45static void
46stat_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 */
100static void
101do_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 */
136static void
137stat_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
149struct GNUNET_TESTING_Command
150GNUNET_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
33struct GNUNET_TESTING_Command
34GNUNET_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
58void
59GNUNET_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
74struct GNUNET_TESTING_Command
75GNUNET_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
84struct GNUNET_TESTING_Command
85GNUNET_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
37struct 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 */
54struct 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
146const struct GNUNET_TESTING_Command *
147GNUNET_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 &current));
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
204const struct GNUNET_TESTING_Command *
205GNUNET_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
225static void
226send_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
240void
241GNUNET_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
266void
267GNUNET_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 */
282static void
283finish_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 */
348static void
349interpreter_run (void *cls);
350
351
352void
353GNUNET_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
394void
395GNUNET_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 */
441static void
442interpreter_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
464void
465GNUNET_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
509void
510GNUNET_TESTING_interpreter_skip (
511 struct GNUNET_TESTING_Interpreter *is)
512{
513 is->skip = true;
514 GNUNET_TESTING_interpreter_fail (is);
515}
516
517
518void
519GNUNET_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
527void
528GNUNET_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 */
550static void
551do_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
563static void
564setup_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
603struct GNUNET_TESTING_Interpreter *
604GNUNET_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
625static struct GNUNET_TESTING_Interpreter *
626start_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
678struct GNUNET_TESTING_PluginFunctions *
679GNUNET_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
691void
692GNUNET_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
701struct GNUNET_TESTING_Barrier *
702GNUNET_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
710struct GNUNET_TESTING_Barrier *
711GNUNET_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
725void
726GNUNET_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
743unsigned int
744GNUNET_TESTING_barrier_count_ (
745 struct GNUNET_TESTING_Interpreter *is)
746{
747 return GNUNET_CONTAINER_multishortmap_size (is->barriers);
748}
749
750
751void
752GNUNET_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
763void
764GNUNET_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
797void
798GNUNET_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
806void
807GNUNET_TESTING_interpreter_current_cmd_inc_tries (
808 struct GNUNET_TESTING_Interpreter *is)
809{
810 is->commands[is->ip].num_tries++;
811}
812
813
814const char *
815GNUNET_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 */
825struct 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 */
851static enum GNUNET_GenericReturnValue
852seek_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 &current));
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 */
916static void
917rewind_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
985static void
986rewind_ip_free (void *cls)
987{
988 struct RewindIpState *ris = cls;
989
990 GNUNET_free (ris);
991}
992
993
994struct GNUNET_TESTING_Command
995GNUNET_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 */
37typedef 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 */
45struct 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 */
85void
86GNUNET_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 */
97void
98GNUNET_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 */
106void
107GNUNET_TESTING_interpreter_next_ (void *cls);
108
109
110void
111GNUNET_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 */
121void
122GNUNET_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 */
134void
135GNUNET_TESTING_add_barrier_ (
136 struct GNUNET_TESTING_Interpreter *is,
137 struct GNUNET_TESTING_Barrier *barrier);
138
139
140struct GNUNET_TESTING_Barrier *
141GNUNET_TESTING_get_barrier2_ (
142 struct GNUNET_TESTING_Interpreter *is,
143 const struct GNUNET_ShortHashCode *create_key);
144
145
146struct GNUNET_TESTING_Barrier *
147GNUNET_TESTING_get_barrier_ (
148 struct GNUNET_TESTING_Interpreter *is,
149 const char *barrier_name);
150
151
152unsigned int
153GNUNET_TESTING_barrier_count_ (
154 struct GNUNET_TESTING_Interpreter *is);
155
156
157void
158GNUNET_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 */
36struct 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 */
67static void
68handle_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
93static void
94do_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 */
112static void
113loop_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
126int
127GNUNET_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 */
64static unsigned int
65get_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 */
92static char *
93get_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?
113static char *
114get_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 */
133static unsigned int
134get_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 */
163static char *
164get_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 */
203static struct GNUNET_TESTING_NodeConnection *
204get_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 */
312static void
313node_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 */
365static int
366log_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 */
412static int
413log_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 */
431static int
432log_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*/
459static void
460get_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 */
541struct GNUNET_TESTING_NetjailNode *
542GNUNET_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 */
563struct GNUNET_TESTING_NodeConnection *
564GNUNET_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
581int
582free_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
613int
614free_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 */
634void
635GNUNET_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
650unsigned int
651GNUNET_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 */
676char *
677GNUNET_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 */
736unsigned int
737GNUNET_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
767static void
768parse_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
798char *
799GNUNET_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 */
813struct GNUNET_TESTING_NetjailTopology *
814GNUNET_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
1078GNUNET_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 */
37struct 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 */
54enum 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 */
70struct 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 */
92struct GNUNET_TESTING_NetjailNode;
93
94/**
95 * Connection to another node.
96 */
97struct 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 */
144struct 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 */
196struct 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 */
217struct 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 */
269struct GNUNET_TESTING_NetjailTopology *
270GNUNET_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 */
279unsigned int
280GNUNET_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 */
292struct GNUNET_TESTING_NetjailNode *
293GNUNET_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 */
304struct GNUNET_TESTING_NodeConnection *
305GNUNET_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 */
317char *
318GNUNET_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 */
326char *
327GNUNET_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 */
337void
338GNUNET_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 */
348unsigned int
349GNUNET_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
363GNUNET_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? */ 32GNUNET_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT,
36 33 GNUNET_TESTING)
37GNUNET_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, GNUNET_TESTING)
38
39GNUNET_TESTING_INDEXED_TRAITS (GNUNET_TESTING_MAKE_IMPL_INDEXED_TRAIT, GNUNET_TESTING)
40
41GNUNET_TESTING_LOOP_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, GNUNET_TESTING)
42
43GNUNET_TESTING_LOOP_INDEXED_TRAITS (GNUNET_TESTING_MAKE_IMPL_INDEXED_TRAIT, GNUNET_TESTING)
44
45GNUNET_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
33GNUNET_NETWORK_STRUCT_BEGIN
34
35/**
36 * Initialization message for gnunet-cmds-testbed to start cmd binary.
37 */
38struct 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
56struct 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 */
74struct 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 */
86struct 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 */
96struct GNUNET_TESTING_CommandBarrierSatisfied
97{
98 struct GNUNET_MessageHeader header;
99 struct GNUNET_ShortHashCode barrier_key;
100};
101
102
103GNUNET_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
20test_container_multihashmap 20test_container_multihashmap
21test_container_multihashmap32 21test_container_multihashmap32
22test_container_multipeermap 22test_container_multipeermap
23test_crypto_blind
23test_crypto_crc 24test_crypto_crc
24test_crypto_ecc_dlog 25test_crypto_ecc_dlog
25test_crypto_ecdh_ecdsa 26test_crypto_ecdh_ecdsa
@@ -28,6 +29,7 @@ test_crypto_ecdhe
28test_crypto_ecdsa 29test_crypto_ecdsa
29test_crypto_eddsa 30test_crypto_eddsa
30test_crypto_edx25519 31test_crypto_edx25519
32test_crypto_elligator
31test_crypto_hash 33test_crypto_hash
32test_crypto_hash_context 34test_crypto_hash_context
33test_crypto_hkdf 35test_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
148libgnunetutil_la_LDFLAGS = \ 148libgnunetutil_la_LDFLAGS = \
149 $(GN_LIB_LDFLAGS) \ 149 $(GN_LIB_LDFLAGS) \
150 -version-info 16:0:0 150 -version-info 16:1:0
151 151
152lib_LTLIBRARIES = libgnunetutil.la 152lib_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 */
59void * 47void *
60GNUNET_xmalloc_ (size_t size, const char *filename, int linenumber) 48GNUNET_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 */
91void ** 72void **
92GNUNET_xnew_array_2d_ (size_t n, 73GNUNET_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 */
127void *** 93void ***
128GNUNET_xnew_array_3d_ (size_t n, 94GNUNET_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 */
191void * 155void *
192GNUNET_xmalloc_unchecked_ (size_t size, const char *filename, int linenumber) 156GNUNET_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 */
219void * 174void *
220GNUNET_xrealloc_ (void *ptr, size_t n, const char *filename, int linenumber) 175GNUNET_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 */
283void 234void
284GNUNET_xfree_ (void *ptr, 235GNUNET_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 */
315char * 258char *
316GNUNET_xstrdup_ (const char *str, const char *filename, int linenumber) 259GNUNET_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
330static size_t 280static size_t
331strnlen (const char *s, size_t n) 281strnlen (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 */
354char * 298char *
355GNUNET_xstrndup_ (const char *str, 299GNUNET_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 */
385void 321void
386GNUNET_xgrow_ (void **old, 322GNUNET_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 */
428int 363int
429GNUNET_asprintf (char **buf, const char *format, ...) 364GNUNET_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 */
455int 389int
456GNUNET_snprintf (char *buf, size_t size, const char *format, ...) 390GNUNET_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/** 424bool
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 */
491enum GNUNET_GenericReturnValue
492GNUNET_is_zero_ (const void *a, 425GNUNET_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
414static void
415buffer_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
414void 429void
415GNUNET_CRYPTO_ecdhe_key_clear (struct GNUNET_CRYPTO_EcdhePrivateKey *pk) 430GNUNET_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
421void 436void
422GNUNET_CRYPTO_ecdsa_key_clear (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk) 437GNUNET_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
428void 443void
429GNUNET_CRYPTO_eddsa_key_clear (struct GNUNET_CRYPTO_EddsaPrivateKey *pk) 444GNUNET_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
46void
47GNUNET_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
46ssize_t 63ssize_t
47GNUNET_CRYPTO_private_key_get_length (const struct 64GNUNET_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)
612struct GNUNET_HELPER_SendHandle * 612struct GNUNET_HELPER_SendHandle *
613GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, 613GNUNET_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 */
361static int 355static enum GNUNET_GenericReturnValue
362have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh) 356have_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 */
382static void 379static void
383do_suspend (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) 380do_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 */
440static int 438static bool
441check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, 439check_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 */
467static int 461static bool
468check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, 462check_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;
476NEXT:
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 */
595static void 588static void
596service_mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state) 589service_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 */
617static void 611static void
618service_mq_error_handler (void *cls, enum GNUNET_MQ_Error error) 612service_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 */
872static void 876static void
873do_resume (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) 877do_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 */
931static int 936static enum GNUNET_GenericReturnValue
932process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, 937process_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 */
972static int 977static enum GNUNET_GenericReturnValue
973process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, 978process_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 */
1460static int 1465static enum GNUNET_GenericReturnValue
1461setup_service (struct GNUNET_SERVICE_Handle *sh) 1466setup_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 */
1627static int 1638static enum GNUNET_GenericReturnValue
1628set_user_id (struct GNUNET_SERVICE_Handle *sh) 1639set_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 */
1716static int 1729static enum GNUNET_GenericReturnValue
1717detach_terminal (struct GNUNET_SERVICE_Handle *sh) 1730detach_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 */
1823static void 1842static void
1824return_agpl (void *cls, const struct GNUNET_MessageHeader *msg) 1843return_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 */
1879struct GNUNET_SERVICE_Handle * 1866struct GNUNET_SERVICE_Handle *
1880GNUNET_SERVICE_start (const char *service_name, 1867GNUNET_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 */
1902static void
1903finish_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
1912void 1937void
1913GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv) 1938GNUNET_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 */
2143struct ServiceHandleList 2186struct ServiceHandleList
@@ -2153,10 +2196,11 @@ struct ServiceHandleList
2153}; 2196};
2154 2197
2155/* The service list */ 2198/* The service list */
2156static struct ServiceHandleList *hll_head = NULL; 2199static struct ServiceHandleList *hll_head;
2157 2200
2158/* The service list */ 2201/* The service list */
2159static struct ServiceHandleList *hll_tail = NULL; 2202static struct ServiceHandleList *hll_tail;
2203
2160 2204
2161int 2205int
2162GNUNET_SERVICE_register_ (const char *service_name, 2206GNUNET_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
2192static void 2237static void
2193do_registered_services_shutdown (void *cls) 2238do_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)
2216static void 2264static void
2217launch_registered_services (void *cls) 2265launch_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);
2330shutdown: 2391shutdown:
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 */
2346void 2401void
2347GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh) 2402GNUNET_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 */
2358void 2409void
2359GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh) 2410GNUNET_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 */
2407void 2454void
2408GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c) 2455GNUNET_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 */
2431void 2471void
2432GNUNET_SERVICE_client_disable_continue_warning (struct GNUNET_SERVICE_Client *c) 2472GNUNET_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 */
2448static void
2449finish_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 */
2488void 2483void
2489GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c) 2484GNUNET_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 */
2547void 2532void
2548GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh) 2533GNUNET_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 */
2571void 2548void
2572GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c) 2549GNUNET_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 */
2588void 2558void
2589GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c) 2559GNUNET_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 */
2601struct GNUNET_MQ_Handle * 2565struct GNUNET_MQ_Handle *
2602GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c) 2566GNUNET_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
43size_t 43size_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
1723size_t 1723size_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 @@
1SUBDIRS = \ 1SUBDIRS = \
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
14endif 14endif
15 15
16lib_LTLIBRARIES = libgnunetarm.la 16lib_LTLIBRARIES = \
17 libgnunetarm.la \
18 libgnunettestingarm.la
17 19
18libgnunetarm_la_SOURCES = \ 20libgnunetarm_la_SOURCES = \
19 arm_api.c arm_monitor_api.c arm.h 21 arm_api.c \
22 arm_monitor_api.c \
23 arm.h
20libgnunetarm_la_LIBADD = \ 24libgnunetarm_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
31libgnunettestingarm_la_SOURCES = \
32 testing_arm_cmd_start_peer.c \
33 testing_arm_cmd_stop_peer.c \
34 testing_arm_traits.c
35libgnunettestingarm_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)
42libgnunettestingarm_la_LDFLAGS = \
43 $(GN_LIB_LDFLAGS) \
44 -version-info 0:0:0
45
27 46
28noinst_PROGRAMS = \ 47noinst_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 */
37struct 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 */
84static void
85conn_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 */
105static void
106start_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 */
219static void
220start_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 */
253static enum GNUNET_GenericReturnValue
254start_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
276struct GNUNET_TESTING_Command
277GNUNET_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 */
41struct StopPeerState 36struct 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 */
116struct GNUNET_TESTING_Command 114struct GNUNET_TESTING_Command
117GNUNET_TESTING_cmd_stop_peer (const char *label, 115GNUNET_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
55libgnunetcoretesting_la_SOURCES = \ 55libgnunetcoretesting_la_SOURCES = \
56 core_api_cmd_connecting_peers.c 56 core_api_cmd_connecting_peers.c
57libgnunetcoretesting_la_LIBADD = \ 57libgnunetcoretesting_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
107test_core_api_send_to_self_LDADD = \ 107test_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
112test_core_api_start_only_SOURCES = \ 112test_core_api_start_only_SOURCES = \
113 test_core_api_start_only.c 113 test_core_api_start_only.c
114test_core_api_start_only_LDADD = \ 114test_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
277GNUNET_CORE_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, GNUNET_CORE_TESTING) 276GNUNET_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
57configure_file(input : 'dhtu.conf',
58 output : 'dhtu.conf',
59 configuration : cdata,
60 install: true,
61 install_dir: pkgcfgdir)
62
63libgnunettestingdhtu = library('gnunettestingdhtu', 57libgnunettestingdhtu = 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/** 227enum GNUNET_GenericReturnValue
227 * Perform an asynchronous lookup operation on the GNS, 228GNUNET_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 */
239struct GNUNET_GNS_LookupWithTldRequest * 239struct GNUNET_GNS_LookupWithTldRequest *
240GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle, 240GNUNET_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
7subdir('util') 7subdir('util')
8subdir('statistics') 8subdir('statistics')
9subdir('arm') 9subdir('arm')
10subdir('testing')
11subdir('peerstore') 10subdir('peerstore')
12subdir('nat') 11subdir('nat')
13subdir('nat-auto') 12subdir('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
63libgnunetmessengertesting_la_LIBADD = \ 63libgnunetmessengertesting_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
148test_messenger_api_LDADD = \ 148test_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
153test_messenger_anonymous_SOURCES = \ 153test_messenger_anonymous_SOURCES = \
154 test_messenger_anonymous.c 154 test_messenger_anonymous.c
155test_messenger_anonymous_LDADD = \ 155test_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
160EXTRA_DIST = \ 160EXTRA_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
636static void 640static void
641callback_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
652static void
637send_message_to_room (struct GNUNET_MESSENGER_Room *room, 653send_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
1230struct GNUNET_MESSENGER_CheckTicket
1231{
1232 const struct GNUNET_CRYPTO_PublicKey *audience;
1233 enum GNUNET_GenericReturnValue result;
1234};
1235
1236
1237static enum GNUNET_GenericReturnValue
1238check_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
1257void
1258GNUNET_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 @@
32struct GNUNET_MESSENGER_MessageSignature 32struct 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
38struct GNUNET_MESSENGER_ShortMessage 38struct 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
192struct GNUNET_MESSENGER_Message* 194struct GNUNET_MESSENGER_Message*
193create_message_ticket (const struct GNUNET_RECLAIM_Identifier *identifier) 195create_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 */
136struct GNUNET_MESSENGER_Message* 135struct GNUNET_MESSENGER_Message*
137create_message_ticket (const struct GNUNET_RECLAIM_Identifier *identifier); 136create_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 */
1818static void 1818static void
1819handle_request_connection_reversal (void *cls, 1819handle_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 */
1874static int 1873static enum GNUNET_GenericReturnValue
1875check_add_global_address(void *cls, 1874check_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
1899static int
1900is_nat_v4 (const struct in_addr *ip);
1901
1902
1903static int
1904is_nat_v6 (const struct in6_addr *ip);
1905
1906
1907static void
1908notify_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 */
1922static void 1903static void
1923handle_add_global_address(void *cls, 1904handle_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 */
466static char *
467get_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
483void 458void
484GNUNET_NAT_add_global_address (struct GNUNET_NAT_Handle *nh, 459GNUNET_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
495static void
496destroy_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
455static void
456destroy_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
592static void
593destroy_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
239struct GNUNET_PEERSTORE_Monitor * 238struct GNUNET_PEERSTORE_Monitor *
240GNUNET_PEERSTORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 239GNUNET_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
1005check_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm) 984check_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 */
2494static void 2449static void
2495ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket) 2450ticket_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 */
996static void 1003static void
997process_parallel_lookup_result (void *cls, 1004process_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 */
1084static void 1085static void
1085lookup_authz_cb (void *cls, 1086lookup_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 */
1180struct RECLAIM_TICKETS_ConsumeHandle * 1215struct RECLAIM_TICKETS_ConsumeHandle *
1181RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_PrivateKey *id, 1216RECLAIM_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)
1650void 1676void
1651RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_PrivateKey *identity, 1677RECLAIM_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 */
106typedef void (*RECLAIM_TICKETS_TicketIter) ( 107typedef 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 */
195struct RECLAIM_TICKETS_ConsumeHandle * 197struct RECLAIM_TICKETS_ConsumeHandle *
196RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_PrivateKey *id, 198RECLAIM_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);
222void 224void
223RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_PrivateKey *identity, 225RECLAIM_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 *
1491GNUNET_RECLAIM_ticket_issue ( 1497GNUNET_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 */
1550struct GNUNET_RECLAIM_Operation * 1545struct GNUNET_RECLAIM_Operation *
1551GNUNET_RECLAIM_ticket_consume ( 1546GNUNET_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
1741size_t
1742GNUNET_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
1751enum GNUNET_GenericReturnValue
1752GNUNET_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
1784ssize_t
1785GNUNET_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
170parse_ticket (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec) 170parse_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 */
288static int 253static int
289parse_credential (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec) 254parse_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
361char * 363char *
362generate_id_token_body (const struct GNUNET_CRYPTO_PublicKey *aud_key, 364generate_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
426char * 422char *
427OIDC_generate_id_token_rsa (const struct GNUNET_CRYPTO_PublicKey *aud_key, 423OIDC_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 */
488char * 474char *
489OIDC_generate_id_token_hmac (const struct GNUNET_CRYPTO_PublicKey *aud_key, 475OIDC_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 (&params, 0, sizeof(params)); 591 memset (&params, 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 */
766int 753int
767OIDC_parse_authz_code (const struct GNUNET_CRYPTO_PublicKey *audience, 754OIDC_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, &params->ticket, sizeof(params->ticket)); 831 memcpy (ticket, &params->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 */
915char * 900char *
916OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket) 901OIDC_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 */
930int 919int
931OIDC_access_token_parse (const char *token, 920OIDC_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 */
63char * 65char *
64OIDC_generate_id_token_rsa (const struct GNUNET_CRYPTO_PublicKey *aud_key, 66OIDC_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 */
84char* 86char*
85OIDC_generate_id_token_hmac (const struct GNUNET_CRYPTO_PublicKey *aud_key, 87OIDC_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 */
130int 132int
131OIDC_parse_authz_code (const struct GNUNET_CRYPTO_PublicKey *ecdsa_pub, 133OIDC_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 */
158char* 161char*
159OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket); 162OIDC_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 */
164int 168int
165OIDC_access_token_parse (const char *token, 169OIDC_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 */
436static void 437static void
437ticket_collect (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) 438ticket_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
2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3
4if USE_COVERAGE
5 AM_CFLAGS = --coverage -O0
6 XLIB = -lgcov
7endif
8
9libexecdir= $(pkglibdir)/libexec/
10
11pkgcfgdir= $(pkgdatadir)/config.d/
12
13lib_LTLIBRARIES = \
14 libgnunettestbed.la \
15 libgnunettestingtestbed.la
16
17libgnunettestbed_la_SOURCES = \
18 testbed.c
19libgnunettestbed_la_LIBADD = \
20 $(top_builddir)/src/lib/util/libgnunetutil.la
21
22libgnunettestingtestbed_la_SOURCES = \
23 testbed_api_cmd_system_create.c \
24 testing_testbed_traits.c
25libgnunettestingtestbed_la_LIBADD = \
26 libgnunettestbed.la \
27 $(top_builddir)/src/lib/testing/libgnunettesting.la \
28 $(top_builddir)/src/lib/util/libgnunetutil.la
29
30
31bin_PROGRAMS = \
32 gnunet-testbed
33
34gnunet_testbed_SOURCES = \
35 gnunet-testbed.c
36gnunet_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
42check_PROGRAMS = \
43 test_testbed_portreservation
44
45AM_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
49test_testbed_portreservation_SOURCES = \
50 test_testbed_portreservation.c
51test_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 */
37static int ret;
38
39/**
40 * Number of config files to create.
41 */
42static unsigned int create_no;
43
44/**
45 * Filename of the config template to be written.
46 */
47static char *create_cfg_template;
48
49
50static int
51create_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 */
150static void
151run_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 */
181int
182main (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
44run (void *cls, char *const *args, const char *cfgfile, 44run (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
78end: 78end:
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 */
53struct 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
104struct GNUNET_TESTBED_System *
105GNUNET_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
135struct GNUNET_TESTBED_System *
136GNUNET_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
149void
150GNUNET_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
162uint16_t
163GNUNET_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
251void
252GNUNET_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 */
276struct 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 */
322static void
323update_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 */
419static void
420update_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
531enum GNUNET_GenericReturnValue
532GNUNET_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 */
37struct TestSystemState 36struct 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 */
112struct GNUNET_TESTING_Command 107struct GNUNET_TESTING_Command
113GNUNET_TESTING_cmd_system_create (const char *label, 108GNUNET_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
32GNUNET_TRANSPORT_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, GNUNET_TRANSPORT_TESTING) 31
32GNUNET_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
2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3
4if USE_COVERAGE
5 AM_CFLAGS = --coverage -O0
6 XLIB = -lgcov
7endif
8
9libexecdir= $(pkglibdir)/libexec/
10
11pkgcfgdir= $(pkgdatadir)/config.d/
12
13dist_pkgcfg_DATA = \
14 testing.conf
15
16libexec_PROGRAMS = \
17 test_testing_start_with_config \
18 gnunet-cmds-helper
19
20plugindir = $(libdir)/gnunet
21
22lib_LTLIBRARIES = \
23 libgnunettesting.la
24
25gnunet_cmds_helper_SOURCES = \
26 gnunet-cmds-helper.c
27gnunet_cmds_helper_LDADD = $(XLIB) \
28 $(top_builddir)/src/lib/util/libgnunetutil.la \
29 libgnunettesting.la \
30 $(LTLIBINTL) $(Z_LIBS)
31
32libgnunettesting_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
50libgnunettesting_la_LIBADD = \
51 $(top_builddir)/src/service/arm/libgnunetarm.la \
52 $(top_builddir)/src/lib/util/libgnunetutil.la \
53 $(LTLIBINTL)
54libgnunettesting_la_LDFLAGS = \
55 $(GN_LIB_LDFLAGS) \
56 -version-info 2:0:1
57
58bin_PROGRAMS = \
59 gnunet-testing
60
61noinst_PROGRAMS = \
62 list-keys
63
64gnunet_testing_SOURCES = \
65 gnunet-testing.c
66gnunet_testing_LDADD = \
67 libgnunettesting.la \
68 $(top_builddir)/src/lib/util/libgnunetutil.la \
69 $(GN_LIBINTL)
70
71list_keys_SOURCES = \
72 list-keys.c
73list_keys_LDADD = \
74 $(top_builddir)/src/lib/util/libgnunetutil.la \
75 $(GN_LIBINTL)
76
77
78check_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
94test_testing_start_with_config_SOURCES = \
95 test_testing_start_with_config.c
96test_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
101test_testing_portreservation_SOURCES = \
102 test_testing_portreservation.c
103test_testing_portreservation_LDADD = \
104 libgnunettesting.la \
105 $(top_builddir)/src/lib/util/libgnunetutil.la
106
107test_testing_peerstartup_SOURCES = \
108 test_testing_peerstartup.c
109test_testing_peerstartup_LDADD = \
110 libgnunettesting.la \
111 $(top_builddir)/src/lib/util/libgnunetutil.la
112
113test_testing_peerstartup2_SOURCES = \
114 test_testing_peerstartup2.c
115test_testing_peerstartup2_LDADD = \
116 libgnunettesting.la \
117 $(top_builddir)/src/lib/util/libgnunetutil.la
118
119test_testing_servicestartup_SOURCES = \
120 test_testing_servicestartup.c
121test_testing_servicestartup_LDADD = \
122 libgnunettesting.la \
123 $(top_builddir)/src/lib/util/libgnunetutil.la
124
125test_testing_sharedservices_SOURCES = \
126 test_testing_sharedservices.c
127test_testing_sharedservices_LDADD = \
128 libgnunettesting.la \
129 $(top_builddir)/src/lib/util/libgnunetutil.la
130
131EXTRA_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
80struct GNUNET_SCHEDULER_Task *finished_task;
81
82struct GNUNET_TESTING_Interpreter *is;
83
84/**
85 * Struct with information about a specific node and the whole network namespace setup.
86 *
87 */
88struct 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 */
128struct 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
149static struct GNUNET_OS_Process *cmd_binary_process;*/
150
151/**
152 * Plugin to dynamically load a test case.
153 */
154struct TestcasePlugin *plugin;
155
156/**
157 * Our message stream tokenizer
158 */
159struct GNUNET_MessageStreamTokenizer *tokenizer;
160
161/**
162 * Disk handle from stdin
163 */
164static struct GNUNET_DISK_FileHandle *stdin_fd;
165
166/**
167 * Disk handle for stdout
168 */
169static struct GNUNET_DISK_FileHandle *stdout_fd;
170
171/**
172 * Pipe used to communicate shutdown via signal.
173 */
174static struct GNUNET_DISK_PipeHandle *sigpipe;
175
176/**
177 * Task identifier for the read task
178 */
179static struct GNUNET_SCHEDULER_Task *read_task_id;
180
181/**
182 * Task identifier for the write task
183 */
184static struct GNUNET_SCHEDULER_Task *write_task_id;
185
186/**
187 * Are we done reading messages from stdin?
188 */
189static int done_reading;
190
191/**
192 * Result to return in case we fail
193 */
194static int status;
195
196
197/**
198 * Task to shut down cleanly
199 *
200 * @param cls NULL
201 */
202static void
203do_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 */
239static void
240write_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 */
278static void
279write_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
297static void
298delay_shutdown_cb ()
299{
300 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
301 "doing shutdown after delay\n");
302 GNUNET_SCHEDULER_shutdown ();
303}
304
305
306struct GNUNET_MessageHeader *
307GNUNET_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
321static void
322finished_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 */
359static enum GNUNET_GenericReturnValue
360tokenizer_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
505error:
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 */
519static void
520read_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 */
570static void
571run (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 */
599static void
600sighandler_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 */
623int
624main (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 */
37static int ret;
38
39/**
40 * Filename of the hostkey file we should write,
41 * null if we should not write a hostkey file.
42 */
43static char *create_hostkey;
44
45/**
46 * Non-zero if we should create config files.
47 */
48static int create_cfg;
49
50/**
51 * Number of config files to create.
52 */
53static unsigned int create_no;
54
55/**
56 * Filename of the config template to be written.
57 */
58static char *create_cfg_template;
59
60/**
61 * Service we are supposed to run.
62 */
63static char *run_service_name;
64
65/**
66 * File handle to STDIN, for reading restart/quit commands.
67 */
68static struct GNUNET_DISK_FileHandle *fh;
69
70/**
71 * Temporary filename, used with '-r' to write the configuration to.
72 */
73static char *tmpfilename;
74
75/**
76 * Task identifier of the task that waits for stdin.
77 */
78static struct GNUNET_SCHEDULER_Task *tid;
79
80/**
81 * Peer started for '-r'.
82 */
83static struct GNUNET_TESTING_Peer *my_peer;
84
85
86static int
87create_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
172static int
173create_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 */
217static void
218cleanup (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 */
245static void
246stdin_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 */
293static void
294testing_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 */
331static void
332run_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 */
379int
380main (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
5static unsigned int nkeys;
6static unsigned int nskip;
7static 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 */
17static void
18run (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
85int
86main (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]
2GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-testing/
3
4[transport]
5PLUGINS = tcp
6
7[transport-tcp]
8TESTING_IGNORE_KEYS = SOMETHING;KEY1;ACCEPT_FROM;
9
10[transport-tcp]
11BINDTO = 127.0.0.1
12
13[nat]
14DISABLEV6 = YES
15ENABLE_UPNP = NO
16BEHIND_NAT = NO
17ALLOW_NAT = NO
18INTERNAL_ADDRESS = 127.0.0.1
19EXTERNAL_ADDRESS = 127.0.0.1
20USE_LOCALADDR = NO
21
22
23[rps]
24START_ON_DEMAND = NO
25IMMEDIATE_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 */
38int status;
39
40/**
41 * The testing context
42 */
43struct 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 */
67static void
68do_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 */
89static void
90run (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
119end:
120 GNUNET_SCHEDULER_add_now (&do_shutdown, test_ctx);
121 GNUNET_free (emsg);
122}
123
124
125int
126main (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 */
50int status;
51
52/**
53 * The testing context
54 */
55struct 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
86static void
87do_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 */
106static void
107do_shutdown (void *cls);
108
109
110static void
111peer_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 */
138static void
139do_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 */
159static void
160run (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
197end:
198 FAIL_TEST (0);
199 GNUNET_SCHEDULER_add_now (&do_shutdown, test_ctx);
200 GNUNET_free (emsg);
201}
202
203
204int
205main (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 */
38static 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 */
47static void
48test_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 */
62int
63main (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 */
39int status;
40
41/**
42 * The testing context
43 */
44struct 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 */
68static void
69do_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 */
95static void
96run (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
140end:
141 GNUNET_SCHEDULER_add_now (&do_shutdown, test_ctx);
142 GNUNET_free (emsg);
143}
144
145
146int
147main (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]
2GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-testing/
3
4[testbed-logger]
5PORT = 59132
6UNIXPATH = $GNUNET_RUNTIME_DIR/testbed-logger.sock
7DIR = $GNUNET_TMP/testbed-logger
8
9[transport]
10PLUGINS = tcp
11
12[transport-tcp]
13TESTING_IGNORE_KEYS = SOMETHING;KEY1;ACCEPT_FROM;
14
15[transport-tcp]
16BINDTO = 127.0.0.1
17
18[nat]
19DISABLEV6 = YES
20ENABLE_UPNP = NO
21BEHIND_NAT = NO
22ALLOW_NAT = NO
23INTERNAL_ADDRESS = 127.0.0.1
24EXTERNAL_ADDRESS = 127.0.0.1
25USE_LOCALADDR = NO
26
27
28[rps]
29START_ON_DEMAND = NO
30IMMEDIATE_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
34int
35main (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
86struct 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
101struct 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 */
121struct 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 */
194struct 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 */
275static enum GNUNET_GenericReturnValue
276hostkeys_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 */
338static void
339hostkeys_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 */
358static void
359cfg_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 */
391struct GNUNET_TESTING_System *
392GNUNET_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 */
476struct GNUNET_TESTING_System *
477GNUNET_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
492static void
493cleanup_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
508static enum GNUNET_GenericReturnValue
509start_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
535static void
536stop_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 */
556void
557GNUNET_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 */
597uint16_t
598GNUNET_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 */
693void
694GNUNET_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 */
731struct GNUNET_CRYPTO_EddsaPrivateKey *
732GNUNET_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 */
761struct 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 */
807static void
808update_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 */
904static void
905update_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
1010static struct SharedServiceInstance *
1011associate_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 */
1103static int
1104GNUNET_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 */
1166int
1167GNUNET_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 */
1187struct GNUNET_TESTING_Peer *
1188GNUNET_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
1340err_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 */
1358void
1359GNUNET_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 */
1380int
1381GNUNET_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 */
1429int
1430GNUNET_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 */
1461int
1462GNUNET_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 */
1484int
1485GNUNET_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 */
1502static void
1503disconn_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
1524int
1525GNUNET_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 */
1549void
1550GNUNET_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 */
1565void
1566GNUNET_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
1591int
1592GNUNET_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 */
1604struct 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 */
1633static void
1634service_run_main (void *cls)
1635{
1636 struct ServiceContext *sc = cls;
1637
1638 sc->tm (sc->tm_cls, sc->cfg, sc->peer);
1639}
1640
1641
1642int
1643GNUNET_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 */
1733static unsigned int
1734get_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 */
1760static char *
1761get_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 */
1791static char *
1792get_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 */
1825static unsigned int
1826get_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 */
1856static char *
1857get_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 */
1896static struct GNUNET_TESTING_NodeConnection *
1897get_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 */
2005static void
2006node_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 */
2058static int
2059log_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 */
2103static int
2104log_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 */
2118static int
2119log_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*/
2146static void
2147get_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 */
2228struct GNUNET_TESTING_NetjailNode *
2229GNUNET_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 */
2250struct GNUNET_TESTING_NodeConnection *
2251GNUNET_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 */
2275struct GNUNET_PeerIdentity *
2276GNUNET_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
2293int
2294free_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
2325int
2326free_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 */
2346void
2347GNUNET_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
2360unsigned int
2361GNUNET_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 */
2386char *
2387GNUNET_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 */
2446unsigned int
2447GNUNET_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
2477static void
2478parse_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 */
2514struct GNUNET_TESTING_NetjailTopology *
2515GNUNET_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 */
2785struct GNUNET_TESTING_NetjailTopology *
2786GNUNET_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
29GNUNET_NETWORK_STRUCT_BEGIN
30
31/**
32 * Message send to a child loop to inform the child loop about a barrier being advanced.
33 */
34struct 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 */
48struct 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
68struct 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
88GNUNET_NETWORK_STRUCT_END
89
90/**
91 * Handle for a plugin.
92 */
93struct 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
142struct CommandListEntry
143{
144 struct CommandListEntry *next;
145
146 struct CommandListEntry *prev;
147
148 struct GNUNET_TESTING_Command *command;
149};
150
151
152struct 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 */
225bool
226GNUNET_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 */
234bool
235GNUNET_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 */
243struct GNUNET_TESTING_Command *
244GNUNET_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 */
256void
257GNUNET_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 */
268bool
269GNUNET_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 */
277void
278GNUNET_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 */
292void
293GNUNET_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 */
311struct GNUNET_TESTING_NetjailNode *
312GNUNET_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 */
323struct GNUNET_TESTING_Barrier *
324GNUNET_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 */
334void
335GNUNET_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
39struct 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
54void
55GNUNET_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
80bool
81GNUNET_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 */
113static enum GNUNET_GenericReturnValue
114barrier_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 */
136static void
137barrier_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 */
152static void
153barrier_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
164struct GNUNET_TESTING_NetjailNode *
165GNUNET_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
182struct GNUNET_TESTING_Command
183GNUNET_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 */
43struct 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 */
89static void
90barrier_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 */
156static void
157barrier_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 */
174static enum GNUNET_GenericReturnValue
175barrier_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 */
206struct GNUNET_TESTING_Command
207GNUNET_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 */
43static void
44block_until_all_peers_started_cleanup (void *cls)
45{
46 struct BlockState *bs = cls;
47
48 GNUNET_free (bs);
49}
50
51
52static int
53block_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 */
77static void
78block_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 */
105struct GNUNET_TESTING_Command
106GNUNET_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
32struct 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 */
74static void
75exec_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 */
105static void
106child_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 */
136static void
137exec_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
195const struct GNUNET_TESTING_Command
196GNUNET_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 */
44enum GNUNET_GenericReturnValue
45local_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 */
66static void
67local_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 */
79static void
80local_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
97struct GNUNET_TESTING_Command
98GNUNET_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 */
47struct 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 */
73struct 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 */
176struct 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*/
216static void
217netjail_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 */
228static enum GNUNET_GenericReturnValue
229netjail_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 */
258static void
259clear_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
271static void
272send_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
307static void
308send_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
326static void
327send_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
343void
344barrier_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
378void
379barrier_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 */
427static int
428helper_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 */
522static void
523exp_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 */
540static struct GNUNET_TESTING_CommandHelperInit *
541create_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 */
565static void
566start_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 */
821static void
822do_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*/
842static void
843netjail_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 */
892struct GNUNET_TESTING_Command
893GNUNET_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 */
40struct 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 */
72static void
73netjail_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 */
100static void
101child_completed_callback (void *cls,
102 enum GNUNET_OS_ProcessStatusType type,
103 long unsigned int exit_code)
104{
105 struct NetJailState *ns = cls;
106
107 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*/
127static void
128netjail_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
186struct GNUNET_TESTING_Command
187GNUNET_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 */
38struct 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*/
71static void
72stop_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*/
86static void
87stop_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 */
138struct GNUNET_TESTING_Command
139GNUNET_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 */
39struct 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 */
59static enum GNUNET_GenericReturnValue
60send_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 */
73static void
74send_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 */
86static void
87send_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 */
110struct GNUNET_TESTING_Command
111GNUNET_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 */
38struct 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 */
49static void
50system_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 */
70static void
71system_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 */
83static enum GNUNET_GenericReturnValue
84system_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 */
100struct GNUNET_TESTING_Command
101GNUNET_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 */
40struct 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 */
125static const struct GNUNET_TESTING_Command *
126get_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
192const struct GNUNET_TESTING_Command *
193GNUNET_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
203const struct GNUNET_TESTING_Command *
204GNUNET_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
214const struct GNUNET_TESTING_Command *
215GNUNET_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 */
240static void
241clear_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 */
255static void
256send_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 */
293struct 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
307static enum GNUNET_GenericReturnValue
308free_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
334static void
335free_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
353static enum GNUNET_GenericReturnValue
354free_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 */
381static void
382finish_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 */
441static void
442interpreter_run (void *cls);
443
444
445/**
446 * Current command is done, run the next one.
447 */
448static void
449interpreter_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
478void
479GNUNET_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
513void
514GNUNET_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
527void
528GNUNET_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 */
547struct GNUNET_TESTING_Command *
548GNUNET_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 */
560static void
561interpreter_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 */
613static void
614do_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
626struct GNUNET_TESTING_Interpreter *
627GNUNET_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
665struct GNUNET_TESTING_Command
666GNUNET_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
689void
690GNUNET_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
705struct GNUNET_TESTING_Command
706GNUNET_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 */
719struct 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 */
745static void
746handle_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 */
765static void
766loop_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
777int
778GNUNET_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
793void
794GNUNET_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
803struct GNUNET_TESTING_Barrier *
804GNUNET_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 */
827void
828GNUNET_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
850void
851GNUNET_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
33GNUNET_NETWORK_STRUCT_BEGIN
34
35/**
36 * Initialization message for gnunet-cmds-testbed to start cmd binary.
37 */
38struct 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 */
57struct GNUNET_TESTING_CommandHelperReply
58{
59 /**
60 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY
61 */
62 struct GNUNET_MessageHeader header;
63};
64
65struct GNUNET_TESTING_CommandPeerStarted
66{
67 /**
68 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED
69 */
70 struct GNUNET_MessageHeader header;
71};
72
73struct GNUNET_TESTING_CommandAllPeersStarted
74{
75 /**
76 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED
77 */
78 struct GNUNET_MessageHeader header;
79};
80
81struct 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
95struct GNUNET_TESTING_CommandLocalTestPrepared
96{
97 /**
98 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED
99 */
100 struct GNUNET_MessageHeader header;
101};
102
103struct 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
111GNUNET_NETWORK_STRUCT_END
112
113/**
114 * Global state of the interpreter, used by a command
115 * to access information about other commands.
116 */
117struct 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 */
127struct GNUNET_TESTING_Command *
128GNUNET_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 */
138void
139GNUNET_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
3declare -A K_PLUGIN
4declare -A R_TCP
5declare -A R_UDP
6declare -A P_PLUGIN
7
8extract_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
54read_topology(){
55
56local filename=$1
57while 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
95done < $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
15endif 15endif
16 16
17noinst_PROGRAMS = \ 17noinst_PROGRAMS = \
18 test_transport_start_with_config \
19 gnunet-communicator-udp 18 gnunet-communicator-udp
20 19
21TESTING_LIBS = \ 20TESTING_LIBS = \
22 libgnunettransporttesting2.la 21 libgnunettestingtransport.la
23 22
24lib_LTLIBRARIES = \ 23lib_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
31libgnunettransporttesting2_la_SOURCES = \ 30libgnunettestingtransport_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 \ 43libgnunettestingtransport_la_LIBADD = \
45 transport-testing-main2.c \
46 transport-testing-send2.c \
47 transport-testing-communicator.c transport-testing-communicator.h
48libgnunettransporttesting2_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
192plugin_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
200libgnunet_test_transport_plugin_cmd_nat_upnp_la_SOURCES = \ 196libgnunet_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 = \
325endif 321endif
326 322
327 323
328test_transport_start_with_config_SOURCES = \
329 test_transport_start_with_config.c
330test_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
337test_communicator_basic_unix_SOURCES = \ 325test_communicator_basic_unix_SOURCES = \
338 test_communicator_basic.c 326 test_communicator_basic.c
339test_communicator_basic_unix_LDADD = \ 327test_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
347test_communicator_basic_tcp_LDADD = \ 335test_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
355test_communicator_basic_udp_LDADD = \ 343test_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
363test_communicator_basic_quic_LDADD = \ 351test_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
371test_communicator_rekey_tcp_LDADD = \ 359test_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
379test_communicator_rekey_udp_LDADD = \ 367test_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
387test_communicator_backchannel_udp_LDADD = \ 375test_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
395test_communicator_bidirect_tcp_LDADD = \ 383test_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
886static int
887secret_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)
892static void 894static void
893receiver_destroy (struct ReceiverAddress *receiver) 895receiver_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)
1065static void 1076static void
1066sender_destroy (struct SenderAddress *sender) 1077sender_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
920struct TransportGlobalNattedAddress 920struct 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 *
5344get_address_without_port (const char *address); 5347get_address_without_port (const char *address);
5345 5348
5346 5349
5350struct AddGlobalAddressesContext
5351{
5352 size_t off;
5353 char *tgnas;
5354};
5355
5356
5347static enum GNUNET_GenericReturnValue 5357static enum GNUNET_GenericReturnValue
5348add_global_addresses (void *cls, 5358add_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
9610check_flow_control (void *cls, const struct TransportFlowControlMessage *fc) 9621check_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 */
188static struct GNUNET_TESTING_Interpreter * 184void *
189start_testcase (GNUNET_TESTING_cmd_helper_write_cb write_message, 185libgnunet_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/** 314GNUNET_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",
337void * 320 "system-create",
338libgnunet_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
2if ! [ -d "/run/netns" ]; then 2exec 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
4fi 4# exec netjail_test_master.sh gnunet-testing-netjail-launcher test_transport_simple_send_topo.conf
5if [ -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
10fi
11exec 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 */
43static void
44start_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 */
213static void
214start_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 */
237static int
238start_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
270struct GNUNET_TESTING_Command
271GNUNET_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
31GNUNET_TRANSPORT_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT,
32 GNUNET_TRANSPORT_TESTING)
33
34GNUNET_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
108typedef void * 107typedef 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
114struct TestState 112struct 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 */
228struct GNUNET_TESTING_Command 215struct GNUNET_TESTING_Command
229GNUNET_TRANSPORT_cmd_send_simple_performance (const char *label, 216GNUNET_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
269GNUNET_TRANSPORT_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_DECL_SIMPLE_TRAIT, GNUNET_TRANSPORT_TESTING) 256GNUNET_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
1093GNUNET_TRANSPORT_TESTING_transport_communicator_service_stop ( 1096GNUNET_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
313GNUNET_TRANSPORT_TESTING_SIMPLE_TRAITS (GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT, GNUNET_TRANSPORT_TESTING) 314GNUNET_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}