aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/arm/arm_api.c7
-rw-r--r--src/ats-tests/.gitignore14
-rw-r--r--src/ats-tests/Makefile.am169
-rw-r--r--src/ats-tests/ats-testing-experiment.c820
-rw-r--r--src/ats-tests/ats-testing-log.c979
-rw-r--r--src/ats-tests/ats-testing-preferences.c265
-rw-r--r--src/ats-tests/ats-testing-traffic.c393
-rw-r--r--src/ats-tests/ats-testing.c975
-rw-r--r--src/ats-tests/ats-testing.h757
-rw-r--r--src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_prop.conf24
-rw-r--r--src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_prop.exp46
-rw-r--r--src/ats-tests/experiments/send_linear_10_sec.exp30
-rw-r--r--src/ats-tests/experiments/test.exp55
-rw-r--r--src/ats-tests/gnunet-ats-sim.c399
-rw-r--r--src/ats-tests/gnunet-solver-eval.c1025
-rw-r--r--src/ats-tests/gnunet_ats_sim_default.conf6
-rw-r--r--src/ats-tests/perf_ats.c601
-rw-r--r--src/ats-tests/perf_ats.h256
-rw-r--r--src/ats-tests/perf_ats_logging.c780
-rw-r--r--src/ats-tests/perf_ats_proportional_bandwidth.conf4
-rw-r--r--src/ats-tests/perf_ats_proportional_latency.conf4
-rw-r--r--src/ats-tests/perf_ats_proportional_none.conf4
-rw-r--r--src/ats-tests/template_perf_ats.conf52
-rw-r--r--src/block/Makefile.am13
-rw-r--r--src/consensus/Makefile.am1
-rw-r--r--src/conversation/conversation_api.c1
-rw-r--r--src/curl/curl.c51
-rw-r--r--src/datacache/plugin_datacache_postgres.c4
-rw-r--r--src/datacache/plugin_datacache_sqlite.c2
-rw-r--r--src/datastore/datastore_api.c4
-rw-r--r--src/datastore/plugin_datastore_mysql.c2
-rw-r--r--src/datastore/plugin_datastore_postgres.c2
-rw-r--r--src/datastore/plugin_datastore_sqlite.c4
-rw-r--r--src/dht/Makefile.am1
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c12
-rw-r--r--src/dhtu/plugin_dhtu_ip.c67
-rw-r--r--src/dns/Makefile.am6
-rw-r--r--src/fs/Makefile.am5
-rw-r--r--src/gns/gnunet-gns-proxy.c2
-rw-r--r--src/gnsrecord/Makefile.am2
-rw-r--r--src/hostlist/hostlist.conf2
-rw-r--r--src/identity/identity_api.c4
-rw-r--r--src/identity/plugin_rest_identity.c26
-rw-r--r--src/include/Makefile.am2
-rw-r--r--src/include/gnunet_common.h42
-rw-r--r--src/include/gnunet_configuration_lib.h193
-rw-r--r--src/include/gnunet_container_lib.h3
-rw-r--r--src/include/gnunet_curl_lib.h2
-rw-r--r--src/include/gnunet_db_lib.h44
-rw-r--r--src/include/gnunet_disk_lib.h26
-rw-r--r--src/include/gnunet_json_lib.h304
-rw-r--r--src/include/gnunet_messenger_service.h12
-rw-r--r--src/include/gnunet_pq_lib.h125
-rw-r--r--src/include/gnunet_protocols.h7
-rw-r--r--src/include/gnunet_setu_service.h26
-rw-r--r--src/include/gnunet_testbed_ng_service.h284
-rw-r--r--src/include/gnunet_testing_ng_lib.h74
-rw-r--r--src/include/gnunet_testing_plugin.h7
-rw-r--r--src/include/gnunet_util_lib.h3
-rw-r--r--src/include/platform.h34
-rw-r--r--src/json/Makefile.am12
-rw-r--r--src/json/json.c37
-rw-r--r--src/json/json_pack.c325
-rw-r--r--src/messenger/gnunet-messenger.c7
-rw-r--r--src/messenger/gnunet-service-messenger_handle.c32
-rw-r--r--src/messenger/gnunet-service-messenger_member.c1
-rw-r--r--src/messenger/gnunet-service-messenger_room.c1
-rw-r--r--src/namecache/namecache_api.c1
-rw-r--r--src/namestore/Makefile.am4
-rw-r--r--src/namestore/gnunet-namestore-fcfsd.c12
-rw-r--r--src/namestore/plugin_rest_namestore.c6
-rw-r--r--src/namestore/zonefiles/BW7PTMDSN5KS42GMK2VKVE96BAYDS3QVMAS7SC5208FD6HFTAXE0.zkey1
-rw-r--r--src/namestore/zonefiles/CNFGWF0JH0C65M6PQW6VSRR6D3NEZVHAQF6NC037J01TETS6CJ30.zkeybin32 -> 0 bytes
-rw-r--r--src/namestore/zonefiles/KHW2Y5A7X59Z8BC2GHSEQ9WGZ5HWVEF25TBFR3Q5QHCERMVM76DG.zkey1
-rw-r--r--src/namestore/zonefiles/TWY43VS959JJ41KN2FG8782EJ2N0XDF4J6BWASR1BK5BPPRWQJAG.zkey2
-rw-r--r--src/nse/Makefile.am1
-rw-r--r--src/peerinfo-tool/Makefile.am8
-rw-r--r--src/pq/Makefile.am1
-rw-r--r--src/pq/pq.h31
-rw-r--r--src/pq/pq_connect.c84
-rw-r--r--src/pq/pq_event.c320
-rw-r--r--src/pq/test_pq.c129
-rw-r--r--src/reclaim/Makefile.am13
-rw-r--r--src/regex/Makefile.am4
-rw-r--r--src/rest/plugin_rest_config.c14
-rw-r--r--src/revocation/Makefile.am5
-rw-r--r--src/revocation/gnunet-service-revocation.c1
-rw-r--r--src/secretsharing/Makefile.am1
-rw-r--r--src/set/ibf.c2
-rw-r--r--src/set/ibf.h1
-rw-r--r--src/setu/gnunet-service-setu.c2085
-rw-r--r--src/setu/gnunet-service-setu_protocol.h78
-rw-r--r--src/setu/gnunet-service-setu_strata_estimator.c362
-rw-r--r--src/setu/gnunet-service-setu_strata_estimator.h54
-rw-r--r--src/setu/ibf.c290
-rw-r--r--src/setu/ibf.h65
-rw-r--r--src/setu/perf_setu_api.c571
-rw-r--r--src/setu/setu.h49
-rw-r--r--src/setu/setu_api.c40
-rw-r--r--src/setu/test_setu_api.c60
-rw-r--r--src/testbed/Makefile.am59
-rw-r--r--src/testbed/gnunet-cmd.c123
-rw-r--r--src/testbed/testbed_api.h6
-rw-r--r--src/testbed/testbed_api_cmd_controller.c203
-rw-r--r--src/testbed/testbed_api_cmd_peer.c281
-rw-r--r--src/testbed/testbed_api_cmd_peer_store.c60
-rw-r--r--src/testbed/testbed_api_cmd_send_peer_ready.c103
-rw-r--r--src/testbed/testbed_api_cmd_tng_connect.c55
-rw-r--r--src/testbed/testbed_api_cmd_tng_service.c276
-rw-r--r--src/testbed/testbed_api_hosts.c53
-rw-r--r--src/testbed/testbed_helper.h54
-rw-r--r--src/testing/Makefile.am50
-rw-r--r--src/testing/gnunet-cmds-helper.c (renamed from src/testbed/gnunet-cmds-helper.c)205
-rwxr-xr-xsrc/testing/netjail_core.sh (renamed from src/testbed/netjail_core.sh)15
-rwxr-xr-xsrc/testing/netjail_exec.sh (renamed from src/testbed/netjail_exec.sh)4
-rwxr-xr-xsrc/testing/netjail_start.sh (renamed from src/testbed/netjail_start.sh)2
-rwxr-xr-xsrc/testing/netjail_stop.sh (renamed from src/testbed/netjail_stop.sh)2
-rw-r--r--src/testing/test_testing_api_cmd_netjail.c (renamed from src/testbed/test_testbed_api_cmd_netjail.c)21
-rw-r--r--src/testing/test_testing_plugin_testcmd.c (renamed from src/testbed/plugin_testcmd.c)9
-rw-r--r--src/testing/testing_api_cmd_block_until_all_peers_started.c (renamed from src/testbed/testbed_api_cmd_block_until_all_peers_started.c)41
-rw-r--r--src/testing/testing_api_cmd_local_test_finished.c (renamed from src/testbed/testbed_api_cmd_local_test_finished.c)50
-rw-r--r--src/testing/testing_api_cmd_netjail_start.c (renamed from src/testbed/testbed_api_cmd_netjail_start.c)66
-rw-r--r--src/testing/testing_api_cmd_netjail_start_testsystem.c (renamed from src/testbed/testbed_api_cmd_netjail_start_testbed.c)318
-rw-r--r--src/testing/testing_api_cmd_netjail_stop.c (renamed from src/testbed/testbed_api_cmd_netjail_stop.c)64
-rw-r--r--src/testing/testing_api_cmd_netjail_stop_testsystem.c (renamed from src/testbed/testbed_api_cmd_netjail_stop_testbed.c)68
-rw-r--r--src/testing/testing_api_cmd_send_peer_ready.c36
-rw-r--r--src/testing/testing_api_cmd_system_create.c25
-rw-r--r--src/testing/testing_api_cmd_system_destroy.c116
-rw-r--r--src/testing/testing_api_loop.c44
-rw-r--r--src/testing/testing_cmds.h90
-rw-r--r--src/transport/Makefile.am71
-rw-r--r--src/transport/gnunet-communicator-tcp.c32
-rw-r--r--src/transport/plugin_cmd_simple_send.c188
-rw-r--r--src/transport/test_transport_api2_tcp_node1.conf23
-rw-r--r--src/transport/test_transport_api2_tcp_node2.conf22
-rw-r--r--src/transport/test_transport_api_cmd_simple_send.c80
-rw-r--r--src/transport/test_transport_plugin_cmd_simple_send.c248
-rwxr-xr-xsrc/transport/test_transport_simple_send.sh2
-rw-r--r--src/transport/transport-testing-cmds.h81
-rw-r--r--src/transport/transport-testing-ng.h74
-rw-r--r--src/transport/transport-testing2.h37
-rw-r--r--src/transport/transport_api_cmd_connecting_peers.c118
-rw-r--r--src/transport/transport_api_cmd_send_simple.c82
-rw-r--r--src/transport/transport_api_cmd_start_peer.c274
-rw-r--r--src/transport/transport_api_cmd_stop_peer.c163
-rw-r--r--src/util/Makefile.am10
-rw-r--r--src/util/client.c1
-rw-r--r--src/util/common_logging.c4
-rw-r--r--src/util/configuration.c1096
-rw-r--r--src/util/configuration_helper.c302
-rw-r--r--src/util/configuration_loader.c91
-rw-r--r--src/util/crypto_hkdf.c6
-rw-r--r--src/util/disk.c194
-rw-r--r--src/util/gnunet-config.c318
-rw-r--r--src/util/network.c30
-rw-r--r--src/util/os_installation.c2
-rw-r--r--src/util/os_priority.c14
-rw-r--r--src/util/plugin.c6
-rw-r--r--src/util/program.c89
-rw-r--r--src/util/strings.c2
-rw-r--r--src/util/test_plugin.c52
-rw-r--r--src/util/test_plugin_plug.c5
-rw-r--r--src/vpn/Makefile.am5
-rw-r--r--src/vpn/gnunet-helper-vpn.c11
165 files changed, 7947 insertions, 12062 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 5df85f9db..ef8c5b110 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,7 +3,6 @@
3if HAVE_TESTING 3if HAVE_TESTING
4 TESTING = testing 4 TESTING = testing
5 TESTBED = testbed-logger testbed 5 TESTBED = testbed-logger testbed
6 ATS_TESTS = ats-tests
7endif 6endif
8 7
9if HAVE_EXPERIMENTAL 8if HAVE_EXPERIMENTAL
@@ -72,7 +71,6 @@ SUBDIRS = \
72 ats-tool \ 71 ats-tool \
73 core \ 72 core \
74 $(TESTBED) \ 73 $(TESTBED) \
75 $(ATS_TESTS) \
76 nse \ 74 nse \
77 dhtu \ 75 dhtu \
78 dht \ 76 dht \
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c
index afc32fc3a..5fcbfb0a9 100644
--- a/src/arm/arm_api.c
+++ b/src/arm/arm_api.c
@@ -977,9 +977,12 @@ GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h,
977 { 977 {
978 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 978 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
979 "pipe"); 979 "pipe");
980 } else { 980 ret = GNUNET_ARM_RESULT_START_FAILED;
981 }
982 else
983 {
981 wsig = GNUNET_DISK_pipe_detach_end (sig, 984 wsig = GNUNET_DISK_pipe_detach_end (sig,
982 GNUNET_DISK_PIPE_END_WRITE); 985 GNUNET_DISK_PIPE_END_WRITE);
983 ret = start_arm_service (h, 986 ret = start_arm_service (h,
984 std_inheritance, 987 std_inheritance,
985 wsig); 988 wsig);
diff --git a/src/ats-tests/.gitignore b/src/ats-tests/.gitignore
deleted file mode 100644
index 5e15db496..000000000
--- a/src/ats-tests/.gitignore
+++ /dev/null
@@ -1,14 +0,0 @@
1gnunet-solver-eval
2gnunet-ats-sim
3perf_ats_proportional_core_bandwidth
4perf_ats_proportional_core_latency
5perf_ats_proportional_core_none
6perf_ats_proportional_transport_bandwidth
7perf_ats_proportional_transport_latency
8perf_ats_proportional_transport_none
9perf_ats_mlp_core_bandwidth
10perf_ats_mlp_core_latency
11perf_ats_mlp_core_none
12perf_ats_mlp_transport_bandwidth
13perf_ats_mlp_transport_latency
14perf_ats_mlp_transport_none
diff --git a/src/ats-tests/Makefile.am b/src/ats-tests/Makefile.am
deleted file mode 100644
index 543fed287..000000000
--- a/src/ats-tests/Makefile.am
+++ /dev/null
@@ -1,169 +0,0 @@
1#t This Makefile.am is in the public domain
2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3
4pkgcfgdir= $(pkgdatadir)/config.d/
5
6libexecdir= $(pkglibdir)/libexec/
7
8if USE_COVERAGE
9 AM_CFLAGS = -fprofile-arcs -ftest-coverage
10endif
11
12if HAVE_TESTING
13TESTING_TESTS = \
14 perf_ats_proportional_transport_none \
15 perf_ats_proportional_transport_bandwidth \
16 perf_ats_proportional_transport_latency \
17 perf_ats_proportional_core_none \
18 perf_ats_proportional_core_bandwidth \
19 perf_ats_proportional_core_latency \
20 $(PERF_MLP)
21
22endif
23
24lib_LTLIBRARIES = \
25 libgnunetatstesting.la
26
27check_PROGRAMS = \
28 $(TESTING_TESTS)
29
30if ENABLE_TEST_RUN
31AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
32TESTS = $(check_PROGRAMS)
33endif
34
35noinst_PROGRAMS = \
36 gnunet-ats-sim gnunet-solver-eval
37
38libgnunetatstesting_la_SOURCES = \
39 ats-testing.c ats-testing.h \
40 ats-testing-log.c ats-testing-traffic.c \
41 ats-testing-experiment.c ats-testing-preferences.c
42libgnunetatstesting_la_LIBADD = \
43 $(top_builddir)/src/testbed/libgnunettestbed.la \
44 $(top_builddir)/src/testing/libgnunettesting.la \
45 $(top_builddir)/src/statistics/libgnunetstatistics.la \
46 $(top_builddir)/src/core/libgnunetcore.la \
47 $(top_builddir)/src/transport/libgnunettransport.la \
48 $(top_builddir)/src/hello/libgnunethello.la \
49 $(top_builddir)/src/ats/libgnunetats.la \
50 $(top_builddir)/src/arm/libgnunetarm.la \
51 $(top_builddir)/src/util/libgnunetutil.la \
52 $(GN_LIBINTL)
53libgnunetatstesting_la_DEPENDENCIES = \
54 $(top_builddir)/src/testbed/libgnunettestbed.la \
55 $(top_builddir)/src/ats/libgnunetats.la
56libgnunetatstesting_la_LDFLAGS = \
57 $(GN_LIB_LDFLAGS)
58
59gnunet_ats_sim_SOURCES = \
60 gnunet-ats-sim.c
61gnunet_ats_sim_LDADD = \
62 $(top_builddir)/src/util/libgnunetutil.la \
63 $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
64 $(top_builddir)/src/testbed/libgnunettestbed.la \
65 $(top_builddir)/src/ats/libgnunetats.la \
66 $(top_builddir)/src/core/libgnunetcore.la \
67 $(top_builddir)/src/transport/libgnunettransport.la
68gnunet_ats_sim_DEPENDENCIES = \
69 libgnunetatstesting.la \
70 $(top_builddir)/src/util/libgnunetutil.la
71gnunet_ats_sim_LDFLAGS = \
72 $(GN_LIBINTL)
73
74
75gnunet_solver_eval_SOURCES = \
76 gnunet-solver-eval.c
77gnunet_solver_eval_LDADD = \
78 $(top_builddir)/src/util/libgnunetutil.la \
79 $(top_builddir)/src/ats/libgnunetats.la \
80 $(top_builddir)/src/core/libgnunetcore.la \
81 $(top_builddir)/src/transport/libgnunettransport.la
82gnunet_solver_eval_DEPENDENCIES = \
83 $(top_builddir)/src/util/libgnunetutil.la
84gnunet_solver_eval_LDFLAGS = \
85 $(GN_LIBINTL)
86
87perf_ats_proportional_core_none_SOURCES = \
88 perf_ats.c
89perf_ats_proportional_core_none_LDADD = \
90 $(top_builddir)/src/util/libgnunetutil.la \
91 $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
92 $(top_builddir)/src/testbed/libgnunettestbed.la \
93 $(top_builddir)/src/ats/libgnunetats.la \
94 $(top_builddir)/src/core/libgnunetcore.la \
95 $(top_builddir)/src/transport/libgnunettransport.la
96perf_ats_proportional_core_none_DEPENDENCIES = \
97 libgnunetatstesting.la \
98 $(top_builddir)/src/util/libgnunetutil.la
99
100perf_ats_proportional_transport_none_SOURCES = \
101 perf_ats.c
102perf_ats_proportional_transport_none_LDADD = \
103 $(top_builddir)/src/util/libgnunetutil.la \
104 $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
105 $(top_builddir)/src/testbed/libgnunettestbed.la \
106 $(top_builddir)/src/ats/libgnunetats.la \
107 $(top_builddir)/src/core/libgnunetcore.la \
108 $(top_builddir)/src/transport/libgnunettransport.la
109perf_ats_proportional_transport_none_DEPENDENCIES = \
110 libgnunetatstesting.la \
111 $(top_builddir)/src/util/libgnunetutil.la
112
113perf_ats_proportional_core_bandwidth_SOURCES = \
114 perf_ats.c
115perf_ats_proportional_core_bandwidth_LDADD = \
116 $(top_builddir)/src/util/libgnunetutil.la \
117 $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
118 $(top_builddir)/src/testbed/libgnunettestbed.la \
119 $(top_builddir)/src/ats/libgnunetats.la \
120 $(top_builddir)/src/core/libgnunetcore.la \
121 $(top_builddir)/src/transport/libgnunettransport.la
122perf_ats_proportional_core_bandwidth_DEPENDENCIES = \
123 libgnunetatstesting.la \
124 $(top_builddir)/src/util/libgnunetutil.la
125
126perf_ats_proportional_transport_bandwidth_SOURCES = \
127 perf_ats.c
128perf_ats_proportional_transport_bandwidth_LDADD = \
129 $(top_builddir)/src/util/libgnunetutil.la \
130 $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
131 $(top_builddir)/src/testbed/libgnunettestbed.la \
132 $(top_builddir)/src/ats/libgnunetats.la \
133 $(top_builddir)/src/core/libgnunetcore.la \
134 $(top_builddir)/src/transport/libgnunettransport.la
135perf_ats_proportional_transport_bandwidth_DEPENDENCIES = \
136 libgnunetatstesting.la \
137 $(top_builddir)/src/util/libgnunetutil.la
138
139perf_ats_proportional_core_latency_SOURCES = \
140 perf_ats.c
141perf_ats_proportional_core_latency_LDADD = \
142 $(top_builddir)/src/util/libgnunetutil.la \
143 $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
144 $(top_builddir)/src/testbed/libgnunettestbed.la \
145 $(top_builddir)/src/ats/libgnunetats.la \
146 $(top_builddir)/src/core/libgnunetcore.la \
147 $(top_builddir)/src/transport/libgnunettransport.la
148perf_ats_proportional_core_latency_DEPENDENCIES = \
149 libgnunetatstesting.la \
150 $(top_builddir)/src/util/libgnunetutil.la
151
152perf_ats_proportional_transport_latency_SOURCES = \
153 perf_ats.c
154perf_ats_proportional_transport_latency_LDADD = \
155 $(top_builddir)/src/util/libgnunetutil.la \
156 $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
157 $(top_builddir)/src/testbed/libgnunettestbed.la \
158 $(top_builddir)/src/ats/libgnunetats.la \
159 $(top_builddir)/src/core/libgnunetcore.la \
160 $(top_builddir)/src/transport/libgnunettransport.la
161perf_ats_proportional_transport_latency_DEPENDENCIES = \
162 libgnunetatstesting.la \
163 $(top_builddir)/src/util/libgnunetutil.la
164
165EXTRA_DIST = \
166 gnunet_ats_sim_default.conf \
167 perf_ats_proportional_none.conf \
168 perf_ats_proportional_bandwidth.conf \
169 perf_ats_proportional_latency.conf
diff --git a/src/ats-tests/ats-testing-experiment.c b/src/ats-tests/ats-testing-experiment.c
deleted file mode 100644
index 9f8db1be4..000000000
--- a/src/ats-tests/ats-testing-experiment.c
+++ /dev/null
@@ -1,820 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 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 ats-tests/ats-testing-experiment.c
22 * @brief ats benchmark: controlled experiment execution
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "ats-testing.h"
29
30const char *
31print_op (enum OperationType op)
32{
33 switch (op)
34 {
35 case START_SEND:
36 return "START_SEND";
37
38 case STOP_SEND:
39 return "STOP_SEND";
40
41 case START_PREFERENCE:
42 return "START_PREFERENCE";
43
44 case STOP_PREFERENCE:
45 return "STOP_PREFERENCE";
46
47 default:
48 break;
49 }
50 return "";
51}
52
53
54static struct Experiment *
55create_experiment ()
56{
57 struct Experiment *e;
58
59 e = GNUNET_new (struct Experiment);
60 e->name = NULL;
61 e->num_masters = 0;
62 e->num_slaves = 0;
63 e->start = NULL;
64 e->total_duration = GNUNET_TIME_UNIT_ZERO;
65 return e;
66}
67
68
69static void
70free_experiment (struct Experiment *e)
71{
72 struct Episode *cur;
73 struct Episode *next;
74 struct GNUNET_ATS_TEST_Operation *cur_o;
75 struct GNUNET_ATS_TEST_Operation *next_o;
76
77 next = e->start;
78 for (cur = next; NULL != cur; cur = next)
79 {
80 next = cur->next;
81
82 next_o = cur->head;
83 for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
84 {
85 next_o = cur_o->next;
86 GNUNET_free (cur_o);
87 }
88 GNUNET_free (cur);
89 }
90
91 GNUNET_free (e->name);
92 GNUNET_free (e->cfg_file);
93 GNUNET_free (e);
94}
95
96
97static int
98load_episode (struct Experiment *e,
99 struct Episode *cur,
100 struct GNUNET_CONFIGURATION_Handle *cfg)
101{
102 struct GNUNET_ATS_TEST_Operation *o;
103 char *sec_name;
104 char *op_name;
105 char *op;
106 char *type;
107 char *pref;
108 int op_counter = 0;
109
110 fprintf (stderr, "Parsing episode %u\n", cur->id);
111 GNUNET_asprintf (&sec_name, "episode-%u", cur->id);
112
113 while (1)
114 {
115 /* Load operation */
116 GNUNET_asprintf (&op_name, "op-%u-operation", op_counter);
117 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
118 sec_name,
119 op_name, &op))
120 {
121 GNUNET_free (op_name);
122 break;
123 }
124 o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
125 /* operations = set_rate, start_send, stop_send, set_preference */
126 if (0 == strcmp (op, "start_send"))
127 {
128 o->type = START_SEND;
129 }
130 else if (0 == strcmp (op, "stop_send"))
131 {
132 o->type = STOP_SEND;
133 }
134 else if (0 == strcmp (op, "start_preference"))
135 {
136 o->type = START_PREFERENCE;
137 }
138 else if (0 == strcmp (op, "stop_preference"))
139 {
140 o->type = STOP_PREFERENCE;
141 }
142 else
143 {
144 fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
145 op_counter, op, cur->id);
146 GNUNET_free (op);
147 GNUNET_free (op_name);
148 GNUNET_free (o);
149 GNUNET_free (sec_name);
150 return GNUNET_SYSERR;
151 }
152 GNUNET_free (op_name);
153
154 /* Get source */
155 GNUNET_asprintf (&op_name, "op-%u-src", op_counter);
156 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
157 sec_name,
158 op_name,
159 &o->src_id))
160 {
161 fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n",
162 op_counter, op, cur->id);
163 GNUNET_free (op);
164 GNUNET_free (op_name);
165 GNUNET_free (o);
166 GNUNET_free (sec_name);
167 return GNUNET_SYSERR;
168 }
169 if (o->src_id > (e->num_masters - 1))
170 {
171 fprintf (stderr, "Invalid src %llu in operation %u `%s' in episode %u\n",
172 o->src_id, op_counter, op, cur->id);
173 GNUNET_free (op);
174 GNUNET_free (op_name);
175 GNUNET_free (o);
176 GNUNET_free (sec_name);
177 return GNUNET_SYSERR;
178 }
179 GNUNET_free (op_name);
180
181 /* Get destination */
182 GNUNET_asprintf (&op_name, "op-%u-dest", op_counter);
183 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
184 sec_name,
185 op_name,
186 &o->dest_id))
187 {
188 fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n",
189 op_counter, op, cur->id);
190 GNUNET_free (op);
191 GNUNET_free (op_name);
192 GNUNET_free (o);
193 GNUNET_free (sec_name);
194 return GNUNET_SYSERR;
195 }
196 if (o->dest_id > (e->num_slaves - 1))
197 {
198 fprintf (stderr,
199 "Invalid destination %llu in operation %u `%s' in episode %u\n",
200 o->dest_id, op_counter, op, cur->id);
201 GNUNET_free (op);
202 GNUNET_free (op_name);
203 GNUNET_free (o);
204 GNUNET_free (sec_name);
205 return GNUNET_SYSERR;
206 }
207 GNUNET_free (op_name);
208
209 GNUNET_asprintf (&op_name, "op-%u-type", op_counter);
210 if ((GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_string (cfg,
211 sec_name,
212 op_name,
213 &type)) &&
214 (STOP_SEND != o->type) &&
215 (STOP_PREFERENCE != o->type))
216 {
217 /* Load arguments for set_rate, start_send, set_preference */
218 if (0 == strcmp (type, "constant"))
219 {
220 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
221 }
222 else if (0 == strcmp (type, "linear"))
223 {
224 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
225 }
226 else if (0 == strcmp (type, "sinus"))
227 {
228 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
229 }
230 else if (0 == strcmp (type, "random"))
231 {
232 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
233 }
234 else
235 {
236 fprintf (stderr, "Invalid type %u `%s' in episode %u\n",
237 op_counter, op, cur->id);
238 GNUNET_free (type);
239 GNUNET_free (op);
240 GNUNET_free (op_name);
241 GNUNET_free (sec_name);
242 GNUNET_free (o);
243 return GNUNET_SYSERR;
244 }
245 GNUNET_free (op_name);
246
247 /* Get base rate */
248 GNUNET_asprintf (&op_name, "op-%u-base-rate", op_counter);
249 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
250 sec_name,
251 op_name,
252 &o->base_rate))
253 {
254 fprintf (stderr,
255 "Missing base rate in operation %u `%s' in episode %u\n",
256 op_counter, op, cur->id);
257 GNUNET_free (type);
258 GNUNET_free (op);
259 GNUNET_free (op_name);
260 GNUNET_free (sec_name);
261 GNUNET_free (o);
262 return GNUNET_SYSERR;
263 }
264 GNUNET_free (op_name);
265
266 /* Get max rate */
267 GNUNET_asprintf (&op_name, "op-%u-max-rate", op_counter);
268 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
269 sec_name,
270 op_name,
271 &o->max_rate))
272 {
273 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
274 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
275 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
276 {
277 fprintf (stderr,
278 "Missing max rate in operation %u `%s' in episode %u\n",
279 op_counter, op, cur->id);
280 GNUNET_free (type);
281 GNUNET_free (op_name);
282 GNUNET_free (op);
283 GNUNET_free (o);
284 GNUNET_free (sec_name);
285 return GNUNET_SYSERR;
286 }
287 }
288 GNUNET_free (op_name);
289
290 /* Get period */
291 GNUNET_asprintf (&op_name, "op-%u-period", op_counter);
292 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
293 sec_name,
294 op_name,
295 &o->period))
296 {
297 o->period = cur->duration;
298 }
299 GNUNET_free (op_name);
300
301 if (START_PREFERENCE == o->type)
302 {
303 /* Get frequency */
304 GNUNET_asprintf (&op_name, "op-%u-frequency", op_counter);
305 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
306 sec_name,
307 op_name,
308 &o->frequency))
309 {
310 fprintf (stderr,
311 "Missing frequency in operation %u `%s' in episode %u\n",
312 op_counter, op, cur->id);
313 GNUNET_free (type);
314 GNUNET_free (op_name);
315 GNUNET_free (op);
316 GNUNET_free (o);
317 GNUNET_free (sec_name);
318 return GNUNET_SYSERR;
319 }
320 GNUNET_free (op_name);
321
322 /* Get preference */
323 GNUNET_asprintf (&op_name, "op-%u-pref", op_counter);
324 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
325 sec_name,
326 op_name,
327 &pref))
328 {
329 fprintf (stderr,
330 "Missing preference in operation %u `%s' in episode %u\n",
331 op_counter, op, cur->id);
332 GNUNET_free (type);
333 GNUNET_free (op_name);
334 GNUNET_free (op);
335 GNUNET_free (pref);
336 GNUNET_free (o);
337 GNUNET_free (sec_name);
338 return GNUNET_SYSERR;
339 }
340
341 if (0 == strcmp (pref, "bandwidth"))
342 o->pref_type = GNUNET_ATS_PREFERENCE_BANDWIDTH;
343 else if (0 == strcmp (pref, "latency"))
344 o->pref_type = GNUNET_ATS_PREFERENCE_LATENCY;
345 else
346 {
347 fprintf (stderr,
348 "Invalid preference in operation %u `%s' in episode %u\n",
349 op_counter, op, cur->id);
350 GNUNET_free (type);
351 GNUNET_free (op_name);
352 GNUNET_free (op);
353 GNUNET_free (pref);
354 GNUNET_free (o);
355 GNUNET_free (sec_name);
356 return GNUNET_SYSERR;
357 }
358 GNUNET_free (pref);
359 GNUNET_free (op_name);
360 }
361 }
362
363 /* Safety checks */
364 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
365 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
366 {
367 if ((o->max_rate - o->base_rate) > o->base_rate)
368 {
369 /* This will cause an underflow */
370 GNUNET_break (0);
371 }
372 fprintf (stderr,
373 "Selected max rate and base rate cannot be used for desired traffic form!\n");
374 }
375
376 if ((START_SEND == o->type) || (START_PREFERENCE == o->type))
377 fprintf (stderr,
378 "Found operation %u in episode %u: %s [%llu]->[%llu] == %s, %llu -> %llu in %s\n",
379 op_counter, cur->id, print_op (o->type), o->src_id,
380 o->dest_id, (NULL != type) ? type : "",
381 o->base_rate, o->max_rate,
382 GNUNET_STRINGS_relative_time_to_string (o->period, GNUNET_YES));
383 else
384 fprintf (stderr, "Found operation %u in episode %u: %s [%llu]->[%llu]\n",
385 op_counter, cur->id, print_op (o->type), o->src_id, o->dest_id);
386
387 GNUNET_free (type);
388 GNUNET_free (op);
389
390 GNUNET_CONTAINER_DLL_insert (cur->head, cur->tail, o);
391 op_counter++;
392 }
393 GNUNET_free (sec_name);
394
395 return GNUNET_OK;
396}
397
398
399static int
400load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
401{
402 int e_counter = 0;
403 char *sec_name;
404 struct GNUNET_TIME_Relative e_duration;
405 struct Episode *cur;
406 struct Episode *last;
407
408 e_counter = 0;
409 last = NULL;
410 while (1)
411 {
412 GNUNET_asprintf (&sec_name, "episode-%u", e_counter);
413 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
414 sec_name,
415 "duration",
416 &e_duration))
417 {
418 GNUNET_free (sec_name);
419 break;
420 }
421
422 cur = GNUNET_new (struct Episode);
423 cur->duration = e_duration;
424 cur->id = e_counter;
425
426 if (GNUNET_OK != load_episode (e, cur, cfg))
427 {
428 GNUNET_free (sec_name);
429 GNUNET_free (cur);
430 return GNUNET_SYSERR;
431 }
432
433 fprintf (stderr, "Found episode %u with duration %s \n",
434 e_counter,
435 GNUNET_STRINGS_relative_time_to_string (cur->duration,
436 GNUNET_YES));
437
438 /* Update experiment */
439 e->num_episodes++;
440 e->total_duration = GNUNET_TIME_relative_add (e->total_duration,
441 cur->duration);
442 /* Put in linked list */
443 if (NULL == last)
444 e->start = cur;
445 else
446 last->next = cur;
447
448 GNUNET_free (sec_name);
449 e_counter++;
450 last = cur;
451 }
452 return e_counter;
453}
454
455
456static void
457timeout_experiment (void *cls)
458{
459 struct Experiment *e = cls;
460
461 e->experiment_timeout_task = NULL;
462 fprintf (stderr, "Experiment timeout!\n");
463
464 if (NULL != e->episode_timeout_task)
465 {
466 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
467 e->episode_timeout_task = NULL;
468 }
469
470 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration (e->start_time),
471 GNUNET_SYSERR);
472}
473
474
475static void
476enforce_start_send (struct GNUNET_ATS_TEST_Operation *op)
477{
478 struct BenchmarkPeer *peer;
479 struct BenchmarkPartner *partner;
480
481 peer = GNUNET_ATS_TEST_get_peer (op->src_id);
482 if (NULL == peer)
483 {
484 GNUNET_break (0);
485 return;
486 }
487
488 partner = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
489 if (NULL == partner)
490 {
491 GNUNET_break (0);
492 return;
493 }
494
495 fprintf (stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id);
496
497 if (NULL != partner->tg)
498 {
499 fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",
500 op->src_id, op->dest_id);
501 GNUNET_ATS_TEST_generate_traffic_stop (partner->tg);
502 partner->tg = NULL;
503 }
504
505 partner->tg = GNUNET_ATS_TEST_generate_traffic_start (peer, partner,
506 op->gen_type,
507 op->base_rate,
508 op->max_rate,
509 op->period,
510 GNUNET_TIME_UNIT_FOREVER_REL);
511}
512
513
514static void
515enforce_stop_send (struct GNUNET_ATS_TEST_Operation *op)
516{
517 struct BenchmarkPartner *p;
518
519 p = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
520 if (NULL == p)
521 {
522 GNUNET_break (0);
523 return;
524 }
525
526 fprintf (stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id);
527
528 if (NULL != p->tg)
529 {
530 fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",
531 op->src_id, op->dest_id);
532 GNUNET_ATS_TEST_generate_traffic_stop (p->tg);
533 p->tg = NULL;
534 }
535}
536
537
538static void
539enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
540{
541 struct BenchmarkPeer *peer;
542 struct BenchmarkPartner *partner;
543
544 peer = GNUNET_ATS_TEST_get_peer (op->src_id);
545 if (NULL == peer)
546 {
547 GNUNET_break (0);
548 return;
549 }
550
551 partner = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
552 if (NULL == partner)
553 {
554 GNUNET_break (0);
555 return;
556 }
557
558 fprintf (stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id);
559
560 if (NULL != partner->pg)
561 {
562 fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",
563 op->src_id, op->dest_id);
564 GNUNET_ATS_TEST_generate_preferences_stop (partner->pg);
565 partner->pg = NULL;
566 }
567
568 partner->pg = GNUNET_ATS_TEST_generate_preferences_start (peer, partner,
569 op->gen_type,
570 op->base_rate,
571 op->max_rate,
572 op->period,
573 op->frequency,
574 op->pref_type);
575}
576
577
578static void
579enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
580{
581 struct BenchmarkPartner *p;
582
583 p = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
584 if (NULL == p)
585 {
586 GNUNET_break (0);
587 return;
588 }
589
590 fprintf (stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id);
591
592 if (NULL != p->pg)
593 {
594 fprintf (stderr, "Stopping preference between master %llu slave %llu\n",
595 op->src_id, op->dest_id);
596 GNUNET_ATS_TEST_generate_preferences_stop (p->pg);
597 p->pg = NULL;
598 }
599}
600
601
602static void
603enforce_episode (struct Episode *ep)
604{
605 struct GNUNET_ATS_TEST_Operation *cur;
606
607 for (cur = ep->head; NULL != cur; cur = cur->next)
608 {
609 fprintf (stderr, "Enforcing operation: %s [%llu]->[%llu] == %llu\n",
610 print_op (cur->type), cur->src_id, cur->dest_id, cur->base_rate);
611 switch (cur->type)
612 {
613 case START_SEND:
614 enforce_start_send (cur);
615 break;
616
617 case STOP_SEND:
618 enforce_stop_send (cur);
619 break;
620
621 case START_PREFERENCE:
622 enforce_start_preference (cur);
623 break;
624
625 case STOP_PREFERENCE:
626 enforce_stop_preference (cur);
627 break;
628
629 default:
630 break;
631 }
632 }
633}
634
635
636static void
637timeout_episode (void *cls)
638{
639 struct Experiment *e = cls;
640
641 e->episode_timeout_task = NULL;
642 if (NULL != e->ep_done_cb)
643 e->ep_done_cb (e->cur);
644
645 /* Scheduling next */
646 e->cur = e->cur->next;
647 if (NULL == e->cur)
648 {
649 /* done */
650 fprintf (stderr, "Last episode done!\n");
651 if (NULL != e->experiment_timeout_task)
652 {
653 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
654 e->experiment_timeout_task = NULL;
655 }
656 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration (e->start_time),
657 GNUNET_OK);
658 return;
659 }
660
661 fprintf (stderr, "Running episode %u with timeout %s\n",
662 e->cur->id,
663 GNUNET_STRINGS_relative_time_to_string (e->cur->duration,
664 GNUNET_YES));
665 enforce_episode (e->cur);
666
667 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
668 &timeout_episode, e);
669}
670
671
672void
673GNUNET_ATS_TEST_experimentation_run (struct Experiment *e,
674 GNUNET_ATS_TESTING_EpisodeDoneCallback
675 ep_done_cb,
676 GNUNET_ATS_TESTING_ExperimentDoneCallback
677 e_done_cb)
678{
679 fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name,
680 GNUNET_STRINGS_relative_time_to_string (e->max_duration,
681 GNUNET_YES));
682 e->e_done_cb = e_done_cb;
683 e->ep_done_cb = ep_done_cb;
684 e->start_time = GNUNET_TIME_absolute_get ();
685
686 /* Start total time out */
687 e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
688 &timeout_experiment,
689 e);
690
691 /* Start */
692 e->cur = e->start;
693 fprintf (stderr, "Running episode %u with timeout %s\n",
694 e->cur->id,
695 GNUNET_STRINGS_relative_time_to_string (e->cur->duration,
696 GNUNET_YES));
697 enforce_episode (e->cur);
698 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
699 &timeout_episode, e);
700}
701
702
703struct Experiment *
704GNUNET_ATS_TEST_experimentation_load (const char *filename)
705{
706 struct Experiment *e;
707 struct GNUNET_CONFIGURATION_Handle *cfg;
708
709 e = NULL;
710
711 cfg = GNUNET_CONFIGURATION_create ();
712 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
713 {
714 fprintf (stderr, "Failed to load `%s'\n", filename);
715 GNUNET_CONFIGURATION_destroy (cfg);
716 return NULL;
717 }
718
719 e = create_experiment ();
720
721 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, "experiment",
722 "name", &e->name))
723 {
724 fprintf (stderr, "Invalid %s", "name");
725 free_experiment (e);
726 return NULL;
727 }
728 else
729 fprintf (stderr, "Experiment name: `%s'\n", e->name);
730
731 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg,
732 "experiment",
733 "cfg_file",
734 &e->cfg_file))
735 {
736 fprintf (stderr, "Invalid %s", "cfg_file");
737 free_experiment (e);
738 return NULL;
739 }
740 else
741 fprintf (stderr, "Experiment name: `%s'\n", e->cfg_file);
742
743 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg, "experiment",
744 "masters",
745 &e->num_masters))
746 {
747 fprintf (stderr, "Invalid %s", "masters");
748 free_experiment (e);
749 return NULL;
750 }
751 else
752 fprintf (stderr, "Experiment masters: `%llu'\n",
753 e->num_masters);
754
755 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg, "experiment",
756 "slaves",
757 &e->num_slaves))
758 {
759 fprintf (stderr, "Invalid %s", "slaves");
760 free_experiment (e);
761 return NULL;
762 }
763 else
764 fprintf (stderr, "Experiment slaves: `%llu'\n",
765 e->num_slaves);
766
767 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg, "experiment",
768 "log_freq",
769 &e->log_freq))
770 {
771 fprintf (stderr, "Invalid %s", "log_freq");
772 free_experiment (e);
773 return NULL;
774 }
775 else
776 fprintf (stderr, "Experiment logging frequency: `%s'\n",
777 GNUNET_STRINGS_relative_time_to_string (e->log_freq, GNUNET_YES));
778
779 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg, "experiment",
780 "max_duration",
781 &e->max_duration))
782 {
783 fprintf (stderr, "Invalid %s", "max_duration");
784 free_experiment (e);
785 return NULL;
786 }
787 else
788 fprintf (stderr, "Experiment duration: `%s'\n",
789 GNUNET_STRINGS_relative_time_to_string (e->max_duration,
790 GNUNET_YES));
791
792 load_episodes (e, cfg);
793 fprintf (stderr, "Loaded %u episodes with total duration %s\n",
794 e->num_episodes,
795 GNUNET_STRINGS_relative_time_to_string (e->total_duration,
796 GNUNET_YES));
797
798 GNUNET_CONFIGURATION_destroy (cfg);
799 return e;
800}
801
802
803void
804GNUNET_ATS_TEST_experimentation_stop (struct Experiment *e)
805{
806 if (NULL != e->experiment_timeout_task)
807 {
808 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
809 e->experiment_timeout_task = NULL;
810 }
811 if (NULL != e->episode_timeout_task)
812 {
813 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
814 e->episode_timeout_task = NULL;
815 }
816 free_experiment (e);
817}
818
819
820/* end of file ats-testing-experiment.c*/
diff --git a/src/ats-tests/ats-testing-log.c b/src/ats-tests/ats-testing-log.c
deleted file mode 100644
index dfdfa8a80..000000000
--- a/src/ats-tests/ats-testing-log.c
+++ /dev/null
@@ -1,979 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 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 ats-tests/ats-testing-log.c
22 * @brief ats benchmark: logging for performance tests
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "ats-testing.h"
29
30#define THROUGHPUT_TEMPLATE "#!/usr/bin/gnuplot \n" \
31 "set datafile separator ';' \n" \
32 "set title \"Throughput between Master and Slaves\" \n" \
33 "set xlabel \"Time in ms\" \n" \
34 "set ylabel \"Bytes/s\" \n" \
35 "set grid \n"
36
37#define RTT_TEMPLATE "#!/usr/bin/gnuplot \n" \
38 "set datafile separator ';' \n" \
39 "set title \"Application level roundtrip time between Master and Slaves\" \n" \
40 "set xlabel \"Time in ms\" \n" \
41 "set ylabel \"ms\" \n" \
42 "set grid \n"
43
44#define BW_TEMPLATE "#!/usr/bin/gnuplot \n" \
45 "set datafile separator ';' \n" \
46 "set title \"Bandwidth inbound and outbound between Master and Slaves\" \n" \
47 "set xlabel \"Time in ms\" \n" \
48 "set ylabel \"Bytes / s \" \n" \
49 "set grid \n"
50
51#define LOG_ITEMS_TIME 2
52#define LOG_ITEMS_PER_PEER 17
53
54#define LOG_ITEM_BYTES_SENT 1
55#define LOG_ITEM_MSGS_SENT 2
56#define LOG_ITEM_THROUGHPUT_SENT 3
57#define LOG_ITEM_BYTES_RECV 4
58#define LOG_ITEM_MSGS_RECV 5
59#define LOG_ITEM_THROUGHPUT_RECV 6
60#define LOG_ITEM_APP_RTT 7
61#define LOG_ITEM_ATS_BW_IN 8
62#define LOG_ITEM_ATS_BW_OUT 9
63#define LOG_ITEM_ATS_COSTS_LAN 10
64#define LOG_ITEM_ATS_WAN 11
65#define LOG_ITEM_ATS_WLAN 12
66#define LOG_ITEM_ATS_DELAY 13
67#define LOG_ITEM_ATS_DISTANCE 14
68#define LOG_ITEM_ATS_NETWORKTYPE 15
69#define LOG_ITEM_ATS_UTIL_UP 16
70#define LOG_ITEM_ATS_UTIL_DOWN 17
71
72/**
73 * A single logging time step for a partner
74 */
75struct PartnerLoggingTimestep
76{
77 /**
78 * Peer
79 */
80 struct BenchmarkPeer *slave;
81
82 /**
83 * Total number of messages this peer has sent
84 */
85 unsigned int total_messages_sent;
86
87 /**
88 * Total number of bytes this peer has sent
89 */
90 unsigned int total_bytes_sent;
91
92 /**
93 * Total number of messages this peer has received
94 */
95 unsigned int total_messages_received;
96
97 /**
98 * Total number of bytes this peer has received
99 */
100 unsigned int total_bytes_received;
101
102 /**
103 * Total outbound throughput for master in Bytes / s
104 */
105 unsigned int throughput_sent;
106
107 /**
108 * Total inbound throughput for master in Bytes / s
109 */
110 unsigned int throughput_recv;
111
112 /**
113 * Accumulated RTT for all messages
114 */
115 unsigned int total_app_rtt;
116
117 /**
118 * Current application level delay
119 */
120 unsigned int app_rtt;
121
122 /* Current ATS properties */
123
124 unsigned int ats_distance;
125
126 struct GNUNET_TIME_Relative ats_delay;
127
128 uint32_t bandwidth_in;
129
130 uint32_t bandwidth_out;
131
132 uint32_t ats_utilization_out;
133
134 uint32_t ats_utilization_in;
135
136 enum GNUNET_NetworkType ats_network_type;
137
138 double pref_bandwidth;
139 double pref_delay;
140};
141
142
143/**
144 * A single logging time step for a peer
145 */
146struct PeerLoggingTimestep
147{
148 /**
149 * Next in DLL
150 */
151 struct PeerLoggingTimestep *next;
152
153 /**
154 * Prev in DLL
155 */
156 struct PeerLoggingTimestep *prev;
157
158 /**
159 * Logging timestamp
160 */
161 struct GNUNET_TIME_Absolute timestamp;
162
163 /**
164 * Total number of messages this peer has sent
165 */
166 unsigned int total_messages_sent;
167
168 /**
169 * Total number of bytes this peer has sent
170 */
171 unsigned int total_bytes_sent;
172
173 /**
174 * Total number of messages this peer has received
175 */
176 unsigned int total_messages_received;
177
178 /**
179 * Total number of bytes this peer has received
180 */
181 unsigned int total_bytes_received;
182
183 /**
184 * Total outbound throughput for master in Bytes / s
185 */
186 unsigned int total_throughput_send;
187
188 /**
189 * Total inbound throughput for master in Bytes / s
190 */
191 unsigned int total_throughput_recv;
192
193 /**
194 * Logs for slaves
195 */
196 struct PartnerLoggingTimestep *slaves_log;
197};
198
199/**
200 * Entry for a benchmark peer
201 */
202struct LoggingPeer
203{
204 /**
205 * Peer
206 */
207 struct BenchmarkPeer *peer;
208
209 /**
210 * Start time
211 */
212 struct GNUNET_TIME_Absolute start;
213
214 /**
215 * DLL for logging entries: head
216 */
217 struct PeerLoggingTimestep *head;
218
219 /**
220 * DLL for logging entries: tail
221 */
222 struct PeerLoggingTimestep *tail;
223};
224
225struct LoggingHandle
226{
227 /**
228 * Logging task
229 */
230 struct GNUNET_SCHEDULER_Task *log_task;
231
232 /**
233 * Reference to perf_ats' masters
234 */
235 int num_masters;
236 int num_slaves;
237 int running;
238 int verbose;
239 const char *name;
240 struct GNUNET_TIME_Relative frequency;
241
242 /**
243 * Log structure of length num_peers
244 */
245 struct LoggingPeer *lp;
246};
247
248
249static void
250write_throughput_gnuplot_script (char *fn, struct LoggingPeer *lp, char **fs,
251 int slaves)
252{
253 struct GNUNET_DISK_FileHandle *f;
254 char *gfn;
255 char *data;
256 int c_s;
257
258 GNUNET_asprintf (&gfn, "gnuplot_throughput_%s", fn);
259 fprintf (stderr,
260 "Writing throughput plot for master %u and %u slaves to `%s'\n",
261 lp->peer->no, slaves, gfn);
262
263 f = GNUNET_DISK_file_open (gfn,
264 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
265 GNUNET_DISK_PERM_USER_EXEC
266 | GNUNET_DISK_PERM_USER_READ
267 | GNUNET_DISK_PERM_USER_WRITE);
268 if (NULL == f)
269 {
270 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n",
271 gfn);
272 GNUNET_free (gfn);
273 return;
274 }
275
276 /* Write header */
277 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, THROUGHPUT_TEMPLATE,
278 strlen (THROUGHPUT_TEMPLATE)))
279 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
280 "Cannot write data to plot file `%s'\n", gfn);
281
282 /* Write master data */
283 GNUNET_asprintf (&data,
284 "plot '%s' using 2:%u with lines title 'Master %u send total', \\\n" \
285 "'%s' using 2:%u with lines title 'Master %u receive total', \\\n",
286 fn, LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_SENT, lp->peer->no,
287 fn, LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_RECV, lp->peer->no);
288 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, data, strlen (data)))
289 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
290 "Cannot write data to plot file `%s'\n", gfn);
291 GNUNET_free (data);
292
293 for (c_s = 0; c_s < slaves; c_s++)
294 {
295 GNUNET_asprintf (&data,
296 "'%s' using 2:%u with lines title 'Master %u - Slave %u send', \\\n" \
297 "'%s' using 2:%u with lines title 'Master %u - Slave %u receive'%s\n",
298 fs[c_s],
299 LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_SENT,
300 lp->peer->no,
301 lp->peer->partners[c_s].dest->no,
302 fs[c_s],
303 LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_RECV,
304 lp->peer->no,
305 lp->peer->partners[c_s].dest->no,
306 (c_s < lp->peer->num_partners - 1) ? ", \\" :
307 "\n pause -1");
308 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, data, strlen (data)))
309 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
310 "Cannot write data to plot file `%s'\n", gfn);
311 GNUNET_free (data);
312 }
313
314 if (GNUNET_SYSERR == GNUNET_DISK_file_close (f))
315 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
316 "Cannot close gnuplot file `%s'\n", gfn);
317 else
318 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
319 "Data successfully written to plot file `%s'\n", gfn);
320 GNUNET_free (gfn);
321}
322
323
324static void
325write_rtt_gnuplot_script (char *fn, struct LoggingPeer *lp, char **fs, int
326 slaves)
327{
328 struct GNUNET_DISK_FileHandle *f;
329 char *gfn;
330 char *data;
331 int c_s;
332
333 GNUNET_asprintf (&gfn, "gnuplot_rtt_%s", fn);
334 fprintf (stderr, "Writing rtt plot for master %u to `%s'\n",
335 lp->peer->no, gfn);
336
337 f = GNUNET_DISK_file_open (gfn,
338 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
339 GNUNET_DISK_PERM_USER_EXEC
340 | GNUNET_DISK_PERM_USER_READ
341 | GNUNET_DISK_PERM_USER_WRITE);
342 if (NULL == f)
343 {
344 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n",
345 gfn);
346 GNUNET_free (gfn);
347 return;
348 }
349
350 /* Write header */
351 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, RTT_TEMPLATE, strlen (
352 RTT_TEMPLATE)))
353 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
354 "Cannot write data to plot file `%s'\n", gfn);
355
356 for (c_s = 0; c_s < slaves; c_s++)
357 {
358 GNUNET_asprintf (&data,
359 "%s'%s' using 2:%u with lines title 'Master %u - Slave %u '%s\n",
360 (0 == c_s) ? "plot " : "",
361 fs[c_s],
362 LOG_ITEMS_TIME + LOG_ITEM_APP_RTT,
363 lp->peer->no,
364 lp->peer->partners[c_s].dest->no,
365 (c_s < lp->peer->num_partners - 1) ? ", \\" :
366 "\n pause -1");
367 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, data, strlen (data)))
368 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
369 "Cannot write data to plot file `%s'\n", gfn);
370 GNUNET_free (data);
371 }
372
373 if (GNUNET_SYSERR == GNUNET_DISK_file_close (f))
374 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n",
375 gfn);
376 else
377 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
378 "Data successfully written to plot file `%s'\n", gfn);
379 GNUNET_free (gfn);
380}
381
382
383static void
384write_bw_gnuplot_script (char *fn, struct LoggingPeer *lp, char **fs, int
385 slaves)
386{
387 struct GNUNET_DISK_FileHandle *f;
388 char *gfn;
389 char *data;
390 int c_s;
391
392 GNUNET_asprintf (&gfn, "gnuplot_bw_%s", fn);
393 fprintf (stderr, "Writing bandwidth plot for master %u to `%s'\n",
394 lp->peer->no, gfn);
395
396 f = GNUNET_DISK_file_open (gfn,
397 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
398 GNUNET_DISK_PERM_USER_EXEC
399 | GNUNET_DISK_PERM_USER_READ
400 | GNUNET_DISK_PERM_USER_WRITE);
401 if (NULL == f)
402 {
403 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n",
404 gfn);
405 GNUNET_free (gfn);
406 return;
407 }
408
409 /* Write header */
410 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, BW_TEMPLATE, strlen (
411 BW_TEMPLATE)))
412 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
413 "Cannot write data to plot file `%s'\n", gfn);
414
415 for (c_s = 0; c_s < slaves; c_s++)
416 {
417 GNUNET_asprintf (&data, "%s" \
418 "'%s' using 2:%u with lines title 'BW out master %u - Slave %u ', \\\n" \
419 "'%s' using 2:%u with lines title 'BW in master %u - Slave %u '" \
420 "%s\n",
421 (0 == c_s) ? "plot " : "",
422 fs[c_s],
423 LOG_ITEMS_TIME + LOG_ITEM_ATS_BW_OUT,
424 lp->peer->no, c_s,
425 fs[c_s],
426 LOG_ITEMS_TIME + LOG_ITEM_ATS_BW_IN,
427 lp->peer->no, c_s,
428 (c_s < lp->peer->num_partners - 1) ? ", \\" :
429 "\n pause -1");
430 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, data, strlen (data)))
431 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
432 "Cannot write data to plot file `%s'\n", gfn);
433 GNUNET_free (data);
434 }
435
436 if (GNUNET_SYSERR == GNUNET_DISK_file_close (f))
437 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n",
438 gfn);
439 else
440 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
441 "Data successfully written to plot file `%s'\n", gfn);
442 GNUNET_free (gfn);
443}
444
445
446void
447GNUNET_ATS_TEST_logging_write_to_file (struct LoggingHandle *l,
448 const char *experiment_name,
449 int plots)
450{
451 struct GNUNET_DISK_FileHandle *f[l->num_slaves];
452 struct GNUNET_DISK_FileHandle *f_m;
453 const char *tmp_exp_name;
454 char *filename_master;
455 char *filename_slaves[l->num_slaves];
456 char *data;
457 struct PeerLoggingTimestep *cur_lt;
458 struct PartnerLoggingTimestep *plt;
459 struct GNUNET_TIME_Absolute timestamp;
460 int c_m;
461 int c_s;
462
463
464 timestamp = GNUNET_TIME_absolute_get ();
465
466 tmp_exp_name = experiment_name;
467 for (c_m = 0; c_m < l->num_masters; c_m++)
468 {
469 GNUNET_asprintf (&filename_master, "%s_%llu_master%u_%s",
470 experiment_name,
471 (unsigned long long) timestamp.abs_value_us, c_m, l->name);
472 fprintf (stderr, "Writing data for master %u to file `%s'\n",
473 c_m, filename_master);
474
475 f_m = GNUNET_DISK_file_open (filename_master,
476 GNUNET_DISK_OPEN_WRITE
477 | GNUNET_DISK_OPEN_CREATE,
478 GNUNET_DISK_PERM_USER_READ
479 | GNUNET_DISK_PERM_USER_WRITE);
480 if (NULL == f_m)
481 {
482 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n",
483 filename_master);
484 GNUNET_free (filename_master);
485 return;
486 }
487
488 GNUNET_asprintf (&data, "# master %u; experiment : %s\n"
489 "timestamp; timestamp delta; #messages sent; #bytes sent; #throughput sent; #messages received; #bytes received; #throughput received; \n",
490 c_m, experiment_name);
491 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f_m, data, strlen (data)))
492 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
493 "Cannot write data to log file `%s'\n", filename_master);
494 GNUNET_free (data);
495
496 for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++)
497 {
498 GNUNET_asprintf (&filename_slaves[c_s], "%s_%llu_master%u_slave_%u_%s",
499 tmp_exp_name,
500 (unsigned long long) timestamp.abs_value_us,
501 c_m, c_s, l->name);
502
503 fprintf (stderr, "Writing data for master %u slave %u to file `%s'\n",
504 c_m, c_s, filename_slaves[c_s]);
505
506 f[c_s] = GNUNET_DISK_file_open (filename_slaves[c_s],
507 GNUNET_DISK_OPEN_WRITE
508 | GNUNET_DISK_OPEN_CREATE,
509 GNUNET_DISK_PERM_USER_READ
510 | GNUNET_DISK_PERM_USER_WRITE);
511 if (NULL == f[c_s])
512 {
513 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n",
514 filename_slaves[c_s]);
515 GNUNET_free (filename_slaves[c_s]);
516 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (f_m));
517 GNUNET_free (filename_master);
518 return;
519 }
520
521 /* Header */
522 GNUNET_asprintf (&data, "# master %u; slave %u ; experiment : %s\n"
523 "timestamp; timestamp delta; #messages sent; #bytes sent; #throughput sent; #messages received; #bytes received; #throughput received; " \
524 "rtt; bw in; bw out; ats_cost_lan; ats_cost_wlan; ats_delay; ats_distance; ats_network_type; ats_utilization_up ;ats_utilization_down;" \
525 "pref bandwidth; pref delay\n",
526 c_m, c_s, experiment_name);
527 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f[c_s], data, strlen (data)))
528 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
529 "Cannot write data to log file `%s'\n",
530 filename_slaves[c_s]);
531 GNUNET_free (data);
532 }
533
534 for (cur_lt = l->lp[c_m].head; NULL != cur_lt; cur_lt = cur_lt->next)
535 {
536 if (l->verbose)
537 fprintf (stderr,
538 "Master [%u]: timestamp %llu %llu ; %u %u %u ; %u %u %u\n",
539 l->lp[c_m].peer->no,
540 (long long unsigned int) cur_lt->timestamp.abs_value_us,
541 (long long unsigned int) GNUNET_TIME_absolute_get_difference (
542 l->lp[c_m].start,
543 cur_lt
544 ->timestamp).rel_value_us / 1000,
545 cur_lt->total_messages_sent,
546 cur_lt->total_bytes_sent,
547 cur_lt->total_throughput_send,
548 cur_lt->total_messages_received,
549 cur_lt->total_bytes_received,
550 cur_lt->total_throughput_recv);
551
552 /* Assembling master string */
553 GNUNET_asprintf (&data, "%llu;%llu;%u;%u;%u;%u;%u;%u;\n",
554 (long long unsigned int) cur_lt->timestamp.abs_value_us,
555 (long long unsigned
556 int) GNUNET_TIME_absolute_get_difference (
557 l->lp[c_m].start,
558 cur_lt
559 ->timestamp).
560 rel_value_us / 1000,
561 cur_lt->total_messages_sent,
562 cur_lt->total_bytes_sent,
563 cur_lt->total_throughput_send,
564 cur_lt->total_messages_received,
565 cur_lt->total_bytes_received,
566 cur_lt->total_throughput_recv);
567
568 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f_m, data, strlen (data)))
569 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
570 "Cannot write data to master file %u\n", c_m);
571 GNUNET_free (data);
572
573
574 for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++)
575 {
576 plt = &cur_lt->slaves_log[c_s];
577 /* Log partners */
578
579 /* Assembling slave string */
580 GNUNET_asprintf (&data,
581 "%llu;%llu;%u;%u;%u;%u;%u;%u;%.3f;%u;%u;%llu;%u;%u;%u;%u;%.3f;%.3f\n",
582 (long long unsigned
583 int) cur_lt->timestamp.abs_value_us,
584 (long long unsigned
585 int) GNUNET_TIME_absolute_get_difference (
586 l->lp[c_m].start,
587 cur_lt
588 ->timestamp)
589 .rel_value_us / 1000,
590 plt->total_messages_sent,
591 plt->total_bytes_sent,
592 plt->throughput_sent,
593 plt->total_messages_received,
594 plt->total_bytes_received,
595 plt->throughput_recv,
596 (double) plt->app_rtt / 1000,
597 plt->bandwidth_in,
598 plt->bandwidth_out,
599 (unsigned long long) plt->ats_delay.rel_value_us,
600 plt->ats_distance,
601 plt->ats_network_type,
602 plt->ats_utilization_out,
603 plt->ats_utilization_in,
604 plt->pref_bandwidth,
605 plt->pref_delay);
606
607 if (l->verbose)
608 fprintf (stderr,
609 "\t Slave [%u]: %u %u %u ; %u %u %u rtt %u delay %llu bw_in %u bw_out %u \n",
610 plt->slave->no,
611 plt->total_messages_sent,
612 plt->total_bytes_sent,
613 plt->throughput_sent,
614 plt->total_messages_received,
615 plt->total_bytes_received,
616 plt->throughput_recv,
617 plt->app_rtt,
618 (long long unsigned int) plt->ats_delay.rel_value_us,
619 plt->bandwidth_in,
620 plt->bandwidth_out);
621
622 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f[c_s], data, strlen (
623 data)))
624 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
625 "Cannot write data to log file `%s'\n",
626 filename_slaves[c_s]);
627 GNUNET_free (data);
628 }
629 }
630
631 for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++)
632 {
633 if (GNUNET_SYSERR == GNUNET_DISK_file_close (f[c_s]))
634 {
635 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
636 "Cannot close log file for master[%u] slave[%u]\n", c_m,
637 c_s);
638 continue;
639 }
640 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
641 "Data file successfully written to log file for `%s'\n",
642 filename_slaves[c_s]);
643 }
644
645 if (GNUNET_SYSERR == GNUNET_DISK_file_close (f_m))
646 {
647 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
648 "close",
649 filename_master);
650 GNUNET_free (filename_master);
651 return;
652 }
653 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
654 "Data file successfully written to log file for master `%s'\n",
655 filename_master);
656
657 if (GNUNET_YES == plots)
658 {
659 write_throughput_gnuplot_script (filename_master, &l->lp[c_m],
660 filename_slaves, l->num_slaves);
661 write_rtt_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves,
662 l->num_slaves);
663 write_bw_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves,
664 l->num_slaves);
665 }
666 }
667 GNUNET_free (filename_master);
668}
669
670
671/**
672 * Log all data now
673 *
674 * @param l logging handle to use
675 */
676void
677GNUNET_ATS_TEST_logging_now (struct LoggingHandle *l)
678{
679 struct LoggingPeer *bp;
680 struct PeerLoggingTimestep *mlt;
681 struct PeerLoggingTimestep *prev_log_mlt;
682 struct PartnerLoggingTimestep *slt;
683 struct PartnerLoggingTimestep *prev_log_slt;
684 struct BenchmarkPartner *p;
685 struct GNUNET_TIME_Relative delta;
686 int c_s;
687 int c_m;
688 unsigned int app_rtt;
689 double mult;
690
691 if (GNUNET_YES != l->running)
692 return;
693
694 for (c_m = 0; c_m < l->num_masters; c_m++)
695 {
696 bp = &l->lp[c_m];
697 mlt = GNUNET_new (struct PeerLoggingTimestep);
698 GNUNET_CONTAINER_DLL_insert_tail (l->lp[c_m].head, l->lp[c_m].tail, mlt);
699 prev_log_mlt = mlt->prev;
700
701 /* Collect data */
702 /* Current master state */
703 mlt->timestamp = GNUNET_TIME_absolute_get ();
704 mlt->total_bytes_sent = bp->peer->total_bytes_sent;
705 mlt->total_messages_sent = bp->peer->total_messages_sent;
706 mlt->total_bytes_received = bp->peer->total_bytes_received;
707 mlt->total_messages_received = bp->peer->total_messages_received;
708
709 /* Throughput */
710 if (NULL == prev_log_mlt)
711 {
712 /* Get difference to start */
713 delta = GNUNET_TIME_absolute_get_difference (l->lp[c_m].start,
714 mlt->timestamp);
715 }
716 else
717 {
718 /* Get difference to last timestep */
719 delta = GNUNET_TIME_absolute_get_difference (mlt->prev->timestamp,
720 mlt->timestamp);
721 }
722
723 /* Multiplication factor for throughput calculation */
724 mult = (double) GNUNET_TIME_UNIT_SECONDS.rel_value_us
725 / (delta.rel_value_us);
726
727 /* Total throughput */
728 if (NULL != prev_log_mlt)
729 {
730 if (mlt->total_bytes_sent - mlt->prev->total_bytes_sent > 0)
731 {
732 mlt->total_throughput_send = mult * (mlt->total_bytes_sent
733 - mlt->prev->total_bytes_sent);
734 }
735 else
736 {
737 mlt->total_throughput_send = 0;
738 // mlt->total_throughput_send = prev_log_mlt->total_throughput_send; /* no msgs send */
739 }
740
741 if (mlt->total_bytes_received - mlt->prev->total_bytes_received > 0)
742 {
743 mlt->total_throughput_recv = mult * (mlt->total_bytes_received
744 - mlt->prev->total_bytes_received);
745 }
746 else
747 {
748 mlt->total_throughput_recv = 0;
749 // mlt->total_throughput_recv = prev_log_mlt->total_throughput_recv; /* no msgs received */
750 }
751 }
752 else
753 {
754 mlt->total_throughput_send = mult * mlt->total_bytes_sent;
755 mlt->total_throughput_recv = mult * mlt->total_bytes_received;
756 }
757
758 if (GNUNET_YES == l->verbose)
759 {
760 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
761 "Master[%u] delta: %llu us, bytes (sent/received): %u / %u; throughput send/recv: %u / %u\n",
762 c_m,
763 (unsigned long long) delta.rel_value_us,
764 mlt->total_bytes_sent,
765 mlt->total_bytes_received,
766 mlt->total_throughput_send,
767 mlt->total_throughput_recv);
768 }
769
770 mlt->slaves_log = GNUNET_malloc (bp->peer->num_partners
771 * sizeof(struct PartnerLoggingTimestep));
772
773 for (c_s = 0; c_s < bp->peer->num_partners; c_s++)
774 {
775 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
776 "Collect logging data master[%u] slave [%u]\n", c_m, c_s);
777
778 p = &bp->peer->partners[c_s];
779 slt = &mlt->slaves_log[c_s];
780
781 slt->slave = p->dest;
782 /* Bytes sent from master to this slave */
783 slt->total_bytes_sent = p->bytes_sent;
784 /* Messages sent from master to this slave */
785 slt->total_messages_sent = p->messages_sent;
786 /* Bytes master received from this slave */
787 slt->total_bytes_received = p->bytes_received;
788 /* Messages master received from this slave */
789 slt->total_messages_received = p->messages_received;
790 slt->total_app_rtt = p->total_app_rtt;
791 /* ats performance information */
792 slt->ats_delay = p->props.delay;
793 slt->ats_distance = p->props.distance;
794 slt->ats_network_type = p->props.scope;
795 slt->ats_utilization_in = p->props.utilization_out;
796 slt->ats_utilization_out = p->props.utilization_out;
797 slt->bandwidth_in = p->bandwidth_in;
798 slt->bandwidth_out = p->bandwidth_out;
799 slt->pref_bandwidth = p->pref_bandwidth;
800 slt->pref_delay = p->pref_delay;
801
802 /* Total application level rtt */
803 if (NULL == prev_log_mlt)
804 {
805 if (0 != slt->total_messages_sent)
806 app_rtt = slt->total_app_rtt / slt->total_messages_sent;
807 else
808 app_rtt = 0;
809 }
810 else
811 {
812 prev_log_slt = &prev_log_mlt->slaves_log[c_s];
813 if ((slt->total_messages_sent - prev_log_slt->total_messages_sent) > 0)
814 app_rtt = (slt->total_app_rtt - prev_log_slt->total_app_rtt)
815 / (slt->total_messages_sent
816 - prev_log_slt->total_messages_sent);
817 else
818 {
819 app_rtt = prev_log_slt->app_rtt; /* No messages were */
820 }
821 }
822 slt->app_rtt = app_rtt;
823
824 /* Partner throughput */
825 if (NULL != prev_log_mlt)
826 {
827 prev_log_slt = &prev_log_mlt->slaves_log[c_s];
828 if (slt->total_bytes_sent > prev_log_slt->total_bytes_sent)
829 slt->throughput_sent = mult * (slt->total_bytes_sent
830 - prev_log_slt->total_bytes_sent);
831 else
832 slt->throughput_sent = 0;
833
834 if (slt->total_bytes_received > prev_log_slt->total_bytes_received)
835 slt->throughput_recv = mult
836 * (slt->total_bytes_received
837 - prev_log_slt->total_bytes_received);
838 else
839 slt->throughput_recv = 0;
840 }
841 else
842 {
843 slt->throughput_sent = mult * slt->total_bytes_sent;
844 slt->throughput_recv = mult * slt->total_bytes_received;
845 }
846
847 if (GNUNET_YES == l->verbose)
848 {
849 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
850 "Master [%u] -> Slave [%u]: delta: %llu us, bytes (sent/received): %u / %u; throughput send/recv: %u / %u\n",
851 c_m, c_s,
852 (unsigned long long) delta.rel_value_us,
853 mlt->total_bytes_sent,
854 mlt->total_bytes_received,
855 slt->throughput_sent,
856 slt->throughput_recv);
857 }
858 else
859 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
860 "Master [%u]: slave [%u]\n",
861 bp->peer->no, p->dest->no);
862 }
863 }
864}
865
866
867static void
868collect_log_task (void *cls)
869{
870 struct LoggingHandle *l = cls;
871
872 l->log_task = NULL;
873 GNUNET_ATS_TEST_logging_now (l);
874 l->log_task = GNUNET_SCHEDULER_add_delayed (l->frequency,
875 &collect_log_task,
876 l);
877}
878
879
880/**
881 * Stop logging
882 *
883 * @param l the logging handle
884 */
885void
886GNUNET_ATS_TEST_logging_stop (struct LoggingHandle *l)
887{
888 if (GNUNET_YES != l->running)
889 return;
890
891 if (NULL != l->log_task)
892 {
893 GNUNET_SCHEDULER_cancel (l->log_task);
894 l->log_task = NULL;
895 }
896 l->running = GNUNET_NO;
897
898 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
899 _ ("Stop logging\n"));
900}
901
902
903/**
904 * Clean up logging data
905 *
906 * @param l the logging handle
907 */
908void
909GNUNET_ATS_TEST_logging_clean_up (struct LoggingHandle *l)
910{
911 int c_m;
912 struct PeerLoggingTimestep *cur;
913
914 if (GNUNET_YES == l->running)
915 GNUNET_ATS_TEST_logging_stop (l);
916
917 for (c_m = 0; c_m < l->num_masters; c_m++)
918 {
919 while (NULL != (cur = l->lp[c_m].head))
920 {
921 GNUNET_CONTAINER_DLL_remove (l->lp[c_m].head, l->lp[c_m].tail, cur);
922 GNUNET_free (cur->slaves_log);
923 GNUNET_free (cur);
924 }
925 }
926
927 GNUNET_free (l->lp);
928 GNUNET_free (l);
929}
930
931
932/**
933 * Start logging
934 *
935 * @param log_frequency the logging frequency
936 * @param testname the testname
937 * @param masters the master peers used for benchmarking
938 * @param num_masters the number of master peers
939 * @param num_slaves the number of slave peers
940 * @param verbose verbose logging
941 * @return the logging handle or NULL on error
942 */
943struct LoggingHandle *
944GNUNET_ATS_TEST_logging_start (struct GNUNET_TIME_Relative log_frequency,
945 const char *testname,
946 struct BenchmarkPeer *masters,
947 int num_masters,
948 int num_slaves,
949 int verbose)
950{
951 struct LoggingHandle *l;
952 int c_m;
953
954 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
955 _ ("Start logging `%s'\n"), testname);
956
957 l = GNUNET_new (struct LoggingHandle);
958 l->num_masters = num_masters;
959 l->num_slaves = num_slaves;
960 l->name = testname;
961 l->frequency = log_frequency;
962 l->verbose = verbose;
963 l->lp = GNUNET_malloc (num_masters * sizeof(struct LoggingPeer));
964
965 for (c_m = 0; c_m < num_masters; c_m++)
966 {
967 l->lp[c_m].peer = &masters[c_m];
968 l->lp[c_m].start = GNUNET_TIME_absolute_get ();
969 }
970
971 /* Schedule logging task */
972 l->log_task = GNUNET_SCHEDULER_add_now (&collect_log_task, l);
973 l->running = GNUNET_YES;
974
975 return l;
976}
977
978
979/* end of file ats-testing-log.c */
diff --git a/src/ats-tests/ats-testing-preferences.c b/src/ats-tests/ats-testing-preferences.c
deleted file mode 100644
index f30fde960..000000000
--- a/src/ats-tests/ats-testing-preferences.c
+++ /dev/null
@@ -1,265 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 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 ats-tests/ats-testing-preferences.c
22 * @brief ats benchmark: preference generator
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "ats-testing.h"
29
30static struct PreferenceGenerator *pg_head;
31static struct PreferenceGenerator *pg_tail;
32
33extern struct GNUNET_ATS_TEST_Topology *top;
34
35static double
36get_preference (struct PreferenceGenerator *pg)
37{
38 struct GNUNET_TIME_Relative time_delta;
39 double delta_value;
40 double pref_value;
41
42 /* Calculate the current preference value */
43 switch (pg->type)
44 {
45 case GNUNET_ATS_TEST_TG_CONSTANT:
46 pref_value = pg->base_value;
47 break;
48
49 case GNUNET_ATS_TEST_TG_LINEAR:
50 time_delta = GNUNET_TIME_absolute_get_duration (pg->time_start);
51 /* Calculate point of time in the current period */
52 time_delta.rel_value_us = time_delta.rel_value_us
53 % pg->duration_period.rel_value_us;
54 delta_value = ((double) time_delta.rel_value_us
55 / pg->duration_period.rel_value_us) * (pg->max_value
56 - pg->base_value);
57 if ((pg->max_value < pg->base_value) &&
58 ((pg->max_value - pg->base_value) > pg->base_value))
59 {
60 /* This will cause an underflow */
61 GNUNET_break (0);
62 }
63 pref_value = pg->base_value + delta_value;
64 break;
65
66 case GNUNET_ATS_TEST_TG_RANDOM:
67 delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
68 10000 * (pg->max_value
69 - pg->base_value))
70 / 10000;
71 pref_value = pg->base_value + delta_value;
72 break;
73
74 case GNUNET_ATS_TEST_TG_SINUS:
75 time_delta = GNUNET_TIME_absolute_get_duration (pg->time_start);
76 /* Calculate point of time in the current period */
77 time_delta.rel_value_us = time_delta.rel_value_us
78 % pg->duration_period.rel_value_us;
79 if ((pg->max_value - pg->base_value) > pg->base_value)
80 {
81 /* This will cause an underflow for second half of sinus period,
82 * will be detected in general when experiments are loaded */
83 GNUNET_break (0);
84 }
85 delta_value = (pg->max_value - pg->base_value)
86 * sin ((2 * M_PI)
87 / ((double) pg->duration_period.rel_value_us)
88 * time_delta.rel_value_us);
89 pref_value = pg->base_value + delta_value;
90 break;
91
92 default:
93 pref_value = 0.0;
94 break;
95 }
96 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current preference value is %f\n",
97 pref_value);
98 return pref_value;
99}
100
101
102static void
103set_pref_task (void *cls)
104{
105 struct BenchmarkPartner *p = cls;
106 double pref_value;
107
108 p->pg->set_task = NULL;
109
110 pref_value = get_preference (p->pg);
111
112 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
113 "Setting preference for master [%u] and slave [%u] for %s to %f\n",
114 p->me->no, p->dest->no,
115 GNUNET_ATS_print_preference_type (p->pg->kind), pref_value);
116
117 GNUNET_ATS_performance_change_preference (p->me->ats_perf_handle,
118 &p->dest->id,
119 p->pg->kind,
120 pref_value,
121 GNUNET_ATS_PREFERENCE_END);
122
123 switch (p->pg->kind)
124 {
125 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
126 p->pref_bandwidth = pref_value;
127 break;
128
129 case GNUNET_ATS_PREFERENCE_LATENCY:
130 p->pref_delay = pref_value;
131 break;
132
133 default:
134 break;
135 }
136
137 p->pg->set_task = GNUNET_SCHEDULER_add_delayed (p->pg->frequency,
138 set_pref_task, p);
139}
140
141
142/**
143 * Generate between the source master and the partner and set preferences with a
144 * value depending on the generator.
145 *
146 * @param src source
147 * @param dest partner
148 * @param type type of preferences to generate
149 * @param base_value traffic base rate to send data with
150 * @param value_rate traffic maximum rate to send data with
151 * @param period duration of a period of preferences generation (~ 1/frequency)
152 * @param frequency how long to generate preferences
153 * @param kind ATS preference to generate
154 * @return the preference generator
155 */
156struct PreferenceGenerator *
157GNUNET_ATS_TEST_generate_preferences_start (struct BenchmarkPeer *src,
158 struct BenchmarkPartner *dest,
159 enum GeneratorType type,
160 unsigned int base_value,
161 unsigned int value_rate,
162 struct GNUNET_TIME_Relative period,
163 struct GNUNET_TIME_Relative
164 frequency,
165 enum GNUNET_ATS_PreferenceKind kind)
166{
167 struct PreferenceGenerator *pg;
168
169 if (NULL != dest->pg)
170 {
171 GNUNET_break (0);
172 return NULL;
173 }
174
175 pg = GNUNET_new (struct PreferenceGenerator);
176 GNUNET_CONTAINER_DLL_insert (pg_head, pg_tail, pg);
177 pg->type = type;
178 pg->src = src;
179 pg->dest = dest;
180 pg->kind = kind;
181 pg->base_value = base_value;
182 pg->max_value = value_rate;
183 pg->duration_period = period;
184 pg->frequency = frequency;
185 pg->time_start = GNUNET_TIME_absolute_get ();
186
187 switch (type)
188 {
189 case GNUNET_ATS_TEST_TG_CONSTANT:
190 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
191 "Setting up constant preference generator master[%u] `%s' and slave [%u] `%s' max %u Bips\n",
192 dest->me->no, GNUNET_i2s (&dest->me->id),
193 dest->dest->no, GNUNET_i2s (&dest->dest->id),
194 base_value);
195 break;
196
197 case GNUNET_ATS_TEST_TG_LINEAR:
198 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
199 "Setting up linear preference generator master[%u] `%s' and slave [%u] `%s' min %u Bips max %u Bips\n",
200 dest->me->no, GNUNET_i2s (&dest->me->id),
201 dest->dest->no, GNUNET_i2s (&dest->dest->id),
202 base_value, value_rate);
203 break;
204
205 case GNUNET_ATS_TEST_TG_SINUS:
206 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
207 "Setting up sinus preference generator master[%u] `%s' and slave [%u] `%s' baserate %u Bips, amplitude %u Bps\n",
208 dest->me->no, GNUNET_i2s (&dest->me->id),
209 dest->dest->no, GNUNET_i2s (&dest->dest->id),
210 base_value, value_rate);
211 break;
212
213 case GNUNET_ATS_TEST_TG_RANDOM:
214 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
215 "Setting up random preference generator master[%u] `%s' and slave [%u] `%s' min %u Bips max %u Bps\n",
216 dest->me->no, GNUNET_i2s (&dest->me->id),
217 dest->dest->no, GNUNET_i2s (&dest->dest->id),
218 base_value, value_rate);
219 break;
220
221 default:
222 break;
223 }
224
225 dest->pg = pg;
226 pg->set_task = GNUNET_SCHEDULER_add_now (&set_pref_task, dest);
227 return pg;
228}
229
230
231void
232GNUNET_ATS_TEST_generate_preferences_stop (struct PreferenceGenerator *pg)
233{
234 GNUNET_CONTAINER_DLL_remove (pg_head, pg_tail, pg);
235 pg->dest->pg = NULL;
236
237 if (NULL != pg->set_task)
238 {
239 GNUNET_SCHEDULER_cancel (pg->set_task);
240 pg->set_task = NULL;
241 }
242
243 GNUNET_free (pg);
244}
245
246
247/**
248 * Stop all preferences generators
249 */
250void
251GNUNET_ATS_TEST_generate_preferences_stop_all ()
252{
253 struct PreferenceGenerator *cur;
254 struct PreferenceGenerator *next;
255
256 next = pg_head;
257 for (cur = next; NULL != cur; cur = next)
258 {
259 next = cur->next;
260 GNUNET_ATS_TEST_generate_preferences_stop (cur);
261 }
262}
263
264
265/* end of file ats-testing-preferences.c */
diff --git a/src/ats-tests/ats-testing-traffic.c b/src/ats-tests/ats-testing-traffic.c
deleted file mode 100644
index f19eac871..000000000
--- a/src/ats-tests/ats-testing-traffic.c
+++ /dev/null
@@ -1,393 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2013, 2016 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 ats-tests/ats-testing-traffic.c
22 * @brief ats benchmark: traffic generator
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "ats-testing.h"
29
30static struct TrafficGenerator *tg_head;
31static struct TrafficGenerator *tg_tail;
32
33extern struct GNUNET_ATS_TEST_Topology *top;
34
35static struct GNUNET_TIME_Relative
36get_delay (struct TrafficGenerator *tg)
37{
38 struct GNUNET_TIME_Relative delay;
39 struct GNUNET_TIME_Relative time_delta;
40 long long int cur_rate;
41 long long int delta_rate;
42
43 delay.rel_value_us = 0;
44
45 /* Calculate the current transmission rate based on the type of traffic */
46 switch (tg->type)
47 {
48 case GNUNET_ATS_TEST_TG_CONSTANT:
49 if (UINT32_MAX == tg->base_rate)
50 return GNUNET_TIME_UNIT_ZERO;
51 cur_rate = tg->base_rate;
52 break;
53
54 case GNUNET_ATS_TEST_TG_LINEAR:
55 time_delta = GNUNET_TIME_absolute_get_duration (tg->time_start);
56 /* Calculate point of time in the current period */
57 time_delta.rel_value_us = time_delta.rel_value_us
58 % tg->duration_period.rel_value_us;
59 delta_rate = ((double) time_delta.rel_value_us
60 / tg->duration_period.rel_value_us)
61 * (tg->max_rate - tg->base_rate);
62 if ((tg->max_rate < tg->base_rate) && ((tg->max_rate - tg->base_rate) >
63 tg->base_rate))
64 {
65 /* This will cause an underflow */
66 GNUNET_break (0);
67 }
68 cur_rate = tg->base_rate + delta_rate;
69 break;
70
71 case GNUNET_ATS_TEST_TG_RANDOM:
72 cur_rate = tg->base_rate + GNUNET_CRYPTO_random_u32 (
73 GNUNET_CRYPTO_QUALITY_WEAK,
74 tg->max_rate
75 - tg->base_rate);
76 break;
77
78 case GNUNET_ATS_TEST_TG_SINUS:
79 time_delta = GNUNET_TIME_absolute_get_duration (tg->time_start);
80 /* Calculate point of time in the current period */
81 time_delta.rel_value_us = time_delta.rel_value_us
82 % tg->duration_period.rel_value_us;
83 if ((tg->max_rate - tg->base_rate) > tg->base_rate)
84 {
85 /* This will cause an underflow for second half of sinus period,
86 * will be detected in general when experiments are loaded */
87 GNUNET_break (0);
88 }
89 delta_rate = (tg->max_rate - tg->base_rate)
90 * sin ((2 * M_PI)
91 / ((double) tg->duration_period.rel_value_us)
92 * time_delta.rel_value_us);
93 cur_rate = tg->base_rate + delta_rate;
94 break;
95
96 default:
97 return delay;
98 break;
99 }
100
101 if (cur_rate < 0)
102 {
103 cur_rate = 1;
104 }
105 /* Calculate the delay for the next message based on the current delay */
106 delay.rel_value_us = GNUNET_TIME_UNIT_SECONDS.rel_value_us
107 * TEST_MESSAGE_SIZE / cur_rate;
108
109 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
110 "Current rate is %lld, calculated delay is %llu\n",
111 cur_rate,
112 (unsigned long long) delay.rel_value_us);
113 return delay;
114}
115
116
117static void
118update_ping_data (void *cls)
119{
120 struct BenchmarkPartner *p = cls;
121 struct GNUNET_TIME_Relative delay;
122
123 p->messages_sent++;
124 p->bytes_sent += TEST_MESSAGE_SIZE;
125 p->me->total_messages_sent++;
126 p->me->total_bytes_sent += TEST_MESSAGE_SIZE;
127
128 if (NULL == p->tg)
129 {
130 GNUNET_break (0);
131 return;
132 }
133 delay = get_delay (p->tg);
134 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
135 "Delay for next transmission %s\n",
136 GNUNET_STRINGS_relative_time_to_string (delay,
137 GNUNET_YES));
138 p->tg->next_ping_transmission
139 = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
140 delay);
141}
142
143
144static void
145comm_schedule_send (void *cls)
146{
147 struct BenchmarkPartner *p = cls;
148 struct TestMessage *msg;
149 struct GNUNET_MQ_Envelope *env;
150
151 p->tg->send_task = NULL;
152 p->last_message_sent = GNUNET_TIME_absolute_get ();
153 env = GNUNET_MQ_msg (msg,
154 TEST_MESSAGE_TYPE_PING);
155 memset (msg->padding,
156 'a',
157 sizeof(msg->padding));
158 GNUNET_MQ_notify_sent (env,
159 &update_ping_data,
160 p);
161 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
162 "Master [%u]: Sending PING to [%u]\n",
163 p->me->no,
164 p->dest->no);
165 GNUNET_MQ_send (p->mq,
166 env);
167}
168
169
170static void
171update_pong_data (void *cls)
172{
173 struct BenchmarkPartner *p = cls;
174
175 p->messages_sent++;
176 p->bytes_sent += TEST_MESSAGE_SIZE;
177 p->me->total_messages_sent++;
178 p->me->total_bytes_sent += TEST_MESSAGE_SIZE;
179}
180
181
182void
183GNUNET_ATS_TEST_traffic_handle_ping (struct BenchmarkPartner *p)
184{
185 struct TestMessage *msg;
186 struct GNUNET_MQ_Envelope *env;
187
188 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
189 "Slave [%u]: Received PING from [%u], sending PONG\n",
190 p->me->no,
191 p->dest->no);
192 p->messages_received++;
193 p->bytes_received += TEST_MESSAGE_SIZE;
194 p->me->total_messages_received++;
195 p->me->total_bytes_received += TEST_MESSAGE_SIZE;
196
197
198 env = GNUNET_MQ_msg (msg,
199 TEST_MESSAGE_TYPE_PING);
200 memset (msg->padding,
201 'a',
202 sizeof(msg->padding));
203 GNUNET_MQ_notify_sent (env,
204 &update_pong_data,
205 p);
206 GNUNET_MQ_send (p->mq,
207 env);
208}
209
210
211void
212GNUNET_ATS_TEST_traffic_handle_pong (struct BenchmarkPartner *p)
213{
214 struct GNUNET_TIME_Relative left;
215
216 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
217 "Master [%u]: Received PONG from [%u], next message\n",
218 p->me->no,
219 p->dest->no);
220
221 p->messages_received++;
222 p->bytes_received += TEST_MESSAGE_SIZE;
223 p->me->total_messages_received++;
224 p->me->total_bytes_received += TEST_MESSAGE_SIZE;
225 p->total_app_rtt += GNUNET_TIME_absolute_get_difference (p->last_message_sent,
226 GNUNET_TIME_absolute_get ())
227 .rel_value_us;
228
229 /* Schedule next send event */
230 if (NULL == p->tg)
231 return;
232
233 left = GNUNET_TIME_absolute_get_remaining (p->tg->next_ping_transmission);
234 if (UINT32_MAX == p->tg->base_rate)
235 {
236 p->tg->send_task = GNUNET_SCHEDULER_add_now (&comm_schedule_send, p);
237 }
238 else if (0 == left.rel_value_us)
239 {
240 p->tg->send_task = GNUNET_SCHEDULER_add_now (&comm_schedule_send, p);
241 }
242 else
243 {
244 /* Enforce minimum transmission rate 1 msg / sec */
245 if (GNUNET_TIME_UNIT_SECONDS.rel_value_us == (left =
246 GNUNET_TIME_relative_min (
247 left,
248 GNUNET_TIME_UNIT_SECONDS))
249 .rel_value_us)
250 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
251 "Enforcing minimum send rate between master [%u] and slave [%u]\n",
252 p->me->no, p->dest->no);
253 p->tg->send_task = GNUNET_SCHEDULER_add_delayed (left,
254 &comm_schedule_send, p);
255 }
256}
257
258
259/**
260 * Generate between the source master and the partner and send traffic with a
261 * maximum rate.
262 *
263 * @param src traffic source
264 * @param dest traffic partner
265 * @param type type of traffic to generate
266 * @param base_rate traffic base rate to send data with
267 * @param max_rate traffic maximum rate to send data with
268 * @param period duration of a period of traffic generation (~ 1/frequency)
269 * @param duration how long to generate traffic
270 * @return the traffic generator
271 */
272struct TrafficGenerator *
273GNUNET_ATS_TEST_generate_traffic_start (struct BenchmarkPeer *src,
274 struct BenchmarkPartner *dest,
275 enum GeneratorType type,
276 unsigned int base_rate,
277 unsigned int max_rate,
278 struct GNUNET_TIME_Relative period,
279 struct GNUNET_TIME_Relative duration)
280{
281 struct TrafficGenerator *tg;
282
283 if (NULL != dest->tg)
284 {
285 GNUNET_break (0);
286 return NULL;
287 }
288
289 tg = GNUNET_new (struct TrafficGenerator);
290 GNUNET_CONTAINER_DLL_insert (tg_head,
291 tg_tail,
292 tg);
293 tg->type = type;
294 tg->src = src;
295 tg->dest = dest;
296 tg->base_rate = base_rate;
297 tg->max_rate = max_rate;
298 tg->duration_period = period;
299 tg->time_start = GNUNET_TIME_absolute_get ();
300 tg->next_ping_transmission = GNUNET_TIME_UNIT_FOREVER_ABS;
301
302 switch (type)
303 {
304 case GNUNET_ATS_TEST_TG_CONSTANT:
305 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
306 "Setting up constant traffic generator master[%u] `%s' and slave [%u] `%s' max %u Bips\n",
307 dest->me->no,
308 GNUNET_i2s (&dest->me->id),
309 dest->dest->no,
310 GNUNET_i2s (&dest->dest->id),
311 base_rate);
312 break;
313
314 case GNUNET_ATS_TEST_TG_LINEAR:
315 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
316 "Setting up linear traffic generator master[%u] `%s' and slave [%u] `%s' min %u Bips max %u Bips\n",
317 dest->me->no,
318 GNUNET_i2s (&dest->me->id),
319 dest->dest->no,
320 GNUNET_i2s (&dest->dest->id),
321 base_rate,
322 max_rate);
323 break;
324
325 case GNUNET_ATS_TEST_TG_SINUS:
326 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
327 "Setting up sinus traffic generator master[%u] `%s' and slave [%u] `%s' baserate %u Bips, amplitude %u Bps\n",
328 dest->me->no,
329 GNUNET_i2s (&dest->me->id),
330 dest->dest->no,
331 GNUNET_i2s (&dest->dest->id),
332 base_rate,
333 max_rate);
334 break;
335
336 case GNUNET_ATS_TEST_TG_RANDOM:
337 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
338 "Setting up random traffic generator master[%u] `%s' and slave [%u] `%s' min %u Bips max %u Bps\n",
339 dest->me->no,
340 GNUNET_i2s (&dest->me->id),
341 dest->dest->no,
342 GNUNET_i2s (&dest->dest->id),
343 base_rate,
344 max_rate);
345 break;
346
347 default:
348 break;
349 }
350
351 dest->tg = tg;
352 tg->send_task
353 = GNUNET_SCHEDULER_add_now (&comm_schedule_send,
354 dest);
355 return tg;
356}
357
358
359void
360GNUNET_ATS_TEST_generate_traffic_stop (struct TrafficGenerator *tg)
361{
362 GNUNET_CONTAINER_DLL_remove (tg_head,
363 tg_tail,
364 tg);
365 tg->dest->tg = NULL;
366 if (NULL != tg->send_task)
367 {
368 GNUNET_SCHEDULER_cancel (tg->send_task);
369 tg->send_task = NULL;
370 }
371 GNUNET_free (tg);
372}
373
374
375/**
376 * Stop all traffic generators
377 */
378void
379GNUNET_ATS_TEST_generate_traffic_stop_all ()
380{
381 struct TrafficGenerator *cur;
382 struct TrafficGenerator *next;
383
384 next = tg_head;
385 for (cur = next; NULL != cur; cur = next)
386 {
387 next = cur->next;
388 GNUNET_ATS_TEST_generate_traffic_stop (cur);
389 }
390}
391
392
393/* end of file ats-testing-traffic.c */
diff --git a/src/ats-tests/ats-testing.c b/src/ats-tests/ats-testing.c
deleted file mode 100644
index c6ba8533d..000000000
--- a/src/ats-tests/ats-testing.c
+++ /dev/null
@@ -1,975 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2013, 2016, 2017 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 ats-tests/ats-testing.c
22 * @brief ats testing library: setup topology
23 * solvers
24 * @author Christian Grothoff
25 * @author Matthias Wachs
26 */
27#include "ats-testing.h"
28
29
30/**
31 * Connect peers with testbed
32 */
33struct TestbedConnectOperation
34{
35 /**
36 * The benchmarking master initiating this connection
37 */
38 struct BenchmarkPeer *master;
39
40 /**
41 * The benchmarking slave to connect to
42 */
43 struct BenchmarkPeer *slave;
44
45 /**
46 * Testbed operation to connect peers
47 */
48 struct GNUNET_TESTBED_Operation *connect_op;
49};
50
51struct GNUNET_CONFIGURATION_Handle *cfg;
52
53struct GNUNET_ATS_TEST_Topology *top;
54
55
56/**
57 * Shutdown nicely
58 *
59 * @param cls NULL
60 */
61static void
62do_shutdown (void *cls)
63{
64 int c_m;
65 int c_s;
66 int c_op;
67 struct BenchmarkPeer *p;
68
69 top->state.benchmarking = GNUNET_NO;
70
71 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
72 "Benchmarking done\n");
73
74 GNUNET_ATS_TEST_generate_traffic_stop_all ();
75
76 for (c_m = 0; c_m < top->num_masters; c_m++)
77 {
78 p = &top->mps[c_m];
79 if (NULL != top->mps[c_m].peer_id_op)
80 {
81 GNUNET_TESTBED_operation_done (p->peer_id_op);
82 p->peer_id_op = NULL;
83 }
84
85 if (NULL != p->ats_task)
86 GNUNET_SCHEDULER_cancel (p->ats_task);
87 p->ats_task = NULL;
88
89 for (c_op = 0; c_op < p->num_partners; c_op++)
90 {
91 if ((NULL != p->core_connect_ops) &&
92 (NULL != p->core_connect_ops[c_op].connect_op))
93 {
94 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
95 "Failed to connect peer 0 and %u\n",
96 c_op);
97 GNUNET_TESTBED_operation_done (p->core_connect_ops[c_op].connect_op);
98 p->core_connect_ops[c_op].connect_op = NULL;
99 }
100 }
101
102 if (NULL != p->ats_perf_op)
103 {
104 GNUNET_TESTBED_operation_done (p->ats_perf_op);
105 p->ats_perf_op = NULL;
106 }
107
108 if (NULL != p->comm_op)
109 {
110 GNUNET_TESTBED_operation_done (p->comm_op);
111 p->comm_op = NULL;
112 }
113 GNUNET_free (p->core_connect_ops);
114 GNUNET_free (p->partners);
115 p->partners = NULL;
116 }
117
118 for (c_s = 0; c_s < top->num_slaves; c_s++)
119 {
120 p = &top->sps[c_s];
121 if (NULL != p->peer_id_op)
122 {
123 GNUNET_TESTBED_operation_done (p->peer_id_op);
124 p->peer_id_op = NULL;
125 }
126 if (NULL != p->ats_perf_op)
127 {
128 GNUNET_TESTBED_operation_done (p->ats_perf_op);
129 p->ats_perf_op = NULL;
130 }
131 if (NULL != p->comm_op)
132 {
133 GNUNET_TESTBED_operation_done (p->comm_op);
134 p->comm_op = NULL;
135 }
136 GNUNET_free (p->partners);
137 p->partners = NULL;
138 }
139 GNUNET_SCHEDULER_shutdown ();
140 GNUNET_free (top);
141 top = NULL;
142}
143
144
145static struct BenchmarkPartner *
146find_partner (struct BenchmarkPeer *me,
147 const struct GNUNET_PeerIdentity *peer)
148{
149 int c_m;
150
151 for (c_m = 0; c_m < me->num_partners; c_m++)
152 {
153 /* Find a partner with other as destination */
154 if (0 == GNUNET_memcmp (peer,
155 &me->partners[c_m].dest->id))
156 {
157 return &me->partners[c_m];
158 }
159 }
160
161 return NULL;
162}
163
164
165static struct BenchmarkPeer *
166find_peer (const struct GNUNET_PeerIdentity *peer)
167{
168 int c_p;
169
170 for (c_p = 0; c_p < top->num_masters; c_p++)
171 {
172 if (0 == GNUNET_memcmp (&top->mps[c_p].id,
173 peer))
174 return &top->mps[c_p];
175 }
176
177 for (c_p = 0; c_p < top->num_slaves; c_p++)
178 {
179 if (0 == GNUNET_memcmp (&top->sps[c_p].id,
180 peer))
181 return &top->sps[c_p];
182 }
183 return NULL;
184}
185
186
187/**
188 * Method called whenever a given peer connects.
189 *
190 * @param cls closure
191 * @param peer peer identity this notification is about
192 * @param mq queue to use to send messages to @a peer
193 * @return the `struct BenchmarkPartner` of @a peer
194 */
195static void *
196comm_connect_cb (void *cls,
197 const struct GNUNET_PeerIdentity *peer,
198 struct GNUNET_MQ_Handle *mq)
199{
200 struct BenchmarkPeer *me = cls;
201 struct BenchmarkPeer *remote;
202 struct BenchmarkPartner *p;
203 char *id;
204 int c;
205 int completed;
206
207 remote = find_peer (peer);
208 if (NULL == remote)
209 {
210 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
211 "Unknown peer connected: `%s'\n",
212 GNUNET_i2s (peer));
213 GNUNET_break (0);
214 return NULL;
215 }
216
217 id = GNUNET_strdup (GNUNET_i2s (&me->id));
218 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
219 "%s [%u] `%s' connected to %s [%u] %s\n",
220 (me->master == GNUNET_YES) ? "Master" : "Slave",
221 me->no,
222 id,
223 (remote->master == GNUNET_YES) ? "Master" : "Slave",
224 remote->no,
225 GNUNET_i2s (peer));
226
227 me->core_connections++;
228 if ((GNUNET_YES == me->master) &&
229 (GNUNET_NO == remote->master) &&
230 (GNUNET_NO == top->state.connected_CORE))
231 {
232 me->core_slave_connections++;
233
234 if (me->core_slave_connections == top->num_slaves)
235 {
236 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
237 "Master [%u] connected all slaves\n",
238 me->no);
239 }
240 completed = GNUNET_YES;
241 for (c = 0; c < top->num_masters; c++)
242 {
243 if (top->mps[c].core_slave_connections != top->num_slaves)
244 completed = GNUNET_NO;
245 }
246 if (GNUNET_YES == completed)
247 {
248 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
249 "All master peers connected all slave peers\n");
250 top->state.connected_CORE = GNUNET_YES;
251 /* Notify about setup done */
252 if (NULL != top->done_cb)
253 top->done_cb (top->done_cb_cls,
254 top->mps,
255 top->sps);
256 }
257 }
258 GNUNET_free (id);
259 p = find_partner (me,
260 peer);
261 if (NULL != p)
262 p->mq = mq;
263 return p;
264}
265
266
267/**
268 * @param cls this peer
269 * @param peer id of disconnecting peer
270 * @param internal_cls the `struct BenchmarkPartner` of @a peer
271 */
272static void
273comm_disconnect_cb (void *cls,
274 const struct GNUNET_PeerIdentity *peer,
275 void *internal_cls)
276{
277 struct BenchmarkPeer *me = cls;
278 struct BenchmarkPartner *p = internal_cls;
279 char *id;
280
281 if (NULL == p)
282 return;
283
284 id = GNUNET_strdup (GNUNET_i2s (&me->id));
285 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
286 "%s disconnected from %s\n",
287 id,
288 GNUNET_i2s (peer));
289 GNUNET_assert (me->core_connections > 0);
290 me->core_connections--;
291
292 if ((GNUNET_YES == top->state.benchmarking) &&
293 ((GNUNET_YES == me->master) ||
294 (GNUNET_YES == p->dest->master)))
295 {
296 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
297 "%s disconnected from %s while benchmarking\n",
298 id,
299 GNUNET_i2s (peer));
300 }
301 GNUNET_free (id);
302}
303
304
305static void
306handle_pong (void *cls,
307 const struct TestMessage *message)
308{
309 struct BenchmarkPartner *p = cls;
310
311 GNUNET_ATS_TEST_traffic_handle_pong (p);
312}
313
314
315static void
316handle_ping (void *cls,
317 const struct TestMessage *message)
318{
319 struct BenchmarkPartner *p = cls;
320
321 GNUNET_ATS_TEST_traffic_handle_ping (p);
322}
323
324
325static void *
326transport_connect_adapter (void *cls,
327 const struct GNUNET_CONFIGURATION_Handle *cfg)
328{
329 struct BenchmarkPeer *me = cls;
330 struct GNUNET_MQ_MessageHandler handlers[] = {
331 GNUNET_MQ_hd_fixed_size (ping,
332 TEST_MESSAGE_TYPE_PING,
333 struct TestMessage,
334 me),
335 GNUNET_MQ_hd_fixed_size (pong,
336 TEST_MESSAGE_TYPE_PONG,
337 struct TestMessage,
338 me),
339 GNUNET_MQ_handler_end ()
340 };
341
342 me->th = GNUNET_TRANSPORT_core_connect (cfg,
343 &me->id,
344 handlers,
345 me,
346 &comm_connect_cb,
347 &comm_disconnect_cb,
348 NULL);
349 if (NULL == me->th)
350 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
351 "Failed to create transport connection \n");
352 return me->th;
353}
354
355
356static void
357transport_disconnect_adapter (void *cls,
358 void *op_result)
359{
360 struct BenchmarkPeer *me = cls;
361
362 GNUNET_TRANSPORT_core_disconnect (me->th);
363 me->th = NULL;
364}
365
366
367static void *
368core_connect_adapter (void *cls,
369 const struct GNUNET_CONFIGURATION_Handle *cfg)
370{
371 struct BenchmarkPeer *me = cls;
372 struct GNUNET_MQ_MessageHandler handlers[] = {
373 GNUNET_MQ_hd_fixed_size (ping,
374 TEST_MESSAGE_TYPE_PING,
375 struct TestMessage,
376 me),
377 GNUNET_MQ_hd_fixed_size (pong,
378 TEST_MESSAGE_TYPE_PONG,
379 struct TestMessage,
380 me),
381 GNUNET_MQ_handler_end ()
382 };
383
384 me->ch = GNUNET_CORE_connect (cfg,
385 me,
386 NULL,
387 &comm_connect_cb,
388 &comm_disconnect_cb,
389 handlers);
390 if (NULL == me->ch)
391 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
392 "Failed to create core connection \n");
393 return me->ch;
394}
395
396
397static void
398core_disconnect_adapter (void *cls,
399 void *op_result)
400{
401 struct BenchmarkPeer *me = cls;
402
403 GNUNET_CORE_disconnect (me->ch);
404 me->ch = NULL;
405}
406
407
408static void
409connect_completion_callback (void *cls,
410 struct GNUNET_TESTBED_Operation *op,
411 const char *emsg)
412{
413 struct TestbedConnectOperation *cop = cls;
414 static int ops = 0;
415 int c;
416
417 if (NULL == emsg)
418 {
419 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
420 _ ("Connected master [%u] with slave [%u]\n"),
421 cop->master->no,
422 cop->slave->no);
423 }
424 else
425 {
426 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
427 _ ("Failed to connect master peer [%u] with slave [%u]\n"),
428 cop->master->no, cop->slave->no);
429 GNUNET_break (0);
430 GNUNET_SCHEDULER_shutdown ();
431 }
432 GNUNET_TESTBED_operation_done (op);
433 ops++;
434 for (c = 0; c < top->num_slaves; c++)
435 {
436 if (cop == &cop->master->core_connect_ops[c])
437 cop->master->core_connect_ops[c].connect_op = NULL;
438 }
439 if (ops == top->num_masters * top->num_slaves)
440 {
441 top->state.connected_PEERS = GNUNET_YES;
442 }
443}
444
445
446static void
447do_connect_peers (void *cls)
448{
449 int c_m;
450 int c_s;
451 struct BenchmarkPeer *p;
452
453 if ((top->state.connected_ATS_service == GNUNET_NO) ||
454 (top->state.connected_COMM_service == GNUNET_NO))
455 return;
456
457 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
458 "Connecting peers on CORE level\n");
459 for (c_m = 0; c_m < top->num_masters; c_m++)
460 {
461 p = &top->mps[c_m];
462 p->core_connect_ops = GNUNET_malloc (top->num_slaves
463 * sizeof(struct
464 TestbedConnectOperation));
465
466 for (c_s = 0; c_s < top->num_slaves; c_s++)
467 {
468 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
469 "Connecting master [%u] with slave [%u]\n",
470 p->no,
471 top->sps[c_s].no);
472 p->core_connect_ops[c_s].master = p;
473 p->core_connect_ops[c_s].slave = &top->sps[c_s];
474 p->core_connect_ops[c_s].connect_op
475 = GNUNET_TESTBED_overlay_connect (NULL,
476 &connect_completion_callback,
477 &p->core_connect_ops[c_s],
478 top->sps[c_s].peer,
479 p->peer);
480 if (NULL == p->core_connect_ops[c_s].connect_op)
481 {
482 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
483 "Could not connect master [%u] and slave [%u]\n",
484 p->no,
485 top->sps[c_s].no);
486 GNUNET_break (0);
487 GNUNET_SCHEDULER_shutdown ();
488 return;
489 }
490 }
491 }
492}
493
494
495static void
496comm_connect_completion_cb (void *cls,
497 struct GNUNET_TESTBED_Operation *op,
498 void *ca_result,
499 const char *emsg)
500{
501 static int comm_done = 0;
502
503 if ((NULL != emsg) || (NULL == ca_result))
504 {
505 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
506 "Initialization failed, shutdown\n");
507 GNUNET_break (0);
508 GNUNET_SCHEDULER_shutdown ();
509 return;
510 }
511 comm_done++;
512
513 if (comm_done == top->num_slaves + top->num_masters)
514 {
515 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
516 "Connected to all %s services\n",
517 (GNUNET_YES == top->test_core) ? "CORE" : "TRANSPORT");
518 top->state.connected_COMM_service = GNUNET_YES;
519 GNUNET_SCHEDULER_add_now (&do_connect_peers,
520 NULL);
521 }
522}
523
524
525static void
526do_comm_connect (void *cls)
527{
528 int c_s;
529 int c_m;
530
531 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
532 "Connecting to all %s services\n",
533 (GNUNET_YES == top->test_core) ? "CORE" : "TRANSPORT");
534 for (c_m = 0; c_m < top->num_masters; c_m++)
535 {
536 if (GNUNET_YES == top->test_core)
537 top->mps[c_m].comm_op
538 = GNUNET_TESTBED_service_connect (NULL,
539 top->mps[c_m].peer,
540 "core",
541 &comm_connect_completion_cb,
542 NULL,
543 &core_connect_adapter,
544 &core_disconnect_adapter,
545 &top->mps[c_m]);
546 else
547 {
548 top->mps[c_m].comm_op
549 = GNUNET_TESTBED_service_connect (NULL,
550 top->mps[c_m].peer,
551 "transport",
552 &comm_connect_completion_cb,
553 NULL,
554 &transport_connect_adapter,
555 &transport_disconnect_adapter,
556 &top->mps[c_m]);
557 }
558 }
559
560 for (c_s = 0; c_s < top->num_slaves; c_s++)
561 {
562 if (GNUNET_YES == top->test_core)
563 top->sps[c_s].comm_op
564 = GNUNET_TESTBED_service_connect (NULL,
565 top->sps[c_s].peer,
566 "core",
567 &comm_connect_completion_cb,
568 NULL,
569 &core_connect_adapter,
570 &core_disconnect_adapter,
571 &top->sps[c_s]);
572 else
573 {
574 top->sps[c_s].comm_op
575 = GNUNET_TESTBED_service_connect (NULL,
576 top->sps[c_s].peer,
577 "transport",
578 &comm_connect_completion_cb,
579 NULL,
580 &transport_connect_adapter,
581 &transport_disconnect_adapter,
582 &top->sps[c_s]);
583 }
584 }
585}
586
587
588static void
589ats_performance_info_cb (void *cls,
590 const struct GNUNET_HELLO_Address *address,
591 int address_active,
592 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
593 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
594 const struct GNUNET_ATS_Properties *ats_prop)
595{
596 struct BenchmarkPeer *me = cls;
597 struct BenchmarkPartner *p;
598 int log;
599 char *peer_id;
600
601 if (NULL == address)
602 {
603 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
604 "Peer %u: ATS Service disconnected!\n",
605 me->no);
606 return;
607 }
608
609 p = find_partner (me,
610 &address->peer);
611 if (NULL == p)
612 {
613 /* This is not one of my partners
614 * Will happen since the peers will connect to each other due to gossiping
615 */
616 return;
617 }
618 peer_id = GNUNET_strdup (GNUNET_i2s (&me->id));
619
620 log = GNUNET_NO;
621 if ((p->bandwidth_in != ntohl (bandwidth_in.value__)) ||
622 (p->bandwidth_out != ntohl (bandwidth_out.value__)))
623 log = GNUNET_YES;
624 p->bandwidth_in = ntohl (bandwidth_in.value__);
625 p->bandwidth_out = ntohl (bandwidth_out.value__);
626
627 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
628 "%s [%u] received ATS information: %s\n",
629 (GNUNET_YES == p->me->master) ? "Master" : "Slave",
630 p->me->no,
631 GNUNET_i2s (&p->dest->id));
632
633 p->props.utilization_out = ats_prop->utilization_out;
634 p->props.utilization_in = ats_prop->utilization_in;
635 p->props.scope = ats_prop->scope;
636 p->props.delay = ats_prop->delay;
637 p->props.distance = ats_prop->distance;
638
639 if (GNUNET_YES == log)
640 top->ats_perf_cb (cls, address,
641 address_active,
642 bandwidth_out,
643 bandwidth_in,
644 ats_prop);
645 GNUNET_free (peer_id);
646}
647
648
649static void *
650ats_perf_connect_adapter (void *cls,
651 const struct GNUNET_CONFIGURATION_Handle *cfg)
652{
653 struct BenchmarkPeer *me = cls;
654
655 me->ats_perf_handle
656 = GNUNET_ATS_performance_init (cfg,
657 &ats_performance_info_cb,
658 me);
659 if (NULL == me->ats_perf_handle)
660 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
661 "Failed to create ATS performance handle \n");
662 return me->ats_perf_handle;
663}
664
665
666static void
667ats_perf_disconnect_adapter (void *cls,
668 void *op_result)
669{
670 struct BenchmarkPeer *me = cls;
671
672 GNUNET_ATS_performance_done (me->ats_perf_handle);
673 me->ats_perf_handle = NULL;
674}
675
676
677static void
678ats_connect_completion_cb (void *cls,
679 struct GNUNET_TESTBED_Operation *op,
680 void *ca_result,
681 const char *emsg)
682{
683 static int op_done = 0;
684
685 if ((NULL != emsg) || (NULL == ca_result))
686 {
687 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
688 "Initialization failed, shutdown\n");
689 GNUNET_break (0);
690 GNUNET_SCHEDULER_shutdown ();
691 return;
692 }
693 op_done++;
694 if (op_done == (top->num_masters + top->num_slaves))
695 {
696 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
697 "Connected to all ATS services\n");
698 top->state.connected_ATS_service = GNUNET_YES;
699 GNUNET_SCHEDULER_add_now (&do_comm_connect,
700 NULL);
701 }
702}
703
704
705static void
706do_connect_ats (void *cls)
707{
708 int c_m;
709 int c_s;
710
711 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
712 "Connecting to all ATS services\n");
713 for (c_m = 0; c_m < top->num_masters; c_m++)
714 {
715 top->mps[c_m].ats_perf_op
716 = GNUNET_TESTBED_service_connect (NULL,
717 top->mps[c_m].peer,
718 "ats",
719 &ats_connect_completion_cb,
720 NULL,
721 &ats_perf_connect_adapter,
722 &ats_perf_disconnect_adapter,
723 &top->mps[c_m]);
724 }
725
726 for (c_s = 0; c_s < top->num_slaves; c_s++)
727 {
728 top->sps[c_s].ats_perf_op
729 = GNUNET_TESTBED_service_connect (NULL,
730 top->sps[c_s].peer,
731 "ats",
732 &ats_connect_completion_cb,
733 NULL,
734 &ats_perf_connect_adapter,
735 &ats_perf_disconnect_adapter,
736 &top->sps[c_s]);
737 }
738}
739
740
741static void
742peerinformation_cb (void *cb_cls,
743 struct GNUNET_TESTBED_Operation *op,
744 const struct GNUNET_TESTBED_PeerInformation *pinfo,
745 const char *emsg)
746{
747 struct BenchmarkPeer *p = cb_cls;
748 static int done = 0;
749
750 GNUNET_assert (pinfo->pit == GNUNET_TESTBED_PIT_IDENTITY);
751
752 p->id = *pinfo->result.id;
753 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
754 "%s [%u] has peer id `%s'\n",
755 (p->master == GNUNET_YES) ? "Master" : "Slave",
756 p->no,
757 GNUNET_i2s (&p->id));
758
759 GNUNET_TESTBED_operation_done (op);
760 p->peer_id_op = NULL;
761 done++;
762
763 if (done == top->num_slaves + top->num_masters)
764 {
765 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
766 "Retrieved all peer ID, connect to ATS\n");
767 GNUNET_SCHEDULER_add_now (&do_connect_ats,
768 NULL);
769 }
770}
771
772
773/**
774 * Signature of a main function for a testcase.
775 *
776 * @param cls closure
777 * @param h testbed handle
778 * @param num_peers number of peers in 'peers'
779 * @param peers_ handle to peers run in the testbed
780 * @param links_succeeded the number of overlay link connection attempts that
781 * succeeded
782 * @param links_failed the number of overlay link connection attempts that
783 * failed
784 */
785static void
786main_run (void *cls,
787 struct GNUNET_TESTBED_RunHandle *h,
788 unsigned int num_peers,
789 struct GNUNET_TESTBED_Peer **peers_,
790 unsigned int links_succeeded,
791 unsigned int links_failed)
792{
793 int c_m;
794 int c_s;
795
796 GNUNET_assert (NULL == cls);
797 GNUNET_assert (top->num_masters + top->num_slaves == num_peers);
798 GNUNET_assert (NULL != peers_);
799
800 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
801 top);
802
803 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
804 "Setting up %u masters and %u slaves\n",
805 top->num_masters,
806 top->num_slaves);
807
808 /* Setup master peers */
809 for (c_m = 0; c_m < top->num_masters; c_m++)
810 {
811 GNUNET_assert (NULL != peers_[c_m]);
812 top->mps[c_m].peer = peers_[c_m];
813 top->mps[c_m].no = c_m;
814 top->mps[c_m].master = GNUNET_YES;
815 top->mps[c_m].pref_partner = &top->sps[c_m];
816 top->mps[c_m].pref_value = TEST_ATS_PREFERENCE_DEFAULT;
817 top->mps[c_m].partners =
818 GNUNET_malloc (top->num_slaves * sizeof(struct BenchmarkPartner));
819 top->mps[c_m].num_partners = top->num_slaves;
820 /* Initialize partners */
821 for (c_s = 0; c_s < top->num_slaves; c_s++)
822 {
823 top->mps[c_m].partners[c_s].me = &top->mps[c_m];
824 top->mps[c_m].partners[c_s].dest = &top->sps[c_s];
825 }
826 /* Get configuration */
827 top->mps[c_m].peer_id_op
828 = GNUNET_TESTBED_peer_get_information (top->mps[c_m].peer,
829 GNUNET_TESTBED_PIT_IDENTITY,
830 &peerinformation_cb,
831 &top->mps[c_m]);
832 }
833
834 /* Setup slave peers */
835 for (c_s = 0; c_s < top->num_slaves; c_s++)
836 {
837 GNUNET_assert (NULL != peers_[c_s + top->num_masters]);
838 top->sps[c_s].peer = peers_[c_s + top->num_masters];
839 top->sps[c_s].no = c_s + top->num_masters;
840 top->sps[c_s].master = GNUNET_NO;
841 top->sps[c_s].partners =
842 GNUNET_new_array (top->num_masters,
843 struct BenchmarkPartner);
844 top->sps[c_s].num_partners = top->num_masters;
845 /* Initialize partners */
846 for (c_m = 0; c_m < top->num_masters; c_m++)
847 {
848 top->sps[c_s].partners[c_m].me = &top->sps[c_s];
849 top->sps[c_s].partners[c_m].dest = &top->mps[c_m];
850
851 /* Initialize properties */
852 top->sps[c_s].partners[c_m].props.delay = GNUNET_TIME_UNIT_ZERO;
853 top->sps[c_s].partners[c_m].props.distance = 0;
854 top->sps[c_s].partners[c_m].props.scope = GNUNET_NT_UNSPECIFIED;
855 top->sps[c_s].partners[c_m].props.utilization_in = 0;
856 top->sps[c_s].partners[c_m].props.utilization_out = 0;
857 }
858 /* Get configuration */
859 top->sps[c_s].peer_id_op
860 = GNUNET_TESTBED_peer_get_information (top->sps[c_s].peer,
861 GNUNET_TESTBED_PIT_IDENTITY,
862 &peerinformation_cb,
863 &top->sps[c_s]);
864 }
865}
866
867
868/**
869 * Controller event callback
870 *
871 * @param cls NULL
872 * @param event the controller event
873 */
874static void
875controller_event_cb (void *cls,
876 const struct GNUNET_TESTBED_EventInformation *event)
877{
878 switch (event->type)
879 {
880 case GNUNET_TESTBED_ET_CONNECT:
881 break;
882
883 case GNUNET_TESTBED_ET_OPERATION_FINISHED:
884 break;
885
886 default:
887 GNUNET_break (0);
888 GNUNET_SCHEDULER_shutdown ();
889 }
890}
891
892
893struct BenchmarkPeer *
894GNUNET_ATS_TEST_get_peer (int src)
895{
896 if (src > top->num_masters)
897 return NULL;
898 return &top->mps[src];
899}
900
901
902struct BenchmarkPartner *
903GNUNET_ATS_TEST_get_partner (int src,
904 int dest)
905{
906 if (src > top->num_masters)
907 return NULL;
908 if (dest > top->num_slaves)
909 return NULL;
910 return &top->mps[src].partners[dest];
911}
912
913
914/**
915 * Create a topology for ats testing
916 *
917 * @param name test name
918 * @param cfg_file configuration file to use for the peers
919 * @param num_slaves number of slaves
920 * @param num_masters number of masters
921 * @param test_core connect to CORE service (GNUNET_YES) or transport (GNUNET_NO)
922 * @param done_cb function to call when topology is setup
923 * @param done_cb_cls cls for callback
924 * @param log_request_cb callback to call when logging is required
925 */
926void
927GNUNET_ATS_TEST_create_topology (char *name, char *cfg_file,
928 unsigned int num_slaves,
929 unsigned int num_masters,
930 int test_core,
931 GNUNET_ATS_TEST_TopologySetupDoneCallback
932 done_cb,
933 void *done_cb_cls,
934 GNUNET_ATS_AddressInformationCallback
935 log_request_cb)
936{
937 top = GNUNET_new (struct GNUNET_ATS_TEST_Topology);
938 top->num_masters = num_masters;
939 top->num_slaves = num_slaves;
940 top->done_cb = done_cb;
941 top->done_cb_cls = done_cb_cls;
942 top->test_core = test_core;
943 top->ats_perf_cb = log_request_cb;
944 top->mps = GNUNET_new_array (num_masters,
945 struct BenchmarkPeer);
946 top->sps = GNUNET_new_array (num_slaves,
947 struct BenchmarkPeer);
948
949 /* Start topology */
950 uint64_t event_mask;
951 event_mask = 0;
952 event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT);
953 event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED);
954 (void) GNUNET_TESTBED_test_run (name,
955 cfg_file,
956 num_slaves + num_masters,
957 event_mask,
958 &controller_event_cb, NULL,
959 &main_run, NULL);
960}
961
962
963/**
964 * Shutdown topology
965 */
966void
967GNUNET_ATS_TEST_shutdown_topology (void)
968{
969 if (NULL == top)
970 return;
971 GNUNET_SCHEDULER_shutdown ();
972}
973
974
975/* end of file ats-testing.c */
diff --git a/src/ats-tests/ats-testing.h b/src/ats-tests/ats-testing.h
deleted file mode 100644
index 017ffef4f..000000000
--- a/src/ats-tests/ats-testing.h
+++ /dev/null
@@ -1,757 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 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 ats-tests/ats-testing.h
22 * @brief ats testing library: setup topology and provide logging to test ats
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testbed_service.h"
29#include "gnunet_ats_service.h"
30#include "gnunet_core_service.h"
31#include "gnunet_transport_service.h"
32
33#define TEST_ATS_PREFERENCE_DEFAULT 1.0
34
35/**
36 * Message type sent for traffic generation
37 */
38#define TEST_MESSAGE_TYPE_PING 12345
39
40/**
41 * Message type sent as response during traffic generation
42 */
43#define TEST_MESSAGE_TYPE_PONG 12346
44
45/**
46 * Size of test messages
47 */
48#define TEST_MESSAGE_SIZE 100
49
50
51struct TestMessage
52{
53 struct GNUNET_MessageHeader header;
54
55 uint8_t padding[TEST_MESSAGE_SIZE - sizeof(struct GNUNET_MessageHeader)];
56};
57
58
59struct BenchmarkPartner;
60
61struct BenchmarkPeer;
62
63struct GNUNET_ATS_TEST_Topology;
64
65struct TrafficGenerator;
66
67struct LoggingHandle;
68
69enum GeneratorType
70{
71 GNUNET_ATS_TEST_TG_LINEAR,
72 GNUNET_ATS_TEST_TG_CONSTANT,
73 GNUNET_ATS_TEST_TG_RANDOM,
74 GNUNET_ATS_TEST_TG_SINUS
75};
76
77
78/**
79 * Callback to call when topology setup is completed
80 *
81 * @param cls the closure
82 * @param masters array of master peers
83 * @param slaves array of master peers
84 */
85typedef void (*GNUNET_ATS_TEST_TopologySetupDoneCallback) (
86 void *cls,
87 struct BenchmarkPeer *masters,
88 struct BenchmarkPeer *slaves);
89
90/**
91 * Callback called when logging is required for the data contained
92 *
93 * @param cls the closure
94 * @param address an address
95 * @param address_active is address active
96 * @param bandwidth_out bandwidth outbound
97 * @param bandwidth_in bandwidth inbound
98 * @param prop performance information
99 */
100typedef void (*GNUNET_ATS_TEST_LogRequest) (
101 void *cls,
102 const struct GNUNET_HELLO_Address *address,
103 int address_active,
104 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
105 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
106 const struct GNUNET_ATS_Properties *prop);
107
108/**
109 * Information we track for a peer in the testbed.
110 */
111struct BenchmarkPeer
112{
113 /**
114 * Handle with testbed.
115 */
116 struct GNUNET_TESTBED_Peer *peer;
117
118 /**
119 * Unique identifier
120 */
121 int no;
122
123 /**
124 * Is this peer a measter: GNUNET_YES/GNUNET_NO
125 */
126 int master;
127
128 /**
129 * Peer ID
130 */
131 struct GNUNET_PeerIdentity id;
132
133 /**
134 * Testbed operation to get peer information
135 */
136 struct GNUNET_TESTBED_Operation *peer_id_op;
137
138 /**
139 * Testbed operation to connect to ATS performance service
140 */
141 struct GNUNET_TESTBED_Operation *ats_perf_op;
142
143 /**
144 * Testbed operation to connect to core
145 */
146 struct GNUNET_TESTBED_Operation *comm_op;
147
148 /**
149 * ATS performance handle
150 */
151 struct GNUNET_ATS_PerformanceHandle *ats_perf_handle;
152
153 /**
154 * Masters only:
155 * Testbed connect operations to connect masters to slaves
156 */
157 struct TestbedConnectOperation *core_connect_ops;
158
159 /**
160 * Core handle
161 */
162 struct GNUNET_CORE_Handle *ch;
163
164 /**
165 * Transport handle
166 */
167 struct GNUNET_TRANSPORT_CoreHandle *th;
168
169 /**
170 * Masters only:
171 * Peer to set ATS preferences for
172 */
173 struct BenchmarkPeer *pref_partner;
174
175 /**
176 * Masters only
177 * Progress task
178 */
179 struct GNUNET_SCHEDULER_Task *ats_task;
180
181 /**
182 * Masters only
183 * Progress task
184 */
185 double pref_value;
186
187 /**
188 * Array of partners with num_slaves entries (if master) or
189 * num_master entries (if slave)
190 */
191 struct BenchmarkPartner *partners;
192
193 /**
194 * Number of partners
195 */
196 int num_partners;
197
198 /**
199 * Number of core connections
200 */
201 int core_connections;
202
203 /**
204 * Masters only:
205 * Number of connections to slave peers
206 */
207 int core_slave_connections;
208
209 /**
210 * Total number of messages this peer has sent
211 */
212 unsigned int total_messages_sent;
213
214 /**
215 * Total number of bytes this peer has sent
216 */
217 unsigned int total_bytes_sent;
218
219 /**
220 * Total number of messages this peer has received
221 */
222 unsigned int total_messages_received;
223
224 /**
225 * Total number of bytes this peer has received
226 */
227 unsigned int total_bytes_received;
228};
229
230struct TrafficGenerator
231{
232 struct TrafficGenerator *prev;
233 struct TrafficGenerator *next;
234
235 enum GeneratorType type;
236
237 struct BenchmarkPeer *src;
238 struct BenchmarkPartner *dest;
239
240 long int base_rate;
241 long int max_rate;
242 struct GNUNET_TIME_Relative duration_period;
243
244 struct GNUNET_SCHEDULER_Task *send_task;
245 struct GNUNET_TIME_Absolute next_ping_transmission;
246 struct GNUNET_TIME_Absolute time_start;
247};
248
249
250struct PreferenceGenerator
251{
252 struct PreferenceGenerator *prev;
253 struct PreferenceGenerator *next;
254
255 enum GeneratorType type;
256
257 struct BenchmarkPeer *src;
258 struct BenchmarkPartner *dest;
259
260 enum GNUNET_ATS_PreferenceKind kind;
261
262 long int base_value;
263 long int max_value;
264 struct GNUNET_TIME_Relative duration_period;
265 struct GNUNET_TIME_Relative frequency;
266
267 struct GNUNET_SCHEDULER_Task *set_task;
268 struct GNUNET_TIME_Absolute next_ping_transmission;
269 struct GNUNET_TIME_Absolute time_start;
270};
271
272/**
273 * Information about a benchmarking partner
274 */
275struct BenchmarkPartner
276{
277 /**
278 * The peer itself this partner belongs to
279 */
280 struct BenchmarkPeer *me;
281
282 /**
283 * The partner peer
284 */
285 struct BenchmarkPeer *dest;
286
287 /**
288 * Message queue handle.
289 */
290 struct GNUNET_MQ_Handle *mq;
291
292 /**
293 * Handle for traffic generator
294 */
295 struct TrafficGenerator *tg;
296
297 /**
298 * Handle for preference generator
299 */
300 struct PreferenceGenerator *pg;
301
302 /**
303 * Timestamp to calculate communication layer delay
304 */
305 struct GNUNET_TIME_Absolute last_message_sent;
306
307 /**
308 * Accumulated RTT for all messages
309 */
310 unsigned int total_app_rtt;
311
312 /**
313 * Number of messages sent to this partner
314 */
315 unsigned int messages_sent;
316
317 /**
318 * Number of bytes sent to this partner
319 */
320 unsigned int bytes_sent;
321
322 /**
323 * Number of messages received from this partner
324 */
325 unsigned int messages_received;
326
327 /**
328 * Number of bytes received from this partner
329 */
330 unsigned int bytes_received;
331
332 /**
333 * Current ATS properties
334 */
335 struct GNUNET_ATS_Properties props;
336
337 /**
338 * Bandwidth assigned inbound
339 */
340 uint32_t bandwidth_in;
341
342 /**
343 * Bandwidth assigned outbound
344 */
345 uint32_t bandwidth_out;
346
347 /**
348 * Current preference values for bandwidth
349 */
350 double pref_bandwidth;
351
352 /**
353 * Current preference values for delay
354 */
355 double pref_delay;
356};
357
358
359/**
360 * Overall state of the performance benchmark
361 */
362struct BenchmarkState
363{
364 /**
365 * Are we connected to ATS service of all peers: GNUNET_YES/NO
366 */
367 int connected_ATS_service;
368
369 /**
370 * Are we connected to CORE service of all peers: GNUNET_YES/NO
371 */
372 int connected_COMM_service;
373
374 /**
375 * Are we connected to all peers: GNUNET_YES/NO
376 */
377 int connected_PEERS;
378
379 /**
380 * Are we connected to all slave peers on CORE level: GNUNET_YES/NO
381 */
382 int connected_CORE;
383
384 /**
385 * Are we connected to CORE service of all peers: GNUNET_YES/NO
386 */
387 int benchmarking;
388};
389
390
391struct GNUNET_ATS_TEST_Topology
392{
393 /**
394 * Progress task
395 */
396 struct GNUNET_SCHEDULER_Task *progress_task;
397
398 /**
399 * Test result
400 */
401 int result;
402
403 /**
404 * Test core (#GNUNET_YES) or transport (#GNUNET_NO)
405 */
406 int test_core;
407
408 /**
409 * Solver string
410 */
411 char *solver;
412
413 /**
414 * Preference string
415 */
416 char *testname;
417
418 /**
419 * Preference string
420 */
421 char *pref_str;
422
423 /**
424 * ATS preference value
425 */
426 int pref_val;
427
428 /**
429 * Number master peers
430 */
431 unsigned int num_masters;
432
433 /**
434 * Array of master peers
435 */
436 struct BenchmarkPeer *mps;
437
438 /**
439 * Number slave peers
440 */
441 unsigned int num_slaves;
442
443 /**
444 * Array of slave peers
445 */
446 struct BenchmarkPeer *sps;
447
448 /**
449 * Benchmark duration
450 */
451 struct GNUNET_TIME_Relative perf_duration;
452
453 /**
454 * Logging frequency
455 */
456 struct GNUNET_TIME_Relative log_frequency;
457
458 /**
459 * Benchmark state
460 */
461 struct BenchmarkState state;
462
463 GNUNET_ATS_TEST_TopologySetupDoneCallback done_cb;
464
465 GNUNET_ATS_AddressInformationCallback ats_perf_cb;
466
467 void *done_cb_cls;
468};
469
470enum OperationType
471{
472 START_SEND,
473 STOP_SEND,
474 START_PREFERENCE,
475 STOP_PREFERENCE
476};
477
478struct Episode;
479
480struct Experiment;
481
482typedef void (*GNUNET_ATS_TESTING_EpisodeDoneCallback) (struct Episode *e);
483
484typedef void (*GNUNET_ATS_TESTING_ExperimentDoneCallback) (
485 struct Experiment *e,
486 struct GNUNET_TIME_Relative duration,
487 int success);
488
489/**
490 * An operation in an experiment
491 */
492struct GNUNET_ATS_TEST_Operation
493{
494 struct GNUNET_ATS_TEST_Operation *next;
495 struct GNUNET_ATS_TEST_Operation *prev;
496
497 long long unsigned int src_id;
498 long long unsigned int dest_id;
499
500 long long unsigned int base_rate;
501 long long unsigned int max_rate;
502 struct GNUNET_TIME_Relative period;
503 struct GNUNET_TIME_Relative frequency;
504
505 enum OperationType type;
506 enum GeneratorType gen_type;
507 enum GNUNET_ATS_PreferenceKind pref_type;
508};
509
510struct Episode
511{
512 int id;
513 struct Episode *next;
514 struct GNUNET_TIME_Relative duration;
515
516 struct GNUNET_ATS_TEST_Operation *head;
517 struct GNUNET_ATS_TEST_Operation *tail;
518};
519
520
521struct Experiment
522{
523 char *name;
524 char *cfg_file;
525 unsigned long long int num_masters;
526 unsigned long long int num_slaves;
527 struct GNUNET_TIME_Relative log_freq;
528 struct GNUNET_TIME_Relative max_duration;
529 struct GNUNET_TIME_Relative total_duration;
530 struct GNUNET_TIME_Absolute start_time;
531 unsigned int num_episodes;
532 struct Episode *start;
533
534 struct GNUNET_SCHEDULER_Task *experiment_timeout_task;
535 struct GNUNET_SCHEDULER_Task *episode_timeout_task;
536 struct Episode *cur;
537
538 GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb;
539 GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb;
540};
541
542
543extern struct GNUNET_CONFIGURATION_Handle *cfg;
544
545/**
546 * Execute the specified experiment
547 *
548 * @param e the Experiment
549 * @param ep_done_cb a episode is completed
550 * @param e_done_cb the experiment is completed
551 */
552void
553GNUNET_ATS_TEST_experimentation_run (
554 struct Experiment *e,
555 GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
556 GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb);
557
558
559/**
560 * Load an experiment from a file
561 *
562 * @param filename the file
563 * @return the Experiment or NULL on failure
564 */
565struct Experiment *
566GNUNET_ATS_TEST_experimentation_load (const char *filename);
567
568
569/**
570 * Stop an experiment
571 *
572 * @param e the experiment
573 */
574void
575GNUNET_ATS_TEST_experimentation_stop (struct Experiment *e);
576
577
578void
579GNUNET_ATS_TEST_traffic_handle_ping (struct BenchmarkPartner *p);
580
581
582void
583GNUNET_ATS_TEST_traffic_handle_pong (struct BenchmarkPartner *p);
584
585
586/**
587 * Generate between the source master and the partner and send traffic with a
588 * maximum rate.
589 *
590 * @param src traffic source
591 * @param dest traffic partner
592 * @param type type of traffic to generate
593 * @param base_rate traffic base rate to send data with
594 * @param max_rate traffic maximum rate to send data with
595 * @param period duration of a period of traffic generation (~ 1/frequency)
596 * @param duration how long to generate traffic
597 * @return the traffic generator
598 */
599struct TrafficGenerator *
600GNUNET_ATS_TEST_generate_traffic_start (struct BenchmarkPeer *src,
601 struct BenchmarkPartner *dest,
602 enum GeneratorType type,
603 unsigned int base_rate,
604 unsigned int max_rate,
605 struct GNUNET_TIME_Relative period,
606 struct GNUNET_TIME_Relative duration);
607
608
609void
610GNUNET_ATS_TEST_generate_traffic_stop (struct TrafficGenerator *tg);
611
612
613/**
614 * Stop all traffic generators
615 */
616void
617GNUNET_ATS_TEST_generate_traffic_stop_all (void);
618
619
620/**
621 * Generate between the source master and the partner and set preferences with a
622 * value depending on the generator.
623 *
624 * @param src source
625 * @param dest partner
626 * @param type type of preferences to generate
627 * @param base_value traffic base rate to send data with
628 * @param value_rate traffic maximum rate to send data with
629 * @param period duration of a period of preferences generation (~ 1/frequency)
630 * @param frequency how long to generate preferences
631 * @param kind ATS preference to generate
632 * @return the traffic generator
633 */
634struct PreferenceGenerator *
635GNUNET_ATS_TEST_generate_preferences_start (
636 struct BenchmarkPeer *src,
637 struct BenchmarkPartner *dest,
638 enum GeneratorType type,
639 unsigned int base_value,
640 unsigned int value_rate,
641 struct GNUNET_TIME_Relative period,
642 struct GNUNET_TIME_Relative frequency,
643 enum GNUNET_ATS_PreferenceKind kind);
644
645
646void
647GNUNET_ATS_TEST_generate_preferences_stop (struct PreferenceGenerator *pg);
648
649
650void
651GNUNET_ATS_TEST_generate_preferences_stop_all (void);
652
653
654/**
655 * Start logging
656 *
657 * @param log_frequency the logging frequency
658 * @param testname the testname
659 * @param masters the master peers used for benchmarking
660 * @param num_masters the number of master peers
661 * @param num_slaves the number of slave peers
662 * @param verbose verbose logging
663 * @return the logging handle or NULL on error
664 */
665struct LoggingHandle *
666GNUNET_ATS_TEST_logging_start (struct GNUNET_TIME_Relative log_frequency,
667 const char *testname,
668 struct BenchmarkPeer *masters,
669 int num_masters,
670 int num_slaves,
671 int verbose);
672
673
674/**
675 * Stop logging
676 *
677 * @param l the logging handle
678 */
679void
680GNUNET_ATS_TEST_logging_clean_up (struct LoggingHandle *l);
681
682
683/**
684 * Stop logging
685 *
686 * @param l the logging handle
687 */
688void
689GNUNET_ATS_TEST_logging_stop (struct LoggingHandle *l);
690
691
692/**
693 * Log all data now
694 *
695 * @param l logging handle to use
696 */
697void
698GNUNET_ATS_TEST_logging_now (struct LoggingHandle *l);
699
700
701/**
702 * Write logging data to file
703 *
704 * @param l logging handle to use
705 * @param test_name name of the current test
706 * @param plots create gnuplots: #GNUNET_YES or #GNUNET_NO
707 */
708void
709GNUNET_ATS_TEST_logging_write_to_file (struct LoggingHandle *l,
710 const char *test_name,
711 int plots);
712
713
714/**
715 * Topology related functions
716 */
717struct BenchmarkPeer *
718GNUNET_ATS_TEST_get_peer (int src);
719
720
721struct BenchmarkPartner *
722GNUNET_ATS_TEST_get_partner (int src, int dest);
723
724
725/**
726 * Create a topology for ats testing
727 *
728 * @param name test name
729 * @param cfg_file configuration file to use for the peers
730 * @param num_slaves number of slaves
731 * @param num_masters number of masters
732 * @param test_core connect to CORE service (#GNUNET_YES) or transport
733 * (#GNUNET_NO)
734 * @param done_cb function to call when topology is setup
735 * @param done_cb_cls cls for callback
736 * @param log_request_cb callback to call when logging is required
737 */
738void
739GNUNET_ATS_TEST_create_topology (
740 char *name,
741 char *cfg_file,
742 unsigned int num_slaves,
743 unsigned int num_masters,
744 int test_core,
745 GNUNET_ATS_TEST_TopologySetupDoneCallback done_cb,
746 void *done_cb_cls,
747 GNUNET_ATS_TEST_LogRequest ats_perf_cb);
748
749
750/**
751 * Shutdown topology
752 */
753void
754GNUNET_ATS_TEST_shutdown_topology (void);
755
756
757/* end of file ats-testing.h */
diff --git a/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_prop.conf b/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_prop.conf
deleted file mode 100644
index 4b66e5aea..000000000
--- a/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_prop.conf
+++ /dev/null
@@ -1,24 +0,0 @@
1@INLINE@ template_perf_ats.conf
2
3[transport]
4plugins = unix
5
6[ats]
7MODE = MLP
8UNSPECIFIED_QUOTA_IN = 128 KiB
9UNSPECIFIED_QUOTA_OUT = 128 KiB
10# LOOPBACK
11LOOPBACK_QUOTA_IN = 128 KiB
12LOOPBACK_QUOTA_OUT = 128 KiB
13# LAN
14LAN_QUOTA_IN = 128 KiB
15LAN_QUOTA_OUT = 128 KiB
16# WAN
17WAN_QUOTA_IN = 128 KiB
18WAN_QUOTA_OUT = 128 KiB
19# WLAN
20WLAN_QUOTA_IN = 128 KiB
21WLAN_QUOTA_OUT = 128 KiB
22# BLUETOOTH
23BLUETOOTH_QUOTA_IN = 128 KiB
24BLUETOOTH_QUOTA_OUT = 128 KiB \ No newline at end of file
diff --git a/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_prop.exp b/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_prop.exp
deleted file mode 100644
index 6a04e7491..000000000
--- a/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_prop.exp
+++ /dev/null
@@ -1,46 +0,0 @@
1[experiment]
2name = sc1_eval_dru_prop
3masters = 1
4slaves = 3
5max_duration = 20 s
6log_freq = 100 ms
7cfg_file = experiments/evaluation1_dru_3_peers_1addr_1scope_prop.conf
8
9[episode-0]
10# operations = start_send, stop_send, start_preference, stop_preference
11duration = 10 s
12op-0-operation = start_send
13op-0-src = 0
14op-0-dest = 0
15op-0-type = constant
16#op-0-period = 10 s
17op-0-base-rate= 10000
18#op-0-max-rate = 10000
19
20op-1-operation = start_send
21op-1-src = 0
22op-1-dest = 1
23op-1-type = constant
24#op-1-period = 10 s
25op-1-base-rate= 10000
26#op-1-max-rate = 10000
27
28op-2-operation = start_send
29op-2-src = 0
30op-2-dest = 2
31op-2-type = constant
32#op-1-period = 10 s
33op-2-base-rate= 10000
34#op-1-max-rate = 10000
35
36[episode-1]
37duration = 10 s
38op-0-operation = start_preference
39op-0-src = 0
40op-0-dest = 2
41op-0-type = constant
42#op-0-period = 10 s
43op-0-pref = bandwidth
44op-0-frequency = 1 s
45op-0-base-rate= 50
46#op-0-max-rate = 10000 \ No newline at end of file
diff --git a/src/ats-tests/experiments/send_linear_10_sec.exp b/src/ats-tests/experiments/send_linear_10_sec.exp
deleted file mode 100644
index efd2c7b08..000000000
--- a/src/ats-tests/experiments/send_linear_10_sec.exp
+++ /dev/null
@@ -1,30 +0,0 @@
1[experiment]
2 name = test
3 masters = 1
4 slaves = 3
5 max_duration = 2 s
6 cfg_file = gnunet_ats_sim_default.conf
7
8[episode-0]
9# operations = set_rate, start_send, stop_send, set_preference
10duration = 2 s
11op-0-operation = set_rate
12op-0-src = 0
13op-0-dest = 0
14op-0-type = constant
15op-0-base-rate= 10000
16op-0-max-rate = 10000
17
18op-1-operation = set_rate
19op-1-src = 0
20op-1-dest = 1
21op-1-type = constant
22op-1-base-rate= 10000
23op-1-max-rate = 10000
24
25op-2-operation = set_rate
26op-2-src = 0
27op-2-dest = 2
28op-2-type = constant
29op-2-base-rate= 10000
30op-2-max-rate = 10000 \ No newline at end of file
diff --git a/src/ats-tests/experiments/test.exp b/src/ats-tests/experiments/test.exp
deleted file mode 100644
index 636139f89..000000000
--- a/src/ats-tests/experiments/test.exp
+++ /dev/null
@@ -1,55 +0,0 @@
1[experiment]
2 name = test
3 masters = 1
4 slaves = 2
5 max_duration = 15 s
6 log_freq = 100 ms
7 cfg_file = gnunet_ats_sim_default.conf
8
9[episode-0]
10# operations = start_send, stop_send, start_preference, stop_preference
11duration = 10 s
12op-0-operation = start_send
13op-0-src = 0
14op-0-dest = 0
15op-0-type = constant
16op-0-base-rate= 10000
17op-0-max-rate = 10000
18
19op-1-operation = start_send
20op-1-src = 0
21op-1-dest = 1
22op-1-type = sinus
23op-1-period = 5 s
24op-1-base-rate= 10000
25op-1-max-rate = 15000
26
27op-2-operation = start_preference
28op-2-src = 0
29op-2-dest = 0
30op-2-type = constant
31op-2-period = 5 s
32op-2-base-rate= 10
33op-2-max-rate = 5
34op-2-pref = latency
35op-2-frequency = 2 s
36
37op-3-operation = start_preference
38op-3-src = 0
39op-3-dest = 1
40op-3-type = linear
41op-3-period = 5 s
42op-3-base-rate= 40
43op-3-max-rate = 50
44op-3-pref = bandwidth
45op-3-frequency = 750 ms
46
47[episode-1]
48duration = 5 s
49op-0-operation = stop_preference
50op-0-src = 0
51op-0-dest = 0
52
53op-1-operation = stop_preference
54op-1-src = 0
55op-1-dest = 1
diff --git a/src/ats-tests/gnunet-ats-sim.c b/src/ats-tests/gnunet-ats-sim.c
deleted file mode 100644
index 15cd52e2f..000000000
--- a/src/ats-tests/gnunet-ats-sim.c
+++ /dev/null
@@ -1,399 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 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 ats-tests/gnunet-ats-sim.c
22 * @brief ats traffic simulator: this tool uses the ats-test library to setup a
23 * topology and generate traffic between these peers. The traffic description
24 * is loaded from a experiment description file
25 * @author Christian Grothoff
26 * @author Matthias Wachs
27 */
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_testbed_service.h"
31#include "gnunet_ats_service.h"
32#include "gnunet_core_service.h"
33#include "ats-testing.h"
34
35#define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, \
36 10)
37
38static struct BenchmarkPeer *masters_p;
39static struct BenchmarkPeer *slaves_p;
40
41/**
42 * cmd option -e: experiment file
43 */
44static char *opt_exp_file;
45
46/**
47 * cmd option -l: enable logging
48 */
49static int opt_log;
50
51/**
52 * cmd option -p: enable plots
53 */
54static int opt_plot;
55
56/**
57 * cmd option -v: verbose logs
58 */
59static int opt_verbose;
60
61static struct GNUNET_SCHEDULER_Task *timeout_task;
62
63static struct Experiment *e;
64
65static struct LoggingHandle *l;
66
67
68static void
69evaluate (struct GNUNET_TIME_Relative duration_total)
70{
71 int c_m;
72 int c_s;
73 unsigned int duration;
74 struct BenchmarkPeer *mp;
75 struct BenchmarkPartner *p;
76
77 unsigned int b_sent_sec;
78 double kb_sent_percent;
79 unsigned int b_recv_sec;
80 double kb_recv_percent;
81 unsigned int rtt;
82
83
84 duration = (duration_total.rel_value_us / (1000 * 1000));
85 if (0 == duration)
86 duration = 1;
87 for (c_m = 0; c_m < e->num_masters; c_m++)
88 {
89 mp = &masters_p[c_m];
90 fprintf (stderr,
91 _ (
92 "Master [%u]: sent: %u KiB in %u sec. = %u KiB/s, received: %u KiB in %u sec. = %u KiB/s\n"),
93 mp->no, mp->total_bytes_sent / 1024,
94 duration,
95 (mp->total_bytes_sent / 1024) / duration,
96 mp->total_bytes_received / 1024,
97 duration,
98 (mp->total_bytes_received / 1024) / duration);
99
100 for (c_s = 0; c_s < e->num_slaves; c_s++)
101 {
102 p = &mp->partners[c_s];
103
104 b_sent_sec = 0;
105 b_recv_sec = 0;
106 kb_sent_percent = 0.0;
107 kb_recv_percent = 0.0;
108 rtt = 0;
109
110 if (duration > 0)
111 {
112 b_sent_sec = p->bytes_sent / duration;
113 b_recv_sec = p->bytes_received / duration;
114 }
115
116 if (mp->total_bytes_sent > 0)
117 kb_sent_percent = ((double) p->bytes_sent * 100) / mp->total_bytes_sent;
118 if (mp->total_bytes_received > 0)
119 kb_recv_percent = ((double) p->bytes_received * 100)
120 / mp->total_bytes_received;
121 if (1000 * p->messages_sent > 0)
122 rtt = p->total_app_rtt / (1000 * p->messages_sent);
123 fprintf (stderr,
124 "%c Master [%u] -> Slave [%u]: sent %u Bips (%.2f %%), received %u Bips (%.2f %%)\n",
125 (mp->pref_partner == p->dest) ? '*' : ' ',
126 mp->no, p->dest->no,
127 b_sent_sec, kb_sent_percent,
128 b_recv_sec, kb_recv_percent);
129 fprintf (stderr,
130 "%c Master [%u] -> Slave [%u]: Average application layer RTT: %u ms\n",
131 (mp->pref_partner == p->dest) ? '*' : ' ',
132 mp->no, p->dest->no, rtt);
133 }
134 }
135}
136
137
138static void
139do_shutdown (void *cls)
140{
141 fprintf (stderr, "Shutdown\n");
142 if (NULL != timeout_task)
143 {
144 GNUNET_SCHEDULER_cancel (timeout_task);
145 timeout_task = NULL;
146 }
147 if (NULL != l)
148 {
149 GNUNET_ATS_TEST_logging_stop (l);
150 GNUNET_ATS_TEST_logging_clean_up (l);
151 l = NULL;
152 }
153
154 /* Stop traffic generation */
155 GNUNET_ATS_TEST_generate_traffic_stop_all ();
156
157 /* Stop all preference generations */
158 GNUNET_ATS_TEST_generate_preferences_stop_all ();
159
160 if (NULL != e)
161 {
162 GNUNET_ATS_TEST_experimentation_stop (e);
163 e = NULL;
164 }
165 GNUNET_ATS_TEST_shutdown_topology ();
166}
167
168
169static void
170do_timeout (void *cls)
171{
172 timeout_task = NULL;
173 GNUNET_SCHEDULER_shutdown ();
174}
175
176
177static void
178log_request__cb (void *cls,
179 const struct GNUNET_HELLO_Address *address,
180 int address_active,
181 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
182 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
183 const struct GNUNET_ATS_Properties *ats)
184{
185 if (NULL != l)
186 {
187 // GNUNET_break (0);
188 // GNUNET_ATS_TEST_logging_now (l);
189 }
190}
191
192
193static void
194experiment_done_cb (struct Experiment *e,
195 struct GNUNET_TIME_Relative duration,
196 int success)
197{
198 if (GNUNET_OK == success)
199 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
200 "Experiment done successful in %s\n",
201 GNUNET_STRINGS_relative_time_to_string (duration,
202 GNUNET_YES));
203 else
204 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment failed \n");
205
206 /* Stop logging */
207 GNUNET_ATS_TEST_logging_stop (l);
208
209 /* Stop traffic generation */
210 GNUNET_ATS_TEST_generate_traffic_stop_all ();
211
212 /* Stop all preference generations */
213 GNUNET_ATS_TEST_generate_preferences_stop_all ();
214
215 evaluate (duration);
216 if (opt_log)
217 GNUNET_ATS_TEST_logging_write_to_file (l, opt_exp_file, opt_plot);
218 GNUNET_SCHEDULER_shutdown ();
219}
220
221
222static void
223episode_done_cb (struct Episode *ep)
224{
225 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
226 "Episode %u done\n",
227 ep->id);
228}
229
230
231static void
232topology_setup_done (void *cls,
233 struct BenchmarkPeer *masters,
234 struct BenchmarkPeer *slaves)
235{
236 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
237 "Topology setup complete!\n");
238
239 masters_p = masters;
240 slaves_p = slaves;
241
242 l = GNUNET_ATS_TEST_logging_start (e->log_freq,
243 e->name,
244 masters_p,
245 e->num_masters, e->num_slaves,
246 opt_verbose);
247 GNUNET_ATS_TEST_experimentation_run (e,
248 &episode_done_cb,
249 &experiment_done_cb);
250/*
251 GNUNET_ATS_TEST_generate_preferences_start(&masters[0],&masters[0].partners[0],
252 GNUNET_ATS_TEST_TG_CONSTANT, 1, 1, GNUNET_TIME_UNIT_SECONDS,
253 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250),
254 GNUNET_ATS_PREFERENCE_BANDWIDTH);
255 *//*
256 GNUNET_ATS_TEST_generate_preferences_start(&masters[0],&masters[0].partners[0],
257 GNUNET_ATS_TEST_TG_LINEAR, 1, 50,
258 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 2),
259 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250),
260 GNUNET_ATS_PREFERENCE_BANDWIDTH);
261 *//*
262 GNUNET_ATS_TEST_generate_preferences_start(&masters[0],&masters[0].partners[0],
263 GNUNET_ATS_TEST_TG_RANDOM, 1, 50,
264 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 2),
265 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250),
266 GNUNET_ATS_PREFERENCE_BANDWIDTH);
267 *//*
268 GNUNET_ATS_TEST_generate_preferences_start(&masters[0],&masters[0].partners[0],
269 GNUNET_ATS_TEST_TG_SINUS, 10, 5,
270 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5),
271 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250),
272 GNUNET_ATS_PREFERENCE_BANDWIDTH);
273 */
274#if 0
275 int c_m;
276 int c_s;
277 for (c_m = 0; c_m < e->num_masters; c_m++)
278 {
279 for (c_s = 0; c_s < e->num_slaves; c_s++)
280 {
281 /* Generate maximum traffic to all peers */
282 /* Example: Generate traffic with constant 10,000 Bytes/s */
283 GNUNET_ATS_TEST_generate_traffic_start (&masters[c_m],
284 &masters[c_m].partners[c_s],
285 GNUNET_ATS_TEST_TG_CONSTANT,
286 10000,
287 GNUNET_TIME_UNIT_FOREVER_REL);
288 /* Example: Generate traffic with an increasing rate from 1000 to 2000
289 * Bytes/s with in a minute */
290 GNUNET_ATS_TEST_generate_traffic_start (&masters[c_m],
291 &masters[c_m].partners[c_s],
292 GNUNET_ATS_TEST_TG_LINEAR,
293 1000,
294 2000,
295 GNUNET_TIME_UNIT_MINUTES,
296 GNUNET_TIME_UNIT_FOREVER_REL);
297 /* Example: Generate traffic with a random rate between 1000 to 2000
298 * Bytes/s */
299 GNUNET_ATS_TEST_generate_traffic_start (&masters[c_m],
300 &masters[c_m].partners[c_s],
301 GNUNET_ATS_TEST_TG_RANDOM,
302 1000,
303 2000,
304 GNUNET_TIME_UNIT_FOREVER_REL,
305 GNUNET_TIME_UNIT_FOREVER_REL);
306 /* Example: Generate traffic with a sinus form, a base rate of
307 * 1000 Bytes/s, an amplitude of (max-base), and a period of 1 minute */
308 GNUNET_ATS_TEST_generate_traffic_start (&masters[c_m],
309 &masters[c_m].partners[c_s],
310 GNUNET_ATS_TEST_TG_SINUS,
311 1000,
312 2000,
313 GNUNET_TIME_UNIT_MINUTES,
314 GNUNET_TIME_UNIT_FOREVER_REL);
315 }
316 }
317#endif
318
319 timeout_task
320 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_add (
321 GNUNET_TIME_UNIT_MINUTES,
322 e->max_duration),
323 &do_timeout,
324 NULL);
325 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
326}
327
328
329static void
330parse_args (int argc, char *argv[])
331{
332 int c;
333
334 opt_exp_file = NULL;
335 opt_log = GNUNET_NO;
336 opt_plot = GNUNET_NO;
337
338 for (c = 0; c < argc; c++)
339 {
340 if ((c < (argc - 1)) && (0 == strcmp (argv[c], "-e")))
341 {
342 GNUNET_free (opt_exp_file);
343 opt_exp_file = GNUNET_strdup (argv[c + 1]);
344 }
345 if (0 == strcmp (argv[c], "-l"))
346 {
347 opt_log = GNUNET_YES;
348 }
349 if (0 == strcmp (argv[c], "-p"))
350 {
351 opt_plot = GNUNET_YES;
352 }
353 if (0 == strcmp (argv[c], "-v"))
354 {
355 opt_verbose = GNUNET_YES;
356 }
357 }
358}
359
360
361int
362main (int argc, char *argv[])
363{
364 GNUNET_log_setup ("gnunet-ats-sim", "INFO", NULL);
365
366 parse_args (argc, argv);
367 if (NULL == opt_exp_file)
368 {
369 fprintf (stderr, "No experiment given...\n");
370 return 1;
371 }
372
373 fprintf (stderr, "Loading experiment `%s' \n", opt_exp_file);
374 e = GNUNET_ATS_TEST_experimentation_load (opt_exp_file);
375 if (NULL == e)
376 {
377 fprintf (stderr, "Invalid experiment\n");
378 return 1;
379 }
380 if (0 == e->num_episodes)
381 {
382 fprintf (stderr, "No episodes included\n");
383 return 1;
384 }
385
386 /* Setup a topology with */
387 GNUNET_ATS_TEST_create_topology ("gnunet-ats-sim", e->cfg_file,
388 e->num_slaves,
389 e->num_masters,
390 GNUNET_NO,
391 &topology_setup_done,
392 NULL,
393 &log_request__cb);
394 GNUNET_free (opt_exp_file);
395 return 0;
396}
397
398
399/* end of file gnunet-ats-sim.c */
diff --git a/src/ats-tests/gnunet-solver-eval.c b/src/ats-tests/gnunet-solver-eval.c
deleted file mode 100644
index 7a3461bf7..000000000
--- a/src/ats-tests/gnunet-solver-eval.c
+++ /dev/null
@@ -1,1025 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 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 ats-tests/ats-testing-experiment.c
22 * @brief ats benchmark: controlled experiment execution
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_ats_plugin.h"
29#include "gnunet_ats_service.h"
30#include "ats-testing.h"
31
32
33/**
34 * Experiments
35 */
36const char *
37print_op (enum OperationType op)
38{
39 switch (op)
40 {
41 case START_SEND:
42 return "START_SEND";
43
44 case STOP_SEND:
45 return "STOP_SEND";
46
47 case START_PREFERENCE:
48 return "START_PREFERENCE";
49
50 case STOP_PREFERENCE:
51 return "STOP_PREFERENCE";
52
53 default:
54 break;
55 }
56 return "";
57}
58
59
60static struct Experiment *
61create_experiment ()
62{
63 struct Experiment *e;
64
65 e = GNUNET_new (struct Experiment);
66 e->name = NULL;
67 e->num_masters = 0;
68 e->num_slaves = 0;
69 e->start = NULL;
70 e->total_duration = GNUNET_TIME_UNIT_ZERO;
71 return e;
72}
73
74
75static void
76free_experiment (struct Experiment *e)
77{
78 struct Episode *cur;
79 struct Episode *next;
80 struct GNUNET_ATS_TEST_Operation *cur_o;
81 struct GNUNET_ATS_TEST_Operation *next_o;
82
83 next = e->start;
84 for (cur = next; NULL != cur; cur = next)
85 {
86 next = cur->next;
87
88 next_o = cur->head;
89 for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
90 {
91 next_o = cur_o->next;
92 GNUNET_free (cur_o);
93 }
94 GNUNET_free (cur);
95 }
96
97 GNUNET_free (e->name);
98 GNUNET_free (e->cfg_file);
99 GNUNET_free (e);
100}
101
102
103static int
104load_episode (struct Experiment *e,
105 struct Episode *cur,
106 struct GNUNET_CONFIGURATION_Handle *cfg)
107{
108 struct GNUNET_ATS_TEST_Operation *o;
109 char *sec_name;
110 char *op_name;
111 char *op;
112 char *type;
113 char *pref;
114 int op_counter = 0;
115
116 fprintf (stderr, "Parsing episode %u\n", cur->id);
117 GNUNET_asprintf (&sec_name, "episode-%u", cur->id);
118
119 while (1)
120 {
121 /* Load operation */
122 GNUNET_asprintf (&op_name, "op-%u-operation", op_counter);
123 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
124 sec_name,
125 op_name, &op))
126 {
127 GNUNET_free (op_name);
128 break;
129 }
130 o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
131 /* operations = set_rate, start_send, stop_send, set_preference */
132 if (0 == strcmp (op, "start_send"))
133 {
134 o->type = START_SEND;
135 }
136 else if (0 == strcmp (op, "stop_send"))
137 {
138 o->type = STOP_SEND;
139 }
140 else if (0 == strcmp (op, "start_preference"))
141 {
142 o->type = START_PREFERENCE;
143 }
144 else if (0 == strcmp (op, "stop_preference"))
145 {
146 o->type = STOP_PREFERENCE;
147 }
148 else
149 {
150 fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
151 op_counter, op, cur->id);
152 GNUNET_free (op);
153 GNUNET_free (op_name);
154 GNUNET_free (sec_name);
155 GNUNET_free (o);
156 return GNUNET_SYSERR;
157 }
158 GNUNET_free (op_name);
159
160 /* Get source */
161 GNUNET_asprintf (&op_name, "op-%u-src", op_counter);
162 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
163 sec_name,
164 op_name,
165 &o->src_id))
166 {
167 fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n",
168 op_counter, op, cur->id);
169 GNUNET_free (op);
170 GNUNET_free (op_name);
171 GNUNET_free (sec_name);
172 GNUNET_free (o);
173 return GNUNET_SYSERR;
174 }
175 if (o->src_id > (e->num_masters - 1))
176 {
177 fprintf (stderr, "Invalid src %llu in operation %u `%s' in episode %u\n",
178 o->src_id, op_counter, op, cur->id);
179 GNUNET_free (op);
180 GNUNET_free (op_name);
181 GNUNET_free (sec_name);
182 GNUNET_free (o);
183 return GNUNET_SYSERR;
184 }
185 GNUNET_free (op_name);
186
187 /* Get destination */
188 GNUNET_asprintf (&op_name, "op-%u-dest", op_counter);
189 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
190 sec_name,
191 op_name,
192 &o->dest_id))
193 {
194 fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n",
195 op_counter, op, cur->id);
196 GNUNET_free (op);
197 GNUNET_free (op_name);
198 GNUNET_free (sec_name);
199 GNUNET_free (o);
200 return GNUNET_SYSERR;
201 }
202 if (o->dest_id > (e->num_slaves - 1))
203 {
204 fprintf (stderr,
205 "Invalid destination %llu in operation %u `%s' in episode %u\n",
206 o->dest_id,
207 op_counter,
208 op,
209 cur->id);
210 GNUNET_free (op);
211 GNUNET_free (op_name);
212 GNUNET_free (sec_name);
213 GNUNET_free (o);
214 return GNUNET_SYSERR;
215 }
216 GNUNET_free (op_name);
217
218 GNUNET_asprintf (&op_name, "op-%u-type", op_counter);
219 if ((GNUNET_SYSERR !=
220 GNUNET_CONFIGURATION_get_value_string (cfg,
221 sec_name,
222 op_name,
223 &type)) &&
224 (STOP_SEND != o->type) &&
225 (STOP_PREFERENCE != o->type))
226 {
227 /* Load arguments for set_rate, start_send, set_preference */
228 if (0 == strcmp (type, "constant"))
229 {
230 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
231 }
232 else if (0 == strcmp (type, "linear"))
233 {
234 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
235 }
236 else if (0 == strcmp (type, "sinus"))
237 {
238 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
239 }
240 else if (0 == strcmp (type, "random"))
241 {
242 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
243 }
244 else
245 {
246 fprintf (stderr, "Invalid type %u `%s' in episode %u\n",
247 op_counter, op, cur->id);
248 GNUNET_free (type);
249 GNUNET_free (op);
250 GNUNET_free (op_name);
251 GNUNET_free (sec_name);
252 GNUNET_free (o);
253 return GNUNET_SYSERR;
254 }
255 GNUNET_free (op_name);
256
257 /* Get base rate */
258 GNUNET_asprintf (&op_name, "op-%u-base-rate", op_counter);
259 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
260 sec_name,
261 op_name,
262 &o->base_rate))
263 {
264 fprintf (stderr,
265 "Missing base rate in operation %u `%s' in episode %u\n",
266 op_counter, op, cur->id);
267 GNUNET_free (type);
268 GNUNET_free (op);
269 GNUNET_free (op_name);
270 GNUNET_free (sec_name);
271 GNUNET_free (o);
272 return GNUNET_SYSERR;
273 }
274 GNUNET_free (op_name);
275
276 /* Get max rate */
277 GNUNET_asprintf (&op_name, "op-%u-max-rate", op_counter);
278 if (GNUNET_SYSERR ==
279 GNUNET_CONFIGURATION_get_value_number (cfg,
280 sec_name,
281 op_name,
282 &o->max_rate))
283 {
284 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
285 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
286 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
287 {
288 fprintf (stderr,
289 "Missing max rate in operation %u `%s' in episode %u\n",
290 op_counter, op, cur->id);
291 GNUNET_free (type);
292 GNUNET_free (op_name);
293 GNUNET_free (op);
294 GNUNET_free (sec_name);
295 GNUNET_free (o);
296 return GNUNET_SYSERR;
297 }
298 }
299 GNUNET_free (op_name);
300
301 /* Get period */
302 GNUNET_asprintf (&op_name, "op-%u-period", op_counter);
303 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
304 sec_name,
305 op_name,
306 &o->period))
307 {
308 o->period = cur->duration;
309 }
310 GNUNET_free (op_name);
311
312 if (START_PREFERENCE == o->type)
313 {
314 /* Get frequency */
315 GNUNET_asprintf (&op_name, "op-%u-frequency", op_counter);
316 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
317 sec_name,
318 op_name,
319 &o->frequency))
320 {
321 fprintf (stderr,
322 "Missing frequency in operation %u `%s' in episode %u\n",
323 op_counter, op, cur->id);
324 GNUNET_free (type);
325 GNUNET_free (op_name);
326 GNUNET_free (op);
327 GNUNET_free (sec_name);
328 GNUNET_free (o);
329 return GNUNET_SYSERR;
330 }
331 GNUNET_free (op_name);
332
333 /* Get preference */
334 GNUNET_asprintf (&op_name, "op-%u-pref", op_counter);
335 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
336 sec_name,
337 op_name,
338 &pref))
339 {
340 fprintf (stderr,
341 "Missing preference in operation %u `%s' in episode %u\n",
342 op_counter, op, cur->id);
343 GNUNET_free (type);
344 GNUNET_free (op_name);
345 GNUNET_free (op);
346 GNUNET_free (sec_name);
347 GNUNET_free (pref);
348 GNUNET_free (o);
349 return GNUNET_SYSERR;
350 }
351
352 if (0 == strcmp (pref, "bandwidth"))
353 o->pref_type = GNUNET_ATS_PREFERENCE_BANDWIDTH;
354 else if (0 == strcmp (pref, "latency"))
355 o->pref_type = GNUNET_ATS_PREFERENCE_LATENCY;
356 else
357 {
358 fprintf (stderr,
359 "Invalid preference in operation %u `%s' in episode %u\n",
360 op_counter,
361 op,
362 cur->id);
363 GNUNET_free (type);
364 GNUNET_free (op_name);
365 GNUNET_free (op);
366 GNUNET_free (sec_name);
367 GNUNET_free (pref);
368 GNUNET_free (o);
369 return GNUNET_SYSERR;
370 }
371 GNUNET_free (pref);
372 GNUNET_free (op_name);
373 }
374 }
375
376 /* Safety checks */
377 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
378 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
379 {
380 if ((o->max_rate - o->base_rate) > o->base_rate)
381 {
382 /* This will cause an underflow */
383 GNUNET_break (0);
384 }
385 fprintf (stderr,
386 "Selected max rate and base rate cannot be used for desired traffic form!\n");
387 }
388
389 if ((START_SEND == o->type) || (START_PREFERENCE == o->type))
390 fprintf (stderr,
391 "Found operation %u in episode %u: %s [%llu]->[%llu] == %s, %llu -> %llu in %s\n",
392 op_counter, cur->id, print_op (o->type), o->src_id,
393 o->dest_id, (NULL != type) ? type : "",
394 o->base_rate, o->max_rate,
395 GNUNET_STRINGS_relative_time_to_string (o->period, GNUNET_YES));
396 else
397 fprintf (stderr, "Found operation %u in episode %u: %s [%llu]->[%llu]\n",
398 op_counter, cur->id, print_op (o->type), o->src_id, o->dest_id);
399
400 GNUNET_free (type);
401 GNUNET_free (op);
402
403 GNUNET_CONTAINER_DLL_insert (cur->head, cur->tail, o);
404 op_counter++;
405 }
406 GNUNET_free (sec_name);
407
408 return GNUNET_OK;
409}
410
411
412static int
413load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
414{
415 int e_counter = 0;
416 char *sec_name;
417 struct GNUNET_TIME_Relative e_duration;
418 struct Episode *cur;
419 struct Episode *last;
420
421 e_counter = 0;
422 last = NULL;
423 while (1)
424 {
425 GNUNET_asprintf (&sec_name, "episode-%u", e_counter);
426 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
427 sec_name,
428 "duration",
429 &e_duration))
430 {
431 GNUNET_free (sec_name);
432 break;
433 }
434
435 cur = GNUNET_new (struct Episode);
436 cur->duration = e_duration;
437 cur->id = e_counter;
438
439 if (GNUNET_OK != load_episode (e, cur, cfg))
440 {
441 GNUNET_free (sec_name);
442 GNUNET_free (cur);
443 return GNUNET_SYSERR;
444 }
445
446 fprintf (stderr, "Found episode %u with duration %s \n",
447 e_counter,
448 GNUNET_STRINGS_relative_time_to_string (cur->duration,
449 GNUNET_YES));
450
451 /* Update experiment */
452 e->num_episodes++;
453 e->total_duration = GNUNET_TIME_relative_add (e->total_duration,
454 cur->duration);
455 /* Put in linked list */
456 if (NULL == last)
457 e->start = cur;
458 else
459 last->next = cur;
460
461 GNUNET_free (sec_name);
462 e_counter++;
463 last = cur;
464 }
465 return e_counter;
466}
467
468
469static void
470timeout_experiment (void *cls)
471{
472 struct Experiment *e = cls;
473
474 e->experiment_timeout_task = NULL;
475 fprintf (stderr, "Experiment timeout!\n");
476
477 if (NULL != e->episode_timeout_task)
478 {
479 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
480 e->episode_timeout_task = NULL;
481 }
482
483 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration (e->start_time),
484 GNUNET_SYSERR);
485}
486
487
488static void
489enforce_start_send (struct GNUNET_ATS_TEST_Operation *op)
490{
491 /*
492 struct BenchmarkPeer *peer;
493 struct BenchmarkPartner *partner;
494
495 peer = GNUNET_ATS_TEST_get_peer (op->src_id);
496 if (NULL == peer)
497 {
498 GNUNET_break (0);
499 return;
500 }
501
502 partner = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
503 if (NULL == partner)
504 {
505 GNUNET_break (0);
506 return;
507 }
508
509 fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
510
511 if (NULL != partner->tg)
512 {
513 fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",op->src_id, op->dest_id);
514 GNUNET_ATS_TEST_generate_traffic_stop(partner->tg);
515 partner->tg = NULL;
516 }
517
518 partner->tg = GNUNET_ATS_TEST_generate_traffic_start(peer, partner,
519 op->tg_type, op->base_rate, op->max_rate, op->period,
520 GNUNET_TIME_UNIT_FOREVER_REL);
521 */}
522
523
524static void
525enforce_stop_send (struct GNUNET_ATS_TEST_Operation *op)
526{
527 /*
528 struct BenchmarkPartner *p;
529 p = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
530 if (NULL == p)
531 {
532 GNUNET_break (0);
533 return;
534 }
535
536 fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
537
538 if (NULL != p->tg)
539 {
540 fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",
541 op->src_id, op->dest_id);
542 GNUNET_ATS_TEST_generate_traffic_stop(p->tg);
543 p->tg = NULL;
544 }
545 */}
546
547
548static void
549enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
550{
551 /*
552 struct BenchmarkPeer *peer;
553 struct BenchmarkPartner *partner;
554
555 peer = GNUNET_ATS_TEST_get_peer (op->src_id);
556 if (NULL == peer)
557 {
558 GNUNET_break (0);
559 return;
560 }
561
562 partner = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
563 if (NULL == partner)
564 {
565 GNUNET_break (0);
566 return;
567 }
568
569 fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
570
571 if (NULL != partner->pg)
572 {
573 fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",
574 op->src_id, op->dest_id);
575 GNUNET_ATS_TEST_generate_preferences_stop(partner->pg);
576 partner->pg = NULL;
577 }
578
579 partner->pg = GNUNET_ATS_TEST_generate_preferences_start(peer, partner,
580 op->tg_type, op->base_rate, op->max_rate, op->period, op->frequency,
581 op->pref_type);
582 */}
583
584
585static void
586enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
587{
588 /*
589 struct BenchmarkPartner *p;
590 p = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
591 if (NULL == p)
592 {
593 GNUNET_break (0);
594 return;
595 }
596
597 fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
598
599 if (NULL != p->pg)
600 {
601 fprintf (stderr, "Stopping preference between master %llu slave %llu\n",
602 op->src_id, op->dest_id);
603 GNUNET_ATS_TEST_generate_preferences_stop (p->pg);
604 p->pg = NULL;
605 }
606 */}
607
608
609static void
610enforce_episode (struct Episode *ep)
611{
612 struct GNUNET_ATS_TEST_Operation *cur;
613
614 for (cur = ep->head; NULL != cur; cur = cur->next)
615 {
616 fprintf (stderr, "Enforcing operation: %s [%llu]->[%llu] == %llu\n",
617 print_op (cur->type), cur->src_id, cur->dest_id, cur->base_rate);
618 switch (cur->type)
619 {
620 case START_SEND:
621 enforce_start_send (cur);
622 break;
623
624 case STOP_SEND:
625 enforce_stop_send (cur);
626 break;
627
628 case START_PREFERENCE:
629 enforce_start_preference (cur);
630 break;
631
632 case STOP_PREFERENCE:
633 enforce_stop_preference (cur);
634 break;
635
636 default:
637 break;
638 }
639 }
640}
641
642
643static void
644timeout_episode (void *cls)
645{
646 struct Experiment *e = cls;
647
648 e->episode_timeout_task = NULL;
649 if (NULL != e->ep_done_cb)
650 e->ep_done_cb (e->cur);
651
652 /* Scheduling next */
653 e->cur = e->cur->next;
654 if (NULL == e->cur)
655 {
656 /* done */
657 fprintf (stderr, "Last episode done!\n");
658 if (NULL != e->experiment_timeout_task)
659 {
660 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
661 e->experiment_timeout_task = NULL;
662 }
663 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration (e->start_time),
664 GNUNET_OK);
665 return;
666 }
667
668 fprintf (stderr, "Running episode %u with timeout %s\n",
669 e->cur->id,
670 GNUNET_STRINGS_relative_time_to_string (e->cur->duration,
671 GNUNET_YES));
672 enforce_episode (e->cur);
673
674 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
675 &timeout_episode, e);
676}
677
678
679void
680GNUNET_ATS_solvers_experimentation_run (struct Experiment *e,
681 GNUNET_ATS_TESTING_EpisodeDoneCallback
682 ep_done_cb,
683 GNUNET_ATS_TESTING_ExperimentDoneCallback
684 e_done_cb)
685{
686 fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name,
687 GNUNET_STRINGS_relative_time_to_string (e->max_duration,
688 GNUNET_YES));
689 e->e_done_cb = e_done_cb;
690 e->ep_done_cb = ep_done_cb;
691 e->start_time = GNUNET_TIME_absolute_get ();
692
693 /* Start total time out */
694 e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
695 &timeout_experiment,
696 e);
697
698 /* Start */
699 e->cur = e->start;
700 fprintf (stderr, "Running episode %u with timeout %s\n",
701 e->cur->id,
702 GNUNET_STRINGS_relative_time_to_string (e->cur->duration,
703 GNUNET_YES));
704 enforce_episode (e->cur);
705 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
706 &timeout_episode, e);
707}
708
709
710struct Experiment *
711GNUNET_ATS_solvers_experimentation_load (char *filename)
712{
713 struct Experiment *e;
714 struct GNUNET_CONFIGURATION_Handle *cfg;
715
716 e = NULL;
717
718 cfg = GNUNET_CONFIGURATION_create ();
719 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
720 {
721 fprintf (stderr, "Failed to load `%s'\n", filename);
722 GNUNET_CONFIGURATION_destroy (cfg);
723 return NULL;
724 }
725
726 e = create_experiment ();
727
728 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, "experiment",
729 "name", &e->name))
730 {
731 fprintf (stderr, "Invalid %s", "name");
732 free_experiment (e);
733 return NULL;
734 }
735 else
736 fprintf (stderr, "Experiment name: `%s'\n", e->name);
737
738 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg,
739 "experiment",
740 "cfg_file",
741 &e->cfg_file))
742 {
743 fprintf (stderr, "Invalid %s", "cfg_file");
744 free_experiment (e);
745 return NULL;
746 }
747 else
748 fprintf (stderr, "Experiment name: `%s'\n", e->cfg_file);
749
750 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg, "experiment",
751 "masters",
752 &e->num_masters))
753 {
754 fprintf (stderr, "Invalid %s", "masters");
755 free_experiment (e);
756 return NULL;
757 }
758 else
759 fprintf (stderr, "Experiment masters: `%llu'\n",
760 e->num_masters);
761
762 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg, "experiment",
763 "slaves",
764 &e->num_slaves))
765 {
766 fprintf (stderr, "Invalid %s", "slaves");
767 free_experiment (e);
768 return NULL;
769 }
770 else
771 fprintf (stderr, "Experiment slaves: `%llu'\n",
772 e->num_slaves);
773
774 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg, "experiment",
775 "log_freq",
776 &e->log_freq))
777 {
778 fprintf (stderr, "Invalid %s", "log_freq");
779 free_experiment (e);
780 return NULL;
781 }
782 else
783 fprintf (stderr, "Experiment logging frequency: `%s'\n",
784 GNUNET_STRINGS_relative_time_to_string (e->log_freq, GNUNET_YES));
785
786 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg, "experiment",
787 "max_duration",
788 &e->max_duration))
789 {
790 fprintf (stderr, "Invalid %s", "max_duration");
791 free_experiment (e);
792 return NULL;
793 }
794 else
795 fprintf (stderr, "Experiment duration: `%s'\n",
796 GNUNET_STRINGS_relative_time_to_string (e->max_duration,
797 GNUNET_YES));
798
799 load_episodes (e, cfg);
800 fprintf (stderr, "Loaded %u episodes with total duration %s\n",
801 e->num_episodes,
802 GNUNET_STRINGS_relative_time_to_string (e->total_duration,
803 GNUNET_YES));
804
805 GNUNET_CONFIGURATION_destroy (cfg);
806 return e;
807}
808
809
810void
811GNUNET_ATS_solvers_experimentation_stop (struct Experiment *e)
812{
813 if (NULL != e->experiment_timeout_task)
814 {
815 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
816 e->experiment_timeout_task = NULL;
817 }
818 if (NULL != e->episode_timeout_task)
819 {
820 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
821 e->episode_timeout_task = NULL;
822 }
823 free_experiment (e);
824}
825
826
827/**
828 * Solver
829 */
830
831struct GNUNET_ATS_TESTING_SolverHandle
832{
833 char *plugin;
834 struct GNUNET_ATS_PluginEnvironment env;
835 void *solver;
836};
837
838enum GNUNET_ATS_Solvers
839{
840 GNUNET_ATS_SOLVER_PROPORTIONAL,
841 GNUNET_ATS_SOLVER_MLP,
842 GNUNET_ATS_SOLVER_RIL,
843};
844
845void
846GNUNET_ATS_solvers_solver_stop (struct GNUNET_ATS_TESTING_SolverHandle *sh)
847{
848 GNUNET_PLUGIN_unload (sh->plugin, sh->solver);
849 GNUNET_free (sh->plugin);
850 GNUNET_free (sh);
851}
852
853
854struct GNUNET_ATS_TESTING_SolverHandle *
855GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
856{
857 struct GNUNET_ATS_TESTING_SolverHandle *sh;
858 char *solver_str;
859
860 switch (type)
861 {
862 case GNUNET_ATS_SOLVER_PROPORTIONAL:
863 solver_str = "proportional";
864 break;
865
866 case GNUNET_ATS_SOLVER_MLP:
867 solver_str = "mlp";
868 break;
869
870 case GNUNET_ATS_SOLVER_RIL:
871 solver_str = "ril";
872 break;
873
874 default:
875 GNUNET_break (0);
876 return NULL;
877 break;
878 }
879
880 sh = GNUNET_new (struct GNUNET_ATS_TESTING_SolverHandle);
881 GNUNET_asprintf (&sh->plugin, "libgnunet_plugin_ats_%s", solver_str);
882 // sh->solver = GNUNET_PLUGIN_load (sh->plugin, &sh->env);
883 if (NULL == sh->solver)
884 {
885 fprintf (stderr, "Failed to load solver `%s'\n", sh->plugin);
886 exit (1);
887 }
888
889 return sh;
890}
891
892
893static struct Experiment *e;
894
895static struct GNUNET_ATS_TESTING_SolverHandle *sh;
896
897/**
898 * cmd option -e: experiment file
899 */
900static char *opt_exp_file;
901
902static char *opt_solver;
903
904/**
905 * cmd option -l: enable logging
906 */
907static int opt_log;
908
909/**
910 * cmd option -p: enable plots
911 */
912static int opt_plot;
913
914/**
915 * cmd option -v: verbose logs
916 */
917static int opt_verbose;
918
919static void
920run (void *cls, char *const *args, const char *cfgfile,
921 const struct GNUNET_CONFIGURATION_Handle *cfg)
922{
923 enum GNUNET_ATS_Solvers solver;
924
925 if (NULL == opt_exp_file)
926 {
927 fprintf (stderr, "No experiment given ...\n");
928 exit (1);
929 }
930
931 if (NULL == opt_solver)
932 {
933 fprintf (stderr, "No solver given ...\n");
934 exit (1);
935 }
936
937 if (0 == strcmp (opt_solver, "mlp"))
938 {
939 solver = GNUNET_ATS_SOLVER_MLP;
940 }
941 else if (0 == strcmp (opt_solver, "proportional"))
942 {
943 solver = GNUNET_ATS_SOLVER_PROPORTIONAL;
944 }
945 else if (0 == strcmp (opt_solver, "ril"))
946 {
947 solver = GNUNET_ATS_SOLVER_RIL;
948 }
949 else
950 {
951 fprintf (stderr, "No solver given ...");
952 return;
953 }
954
955 /* load experiment */
956 e = GNUNET_ATS_solvers_experimentation_load (opt_exp_file);
957 if (NULL == e)
958 {
959 fprintf (stderr, "Failed to load experiment ...\n");
960 return;
961 }
962
963 /* load solver */
964 sh = GNUNET_ATS_solvers_solver_start (solver);
965 if (NULL == sh)
966 {
967 fprintf (stderr, "Failed to start solver ...\n");
968 return;
969 }
970
971 /* start logging */
972
973 /* run experiment */
974
975 /* WAIT */
976}
977
978
979/**
980 * Main function of the benchmark
981 *
982 * @param argc argument count
983 * @param argv argument values
984 */
985int
986main (int argc, char *argv[])
987{
988 opt_exp_file = NULL;
989 opt_solver = NULL;
990 opt_log = GNUNET_NO;
991 opt_plot = GNUNET_NO;
992
993 struct GNUNET_GETOPT_CommandLineOption options[] = {
994 GNUNET_GETOPT_option_string ('s',
995 "solver",
996 NULL,
997 gettext_noop ("solver to use"),
998 &opt_solver),
999
1000 GNUNET_GETOPT_option_string ('e',
1001 "experiment",
1002 NULL,
1003 gettext_noop ("experiment to use"),
1004 &opt_exp_file),
1005
1006 GNUNET_GETOPT_option_flag ('e',
1007 "experiment",
1008 gettext_noop ("experiment to use"),
1009 &opt_verbose),
1010 GNUNET_GETOPT_OPTION_END
1011 };
1012
1013 if (GNUNET_OK !=
1014 GNUNET_PROGRAM_run (argc,
1015 argv, argv[0],
1016 NULL,
1017 options,
1018 &run, argv[0]))
1019 return 1;
1020
1021 return 0;
1022}
1023
1024
1025/* end of file gnunet-solver-eval.c*/
diff --git a/src/ats-tests/gnunet_ats_sim_default.conf b/src/ats-tests/gnunet_ats_sim_default.conf
deleted file mode 100644
index a838306c3..000000000
--- a/src/ats-tests/gnunet_ats_sim_default.conf
+++ /dev/null
@@ -1,6 +0,0 @@
1@INLINE@ template_perf_ats.conf
2[transport]
3plugins = unix
4
5[ats]
6MODE = proportional
diff --git a/src/ats-tests/perf_ats.c b/src/ats-tests/perf_ats.c
deleted file mode 100644
index 64756b8aa..000000000
--- a/src/ats-tests/perf_ats.c
+++ /dev/null
@@ -1,601 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2013, 2016 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 ats/perf_ats.c
22 * @brief ats benchmark: start peers and modify preferences, monitor change over time
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testbed_service.h"
29#include "gnunet_ats_service.h"
30#include "gnunet_core_service.h"
31#include "ats-testing.h"
32
33
34#define TEST_ATS_PREFRENCE_FREQUENCY GNUNET_TIME_relative_multiply ( \
35 GNUNET_TIME_UNIT_SECONDS, 1)
36#define TEST_ATS_PREFRENCE_START 1.0
37#define TEST_ATS_PREFRENCE_DELTA 1.0
38
39#define TEST_MESSAGE_FREQUENCY GNUNET_TIME_relative_multiply ( \
40 GNUNET_TIME_UNIT_SECONDS, 1)
41
42#define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, \
43 120)
44#define BENCHMARK_DURATION GNUNET_TIME_relative_multiply ( \
45 GNUNET_TIME_UNIT_SECONDS, 10)
46#define LOGGING_FREQUENCY GNUNET_TIME_relative_multiply ( \
47 GNUNET_TIME_UNIT_MILLISECONDS, 500)
48#define TESTNAME_PREFIX "perf_ats_"
49#define DEFAULT_SLAVES_NUM 2
50#define DEFAULT_MASTERS_NUM 1
51
52/**
53 * timeout task
54 */
55static struct GNUNET_SCHEDULER_Task *timeout_task;
56
57/**
58 * Progress task
59 */
60static struct GNUNET_SCHEDULER_Task *progress_task;
61
62/**
63 * Test result
64 */
65static int result;
66
67/**
68 * Test result logging
69 */
70static int logging;
71
72/**
73 * Test core (#GNUNET_YES) or transport (#GNUNET_NO)
74 */
75static int test_core;
76
77/**
78 * Solver string
79 */
80static char *solver;
81
82/**
83 * Preference string
84 */
85static char *testname;
86
87/**
88 * Preference string
89 */
90static char *pref_str;
91
92/**
93 * ATS preference value
94 */
95static int pref_val;
96
97/**
98 * Benchmark duration
99 */
100static struct GNUNET_TIME_Relative perf_duration;
101
102/**
103 * Logging frequency
104 */
105static struct GNUNET_TIME_Relative log_frequency;
106
107/**
108 * Number master peers
109 */
110static unsigned int num_masters;
111
112/**
113 * Array of master peers
114 */
115static struct BenchmarkPeer *mps;
116
117/**
118 * Number slave peers
119 */
120static unsigned int num_slaves;
121
122/**
123 * Array of master peers
124 */
125static struct BenchmarkPeer *sps;
126
127static struct LoggingHandle *l;
128
129
130static void
131evaluate ()
132{
133 int c_m;
134 int c_s;
135 unsigned int duration;
136 struct BenchmarkPeer *mp;
137 struct BenchmarkPartner *p;
138
139 unsigned int kb_sent_sec;
140 double kb_sent_percent;
141 unsigned int kb_recv_sec;
142 double kb_recv_percent;
143 unsigned int rtt;
144
145 duration = 1 + (perf_duration.rel_value_us / (1000 * 1000));
146 for (c_m = 0; c_m < num_masters; c_m++)
147 {
148 mp = &mps[c_m];
149 fprintf (stderr,
150 "Master [%u]: sent: %u KiB in %u sec. = %u KiB/s, received: %u KiB in %u sec. = %u KiB/s\n",
151 mp->no, mp->total_bytes_sent / 1024, duration,
152 (mp->total_bytes_sent / 1024) / duration,
153 mp->total_bytes_received / 1024, duration,
154 (mp->total_bytes_received / 1024) / duration);
155
156 for (c_s = 0; c_s < num_slaves; c_s++)
157 {
158 p = &mp->partners[c_s];
159 kb_sent_sec = 0;
160 kb_recv_sec = 0;
161 kb_sent_percent = 0.0;
162 kb_recv_percent = 0.0;
163 rtt = 0;
164
165 if (duration > 0)
166 {
167 kb_sent_sec = (p->bytes_sent / 1024) / duration;
168 kb_recv_sec = (p->bytes_received / 1024) / duration;
169 }
170
171 if (mp->total_bytes_sent > 0)
172 kb_sent_percent = ((double) p->bytes_sent * 100) / mp->total_bytes_sent;
173 if (mp->total_bytes_received > 0)
174 kb_recv_percent = ((double) p->bytes_received * 100)
175 / mp->total_bytes_received;
176 if (1000 * p->messages_sent > 0)
177 rtt = p->total_app_rtt / (1000 * p->messages_sent);
178 fprintf (stderr,
179 "%c Master [%u] -> Slave [%u]: sent %u KiB/s (%.2f %%), received %u KiB/s (%.2f %%)\n",
180 (mp->pref_partner == p->dest) ? '*' : ' ',
181 mp->no, p->dest->no,
182 kb_sent_sec, kb_sent_percent,
183 kb_recv_sec, kb_recv_percent);
184 fprintf (stderr,
185 "%c Master [%u] -> Slave [%u]: Average application layer RTT: %u ms\n",
186 (mp->pref_partner == p->dest) ? '*' : ' ',
187 mp->no, p->dest->no, rtt);
188 }
189 }
190}
191
192
193/**
194 * Shutdown nicely
195 *
196 * @param cls NULL
197 */
198static void
199do_shutdown (void *cls)
200{
201 if (GNUNET_YES == logging)
202 GNUNET_ATS_TEST_logging_clean_up (l);
203 if (NULL != timeout_task)
204 {
205 GNUNET_SCHEDULER_cancel (timeout_task);
206 timeout_task = NULL;
207 }
208 if (NULL != progress_task)
209 {
210 fprintf (stderr, "0\n");
211 GNUNET_SCHEDULER_cancel (progress_task);
212 progress_task = NULL;
213 }
214 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
215 "Benchmarking done\n");
216 GNUNET_ATS_TEST_shutdown_topology ();
217}
218
219
220/**
221 * Shutdown nicely
222 *
223 * @param cls NULL
224 */
225static void
226do_timeout (void *cls)
227{
228 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
229 "Terminating with timeout\n");
230 timeout_task = NULL;
231 evaluate ();
232 GNUNET_SCHEDULER_shutdown ();
233}
234
235
236static void
237print_progress (void *cls)
238{
239 static int calls;
240
241 progress_task = NULL;
242 fprintf (stderr,
243 "%llu..",
244 (long long unsigned) perf_duration.rel_value_us / (1000 * 1000)
245 - calls);
246 calls++;
247
248 progress_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
249 &print_progress,
250 NULL);
251}
252
253
254static void
255ats_pref_task (void *cls)
256{
257 struct BenchmarkPeer *me = cls;
258
259 me->ats_task = NULL;
260
261 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
262 " Master [%u] set preference for slave [%u] to %f\n",
263 me->no, me->pref_partner->no, me->pref_value);
264 GNUNET_ATS_performance_change_preference (me->ats_perf_handle,
265 &me->pref_partner->id,
266 pref_val, me->pref_value,
267 GNUNET_ATS_PREFERENCE_END);
268 me->pref_value += TEST_ATS_PREFRENCE_DELTA;
269 me->ats_task = GNUNET_SCHEDULER_add_delayed (TEST_ATS_PREFRENCE_FREQUENCY,
270 &ats_pref_task, cls);
271}
272
273
274static void
275start_benchmark (void *cls)
276{
277 int c_m;
278 int c_s;
279
280 progress_task = GNUNET_SCHEDULER_add_now (&print_progress,
281 NULL);
282
283 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
284 "Topology connected, start benchmarking...\n");
285
286 /* Start sending test messages */
287 for (c_m = 0; c_m < num_masters; c_m++)
288 {
289 for (c_s = 0; c_s < num_slaves; c_s++)
290 {
291 GNUNET_ATS_TEST_generate_traffic_start (&mps[c_m],
292 &mps[c_m].partners[c_s],
293 GNUNET_ATS_TEST_TG_LINEAR,
294 UINT32_MAX,
295 UINT32_MAX,
296 GNUNET_TIME_UNIT_MINUTES,
297 GNUNET_TIME_UNIT_FOREVER_REL);
298 }
299 if (pref_val != GNUNET_ATS_PREFERENCE_END)
300 mps[c_m].ats_task = GNUNET_SCHEDULER_add_now (&ats_pref_task,
301 &mps[c_m]);
302 }
303
304 if (GNUNET_YES == logging)
305 l = GNUNET_ATS_TEST_logging_start (log_frequency,
306 testname, mps,
307 num_masters, num_slaves,
308 GNUNET_NO);
309}
310
311
312static void
313do_benchmark (void *cls,
314 struct BenchmarkPeer *masters,
315 struct BenchmarkPeer *slaves)
316{
317 mps = masters;
318 sps = slaves;
319 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
320 NULL);
321 timeout_task = GNUNET_SCHEDULER_add_delayed (perf_duration,
322 &do_timeout,
323 NULL);
324 progress_task = GNUNET_SCHEDULER_add_now (&start_benchmark,
325 NULL);
326}
327
328
329static struct BenchmarkPartner *
330find_partner (struct BenchmarkPeer *me,
331 const struct GNUNET_PeerIdentity *peer)
332{
333 int c_m;
334
335 GNUNET_assert (NULL != me);
336 GNUNET_assert (NULL != peer);
337
338 for (c_m = 0; c_m < me->num_partners; c_m++)
339 {
340 /* Find a partner with other as destination */
341 if (0 == GNUNET_memcmp (peer, &me->partners[c_m].dest->id))
342 {
343 return &me->partners[c_m];
344 }
345 }
346 return NULL;
347}
348
349
350static void
351log_request_cb (void *cls,
352 const struct GNUNET_HELLO_Address *address,
353 int address_active,
354 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
355 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
356 const struct GNUNET_ATS_Properties *ats)
357{
358 struct BenchmarkPeer *me = cls;
359 struct BenchmarkPartner *p;
360 char *peer_id;
361
362 p = find_partner (me, &address->peer);
363 if (NULL == p)
364 {
365 /* This is not one of my partners
366 * Will happen since the peers will connect to each other due to gossiping
367 */
368 return;
369 }
370 peer_id = GNUNET_strdup (GNUNET_i2s (&me->id));
371
372 if ((p->bandwidth_in != ntohl (bandwidth_in.value__)) ||
373 (p->bandwidth_out != ntohl (bandwidth_out.value__)))
374 p->bandwidth_in = ntohl (bandwidth_in.value__);
375 p->bandwidth_out = ntohl (bandwidth_out.value__);
376
377 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
378 "%s [%u] received ATS information for peers `%s'\n",
379 (GNUNET_YES == p->me->master) ? "Master" : "Slave",
380 p->me->no,
381 GNUNET_i2s (&p->dest->id));
382
383 GNUNET_free (peer_id);
384 if (NULL != l)
385 GNUNET_ATS_TEST_logging_now (l);
386}
387
388
389/*
390 * Start the performance test case
391 */
392int
393main (int argc, char *argv[])
394{
395 char *tmp;
396 char *tmp_sep;
397 char *test_name;
398 char *conf_name;
399 char *comm_name;
400 char *dotexe;
401 char *prefs[] = GNUNET_ATS_PreferenceTypeString;
402 int c;
403
404 result = 0;
405
406 /* Determine testname
407 * perf_ats_<solver>_<transport>_<preference>[.exe]*/
408
409 /* Find test prefix, store in temp */
410 tmp = strstr (argv[0], TESTNAME_PREFIX);
411 if (NULL == tmp)
412 {
413 fprintf (stderr, "Unable to parse test name `%s'\n", argv[0]);
414 return GNUNET_SYSERR;
415 }
416
417 /* Set tmp to end of test name prefix */
418 tmp += strlen (TESTNAME_PREFIX);
419
420 /* Determine solver name */
421 solver = GNUNET_strdup (tmp);
422 /* Remove .exe prefix */
423 if ((NULL != (dotexe = strstr (solver, ".exe"))) && (dotexe[4] == '\0'))
424 dotexe[0] = '\0';
425
426 /* Determine first '_' after solver */
427 tmp_sep = strchr (solver, '_');
428 if (NULL == tmp_sep)
429 {
430 fprintf (stderr, "Unable to parse test name `%s'\n", argv[0]);
431 GNUNET_free (solver);
432 return GNUNET_SYSERR;
433 }
434 tmp_sep[0] = '\0';
435 comm_name = GNUNET_strdup (&tmp_sep[1]);
436 tmp_sep = strchr (comm_name, '_');
437 if (NULL == tmp_sep)
438 {
439 fprintf (stderr, "Unable to parse test name `%s'\n", argv[0]);
440 GNUNET_free (solver);
441 return GNUNET_SYSERR;
442 }
443 tmp_sep[0] = '\0';
444 for (c = 0; c <= strlen (comm_name); c++)
445 comm_name[c] = toupper (comm_name[c]);
446 if (0 == strcmp (comm_name, "CORE"))
447 test_core = GNUNET_YES;
448 else if (0 == strcmp (comm_name, "TRANSPORT"))
449 test_core = GNUNET_NO;
450 else
451 {
452 GNUNET_free (comm_name);
453 GNUNET_free (solver);
454 return GNUNET_SYSERR;
455 }
456
457 pref_str = GNUNET_strdup (tmp_sep + 1);
458
459 GNUNET_asprintf (&conf_name, "%s%s_%s.conf", TESTNAME_PREFIX, solver,
460 pref_str);
461 GNUNET_asprintf (&test_name, "%s%s_%s", TESTNAME_PREFIX, solver, pref_str);
462
463 for (c = 0; c <= strlen (pref_str); c++)
464 pref_str[c] = toupper (pref_str[c]);
465 pref_val = -1;
466
467 if (0 != strcmp (pref_str, "NONE"))
468 {
469 for (c = 0; c < GNUNET_ATS_PREFERENCE_END; c++)
470 {
471 if (0 == strcmp (pref_str, prefs[c]))
472 {
473 pref_val = c;
474 break;
475 }
476 }
477 }
478 else
479 {
480 /* abuse terminator to indicate no pref */
481 pref_val = GNUNET_ATS_PREFERENCE_END;
482 }
483 if (-1 == pref_val)
484 {
485 fprintf (stderr, "Unknown preference: `%s'\n", pref_str);
486 GNUNET_free (solver);
487 GNUNET_free (pref_str);
488 GNUNET_free (comm_name);
489 return -1;
490 }
491
492 for (c = 0; c < (argc - 1); c++)
493 {
494 if (0 == strcmp (argv[c], "-d"))
495 break;
496 }
497 if (c < argc - 1)
498 {
499 if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_relative (argv[c + 1],
500 &perf_duration))
501 fprintf (stderr, "Failed to parse duration `%s'\n", argv[c + 1]);
502 }
503 else
504 {
505 perf_duration = BENCHMARK_DURATION;
506 }
507 fprintf (stderr, "Running benchmark for %llu secs\n", (unsigned long
508 long) (perf_duration.
509 rel_value_us)
510 / (1000 * 1000));
511
512 for (c = 0; c < (argc - 1); c++)
513 {
514 if (0 == strcmp (argv[c], "-s"))
515 break;
516 }
517 if (c < argc - 1)
518 {
519 if ((0L != (num_slaves = strtol (argv[c + 1], NULL, 10)))
520 && (num_slaves >= 1))
521 fprintf (stderr, "Starting %u slave peers\n", num_slaves);
522 else
523 num_slaves = DEFAULT_SLAVES_NUM;
524 }
525 else
526 num_slaves = DEFAULT_SLAVES_NUM;
527
528 for (c = 0; c < (argc - 1); c++)
529 {
530 if (0 == strcmp (argv[c], "-m"))
531 break;
532 }
533 if (c < argc - 1)
534 {
535 if ((0L != (num_masters = strtol (argv[c + 1], NULL, 10)))
536 && (num_masters >= 2))
537 fprintf (stderr, "Starting %u master peers\n", num_masters);
538 else
539 num_masters = DEFAULT_MASTERS_NUM;
540 }
541 else
542 num_masters = DEFAULT_MASTERS_NUM;
543
544 logging = GNUNET_NO;
545 for (c = 0; c < argc; c++)
546 {
547 if (0 == strcmp (argv[c], "-l"))
548 logging = GNUNET_YES;
549 }
550
551 if (GNUNET_YES == logging)
552 {
553 for (c = 0; c < (argc - 1); c++)
554 {
555 if (0 == strcmp (argv[c], "-f"))
556 break;
557 }
558 if (c < argc - 1)
559 {
560 if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_relative (argv[c + 1],
561 &log_frequency))
562 fprintf (stderr, "Failed to parse duration `%s'\n", argv[c + 1]);
563 }
564 else
565 {
566 log_frequency = LOGGING_FREQUENCY;
567 }
568 fprintf (stderr, "Using log frequency %llu ms\n",
569 (unsigned long long) (log_frequency.rel_value_us) / (1000));
570 }
571
572 GNUNET_asprintf (&testname, "%s_%s_%s", solver, comm_name, pref_str);
573
574 if (num_slaves < num_masters)
575 {
576 fprintf (stderr,
577 "Number of master peers is lower than slaves! exit...\n");
578 GNUNET_free (test_name);
579 GNUNET_free (solver);
580 GNUNET_free (pref_str);
581 GNUNET_free (comm_name);
582 return GNUNET_SYSERR;
583 }
584
585 /**
586 * Setup the topology
587 */
588 GNUNET_ATS_TEST_create_topology ("perf-ats",
589 conf_name,
590 num_slaves,
591 num_masters,
592 test_core,
593 &do_benchmark,
594 NULL,
595 &log_request_cb);
596
597 return result;
598}
599
600
601/* end of file perf_ats.c */
diff --git a/src/ats-tests/perf_ats.h b/src/ats-tests/perf_ats.h
deleted file mode 100644
index 6460aa098..000000000
--- a/src/ats-tests/perf_ats.h
+++ /dev/null
@@ -1,256 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 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 ats/perf_ats.c
22 * @brief ats benchmark: start peers and modify preferences, monitor change over time
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testbed_service.h"
29#include "gnunet_ats_service.h"
30#include "gnunet_core_service.h"
31#include "ats-testing.h"
32
33#define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, \
34 120)
35#define BENCHMARK_DURATION GNUNET_TIME_relative_multiply ( \
36 GNUNET_TIME_UNIT_SECONDS, 10)
37#define LOGGING_FREQUENCY GNUNET_TIME_relative_multiply ( \
38 GNUNET_TIME_UNIT_MILLISECONDS, 500)
39#define TESTNAME_PREFIX "perf_ats_"
40#define DEFAULT_SLAVES_NUM 2
41#define DEFAULT_MASTERS_NUM 1
42
43#define TEST_ATS_PREFRENCE_FREQUENCY GNUNET_TIME_relative_multiply ( \
44 GNUNET_TIME_UNIT_SECONDS, 1)
45#define TEST_ATS_PREFRENCE_START 1.0
46#define TEST_ATS_PREFRENCE_DELTA 1.0
47
48#define TEST_MESSAGE_TYPE_PING 12345
49#define TEST_MESSAGE_TYPE_PONG 12346
50#define TEST_MESSAGE_SIZE 1000
51#define TEST_MESSAGE_FREQUENCY GNUNET_TIME_relative_multiply ( \
52 GNUNET_TIME_UNIT_SECONDS, 1)
53
54/**
55 * Information about a benchmarking partner
56 */
57struct BenchmarkPartner
58{
59 /**
60 * The peer itself this partner belongs to
61 */
62 struct BenchmarkPeer *me;
63
64 /**
65 * The partner peer
66 */
67 struct BenchmarkPeer *dest;
68
69 /**
70 * Core transmit handles
71 */
72 struct GNUNET_CORE_TransmitHandle *cth;
73
74 /**
75 * Transport transmit handles
76 */
77 struct GNUNET_TRANSPORT_TransmitHandle *tth;
78
79 /**
80 * Timestamp to calculate communication layer delay
81 */
82 struct GNUNET_TIME_Absolute last_message_sent;
83
84 /**
85 * Accumulated RTT for all messages
86 */
87 unsigned int total_app_rtt;
88
89 /**
90 * Number of messages sent to this partner
91 */
92 unsigned int messages_sent;
93
94 /**
95 * Number of bytes sent to this partner
96 */
97 unsigned int bytes_sent;
98
99 /**
100 * Number of messages received from this partner
101 */
102 unsigned int messages_received;
103
104 /**
105 * Number of bytes received from this partner
106 */
107 unsigned int bytes_received;
108
109 /* Current ATS properties */
110
111 uint32_t ats_distance;
112
113 uint32_t ats_delay;
114
115 uint32_t bandwidth_in;
116
117 uint32_t bandwidth_out;
118
119 uint32_t ats_utilization_up;
120
121 uint32_t ats_utilization_down;
122
123 uint32_t ats_network_type;
124
125 uint32_t ats_cost_wan;
126
127 uint32_t ats_cost_lan;
128
129 uint32_t ats_cost_wlan;
130};
131
132
133/**
134 * Information we track for a peer in the testbed.
135 */
136struct BenchmarkPeer
137{
138 /**
139 * Handle with testbed.
140 */
141 struct GNUNET_TESTBED_Peer *peer;
142
143 /**
144 * Unique identifier
145 */
146 int no;
147
148 /**
149 * Is this peer a measter: GNUNET_YES/GNUNET_NO
150 */
151 int master;
152
153 /**
154 * Peer ID
155 */
156 struct GNUNET_PeerIdentity id;
157
158 /**
159 * Testbed operation to get peer information
160 */
161 struct GNUNET_TESTBED_Operation *peer_id_op;
162
163 /**
164 * Testbed operation to connect to ATS performance service
165 */
166 struct GNUNET_TESTBED_Operation *ats_perf_op;
167
168 /**
169 * Testbed operation to connect to core
170 */
171 struct GNUNET_TESTBED_Operation *comm_op;
172
173 /**
174 * ATS performance handle
175 */
176 struct GNUNET_ATS_PerformanceHandle *ats_perf_handle;
177
178 /**
179 * Masters only:
180 * Testbed connect operations to connect masters to slaves
181 */
182 struct TestbedConnectOperation *core_connect_ops;
183
184 /**
185 * Core handle
186 */
187 struct GNUNET_CORE_Handle *ch;
188
189 /**
190 * Core handle
191 */
192 struct GNUNET_TRANSPORT_Handle *th;
193
194 /**
195 * Masters only:
196 * Peer to set ATS preferences for
197 */
198 struct BenchmarkPeer *pref_partner;
199
200 /**
201 * Masters only
202 * Progress task
203 */
204 struct GNUNET_SCHEDULER_Task *ats_task;
205
206 /**
207 * Masters only
208 * Progress task
209 */
210 double pref_value;
211
212 /**
213 * Array of partners with num_slaves entries (if master) or
214 * num_master entries (if slave)
215 */
216 struct BenchmarkPartner *partners;
217
218 /**
219 * Number of partners
220 */
221 int num_partners;
222
223 /**
224 * Number of core connections
225 */
226 int core_connections;
227
228 /**
229 * Masters only:
230 * Number of connections to slave peers
231 */
232 int core_slave_connections;
233
234 /**
235 * Total number of messages this peer has sent
236 */
237 unsigned int total_messages_sent;
238
239 /**
240 * Total number of bytes this peer has sent
241 */
242 unsigned int total_bytes_sent;
243
244 /**
245 * Total number of messages this peer has received
246 */
247 unsigned int total_messages_received;
248
249 /**
250 * Total number of bytes this peer has received
251 */
252 unsigned int total_bytes_received;
253};
254
255
256/* end of file perf_ats.h */
diff --git a/src/ats-tests/perf_ats_logging.c b/src/ats-tests/perf_ats_logging.c
deleted file mode 100644
index ac8fa8950..000000000
--- a/src/ats-tests/perf_ats_logging.c
+++ /dev/null
@@ -1,780 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 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 ats/perf_ats_logging.c
22 * @brief ats benchmark: logging for performance tests
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "perf_ats.h"
29
30#define THROUGHPUT_TEMPLATE "#!/usr/bin/gnuplot \n" \
31 "set datafile separator ';' \n" \
32 "set title \"Throughput between Master and Slaves\" \n" \
33 "set xlabel \"Time in ms\" \n" \
34 "set ylabel \"Bytes/s\" \n" \
35 "set grid \n"
36
37#define RTT_TEMPLATE "#!/usr/bin/gnuplot \n" \
38 "set datafile separator ';' \n" \
39 "set title \"Application level roundtrip time between Master and Slaves\" \n" \
40 "set xlabel \"Time in ms\" \n" \
41 "set ylabel \"ms\" \n" \
42 "set grid \n"
43
44#define BW_TEMPLATE "#!/usr/bin/gnuplot \n" \
45 "set datafile separator ';' \n" \
46 "set title \"Bandwidth inbound and outbound between Master and Slaves\" \n" \
47 "set xlabel \"Time in ms\" \n" \
48 "set ylabel \"Bytes / s \" \n" \
49 "set grid \n"
50
51#define LOG_ITEMS_TIME 2
52#define LOG_ITEMS_PER_PEER 17
53
54#define LOG_ITEM_BYTES_SENT 1
55#define LOG_ITEM_MSGS_SENT 2
56#define LOG_ITEM_THROUGHPUT_SENT 3
57#define LOG_ITEM_BYTES_RECV 4
58#define LOG_ITEM_MSGS_RECV 5
59#define LOG_ITEM_THROUGHPUT_RECV 6
60#define LOG_ITEM_APP_RTT 7
61#define LOG_ITEM_ATS_BW_IN 8
62#define LOG_ITEM_ATS_BW_OUT 9
63#define LOG_ITEM_ATS_COSTS_LAN 10
64#define LOG_ITEM_ATS_WAN 11
65#define LOG_ITEM_ATS_WLAN 12
66#define LOG_ITEM_ATS_DELAY 13
67#define LOG_ITEM_ATS_DISTANCE 14
68#define LOG_ITEM_ATS_NETWORKTYPE 15
69#define LOG_ITEM_ATS_UTIL_UP 16
70#define LOG_ITEM_ATS_UTIL_DOWN 17
71
72/**
73 * Logging task
74 */
75static struct GNUNET_SCHEDULER_Task *log_task;
76
77/**
78 * Reference to perf_ats' masters
79 */
80static int num_peers;
81static int running;
82static char *name;
83static struct GNUNET_TIME_Relative frequency;
84
85/**
86 * A single logging time step for a partner
87 */
88struct PartnerLoggingTimestep
89{
90 /**
91 * Peer
92 */
93 struct BenchmarkPeer *slave;
94
95 /**
96 * Total number of messages this peer has sent
97 */
98 unsigned int total_messages_sent;
99
100 /**
101 * Total number of bytes this peer has sent
102 */
103 unsigned int total_bytes_sent;
104
105 /**
106 * Total number of messages this peer has received
107 */
108 unsigned int total_messages_received;
109
110 /**
111 * Total number of bytes this peer has received
112 */
113 unsigned int total_bytes_received;
114
115 /**
116 * Total outbound throughput for master in Bytes / s
117 */
118 unsigned int throughput_sent;
119
120 /**
121 * Total inbound throughput for master in Bytes / s
122 */
123 unsigned int throughput_recv;
124
125 /**
126 * Accumulated RTT for all messages
127 */
128 unsigned int total_app_rtt;
129
130 /**
131 * Current application level delay
132 */
133 unsigned int app_rtt;
134
135 /* Current ATS properties */
136
137 uint32_t ats_distance;
138
139 uint32_t ats_delay;
140
141 uint32_t bandwidth_in;
142
143 uint32_t bandwidth_out;
144
145 uint32_t ats_utilization_up;
146
147 uint32_t ats_utilization_down;
148
149 uint32_t ats_network_type;
150
151 uint32_t ats_cost_wan;
152
153 uint32_t ats_cost_lan;
154
155 uint32_t ats_cost_wlan;
156};
157
158
159/**
160 * A single logging time step for a peer
161 */
162struct PeerLoggingTimestep
163{
164 /**
165 * Next in DLL
166 */
167 struct PeerLoggingTimestep *next;
168
169 /**
170 * Prev in DLL
171 */
172 struct PeerLoggingTimestep *prev;
173
174 /**
175 * Logging timestamp
176 */
177 struct GNUNET_TIME_Absolute timestamp;
178
179 /**
180 * Total number of messages this peer has sent
181 */
182 unsigned int total_messages_sent;
183
184 /**
185 * Total number of bytes this peer has sent
186 */
187 unsigned int total_bytes_sent;
188
189 /**
190 * Total number of messages this peer has received
191 */
192 unsigned int total_messages_received;
193
194 /**
195 * Total number of bytes this peer has received
196 */
197 unsigned int total_bytes_received;
198
199 /**
200 * Total outbound throughput for master in Bytes / s
201 */
202 unsigned int total_throughput_send;
203
204 /**
205 * Total inbound throughput for master in Bytes / s
206 */
207 unsigned int total_throughput_recv;
208
209 /**
210 * Logs for slaves
211 */
212 struct PartnerLoggingTimestep *slaves_log;
213};
214
215/**
216 * Entry for a benchmark peer
217 */
218struct LoggingPeer
219{
220 /**
221 * Peer
222 */
223 struct BenchmarkPeer *peer;
224
225 /**
226 * Start time
227 */
228 struct GNUNET_TIME_Absolute start;
229
230 /**
231 * DLL for logging entries: head
232 */
233 struct PeerLoggingTimestep *head;
234
235 /**
236 * DLL for logging entries: tail
237 */
238 struct PeerLoggingTimestep *tail;
239};
240
241/**
242 * Log structure of length num_peers
243 */
244static struct LoggingPeer *lp;
245
246
247static void
248write_throughput_gnuplot_script (char *fn, struct LoggingPeer *lp)
249{
250 struct GNUNET_DISK_FileHandle *f;
251 char *gfn;
252 char *data;
253 int c_s;
254 int peer_index;
255
256 GNUNET_asprintf (&gfn, "gnuplot_throughput_%s", fn);
257 f = GNUNET_DISK_file_open (gfn,
258 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
259 GNUNET_DISK_PERM_USER_EXEC
260 | GNUNET_DISK_PERM_USER_READ
261 | GNUNET_DISK_PERM_USER_WRITE);
262 if (NULL == f)
263 {
264 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n",
265 gfn);
266 GNUNET_free (gfn);
267 return;
268 }
269
270 /* Write header */
271
272 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, THROUGHPUT_TEMPLATE, strlen (
273 THROUGHPUT_TEMPLATE)))
274 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
275 "Cannot write data to plot file `%s'\n", gfn);
276
277 /* Write master data */
278 peer_index = LOG_ITEMS_TIME;
279 GNUNET_asprintf (&data,
280 "plot '%s' using 2:%u with lines title 'Master %u send total', \\\n" \
281 "'%s' using 2:%u with lines title 'Master %u receive total', \\\n",
282 fn, peer_index + LOG_ITEM_THROUGHPUT_SENT, lp->peer->no,
283 fn, peer_index + LOG_ITEM_THROUGHPUT_RECV, lp->peer->no);
284 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, data, strlen (data)))
285 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
286 "Cannot write data to plot file `%s'\n", gfn);
287 GNUNET_free (data);
288
289 peer_index = LOG_ITEMS_TIME + LOG_ITEMS_PER_PEER;
290 for (c_s = 0; c_s < lp->peer->num_partners; c_s++)
291 {
292 GNUNET_asprintf (&data,
293 "'%s' using 2:%u with lines title 'Master %u - Slave %u send', \\\n" \
294 "'%s' using 2:%u with lines title 'Master %u - Slave %u receive'%s\n",
295 fn, peer_index + LOG_ITEM_THROUGHPUT_SENT, lp->peer->no,
296 lp->peer->partners[c_s].dest->no,
297 fn, peer_index + LOG_ITEM_THROUGHPUT_RECV, lp->peer->no,
298 lp->peer->partners[c_s].dest->no,
299 (c_s < lp->peer->num_partners - 1) ? ", \\" :
300 "\n pause -1");
301 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, data, strlen (data)))
302 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
303 "Cannot write data to plot file `%s'\n", gfn);
304 GNUNET_free (data);
305 peer_index += LOG_ITEMS_PER_PEER;
306 }
307
308 if (GNUNET_SYSERR == GNUNET_DISK_file_close (f))
309 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n",
310 gfn);
311 else
312 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
313 "Data successfully written to plot file `%s'\n", gfn);
314
315 GNUNET_free (gfn);
316}
317
318
319static void
320write_rtt_gnuplot_script (char *fn, struct LoggingPeer *lp)
321{
322 struct GNUNET_DISK_FileHandle *f;
323 char *gfn;
324 char *data;
325 int c_s;
326 int index;
327
328 GNUNET_asprintf (&gfn, "gnuplot_rtt_%s", fn);
329 f = GNUNET_DISK_file_open (gfn,
330 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
331 GNUNET_DISK_PERM_USER_EXEC
332 | GNUNET_DISK_PERM_USER_READ
333 | GNUNET_DISK_PERM_USER_WRITE);
334 if (NULL == f)
335 {
336 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n",
337 gfn);
338 GNUNET_free (gfn);
339 return;
340 }
341
342 /* Write header */
343
344 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, RTT_TEMPLATE, strlen (
345 RTT_TEMPLATE)))
346 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
347 "Cannot write data to plot file `%s'\n", gfn);
348
349 index = LOG_ITEMS_TIME + LOG_ITEMS_PER_PEER;
350 for (c_s = 0; c_s < lp->peer->num_partners; c_s++)
351 {
352 GNUNET_asprintf (&data,
353 "%s'%s' using 2:%u with lines title 'Master %u - Slave %u '%s\n",
354 (0 == c_s) ? "plot " : "",
355 fn, index + LOG_ITEM_APP_RTT, lp->peer->no,
356 lp->peer->partners[c_s].dest->no,
357 (c_s < lp->peer->num_partners - 1) ? ", \\" :
358 "\n pause -1");
359 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, data, strlen (data)))
360 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
361 "Cannot write data to plot file `%s'\n", gfn);
362 GNUNET_free (data);
363 index += LOG_ITEMS_PER_PEER;
364 }
365
366 if (GNUNET_SYSERR == GNUNET_DISK_file_close (f))
367 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n",
368 gfn);
369 else
370 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
371 "Data successfully written to plot file `%s'\n", gfn);
372 GNUNET_free (gfn);
373}
374
375
376static void
377write_bw_gnuplot_script (char *fn, struct LoggingPeer *lp)
378{
379 struct GNUNET_DISK_FileHandle *f;
380 char *gfn;
381 char *data;
382 int c_s;
383 int index;
384
385 GNUNET_asprintf (&gfn, "gnuplot_bw_%s", fn);
386 f = GNUNET_DISK_file_open (gfn,
387 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
388 GNUNET_DISK_PERM_USER_EXEC
389 | GNUNET_DISK_PERM_USER_READ
390 | GNUNET_DISK_PERM_USER_WRITE);
391 if (NULL == f)
392 {
393 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n",
394 gfn);
395 GNUNET_free (gfn);
396 return;
397 }
398
399 /* Write header */
400
401 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, BW_TEMPLATE, strlen (
402 BW_TEMPLATE)))
403 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
404 "Cannot write data to plot file `%s'\n", gfn);
405
406 index = LOG_ITEMS_TIME + LOG_ITEMS_PER_PEER;
407 for (c_s = 0; c_s < lp->peer->num_partners; c_s++)
408 {
409 GNUNET_asprintf (&data, "%s" \
410 "'%s' using 2:%u with lines title 'BW out master %u - Slave %u ', \\\n" \
411 "'%s' using 2:%u with lines title 'BW in master %u - Slave %u '" \
412 "%s\n",
413 (0 == c_s) ? "plot " : "",
414 fn, index + LOG_ITEM_ATS_BW_OUT, lp->peer->no,
415 lp->peer->partners[c_s].dest->no,
416 fn, index + LOG_ITEM_ATS_BW_IN, lp->peer->no,
417 lp->peer->partners[c_s].dest->no,
418 (c_s < lp->peer->num_partners - 1) ? ", \\" :
419 "\n pause -1");
420 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, data, strlen (data)))
421 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
422 "Cannot write data to plot file `%s'\n", gfn);
423 GNUNET_free (data);
424 index += LOG_ITEMS_PER_PEER;
425 }
426
427 if (GNUNET_SYSERR == GNUNET_DISK_file_close (f))
428 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n",
429 gfn);
430 else
431 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
432 "Data successfully written to plot file `%s'\n", gfn);
433 GNUNET_free (gfn);
434}
435
436
437static void
438write_to_file ()
439{
440 struct GNUNET_DISK_FileHandle *f;
441
442 char *filename;
443 char *data;
444 char *slave_string;
445 char *slave_string_tmp;
446 struct PeerLoggingTimestep *cur_lt;
447 struct PartnerLoggingTimestep *plt;
448 int c_m;
449 int c_s;
450
451 for (c_m = 0; c_m < num_peers; c_m++)
452 {
453 GNUNET_asprintf (&filename, "%llu_master_%u_%s_%s.data",
454 GNUNET_TIME_absolute_get ().abs_value_us,
455 lp[c_m].peer->no, GNUNET_i2s (&lp[c_m].peer->id), name);
456
457 f = GNUNET_DISK_file_open (filename,
458 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
459 GNUNET_DISK_PERM_USER_READ
460 | GNUNET_DISK_PERM_USER_WRITE);
461 if (NULL == f)
462 {
463 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n",
464 filename);
465 GNUNET_free (filename);
466 return;
467 }
468
469 for (cur_lt = lp[c_m].head; NULL != cur_lt; cur_lt = cur_lt->next)
470 {
471 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
472 "Master [%u]: timestamp %llu %llu ; %u %u %u ; %u %u %u\n",
473 lp[c_m].peer->no,
474 cur_lt->timestamp, GNUNET_TIME_absolute_get_difference (
475 lp[c_m].start, cur_lt->timestamp).rel_value_us / 1000,
476 cur_lt->total_messages_sent, cur_lt->total_bytes_sent,
477 cur_lt->total_throughput_send,
478 cur_lt->total_messages_received, cur_lt->total_bytes_received,
479 cur_lt->total_throughput_recv);
480
481 slave_string = GNUNET_strdup (";");
482 for (c_s = 0; c_s < lp[c_m].peer->num_partners; c_s++)
483 {
484 plt = &cur_lt->slaves_log[c_s];
485 /* Log partners */
486
487 /* Assembling slave string */
488 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
489 "\t Slave [%u]: %u %u %u ; %u %u %u rtt %u delay %u bw_in %u bw_out %u \n",
490 plt->slave->no,
491 plt->total_messages_sent, plt->total_bytes_sent,
492 plt->throughput_sent,
493 plt->total_messages_received, plt->total_bytes_received,
494 plt->throughput_recv,
495 plt->app_rtt, plt->ats_delay,
496 plt->bandwidth_in, plt->bandwidth_out);
497
498 GNUNET_asprintf (&slave_string_tmp,
499 "%s%u;%u;%u;%u;%u;%u;%.3f;%u;%u;%u;%u;%u;%u;%u;%u;%u;%u;",
500 slave_string,
501 plt->total_messages_sent, plt->total_bytes_sent,
502 plt->throughput_sent,
503 plt->total_messages_received,
504 plt->total_bytes_received, plt->throughput_sent,
505 (double) plt->app_rtt / 1000,
506 plt->bandwidth_in, plt->bandwidth_out,
507 plt->ats_cost_lan, plt->ats_cost_wan,
508 plt->ats_cost_wlan,
509 plt->ats_delay, plt->ats_distance,
510 plt->ats_network_type,
511 plt->ats_utilization_up, plt->ats_utilization_down);
512 GNUNET_free (slave_string);
513 slave_string = slave_string_tmp;
514 }
515 /* Assembling master string */
516
517
518 GNUNET_asprintf (&data, "%llu;%llu;%u;%u;%u;%u;%u;%u;;;;;;;;;;;%s\n",
519 cur_lt->timestamp,
520 GNUNET_TIME_absolute_get_difference (lp[c_m].start,
521 cur_lt->timestamp).
522 rel_value_us / 1000,
523 cur_lt->total_messages_sent, cur_lt->total_bytes_sent,
524 cur_lt->total_throughput_send,
525 cur_lt->total_messages_received,
526 cur_lt->total_bytes_received,
527 cur_lt->total_throughput_recv,
528 slave_string);
529 GNUNET_free (slave_string);
530
531 if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, data, strlen (data)))
532 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
533 "Cannot write data to log file `%s'\n", filename);
534 GNUNET_free (data);
535 }
536 if (GNUNET_SYSERR == GNUNET_DISK_file_close (f))
537 {
538 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close log file `%s'\n",
539 filename);
540 GNUNET_free (filename);
541 return;
542 }
543
544 write_throughput_gnuplot_script (filename, lp);
545 write_rtt_gnuplot_script (filename, lp);
546 write_bw_gnuplot_script (filename, lp);
547
548 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
549 "Data file successfully written to log file `%s'\n", filename);
550 GNUNET_free (filename);
551 }
552}
553
554
555void
556collect_log_now (void)
557{
558 struct LoggingPeer *bp;
559 struct PeerLoggingTimestep *mlt;
560 struct PeerLoggingTimestep *prev_log_mlt;
561 struct PartnerLoggingTimestep *slt;
562 struct PartnerLoggingTimestep *prev_log_slt;
563 struct BenchmarkPartner *p;
564 struct GNUNET_TIME_Relative delta;
565 int c_s;
566 int c_m;
567 unsigned int app_rtt;
568 double mult;
569
570 if (GNUNET_YES != running)
571 return;
572
573 for (c_m = 0; c_m < num_peers; c_m++)
574 {
575 bp = &lp[c_m];
576 mlt = GNUNET_new (struct PeerLoggingTimestep);
577 GNUNET_CONTAINER_DLL_insert_tail (bp->head, bp->tail, mlt);
578 prev_log_mlt = mlt->prev;
579
580 /* Collect data */
581
582 /* Current master state */
583 mlt->timestamp = GNUNET_TIME_absolute_get ();
584 mlt->total_bytes_sent = bp->peer->total_bytes_sent;
585 mlt->total_messages_sent = bp->peer->total_messages_sent;
586 mlt->total_bytes_received = bp->peer->total_bytes_received;
587 mlt->total_messages_received = bp->peer->total_messages_received;
588
589 /* Throughput */
590 if (NULL == prev_log_mlt)
591 {
592 /* Get difference to start */
593 delta = GNUNET_TIME_absolute_get_difference (lp[c_m].start,
594 mlt->timestamp);
595 }
596 else
597 {
598 /* Get difference to last timestep */
599 delta = GNUNET_TIME_absolute_get_difference (mlt->prev->timestamp,
600 mlt->timestamp);
601 }
602
603 /* Multiplication factor for throughput calculation */
604 mult = (1.0 * 1000 * 1000) / (delta.rel_value_us);
605
606 /* Total throughput */
607 if (NULL != prev_log_mlt)
608 {
609 if (mlt->total_bytes_sent - mlt->prev->total_bytes_sent > 0)
610 mlt->total_throughput_send = mult * (mlt->total_bytes_sent
611 - mlt->prev->total_bytes_sent);
612 else
613 mlt->total_throughput_send = prev_log_mlt->total_throughput_send; /* no msgs send */
614
615 if (mlt->total_bytes_received - mlt->prev->total_bytes_received > 0)
616 mlt->total_throughput_recv = mult * (mlt->total_bytes_received
617 - mlt->prev->total_bytes_received);
618 else
619 mlt->total_throughput_recv = prev_log_mlt->total_throughput_recv; /* no msgs received */
620 }
621 else
622 {
623 mlt->total_throughput_send = mult * mlt->total_bytes_sent;
624 mlt->total_throughput_send = mult * mlt->total_bytes_received;
625 }
626
627 mlt->slaves_log = GNUNET_malloc (bp->peer->num_partners
628 * sizeof(struct PartnerLoggingTimestep));
629
630 for (c_s = 0; c_s < bp->peer->num_partners; c_s++)
631 {
632 p = &bp->peer->partners[c_s];
633 slt = &mlt->slaves_log[c_s];
634
635 slt->slave = p->dest;
636 /* Bytes sent from master to this slave */
637 slt->total_bytes_sent = p->bytes_sent;
638 /* Messages sent from master to this slave */
639 slt->total_messages_sent = p->messages_sent;
640 /* Bytes master received from this slave */
641 slt->total_bytes_received = p->bytes_received;
642 /* Messages master received from this slave */
643 slt->total_messages_received = p->messages_received;
644 slt->total_app_rtt = p->total_app_rtt;
645 /* ats performance information */
646 slt->ats_cost_lan = p->ats_cost_lan;
647 slt->ats_cost_wan = p->ats_cost_wan;
648 slt->ats_cost_wlan = p->ats_cost_wlan;
649 slt->ats_delay = p->ats_delay;
650 slt->ats_distance = p->ats_distance;
651 slt->ats_network_type = p->ats_network_type;
652 slt->ats_utilization_down = p->ats_utilization_down;
653 slt->ats_utilization_up = p->ats_utilization_up;
654 slt->bandwidth_in = p->bandwidth_in;
655 slt->bandwidth_out = p->bandwidth_out;
656
657 /* Total application level rtt */
658 if (NULL == prev_log_mlt)
659 {
660 if (0 != slt->total_messages_sent)
661 app_rtt = slt->total_app_rtt / slt->total_messages_sent;
662 else
663 app_rtt = 0;
664 }
665 else
666 {
667 prev_log_slt = &prev_log_mlt->slaves_log[c_s];
668 if ((slt->total_messages_sent - prev_log_slt->total_messages_sent) > 0)
669 app_rtt = (slt->total_app_rtt - prev_log_slt->total_app_rtt)
670 / (slt->total_messages_sent
671 - prev_log_slt->total_messages_sent);
672 else
673 app_rtt = prev_log_slt->app_rtt; /* No messages were */
674 }
675 slt->app_rtt = app_rtt;
676
677 /* Partner throughput */
678 if (NULL != prev_log_mlt)
679 {
680 prev_log_slt = &prev_log_mlt->slaves_log[c_s];
681 if (slt->total_bytes_sent - prev_log_slt->total_bytes_sent > 0)
682 slt->throughput_sent = mult * (slt->total_bytes_sent
683 - prev_log_slt->total_bytes_sent);
684 else
685 slt->throughput_sent = prev_log_slt->throughput_sent; /* no msgs send */
686
687 if (slt->total_bytes_received - prev_log_slt->total_bytes_received > 0)
688 slt->throughput_recv = mult * (slt->total_bytes_received
689 - prev_log_slt->total_bytes_received);
690 else
691 slt->throughput_recv = prev_log_slt->throughput_recv; /* no msgs received */
692 }
693 else
694 {
695 slt->throughput_sent = mult * slt->total_bytes_sent;
696 slt->throughput_sent = mult * slt->total_bytes_received;
697 }
698
699 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
700 "Master [%u]: slave [%u]\n",
701 bp->peer->no, p->dest->no);
702 }
703 }
704}
705
706
707static void
708collect_log_task (void *cls)
709{
710 log_task = NULL;
711 collect_log_now ();
712 log_task = GNUNET_SCHEDULER_add_delayed (frequency,
713 &collect_log_task, NULL);
714}
715
716
717void
718perf_logging_stop ()
719{
720 int c_m;
721 struct PeerLoggingTimestep *cur;
722
723 if (GNUNET_YES != running)
724 return;
725
726 if (NULL != log_task)
727 {
728 GNUNET_SCHEDULER_cancel (log_task);
729 log_task = NULL;
730 }
731 collect_log_task (NULL);
732
733 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
734 _ ("Stop logging\n"));
735
736 write_to_file ();
737
738 for (c_m = 0; c_m < num_peers; c_m++)
739 {
740 while (NULL != (cur = lp[c_m].head))
741 {
742 GNUNET_CONTAINER_DLL_remove (lp[c_m].head, lp[c_m].tail, cur);
743 GNUNET_free (cur->slaves_log);
744 GNUNET_free (cur);
745 }
746 }
747
748 GNUNET_free (lp);
749}
750
751
752void
753perf_logging_start (struct GNUNET_TIME_Relative log_frequency,
754 char *testname, struct BenchmarkPeer *masters, int
755 num_masters)
756{
757 int c_m;
758
759 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
760 _ ("Start logging `%s'\n"), testname);
761
762 num_peers = num_masters;
763 name = testname;
764 frequency = log_frequency;
765
766 lp = GNUNET_malloc (num_masters * sizeof(struct LoggingPeer));
767
768 for (c_m = 0; c_m < num_masters; c_m++)
769 {
770 lp[c_m].peer = &masters[c_m];
771 lp[c_m].start = GNUNET_TIME_absolute_get ();
772 }
773
774 /* Schedule logging task */
775 log_task = GNUNET_SCHEDULER_add_now (&collect_log_task, NULL);
776 running = GNUNET_YES;
777}
778
779
780/* end of file perf_ats_logging.c */
diff --git a/src/ats-tests/perf_ats_proportional_bandwidth.conf b/src/ats-tests/perf_ats_proportional_bandwidth.conf
deleted file mode 100644
index dba96c0fe..000000000
--- a/src/ats-tests/perf_ats_proportional_bandwidth.conf
+++ /dev/null
@@ -1,4 +0,0 @@
1@INLINE@ template_perf_ats.conf
2
3[ats]
4MODE = proportional
diff --git a/src/ats-tests/perf_ats_proportional_latency.conf b/src/ats-tests/perf_ats_proportional_latency.conf
deleted file mode 100644
index dba96c0fe..000000000
--- a/src/ats-tests/perf_ats_proportional_latency.conf
+++ /dev/null
@@ -1,4 +0,0 @@
1@INLINE@ template_perf_ats.conf
2
3[ats]
4MODE = proportional
diff --git a/src/ats-tests/perf_ats_proportional_none.conf b/src/ats-tests/perf_ats_proportional_none.conf
deleted file mode 100644
index dba96c0fe..000000000
--- a/src/ats-tests/perf_ats_proportional_none.conf
+++ /dev/null
@@ -1,4 +0,0 @@
1@INLINE@ template_perf_ats.conf
2
3[ats]
4MODE = proportional
diff --git a/src/ats-tests/template_perf_ats.conf b/src/ats-tests/template_perf_ats.conf
deleted file mode 100644
index 74f608bfb..000000000
--- a/src/ats-tests/template_perf_ats.conf
+++ /dev/null
@@ -1,52 +0,0 @@
1@INLINE@ ../../contrib/conf/gnunet/no_forcestart.conf
2
3[testbed]
4# How long should operations wait?
5OPERATION_TIMEOUT = 60 s
6
7[transport-udp]
8BROADCAST = NO
9
10[peerinfo]
11USE_INCLUDED_HELLOS = NO
12
13[transport]
14#PREFIX = valgrind --leak-check=yes
15
16[ats]
17# PREFIX = valgrind
18
19# Network specific inbound/outbound quotas
20UNSPECIFIED_QUOTA_IN = 128 KiB
21UNSPECIFIED_QUOTA_OUT = 128 KiB
22# LOOPBACK
23LOOPBACK_QUOTA_IN = 128 KiB
24LOOPBACK_QUOTA_OUT = 128 KiB
25# LAN
26LAN_QUOTA_IN = 128 KiB
27LAN_QUOTA_OUT = 128 KiB
28# WAN
29WAN_QUOTA_IN = 128 KiB
30WAN_QUOTA_OUT = 128 KiB
31# WLAN
32WLAN_QUOTA_IN = 128 KiB
33WLAN_QUOTA_OUT = 128 KiB
34# BLUETOOTH
35BLUETOOTH_QUOTA_IN = 128 KiB
36BLUETOOTH_QUOTA_OUT = 128 KiB
37
38[transport-blacklist-M1RGJB4FQSM17JJ3M9BF7Q0I8MCO8C462NMOHI26RLT7C7A2KE6HCOPRA4ARM5HPL1J9IDDK5G8SFU5GUSHCTBH90ECETK1BFQD76R0]
39HIJN5O404QNUR37OSJUTNJ6H2KJS198DHI2J3I8SE3DMKVRG1RNQPODN1IJBF14KEMPPPRM0B9F9ILFKHOFCA655CH6M5OCNCMR0FE0 =
40CDTU8QQ8UPLGHR3B91V0CLTDOHONLB8QGHGUEM2JM1GANTEV0O6T20SD2N2HDN2QSHDG6IDTBR48KRDCS601FI6VHG59E7DQA98JD2O =
41
42[transport-blacklist-93ARIS6Q347RPU9EFPS9LA00VPHQLG3RBLKEKTHV4D6UVGEAC75KIIBFB5U9KK9P9P1RU1CBPV4BSSDUTB2AL2N2LG9KSO9APQNLS0O]
43HIJN5O404QNUR37OSJUTNJ6H2KJS198DHI2J3I8SE3DMKVRG1RNQPODN1IJBF14KEMPPPRM0B9F9ILFKHOFCA655CH6M5OCNCMR0FE0 =
44CDTU8QQ8UPLGHR3B91V0CLTDOHONLB8QGHGUEM2JM1GANTEV0O6T20SD2N2HDN2QSHDG6IDTBR48KRDCS601FI6VHG59E7DQA98JD2O =
45
46[transport-blacklist-OF84RAOAU2B1SOSEHJH6350MA0F7C98U55RI76LGIQOM7O33TFHPNUFB47CDBSCOLIINMVJ2U82445ABOBQRIVREG20L31KVDV5HG60]
47HIJN5O404QNUR37OSJUTNJ6H2KJS198DHI2J3I8SE3DMKVRG1RNQPODN1IJBF14KEMPPPRM0B9F9ILFKHOFCA655CH6M5OCNCMR0FE0 =
48CDTU8QQ8UPLGHR3B91V0CLTDOHONLB8QGHGUEM2JM1GANTEV0O6T20SD2N2HDN2QSHDG6IDTBR48KRDCS601FI6VHG59E7DQA98JD2O =
49
50[transport-blacklist-548J7M14O4I0F8I84U0UFARVJ97DB6QOT3MCA8O8SNAIT5JJ8TR95LUVAP3N5L7DN33IB49SNMF3Q3C0VPLTGP9ASCULA9S2OIMHHH8]
51HIJN5O404QNUR37OSJUTNJ6H2KJS198DHI2J3I8SE3DMKVRG1RNQPODN1IJBF14KEMPPPRM0B9F9ILFKHOFCA655CH6M5OCNCMR0FE0 =
52CDTU8QQ8UPLGHR3B91V0CLTDOHONLB8QGHGUEM2JM1GANTEV0O6T20SD2N2HDN2QSHDG6IDTBR48KRDCS601FI6VHG59E7DQA98JD2O =
diff --git a/src/block/Makefile.am b/src/block/Makefile.am
index ceeff4c66..ea796bf8f 100644
--- a/src/block/Makefile.am
+++ b/src/block/Makefile.am
@@ -26,10 +26,6 @@ libgnunet_plugin_block_template_la_LIBADD = \
26 libgnunetblock.la \ 26 libgnunetblock.la \
27 $(top_builddir)/src/util/libgnunetutil.la \ 27 $(top_builddir)/src/util/libgnunetutil.la \
28 $(LTLIBINTL) 28 $(LTLIBINTL)
29libgnunet_plugin_block_template_la_DEPENDENCIES = \
30 libgnunetblockgroup.la \
31 libgnunetblock.la \
32 $(top_builddir)/src/util/libgnunetutil.la
33libgnunet_plugin_block_template_la_LDFLAGS = \ 29libgnunet_plugin_block_template_la_LDFLAGS = \
34 $(GN_PLUGIN_LDFLAGS) 30 $(GN_PLUGIN_LDFLAGS)
35 31
@@ -40,10 +36,6 @@ libgnunet_plugin_block_test_la_LIBADD = \
40 libgnunetblock.la \ 36 libgnunetblock.la \
41 $(top_builddir)/src/util/libgnunetutil.la \ 37 $(top_builddir)/src/util/libgnunetutil.la \
42 $(LTLIBINTL) 38 $(LTLIBINTL)
43libgnunet_plugin_block_test_la_DEPENDENCIES = \
44 libgnunetblockgroup.la \
45 libgnunetblock.la \
46 $(top_builddir)/src/util/libgnunetutil.la
47libgnunet_plugin_block_test_la_LDFLAGS = \ 39libgnunet_plugin_block_test_la_LDFLAGS = \
48 $(GN_PLUGIN_LDFLAGS) 40 $(GN_PLUGIN_LDFLAGS)
49 41
@@ -51,8 +43,6 @@ libgnunetblock_la_SOURCES = \
51 block.c 43 block.c
52libgnunetblock_la_LIBADD = \ 44libgnunetblock_la_LIBADD = \
53 $(top_builddir)/src/util/libgnunetutil.la 45 $(top_builddir)/src/util/libgnunetutil.la
54libgnunetblock_la_DEPENDENCIES = \
55 $(top_builddir)/src/util/libgnunetutil.la
56libgnunetblock_la_LDFLAGS = \ 46libgnunetblock_la_LDFLAGS = \
57 $(GN_LIB_LDFLAGS) \ 47 $(GN_LIB_LDFLAGS) \
58 $(GN_LIBINTL) \ 48 $(GN_LIBINTL) \
@@ -63,9 +53,6 @@ libgnunetblockgroup_la_SOURCES = \
63libgnunetblockgroup_la_LIBADD = \ 53libgnunetblockgroup_la_LIBADD = \
64 libgnunetblock.la \ 54 libgnunetblock.la \
65 $(top_builddir)/src/util/libgnunetutil.la 55 $(top_builddir)/src/util/libgnunetutil.la
66libgnunetblockgroup_la_DEPENDENCIES = \
67 libgnunetblock.la \
68 $(top_builddir)/src/util/libgnunetutil.la
69libgnunetblockgroup_la_LDFLAGS = \ 56libgnunetblockgroup_la_LDFLAGS = \
70 $(GN_LIB_LDFLAGS) \ 57 $(GN_LIB_LDFLAGS) \
71 $(GN_LIBINTL) \ 58 $(GN_LIBINTL) \
diff --git a/src/consensus/Makefile.am b/src/consensus/Makefile.am
index 24e685fb9..cf1d32e74 100644
--- a/src/consensus/Makefile.am
+++ b/src/consensus/Makefile.am
@@ -40,6 +40,7 @@ gnunet_consensus_profiler_SOURCES = \
40gnunet_consensus_profiler_LDADD = \ 40gnunet_consensus_profiler_LDADD = \
41 $(top_builddir)/src/util/libgnunetutil.la \ 41 $(top_builddir)/src/util/libgnunetutil.la \
42 libgnunetconsensus.la \ 42 libgnunetconsensus.la \
43 $(top_builddir)/src/testing/libgnunettesting.la \
43 $(top_builddir)/src/testbed/libgnunettestbed.la \ 44 $(top_builddir)/src/testbed/libgnunettestbed.la \
44 $(GN_LIBINTL) 45 $(GN_LIBINTL)
45 46
diff --git a/src/conversation/conversation_api.c b/src/conversation/conversation_api.c
index 88fe8f11c..1984abdd6 100644
--- a/src/conversation/conversation_api.c
+++ b/src/conversation/conversation_api.c
@@ -645,6 +645,7 @@ GNUNET_CONVERSATION_phone_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
645 GNUNET_CRYPTO_hash (line, 645 GNUNET_CRYPTO_hash (line,
646 strlen (line), 646 strlen (line),
647 &line_port); 647 &line_port);
648 GNUNET_free (line);
648 phone = GNUNET_new (struct GNUNET_CONVERSATION_Phone); 649 phone = GNUNET_new (struct GNUNET_CONVERSATION_Phone);
649 if (GNUNET_OK != 650 if (GNUNET_OK !=
650 GNUNET_CRYPTO_get_peer_identity (cfg, 651 GNUNET_CRYPTO_get_peer_identity (cfg,
diff --git a/src/curl/curl.c b/src/curl/curl.c
index b6aef4f61..71672c780 100644
--- a/src/curl/curl.c
+++ b/src/curl/curl.c
@@ -759,6 +759,15 @@ GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db,
759 "Downloaded body: %.*s\n", 759 "Downloaded body: %.*s\n",
760 (int) db->buf_size, 760 (int) db->buf_size,
761 (char *) db->buf); 761 (char *) db->buf);
762 if (CURLE_OK !=
763 curl_easy_getinfo (eh,
764 CURLINFO_RESPONSE_CODE,
765 response_code))
766 {
767 /* unexpected error... */
768 GNUNET_break (0);
769 *response_code = 0;
770 }
762 if ((CURLE_OK != 771 if ((CURLE_OK !=
763 curl_easy_getinfo (eh, 772 curl_easy_getinfo (eh,
764 CURLINFO_CONTENT_TYPE, 773 CURLINFO_CONTENT_TYPE,
@@ -768,15 +777,6 @@ GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db,
768 { 777 {
769 /* No content type or explicitly not JSON, refuse to parse 778 /* No content type or explicitly not JSON, refuse to parse
770 (but keep response code) */ 779 (but keep response code) */
771 if (CURLE_OK !=
772 curl_easy_getinfo (eh,
773 CURLINFO_RESPONSE_CODE,
774 response_code))
775 {
776 /* unexpected error... */
777 GNUNET_break (0);
778 *response_code = 0;
779 }
780 if (0 != db->buf_size) 780 if (0 != db->buf_size)
781 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 781 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
782 "Did NOT detect response `%.*s' as JSON\n", 782 "Did NOT detect response `%.*s' as JSON\n",
@@ -786,6 +786,20 @@ GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db,
786 } 786 }
787 if (MHD_HTTP_NO_CONTENT == *response_code) 787 if (MHD_HTTP_NO_CONTENT == *response_code)
788 return NULL; 788 return NULL;
789 if (0 == *response_code)
790 {
791 char *url;
792
793 if (CURLE_OK !=
794 curl_easy_getinfo (eh,
795 CURLINFO_EFFECTIVE_URL,
796 &url))
797 url = "<unknown URL>";
798 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
799 "Failed to download response from `%s': \n",
800 url);
801 return NULL;
802 }
789 json = NULL; 803 json = NULL;
790 if (0 == db->eno) 804 if (0 == db->eno)
791 { 805 {
@@ -802,18 +816,6 @@ GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db,
802 GNUNET_free (db->buf); 816 GNUNET_free (db->buf);
803 db->buf = NULL; 817 db->buf = NULL;
804 db->buf_size = 0; 818 db->buf_size = 0;
805 if (NULL != json)
806 {
807 if (CURLE_OK !=
808 curl_easy_getinfo (eh,
809 CURLINFO_RESPONSE_CODE,
810 response_code))
811 {
812 /* unexpected error... */
813 GNUNET_break (0);
814 *response_code = 0;
815 }
816 }
817 return json; 819 return json;
818} 820}
819 821
@@ -825,8 +827,9 @@ GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db,
825 * @param header header string; will be given to the context AS IS. 827 * @param header header string; will be given to the context AS IS.
826 * @return #GNUNET_OK if no errors occurred, #GNUNET_SYSERR otherwise. 828 * @return #GNUNET_OK if no errors occurred, #GNUNET_SYSERR otherwise.
827 */ 829 */
828int 830enum GNUNET_GenericReturnValue
829GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, const char *header) 831GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx,
832 const char *header)
830{ 833{
831 ctx->common_headers = curl_slist_append (ctx->common_headers, header); 834 ctx->common_headers = curl_slist_append (ctx->common_headers, header);
832 if (NULL == ctx->common_headers) 835 if (NULL == ctx->common_headers)
@@ -892,7 +895,7 @@ do_benchmark (CURLMsg *cmsg)
892 curl -w "foo%{size_request} -XPOST --data "ABC" $URL 895 curl -w "foo%{size_request} -XPOST --data "ABC" $URL
893 the CURLINFO_REQUEST_SIZE should be the whole size of the request 896 the CURLINFO_REQUEST_SIZE should be the whole size of the request
894 including headers and body. 897 including headers and body.
895 */// 898 */
896 GNUNET_break (size_curl <= size_long); 899 GNUNET_break (size_curl <= size_long);
897 900
898 urd = get_url_benchmark_data (url, (unsigned int) response_code); 901 urd = get_url_benchmark_data (url, (unsigned int) response_code);
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c
index 724324ca4..6613ae928 100644
--- a/src/datacache/plugin_datacache_postgres.c
+++ b/src/datacache/plugin_datacache_postgres.c
@@ -306,7 +306,7 @@ postgres_plugin_get (void *cls,
306{ 306{
307 struct Plugin *plugin = cls; 307 struct Plugin *plugin = cls;
308 uint32_t type32 = (uint32_t) type; 308 uint32_t type32 = (uint32_t) type;
309 struct GNUNET_TIME_Absolute now; 309 struct GNUNET_TIME_Absolute now = { 0 };
310 struct GNUNET_PQ_QueryParam paramk[] = { 310 struct GNUNET_PQ_QueryParam paramk[] = {
311 GNUNET_PQ_query_param_auto_from_type (key), 311 GNUNET_PQ_query_param_auto_from_type (key),
312 GNUNET_PQ_query_param_absolute_time (&now), 312 GNUNET_PQ_query_param_absolute_time (&now),
@@ -424,7 +424,7 @@ postgres_plugin_get_random (void *cls,
424{ 424{
425 struct Plugin *plugin = cls; 425 struct Plugin *plugin = cls;
426 uint32_t off; 426 uint32_t off;
427 struct GNUNET_TIME_Absolute now; 427 struct GNUNET_TIME_Absolute now = { 0 };
428 struct GNUNET_TIME_Absolute expiration_time; 428 struct GNUNET_TIME_Absolute expiration_time;
429 size_t data_size; 429 size_t data_size;
430 void *data; 430 void *data;
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c
index a7da6b068..66ff9e82c 100644
--- a/src/datacache/plugin_datacache_sqlite.c
+++ b/src/datacache/plugin_datacache_sqlite.c
@@ -468,7 +468,7 @@ sqlite_plugin_get_random (void *cls,
468 struct GNUNET_TIME_Absolute exp; 468 struct GNUNET_TIME_Absolute exp;
469 size_t size; 469 size_t size;
470 void *dat; 470 void *dat;
471 uint32_t off; 471 uint32_t off = 0;
472 size_t psize; 472 size_t psize;
473 uint32_t type; 473 uint32_t type;
474 struct GNUNET_PeerIdentity *path; 474 struct GNUNET_PeerIdentity *path;
diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c
index d658b9c85..a49bc8586 100644
--- a/src/datastore/datastore_api.c
+++ b/src/datastore/datastore_api.c
@@ -1400,7 +1400,7 @@ GNUNET_DATASTORE_get_key (struct GNUNET_DATASTORE_Handle *h,
1400 LOG (GNUNET_ERROR_TYPE_DEBUG, 1400 LOG (GNUNET_ERROR_TYPE_DEBUG,
1401 "Asked to look for data of type %u under key `%s'\n", 1401 "Asked to look for data of type %u under key `%s'\n",
1402 (unsigned int) type, 1402 (unsigned int) type,
1403 GNUNET_h2s (key)); 1403 (NULL != key) ? GNUNET_h2s (key) : "NULL");
1404 if (NULL == key) 1404 if (NULL == key)
1405 { 1405 {
1406 env = GNUNET_MQ_msg (gm, 1406 env = GNUNET_MQ_msg (gm,
@@ -1430,7 +1430,7 @@ GNUNET_DATASTORE_get_key (struct GNUNET_DATASTORE_Handle *h,
1430 { 1430 {
1431 LOG (GNUNET_ERROR_TYPE_DEBUG, 1431 LOG (GNUNET_ERROR_TYPE_DEBUG,
1432 "Could not queue request for `%s'\n", 1432 "Could not queue request for `%s'\n",
1433 GNUNET_h2s (key)); 1433 (NULL != key) ? GNUNET_h2s (key): "NULL");
1434 return NULL; 1434 return NULL;
1435 } 1435 }
1436#if INSANE_STATISTICS 1436#if INSANE_STATISTICS
diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c
index 4f0e0838e..216a6faa4 100644
--- a/src/datastore/plugin_datastore_mysql.c
+++ b/src/datastore/plugin_datastore_mysql.c
@@ -994,7 +994,7 @@ mysql_plugin_get_expiration (void *cls,
994 void *proc_cls) 994 void *proc_cls)
995{ 995{
996 struct Plugin *plugin = cls; 996 struct Plugin *plugin = cls;
997 struct GNUNET_TIME_Absolute now; 997 struct GNUNET_TIME_Absolute now = { 0 };
998 struct GNUNET_MY_QueryParam params_select[] = { 998 struct GNUNET_MY_QueryParam params_select[] = {
999 GNUNET_MY_query_param_absolute_time (&now), 999 GNUNET_MY_query_param_absolute_time (&now),
1000 GNUNET_MY_query_param_end 1000 GNUNET_MY_query_param_end
diff --git a/src/datastore/plugin_datastore_postgres.c b/src/datastore/plugin_datastore_postgres.c
index 66929f91a..8fb0bf6ee 100644
--- a/src/datastore/plugin_datastore_postgres.c
+++ b/src/datastore/plugin_datastore_postgres.c
@@ -729,7 +729,7 @@ postgres_plugin_get_expiration (void *cls,
729 void *proc_cls) 729 void *proc_cls)
730{ 730{
731 struct Plugin *plugin = cls; 731 struct Plugin *plugin = cls;
732 struct GNUNET_TIME_Absolute now; 732 struct GNUNET_TIME_Absolute now = { 0 };
733 struct GNUNET_PQ_QueryParam params[] = { 733 struct GNUNET_PQ_QueryParam params[] = {
734 GNUNET_PQ_query_param_absolute_time (&now), 734 GNUNET_PQ_query_param_absolute_time (&now),
735 GNUNET_PQ_query_param_end 735 GNUNET_PQ_query_param_end
diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c
index f58955b7b..3c2d7f2d4 100644
--- a/src/datastore/plugin_datastore_sqlite.c
+++ b/src/datastore/plugin_datastore_sqlite.c
@@ -1029,7 +1029,7 @@ sqlite_plugin_get_replication (void *cls,
1029{ 1029{
1030 struct Plugin *plugin = cls; 1030 struct Plugin *plugin = cls;
1031 struct ReplCtx rc; 1031 struct ReplCtx rc;
1032 uint64_t rvalue; 1032 uint64_t rvalue = 0;
1033 uint32_t repl; 1033 uint32_t repl;
1034 struct GNUNET_SQ_QueryParam params_sel_repl[] = 1034 struct GNUNET_SQ_QueryParam params_sel_repl[] =
1035 { GNUNET_SQ_query_param_uint64 (&rvalue), 1035 { GNUNET_SQ_query_param_uint64 (&rvalue),
@@ -1096,7 +1096,7 @@ sqlite_plugin_get_expiration (void *cls,
1096{ 1096{
1097 struct Plugin *plugin = cls; 1097 struct Plugin *plugin = cls;
1098 sqlite3_stmt *stmt; 1098 sqlite3_stmt *stmt;
1099 struct GNUNET_TIME_Absolute now; 1099 struct GNUNET_TIME_Absolute now = { 0 };
1100 struct GNUNET_SQ_QueryParam params[] = { GNUNET_SQ_query_param_absolute_time ( 1100 struct GNUNET_SQ_QueryParam params[] = { GNUNET_SQ_query_param_absolute_time (
1101 &now), 1101 &now),
1102 GNUNET_SQ_query_param_end }; 1102 GNUNET_SQ_query_param_end };
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am
index 2182d1c7f..919eca438 100644
--- a/src/dht/Makefile.am
+++ b/src/dht/Makefile.am
@@ -112,6 +112,7 @@ gnunet_dht_profiler_LDADD = \
112 libgnunetdht.la \ 112 libgnunetdht.la \
113 $(top_builddir)/src/core/libgnunetcore.la \ 113 $(top_builddir)/src/core/libgnunetcore.la \
114 $(top_builddir)/src/util/libgnunetutil.la \ 114 $(top_builddir)/src/util/libgnunetutil.la \
115 $(top_builddir)/src/testing/libgnunettesting.la \
115 $(top_builddir)/src/testbed/libgnunettestbed.la 116 $(top_builddir)/src/testbed/libgnunettestbed.la
116gnunet_dht_profiler_LDFLAGS = \ 117gnunet_dht_profiler_LDFLAGS = \
117 $(GN_LIBINTL) 118 $(GN_LIBINTL)
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index 2c30f0b68..ca255310c 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -894,7 +894,7 @@ get_distance (const struct GNUNET_HashCode *target,
894 unsigned int bucket) 894 unsigned int bucket)
895{ 895{
896 uint64_t lsb = 0; 896 uint64_t lsb = 0;
897 897
898 for (unsigned int i = bucket + 1; 898 for (unsigned int i = bucket + 1;
899 (i < sizeof(struct GNUNET_HashCode) * 8) && 899 (i < sizeof(struct GNUNET_HashCode) * 8) &&
900 (i < bucket + 1 + 64); 900 (i < bucket + 1 + 64);
@@ -997,14 +997,15 @@ select_peer (const struct GNUNET_HashCode *key,
997 chosen = NULL; 997 chosen = NULL;
998 for (bc = 0; bc <= closest_bucket; bc++) 998 for (bc = 0; bc <= closest_bucket; bc++)
999 { 999 {
1000 pos = k_buckets[bc].head;
1001 count = 0; 1000 count = 0;
1002 while ( (pos != NULL) && 1001 for (pos = k_buckets[bc].head;
1003 (count < bucket_size) ) 1002 (pos != NULL) &&
1003 (count < bucket_size);
1004 pos = pos->next)
1004 { 1005 {
1005 unsigned int bucket; 1006 unsigned int bucket;
1006 uint64_t dist; 1007 uint64_t dist;
1007 1008
1008 bucket = GNUNET_CRYPTO_hash_matching_bits (key, 1009 bucket = GNUNET_CRYPTO_hash_matching_bits (key,
1009 &pos->phash); 1010 &pos->phash);
1010 dist = get_distance (key, 1011 dist = get_distance (key,
@@ -1037,7 +1038,6 @@ select_peer (const struct GNUNET_HashCode *key,
1037 chosen = NULL; 1038 chosen = NULL;
1038 } 1039 }
1039 count++; 1040 count++;
1040 pos = pos->next;
1041 } 1041 }
1042 } 1042 }
1043 if (NULL == chosen) 1043 if (NULL == chosen)
diff --git a/src/dhtu/plugin_dhtu_ip.c b/src/dhtu/plugin_dhtu_ip.c
index f80325cbc..8593a69ef 100644
--- a/src/dhtu/plugin_dhtu_ip.c
+++ b/src/dhtu/plugin_dhtu_ip.c
@@ -64,12 +64,12 @@ struct GNUNET_DHTU_Source
64 * Address in URL form ("ip+udp://$IP:$PORT") 64 * Address in URL form ("ip+udp://$IP:$PORT")
65 */ 65 */
66 char *address; 66 char *address;
67 67
68 /** 68 /**
69 * Hash of the IP address. 69 * Hash of the IP address.
70 */ 70 */
71 struct GNUNET_DHTU_Hash id; 71 struct GNUNET_DHTU_Hash id;
72 72
73 /** 73 /**
74 * My actual address. 74 * My actual address.
75 */ 75 */
@@ -79,12 +79,12 @@ struct GNUNET_DHTU_Source
79 * Number of bytes in @a addr. 79 * Number of bytes in @a addr.
80 */ 80 */
81 socklen_t addrlen; 81 socklen_t addrlen;
82 82
83 /** 83 /**
84 * Last generation this address was observed. 84 * Last generation this address was observed.
85 */ 85 */
86 unsigned int scan_generation; 86 unsigned int scan_generation;
87 87
88}; 88};
89 89
90 90
@@ -104,12 +104,12 @@ struct GNUNET_DHTU_Target
104 * Kept in a DLL. 104 * Kept in a DLL.
105 */ 105 */
106 struct GNUNET_DHTU_Target *prev; 106 struct GNUNET_DHTU_Target *prev;
107 107
108 /** 108 /**
109 * Application context for this target. 109 * Application context for this target.
110 */ 110 */
111 void *app_ctx; 111 void *app_ctx;
112 112
113 /** 113 /**
114 * Hash of the IP address. 114 * Hash of the IP address.
115 */ 115 */
@@ -124,7 +124,7 @@ struct GNUNET_DHTU_Target
124 * Tail of preferences expressed for this target. 124 * Tail of preferences expressed for this target.
125 */ 125 */
126 struct GNUNET_DHTU_PreferenceHandle *ph_tail; 126 struct GNUNET_DHTU_PreferenceHandle *ph_tail;
127 127
128 /** 128 /**
129 * Target IP address. 129 * Target IP address.
130 */ 130 */
@@ -134,7 +134,7 @@ struct GNUNET_DHTU_Target
134 * Number of bytes in @a addr. 134 * Number of bytes in @a addr.
135 */ 135 */
136 socklen_t addrlen; 136 socklen_t addrlen;
137 137
138 /** 138 /**
139 * Preference counter, length of the @a ph_head DLL. 139 * Preference counter, length of the @a ph_head DLL.
140 */ 140 */
@@ -170,7 +170,7 @@ struct GNUNET_DHTU_PreferenceHandle
170 */ 170 */
171struct Plugin 171struct Plugin
172{ 172{
173 /** 173 /**
174 * Callbacks into the DHT. 174 * Callbacks into the DHT.
175 */ 175 */
176 struct GNUNET_DHTU_PluginEnvironment *env; 176 struct GNUNET_DHTU_PluginEnvironment *env;
@@ -200,7 +200,7 @@ struct Plugin
200 * Map from hashes of sockaddrs to targets. 200 * Map from hashes of sockaddrs to targets.
201 */ 201 */
202 struct GNUNET_CONTAINER_MultiHashMap *dsts; 202 struct GNUNET_CONTAINER_MultiHashMap *dsts;
203 203
204 /** 204 /**
205 * Task that scans for IP address changes. 205 * Task that scans for IP address changes.
206 */ 206 */
@@ -212,7 +212,7 @@ struct Plugin
212 struct GNUNET_SCHEDULER_Task *read_task; 212 struct GNUNET_SCHEDULER_Task *read_task;
213 213
214 /** 214 /**
215 * Port we bind to. 215 * Port we bind to.
216 */ 216 */
217 char *port; 217 char *port;
218 218
@@ -290,7 +290,7 @@ create_target (struct Plugin *plugin,
290 GNUNET_CONTAINER_multihashmap_size (plugin->dsts)) 290 GNUNET_CONTAINER_multihashmap_size (plugin->dsts))
291 { 291 {
292 struct GNUNET_HashCode key; 292 struct GNUNET_HashCode key;
293 293
294 dst = NULL; 294 dst = NULL;
295 for (struct GNUNET_DHTU_Target *pos = plugin->dst_head; 295 for (struct GNUNET_DHTU_Target *pos = plugin->dst_head;
296 NULL != pos; 296 NULL != pos;
@@ -316,7 +316,7 @@ create_target (struct Plugin *plugin,
316 GNUNET_assert (NULL == dst->ph_head); 316 GNUNET_assert (NULL == dst->ph_head);
317 GNUNET_free (dst); 317 GNUNET_free (dst);
318 } 318 }
319 pk.size = htons (sizeof (pk)); 319 pk.size = htons (sizeof (pk));
320 dst = GNUNET_new (struct GNUNET_DHTU_Target); 320 dst = GNUNET_new (struct GNUNET_DHTU_Target);
321 dst->addrlen = addrlen; 321 dst->addrlen = addrlen;
322 memcpy (&dst->addr, 322 memcpy (&dst->addr,
@@ -391,10 +391,10 @@ find_target (struct Plugin *plugin,
391 addrlen); 391 addrlen);
392 GNUNET_assert (GNUNET_YES == 392 GNUNET_assert (GNUNET_YES ==
393 GNUNET_CONTAINER_multihashmap_put ( 393 GNUNET_CONTAINER_multihashmap_put (
394 plugin->dsts, 394 plugin->dsts,
395 &key, 395 &key,
396 dst, 396 dst,
397 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 397 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
398 } 398 }
399 else 399 else
400 { 400 {
@@ -429,7 +429,7 @@ ip_try_connect (void *cls,
429 .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV 429 .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV
430 }; 430 };
431 struct addrinfo *result = NULL; 431 struct addrinfo *result = NULL;
432 432
433 if (0 != 433 if (0 !=
434 strncmp (address, 434 strncmp (address,
435 "ip+", 435 "ip+",
@@ -481,7 +481,7 @@ ip_try_connect (void *cls,
481 * Request underlay to keep the connection to @a target alive if possible. 481 * Request underlay to keep the connection to @a target alive if possible.
482 * Hold may be called multiple times to express a strong preference to 482 * Hold may be called multiple times to express a strong preference to
483 * keep a connection, say because a @a target is in multiple tables. 483 * keep a connection, say because a @a target is in multiple tables.
484 * 484 *
485 * @param cls closure 485 * @param cls closure
486 * @param target connection to keep alive 486 * @param target connection to keep alive
487 */ 487 */
@@ -503,7 +503,7 @@ ip_hold (void *cls,
503 503
504/** 504/**
505 * Do no long request underlay to keep the connection alive. 505 * Do no long request underlay to keep the connection alive.
506 * 506 *
507 * @param cls closure 507 * @param cls closure
508 * @param target connection to keep alive 508 * @param target connection to keep alive
509 */ 509 */
@@ -511,7 +511,7 @@ static void
511ip_drop (struct GNUNET_DHTU_PreferenceHandle *ph) 511ip_drop (struct GNUNET_DHTU_PreferenceHandle *ph)
512{ 512{
513 struct GNUNET_DHTU_Target *target = ph->target; 513 struct GNUNET_DHTU_Target *target = ph->target;
514 514
515 GNUNET_CONTAINER_DLL_remove (target->ph_head, 515 GNUNET_CONTAINER_DLL_remove (target->ph_head,
516 target->ph_tail, 516 target->ph_tail,
517 ph); 517 ph);
@@ -532,7 +532,7 @@ ip_drop (struct GNUNET_DHTU_PreferenceHandle *ph)
532 * @param msg_size number of bytes in @a msg 532 * @param msg_size number of bytes in @a msg
533 * @param finished_cb function called once transmission is done 533 * @param finished_cb function called once transmission is done
534 * (not called if @a target disconnects, then only the 534 * (not called if @a target disconnects, then only the
535 * disconnect_cb is called). 535 * disconnect_cb is called).
536 * @param finished_cb_cls closure for @a finished_cb 536 * @param finished_cb_cls closure for @a finished_cb
537 */ 537 */
538static void 538static void
@@ -568,7 +568,7 @@ create_source (struct Plugin *plugin,
568 socklen_t addrlen) 568 socklen_t addrlen)
569{ 569{
570 struct GNUNET_DHTU_Source *src; 570 struct GNUNET_DHTU_Source *src;
571 571
572 src = GNUNET_new (struct GNUNET_DHTU_Source); 572 src = GNUNET_new (struct GNUNET_DHTU_Source);
573 src->addrlen = addrlen; 573 src->addrlen = addrlen;
574 memcpy (&src->addr, 574 memcpy (&src->addr,
@@ -731,7 +731,7 @@ find_source (struct Plugin *plugin,
731 (0 == memcmp (addr, 731 (0 == memcmp (addr,
732 &src->addr, 732 &src->addr,
733 addrlen)) ) 733 addrlen)) )
734 return src; 734 return src;
735 } 735 }
736 736
737 return create_source (plugin, 737 return create_source (plugin,
@@ -788,7 +788,7 @@ read_cb (void *cls)
788 cmsg->cmsg_len) 788 cmsg->cmsg_len)
789 { 789 {
790 struct in_pktinfo pi; 790 struct in_pktinfo pi;
791 791
792 memcpy (&pi, 792 memcpy (&pi,
793 CMSG_DATA (cmsg), 793 CMSG_DATA (cmsg),
794 sizeof (pi)); 794 sizeof (pi));
@@ -797,7 +797,7 @@ read_cb (void *cls)
797 .sin_family = AF_INET, 797 .sin_family = AF_INET,
798 .sin_addr = pi.ipi_addr 798 .sin_addr = pi.ipi_addr
799 }; 799 };
800 800
801 src = find_source (plugin, 801 src = find_source (plugin,
802 &sa, 802 &sa,
803 sizeof (sa)); 803 sizeof (sa));
@@ -814,7 +814,7 @@ read_cb (void *cls)
814 cmsg->cmsg_len) 814 cmsg->cmsg_len)
815 { 815 {
816 struct in6_pktinfo pi; 816 struct in6_pktinfo pi;
817 817
818 memcpy (&pi, 818 memcpy (&pi,
819 CMSG_DATA (cmsg), 819 CMSG_DATA (cmsg),
820 sizeof (pi)); 820 sizeof (pi));
@@ -824,7 +824,7 @@ read_cb (void *cls)
824 .sin6_addr = pi.ipi6_addr, 824 .sin6_addr = pi.ipi6_addr,
825 .sin6_scope_id = pi.ipi6_ifindex 825 .sin6_scope_id = pi.ipi6_ifindex
826 }; 826 };
827 827
828 src = find_source (plugin, 828 src = find_source (plugin,
829 &sa, 829 &sa,
830 sizeof (sa)); 830 sizeof (sa));
@@ -833,7 +833,7 @@ read_cb (void *cls)
833 } 833 }
834 else 834 else
835 GNUNET_break (0); 835 GNUNET_break (0);
836 } 836 }
837 } 837 }
838 dst = find_target (plugin, 838 dst = find_target (plugin,
839 &sa, 839 &sa,
@@ -932,7 +932,8 @@ libgnunet_plugin_dhtu_ip_init (void *cls)
932 GNUNET_free (plugin); 932 GNUNET_free (plugin);
933 return NULL; 933 return NULL;
934 } 934 }
935 switch (af) { 935 switch (af)
936 {
936 case AF_INET: 937 case AF_INET:
937 { 938 {
938 int on = 1; 939 int on = 1;
@@ -956,7 +957,7 @@ libgnunet_plugin_dhtu_ip_init (void *cls)
956 957
957 if (0 != 958 if (0 !=
958 bind (sock, 959 bind (sock,
959 &sa, 960 (const struct sockaddr *) &sa,
960 sizeof (sa))) 961 sizeof (sa)))
961 { 962 {
962 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, 963 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
@@ -989,10 +990,10 @@ libgnunet_plugin_dhtu_ip_init (void *cls)
989 .sin6_family = AF_INET6, 990 .sin6_family = AF_INET6,
990 .sin6_port = htons ((uint16_t) nport) 991 .sin6_port = htons ((uint16_t) nport)
991 }; 992 };
992 993
993 if (0 != 994 if (0 !=
994 bind (sock, 995 bind (sock,
995 &sa, 996 (const struct sockaddr *) &sa,
996 sizeof (sa))) 997 sizeof (sa)))
997 { 998 {
998 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, 999 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
diff --git a/src/dns/Makefile.am b/src/dns/Makefile.am
index 45107304b..f8672d55e 100644
--- a/src/dns/Makefile.am
+++ b/src/dns/Makefile.am
@@ -83,10 +83,6 @@ libgnunet_plugin_block_dns_la_LIBADD = \
83 $(top_builddir)/src/block/libgnunetblockgroup.la \ 83 $(top_builddir)/src/block/libgnunetblockgroup.la \
84 $(top_builddir)/src/block/libgnunetblock.la \ 84 $(top_builddir)/src/block/libgnunetblock.la \
85 $(top_builddir)/src/util/libgnunetutil.la 85 $(top_builddir)/src/util/libgnunetutil.la
86libgnunet_plugin_block_dns_la_DEPENDENCIES = \
87 $(top_builddir)/src/block/libgnunetblockgroup.la \
88 $(top_builddir)/src/block/libgnunetblock.la \
89 $(top_builddir)/src/util/libgnunetutil.la
90libgnunet_plugin_block_dns_la_LDFLAGS = \ 86libgnunet_plugin_block_dns_la_LDFLAGS = \
91 $(GN_LIBINTL) \ 87 $(GN_LIBINTL) \
92 $(top_builddir)/src/block/$(GN_PLUGIN_LDFLAGS) 88 $(top_builddir)/src/block/$(GN_PLUGIN_LDFLAGS)
@@ -99,5 +95,3 @@ endif
99 95
100EXTRA_DIST = \ 96EXTRA_DIST = \
101 $(check_SCRIPTS) 97 $(check_SCRIPTS)
102
103
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am
index 25590c6f7..5b6ba2376 100644
--- a/src/fs/Makefile.am
+++ b/src/fs/Makefile.am
@@ -49,10 +49,6 @@ libgnunetfs_la_LIBADD = \
49 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 49 $(top_builddir)/src/statistics/libgnunetstatistics.la \
50 $(top_builddir)/src/util/libgnunetutil.la \ 50 $(top_builddir)/src/util/libgnunetutil.la \
51 $(GN_LIBINTL) $(XLIB) $(LIBGCRYPT_LIBS) -lunistring 51 $(GN_LIBINTL) $(XLIB) $(LIBGCRYPT_LIBS) -lunistring
52libgnunetfs_la_DEPENDENCIES = \
53 $(top_builddir)/src/datastore/libgnunetdatastore.la \
54 $(top_builddir)/src/statistics/libgnunetstatistics.la \
55 $(top_builddir)/src/util/libgnunetutil.la
56 52
57if HAVE_LIBEXTRACTOR 53if HAVE_LIBEXTRACTOR
58libgnunetfs_la_LIBADD += \ 54libgnunetfs_la_LIBADD += \
@@ -105,6 +101,7 @@ endif
105gnunet_fs_profiler_SOURCES = \ 101gnunet_fs_profiler_SOURCES = \
106 gnunet-fs-profiler.c 102 gnunet-fs-profiler.c
107gnunet_fs_profiler_LDADD = \ 103gnunet_fs_profiler_LDADD = \
104 $(top_builddir)/src/testing/libgnunettesting.la \
108 $(top_builddir)/src/testbed/libgnunettestbed.la \ 105 $(top_builddir)/src/testbed/libgnunettestbed.la \
109 $(top_builddir)/src/util/libgnunetutil.la \ 106 $(top_builddir)/src/util/libgnunetutil.la \
110 $(GN_LIBINTL) 107 $(GN_LIBINTL)
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index 5e3f9d6df..ec9fb12ae 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -1264,7 +1264,7 @@ curl_check_hdr (void *buffer,
1264 } 1264 }
1265 GNUNET_free (leho_host); 1265 GNUNET_free (leho_host);
1266 } 1266 }
1267 if (0 == strcasecmp (MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, 1267 else if (0 == strcasecmp (MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
1268 hdr_type)) 1268 hdr_type))
1269 { 1269 {
1270 char *leho_host; 1270 char *leho_host;
diff --git a/src/gnsrecord/Makefile.am b/src/gnsrecord/Makefile.am
index 27f5446a1..42ac4ede4 100644
--- a/src/gnsrecord/Makefile.am
+++ b/src/gnsrecord/Makefile.am
@@ -53,8 +53,6 @@ libgnunetgnsrecord_la_LIBADD = \
53 $(LIBGCRYPT_LIBS) \ 53 $(LIBGCRYPT_LIBS) \
54 -lsodium \ 54 -lsodium \
55 $(GN_LIBINTL) 55 $(GN_LIBINTL)
56libgnunetgnsrecord_la_DEPENDENCIES = \
57 $(top_builddir)/src/identity/libgnunetidentity.la
58libgnunetgnsrecord_la_LDFLAGS = \ 56libgnunetgnsrecord_la_LDFLAGS = \
59 $(GN_LIB_LDFLAGS) \ 57 $(GN_LIB_LDFLAGS) \
60 -version-info 0:0:0 58 -version-info 0:0:0
diff --git a/src/hostlist/hostlist.conf b/src/hostlist/hostlist.conf
index 0a31a23ad..d994ce9fb 100644
--- a/src/hostlist/hostlist.conf
+++ b/src/hostlist/hostlist.conf
@@ -20,7 +20,7 @@ HOSTLISTFILE = $GNUNET_CONFIG_HOME/hostlist/learned.txt
20OPTIONS = -b 20OPTIONS = -b
21 21
22# Default list of hostlist servers for bootstrapping 22# Default list of hostlist servers for bootstrapping
23SERVERS = http://v14.gnunet.org/hostlist https://gnunet.io/hostlist 23SERVERS = http://v15.gnunet.org/hostlist https://gnunet.io/hostlist
24# http://silent.0xdeadc0de.eu:8080/ 24# http://silent.0xdeadc0de.eu:8080/
25 25
26# bind hostlist http server to a specific IPv4 26# bind hostlist http server to a specific IPv4
diff --git a/src/identity/identity_api.c b/src/identity/identity_api.c
index 3bbe0b957..22371f91a 100644
--- a/src/identity/identity_api.c
+++ b/src/identity/identity_api.c
@@ -1236,14 +1236,12 @@ GNUNET_IDENTITY_public_key_from_string (const char *str,
1236 struct GNUNET_IDENTITY_PublicKey *key) 1236 struct GNUNET_IDENTITY_PublicKey *key)
1237{ 1237{
1238 enum GNUNET_GenericReturnValue ret; 1238 enum GNUNET_GenericReturnValue ret;
1239 enum GNUNET_IDENTITY_KeyType ktype;
1240 ret = GNUNET_STRINGS_string_to_data (str, 1239 ret = GNUNET_STRINGS_string_to_data (str,
1241 strlen (str), 1240 strlen (str),
1242 key, 1241 key,
1243 sizeof (*key)); 1242 sizeof (*key));
1244 if (GNUNET_OK != ret) 1243 if (GNUNET_OK != ret)
1245 return GNUNET_SYSERR; 1244 return GNUNET_SYSERR;
1246 ktype = ntohl (key->type);
1247 return GNUNET_OK; 1245 return GNUNET_OK;
1248 1246
1249} 1247}
@@ -1254,14 +1252,12 @@ GNUNET_IDENTITY_private_key_from_string (const char *str,
1254 struct GNUNET_IDENTITY_PrivateKey *key) 1252 struct GNUNET_IDENTITY_PrivateKey *key)
1255{ 1253{
1256 enum GNUNET_GenericReturnValue ret; 1254 enum GNUNET_GenericReturnValue ret;
1257 enum GNUNET_IDENTITY_KeyType ktype;
1258 ret = GNUNET_STRINGS_string_to_data (str, 1255 ret = GNUNET_STRINGS_string_to_data (str,
1259 strlen (str), 1256 strlen (str),
1260 key, 1257 key,
1261 sizeof (*key)); 1258 sizeof (*key));
1262 if (GNUNET_OK != ret) 1259 if (GNUNET_OK != ret)
1263 return GNUNET_SYSERR; 1260 return GNUNET_SYSERR;
1264 ktype = ntohl (key->type);
1265 return GNUNET_OK; 1261 return GNUNET_OK;
1266} 1262}
1267 1263
diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c
index dba1d478d..d7cd0e826 100644
--- a/src/identity/plugin_rest_identity.c
+++ b/src/identity/plugin_rest_identity.c
@@ -322,7 +322,9 @@ do_error (void *cls)
322 handle->response_code = MHD_HTTP_OK; 322 handle->response_code = MHD_HTTP_OK;
323 response = json_dumps (json_error, 0); 323 response = json_dumps (json_error, 0);
324 resp = GNUNET_REST_create_response (response); 324 resp = GNUNET_REST_create_response (response);
325 MHD_add_response_header (resp, "Content-Type", "application/json"); 325 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
326 "Content-Type",
327 "application/json"));
326 handle->proc (handle->proc_cls, resp, handle->response_code); 328 handle->proc (handle->proc_cls, resp, handle->response_code);
327 json_decref (json_error); 329 json_decref (json_error);
328 GNUNET_free (response); 330 GNUNET_free (response);
@@ -412,7 +414,9 @@ ego_get_for_subsystem (void *cls,
412 result_str = json_dumps (json_root, 0); 414 result_str = json_dumps (json_root, 0);
413 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); 415 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
414 resp = GNUNET_REST_create_response (result_str); 416 resp = GNUNET_REST_create_response (result_str);
415 MHD_add_response_header (resp, "Content-Type", "application/json"); 417 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
418 "Content-Type",
419 "application/json"));
416 json_decref (json_root); 420 json_decref (json_root);
417 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 421 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
418 GNUNET_free (result_str); 422 GNUNET_free (result_str);
@@ -514,7 +518,9 @@ ego_get_all (struct GNUNET_REST_RequestHandle *con_handle,
514 result_str = json_dumps (json_root, 0); 518 result_str = json_dumps (json_root, 0);
515 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); 519 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
516 resp = GNUNET_REST_create_response (result_str); 520 resp = GNUNET_REST_create_response (result_str);
517 MHD_add_response_header (resp, "Content-Type", "application/json"); 521 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
522 "Content-Type",
523 "application/json"));
518 json_decref (json_root); 524 json_decref (json_root);
519 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 525 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
520 GNUNET_free (result_str); 526 GNUNET_free (result_str);
@@ -561,7 +567,9 @@ ego_get_response (struct RequestHandle *handle, struct EgoEntry *ego_entry)
561 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); 567 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
562 resp = GNUNET_REST_create_response (result_str); 568 resp = GNUNET_REST_create_response (result_str);
563 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 569 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
564 MHD_add_response_header (resp, "Content-Type", "application/json"); 570 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
571 "Content-Type",
572 "application/json"));
565 json_decref (json_ego); 573 json_decref (json_ego);
566 GNUNET_free (result_str); 574 GNUNET_free (result_str);
567 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); 575 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
@@ -1195,7 +1203,9 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
1195 1203
1196 // For now, independent of path return all options 1204 // For now, independent of path return all options
1197 resp = GNUNET_REST_create_response (NULL); 1205 resp = GNUNET_REST_create_response (NULL);
1198 MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods); 1206 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
1207 "Access-Control-Allow-Methods",
1208 allow_methods));
1199 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 1209 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1200 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); 1210 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
1201 return; 1211 return;
@@ -1216,6 +1226,12 @@ list_ego (void *cls,
1216 state = ID_REST_STATE_POST_INIT; 1226 state = ID_REST_STATE_POST_INIT;
1217 return; 1227 return;
1218 } 1228 }
1229 if (NULL == ego)
1230 {
1231 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1232 "Called with NULL ego\n");
1233 return;
1234 }
1219 if (ID_REST_STATE_INIT == state) 1235 if (ID_REST_STATE_INIT == state)
1220 { 1236 {
1221 ego_entry = GNUNET_new (struct EgoEntry); 1237 ego_entry = GNUNET_new (struct EgoEntry);
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index d15186342..9c22b5977 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -115,8 +115,8 @@ gnunetinclude_HEADERS = \
115 gnunet_strings_lib.h \ 115 gnunet_strings_lib.h \
116 gnunet_testbed_service.h \ 116 gnunet_testbed_service.h \
117 gnunet_testbed_logger_service.h \ 117 gnunet_testbed_logger_service.h \
118 gnunet_testbed_ng_service.h \
119 gnunet_testing_lib.h \ 118 gnunet_testing_lib.h \
119 gnunet_testing_plugin.h \
120 gnunet_testing_ng_lib.h \ 120 gnunet_testing_ng_lib.h \
121 gnunet_time_lib.h \ 121 gnunet_time_lib.h \
122 gnunet_transport_service.h \ 122 gnunet_transport_service.h \
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
index df1ccff26..3ee2a070a 100644
--- a/src/include/gnunet_common.h
+++ b/src/include/gnunet_common.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2006-2020 GNUnet e.V. 3 Copyright (C) 2006-2021 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
@@ -135,7 +135,7 @@ enum GNUNET_GenericReturnValue
135 * tree where gnunet_config.h is unavailable 135 * tree where gnunet_config.h is unavailable
136 */ 136 */
137#ifndef GNUNET_EXTRA_LOGGING 137#ifndef GNUNET_EXTRA_LOGGING
138#define GNUNET_EXTRA_LOGGING 0 138#define GNUNET_EXTRA_LOGGING 1
139#endif 139#endif
140 140
141/** 141/**
@@ -875,19 +875,37 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind);
875 * @ingroup logging 875 * @ingroup logging
876 * Use this for fatal errors that cannot be handled 876 * Use this for fatal errors that cannot be handled
877 */ 877 */
878#if __GNUC__ >= 6 || __clang_major__ >= 6
878#define GNUNET_assert(cond) \ 879#define GNUNET_assert(cond) \
879 do \ 880 do \
880 { \ 881 { \
882 _Pragma("GCC diagnostic push") \
883 _Pragma("GCC diagnostic ignored \"-Wtautological-compare\"") \
881 if (! (cond)) \ 884 if (! (cond)) \
882 { \ 885 { \
883 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ 886 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
884 _ ("Assertion failed at %s:%d. Aborting.\n"), \ 887 dgettext ("gnunet", "Assertion failed at %s:%d. Aborting.\n"), \
885 __FILE__, \ 888 __FILE__, \
886 __LINE__); \ 889 __LINE__); \
887 GNUNET_abort_ (); \ 890 GNUNET_abort_ (); \
888 } \ 891 } \
892 _Pragma("GCC diagnostic pop") \
889 } while (0) 893 } while (0)
890 894#else
895/* older GCC/clangs do not support -Wtautological-compare */
896#define GNUNET_assert(cond) \
897 do \
898 { \
899 if (! (cond)) \
900 { \
901 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
902 dgettext ("gnunet", "Assertion failed at %s:%d. Aborting.\n"), \
903 __FILE__, \
904 __LINE__); \
905 GNUNET_abort_ (); \
906 } \
907 } while (0)
908#endif
891 909
892/** 910/**
893 * @ingroup logging 911 * @ingroup logging
@@ -899,7 +917,7 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind);
899 if (! (cond)) \ 917 if (! (cond)) \
900 { \ 918 { \
901 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ 919 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
902 _ ("Assertion failed at %s:%d. Aborting.\n"), \ 920 dgettext ("gnunet", "Assertion failed at %s:%d. Aborting.\n"), \
903 f, \ 921 f, \
904 l); \ 922 l); \
905 GNUNET_abort_ (); \ 923 GNUNET_abort_ (); \
@@ -921,7 +939,7 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind);
921 { \ 939 { \
922 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, \ 940 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, \
923 comp, \ 941 comp, \
924 _ ("Assertion failed at %s:%d. Aborting.\n"), \ 942 dgettext ("gnunet", "Assertion failed at %s:%d. Aborting.\n"), \
925 __FILE__, \ 943 __FILE__, \
926 __LINE__); \ 944 __LINE__); \
927 GNUNET_abort_ (); \ 945 GNUNET_abort_ (); \
@@ -962,7 +980,7 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind);
962 if (! (cond)) \ 980 if (! (cond)) \
963 { \ 981 { \
964 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ 982 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
965 _ ("Assertion failed at %s:%d.\n"), \ 983 dgettext ("gnunet", "Assertion failed at %s:%d.\n"), \
966 __FILE__, \ 984 __FILE__, \
967 __LINE__); \ 985 __LINE__); \
968 } \ 986 } \
@@ -984,7 +1002,7 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind);
984 if (! (cond)) \ 1002 if (! (cond)) \
985 { \ 1003 { \
986 GNUNET_log (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, \ 1004 GNUNET_log (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, \
987 _ ("External protocol violation detected at %s:%d.\n"), \ 1005 dgettext ("gnunet", "External protocol violation detected at %s:%d.\n"), \
988 __FILE__, \ 1006 __FILE__, \
989 __LINE__); \ 1007 __LINE__); \
990 } \ 1008 } \
@@ -1001,7 +1019,7 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind);
1001 do \ 1019 do \
1002 { \ 1020 { \
1003 GNUNET_log (level, \ 1021 GNUNET_log (level, \
1004 _ ("`%s' failed at %s:%d with error: %s\n"), \ 1022 dgettext ("gnunet", "`%s' failed at %s:%d with error: %s\n"), \
1005 cmd, \ 1023 cmd, \
1006 __FILE__, \ 1024 __FILE__, \
1007 __LINE__, \ 1025 __LINE__, \
@@ -1020,7 +1038,7 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind);
1020 { \ 1038 { \
1021 GNUNET_log_from (level, \ 1039 GNUNET_log_from (level, \
1022 component, \ 1040 component, \
1023 _ ("`%s' failed at %s:%d with error: %s\n"), \ 1041 dgettext ("gnunet", "`%s' failed at %s:%d with error: %s\n"), \
1024 cmd, \ 1042 cmd, \
1025 __FILE__, \ 1043 __FILE__, \
1026 __LINE__, \ 1044 __LINE__, \
@@ -1038,7 +1056,7 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind);
1038 do \ 1056 do \
1039 { \ 1057 { \
1040 GNUNET_log (level, \ 1058 GNUNET_log (level, \
1041 _ ("`%s' failed on file `%s' at %s:%d with error: %s\n"), \ 1059 dgettext ("gnunet", "`%s' failed on file `%s' at %s:%d with error: %s\n"), \
1042 cmd, \ 1060 cmd, \
1043 filename, \ 1061 filename, \
1044 __FILE__, \ 1062 __FILE__, \
@@ -1058,7 +1076,7 @@ GNUNET_error_type_to_string (enum GNUNET_ErrorType kind);
1058 { \ 1076 { \
1059 GNUNET_log_from (level, \ 1077 GNUNET_log_from (level, \
1060 component, \ 1078 component, \
1061 _ ("`%s' failed on file `%s' at %s:%d with error: %s\n"), \ 1079 dgettext ("gnunet", "`%s' failed on file `%s' at %s:%d with error: %s\n"), \
1062 cmd, \ 1080 cmd, \
1063 filename, \ 1081 filename, \
1064 __FILE__, \ 1082 __FILE__, \
diff --git a/src/include/gnunet_configuration_lib.h b/src/include/gnunet_configuration_lib.h
index 21a5ab810..570546b68 100644
--- a/src/include/gnunet_configuration_lib.h
+++ b/src/include/gnunet_configuration_lib.h
@@ -113,6 +113,18 @@ GNUNET_CONFIGURATION_default (void);
113 113
114 114
115/** 115/**
116 * Return the filename of the default configuration filename
117 * that is used when no explicit configuration entry point
118 * has been specified.
119 *
120 * @returns NULL if no default configuration file can be located,
121 * a newly allocated string otherwise
122 */
123char *
124GNUNET_CONFIGURATION_default_filename (void);
125
126
127/**
116 * Parse a configuration file, add all of the options in the 128 * Parse a configuration file, add all of the options in the
117 * file to the configuration environment. 129 * file to the configuration environment.
118 * 130 *
@@ -139,21 +151,33 @@ GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg,
139 151
140 152
141/** 153/**
154 * Serializes the given configuration with diagnostics information.
155 * Diagnostics information will only be available if diagnostics
156 * have been enabled before parsing.
157 *
158 * @param cfg configuration to serialize
159 * @return the memory block where the serialized configuration is
160 * present. This memory should be freed by the caller
161 */
162char *
163GNUNET_CONFIGURATION_serialize_diagnostics (const struct
164 GNUNET_CONFIGURATION_Handle *cfg);
165
166/**
142 * De-serializes configuration 167 * De-serializes configuration
143 * 168 *
144 * @param cfg configuration to update 169 * @param cfg configuration to update
145 * @param mem the memory block of serialized configuration 170 * @param mem the memory block of serialized configuration
146 * @param size the size of the memory block 171 * @param size the size of the memory block
147 * @param allow_inline set to the base directory if we recursively load configuration 172 * @param source_filename source filename, will be used
148 * from inlined configurations; NULL if not and raise warnings 173 * to resolve relative @INLINE@ statements
149 * when we come across them
150 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 174 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
151 */ 175 */
152enum GNUNET_GenericReturnValue 176enum GNUNET_GenericReturnValue
153GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, 177GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg,
154 const char *mem, 178 const char *mem,
155 size_t size, 179 size_t size,
156 const char *basedir); 180 const char *source_filename);
157 181
158 182
159/** 183/**
@@ -235,6 +259,16 @@ GNUNET_CONFIGURATION_parse_and_run (const char *filename,
235 GNUNET_CONFIGURATION_Callback cb, 259 GNUNET_CONFIGURATION_Callback cb,
236 void *cb_cls); 260 void *cb_cls);
237 261
262/**
263 * Enable extra diagnostics. Will produce more log output
264 * and allocate more memory.
265 *
266 * @param cfg configuration handle
267 */
268void
269GNUNET_CONFIGURATION_enable_diagnostics (struct
270 GNUNET_CONFIGURATION_Handle *cfg);
271
238 272
239/** 273/**
240 * Function to iterate over options. 274 * Function to iterate over options.
@@ -598,6 +632,157 @@ GNUNET_CONFIGURATION_append_value_filename (struct
598 const char *option, 632 const char *option,
599 const char *value); 633 const char *value);
600 634
635
636/**
637 * Closure for #GNUNET_CONFIGURATION_config_tool_run()
638 * with settings for what should be done with the
639 * configuration.
640 */
641struct GNUNET_CONFIGURATION_ConfigSettings
642{
643
644 /**
645 * Must be set to the API version, i.e.
646 * #GNUNET_UTIL_VERSION. Used to detect
647 * which version of the struct the client
648 * is using.
649 */
650 unsigned int api_version;
651
652 /**
653 * Name of the section
654 */
655 char *section;
656
657 /**
658 * Name of the option
659 */
660 char *option;
661
662 /**
663 * Value to set
664 */
665 char *value;
666
667 /**
668 * Treat option as a filename.
669 */
670 int is_filename;
671
672 /**
673 * Whether to show the sections.
674 */
675 int list_sections;
676
677 /**
678 * Should we write out the configuration file, even if no value was changed?
679 */
680 int rewrite;
681
682 /**
683 * Should we give extra diagnostics?
684 */
685 int diagnostics;
686
687 /**
688 * Should the generated configuration file contain the whole configuration?
689 */
690 int full;
691
692
693 /**
694 * Return value from the operation, to be returned
695 * from 'main'.
696 */
697 int global_ret;
698
699};
700
701
702/**
703 * Macro that expands to a set of GNUNET-getopt directives
704 * to initialize a `struct GNUNET_CONFIGURATION_ConfigSettings`
705 * from the command line.
706 *
707 * @param cs configuration settings to initialize
708 */
709#define GNUNET_CONFIGURATION_CONFIG_OPTIONS(cs) \
710 GNUNET_GETOPT_option_flag ( \
711 'F', \
712 "full", \
713 gettext_noop ( \
714 "write the full configuration file, including default values"), \
715 &(cs)->full), \
716 GNUNET_GETOPT_option_flag ( \
717 'f', \
718 "filename", \
719 gettext_noop ("interpret option value as a filename (with $-expansion)"), \
720 &(cs)->is_filename), \
721 GNUNET_GETOPT_option_string ('o', \
722 "option", \
723 "OPTION", \
724 gettext_noop ("name of the option to access"), \
725 &(cs)->option), \
726 GNUNET_GETOPT_option_flag ( \
727 'r', \
728 "rewrite", \
729 gettext_noop ( \
730 "rewrite the configuration file, even if nothing changed"), \
731 &(cs)->rewrite), \
732 GNUNET_GETOPT_option_flag ( \
733 'd', \
734 "diagnostics", \
735 gettext_noop ( \
736 "output extra diagnostics"), \
737 &(cs)->diagnostics), \
738 GNUNET_GETOPT_option_flag ('S', \
739 "list-sections", \
740 gettext_noop ( \
741 "print available configuration sections"), \
742 &(cs)->list_sections), \
743 GNUNET_GETOPT_option_string ('s', \
744 "section", \
745 "SECTION", \
746 gettext_noop ( \
747 "name of the section to access"), \
748 &(cs)->section), \
749 GNUNET_GETOPT_option_string ('V', \
750 "value", \
751 "VALUE", \
752 gettext_noop ("value to set"), \
753 &(cs)->value)
754
755
756/**
757 * Free resources associated with @a cs.
758 *
759 * @param[in] cs settings to free (actual memory
760 * of @a cs itself is not released)
761 */
762void
763GNUNET_CONFIGURATION_config_settings_free (
764 struct GNUNET_CONFIGURATION_ConfigSettings *cs);
765
766
767/**
768 * Main task to run to perform operations typical for
769 * gnunet-config as per the configuration settings
770 * given in @a cls.
771 *
772 * @param cls closure with the `struct GNUNET_CONFIGURATION_ConfigSettings`
773 * @param args remaining command-line arguments
774 * @param cfgfile name of the configuration file used (for saving,
775 * can be NULL!)
776 * @param cfg configuration
777 */
778void
779GNUNET_CONFIGURATION_config_tool_run (
780 void *cls,
781 char *const *args,
782 const char *cfgfile,
783 const struct GNUNET_CONFIGURATION_Handle *cfg);
784
785
601#if 0 /* keep Emacsens' auto-indent happy */ 786#if 0 /* keep Emacsens' auto-indent happy */
602{ 787{
603#endif 788#endif
diff --git a/src/include/gnunet_container_lib.h b/src/include/gnunet_container_lib.h
index c8930746d..3eb80595c 100644
--- a/src/include/gnunet_container_lib.h
+++ b/src/include/gnunet_container_lib.h
@@ -2608,7 +2608,8 @@ GNUNET_CONTAINER_heap_node_get_cost (
2608 * @return #GNUNET_YES if we should continue to iterate, 2608 * @return #GNUNET_YES if we should continue to iterate,
2609 * #GNUNET_NO if not. 2609 * #GNUNET_NO if not.
2610 */ 2610 */
2611typedef int (*GNUNET_CONTAINER_HeapIterator) ( 2611typedef int
2612(*GNUNET_CONTAINER_HeapIterator) (
2612 void *cls, 2613 void *cls,
2613 struct GNUNET_CONTAINER_HeapNode *node, 2614 struct GNUNET_CONTAINER_HeapNode *node,
2614 void *element, 2615 void *element,
diff --git a/src/include/gnunet_curl_lib.h b/src/include/gnunet_curl_lib.h
index f51e4b503..38acecc48 100644
--- a/src/include/gnunet_curl_lib.h
+++ b/src/include/gnunet_curl_lib.h
@@ -150,7 +150,7 @@ GNUNET_CURL_get_select_info (struct GNUNET_CURL_Context *ctx,
150 * @param header header string; will be given to the context AS IS. 150 * @param header header string; will be given to the context AS IS.
151 * @return #GNUNET_OK if no errors occurred, #GNUNET_SYSERR otherwise. 151 * @return #GNUNET_OK if no errors occurred, #GNUNET_SYSERR otherwise.
152 */ 152 */
153int 153enum GNUNET_GenericReturnValue
154GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, 154GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx,
155 const char *header); 155 const char *header);
156 156
diff --git a/src/include/gnunet_db_lib.h b/src/include/gnunet_db_lib.h
index 85ad13e31..e88e836f6 100644
--- a/src/include/gnunet_db_lib.h
+++ b/src/include/gnunet_db_lib.h
@@ -25,6 +25,7 @@
25#ifndef GNUNET_DB_LIB_H 25#ifndef GNUNET_DB_LIB_H
26#define GNUNET_DB_LIB_H 26#define GNUNET_DB_LIB_H
27 27
28#include "gnunet_common.h"
28 29
29/** 30/**
30 * Status code returned from functions running database commands. 31 * Status code returned from functions running database commands.
@@ -61,4 +62,47 @@ enum GNUNET_DB_QueryStatus
61 that returned more than one result. */ 62 that returned more than one result. */
62}; 63};
63 64
65
66/**
67 * Handle for an active LISTENer to a database.
68 */
69struct GNUNET_DB_EventHandler;
70
71/**
72 * Function called on events received from Postgres.
73 *
74 * @param cls closure
75 * @param extra additional event data provided
76 * @param extra_size number of bytes in @a extra
77 */
78typedef void
79(*GNUNET_DB_EventCallback)(void *cls,
80 const void *extra,
81 size_t extra_size);
82
83GNUNET_NETWORK_STRUCT_BEGIN
84
85
86/**
87 * Header of a structure that describes an
88 * event channel we may subscribe to or notify on.
89 */
90struct GNUNET_DB_EventHeaderP
91{
92 /**
93 * The length of the struct (in bytes, including the length field itself),
94 * in big-endian format.
95 */
96 uint16_t size GNUNET_PACKED;
97
98 /**
99 * The type of the message (GNUNET_DB_EVENT_TYPE_XXXX), in big-endian format.
100 */
101 uint16_t type GNUNET_PACKED;
102
103};
104
105GNUNET_NETWORK_STRUCT_END
106
107
64#endif 108#endif
diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h
index 3805039fc..7dfd9ccf1 100644
--- a/src/include/gnunet_disk_lib.h
+++ b/src/include/gnunet_disk_lib.h
@@ -266,6 +266,16 @@ GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h);
266enum GNUNET_GenericReturnValue 266enum GNUNET_GenericReturnValue
267GNUNET_DISK_file_test (const char *fil); 267GNUNET_DISK_file_test (const char *fil);
268 268
269/**
270 * Check that fil corresponds to a filename and the file has read permissions.
271 *
272 * @param fil filename to check
273 * @return #GNUNET_YES if yes, #GNUNET_NO if file doesn't exist or
274 * has no read permissions, #GNUNET_SYSERR if something else
275 * (will print an error message in that case, too).
276 */
277enum GNUNET_GenericReturnValue
278GNUNET_DISK_file_test_read (const char *fil);
269 279
270/** 280/**
271 * Move a file out of the way (create a backup) by renaming it to "orig.NUM~" 281 * Move a file out of the way (create a backup) by renaming it to "orig.NUM~"
@@ -654,6 +664,22 @@ GNUNET_DISK_directory_scan (const char *dir_name,
654 GNUNET_FileNameCallback callback, 664 GNUNET_FileNameCallback callback,
655 void *callback_cls); 665 void *callback_cls);
656 666
667/**
668 * Find all files matching a glob pattern.
669 *
670 * Currently, the glob_pattern only supports asterisks in the last
671 * path component.
672 *
673 * @param glob_patterb the glob pattern to search for
674 * @param callback the method to call for each file
675 * @param callback_cls closure for @a callback
676 * @return the number of files found, -1 on error
677 */
678int
679GNUNET_DISK_glob (const char *glob_pattern,
680 GNUNET_FileNameCallback callback,
681 void *callback_cls);
682
657 683
658/** 684/**
659 * Create the directory structure for storing 685 * Create the directory structure for storing
diff --git a/src/include/gnunet_json_lib.h b/src/include/gnunet_json_lib.h
index 3dc79105e..92f696e08 100644
--- a/src/include/gnunet_json_lib.h
+++ b/src/include/gnunet_json_lib.h
@@ -521,6 +521,310 @@ GNUNET_JSON_getopt (char shortName,
521 const char *description, 521 const char *description,
522 json_t **json); 522 json_t **json);
523 523
524
525/* ****************** JSON PACK helper ******************* */
526
527
528/**
529 * Element in the array to give to the packer.
530 */
531struct GNUNET_JSON_PackSpec;
532
533
534/**
535 * Function called to pack an element into the JSON
536 * object as part of #GNUNET_JSON_pack_().
537 *
538 * @param se pack specification to execute
539 * @return json object to pack, NULL to pack nothing
540 */
541typedef json_t *
542(*GNUNET_JSON_PackCallback)(const struct GNUNET_JSON_PackSpec *se);
543
544
545/**
546 * Element in the array to give to the packer.
547 */
548struct GNUNET_JSON_PackSpec
549{
550 /**
551 * Name of the field to pack.
552 */
553 const char *field_name;
554
555 /**
556 * Object to pack.
557 */
558 json_t *object;
559
560 /**
561 * True if a NULL (or 0) argument is allowed. In this
562 * case, if the argument is NULL the @e packer should
563 * return NULL and the field should be skipped (omitted from
564 * the generated object) and not be serialized at all.
565 */
566 bool allow_null;
567};
568
569
570/**
571 * Pack a JSON object from a @a spec. Aborts if
572 * packing fails.
573 *
574 * @param spec specification object
575 * @return JSON object
576 */
577json_t *
578GNUNET_JSON_pack_ (struct GNUNET_JSON_PackSpec spec[]);
579
580
581/**
582 * Pack a JSON object from a @a spec. Aborts if
583 * packing fails.
584 *
585 * @param ... list of specification objects
586 * @return JSON object
587 */
588#define GNUNET_JSON_PACK(...) \
589 GNUNET_JSON_pack_ ((struct GNUNET_JSON_PackSpec[]) {__VA_ARGS__, \
590 GNUNET_JSON_pack_end_ ()})
591
592
593/**
594 * Do not use directly. Use #GNUNET_JSON_PACK.
595 *
596 * @return array terminator
597 */
598struct GNUNET_JSON_PackSpec
599GNUNET_JSON_pack_end_ (void);
600
601
602/**
603 * Modify packer instruction to allow NULL as a value.
604 *
605 * @param in json pack specification to modify
606 * @return json pack specification
607 */
608struct GNUNET_JSON_PackSpec
609GNUNET_JSON_pack_allow_null (struct GNUNET_JSON_PackSpec in);
610
611
612/**
613 * Generate packer instruction for a JSON field of type
614 * bool.
615 *
616 * @param name name of the field to add to the object
617 * @param b boolean value
618 * @return json pack specification
619 */
620struct GNUNET_JSON_PackSpec
621GNUNET_JSON_pack_bool (const char *name,
622 bool b);
623
624
625/**
626 * Generate packer instruction for a JSON field of type
627 * string.
628 *
629 * @param name name of the field to add to the object
630 * @param s string value
631 * @return json pack specification
632 */
633struct GNUNET_JSON_PackSpec
634GNUNET_JSON_pack_string (const char *name,
635 const char *s);
636
637
638/**
639 * Generate packer instruction for a JSON field of type
640 * unsigned integer. Note that the maximum allowed
641 * value is still limited by JSON and not UINT64_MAX.
642 *
643 * @param name name of the field to add to the object
644 * @param num numeric value
645 * @return json pack specification
646 */
647struct GNUNET_JSON_PackSpec
648GNUNET_JSON_pack_uint64 (const char *name,
649 uint64_t num);
650
651
652/**
653 * Generate packer instruction for a JSON field of type
654 * signed integer.
655 *
656 * @param name name of the field to add to the object
657 * @param num numeric value
658 * @return json pack specification
659 */
660struct GNUNET_JSON_PackSpec
661GNUNET_JSON_pack_int64 (const char *name,
662 int64_t num);
663
664
665/**
666 * Generate packer instruction for a JSON field of type
667 * JSON object where the reference is taken over by
668 * the packer.
669 *
670 * @param name name of the field to add to the object
671 * @param o object to steal
672 * @return json pack specification
673 */
674struct GNUNET_JSON_PackSpec
675GNUNET_JSON_pack_object_steal (const char *name,
676 json_t *o);
677
678
679/**
680 * Generate packer instruction for a JSON field of type JSON object where the
681 * reference counter is incremented by the packer. Note that a deep copy is
682 * not performed.
683 *
684 * @param name name of the field to add to the object
685 * @param o object to increment reference counter of
686 * @return json pack specification
687 */
688struct GNUNET_JSON_PackSpec
689GNUNET_JSON_pack_object_incref (const char *name,
690 json_t *o);
691
692
693/**
694 * Generate packer instruction for a JSON field of type
695 * JSON array where the reference is taken over by
696 * the packer.
697 *
698 * @param name name of the field to add to the object
699 * @param a array to steal
700 * @return json pack specification
701 */
702struct GNUNET_JSON_PackSpec
703GNUNET_JSON_pack_array_steal (const char *name,
704 json_t *a);
705
706
707/**
708 * Generate packer instruction for a JSON field of type JSON array where the
709 * reference counter is incremented by the packer. Note that a deep copy is
710 * not performed.
711 *
712 * @param name name of the field to add to the object
713 * @param a array to increment reference counter of
714 * @return json pack specification
715 */
716struct GNUNET_JSON_PackSpec
717GNUNET_JSON_pack_array_incref (const char *name,
718 json_t *a);
719
720
721/**
722 * Generate packer instruction for a JSON field of type
723 * variable size binary blob.
724 *
725 * @param name name of the field to add to the object
726 * @param blob binary data to pack
727 * @param blob_size number of bytes in @a blob
728 * @return json pack specification
729 */
730struct GNUNET_JSON_PackSpec
731GNUNET_JSON_pack_data_varsize (const char *name,
732 const void *blob,
733 size_t blob_size);
734
735
736/**
737 * Generate packer instruction for a JSON field where the
738 * size is automatically determined from the argument.
739 *
740 * @param name name of the field to add to the object
741 * @param blob data to pack, must not be an array
742 * @return json pack specification
743 */
744#define GNUNET_JSON_pack_data_auto(name,blob) \
745 GNUNET_JSON_pack_data_varsize (name, blob, sizeof (*blob))
746
747
748/**
749 * Generate packer instruction for a JSON field of type
750 * absolute time.
751 *
752 * @param name name of the field to add to the object
753 * @param at absolute time to pack, a value of 0 is only
754 * allowed with #GNUNET_JSON_pack_allow_null()!
755 * @return json pack specification
756 */
757struct GNUNET_JSON_PackSpec
758GNUNET_JSON_pack_time_abs (const char *name,
759 struct GNUNET_TIME_Absolute at);
760
761
762/**
763 * Generate packer instruction for a JSON field of type
764 * absolute time in network byte order.
765 *
766 * @param name name of the field to add to the object
767 * @param at absolute time to pack, a value of 0 is only
768 * allowed with #GNUNET_JSON_pack_allow_null()!
769 * @return json pack specification
770 */
771struct GNUNET_JSON_PackSpec
772GNUNET_JSON_pack_time_abs_nbo (const char *name,
773 struct GNUNET_TIME_AbsoluteNBO at);
774
775
776/**
777 * Generate packer instruction for a JSON field of type
778 * relative time.
779 *
780 * @param name name of the field to add to the object
781 * @param rt relative time to pack
782 * @return json pack specification
783 */
784struct GNUNET_JSON_PackSpec
785GNUNET_JSON_pack_time_rel (const char *name,
786 struct GNUNET_TIME_Relative rt);
787
788
789/**
790 * Generate packer instruction for a JSON field of type
791 * relative time in network byte order.
792 *
793 * @param name name of the field to add to the object
794 * @param rt relative time to pack
795 * @return json pack specification
796 */
797struct GNUNET_JSON_PackSpec
798GNUNET_JSON_pack_time_rel_nbo (const char *name,
799 struct GNUNET_TIME_RelativeNBO rt);
800
801
802/**
803 * Generate packer instruction for a JSON field of type
804 * RSA public key.
805 *
806 * @param name name of the field to add to the object
807 * @param pk RSA public key
808 * @return json pack specification
809 */
810struct GNUNET_JSON_PackSpec
811GNUNET_JSON_pack_rsa_public_key (const char *name,
812 const struct GNUNET_CRYPTO_RsaPublicKey *pk);
813
814
815/**
816 * Generate packer instruction for a JSON field of type
817 * RSA signature.
818 *
819 * @param name name of the field to add to the object
820 * @param sig RSA signature
821 * @return json pack specification
822 */
823struct GNUNET_JSON_PackSpec
824GNUNET_JSON_pack_rsa_signature (const char *name,
825 const struct GNUNET_CRYPTO_RsaSignature *sig);
826
827
524#endif 828#endif
525 829
526/* end of gnunet_json_lib.h */ 830/* end of gnunet_json_lib.h */
diff --git a/src/include/gnunet_messenger_service.h b/src/include/gnunet_messenger_service.h
index ecd856eb9..5d7155a3d 100644
--- a/src/include/gnunet_messenger_service.h
+++ b/src/include/gnunet_messenger_service.h
@@ -499,6 +499,7 @@ struct GNUNET_MESSENGER_Message
499 499
500/** 500/**
501 * Enum for the different supported flags used by message handling 501 * Enum for the different supported flags used by message handling
502 * Compatible flags can be OR'ed together.
502 */ 503 */
503enum GNUNET_MESSENGER_MessageFlags 504enum GNUNET_MESSENGER_MessageFlags
504{ 505{
@@ -508,9 +509,14 @@ enum GNUNET_MESSENGER_MessageFlags
508 GNUNET_MESSENGER_FLAG_NONE = 0, 509 GNUNET_MESSENGER_FLAG_NONE = 0,
509 510
510 /** 511 /**
512 * The sent flag. The flag indicates that the message was sent by the client.
513 */
514 GNUNET_MESSENGER_FLAG_SENT = 1,
515
516 /**
511 * The private flag. The flag indicates that the message was privately encrypted. 517 * The private flag. The flag indicates that the message was privately encrypted.
512 */ 518 */
513 GNUNET_MESSENGER_FLAG_PRIVATE = 1, 519 GNUNET_MESSENGER_FLAG_PRIVATE = 2,
514}; 520};
515 521
516/** 522/**
@@ -526,8 +532,8 @@ typedef void
526/** 532/**
527 * Method called whenever a message is sent or received from a <i>room</i>. 533 * Method called whenever a message is sent or received from a <i>room</i>.
528 * 534 *
529 * The flag <i>private_message</i> will be #GNUNET_YES if a message was 535 * The <i>flags</i> will indicate with a bitmask if a message was
530 * received privately, otherwise #GNUNET_NO. 536 * received privately or if the message was sent by the client.
531 * 537 *
532 * @param[in/out] cls Closure from #GNUNET_MESSENGER_connect 538 * @param[in/out] cls Closure from #GNUNET_MESSENGER_connect
533 * @param[in] room Room handle 539 * @param[in] room Room handle
diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h
index 1f2915165..fe3fabbea 100644
--- a/src/include/gnunet_pq_lib.h
+++ b/src/include/gnunet_pq_lib.h
@@ -853,113 +853,8 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db);
853 853
854 854
855/** 855/**
856 * Function called whenever the socket needed for
857 * notifications from postgres changes.
858 *
859 * @param cls closure
860 * @param fd socket to listen on, -1 for none
861 */
862typedef void
863(*GNUNET_PQ_SocketCallback)(void *cls,
864 int fd);
865
866
867/**
868 * Obtain the file descriptor to poll on for notifications.
869 * Useful if the GNUnet scheduler is NOT to be used for
870 * such notifications.
871 *
872 * @param db database handle
873 * @param sc function to call with the socket
874 * @param sc_cls closure for @a sc
875 */
876void
877GNUNET_PQ_event_set_socket_callback (struct GNUNET_PQ_Context *db,
878 GNUNET_PQ_SocketCallback sc,
879 void *sc_cls);
880
881
882/**
883 * Poll for database events now. Used if the event FD
884 * is ready and the application wants to trigger applicable
885 * events.
886 * Useful if the GNUnet scheduler is NOT to be used for
887 * such notifications.
888 *
889 * @param db database handle
890 */
891void
892GNUNET_PQ_event_do_poll (struct GNUNET_PQ_Context *db);
893
894
895/**
896 * Run poll event loop using the GNUnet scheduler.
897 *
898 * @param db database handle
899 */
900void
901GNUNET_PQ_event_scheduler_start (struct GNUNET_PQ_Context *db);
902
903
904/**
905 * Stop running poll event loop using the GNUnet scheduler.
906 *
907 * @param db database handle
908 */
909void
910GNUNET_PQ_event_scheduler_stop (struct GNUNET_PQ_Context *db);
911
912
913/**
914 * Handle for an active LISTENer to the database.
915 */
916struct GNUNET_PQ_EventHandler;
917
918/**
919 * Function called on events received from Postgres.
920 *
921 * @param cls closure
922 * @param extra additional event data provided
923 * @param extra_size number of bytes in @a extra
924 */
925typedef void
926(*GNUNET_PQ_EventCallback)(void *cls,
927 const void *extra,
928 size_t extra_size);
929
930GNUNET_NETWORK_STRUCT_BEGIN
931
932
933/**
934 * Header of a structure that describes an
935 * event channel we may subscribe to or notify on.
936 */
937struct GNUNET_PQ_EventHeaderP
938{
939 /**
940 * The length of the struct (in bytes, including the length field itself),
941 * in big-endian format.
942 */
943 uint16_t size GNUNET_PACKED;
944
945 /**
946 * The type of the message (GNUNET_PQ_EVENT_TYPE_XXXX), in big-endian format.
947 */
948 uint16_t type GNUNET_PACKED;
949
950};
951
952GNUNET_NETWORK_STRUCT_END
953
954
955/**
956 * Handle for an active LISTENer to the database.
957 */
958struct GNUNET_PQ_EventHandler;
959
960/**
961 * Register callback to be invoked on events of type @a es. 856 * Register callback to be invoked on events of type @a es.
962 * 857 *
963 * Unlike many other calls, this function is thread-safe 858 * Unlike many other calls, this function is thread-safe
964 * and may be called from threads that are different 859 * and may be called from threads that are different
965 * from the one that setup @a db. However, the @a cb 860 * from the one that setup @a db. However, the @a cb
@@ -968,21 +863,23 @@ struct GNUNET_PQ_EventHandler;
968 * 863 *
969 * @param db database context to use 864 * @param db database context to use
970 * @param es specification of the event to listen for 865 * @param es specification of the event to listen for
866 * @param timeout when to trigger @a cb based on timeout
971 * @param cb function to call when the event happens, possibly 867 * @param cb function to call when the event happens, possibly
972 * multiple times (until #GNUNET_PQ_event_listen_cancel() is invoked) 868 * multiple times (until #GNUNET_PQ_event_listen_cancel() is invoked), including on timeout
973 * @param cb_cls closure for @a cb 869 * @param cb_cls closure for @a cb
974 * @return handle useful to cancel the listener 870 * @return handle useful to cancel the listener
975 */ 871 */
976struct GNUNET_PQ_EventHandler * 872struct GNUNET_DB_EventHandler *
977GNUNET_PQ_event_listen (struct GNUNET_PQ_Context *db, 873GNUNET_PQ_event_listen (struct GNUNET_PQ_Context *db,
978 const struct GNUNET_PQ_EventHeaderP *es, 874 const struct GNUNET_DB_EventHeaderP *es,
979 GNUNET_PQ_EventCallback cb, 875 struct GNUNET_TIME_Relative timeout,
876 GNUNET_DB_EventCallback cb,
980 void *cb_cls); 877 void *cb_cls);
981 878
982 879
983/** 880/**
984 * Stop notifications. 881 * Stop notifications.
985 * 882 *
986 * Unlike many other calls, this function is thread-safe 883 * Unlike many other calls, this function is thread-safe
987 * and may be called from threads that are different 884 * and may be called from threads that are different
988 * from the one that setup @a db. However, the @a cb 885 * from the one that setup @a db. However, the @a cb
@@ -992,12 +889,12 @@ GNUNET_PQ_event_listen (struct GNUNET_PQ_Context *db,
992 * @param eh handle to unregister. 889 * @param eh handle to unregister.
993 */ 890 */
994void 891void
995GNUNET_PQ_event_listen_cancel (struct GNUNET_PQ_EventHandler *eh); 892GNUNET_PQ_event_listen_cancel (struct GNUNET_DB_EventHandler *eh);
996 893
997 894
998/** 895/**
999 * Notify all that listen on @a es of an event. 896 * Notify all that listen on @a es of an event.
1000 * 897 *
1001 * Unlike many other calls, this function is thread-safe 898 * Unlike many other calls, this function is thread-safe
1002 * and may be called from threads that are different 899 * and may be called from threads that are different
1003 * from the one that setup @a db. However, the @a cb 900 * from the one that setup @a db. However, the @a cb
@@ -1011,7 +908,7 @@ GNUNET_PQ_event_listen_cancel (struct GNUNET_PQ_EventHandler *eh);
1011 */ 908 */
1012void 909void
1013GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db, 910GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db,
1014 const struct GNUNET_PQ_EventHeaderP *es, 911 const struct GNUNET_DB_EventHeaderP *es,
1015 const void *extra, 912 const void *extra,
1016 size_t extra_size); 913 size_t extra_size);
1017 914
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 715e94c6a..6b61dfc72 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -1784,6 +1784,13 @@ extern "C" {
1784 */ 1784 */
1785#define GNUNET_MESSAGE_TYPE_SETU_P2P_OVER 572 1785#define GNUNET_MESSAGE_TYPE_SETU_P2P_OVER 572
1786 1786
1787/**
1788 * Signals other peer that all elements are sent.
1789 */
1790
1791#define GNUNET_MESSAGE_TYPE_SETU_P2P_SEND_FULL 710
1792
1793
1787 1794
1788/******************************************************************************* 1795/*******************************************************************************
1789 * SETI message types 1796 * SETI message types
diff --git a/src/include/gnunet_setu_service.h b/src/include/gnunet_setu_service.h
index bacec9408..1d7e48402 100644
--- a/src/include/gnunet_setu_service.h
+++ b/src/include/gnunet_setu_service.h
@@ -163,7 +163,31 @@ enum GNUNET_SETU_OptionType
163 /** 163 /**
164 * Notify client also if we are sending a value to the other peer. 164 * Notify client also if we are sending a value to the other peer.
165 */ 165 */
166 GNUNET_SETU_OPTION_SYMMETRIC = 8 166 GNUNET_SETU_OPTION_SYMMETRIC = 8,
167
168 /**
169 * Byzantine upper bound. Is the maximal plausible number of elements
170 * a peer can have default max uint64
171 */
172 GNUNET_SETU_OPTION_CUSTOM_BYZANTINE_UPPER_BOUND = 16,
173
174 /**
175 * Bandwidth latency tradeoff determines how much bytes a single RTT is
176 * worth, which is a performance setting
177 */
178 GNUNET_SETU_OPTION_CUSTOM_BANDWIDTH_LATENCY_TRADEOFF= 32,
179
180 /**
181 * The factor determines the number of buckets an IBF has which is
182 * multiplied by the estimated setsize default: 2
183 */
184 GNUNET_SETU_OPTION_CUSTOM_IBF_BUCKET_NUMBER_FACTOR= 64,
185
186 /**
187 * This setting determines to how many IBF buckets an single elements
188 * is mapped to.
189 */
190 GNUNET_SETU_OPTION_CUSTOM_IBF_BUCKETS_PER_ELEMENT= 128
167}; 191};
168 192
169 193
diff --git a/src/include/gnunet_testbed_ng_service.h b/src/include/gnunet_testbed_ng_service.h
deleted file mode 100644
index 49e9f56bc..000000000
--- a/src/include/gnunet_testbed_ng_service.h
+++ /dev/null
@@ -1,284 +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 * @file
25 * API for writing tests and creating large-scale emulation testbeds for GNUnet with command pattern.
26 *
27 * @defgroup testbed Testbed service
28 * Writing tests and creating large-scale emulation testbeds for GNUnet with command pattern.
29 *
30 * @see [Documentation](https://docs.gnunet.org/handbook/gnunet.html#TESTBED-NG-Subsystem)
31 *
32 * @{
33 */
34
35#ifndef GNUNET_TESTBED_NG_SERVICE_H
36#define GNUNET_TESTBED_NG_SERVICE_H
37
38#include "gnunet_util_lib.h"
39#include "gnunet_testing_ng_lib.h"
40
41struct TngState;
42
43struct PeerCmdState
44{
45 /**
46 * The label of a controller command.
47 */
48 const char *controller_label;
49
50 /**
51 * Handle to operation
52 */
53 struct GNUNET_TESTBED_Operation *operation;
54
55 /**
56 * Name of the host, use "NULL" for localhost.
57 */
58 const char *hostname;
59
60 /**
61 * Username to use for the login; may be NULL.
62 */
63 const char *username;
64
65 /**
66 * Port number to use for ssh; use 0 to let ssh decide.
67 */
68 uint16_t port;
69
70 /**
71 * The configuration to use as a template while starting a controller
72 * on this host. Operation queue sizes specific to a host are also
73 * read from this configuration handle.
74 */
75 struct GNUNET_CONFIGURATION_Handle *cfg;
76
77 /**
78 * The host to run peers and controllers on
79 */
80 struct GNUNET_TESTBED_Host *host;
81
82 /**
83 * Abort task identifier
84 */
85 struct GNUNET_SCHEDULER_Task *abort_task;
86
87 /**
88 * Flag indicating if peer is ready.
89 */
90 int peer_ready;
91
92 /**
93 * Flag indicating controller is going down.
94 */
95 int peer_going_down;
96
97 /**
98 * Interpreter state.
99 */
100 struct GNUNET_TESTING_Interpreter *is;
101
102 /**
103 * Peer to start
104 */
105 struct GNUNET_TESTBED_Peer *peer;
106};
107
108struct ControllerState
109{
110 /**
111 * The ip address of the controller which will be set as TRUSTED
112 * HOST(all connections form this ip are permitted by the testbed) when
113 * starting testbed controller at host. This can either be a single ip
114 * address or a network address in CIDR notation.
115 */
116 const char *trusted_ip;
117
118 /**
119 * Name of the host, use "NULL" for localhost.
120 */
121 const char *hostname;
122
123 /**
124 * Username to use for the login; may be NULL.
125 */
126 const char *username;
127
128 /**
129 * Port number to use for ssh; use 0 to let ssh decide.
130 */
131 uint16_t port;
132
133 /**
134 * The configuration to use as a template while starting a controller
135 * on this host. Operation queue sizes specific to a host are also
136 * read from this configuration handle.
137 */
138 struct GNUNET_CONFIGURATION_Handle *cfg;
139
140 /**
141 * The host to run peers and controllers on
142 */
143 struct GNUNET_TESTBED_Host *host;
144
145 /**
146 * The controller process
147 */
148 struct GNUNET_TESTBED_ControllerProc *cp;
149
150 /**
151 * The controller handle
152 */
153 struct GNUNET_TESTBED_Controller *controller;
154
155 /**
156 * A bit mask with set of events to call the controller for.
157 */
158 uint64_t event_mask;
159
160 /**
161 * Abort task identifier
162 */
163 struct GNUNET_SCHEDULER_Task *abort_task;
164
165 /**
166 * Handle for host registration
167 */
168 struct GNUNET_TESTBED_HostRegistrationHandle *reg_handle;
169
170 /**
171 * Flag indicating if host create with controller is ready.
172 */
173 int host_ready;
174
175 /**
176 * Flag indicating controller is going down.
177 */
178 int controller_going_down;
179
180 /**
181 * Interpreter state.
182 */
183 struct GNUNET_TESTING_Interpreter *is;
184};
185
186/**
187 * Offer data from trait
188 *
189 * @param cmd command to extract the controller from.
190 * @param pt pointer to controller.
191 * @return #GNUNET_OK on success.
192 */
193int
194GNUNET_TESTBED_get_trait_controller (const struct GNUNET_TESTING_Command *cmd,
195 struct GNUNET_TESTBED_Controller **
196 controller);
197
198struct GNUNET_TESTING_Command
199GNUNET_TESTBED_cmd_controller (const char *label,
200 const char *host,
201 uint64_t event_mask);
202
203void
204GNUNET_TESTBED_shutdown_controller (struct ControllerState *cs);
205
206void
207GNUNET_TESTBED_shutdown_peer (struct PeerCmdState *ps);
208
209void
210GNUNET_TESTBED_shutdown_service (struct TngState *ss);
211
212/**
213 * Create command.
214 *
215 * @param label name for command.
216 * @param binaryname to start.
217 * @return command.
218 */
219struct GNUNET_TESTING_Command
220GNUNET_TESTBED_cmd_netjail_start (const char *label,
221 char *local_m,
222 char *global_n);
223
224
225/**
226 * Create command.
227 *
228 * @param label name for command.
229 * @param binaryname to exec.
230 * @return command.
231 */
232struct GNUNET_TESTING_Command
233GNUNET_TESTBED_cmd_netjail_start_testbed (const char *label,
234 char *local_m,
235 char *global_n,
236 char *plugin_name);
237
238
239/**
240 * Create command.
241 *
242 * @param label name for command.
243 * @param binaryname to stop.
244 * @return command.
245 */
246struct GNUNET_TESTING_Command
247GNUNET_TESTBED_cmd_netjail_stop (const char *label,
248 char *local_m,
249 char *global_n);
250
251
252struct GNUNET_TESTING_Command
253GNUNET_TESTBED_cmd_stop_testbed (const char *label,
254 const char *helper_start_label,
255 char *local_m,
256 char *global_n);
257
258
259int
260GNUNET_TESTBED_get_trait_helper_handles (const struct
261 GNUNET_TESTING_Command *cmd,
262 struct GNUNET_HELPER_Handle ***helper);
263
264
265int
266GNUNET_TESTBED_get_trait_hosts (const struct
267 GNUNET_TESTING_Command *cmd,
268 struct GNUNET_TESTBED_Host ***hosts);
269
270struct GNUNET_TESTING_Command
271GNUNET_TESTING_cmd_block_until_all_peers_started (const char *label,
272 unsigned int *
273 all_peers_started);
274
275struct GNUNET_TESTING_Command
276GNUNET_TESTING_cmd_send_peer_ready (const char *label,
277 TESTBED_CMD_HELPER_write_cb write_message);
278
279struct GNUNET_TESTING_Command
280GNUNET_TESTING_cmd_local_test_finished (const char *label,
281 TESTBED_CMD_HELPER_write_cb
282 write_message);
283
284#endif
diff --git a/src/include/gnunet_testing_ng_lib.h b/src/include/gnunet_testing_ng_lib.h
index aad7ddec2..939863d67 100644
--- a/src/include/gnunet_testing_ng_lib.h
+++ b/src/include/gnunet_testing_ng_lib.h
@@ -838,8 +838,82 @@ GNUNET_TESTING_get_trait_test_system (const struct
838 GNUNET_TESTING_Command *cmd, 838 GNUNET_TESTING_Command *cmd,
839 struct GNUNET_TESTING_System **test_system); 839 struct GNUNET_TESTING_System **test_system);
840 840
841
841struct GNUNET_TESTING_Command 842struct GNUNET_TESTING_Command
842GNUNET_TESTING_cmd_system_create (const char *label, 843GNUNET_TESTING_cmd_system_create (const char *label,
843 const char *testdir); 844 const char *testdir);
844 845
846
847struct GNUNET_TESTING_Command
848GNUNET_TESTING_cmd_system_destroy (const char *label,
849 const char *create_label);
850
851
852/**
853 * Create command.
854 *
855 * @param label name for command.
856 * @param binaryname to start.
857 * @return command.
858 */
859struct GNUNET_TESTING_Command
860GNUNET_TESTING_cmd_netjail_start (const char *label,
861 char *local_m,
862 char *global_n);
863
864
865/**
866 * Create command.
867 *
868 * @param label name for command.
869 * @param binaryname to exec.
870 * @return command.
871 */
872struct GNUNET_TESTING_Command
873GNUNET_TESTING_cmd_netjail_start_testing_system (const char *label,
874 char *local_m,
875 char *global_n,
876 char *plugin_name,
877 unsigned int *rv);
878
879
880/**
881 * Create command.
882 *
883 * @param label name for command.
884 * @param binaryname to stop.
885 * @return command.
886 */
887struct GNUNET_TESTING_Command
888GNUNET_TESTING_cmd_netjail_stop (const char *label,
889 char *local_m,
890 char *global_n);
891
892
893struct GNUNET_TESTING_Command
894GNUNET_TESTING_cmd_stop_testing_system (const char *label,
895 const char *helper_start_label,
896 char *local_m,
897 char *global_n);
898
899
900int
901GNUNET_TESTING_get_trait_helper_handles (const struct
902 GNUNET_TESTING_Command *cmd,
903 struct GNUNET_HELPER_Handle ***helper);
904
905
906struct GNUNET_TESTING_Command
907GNUNET_TESTING_cmd_block_until_all_peers_started (const char *label,
908 unsigned int *
909 all_peers_started);
910
911struct GNUNET_TESTING_Command
912GNUNET_TESTING_cmd_send_peer_ready (const char *label,
913 TESTING_CMD_HELPER_write_cb write_message);
914
915struct GNUNET_TESTING_Command
916GNUNET_TESTING_cmd_local_test_finished (const char *label,
917 TESTING_CMD_HELPER_write_cb
918 write_message);
845#endif 919#endif
diff --git a/src/include/gnunet_testing_plugin.h b/src/include/gnunet_testing_plugin.h
index 8395e2a49..151827d4b 100644
--- a/src/include/gnunet_testing_plugin.h
+++ b/src/include/gnunet_testing_plugin.h
@@ -37,15 +37,16 @@ extern "C"
37#endif 37#endif
38 38
39typedef void 39typedef void
40(*TESTBED_CMD_HELPER_write_cb) (struct GNUNET_MessageHeader *message, size_t 40(*TESTING_CMD_HELPER_write_cb) (struct GNUNET_MessageHeader *message, size_t
41 msg_length); 41 msg_length);
42 42
43typedef void 43typedef void
44(*GNUNET_TESTING_PLUGIN_StartTestCase) (TESTBED_CMD_HELPER_write_cb 44(*GNUNET_TESTING_PLUGIN_StartTestCase) (TESTING_CMD_HELPER_write_cb
45 write_message, char *router_ip, 45 write_message, char *router_ip,
46 char *node_ip, 46 char *node_ip,
47 char *n, 47 char *n,
48 char *m); 48 char *m,
49 char *local_m);
49 50
50typedef void 51typedef void
51(*GNUNET_TESTING_PLUGIN_ALL_PEERS_STARTED) (); 52(*GNUNET_TESTING_PLUGIN_ALL_PEERS_STARTED) ();
diff --git a/src/include/gnunet_util_lib.h b/src/include/gnunet_util_lib.h
index 3acd4cb9b..cc4f3a01e 100644
--- a/src/include/gnunet_util_lib.h
+++ b/src/include/gnunet_util_lib.h
@@ -58,7 +58,8 @@ extern "C"
58 * THIS release. Otherwise, you are violating the Affero GPL if you make 58 * THIS release. Otherwise, you are violating the Affero GPL if you make
59 * this service available to anyone but yourself. 59 * this service available to anyone but yourself.
60 */ 60 */
61#define GNUNET_AGPL_URL "https://gnunet.org/git/gnunet.git#" PACKAGE_VERSION 61#define GNUNET_AGPL_URL "https://git.gnunet.org/gnunet.git/tag/?h=v" \
62 PACKAGE_VERSION
62 63
63 64
64#include "gnunet_crypto_lib.h" 65#include "gnunet_crypto_lib.h"
diff --git a/src/include/platform.h b/src/include/platform.h
index e641b38eb..e44f9f51a 100644
--- a/src/include/platform.h
+++ b/src/include/platform.h
@@ -22,7 +22,7 @@
22 * @author Nils Durner 22 * @author Nils Durner
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 * 24 *
25 * @file 25 * @file gnunet/src/include/platform.h
26 * Platform specific includes and defines. 26 * Platform specific includes and defines.
27 * 27 *
28 * This file should never be included by installed 28 * This file should never be included by installed
@@ -170,18 +170,12 @@
170#include "compat.h" 170#include "compat.h"
171 171
172#include <locale.h> 172#include <locale.h>
173#ifndef FRAMEWORK_BUILD
174#include "gettext.h" 173#include "gettext.h"
175/** 174/**
176 * GNU gettext support macro. 175 * GNU gettext support macro.
177 */ 176 */
178#define _(String) dgettext (PACKAGE, String) 177#define _(String) dgettext (PACKAGE, String)
179#define LIBEXTRACTOR_GETTEXT_DOMAIN "libextractor" 178#define LIBEXTRACTOR_GETTEXT_DOMAIN "libextractor"
180#else
181#include "libintlemu.h"
182#define _(String) dgettext ("org.gnunet.gnunet", String)
183#define LIBEXTRACTOR_GETTEXT_DOMAIN "org.gnunet.libextractor"
184#endif
185 179
186#include <sys/mman.h> 180#include <sys/mman.h>
187 181
@@ -252,6 +246,32 @@ atoll (const char *nptr);
252#define GNUNET_THREAD_LOCAL 246#define GNUNET_THREAD_LOCAL
253#endif 247#endif
254 248
249
250/* LSB-style exit status codes */
251#ifndef EXIT_INVALIDARGUMENT
252#define EXIT_INVALIDARGUMENT 2
253#endif
254
255#ifndef EXIT_NOTIMPLEMENTED
256#define EXIT_NOTIMPLEMENTED 3
257#endif
258
259#ifndef EXIT_NOPERMISSION
260#define EXIT_NOPERMISSION 4
261#endif
262
263#ifndef EXIT_NOTINSTALLED
264#define EXIT_NOTINSTALLED 5
265#endif
266
267#ifndef EXIT_NOTCONFIGURED
268#define EXIT_NOTCONFIGURED 6
269#endif
270
271#ifndef EXIT_NOTRUNNING
272#define EXIT_NOTRUNNING 7
273#endif
274
255/** 275/**
256 * clang et al do not have such an attribute 276 * clang et al do not have such an attribute
257 */ 277 */
diff --git a/src/json/Makefile.am b/src/json/Makefile.am
index d4ea38adf..2e97cecb9 100644
--- a/src/json/Makefile.am
+++ b/src/json/Makefile.am
@@ -13,21 +13,21 @@ libgnunetjson_la_LDFLAGS = \
13 $(GN_LIBINTL) \ 13 $(GN_LIBINTL) \
14 -version-info 0:0:0 \ 14 -version-info 0:0:0 \
15 -no-undefined 15 -no-undefined
16libgnunetjson_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS) 16libgnunetjson_la_CFLAGS = \
17 $(MHD_CFLAGS) \
18 $(AM_CFLAGS)
17libgnunetjson_la_SOURCES = \ 19libgnunetjson_la_SOURCES = \
18 json.c \ 20 json.c \
19 json_mhd.c \
20 json_generator.c \ 21 json_generator.c \
21 json_helper.c 22 json_helper.c \
23 json_mhd.c \
24 json_pack.c
22libgnunetjson_la_LIBADD = \ 25libgnunetjson_la_LIBADD = \
23 $(top_builddir)/src/util/libgnunetutil.la \ 26 $(top_builddir)/src/util/libgnunetutil.la \
24 -ljansson \ 27 -ljansson \
25 $(MHD_LIBS) \ 28 $(MHD_LIBS) \
26 $(XLIB) \ 29 $(XLIB) \
27 $(Z_LIBS) 30 $(Z_LIBS)
28libgnunetjson_la_DEPENDENCIES = \
29 $(top_builddir)/src/util/libgnunetutil.la
30
31 31
32check_PROGRAMS = \ 32check_PROGRAMS = \
33 test_json \ 33 test_json \
diff --git a/src/json/json.c b/src/json/json.c
index d55189804..51d5c0c72 100644
--- a/src/json/json.c
+++ b/src/json/json.c
@@ -28,19 +28,6 @@
28#include "gnunet_json_lib.h" 28#include "gnunet_json_lib.h"
29 29
30 30
31/**
32 * Navigate and parse data in a JSON tree. Tries to parse the @a root
33 * to find all of the values given in the @a spec. If one of the
34 * entries in @a spec cannot be found or parsed, the name of the JSON
35 * field is returned in @a error_json_name, and the offset of the
36 * entry in @a spec is returned in @a error_line.
37 *
38 * @param root the JSON node to start the navigation at.
39 * @param spec parse specification array
40 * @param[out] error_json_name which JSON field was problematic
41 * @param[out] which index into @a spec did we encounter an error
42 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
43 */
44enum GNUNET_GenericReturnValue 31enum GNUNET_GenericReturnValue
45GNUNET_JSON_parse (const json_t *root, 32GNUNET_JSON_parse (const json_t *root,
46 struct GNUNET_JSON_Specification *spec, 33 struct GNUNET_JSON_Specification *spec,
@@ -85,12 +72,6 @@ GNUNET_JSON_parse (const json_t *root,
85} 72}
86 73
87 74
88/**
89 * Set the "optional" flag for a parser specification entry.
90 *
91 * @param spec specification to modify
92 * @return spec copy of @a spec with optional bit set
93 */
94struct GNUNET_JSON_Specification 75struct GNUNET_JSON_Specification
95GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec) 76GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec)
96{ 77{
@@ -101,18 +82,13 @@ GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec)
101} 82}
102 83
103 84
104/**
105 * Frees all elements allocated during a #GNUNET_JSON_parse()
106 * operation.
107 *
108 * @param spec specification of the parse operation
109 */
110void 85void
111GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec) 86GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec)
112{ 87{
113 for (unsigned int i = 0; NULL != spec[i].parser; i++) 88 for (unsigned int i = 0; NULL != spec[i].parser; i++)
114 if (NULL != spec[i].cleaner) 89 if (NULL != spec[i].cleaner)
115 spec[i].cleaner (spec[i].cls, &spec[i]); 90 spec[i].cleaner (spec[i].cls,
91 &spec[i]);
116} 92}
117 93
118 94
@@ -151,15 +127,6 @@ set_json (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
151} 127}
152 128
153 129
154/**
155 * Allow user to specify a JSON input value.
156 *
157 * @param shortName short name of the option
158 * @param name long name of the option
159 * @param argumentHelp help text for the option argument
160 * @param description long help text for the option
161 * @param[out] val set to the JSON specified at the command line
162 */
163struct GNUNET_GETOPT_CommandLineOption 130struct GNUNET_GETOPT_CommandLineOption
164GNUNET_JSON_getopt (char shortName, 131GNUNET_JSON_getopt (char shortName,
165 const char *name, 132 const char *name,
diff --git a/src/json/json_pack.c b/src/json/json_pack.c
new file mode 100644
index 000000000..92f8b4535
--- /dev/null
+++ b/src/json/json_pack.c
@@ -0,0 +1,325 @@
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 json/json_pack.c
22 * @brief functions to pack JSON objects
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "gnunet_json_lib.h"
27
28
29json_t *
30GNUNET_JSON_pack_ (struct GNUNET_JSON_PackSpec spec[])
31{
32 json_t *ret;
33
34 ret = json_object ();
35 GNUNET_assert (NULL != ret);
36 for (unsigned int i = 0;
37 NULL != spec[i].field_name;
38 i++)
39 {
40 if (NULL == spec[i].object)
41 {
42 GNUNET_assert (spec[i].allow_null);
43 }
44 else
45 {
46 GNUNET_assert (0 ==
47 json_object_set_new (ret,
48 spec[i].field_name,
49 spec[i].object));
50 spec[i].object = NULL;
51 }
52 }
53 return ret;
54}
55
56
57struct GNUNET_JSON_PackSpec
58GNUNET_JSON_pack_end_ (void)
59{
60 struct GNUNET_JSON_PackSpec ps = {
61 .field_name = NULL
62 };
63
64 return ps;
65}
66
67
68struct GNUNET_JSON_PackSpec
69GNUNET_JSON_pack_allow_null (struct GNUNET_JSON_PackSpec in)
70{
71 in.allow_null = true;
72 return in;
73}
74
75
76struct GNUNET_JSON_PackSpec
77GNUNET_JSON_pack_bool (const char *name,
78 bool b)
79{
80 struct GNUNET_JSON_PackSpec ps = {
81 .field_name = name,
82 .object = json_boolean (b)
83 };
84
85 return ps;
86}
87
88
89struct GNUNET_JSON_PackSpec
90GNUNET_JSON_pack_string (const char *name,
91 const char *s)
92{
93 struct GNUNET_JSON_PackSpec ps = {
94 .field_name = name,
95 .object = json_string (s)
96 };
97
98 return ps;
99}
100
101
102struct GNUNET_JSON_PackSpec
103GNUNET_JSON_pack_uint64 (const char *name,
104 uint64_t num)
105{
106 struct GNUNET_JSON_PackSpec ps = {
107 .field_name = name,
108 .object = json_integer ((json_int_t) num)
109 };
110
111#if JSON_INTEGER_IS_LONG_LONG
112 GNUNET_assert (num <= LLONG_MAX);
113#else
114 GNUNET_assert (num <= LONG_MAX);
115#endif
116 return ps;
117}
118
119
120struct GNUNET_JSON_PackSpec
121GNUNET_JSON_pack_int64 (const char *name,
122 int64_t num)
123{
124 struct GNUNET_JSON_PackSpec ps = {
125 .field_name = name,
126 .object = json_integer ((json_int_t) num)
127 };
128
129#if JSON_INTEGER_IS_LONG_LONG
130 GNUNET_assert (num <= LLONG_MAX);
131 GNUNET_assert (num >= LLONG_MIN);
132#else
133 GNUNET_assert (num <= LONG_MAX);
134 GNUNET_assert (num >= LONG_MIN);
135#endif
136 return ps;
137}
138
139
140struct GNUNET_JSON_PackSpec
141GNUNET_JSON_pack_object_steal (const char *name,
142 json_t *o)
143{
144 struct GNUNET_JSON_PackSpec ps = {
145 .field_name = name,
146 .object = o
147 };
148
149 if (NULL == o)
150 return ps;
151 if (! json_is_object (o))
152 {
153 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
154 "Expected JSON object for field `%s'\n",
155 name);
156 GNUNET_assert (0);
157 }
158 return ps;
159}
160
161
162struct GNUNET_JSON_PackSpec
163GNUNET_JSON_pack_object_incref (const char *name,
164 json_t *o)
165{
166 struct GNUNET_JSON_PackSpec ps = {
167 .field_name = name,
168 .object = o
169 };
170
171 if (NULL == o)
172 return ps;
173 (void) json_incref (o);
174 if (! json_is_object (o))
175 {
176 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
177 "Expected JSON object for field `%s'\n",
178 name);
179 GNUNET_assert (0);
180 }
181 return ps;
182}
183
184
185struct GNUNET_JSON_PackSpec
186GNUNET_JSON_pack_array_steal (const char *name,
187 json_t *a)
188{
189 struct GNUNET_JSON_PackSpec ps = {
190 .field_name = name,
191 .object = a
192 };
193
194 if (NULL == a)
195 return ps;
196 if (! json_is_array (a))
197 {
198 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
199 "Expected JSON array for field `%s'\n",
200 name);
201 GNUNET_assert (0);
202 }
203 return ps;
204}
205
206
207struct GNUNET_JSON_PackSpec
208GNUNET_JSON_pack_array_incref (const char *name,
209 json_t *a)
210{
211 struct GNUNET_JSON_PackSpec ps = {
212 .field_name = name,
213 .object = a
214 };
215
216 if (NULL == a)
217 return ps;
218 (void) json_incref (a);
219 if (! json_is_array (a))
220 {
221 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
222 "Expected JSON array for field `%s'\n",
223 name);
224 GNUNET_assert (0);
225 }
226 return ps;
227}
228
229
230struct GNUNET_JSON_PackSpec
231GNUNET_JSON_pack_data_varsize (const char *name,
232 const void *blob,
233 size_t blob_size)
234{
235 struct GNUNET_JSON_PackSpec ps = {
236 .field_name = name,
237 .object = (NULL != blob)
238 ? GNUNET_JSON_from_data (blob,
239 blob_size)
240 : NULL
241 };
242
243 return ps;
244}
245
246
247struct GNUNET_JSON_PackSpec
248GNUNET_JSON_pack_time_abs (const char *name,
249 struct GNUNET_TIME_Absolute at)
250{
251 struct GNUNET_JSON_PackSpec ps = {
252 .field_name = name
253 };
254
255 if (0 != at.abs_value_us)
256 {
257 ps.object = GNUNET_JSON_from_time_abs (at);
258 GNUNET_assert (NULL != ps.object);
259 }
260 else
261 {
262 ps.object = NULL;
263 }
264 return ps;
265}
266
267
268struct GNUNET_JSON_PackSpec
269GNUNET_JSON_pack_time_abs_nbo (const char *name,
270 struct GNUNET_TIME_AbsoluteNBO at)
271{
272 return GNUNET_JSON_pack_time_abs (name,
273 GNUNET_TIME_absolute_ntoh (at));
274}
275
276
277struct GNUNET_JSON_PackSpec
278GNUNET_JSON_pack_time_rel (const char *name,
279 struct GNUNET_TIME_Relative rt)
280{
281 json_t *json;
282
283 json = GNUNET_JSON_from_time_rel (rt);
284 GNUNET_assert (NULL != json);
285 return GNUNET_JSON_pack_object_steal (name,
286 json);
287}
288
289
290struct GNUNET_JSON_PackSpec
291GNUNET_JSON_pack_time_rel_nbo (const char *name,
292 struct GNUNET_TIME_RelativeNBO rt)
293{
294 return GNUNET_JSON_pack_time_rel (name,
295 GNUNET_TIME_relative_ntoh (rt));
296}
297
298
299struct GNUNET_JSON_PackSpec
300GNUNET_JSON_pack_rsa_public_key (const char *name,
301 const struct GNUNET_CRYPTO_RsaPublicKey *pk)
302{
303 struct GNUNET_JSON_PackSpec ps = {
304 .field_name = name,
305 .object = GNUNET_JSON_from_rsa_public_key (pk)
306 };
307
308 return ps;
309}
310
311
312struct GNUNET_JSON_PackSpec
313GNUNET_JSON_pack_rsa_signature (const char *name,
314 const struct GNUNET_CRYPTO_RsaSignature *sig)
315{
316 struct GNUNET_JSON_PackSpec ps = {
317 .field_name = name,
318 .object = GNUNET_JSON_from_rsa_signature (sig)
319 };
320
321 return ps;
322}
323
324
325/* end of json_pack.c */
diff --git a/src/messenger/gnunet-messenger.c b/src/messenger/gnunet-messenger.c
index 094ae398d..28fa4b147 100644
--- a/src/messenger/gnunet-messenger.c
+++ b/src/messenger/gnunet-messenger.c
@@ -80,7 +80,12 @@ on_message (void *cls, struct GNUNET_MESSENGER_Room *room, const struct GNUNET_M
80 } 80 }
81 case GNUNET_MESSENGER_KIND_TEXT: 81 case GNUNET_MESSENGER_KIND_TEXT:
82 { 82 {
83 printf ("* '%s' says: \"%s\"\n", sender_name, message->body.text.text); 83 if (flags & GNUNET_MESSENGER_FLAG_SENT)
84 printf (">");
85 else
86 printf ("<");
87
88 printf (" '%s' says: \"%s\"\n", sender_name, message->body.text.text);
84 break; 89 break;
85 } 90 }
86 default: 91 default:
diff --git a/src/messenger/gnunet-service-messenger_handle.c b/src/messenger/gnunet-service-messenger_handle.c
index 4d2318d62..d7007dbf6 100644
--- a/src/messenger/gnunet-service-messenger_handle.c
+++ b/src/messenger/gnunet-service-messenger_handle.c
@@ -474,6 +474,28 @@ get_next_member_session_contect(const struct GNUNET_MESSENGER_MemberSession *ses
474 return get_member_session_context(session); 474 return get_member_session_context(session);
475} 475}
476 476
477static const struct GNUNET_MESSENGER_MemberSession*
478get_handle_member_session (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
479{
480 GNUNET_assert((handle) && (key) && (handle->service));
481
482 const struct GNUNET_ShortHashCode *id = get_handle_member_id(handle, key);
483 struct GNUNET_MESSENGER_SrvRoom *room = get_service_room(handle->service, key);
484
485 if ((!id) || (!room))
486 return NULL;
487
488 struct GNUNET_MESSENGER_MemberStore *store = get_room_member_store(room);
489 struct GNUNET_MESSENGER_Member *member = get_store_member(store, id);
490
491 const struct GNUNET_MESSENGER_Ego *ego = get_handle_ego(handle);
492
493 if (!ego)
494 return NULL;
495
496 return get_member_session(member, &(ego->pub));
497}
498
477void 499void
478notify_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, 500notify_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key,
479 const struct GNUNET_MESSENGER_MemberSession *session, 501 const struct GNUNET_MESSENGER_MemberSession *session,
@@ -523,9 +545,13 @@ notify_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, const struct G
523 GNUNET_memcpy(&(msg->context), context, sizeof(msg->context)); 545 GNUNET_memcpy(&(msg->context), context, sizeof(msg->context));
524 GNUNET_memcpy(&(msg->hash), hash, sizeof(msg->hash)); 546 GNUNET_memcpy(&(msg->hash), hash, sizeof(msg->hash));
525 547
526 msg->flags = (uint32_t) ( 548 msg->flags = (uint32_t) GNUNET_MESSENGER_FLAG_NONE;
527 private_message? GNUNET_MESSENGER_FLAG_PRIVATE : GNUNET_MESSENGER_FLAG_NONE 549
528 ); 550 if (get_handle_member_session(handle, key) == session)
551 msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_SENT;
552
553 if (private_message)
554 msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_PRIVATE;
529 555
530 char *buffer = ((char*) msg) + sizeof(*msg); 556 char *buffer = ((char*) msg) + sizeof(*msg);
531 encode_message (message, length, buffer, GNUNET_YES); 557 encode_message (message, length, buffer, GNUNET_YES);
diff --git a/src/messenger/gnunet-service-messenger_member.c b/src/messenger/gnunet-service-messenger_member.c
index 7f00e8438..b0a735dbe 100644
--- a/src/messenger/gnunet-service-messenger_member.c
+++ b/src/messenger/gnunet-service-messenger_member.c
@@ -88,6 +88,7 @@ callback_scan_for_sessions (void *cls, const char *filename)
88 GNUNET_asprintf (&directory, "%s%c", filename, DIR_SEPARATOR); 88 GNUNET_asprintf (&directory, "%s%c", filename, DIR_SEPARATOR);
89 89
90 load_member_session(member, directory); 90 load_member_session(member, directory);
91 GNUNET_free (directory);
91 } 92 }
92 93
93 return GNUNET_OK; 94 return GNUNET_OK;
diff --git a/src/messenger/gnunet-service-messenger_room.c b/src/messenger/gnunet-service-messenger_room.c
index c3a5e3a4b..73e94908f 100644
--- a/src/messenger/gnunet-service-messenger_room.c
+++ b/src/messenger/gnunet-service-messenger_room.c
@@ -1144,6 +1144,7 @@ load_room (struct GNUNET_MESSENGER_SrvRoom *room)
1144 GNUNET_asprintf (&last_messages_file, "%s%s", room_dir, "last_messages.list"); 1144 GNUNET_asprintf (&last_messages_file, "%s%s", room_dir, "last_messages.list");
1145 1145
1146 load_message_state(&(room->state), room_dir); 1146 load_message_state(&(room->state), room_dir);
1147 GNUNET_free (last_messages_file);
1147 } 1148 }
1148 1149
1149 GNUNET_free(room_dir); 1150 GNUNET_free(room_dir);
diff --git a/src/namecache/namecache_api.c b/src/namecache/namecache_api.c
index fdbf142a7..70c848037 100644
--- a/src/namecache/namecache_api.c
+++ b/src/namecache/namecache_api.c
@@ -228,6 +228,7 @@ handle_lookup_block_response (void *cls,
228 char buf[size] GNUNET_ALIGN; 228 char buf[size] GNUNET_ALIGN;
229 struct GNUNET_GNSRECORD_Block *block; 229 struct GNUNET_GNSRECORD_Block *block;
230 230
231 memset (buf, 0, size);
231 block = (struct GNUNET_GNSRECORD_Block *) buf; 232 block = (struct GNUNET_GNSRECORD_Block *) buf;
232 GNUNET_memcpy (block, 233 GNUNET_memcpy (block,
233 &msg[1], 234 &msg[1],
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am
index 61bcfbaf8..18e6a196b 100644
--- a/src/namestore/Makefile.am
+++ b/src/namestore/Makefile.am
@@ -752,8 +752,4 @@ EXTRA_DIST = \
752 test_plugin_namestore_postgres.conf \ 752 test_plugin_namestore_postgres.conf \
753 test_plugin_namestore_flat.conf \ 753 test_plugin_namestore_flat.conf \
754 test_hostkey \ 754 test_hostkey \
755 zonefiles/BW7PTMDSN5KS42GMK2VKVE96BAYDS3QVMAS7SC5208FD6HFTAXE0.zkey \
756 zonefiles/KHW2Y5A7X59Z8BC2GHSEQ9WGZ5HWVEF25TBFR3Q5QHCERMVM76DG.zkey \
757 zonefiles/CNFGWF0JH0C65M6PQW6VSRR6D3NEZVHAQF6NC037J01TETS6CJ30.zkey \
758 zonefiles/TWY43VS959JJ41KN2FG8782EJ2N0XDF4J6BWASR1BK5BPPRWQJAG.zkey \
759 $(check_SCRIPTS) 755 $(check_SCRIPTS)
diff --git a/src/namestore/gnunet-namestore-fcfsd.c b/src/namestore/gnunet-namestore-fcfsd.c
index 847f7cb64..95d4c5878 100644
--- a/src/namestore/gnunet-namestore-fcfsd.c
+++ b/src/namestore/gnunet-namestore-fcfsd.c
@@ -185,15 +185,15 @@ do_shutdown (void *cls)
185 } 185 }
186 if (NULL != notfound_page) 186 if (NULL != notfound_page)
187 { 187 {
188 MHD_destroy_response (main_page->response); 188 MHD_destroy_response (notfound_page->response);
189 GNUNET_free (main_page->handle); 189 GNUNET_free (notfound_page->handle);
190 GNUNET_free (main_page); 190 GNUNET_free (notfound_page);
191 } 191 }
192 if (NULL != forbidden_page) 192 if (NULL != forbidden_page)
193 { 193 {
194 MHD_destroy_response (main_page->response); 194 MHD_destroy_response (forbidden_page->response);
195 GNUNET_free (main_page->handle); 195 GNUNET_free (forbidden_page->handle);
196 GNUNET_free (main_page); 196 GNUNET_free (forbidden_page);
197 } 197 }
198 198
199 if (NULL != namestore) 199 if (NULL != namestore)
diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c
index ae93e5eff..ff5494dc7 100644
--- a/src/namestore/plugin_rest_namestore.c
+++ b/src/namestore/plugin_rest_namestore.c
@@ -955,6 +955,12 @@ list_ego (void *cls,
955 state = ID_REST_STATE_POST_INIT; 955 state = ID_REST_STATE_POST_INIT;
956 return; 956 return;
957 } 957 }
958 if (NULL == ego)
959 {
960 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
961 "Called with NULL ego\n");
962 return;
963 }
958 if (ID_REST_STATE_INIT == state) 964 if (ID_REST_STATE_INIT == state)
959 { 965 {
960 ego_entry = GNUNET_new (struct EgoEntry); 966 ego_entry = GNUNET_new (struct EgoEntry);
diff --git a/src/namestore/zonefiles/BW7PTMDSN5KS42GMK2VKVE96BAYDS3QVMAS7SC5208FD6HFTAXE0.zkey b/src/namestore/zonefiles/BW7PTMDSN5KS42GMK2VKVE96BAYDS3QVMAS7SC5208FD6HFTAXE0.zkey
deleted file mode 100644
index 0d37aefef..000000000
--- a/src/namestore/zonefiles/BW7PTMDSN5KS42GMK2VKVE96BAYDS3QVMAS7SC5208FD6HFTAXE0.zkey
+++ /dev/null
@@ -1 +0,0 @@
1ˆ‘’“ÂÚ Qž”0ÿ·Ò†d Õ/Ô#‰`«ÇËÂ$Éf \ No newline at end of file
diff --git a/src/namestore/zonefiles/CNFGWF0JH0C65M6PQW6VSRR6D3NEZVHAQF6NC037J01TETS6CJ30.zkey b/src/namestore/zonefiles/CNFGWF0JH0C65M6PQW6VSRR6D3NEZVHAQF6NC037J01TETS6CJ30.zkey
deleted file mode 100644
index b5b465ea1..000000000
--- a/src/namestore/zonefiles/CNFGWF0JH0C65M6PQW6VSRR6D3NEZVHAQF6NC037J01TETS6CJ30.zkey
+++ /dev/null
Binary files differ
diff --git a/src/namestore/zonefiles/KHW2Y5A7X59Z8BC2GHSEQ9WGZ5HWVEF25TBFR3Q5QHCERMVM76DG.zkey b/src/namestore/zonefiles/KHW2Y5A7X59Z8BC2GHSEQ9WGZ5HWVEF25TBFR3Q5QHCERMVM76DG.zkey
deleted file mode 100644
index 7535efb5e..000000000
--- a/src/namestore/zonefiles/KHW2Y5A7X59Z8BC2GHSEQ9WGZ5HWVEF25TBFR3Q5QHCERMVM76DG.zkey
+++ /dev/null
@@ -1 +0,0 @@
1p‘Ñç¨Â¡8&û„D6£ Vív+XÃì{ A \ No newline at end of file
diff --git a/src/namestore/zonefiles/TWY43VS959JJ41KN2FG8782EJ2N0XDF4J6BWASR1BK5BPPRWQJAG.zkey b/src/namestore/zonefiles/TWY43VS959JJ41KN2FG8782EJ2N0XDF4J6BWASR1BK5BPPRWQJAG.zkey
deleted file mode 100644
index ac3ed96a3..000000000
--- a/src/namestore/zonefiles/TWY43VS959JJ41KN2FG8782EJ2N0XDF4J6BWASR1BK5BPPRWQJAG.zkey
+++ /dev/null
@@ -1,2 +0,0 @@
1XJèµMíŠÀ …¬½
2dú胦ÓŒòB×=ÏB \ No newline at end of file
diff --git a/src/nse/Makefile.am b/src/nse/Makefile.am
index 85ae4d3be..824aa10d4 100644
--- a/src/nse/Makefile.am
+++ b/src/nse/Makefile.am
@@ -47,6 +47,7 @@ gnunet_nse_profiler_LDADD = -lm \
47 libgnunetnse.la \ 47 libgnunetnse.la \
48 $(top_builddir)/src/util/libgnunetutil.la \ 48 $(top_builddir)/src/util/libgnunetutil.la \
49 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 49 $(top_builddir)/src/statistics/libgnunetstatistics.la \
50 $(top_builddir)/src/testing/libgnunettesting.la \
50 $(top_builddir)/src/testbed/libgnunettestbed.la \ 51 $(top_builddir)/src/testbed/libgnunettestbed.la \
51 $(GN_LIBINTL) 52 $(GN_LIBINTL)
52 53
diff --git a/src/peerinfo-tool/Makefile.am b/src/peerinfo-tool/Makefile.am
index 74af5890b..825ad5452 100644
--- a/src/peerinfo-tool/Makefile.am
+++ b/src/peerinfo-tool/Makefile.am
@@ -26,14 +26,6 @@ libgnunet_plugin_rest_peerinfo_la_LIBADD = \
26 $(top_builddir)/src/json/libgnunetjson.la \ 26 $(top_builddir)/src/json/libgnunetjson.la \
27 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ 27 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
28 $(LTLIBINTL) -ljansson $(MHD_LIBS) 28 $(LTLIBINTL) -ljansson $(MHD_LIBS)
29libgnunet_plugin_rest_peerinfo_la_DEPENDENCIES = \
30 $(top_builddir)/src/hello/libgnunethello.la \
31 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
32 $(top_builddir)/src/transport/libgnunettransport.la \
33 $(top_builddir)/src/ats/libgnunetats.la \
34 $(top_builddir)/src/rest/libgnunetrest.la \
35 $(top_builddir)/src/json/libgnunetjson.la \
36 $(top_builddir)/src/util/libgnunetutil.la
37libgnunet_plugin_rest_peerinfo_la_LDFLAGS = \ 29libgnunet_plugin_rest_peerinfo_la_LDFLAGS = \
38 $(GN_PLUGIN_LDFLAGS) 30 $(GN_PLUGIN_LDFLAGS)
39libgnunet_plugin_rest_peerinfo_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS) 31libgnunet_plugin_rest_peerinfo_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS)
diff --git a/src/pq/Makefile.am b/src/pq/Makefile.am
index 0febac4ac..cbb123cbb 100644
--- a/src/pq/Makefile.am
+++ b/src/pq/Makefile.am
@@ -24,7 +24,6 @@ libgnunetpq_la_LIBADD = -lpq \
24libgnunetpq_la_LDFLAGS = \ 24libgnunetpq_la_LDFLAGS = \
25 $(POSTGRESQL_LDFLAGS) \ 25 $(POSTGRESQL_LDFLAGS) \
26 $(GN_LIB_LDFLAGS) \ 26 $(GN_LIB_LDFLAGS) \
27 -lpthread \
28 -version-info 1:0:0 27 -version-info 1:0:0
29 28
30if ENABLE_TEST_RUN 29if ENABLE_TEST_RUN
diff --git a/src/pq/pq.h b/src/pq/pq.h
index 3c89626a9..d10931d99 100644
--- a/src/pq/pq.h
+++ b/src/pq/pq.h
@@ -28,6 +28,7 @@
28#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
29#include "gnunet_pq_lib.h" 29#include "gnunet_pq_lib.h"
30 30
31
31/** 32/**
32 * Handle to Postgres database. 33 * Handle to Postgres database.
33 */ 34 */
@@ -59,24 +60,32 @@ struct GNUNET_PQ_Context
59 char *load_path; 60 char *load_path;
60 61
61 /** 62 /**
62 * Function to call on Postgres FDs. 63 * Map managing event subscriptions.
63 */ 64 */
64 GNUNET_PQ_SocketCallback sc; 65 struct GNUNET_CONTAINER_MultiShortmap *channel_map;
65 66
66 /** 67 /**
67 * Closure for @e sc. 68 * Task responsible for processing events.
68 */ 69 */
69 void *sc_cls; 70 struct GNUNET_SCHEDULER_Task *event_task;
70 71
71 /** 72 /**
72 * Map managing event subscriptions. 73 * File descriptor wrapper for @e event_task.
73 */ 74 */
74 struct GNUNET_CONTAINER_MultiShortmap *channel_map; 75 struct GNUNET_NETWORK_Handle *rfd;
75
76 /**
77 * Lock to access @e channel_map.
78 */
79 pthread_mutex_t notify_lock;
80}; 76};
81 77
78
79/**
80 * Internal API. Reconnect should re-register notifications
81 * after a disconnect.
82 *
83 * @param db the DB handle
84 * @param fd socket to listen on
85 */
86void
87GNUNET_PQ_event_reconnect_ (struct GNUNET_PQ_Context *db,
88 int fd);
89
90
82#endif 91#endif
diff --git a/src/pq/pq_connect.c b/src/pq/pq_connect.c
index 00664dcd0..a2dce3fb0 100644
--- a/src/pq/pq_connect.c
+++ b/src/pq/pq_connect.c
@@ -24,6 +24,7 @@
24 */ 24 */
25#include "platform.h" 25#include "platform.h"
26#include "pq.h" 26#include "pq.h"
27#include <pthread.h>
27 28
28 29
29/** 30/**
@@ -63,28 +64,6 @@ pq_notice_processor_cb (void *arg,
63} 64}
64 65
65 66
66/**
67 * Create a connection to the Postgres database using @a config_str for the
68 * configuration. Initialize logging via GNUnet's log routines and disable
69 * Postgres's logger. Also ensures that the statements in @a load_path and @a
70 * es are executed whenever we (re)connect to the database, and that the
71 * prepared statements in @a ps are "ready". If statements in @es fail that
72 * were created with #GNUNET_PQ_make_execute(), then the entire operation
73 * fails.
74 *
75 * In @a load_path, a list of "$XXXX.sql" files is expected where $XXXX
76 * must be a sequence of contiguous integer values starting at 0000.
77 * These files are then loaded in sequence using "psql $config_str" before
78 * running statements from @e es. The directory is inspected again on
79 * reconnect.
80 *
81 * @param config_str configuration to use
82 * @param load_path path to directory with SQL transactions to run, can be NULL
83 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated
84 * array of statements to execute upon EACH connection, can be NULL
85 * @param ps array of prepared statements to prepare, can be NULL
86 * @return NULL on error
87 */
88struct GNUNET_PQ_Context * 67struct GNUNET_PQ_Context *
89GNUNET_PQ_connect (const char *config_str, 68GNUNET_PQ_connect (const char *config_str,
90 const char *load_path, 69 const char *load_path,
@@ -122,6 +101,8 @@ GNUNET_PQ_connect (const char *config_str,
122 ps, 101 ps,
123 plen * sizeof (struct GNUNET_PQ_PreparedStatement)); 102 plen * sizeof (struct GNUNET_PQ_PreparedStatement));
124 } 103 }
104 db->channel_map = GNUNET_CONTAINER_multishortmap_create (16,
105 GNUNET_YES);
125 GNUNET_PQ_reconnect (db); 106 GNUNET_PQ_reconnect (db);
126 if (NULL == db->conn) 107 if (NULL == db->conn)
127 { 108 {
@@ -142,7 +123,7 @@ GNUNET_PQ_connect (const char *config_str,
142 * @param i patch number to append to the @a load_path 123 * @param i patch number to append to the @a load_path
143 * @return #GNUNET_OK on success, #GNUNET_NO if patch @a i does not exist, #GNUNET_SYSERR on error 124 * @return #GNUNET_OK on success, #GNUNET_NO if patch @a i does not exist, #GNUNET_SYSERR on error
144 */ 125 */
145static int 126static enum GNUNET_GenericReturnValue
146apply_patch (struct GNUNET_PQ_Context *db, 127apply_patch (struct GNUNET_PQ_Context *db,
147 const char *load_path, 128 const char *load_path,
148 unsigned int i) 129 unsigned int i)
@@ -162,7 +143,7 @@ apply_patch (struct GNUNET_PQ_Context *db,
162 "Applying SQL file `%s' on database %s\n", 143 "Applying SQL file `%s' on database %s\n",
163 buf, 144 buf,
164 db->config_str); 145 db->config_str);
165 psql = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_NONE, 146 psql = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ERR,
166 NULL, 147 NULL,
167 NULL, 148 NULL,
168 NULL, 149 NULL,
@@ -191,7 +172,7 @@ apply_patch (struct GNUNET_PQ_Context *db,
191 (0 != code) ) 172 (0 != code) )
192 { 173 {
193 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 174 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
194 "Could not run PSQL on file %s: %d\n", 175 "Could not run PSQL on file %s: psql exit code was %d\n",
195 buf, 176 buf,
196 (int) code); 177 (int) code);
197 return GNUNET_SYSERR; 178 return GNUNET_SYSERR;
@@ -200,15 +181,6 @@ apply_patch (struct GNUNET_PQ_Context *db,
200} 181}
201 182
202 183
203/**
204 * Within the @a db context, run all the SQL files
205 * from the @a load_path from 0000-9999.sql (as long
206 * as the files exist contiguously).
207 *
208 * @param db database context to use
209 * @param load_path where to find the XXXX.sql files
210 * @return #GNUNET_OK on success
211 */
212enum GNUNET_GenericReturnValue 184enum GNUNET_GenericReturnValue
213GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db, 185GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db,
214 const char *load_path) 186 const char *load_path)
@@ -304,11 +276,6 @@ GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db,
304} 276}
305 277
306 278
307/**
308 * Reinitialize the database @a db if the connection is down.
309 *
310 * @param db database connection to reinitialize
311 */
312void 279void
313GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db) 280GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db)
314{ 281{
@@ -321,14 +288,11 @@ GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db)
321} 288}
322 289
323 290
324/**
325 * Reinitialize the database @a db.
326 *
327 * @param db database connection to reinitialize
328 */
329void 291void
330GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) 292GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db)
331{ 293{
294 GNUNET_PQ_event_reconnect_ (db,
295 -1);
332 if (NULL != db->conn) 296 if (NULL != db->conn)
333 PQfinish (db->conn); 297 PQfinish (db->conn);
334 db->conn = PQconnectdb (db->config_str); 298 db->conn = PQconnectdb (db->config_str);
@@ -380,7 +344,7 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db)
380 0); 344 0);
381 if (GNUNET_NO == ret) 345 if (GNUNET_NO == ret)
382 { 346 {
383 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 347 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
384 "Failed to find SQL file to load database versioning logic\n"); 348 "Failed to find SQL file to load database versioning logic\n");
385 PQfinish (db->conn); 349 PQfinish (db->conn);
386 db->conn = NULL; 350 db->conn = NULL;
@@ -448,26 +412,11 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db)
448 db->conn = NULL; 412 db->conn = NULL;
449 return; 413 return;
450 } 414 }
415 GNUNET_PQ_event_reconnect_ (db,
416 PQsocket (db->conn));
451} 417}
452 418
453 419
454/**
455 * Connect to a postgres database using the configuration
456 * option "CONFIG" in @a section. Also ensures that the
457 * statements in @a es are executed whenever we (re)connect to the
458 * database, and that the prepared statements in @a ps are "ready".
459 *
460 * The caller does not have to ensure that @a es and @a ps remain allocated
461 * and initialized in memory until #GNUNET_PQ_disconnect() is called, as a copy will be made.
462 *
463 * @param cfg configuration
464 * @param section configuration section to use to get Postgres configuration options
465 * @param load_path_suffix suffix to append to the SQL_DIR in the configuration
466 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated
467 * array of statements to execute upon EACH connection, can be NULL
468 * @param ps array of prepared statements to prepare, can be NULL
469 * @return the postgres handle, NULL on error
470 */
471struct GNUNET_PQ_Context * 420struct GNUNET_PQ_Context *
472GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, 421GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg,
473 const char *section, 422 const char *section,
@@ -509,15 +458,14 @@ GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg,
509} 458}
510 459
511 460
512/**
513 * Disconnect from the database, destroying the prepared statements
514 * and releasing other associated resources.
515 *
516 * @param db database handle to disconnect (will be free'd)
517 */
518void 461void
519GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db) 462GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db)
520{ 463{
464 if (NULL == db)
465 return;
466 GNUNET_assert (0 ==
467 GNUNET_CONTAINER_multishortmap_size (db->channel_map));
468 GNUNET_CONTAINER_multishortmap_destroy (db->channel_map);
521 GNUNET_free (db->es); 469 GNUNET_free (db->es);
522 GNUNET_free (db->ps); 470 GNUNET_free (db->ps);
523 GNUNET_free (db->load_path); 471 GNUNET_free (db->load_path);
diff --git a/src/pq/pq_event.c b/src/pq/pq_event.c
index ecb942230..79a2e80c6 100644
--- a/src/pq/pq_event.c
+++ b/src/pq/pq_event.c
@@ -29,8 +29,8 @@
29 29
30/** 30/**
31 * Handle for an active LISTENer to the database. 31 * Handle for an active LISTENer to the database.
32 */ 32 */
33struct GNUNET_PQ_EventHandler 33struct GNUNET_DB_EventHandler
34{ 34{
35 /** 35 /**
36 * Channel name. 36 * Channel name.
@@ -40,7 +40,7 @@ struct GNUNET_PQ_EventHandler
40 /** 40 /**
41 * Function to call on events. 41 * Function to call on events.
42 */ 42 */
43 GNUNET_PQ_EventCallback cb; 43 GNUNET_DB_EventCallback cb;
44 44
45 /** 45 /**
46 * Closure for @e cb. 46 * Closure for @e cb.
@@ -51,9 +51,12 @@ struct GNUNET_PQ_EventHandler
51 * Database context this event handler is with. 51 * Database context this event handler is with.
52 */ 52 */
53 struct GNUNET_PQ_Context *db; 53 struct GNUNET_PQ_Context *db;
54};
55
56 54
55 /**
56 * Task to run on timeout.
57 */
58 struct GNUNET_SCHEDULER_Task *timeout_task;
59};
57 60
58 61
59/** 62/**
@@ -63,7 +66,7 @@ struct GNUNET_PQ_EventHandler
63 * @param[out] sh short hash to set 66 * @param[out] sh short hash to set
64 */ 67 */
65static void 68static void
66es_to_sh (const struct GNUNET_PQ_EventHeaderP *es, 69es_to_sh (const struct GNUNET_DB_EventHeaderP *es,
67 struct GNUNET_ShortHashCode *sh) 70 struct GNUNET_ShortHashCode *sh)
68{ 71{
69 struct GNUNET_HashCode h_channel; 72 struct GNUNET_HashCode h_channel;
@@ -103,6 +106,24 @@ sh_to_channel (struct GNUNET_ShortHashCode *sh,
103 106
104 107
105/** 108/**
109 * Convert @a sh to a Postgres identifier.
110 *
111 * @param identifier to convert
112 * @param[out] sh set to short hash
113 * @return #GNUNET_OK on success
114 */
115static enum GNUNET_GenericReturnValue
116channel_to_sh (const char *identifier,
117 struct GNUNET_ShortHashCode *sh)
118{
119 return GNUNET_STRINGS_string_to_data (identifier,
120 strlen (identifier),
121 sh,
122 sizeof (*sh));
123}
124
125
126/**
106 * Convert @a es to a Postgres identifier. 127 * Convert @a es to a Postgres identifier.
107 * 128 *
108 * @param es spec to hash to an identifier 129 * @param es spec to hash to an identifier
@@ -111,7 +132,7 @@ sh_to_channel (struct GNUNET_ShortHashCode *sh,
111 * @return end position of the identifier 132 * @return end position of the identifier
112 */ 133 */
113static char * 134static char *
114es_to_channel (const struct GNUNET_PQ_EventHeaderP *es, 135es_to_channel (const struct GNUNET_DB_EventHeaderP *es,
115 char identifier[64]) 136 char identifier[64])
116{ 137{
117 struct GNUNET_ShortHashCode sh; 138 struct GNUNET_ShortHashCode sh;
@@ -141,12 +162,12 @@ struct NotifyContext
141 162
142 163
143/** 164/**
144 * Function called on every event handler that 165 * Function called on every event handler that
145 * needs to be triggered. 166 * needs to be triggered.
146 * 167 *
147 * @param cls a `struct NotifyContext` 168 * @param cls a `struct NotifyContext`
148 * @param sh channel name 169 * @param sh channel name
149 * @param value a `struct GNUNET_PQ_EventHandler` 170 * @param value a `struct GNUNET_DB_EventHandler`
150 * @return #GNUNET_OK continue to iterate 171 * @return #GNUNET_OK continue to iterate
151 */ 172 */
152static int 173static int
@@ -155,45 +176,27 @@ do_notify (void *cls,
155 void *value) 176 void *value)
156{ 177{
157 struct NotifyContext *ctx = cls; 178 struct NotifyContext *ctx = cls;
158 struct GNUNET_PQ_EventHandler *eh = value; 179 struct GNUNET_DB_EventHandler *eh = value;
159 180
160 eh->cb (eh->cb_cls, 181 eh->cb (eh->cb_cls,
161 ctx->extra, 182 ctx->extra,
162 ctx->extra_size); 183 ctx->extra_size);
163 return GNUNET_OK; 184 return GNUNET_OK;
164}
165
166
167void
168GNUNET_PQ_event_set_socket_callback (struct GNUNET_PQ_Context *db,
169 GNUNET_PQ_SocketCallback sc,
170 void *sc_cls)
171{
172 int fd;
173
174 db->sc = sc;
175 db->sc_cls = sc_cls;
176 if (NULL == sc)
177 return;
178 GNUNET_assert (0 ==
179 pthread_mutex_lock (&db->notify_lock));
180 fd = PQsocket (db->conn);
181 if ( (-1 != fd) &&
182 (0 != GNUNET_CONTAINER_multishortmap_size (db->channel_map)) )
183 sc (sc_cls,
184 fd);
185 GNUNET_assert (0 ==
186 pthread_mutex_unlock (&db->notify_lock));
187} 185}
188 186
189 187
190void 188static void
191GNUNET_PQ_event_do_poll (struct GNUNET_PQ_Context *db) 189event_do_poll (struct GNUNET_PQ_Context *db)
192{ 190{
193 PGnotify *n; 191 PGnotify *n;
194 192
195 GNUNET_assert (0 == 193 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
196 pthread_mutex_lock (&db->notify_lock)); 194 "PG poll job active\n");
195 if (1 !=
196 PQconsumeInput (db->conn))
197 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
198 "Failed to read from Postgres: %s\n",
199 PQerrorMessage (db->conn));
197 while (NULL != (n = PQnotifies (db->conn))) 200 while (NULL != (n = PQnotifies (db->conn)))
198 { 201 {
199 struct GNUNET_ShortHashCode sh; 202 struct GNUNET_ShortHashCode sh;
@@ -201,15 +204,22 @@ GNUNET_PQ_event_do_poll (struct GNUNET_PQ_Context *db)
201 .extra = NULL 204 .extra = NULL
202 }; 205 };
203 206
207 if ('X' != toupper ((int) n->relname[0]))
208 {
209 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
210 "Ignoring notification for unsupported channel identifier `%s'\n",
211 n->relname);
212 PQfreemem (n);
213 continue;
214 }
204 if (GNUNET_OK != 215 if (GNUNET_OK !=
205 GNUNET_STRINGS_string_to_data (n->relname, 216 channel_to_sh (&n->relname[1],
206 strlen (n->relname), 217 &sh))
207 &sh,
208 sizeof (sh)))
209 { 218 {
210 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 219 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
211 "Ignoring notification for unsupported channel identifier `%s'\n", 220 "Ignoring notification for unsupported channel identifier `%s'\n",
212 n->relname); 221 n->relname);
222 PQfreemem (n);
213 continue; 223 continue;
214 } 224 }
215 if ( (NULL != n->extra) && 225 if ( (NULL != n->extra) &&
@@ -223,36 +233,97 @@ GNUNET_PQ_event_do_poll (struct GNUNET_PQ_Context *db)
223 "Ignoring notification for unsupported extra data `%s' on channel `%s'\n", 233 "Ignoring notification for unsupported extra data `%s' on channel `%s'\n",
224 n->extra, 234 n->extra,
225 n->relname); 235 n->relname);
236 PQfreemem (n);
226 continue; 237 continue;
227 } 238 }
228 GNUNET_CONTAINER_multishortmap_iterate (db->channel_map, 239 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
229 &do_notify, 240 "Received notification %s with extra data `%.*s'\n",
230 &ctx); 241 n->relname,
242 (int) ctx.extra_size,
243 (const char *) ctx.extra);
244 GNUNET_CONTAINER_multishortmap_get_multiple (db->channel_map,
245 &sh,
246 &do_notify,
247 &ctx);
231 GNUNET_free (ctx.extra); 248 GNUNET_free (ctx.extra);
249 PQfreemem (n);
232 } 250 }
233 GNUNET_assert (0 ==
234 pthread_mutex_unlock (&db->notify_lock));
235} 251}
236 252
237 253
238void 254/**
239GNUNET_PQ_event_scheduler_start (struct GNUNET_PQ_Context *db) 255 * The GNUnet scheduler notifies us that we need to
256 * trigger the DB event poller.
257 *
258 * @param cls a `struct GNUNET_PQ_Context *`
259 */
260static void
261do_scheduler_notify (void *cls)
240{ 262{
241 GNUNET_break (0); // FIXME: not implemented 263 struct GNUNET_PQ_Context *db = cls;
264
265 db->event_task = NULL;
266 GNUNET_assert (NULL != db->rfd);
267 event_do_poll (db);
268 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
269 "Resubscribing\n");
270 db->event_task
271 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
272 db->rfd,
273 &do_scheduler_notify,
274 db);
242} 275}
243 276
244 277
245void 278/**
246GNUNET_PQ_event_scheduler_stop (struct GNUNET_PQ_Context *db) 279 * Function called when the Postgres FD changes and we need
280 * to update the scheduler event loop task.
281 *
282 * @param cls a `struct GNUNET_PQ_Context *`
283 * @param fd the file descriptor, possibly -1
284 */
285static void
286scheduler_fd_cb (void *cls,
287 int fd)
247{ 288{
248 GNUNET_break (0); // FIXME: not implemented 289 struct GNUNET_PQ_Context *db = cls;
290
291 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
292 "New poll FD is %d\n",
293 fd);
294 if (NULL != db->event_task)
295 {
296 GNUNET_SCHEDULER_cancel (db->event_task);
297 db->event_task = NULL;
298 }
299 GNUNET_free (db->rfd);
300 if (-1 == fd)
301 return;
302 if (0 == GNUNET_CONTAINER_multishortmap_size (db->channel_map))
303 return;
304 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
305 "Activating poll job on %d\n",
306 fd);
307 db->rfd = GNUNET_NETWORK_socket_box_native (fd);
308 db->event_task
309 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_ZERO,
310 db->rfd,
311 &do_scheduler_notify,
312 db);
249} 313}
250 314
251 315
316/**
317 * Helper function to trigger an SQL @a cmd on @a db
318 *
319 * @param db database to send command to
320 * @param cmd prefix of the command to send
321 * @param eh details about the event
322 */
252static void 323static void
253manage_subscribe (struct GNUNET_PQ_Context *db, 324manage_subscribe (struct GNUNET_PQ_Context *db,
254 const char *cmd, 325 const char *cmd,
255 struct GNUNET_PQ_EventHandler *eh) 326 struct GNUNET_DB_EventHandler *eh)
256{ 327{
257 char sql[16 + 64]; 328 char sql[16 + 64];
258 char *end; 329 char *end;
@@ -262,6 +333,9 @@ manage_subscribe (struct GNUNET_PQ_Context *db,
262 cmd); 333 cmd);
263 end = sh_to_channel (&eh->sh, 334 end = sh_to_channel (&eh->sh,
264 end); 335 end);
336 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
337 "Executing PQ command `%s'\n",
338 sql);
265 result = PQexec (db->conn, 339 result = PQexec (db->conn,
266 sql); 340 sql);
267 if (PGRES_COMMAND_OK != PQresultStatus (result)) 341 if (PGRES_COMMAND_OK != PQresultStatus (result))
@@ -282,76 +356,134 @@ manage_subscribe (struct GNUNET_PQ_Context *db,
282} 356}
283 357
284 358
285struct GNUNET_PQ_EventHandler * 359/**
360 * Re-subscribe to notifications after disconnect.
361 *
362 * @param cls the DB context
363 * @param sh the short hash of the channel
364 * @param eh the event handler
365 * @return #GNUNET_OK to continue to iterate
366 */
367static int
368register_notify (void *cls,
369 const struct GNUNET_ShortHashCode *sh,
370 void *value)
371{
372 struct GNUNET_PQ_Context *db = cls;
373 struct GNUNET_DB_EventHandler *eh = value;
374
375 manage_subscribe (db,
376 "LISTEN X",
377 eh);
378 return GNUNET_OK;
379}
380
381
382void
383GNUNET_PQ_event_reconnect_ (struct GNUNET_PQ_Context *db,
384 int fd)
385{
386 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
387 "Change in PQ event FD to %d\n",
388 fd);
389 scheduler_fd_cb (db,
390 fd);
391 GNUNET_CONTAINER_multishortmap_iterate (db->channel_map,
392 &register_notify,
393 db);
394}
395
396
397/**
398 * Function run on timeout for an event. Triggers
399 * the notification, but does NOT clear the handler.
400 *
401 * @param cls a `struct GNUNET_DB_EventHandler *`
402 */
403static void
404event_timeout (void *cls)
405{
406 struct GNUNET_DB_EventHandler *eh = cls;
407
408 eh->timeout_task = NULL;
409 eh->cb (eh->cb_cls,
410 NULL,
411 0);
412}
413
414
415struct GNUNET_DB_EventHandler *
286GNUNET_PQ_event_listen (struct GNUNET_PQ_Context *db, 416GNUNET_PQ_event_listen (struct GNUNET_PQ_Context *db,
287 const struct GNUNET_PQ_EventHeaderP *es, 417 const struct GNUNET_DB_EventHeaderP *es,
288 GNUNET_PQ_EventCallback cb, 418 struct GNUNET_TIME_Relative timeout,
419 GNUNET_DB_EventCallback cb,
289 void *cb_cls) 420 void *cb_cls)
290{ 421{
291 struct GNUNET_PQ_EventHandler *eh; 422 struct GNUNET_DB_EventHandler *eh;
292 bool was_zero;
293 423
294 eh = GNUNET_new (struct GNUNET_PQ_EventHandler); 424 eh = GNUNET_new (struct GNUNET_DB_EventHandler);
295 eh->db = db; 425 eh->db = db;
296 es_to_sh (es, 426 es_to_sh (es,
297 &eh->sh); 427 &eh->sh);
298 eh->cb = cb; 428 eh->cb = cb;
299 eh->cb_cls = cb_cls; 429 eh->cb_cls = cb_cls;
300 GNUNET_assert (0 ==
301 pthread_mutex_lock (&db->notify_lock));
302 was_zero = (0 == GNUNET_CONTAINER_multishortmap_size (db->channel_map));
303 GNUNET_assert (GNUNET_OK == 430 GNUNET_assert (GNUNET_OK ==
304 GNUNET_CONTAINER_multishortmap_put (db->channel_map, 431 GNUNET_CONTAINER_multishortmap_put (db->channel_map,
305 &eh->sh, 432 &eh->sh,
306 eh, 433 eh,
307 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 434 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
308 if ( (NULL != db->sc) && 435 if (NULL == db->event_task)
309 was_zero)
310 { 436 {
311 int fd = PQsocket (db->conn); 437 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
312 438 "Starting event scheduler\n");
313 if (-1 != fd) 439 scheduler_fd_cb (db,
314 db->sc (db->sc_cls, 440 PQsocket (db->conn));
315 fd);
316 } 441 }
317 manage_subscribe (db, 442 manage_subscribe (db,
318 "LISTEN ", 443 "LISTEN X",
319 eh); 444 eh);
320 GNUNET_assert (0 == 445 eh->timeout_task = GNUNET_SCHEDULER_add_delayed (timeout,
321 pthread_mutex_unlock (&db->notify_lock)); 446 &event_timeout,
447 eh);
322 return eh; 448 return eh;
323} 449}
324 450
325 451
326void 452void
327GNUNET_PQ_event_listen_cancel (struct GNUNET_PQ_EventHandler *eh) 453GNUNET_PQ_event_listen_cancel (struct GNUNET_DB_EventHandler *eh)
328{ 454{
329 struct GNUNET_PQ_Context *db = eh->db; 455 struct GNUNET_PQ_Context *db = eh->db;
330 456
331 GNUNET_assert (0 ==
332 pthread_mutex_lock (&db->notify_lock));
333 GNUNET_assert (GNUNET_OK == 457 GNUNET_assert (GNUNET_OK ==
334 GNUNET_CONTAINER_multishortmap_remove (db->channel_map, 458 GNUNET_CONTAINER_multishortmap_remove (db->channel_map,
335 &eh->sh, 459 &eh->sh,
336 eh)); 460 eh));
337
338 manage_subscribe (db, 461 manage_subscribe (db,
339 "UNLISTEN ", 462 "UNLISTEN X",
340 eh); 463 eh);
341 if ( (NULL != db->sc) && 464 if (0 == GNUNET_CONTAINER_multishortmap_size (db->channel_map))
342 (0 == GNUNET_CONTAINER_multishortmap_size (db->channel_map)) ) 465 {
466 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
467 "Stopping PQ event scheduler job\n");
468 GNUNET_free (db->rfd);
469 if (NULL != db->event_task)
470 {
471 GNUNET_SCHEDULER_cancel (db->event_task);
472 db->event_task = NULL;
473 }
474 }
475 if (NULL != eh->timeout_task)
343 { 476 {
344 db->sc (db->sc_cls, 477 GNUNET_SCHEDULER_cancel (eh->timeout_task);
345 -1); 478 eh->timeout_task = NULL;
346 } 479 }
347 GNUNET_assert (0 == 480 GNUNET_free (eh);
348 pthread_mutex_unlock (&db->notify_lock));
349} 481}
350 482
351 483
352void 484void
353GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db, 485GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db,
354 const struct GNUNET_PQ_EventHeaderP *es, 486 const struct GNUNET_DB_EventHeaderP *es,
355 const void *extra, 487 const void *extra,
356 size_t extra_size) 488 size_t extra_size)
357{ 489{
@@ -360,11 +492,11 @@ GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db,
360 PGresult *result; 492 PGresult *result;
361 493
362 end = stpcpy (sql, 494 end = stpcpy (sql,
363 "NOTIFY "); 495 "NOTIFY X");
364 end = es_to_channel (es, 496 end = es_to_channel (es,
365 end); 497 end);
366 end = stpcpy (end, 498 end = stpcpy (end,
367 "'"); 499 ", '");
368 end = GNUNET_STRINGS_data_to_string (extra, 500 end = GNUNET_STRINGS_data_to_string (extra,
369 extra_size, 501 extra_size,
370 end, 502 end,
@@ -373,6 +505,9 @@ GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db,
373 *end = '\0'; 505 *end = '\0';
374 end = stpcpy (end, 506 end = stpcpy (end,
375 "'"); 507 "'");
508 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
509 "Executing command `%s'\n",
510 sql);
376 result = PQexec (db->conn, 511 result = PQexec (db->conn,
377 sql); 512 sql);
378 if (PGRES_COMMAND_OK != PQresultStatus (result)) 513 if (PGRES_COMMAND_OK != PQresultStatus (result))
@@ -390,7 +525,8 @@ GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db,
390 PQerrorMessage (db->conn)); 525 PQerrorMessage (db->conn));
391 } 526 }
392 PQclear (result); 527 PQclear (result);
528 event_do_poll (db);
393} 529}
394 530
395/* end of pq_event.c */
396 531
532/* end of pq_event.c */
diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c
index e588da45d..90b5c6489 100644
--- a/src/pq/test_pq.c
+++ b/src/pq/test_pq.c
@@ -25,6 +25,26 @@
25#include "platform.h" 25#include "platform.h"
26#include "pq.h" 26#include "pq.h"
27 27
28/**
29 * Database handle.
30 */
31static struct GNUNET_PQ_Context *db;
32
33/**
34 * Global return value, 0 on success.
35 */
36static int ret;
37
38/**
39 * An event handler.
40 */
41static struct GNUNET_DB_EventHandler *eh;
42
43/**
44 * Timeout task.
45 */
46static struct GNUNET_SCHEDULER_Task *tt;
47
28 48
29/** 49/**
30 * Setup prepared statements. 50 * Setup prepared statements.
@@ -109,7 +129,7 @@ run_queries (struct GNUNET_PQ_Context *db)
109 uint64_t u64; 129 uint64_t u64;
110 uint64_t u642; 130 uint64_t u642;
111 uint64_t uzzz = 42; 131 uint64_t uzzz = 42;
112 132
113 priv = GNUNET_CRYPTO_rsa_private_key_create (1024); 133 priv = GNUNET_CRYPTO_rsa_private_key_create (1024);
114 pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv); 134 pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
115 memset (&hmsg, 42, sizeof(hmsg)); 135 memset (&hmsg, 42, sizeof(hmsg));
@@ -220,6 +240,91 @@ run_queries (struct GNUNET_PQ_Context *db)
220} 240}
221 241
222 242
243/**
244 * Task called on shutdown.
245 *
246 * @param cls NULL
247 */
248static void
249event_end (void *cls)
250{
251 GNUNET_PQ_event_listen_cancel (eh);
252 eh = NULL;
253 if (NULL != tt)
254 {
255 GNUNET_SCHEDULER_cancel (tt);
256 tt = NULL;
257 }
258}
259
260
261/**
262 * Task called on timeout. Should not happen, means
263 * we did not get the expected event.
264 *
265 * @param cls NULL
266 */
267static void
268timeout_cb (void *cls)
269{
270 ret = 2;
271 GNUNET_break (0);
272 tt = NULL;
273 GNUNET_SCHEDULER_shutdown ();
274}
275
276
277/**
278 * Task called on expected event
279 *
280 * @param cls NULL
281 */
282static void
283event_sched_cb (void *cls,
284 const void *extra,
285 size_t extra_size)
286{
287 GNUNET_assert (5 == extra_size);
288 GNUNET_assert (0 ==
289 memcmp ("hello",
290 extra,
291 5));
292 GNUNET_SCHEDULER_shutdown ();
293}
294
295
296/**
297 * Run tests that need a scheduler.
298 *
299 * @param cls NULL
300 */
301static void
302sched_tests (void *cls)
303{
304 struct GNUNET_DB_EventHeaderP es = {
305 .size = htons (sizeof (es)),
306 .type = htons (42)
307 };
308
309
310 tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
311 &timeout_cb,
312 NULL);
313 eh = GNUNET_PQ_event_listen (db,
314 &es,
315 GNUNET_TIME_UNIT_FOREVER_REL,
316 &event_sched_cb,
317 NULL);
318 GNUNET_PQ_reconnect (db);
319 GNUNET_SCHEDULER_add_shutdown (&event_end,
320 NULL);
321 GNUNET_PQ_event_notify (db,
322 &es,
323 "hello",
324 5);
325}
326
327
223int 328int
224main (int argc, 329main (int argc,
225 const char *const argv[]) 330 const char *const argv[])
@@ -239,11 +344,9 @@ main (int argc,
239 ")"), 344 ")"),
240 GNUNET_PQ_EXECUTE_STATEMENT_END 345 GNUNET_PQ_EXECUTE_STATEMENT_END
241 }; 346 };
242 struct GNUNET_PQ_Context *db;
243 int ret;
244 347
245 GNUNET_log_setup ("test-pq", 348 GNUNET_log_setup ("test-pq",
246 "WARNING", 349 "INFO",
247 NULL); 350 NULL);
248 db = GNUNET_PQ_connect ("postgres:///gnunetcheck", 351 db = GNUNET_PQ_connect ("postgres:///gnunetcheck",
249 NULL, 352 NULL,
@@ -272,12 +375,26 @@ main (int argc,
272 return 1; 375 return 1;
273 } 376 }
274 ret = run_queries (db); 377 ret = run_queries (db);
378 if (0 != ret)
379 {
380 GNUNET_break (0);
381 GNUNET_PQ_disconnect (db);
382 return ret;
383 }
384 GNUNET_SCHEDULER_run (&sched_tests,
385 NULL);
386 if (0 != ret)
387 {
388 GNUNET_break (0);
389 GNUNET_PQ_disconnect (db);
390 return ret;
391 }
275#if TEST_RESTART 392#if TEST_RESTART
276 fprintf (stderr, "Please restart Postgres database now!\n"); 393 fprintf (stderr, "Please restart Postgres database now!\n");
277 sleep (60); 394 sleep (60);
278 ret = run_queries (db); 395 ret |= run_queries (db);
279 fprintf (stderr, "Result: %d (expect: 1 -- if you restarted the DB)\n", ret); 396 fprintf (stderr, "Result: %d (expect: 1 -- if you restarted the DB)\n", ret);
280 ret = run_queries (db); 397 ret |= run_queries (db);
281 fprintf (stderr, "Result: %d (expect: 0)\n", ret); 398 fprintf (stderr, "Result: %d (expect: 0)\n", ret);
282#endif 399#endif
283 { 400 {
diff --git a/src/reclaim/Makefile.am b/src/reclaim/Makefile.am
index 1a0b7fae4..350d77d4b 100644
--- a/src/reclaim/Makefile.am
+++ b/src/reclaim/Makefile.am
@@ -61,14 +61,6 @@ libgnunet_plugin_rest_reclaim_la_LIBADD = \
61 $(top_builddir)/src/namestore/libgnunetnamestore.la \ 61 $(top_builddir)/src/namestore/libgnunetnamestore.la \
62 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ 62 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
63 $(LTLIBINTL) -ljansson $(MHD_LIBS) 63 $(LTLIBINTL) -ljansson $(MHD_LIBS)
64libgnunet_plugin_rest_reclaim_la_DEPENDENCIES = \
65 $(top_builddir)/src/identity/libgnunetidentity.la \
66 libgnunetreclaim.la \
67 $(top_builddir)/src/json/libgnunetjson.la \
68 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
69 $(top_builddir)/src/rest/libgnunetrest.la \
70 $(top_builddir)/src/namestore/libgnunetnamestore.la \
71 $(top_builddir)/src/util/libgnunetutil.la
72libgnunet_plugin_rest_reclaim_la_LDFLAGS = \ 64libgnunet_plugin_rest_reclaim_la_LDFLAGS = \
73 $(GN_PLUGIN_LDFLAGS) 65 $(GN_PLUGIN_LDFLAGS)
74libgnunet_plugin_rest_reclaim_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS) 66libgnunet_plugin_rest_reclaim_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS)
@@ -102,11 +94,6 @@ libgnunet_plugin_rest_pabc_la_LIBADD = \
102 $(top_builddir)/src/rest/libgnunetrest.la \ 94 $(top_builddir)/src/rest/libgnunetrest.la \
103 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ 95 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
104 $(LTLIBINTL) -ljansson -lpabc $(MHD_LIBS) 96 $(LTLIBINTL) -ljansson -lpabc $(MHD_LIBS)
105libgnunet_plugin_rest_pabc_la_DEPENDENCIES = \
106 libgnunetreclaim.la \
107 $(top_builddir)/src/json/libgnunetjson.la \
108 $(top_builddir)/src/rest/libgnunetrest.la \
109 $(top_builddir)/src/util/libgnunetutil.la
110libgnunet_plugin_rest_pabc_la_LDFLAGS = \ 97libgnunet_plugin_rest_pabc_la_LDFLAGS = \
111 $(GN_PLUGIN_LDFLAGS) 98 $(GN_PLUGIN_LDFLAGS)
112libgnunet_plugin_rest_pabc_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS) 99libgnunet_plugin_rest_pabc_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS)
diff --git a/src/regex/Makefile.am b/src/regex/Makefile.am
index 13413f242..9a7466cb2 100644
--- a/src/regex/Makefile.am
+++ b/src/regex/Makefile.am
@@ -53,9 +53,6 @@ libgnunetregex_internal_a_SOURCES = \
53 regex_internal_lib.h \ 53 regex_internal_lib.h \
54 regex_internal.h regex_internal.c \ 54 regex_internal.h regex_internal.c \
55 regex_internal_dht.c 55 regex_internal_dht.c
56libgnunetregex_internal_a_DEPENDENCIES = \
57 libgnunetregexblock.la
58
59 56
60libgnunetregex_la_SOURCES = \ 57libgnunetregex_la_SOURCES = \
61 regex_api_announce.c \ 58 regex_api_announce.c \
@@ -126,6 +123,7 @@ gnunet_regex_profiler_SOURCES = \
126 gnunet-regex-profiler.c 123 gnunet-regex-profiler.c
127gnunet_regex_profiler_LDADD = -lm \ 124gnunet_regex_profiler_LDADD = -lm \
128 $(top_builddir)/src/arm/libgnunetarm.la \ 125 $(top_builddir)/src/arm/libgnunetarm.la \
126 $(top_builddir)/src/testing/libgnunettesting.la \
129 $(top_builddir)/src/testbed/libgnunettestbed.la \ 127 $(top_builddir)/src/testbed/libgnunettestbed.la \
130 libgnunetregex_internal.a \ 128 libgnunetregex_internal.a \
131 $(top_builddir)/src/dht/libgnunetdht.la \ 129 $(top_builddir)/src/dht/libgnunetdht.la \
diff --git a/src/rest/plugin_rest_config.c b/src/rest/plugin_rest_config.c
index af833efff..b0f18754c 100644
--- a/src/rest/plugin_rest_config.c
+++ b/src/rest/plugin_rest_config.c
@@ -91,7 +91,6 @@ static struct RequestHandle *requests_head;
91static struct RequestHandle *requests_tail; 91static struct RequestHandle *requests_tail;
92 92
93 93
94
95/** 94/**
96 * Cleanup request handle. 95 * Cleanup request handle.
97 * 96 *
@@ -199,7 +198,9 @@ get_cont (struct GNUNET_REST_RequestHandle *con_handle,
199 } 198 }
200 response = json_dumps (result, 0); 199 response = json_dumps (result, 0);
201 resp = GNUNET_REST_create_response (response); 200 resp = GNUNET_REST_create_response (response);
202 MHD_add_response_header (resp, "Content-Type", "application/json"); 201 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
202 "Content-Type",
203 "application/json"));
203 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 204 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
204 cleanup_handle (handle); 205 cleanup_handle (handle);
205 GNUNET_free (response); 206 GNUNET_free (response);
@@ -334,6 +335,7 @@ set_cont (struct GNUNET_REST_RequestHandle *con_handle,
334 handle->proc (handle->proc_cls, 335 handle->proc (handle->proc_cls,
335 GNUNET_REST_create_response (NULL), 336 GNUNET_REST_create_response (NULL),
336 MHD_HTTP_OK); 337 MHD_HTTP_OK);
338 GNUNET_free (cfg_fn);
337 cleanup_handle (handle); 339 cleanup_handle (handle);
338} 340}
339 341
@@ -352,9 +354,9 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
352 struct RequestHandle *handle = cls; 354 struct RequestHandle *handle = cls;
353 355
354 resp = GNUNET_REST_create_response (NULL); 356 resp = GNUNET_REST_create_response (NULL);
355 MHD_add_response_header (resp, 357 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
356 "Access-Control-Allow-Methods", 358 "Access-Control-Allow-Methods",
357 MHD_HTTP_METHOD_GET); 359 MHD_HTTP_METHOD_GET));
358 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 360 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
359 cleanup_handle (handle); 361 cleanup_handle (handle);
360} 362}
@@ -424,7 +426,7 @@ libgnunet_plugin_rest_config_init (void *cls)
424 api->cls = &plugin; 426 api->cls = &plugin;
425 api->name = GNUNET_REST_API_NS_CONFIG; 427 api->name = GNUNET_REST_API_NS_CONFIG;
426 api->process_request = &rest_config_process_request; 428 api->process_request = &rest_config_process_request;
427 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("CONFIG REST API initialized\n")); 429 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("CONFIG REST API initialized\n"));
428 return api; 430 return api;
429} 431}
430 432
diff --git a/src/revocation/Makefile.am b/src/revocation/Makefile.am
index b1a079a0d..d0c58584e 100644
--- a/src/revocation/Makefile.am
+++ b/src/revocation/Makefile.am
@@ -32,11 +32,6 @@ libgnunet_plugin_block_revocation_la_LIBADD = \
32 $(top_builddir)/src/util/libgnunetutil.la \ 32 $(top_builddir)/src/util/libgnunetutil.la \
33 $(top_builddir)/src/identity/libgnunetidentity.la \ 33 $(top_builddir)/src/identity/libgnunetidentity.la \
34 $(LTLIBINTL) 34 $(LTLIBINTL)
35libgnunet_plugin_block_revocation_la_DEPENDENCIES = \
36 libgnunetrevocation.la \
37 $(top_builddir)/src/block/libgnunetblockgroup.la \
38 $(top_builddir)/src/block/libgnunetblock.la \
39 $(top_builddir)/src/util/libgnunetutil.la
40libgnunet_plugin_block_revocation_la_LDFLAGS = \ 35libgnunet_plugin_block_revocation_la_LDFLAGS = \
41 $(GN_PLUGIN_LDFLAGS) 36 $(GN_PLUGIN_LDFLAGS)
42 37
diff --git a/src/revocation/gnunet-service-revocation.c b/src/revocation/gnunet-service-revocation.c
index 2d8111adb..5fe0ade98 100644
--- a/src/revocation/gnunet-service-revocation.c
+++ b/src/revocation/gnunet-service-revocation.c
@@ -949,6 +949,7 @@ run (void *cls,
949 if (0 > ksize) 949 if (0 > ksize)
950 { 950 {
951 GNUNET_break_op (0); 951 GNUNET_break_op (0);
952 GNUNET_free (rm);
952 GNUNET_free (fn); 953 GNUNET_free (fn);
953 return; 954 return;
954 } 955 }
diff --git a/src/secretsharing/Makefile.am b/src/secretsharing/Makefile.am
index 787cfa0c1..9ae6e7892 100644
--- a/src/secretsharing/Makefile.am
+++ b/src/secretsharing/Makefile.am
@@ -24,6 +24,7 @@ gnunet_secretsharing_profiler_SOURCES = \
24 gnunet-secretsharing-profiler.c 24 gnunet-secretsharing-profiler.c
25gnunet_secretsharing_profiler_LDADD = \ 25gnunet_secretsharing_profiler_LDADD = \
26 libgnunetsecretsharing.la \ 26 libgnunetsecretsharing.la \
27 $(top_builddir)/src/testing/libgnunettesting.la \
27 $(top_builddir)/src/testbed/libgnunettestbed.la \ 28 $(top_builddir)/src/testbed/libgnunettestbed.la \
28 $(top_builddir)/src/util/libgnunetutil.la \ 29 $(top_builddir)/src/util/libgnunetutil.la \
29 $(GN_LIBINTL) 30 $(GN_LIBINTL)
diff --git a/src/set/ibf.c b/src/set/ibf.c
index 1532afceb..0f7eb6a9f 100644
--- a/src/set/ibf.c
+++ b/src/set/ibf.c
@@ -294,7 +294,7 @@ ibf_write_slice (const struct InvertibleBloomFilter *ibf, uint32_t start,
294 struct IBF_KeyHash *key_hash_dst; 294 struct IBF_KeyHash *key_hash_dst;
295 struct IBF_Count *count_dst; 295 struct IBF_Count *count_dst;
296 296
297 GNUNET_assert (start + count <= ibf->size); 297 GNUNET_assert (start + count <= ibf->size);
298 298
299 /* copy keys */ 299 /* copy keys */
300 key_dst = (struct IBF_Key *) buf; 300 key_dst = (struct IBF_Key *) buf;
diff --git a/src/set/ibf.h b/src/set/ibf.h
index 7c2ab33b1..334a797ef 100644
--- a/src/set/ibf.h
+++ b/src/set/ibf.h
@@ -245,6 +245,7 @@ void
245ibf_destroy (struct InvertibleBloomFilter *ibf); 245ibf_destroy (struct InvertibleBloomFilter *ibf);
246 246
247 247
248
248#if 0 /* keep Emacsens' auto-indent happy */ 249#if 0 /* keep Emacsens' auto-indent happy */
249{ 250{
250#endif 251#endif
diff --git a/src/setu/gnunet-service-setu.c b/src/setu/gnunet-service-setu.c
index bd1113f15..339d347f8 100644
--- a/src/setu/gnunet-service-setu.c
+++ b/src/setu/gnunet-service-setu.c
@@ -22,6 +22,7 @@
22 * @brief set union operation 22 * @brief set union operation
23 * @author Florian Dold 23 * @author Florian Dold
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Elias Summermatter
25 */ 26 */
26#include "platform.h" 27#include "platform.h"
27#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
@@ -50,33 +51,61 @@
50 */ 51 */
51#define SE_STRATA_COUNT 32 52#define SE_STRATA_COUNT 32
52 53
54
53/** 55/**
54 * Size of the IBFs in the strata estimator. 56 * Primes for all 4 different strata estimators 61,67,71,73,79,83,89,97 348
57 * Based on the bsc thesis of Elias Summermatter (2021)
55 */ 58 */
56#define SE_IBF_SIZE 80 59#define SE_IBFS_TOTAL_SIZE 632
57 60
58/** 61/**
59 * The hash num parameter for the difference digests and strata estimators. 62 * The hash num parameter for the difference digests and strata estimators.
60 */ 63 */
61#define SE_IBF_HASH_NUM 4 64#define SE_IBF_HASH_NUM 3
62 65
63/** 66/**
64 * Number of buckets that can be transmitted in one message. 67 * Number of buckets that can be transmitted in one message.
65 */ 68 */
66#define MAX_BUCKETS_PER_MESSAGE ((1 << 15) / IBF_BUCKET_SIZE) 69#define MAX_BUCKETS_PER_MESSAGE ((1 << 16) / IBF_BUCKET_SIZE)
67 70
68/** 71/**
69 * The maximum size of an ibf we use is 2^(MAX_IBF_ORDER). 72 * The maximum size of an ibf we use is MAX_IBF_SIZE=2^20.
70 * Choose this value so that computing the IBF is still cheaper 73 * Choose this value so that computing the IBF is still cheaper
71 * than transmitting all values. 74 * than transmitting all values.
72 */ 75 */
73#define MAX_IBF_ORDER (20) 76#define MAX_IBF_SIZE 1048576
77
78
79/**
80 * Minimal size of an ibf
81 * Based on the bsc thesis of Elias Summermatter (2021)
82 */
83#define IBF_MIN_SIZE 37
84
85/**
86 * AVG RTT for differential sync when k=2 and Factor = 2
87 * Based on the bsc thesis of Elias Summermatter (2021)
88 */
89#define DIFFERENTIAL_RTT_MEAN 3.65145
90
91/**
92 * Security level used for byzantine checks (2^80)
93 */
94
95#define SECURITY_LEVEL 80
96
97/**
98 * Is the estimated probability for a new round this values
99 * is based on the bsc thesis of Elias Summermatter (2021)
100 */
101
102#define PROBABILITY_FOR_NEW_ROUND 0.15
74 103
75/** 104/**
76 * Number of buckets used in the ibf per estimated 105 * Measure the performance in a csv
77 * difference.
78 */ 106 */
79#define IBF_ALPHA 4 107
108#define MEASURE_PERFORMANCE 0
80 109
81 110
82/** 111/**
@@ -146,6 +175,28 @@ enum UnionOperationPhase
146 PHASE_FULL_RECEIVING 175 PHASE_FULL_RECEIVING
147}; 176};
148 177
178/**
179 * Different modes of operations
180 */
181
182enum MODE_OF_OPERATION
183{
184 /**
185 * Mode just synchronizes the difference between sets
186 */
187 DIFFERENTIAL_SYNC,
188
189 /**
190 * Mode send full set sending local set first
191 */
192 FULL_SYNC_LOCAL_SENDING_FIRST,
193
194 /**
195 * Mode request full set from remote peer
196 */
197 FULL_SYNC_REMOTE_SENDING_FIRST
198};
199
149 200
150/** 201/**
151 * Information about an element element in the set. All elements are 202 * Information about an element element in the set. All elements are
@@ -277,7 +328,7 @@ struct Operation
277 * Copy of the set's strata estimator at the time of 328 * Copy of the set's strata estimator at the time of
278 * creation of this operation. 329 * creation of this operation.
279 */ 330 */
280 struct StrataEstimator *se; 331 struct MultiStrataEstimator *se;
281 332
282 /** 333 /**
283 * The IBF we currently receive. 334 * The IBF we currently receive.
@@ -320,7 +371,7 @@ struct Operation
320 /** 371 /**
321 * Number of ibf buckets already received into the @a remote_ibf. 372 * Number of ibf buckets already received into the @a remote_ibf.
322 */ 373 */
323 unsigned int ibf_buckets_received; 374 uint64_t ibf_buckets_received;
324 375
325 /** 376 /**
326 * Salt that we're using for sending IBFs 377 * Salt that we're using for sending IBFs
@@ -386,7 +437,7 @@ struct Operation
386 * Lower bound for the set size, used only when 437 * Lower bound for the set size, used only when
387 * byzantine mode is enabled. 438 * byzantine mode is enabled.
388 */ 439 */
389 int byzantine_lower_bound; 440 uint64_t byzantine_lower_bound;
390 441
391 /** 442 /**
392 * Unique request id for the request from a remote peer, sent to the 443 * Unique request id for the request from a remote peer, sent to the
@@ -401,21 +452,83 @@ struct Operation
401 */ 452 */
402 unsigned int generation_created; 453 unsigned int generation_created;
403 454
455
456 /**
457 * User defined Bandwidth Round Trips Tradeoff
458 */
459 uint64_t rtt_bandwidth_tradeoff;
460
461
462 /**
463 * Number of Element per bucket in IBF
464 */
465 uint8_t ibf_number_buckets_per_element;
466
467
468 /**
469 * Set difference is multiplied with this factor
470 * to gennerate large enough IBF
471 */
472 uint8_t ibf_bucket_number_factor;
473
474 /**
475 * Defines which site a client is
476 * 0 = Initiating peer
477 * 1 = Receiving peer
478 */
479 uint8_t peer_site;
480
481
404 /** 482 /**
405 * User defined Bandwidth Round Trips Tradeoff 483 * Local peer element count
406 */ 484 */
407 double rtt_bandwidth_tradeoff; 485 uint64_t local_element_count;
408 486
409 /** 487 /**
410 * Number of Element per bucket in IBF 488 * Mode of operation that was chosen by the algorithm
411 */ 489 */
412 unsigned int ibf_number_buckets_per_element; 490 uint8_t mode_of_operation;
413 491
414 /** 492 /**
415 * Number of buckets in IBF 493 * Hashmap to keep track of the send/received messages
416 */ 494 */
417 unsigned ibf_bucket_number; 495 struct GNUNET_CONTAINER_MultiHashMap *message_control_flow;
418 496
497 /**
498 * Hashmap to keep track of the send/received inquiries (ibf keys)
499 */
500 struct GNUNET_CONTAINER_MultiHashMap *inquiries_sent;
501
502
503 /**
504 * Total size of local set
505 */
506 uint64_t total_elements_size_local;
507
508 /**
509 * Limit of number of elements in set
510 */
511 uint64_t byzantine_upper_bound;
512
513 /**
514 * is the count of already passed differential sync iterations
515 */
516 uint8_t differential_sync_iterations;
517
518 /**
519 * Estimated or committed set difference at the start
520 */
521 uint64_t remote_set_diff;
522
523 /**
524 * Estimated or committed set difference at the start
525 */
526 uint64_t local_set_diff;
527
528 /**
529 * Boolean to enforce an active passive switch
530 */
531 bool active_passive_switch_required;
419}; 532};
420 533
421 534
@@ -431,6 +544,16 @@ struct SetContent
431 struct GNUNET_CONTAINER_MultiHashMap *elements; 544 struct GNUNET_CONTAINER_MultiHashMap *elements;
432 545
433 /** 546 /**
547 * Maps `struct GNUNET_HashCode *` to `struct ElementEntry *` randomized.
548 */
549 struct GNUNET_CONTAINER_MultiHashMap *elements_randomized;
550
551 /**
552 * Salt to construct the randomized element map
553 */
554 uint64_t elements_randomized_salt;
555
556 /**
434 * Number of references to the content. 557 * Number of references to the content.
435 */ 558 */
436 unsigned int refcount; 559 unsigned int refcount;
@@ -478,7 +601,7 @@ struct Set
478 * The strata estimator is only generated once for each set. The IBF keys 601 * The strata estimator is only generated once for each set. The IBF keys
479 * are derived from the element hashes with salt=0. 602 * are derived from the element hashes with salt=0.
480 */ 603 */
481 struct StrataEstimator *se; 604 struct MultiStrataEstimator *se;
482 605
483 /** 606 /**
484 * Evaluate operations are held in a linked list. 607 * Evaluate operations are held in a linked list.
@@ -635,96 +758,687 @@ static int in_shutdown;
635 */ 758 */
636static uint32_t suggest_id; 759static uint32_t suggest_id;
637 760
761#if MEASURE_PERFORMANCE
762/**
763 * Handles configuration file for setu performance test
764 *
765 */
766static const struct GNUNET_CONFIGURATION_Handle *setu_cfg;
767
768
769/**
770 * Stores the performance data for induvidual message
771 */
772
773
774struct perf_num_send_received_msg
775{
776 uint64_t sent;
777 uint64_t sent_var_bytes;
778 uint64_t received;
779 uint64_t received_var_bytes;
780};
781
782/**
783 * Main struct to measure performance (data/rtts)
784 */
785struct per_store_struct
786{
787 struct perf_num_send_received_msg operation_request;
788 struct perf_num_send_received_msg se;
789 struct perf_num_send_received_msg request_full;
790 struct perf_num_send_received_msg element_full;
791 struct perf_num_send_received_msg full_done;
792 struct perf_num_send_received_msg ibf;
793 struct perf_num_send_received_msg inquery;
794 struct perf_num_send_received_msg element;
795 struct perf_num_send_received_msg demand;
796 struct perf_num_send_received_msg offer;
797 struct perf_num_send_received_msg done;
798 struct perf_num_send_received_msg over;
799 uint64_t se_diff;
800 uint64_t se_diff_remote;
801 uint64_t se_diff_local;
802 uint64_t active_passive_switches;
803 uint8_t mode_of_operation;
804};
805
806struct per_store_struct perf_store;
807#endif
808
809/**
810 * Different states to control the messages flow in differential mode
811 */
812
813enum MESSAGE_CONTROL_FLOW_STATE
814{
815 /**
816 * Initial message state
817 */
818 MSG_CFS_UNINITIALIZED,
819
820 /**
821 * Track that a message has been sent
822 */
823 MSG_CFS_SENT,
824
825 /**
826 * Track that receiving this message is expected
827 */
828 MSG_CFS_EXPECTED,
829
830 /**
831 * Track that message has been received
832 */
833 MSG_CFS_RECEIVED,
834};
638 835
639/** 836/**
640 * Added Roundtripscounter 837 * Message types to track in message control flow
641 */ 838 */
642 839
840enum MESSAGE_TYPE
841{
842 /**
843 * Offer message type
844 */
845 OFFER_MESSAGE,
643 846
644struct perf_num_send_resived_msg { 847 /**
645 int sent; 848 * Demand message type
646 int sent_var_bytes; 849 */
647 int received; 850 DEMAND_MESSAGE,
648 int received_var_bytes; 851
852 /**
853 * Element message type
854 */
855 ELEMENT_MESSAGE,
649}; 856};
650 857
651 858
652struct perf_rtt_struct 859/**
653{ 860 * Struct to tracked messages in message control flow
654 struct perf_num_send_resived_msg operation_request; 861 */
655 struct perf_num_send_resived_msg se; 862struct messageControlFlowElement
656 struct perf_num_send_resived_msg request_full; 863{
657 struct perf_num_send_resived_msg element_full; 864 /**
658 struct perf_num_send_resived_msg full_done; 865 * Track the message control state of the offer message
659 struct perf_num_send_resived_msg ibf; 866 */
660 struct perf_num_send_resived_msg inquery; 867 enum MESSAGE_CONTROL_FLOW_STATE offer;
661 struct perf_num_send_resived_msg element; 868 /**
662 struct perf_num_send_resived_msg demand; 869 * Track the message control state of the demand message
663 struct perf_num_send_resived_msg offer; 870 */
664 struct perf_num_send_resived_msg done; 871 enum MESSAGE_CONTROL_FLOW_STATE demand;
665 struct perf_num_send_resived_msg over; 872 /**
873 * Track the message control state of the element message
874 */
875 enum MESSAGE_CONTROL_FLOW_STATE element;
666}; 876};
667 877
668struct perf_rtt_struct perf_rtt;
669 878
879#if MEASURE_PERFORMANCE
670 880
881/**
882 * Loads different configuration to perform performance tests
883 *
884 * @param op operation handle
885 */
886static void
887load_config (struct Operation *op)
888{
889 long long number;
890 float fl;
891
892 setu_cfg = GNUNET_CONFIGURATION_create ();
893 GNUNET_CONFIGURATION_load (setu_cfg,
894 "perf_setu.conf");
895 GNUNET_CONFIGURATION_get_value_float (setu_cfg,
896 "IBF",
897 "BUCKET_NUMBER_FACTOR",
898 &fl);
899 op->ibf_bucket_number_factor = fl;
900 GNUNET_CONFIGURATION_get_value_number (setu_cfg,
901 "IBF",
902 "NUMBER_PER_BUCKET",
903 &number);
904 op->ibf_number_buckets_per_element = number;
905 GNUNET_CONFIGURATION_get_value_number (setu_cfg,
906 "PERFORMANCE",
907 "TRADEOFF",
908 &number);
909 op->rtt_bandwidth_tradeoff = number;
910 GNUNET_CONFIGURATION_get_value_number (setu_cfg,
911 "BOUNDARIES",
912 "UPPER_ELEMENT",
913 &number);
914 op->byzantine_upper_bound = number;
915 op->peer_site = 0;
916}
917
918
919/**
920 * Function to calculate total bytes used for performance measurement
921 * @param size
922 * @param perf_num_send_received_msg
923 * @return bytes used
924 */
671static int 925static int
672sum_sent_received_bytes(int size, struct perf_num_send_resived_msg perf_rtt_struct) { 926sum_sent_received_bytes (uint64_t size,
673 return (size * perf_rtt_struct.sent) + 927 struct perf_num_send_received_msg
674 (size * perf_rtt_struct.received) + 928 perf_num_send_received_msg)
675 perf_rtt_struct.sent_var_bytes + 929{
676 perf_rtt_struct.received_var_bytes; 930 return (size * perf_num_send_received_msg.sent)
931 + (size * perf_num_send_received_msg.received)
932 + perf_num_send_received_msg.sent_var_bytes
933 + perf_num_send_received_msg.received_var_bytes;
677} 934}
678 935
679static float
680calculate_perf_rtt() {
681 /**
682 * Calculate RTT of init phase normally always 1
683 */
684 float rtt = 1;
685 int bytes_transmitted = 0;
686 936
687 /** 937/**
688 * Calculate RGNUNET_SETU_AcceptMessageRT of Fullsync normally 1 or 1.5 depending 938 * Function that calculates the perfmance values and writes them down
689 */ 939 */
690 if (( perf_rtt.element_full.received != 0 ) || 940static void
691 ( perf_rtt.element_full.sent != 0) 941calculate_perf_store ()
692 ) rtt += 1; 942{
693 943
694 if (( perf_rtt.request_full.received != 0 ) || 944 /**
695 ( perf_rtt.request_full.sent != 0) 945 * Calculate RTT of init phase normally always 1
696 ) rtt += 0.5; 946 */
947 float rtt = 1;
948 int bytes_transmitted = 0;
697 949
698 /** 950 /**
699 * In case of a differential sync 3 rtt's are needed. 951 * Calculate RGNUNET_SETU_AcceptMessageRT of Fullsync normally 1 or 1.5 depending
700 * for every active/passive switch additional 3.5 rtt's are used 952 */
701 */ 953 if ((perf_store.element_full.received != 0) ||
954 (perf_store.element_full.sent != 0)
955 )
956 rtt += 1;
957
958 if ((perf_store.request_full.received != 0) ||
959 (perf_store.request_full.sent != 0)
960 )
961 rtt += 0.5;
702 962
703 int iterations = perf_rtt.ibf.received; 963 /**
704 if(iterations > 1) 964 * In case of a differential sync 3 rtt's are needed.
705 rtt += (iterations - 1 ) * 0.5; 965 * for every active/passive switch additional 3.5 rtt's are used
706 rtt += 3 * iterations; 966 */
967 if ((perf_store.element.received != 0) ||
968 (perf_store.element.sent != 0))
969 {
970 int iterations = perf_store.active_passive_switches;
971
972 if (iterations > 0)
973 rtt += iterations * 0.5;
974 rtt += 2.5;
975 }
976
977
978 /**
979 * Calculate data sended size
980 */
981 bytes_transmitted += sum_sent_received_bytes (sizeof(struct
982 GNUNET_SETU_ResultMessage),
983 perf_store.request_full);
984
985 bytes_transmitted += sum_sent_received_bytes (sizeof(struct
986 GNUNET_SETU_ElementMessage),
987 perf_store.element_full);
988 bytes_transmitted += sum_sent_received_bytes (sizeof(struct
989 GNUNET_SETU_ElementMessage),
990 perf_store.element);
991 // bytes_transmitted += sum_sent_received_bytes(sizeof(GNUNET_MESSAGE_TYPE_SETU_P2P_OPERATION_REQUEST), perf_store.operation_request);
992 bytes_transmitted += sum_sent_received_bytes (sizeof(struct
993 StrataEstimatorMessage),
994 perf_store.se);
995 bytes_transmitted += sum_sent_received_bytes (4, perf_store.full_done);
996 bytes_transmitted += sum_sent_received_bytes (sizeof(struct IBFMessage),
997 perf_store.ibf);
998 bytes_transmitted += sum_sent_received_bytes (sizeof(struct InquiryMessage),
999 perf_store.inquery);
1000 bytes_transmitted += sum_sent_received_bytes (sizeof(struct
1001 GNUNET_MessageHeader),
1002 perf_store.demand);
1003 bytes_transmitted += sum_sent_received_bytes (sizeof(struct
1004 GNUNET_MessageHeader),
1005 perf_store.offer);
1006 bytes_transmitted += sum_sent_received_bytes (4, perf_store.done);
1007
1008 /**
1009 * Write IBF failure rate for different BUCKET_NUMBER_FACTOR
1010 */
1011 float factor;
1012 GNUNET_CONFIGURATION_get_value_float (setu_cfg,"IBF", "BUCKET_NUMBER_FACTOR",
1013 &factor);
1014 long long num_per_bucket;
1015 GNUNET_CONFIGURATION_get_value_number (setu_cfg,"IBF", "NUMBER_PER_BUCKET",
1016 &num_per_bucket);
1017
1018
1019 int decoded = 0;
1020 if (perf_store.active_passive_switches == 0)
1021 decoded = 1;
1022 int ibf_bytes_transmitted = sum_sent_received_bytes (sizeof(struct
1023 IBFMessage),
1024 perf_store.ibf);
1025
1026 FILE *out1 = fopen ("perf_data.csv", "a");
1027 fprintf (out1, "%d,%f,%d,%d,%f,%d,%d,%d,%d,%d\n",num_per_bucket,factor,
1028 decoded,ibf_bytes_transmitted,rtt,perf_store.se_diff,
1029 bytes_transmitted,
1030 perf_store.se_diff_local,perf_store.se_diff_remote,
1031 perf_store.mode_of_operation);
1032 fclose (out1);
1033
1034}
1035
1036
1037#endif
1038/**
1039 * Function that chooses the optimal mode of operation depending on
1040 * operation parameters.
1041 * @param avg_element_size
1042 * @param local_set_size
1043 * @param remote_set_size
1044 * @param est_set_diff_remote
1045 * @param est_set_diff_local
1046 * @param bandwith_latency_tradeoff
1047 * @param ibf_bucket_number_factor
1048 * @return calcuated mode of operation
1049 */
1050static uint8_t
1051estimate_best_mode_of_operation (uint64_t avg_element_size,
1052 uint64_t local_set_size,
1053 uint64_t remote_set_size,
1054 uint64_t est_set_diff_remote,
1055 uint64_t est_set_diff_local,
1056 uint64_t bandwith_latency_tradeoff,
1057 uint64_t ibf_bucket_number_factor)
1058{
1059
1060 /*
1061 * In case of initial sync fall to predefined states
1062 */
1063
1064 if (0 == local_set_size)
1065 return FULL_SYNC_REMOTE_SENDING_FIRST;
1066 if (0 == remote_set_size)
1067 return FULL_SYNC_LOCAL_SENDING_FIRST;
1068
1069 /*
1070 * Calculate bytes for full Sync
1071 */
1072
1073 uint8_t sizeof_full_done_header = 4;
1074 uint8_t sizeof_done_header = 4;
1075 uint8_t rtt_min_full = 2;
1076 uint8_t sizeof_request_full = 4;
1077 uint64_t estimated_total_diff = (est_set_diff_remote + est_set_diff_local);
1078
1079 /* Estimate byte required if we send first */
1080 uint64_t total_elements_to_send_local_send_first = est_set_diff_remote
1081 + local_set_size;
1082
1083 uint64_t total_bytes_full_local_send_first = (avg_element_size
1084 *
1085 total_elements_to_send_local_send_first) \
1086 + (
1087 total_elements_to_send_local_send_first * sizeof(struct
1088 GNUNET_SETU_ElementMessage)) \
1089 + (sizeof_full_done_header * 2) \
1090 + rtt_min_full
1091 * bandwith_latency_tradeoff;
1092
1093 /* Estimate bytes required if we request from remote peer */
1094 uint64_t total_elements_to_send_remote_send_first = est_set_diff_local
1095 + remote_set_size;
1096
1097 uint64_t total_bytes_full_remote_send_first = (avg_element_size
1098 *
1099 total_elements_to_send_remote_send_first) \
1100 + (
1101 total_elements_to_send_remote_send_first * sizeof(struct
1102 GNUNET_SETU_ElementMessage)) \
1103 + (sizeof_full_done_header * 2) \
1104 + (rtt_min_full + 0.5)
1105 * bandwith_latency_tradeoff \
1106 + sizeof_request_full;
1107
1108 /*
1109 * Calculate bytes for differential Sync
1110 */
1111
1112 /* Estimate bytes required by IBF transmission*/
1113
1114 long double ibf_bucket_count = estimated_total_diff
1115 * ibf_bucket_number_factor;
1116
1117 if (ibf_bucket_count <= IBF_MIN_SIZE)
1118 {
1119 ibf_bucket_count = IBF_MIN_SIZE;
1120 }
1121 uint64_t ibf_message_count = ceil ( ((float) ibf_bucket_count)
1122 / ((float) MAX_BUCKETS_PER_MESSAGE));
1123
1124 uint64_t estimated_counter_size = ceil (
1125 MIN (2 * log2l (((float) local_set_size)
1126 / ((float) ibf_bucket_count)),
1127 log2l (local_set_size)));
1128
1129 long double counter_bytes = (float) estimated_counter_size / 8;
1130
1131 uint64_t ibf_bytes = ceil ((sizeof (struct IBFMessage) * ibf_message_count)
1132 * 1.2 \
1133 + (ibf_bucket_count * sizeof(struct IBF_Key)) * 1.2 \
1134 + (ibf_bucket_count * sizeof(struct IBF_KeyHash))
1135 * 1.2 \
1136 + (ibf_bucket_count * counter_bytes) * 1.2);
1137
1138 /* Estimate full byte count for differential sync */
1139 uint64_t element_size = (avg_element_size
1140 + sizeof (struct GNUNET_SETU_ElementMessage)) \
1141 * estimated_total_diff;
1142 uint64_t done_size = sizeof_done_header;
1143 uint64_t inquery_size = (sizeof (struct IBF_Key)
1144 + sizeof (struct InquiryMessage))
1145 * estimated_total_diff;
1146 uint64_t demand_size =
1147 (sizeof(struct GNUNET_HashCode) + sizeof(struct GNUNET_MessageHeader))
1148 * estimated_total_diff;
1149 uint64_t offer_size = (sizeof (struct GNUNET_HashCode)
1150 + sizeof (struct GNUNET_MessageHeader))
1151 * estimated_total_diff;
1152
1153 uint64_t total_bytes_diff = (element_size + done_size + inquery_size
1154 + demand_size + offer_size + ibf_bytes) \
1155 + (DIFFERENTIAL_RTT_MEAN
1156 * bandwith_latency_tradeoff);
1157
1158 uint64_t full_min = MIN (total_bytes_full_local_send_first,
1159 total_bytes_full_remote_send_first);
1160
1161 /* Decide between full and differential sync */
1162
1163 if (full_min < total_bytes_diff)
1164 {
1165 /* Decide between sending all element first or receiving all elements */
1166 if (total_bytes_full_remote_send_first > total_bytes_full_local_send_first)
1167 {
1168 return FULL_SYNC_LOCAL_SENDING_FIRST;
1169 }
1170 else
1171 {
1172 return FULL_SYNC_REMOTE_SENDING_FIRST;
1173 }
1174 }
1175 else
1176 {
1177 return DIFFERENTIAL_SYNC;
1178 }
1179}
1180
1181
1182/**
1183 * Validates the if a message is received in a correct phase
1184 * @param allowed_phases
1185 * @param size_phases
1186 * @param op
1187 * @return #GNUNET_YES if message permitted in phase and #GNUNET_NO if not permitted in given
1188 * phase
1189 */
1190static enum GNUNET_GenericReturnValue
1191check_valid_phase (const uint8_t allowed_phases[],
1192 size_t size_phases,
1193 struct Operation *op)
1194{
1195 /**
1196 * Iterate over allowed phases
1197 */
1198 for (uint32_t phase_ctr = 0; phase_ctr < size_phases; phase_ctr++)
1199 {
1200 uint8_t phase = allowed_phases[phase_ctr];
1201 if (phase == op->phase)
1202 {
1203 LOG (GNUNET_ERROR_TYPE_DEBUG,
1204 "Message received in valid phase\n");
1205 return GNUNET_YES;
1206 }
1207 }
1208 LOG (GNUNET_ERROR_TYPE_ERROR,
1209 "Received message in invalid phase: %u\n", op->phase);
1210 return GNUNET_NO;
1211}
1212
1213
1214/**
1215 * Function to update, track and validate message received in differential
1216 * sync. This function tracks states of messages and check it against different
1217 * constraints as described in Summermatter's BSc Thesis (2021)
1218 * @param hash_map: Hashmap to store message control flow
1219 * @param new_mcfs: The new message control flow state an given message type should be set to
1220 * @param hash_code: Hash code of the element
1221 * @param mt: The message type for which the message control flow state should be set
1222 * @return GNUNET_YES message is valid in message control flow GNUNET_NO when message is not valid
1223 * at this point in message flow
1224 */
1225static int
1226update_message_control_flow (struct GNUNET_CONTAINER_MultiHashMap *hash_map,
1227 enum MESSAGE_CONTROL_FLOW_STATE new_mcfs,
1228 const struct GNUNET_HashCode *hash_code,
1229 enum MESSAGE_TYPE mt)
1230{
1231 struct messageControlFlowElement *cfe = NULL;
1232 enum MESSAGE_CONTROL_FLOW_STATE *mcfs;
1233
1234 /**
1235 * Check logic for forbidden messages
1236 */
1237
1238 cfe = GNUNET_CONTAINER_multihashmap_get (hash_map, hash_code);
1239 if ((ELEMENT_MESSAGE == mt) && (cfe != NULL))
1240 {
1241 if ((new_mcfs != MSG_CFS_SENT) && (MSG_CFS_RECEIVED != cfe->offer))
1242 {
1243 LOG (GNUNET_ERROR_TYPE_ERROR,
1244 "Received an element without sent offer!\n");
1245 return GNUNET_NO;
1246 }
1247 /* Check that only requested elements are received! */
1248 if ((ELEMENT_MESSAGE == mt) && (new_mcfs != MSG_CFS_SENT) && (cfe->demand !=
1249 MSG_CFS_SENT))
1250 {
1251 LOG (GNUNET_ERROR_TYPE_ERROR,
1252 "Received an element that was not demanded\n");
1253 return GNUNET_NO;
1254 }
1255 }
1256
1257 /**
1258 * In case the element hash is not in the hashmap create a new entry
1259 */
1260
1261 if (NULL == cfe)
1262 {
1263 cfe = GNUNET_new (struct messageControlFlowElement);
1264 if (GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_put (hash_map, hash_code,
1265 cfe,
1266 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
1267 {
1268 GNUNET_free (cfe);
1269 return GNUNET_SYSERR;
1270 }
1271 }
1272
1273 /**
1274 * Set state of message
1275 */
1276
1277 if (OFFER_MESSAGE == mt)
1278 {
1279 mcfs = &cfe->offer;
1280 }
1281 else if (DEMAND_MESSAGE == mt)
1282 {
1283 mcfs = &cfe->demand;
1284 }
1285 else if (ELEMENT_MESSAGE == mt)
1286 {
1287 mcfs = &cfe->element;
1288 }
1289 else
1290 {
1291 return GNUNET_SYSERR;
1292 }
1293
1294 /**
1295 * Check if state is allowed
1296 */
1297
1298 if (new_mcfs <= *mcfs)
1299 {
1300 return GNUNET_NO;
1301 }
1302
1303 *mcfs = new_mcfs;
1304 return GNUNET_YES;
1305}
1306
1307
1308/**
1309 * Validate if a message in differential sync si already received before.
1310 * @param hash_map
1311 * @param hash_code
1312 * @param mt
1313 * @return GNUNET_YES when message is already in store if message is not in store return GNUNET_NO
1314 */
1315static int
1316is_message_in_message_control_flow (struct
1317 GNUNET_CONTAINER_MultiHashMap *hash_map,
1318 struct GNUNET_HashCode *hash_code,
1319 enum MESSAGE_TYPE mt)
1320{
1321 struct messageControlFlowElement *cfe = NULL;
1322 enum MESSAGE_CONTROL_FLOW_STATE *mcfs;
1323
1324 cfe = GNUNET_CONTAINER_multihashmap_get (hash_map, hash_code);
1325
1326 /**
1327 * Set state of message
1328 */
1329
1330 if (cfe != NULL)
1331 {
1332 if (OFFER_MESSAGE == mt)
1333 {
1334 mcfs = &cfe->offer;
1335 }
1336 else if (DEMAND_MESSAGE == mt)
1337 {
1338 mcfs = &cfe->demand;
1339 }
1340 else if (ELEMENT_MESSAGE == mt)
1341 {
1342 mcfs = &cfe->element;
1343 }
1344 else
1345 {
1346 return GNUNET_SYSERR;
1347 }
707 1348
708 /** 1349 /**
709 * Calculate data sended size 1350 * Evaluate if set is in message
710 */ 1351 */
711 bytes_transmitted += sum_sent_received_bytes(sizeof(GNUNET_MESSAGE_TYPE_SETU_P2P_REQUEST_FULL), perf_rtt.request_full); 1352 if (*mcfs != MSG_CFS_UNINITIALIZED)
712 bytes_transmitted += sum_sent_received_bytes(sizeof(GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT), perf_rtt.element_full); 1353 {
713 bytes_transmitted += sum_sent_received_bytes(sizeof(GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENTS), perf_rtt.element); 1354 return GNUNET_YES;
714 bytes_transmitted += sum_sent_received_bytes(sizeof(GNUNET_MESSAGE_TYPE_SETU_P2P_OPERATION_REQUEST), perf_rtt.operation_request); 1355 }
715 bytes_transmitted += sum_sent_received_bytes(sizeof(GNUNET_MESSAGE_TYPE_SETU_P2P_SE), perf_rtt.se); 1356 }
716 bytes_transmitted += sum_sent_received_bytes(sizeof(GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE), perf_rtt.full_done); 1357 return GNUNET_NO;
717 bytes_transmitted += sum_sent_received_bytes(sizeof(GNUNET_MESSAGE_TYPE_SETU_P2P_IBF), perf_rtt.ibf); 1358}
718 bytes_transmitted += sum_sent_received_bytes(sizeof(GNUNET_MESSAGE_TYPE_SETU_P2P_INQUIRY), perf_rtt.inquery);
719 bytes_transmitted += sum_sent_received_bytes(sizeof(GNUNET_MESSAGE_TYPE_SETU_P2P_DEMAND), perf_rtt.demand);
720 bytes_transmitted += sum_sent_received_bytes(sizeof(GNUNET_MESSAGE_TYPE_SETU_P2P_OFFER), perf_rtt.offer);
721 bytes_transmitted += sum_sent_received_bytes(sizeof(GNUNET_MESSAGE_TYPE_SETU_P2P_DONE), perf_rtt.done);
722 1359
723 LOG(GNUNET_ERROR_TYPE_ERROR,"Bytes Transmitted: %d\n", bytes_transmitted);
724 1360
725 LOG(GNUNET_ERROR_TYPE_ERROR,"Reached tradeoff bandwidth/rtt: %f\n", (bytes_transmitted / rtt )); 1361/**
1362 * Iterator for determining if all demands have been
1363 * satisfied
1364 *
1365 * @param cls the union operation `struct Operation *`
1366 * @param key unused
1367 * @param value the `struct ElementEntry *` to insert
1368 * into the key-to-element mapping
1369 * @return #GNUNET_YES (to continue iterating)
1370 */
1371static int
1372determinate_done_message_iterator (void *cls,
1373 const struct GNUNET_HashCode *key,
1374 void *value)
1375{
1376 struct messageControlFlowElement *mcfe = value;
726 1377
727 return rtt; 1378 if (((mcfe->element == MSG_CFS_SENT) || (mcfe->element == MSG_CFS_RECEIVED) ))
1379 {
1380 return GNUNET_YES;
1381 }
1382 return GNUNET_NO;
1383}
1384
1385
1386/**
1387 * Iterator for determining average size
1388 *
1389 * @param cls the union operation `struct Operation *`
1390 * @param key unused
1391 * @param value the `struct ElementEntry *` to insert
1392 * into the key-to-element mapping
1393 * @return #GNUNET_YES (to continue iterating)
1394 */
1395static int
1396determinate_avg_element_size_iterator (void *cls,
1397 const struct GNUNET_HashCode *key,
1398 void *value)
1399{
1400 struct Operation *op = cls;
1401 struct GNUNET_SETU_Element *element = value;
1402 op->total_elements_size_local += element->size;
1403 return GNUNET_YES;
1404}
1405
1406
1407/**
1408 * Create randomized element hashmap for full sending
1409 *
1410 * @param cls the union operation `struct Operation *`
1411 * @param key unused
1412 * @param value the `struct ElementEntry *` to insert
1413 * into the key-to-element mapping
1414 * @return #GNUNET_YES (to continue iterating)
1415 */
1416static int
1417create_randomized_element_iterator (void *cls,
1418 const struct GNUNET_HashCode *key,
1419 void *value)
1420{
1421 struct Operation *op = cls;
1422
1423 struct GNUNET_HashContext *hashed_key_context =
1424 GNUNET_CRYPTO_hash_context_start ();
1425 struct GNUNET_HashCode new_key;
1426
1427 /**
1428 * Hash element with new salt to randomize hashmap
1429 */
1430 GNUNET_CRYPTO_hash_context_read (hashed_key_context,
1431 &key,
1432 sizeof(struct IBF_Key));
1433 GNUNET_CRYPTO_hash_context_read (hashed_key_context,
1434 &op->set->content->elements_randomized_salt,
1435 sizeof(uint32_t));
1436 GNUNET_CRYPTO_hash_context_finish (hashed_key_context,
1437 &new_key);
1438 GNUNET_CONTAINER_multihashmap_put (op->set->content->elements_randomized,
1439 &new_key,value,
1440 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
1441 return GNUNET_YES;
728} 1442}
729 1443
730 1444
@@ -808,6 +1522,36 @@ send_client_done (void *cls)
808} 1522}
809 1523
810 1524
1525/**
1526 * Check if all given byzantine parameters are in given boundaries
1527 * @param op
1528 * @return indicator if all given byzantine parameters are in given boundaries
1529 */
1530
1531static int
1532check_byzantine_bounds (struct Operation *op)
1533{
1534 if (op->byzantine != GNUNET_YES)
1535 return GNUNET_OK;
1536
1537 /**
1538 * Check upper byzantine bounds
1539 */
1540 if (op->remote_element_count + op->remote_set_diff >
1541 op->byzantine_upper_bound)
1542 return GNUNET_SYSERR;
1543 if (op->local_element_count + op->local_set_diff > op->byzantine_upper_bound)
1544 return GNUNET_SYSERR;
1545
1546 /**
1547 * Check lower byzantine bounds
1548 */
1549 if (op->remote_element_count < op->byzantine_lower_bound)
1550 return GNUNET_SYSERR;
1551 return GNUNET_OK;
1552}
1553
1554
811/* FIXME: the destroy logic is a mess and should be cleaned up! */ 1555/* FIXME: the destroy logic is a mess and should be cleaned up! */
812 1556
813/** 1557/**
@@ -977,6 +1721,101 @@ fail_union_operation (struct Operation *op)
977 1721
978 1722
979/** 1723/**
1724 * Function that checks if full sync is plausible
1725 * @param initial_local_elements_in_set
1726 * @param estimated_set_difference
1727 * @param repeated_elements
1728 * @param fresh_elements
1729 * @param op
1730 * @return GNUNET_OK if
1731 */
1732
1733static void
1734full_sync_plausibility_check (struct Operation *op)
1735{
1736 if (GNUNET_YES != op->byzantine)
1737 return;
1738
1739 int security_level_lb = -1 * SECURITY_LEVEL;
1740 uint64_t duplicates = op->received_fresh - op->received_total;
1741
1742 /*
1743 * Protect full sync from receiving double element when in FULL SENDING
1744 */
1745 if (PHASE_FULL_SENDING == op->phase)
1746 {
1747 if (duplicates > 0)
1748 {
1749 LOG (GNUNET_ERROR_TYPE_ERROR,
1750 "PROTOCOL VIOLATION: Received duplicate element in full receiving "
1751 "mode of operation this is not allowed! Duplicates: %llu\n",
1752 (unsigned long long) duplicates);
1753 GNUNET_break_op (0);
1754 fail_union_operation (op);
1755 return;
1756 }
1757
1758 }
1759
1760 /*
1761 * Protect full sync with probabilistic algorithm
1762 */
1763 if (PHASE_FULL_RECEIVING == op->phase)
1764 {
1765 if (0 == op->remote_set_diff)
1766 op->remote_set_diff = 1;
1767
1768 long double base = (1 - (long double) (op->remote_set_diff
1769 / (long double) (op->initial_size
1770 + op->
1771 remote_set_diff)));
1772 long double exponent = (op->received_total - (op->received_fresh * ((long
1773 double)
1774 op->
1775 initial_size
1776 / (long
1777 double)
1778 op->
1779 remote_set_diff)));
1780 long double value = exponent * (log2l (base) / log2l (2));
1781 if ((value < security_level_lb) || (value > SECURITY_LEVEL) )
1782 {
1783 LOG (GNUNET_ERROR_TYPE_ERROR,
1784 "PROTOCOL VIOLATION: Other peer violated probabilistic rule for receiving "
1785 "to many duplicated full element : %LF\n",
1786 value);
1787 GNUNET_break_op (0);
1788 fail_union_operation (op);
1789 return;
1790 }
1791 }
1792}
1793
1794
1795/**
1796 * Limit active passive switches in differential sync to configured security level
1797 * @param op
1798 */
1799static void
1800check_max_differential_rounds (struct Operation *op)
1801{
1802 double probability = op->differential_sync_iterations * (log2l (
1803 PROBABILITY_FOR_NEW_ROUND)
1804 / log2l (2));
1805 if ((-1 * SECURITY_LEVEL) > probability)
1806 {
1807 LOG (GNUNET_ERROR_TYPE_ERROR,
1808 "PROTOCOL VIOLATION: Other peer violated probabilistic rule for to many active passive "
1809 "switches in differential sync: %u\n",
1810 op->differential_sync_iterations);
1811 GNUNET_break_op (0);
1812 fail_union_operation (op);
1813 return;
1814 }
1815}
1816
1817
1818/**
980 * Derive the IBF key from a hash code and 1819 * Derive the IBF key from a hash code and
981 * a salt. 1820 * a salt.
982 * 1821 *
@@ -1004,12 +1843,12 @@ get_ibf_key (const struct GNUNET_HashCode *src)
1004struct GetElementContext 1843struct GetElementContext
1005{ 1844{
1006 /** 1845 /**
1007 * FIXME. 1846 * Gnunet hash code in context
1008 */ 1847 */
1009 struct GNUNET_HashCode hash; 1848 struct GNUNET_HashCode hash;
1010 1849
1011 /** 1850 /**
1012 * FIXME. 1851 * Pointer to the key entry
1013 */ 1852 */
1014 struct KeyEntry *k; 1853 struct KeyEntry *k;
1015}; 1854};
@@ -1122,7 +1961,7 @@ salt_key (const struct IBF_Key *k_in,
1122 uint32_t salt, 1961 uint32_t salt,
1123 struct IBF_Key *k_out) 1962 struct IBF_Key *k_out)
1124{ 1963{
1125 int s = salt % 64; 1964 int s = (salt * 7) % 64;
1126 uint64_t x = k_in->key_val; 1965 uint64_t x = k_in->key_val;
1127 1966
1128 /* rotate ibf key */ 1967 /* rotate ibf key */
@@ -1132,14 +1971,14 @@ salt_key (const struct IBF_Key *k_in,
1132 1971
1133 1972
1134/** 1973/**
1135 * FIXME. 1974 * Reverse modification done in the salt_key function
1136 */ 1975 */
1137static void 1976static void
1138unsalt_key (const struct IBF_Key *k_in, 1977unsalt_key (const struct IBF_Key *k_in,
1139 uint32_t salt, 1978 uint32_t salt,
1140 struct IBF_Key *k_out) 1979 struct IBF_Key *k_out)
1141{ 1980{
1142 int s = salt % 64; 1981 int s = (salt * 7) % 64;
1143 uint64_t x = k_in->key_val; 1982 uint64_t x = k_in->key_val;
1144 1983
1145 x = (x << s) | (x >> (64 - s)); 1984 x = (x << s) | (x >> (64 - s));
@@ -1258,7 +2097,9 @@ prepare_ibf (struct Operation *op,
1258 2097
1259 if (NULL != op->local_ibf) 2098 if (NULL != op->local_ibf)
1260 ibf_destroy (op->local_ibf); 2099 ibf_destroy (op->local_ibf);
1261 op->local_ibf = ibf_create (size, SE_IBF_HASH_NUM); 2100 // op->local_ibf = ibf_create (size, SE_IBF_HASH_NUM);
2101 op->local_ibf = ibf_create (size,
2102 ((uint8_t) op->ibf_number_buckets_per_element));
1262 if (NULL == op->local_ibf) 2103 if (NULL == op->local_ibf)
1263 { 2104 {
1264 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2105 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -1283,13 +2124,23 @@ prepare_ibf (struct Operation *op,
1283 */ 2124 */
1284static int 2125static int
1285send_ibf (struct Operation *op, 2126send_ibf (struct Operation *op,
1286 uint16_t ibf_order) 2127 uint32_t ibf_size)
1287{ 2128{
1288 unsigned int buckets_sent = 0; 2129 uint64_t buckets_sent = 0;
1289 struct InvertibleBloomFilter *ibf; 2130 struct InvertibleBloomFilter *ibf;
2131 op->differential_sync_iterations++;
1290 2132
2133 /**
2134 * Enforce min size of IBF
2135 */
2136 uint32_t ibf_min_size = IBF_MIN_SIZE;
2137
2138 if (ibf_size < ibf_min_size)
2139 {
2140 ibf_size = ibf_min_size;
2141 }
1291 if (GNUNET_OK != 2142 if (GNUNET_OK !=
1292 prepare_ibf (op, 1 << ibf_order)) 2143 prepare_ibf (op, ibf_size))
1293 { 2144 {
1294 /* allocation failed */ 2145 /* allocation failed */
1295 return GNUNET_SYSERR; 2146 return GNUNET_SYSERR;
@@ -1297,45 +2148,52 @@ send_ibf (struct Operation *op,
1297 2148
1298 LOG (GNUNET_ERROR_TYPE_DEBUG, 2149 LOG (GNUNET_ERROR_TYPE_DEBUG,
1299 "sending ibf of size %u\n", 2150 "sending ibf of size %u\n",
1300 1 << ibf_order); 2151 (unsigned int) ibf_size);
1301 2152
1302 { 2153 {
1303 char name[64]; 2154 char name[64];
1304 GNUNET_snprintf (name, sizeof(name), "# sent IBF (order %u)", ibf_order); 2155
2156 GNUNET_snprintf (name,
2157 sizeof(name),
2158 "# sent IBF (order %u)",
2159 ibf_size);
1305 GNUNET_STATISTICS_update (_GSS_statistics, name, 1, GNUNET_NO); 2160 GNUNET_STATISTICS_update (_GSS_statistics, name, 1, GNUNET_NO);
1306 } 2161 }
1307 2162
1308 ibf = op->local_ibf; 2163 ibf = op->local_ibf;
1309 2164
1310 while (buckets_sent < (1 << ibf_order)) 2165 while (buckets_sent < ibf_size)
1311 { 2166 {
1312 unsigned int buckets_in_message; 2167 unsigned int buckets_in_message;
1313 struct GNUNET_MQ_Envelope *ev; 2168 struct GNUNET_MQ_Envelope *ev;
1314 struct IBFMessage *msg; 2169 struct IBFMessage *msg;
1315 2170
1316 buckets_in_message = (1 << ibf_order) - buckets_sent; 2171 buckets_in_message = ibf_size - buckets_sent;
1317 /* limit to maximum */ 2172 /* limit to maximum */
1318 if (buckets_in_message > MAX_BUCKETS_PER_MESSAGE) 2173 if (buckets_in_message > MAX_BUCKETS_PER_MESSAGE)
1319 buckets_in_message = MAX_BUCKETS_PER_MESSAGE; 2174 buckets_in_message = MAX_BUCKETS_PER_MESSAGE;
1320 2175
1321 perf_rtt.ibf.sent += 1; 2176#if MEASURE_PERFORMANCE
1322 perf_rtt.ibf.sent_var_bytes += ( buckets_in_message * IBF_BUCKET_SIZE ); 2177 perf_store.ibf.sent += 1;
2178 perf_store.ibf.sent_var_bytes += (buckets_in_message * IBF_BUCKET_SIZE);
2179#endif
1323 ev = GNUNET_MQ_msg_extra (msg, 2180 ev = GNUNET_MQ_msg_extra (msg,
1324 buckets_in_message * IBF_BUCKET_SIZE, 2181 buckets_in_message * IBF_BUCKET_SIZE,
1325 GNUNET_MESSAGE_TYPE_SETU_P2P_IBF); 2182 GNUNET_MESSAGE_TYPE_SETU_P2P_IBF);
1326 msg->reserved1 = 0; 2183 msg->ibf_size = ibf_size;
1327 msg->reserved2 = 0;
1328 msg->order = ibf_order;
1329 msg->offset = htonl (buckets_sent); 2184 msg->offset = htonl (buckets_sent);
1330 msg->salt = htonl (op->salt_send); 2185 msg->salt = htonl (op->salt_send);
2186 msg->ibf_counter_bit_length = ibf_get_max_counter (ibf);
2187
2188
1331 ibf_write_slice (ibf, buckets_sent, 2189 ibf_write_slice (ibf, buckets_sent,
1332 buckets_in_message, &msg[1]); 2190 buckets_in_message, &msg[1], msg->ibf_counter_bit_length);
1333 buckets_sent += buckets_in_message; 2191 buckets_sent += buckets_in_message;
1334 LOG (GNUNET_ERROR_TYPE_DEBUG, 2192 LOG (GNUNET_ERROR_TYPE_DEBUG,
1335 "ibf chunk size %u, %u/%u sent\n", 2193 "ibf chunk size %u, %llu/%u sent\n",
1336 buckets_in_message, 2194 (unsigned int) buckets_in_message,
1337 buckets_sent, 2195 (unsigned long long) buckets_sent,
1338 1 << ibf_order); 2196 (unsigned int) ibf_size);
1339 GNUNET_MQ_send (op->mq, ev); 2197 GNUNET_MQ_send (op->mq, ev);
1340 } 2198 }
1341 2199
@@ -1354,17 +2212,26 @@ send_ibf (struct Operation *op,
1354 * @return the required size of the ibf 2212 * @return the required size of the ibf
1355 */ 2213 */
1356static unsigned int 2214static unsigned int
1357get_order_from_difference (unsigned int diff) 2215get_size_from_difference (unsigned int diff, int number_buckets_per_element,
2216 float ibf_bucket_number_factor)
1358{ 2217{
1359 unsigned int ibf_order; 2218 /** Make ibf estimation size odd reasoning can be found in BSc Thesis of
2219 * Elias Summermatter (2021) in section 3.11 **/
2220 return (((int) (diff * ibf_bucket_number_factor)) | 1);
2221
2222}
1360 2223
1361 ibf_order = 2; 2224
1362 while (((1 << ibf_order) < (IBF_ALPHA * diff) || 2225static unsigned int
1363 ((1 << ibf_order) < SE_IBF_HASH_NUM)) && 2226get_next_ibf_size (float ibf_bucket_number_factor, unsigned int
1364 (ibf_order < MAX_IBF_ORDER)) 2227 decoded_elements, unsigned int last_ibf_size)
1365 ibf_order++; 2228{
1366 // add one for correction 2229 unsigned int next_size = (unsigned int) ((last_ibf_size * 2)
1367 return ibf_order + 1; 2230 - (ibf_bucket_number_factor
2231 * decoded_elements));
2232 /** Make ibf estimation size odd reasoning can be found in BSc Thesis of
2233 * Elias Summermatter (2021) in section 3.11 **/
2234 return next_size | 1;
1368} 2235}
1369 2236
1370 2237
@@ -1391,8 +2258,10 @@ send_full_element_iterator (void *cls,
1391 LOG (GNUNET_ERROR_TYPE_DEBUG, 2258 LOG (GNUNET_ERROR_TYPE_DEBUG,
1392 "Sending element %s\n", 2259 "Sending element %s\n",
1393 GNUNET_h2s (key)); 2260 GNUNET_h2s (key));
1394 perf_rtt.element_full.received += 1; 2261#if MEASURE_PERFORMANCE
1395 perf_rtt.element_full.received_var_bytes += el->size; 2262 perf_store.element_full.received += 1;
2263 perf_store.element_full.received_var_bytes += el->size;
2264#endif
1396 ev = GNUNET_MQ_msg_extra (emsg, 2265 ev = GNUNET_MQ_msg_extra (emsg,
1397 el->size, 2266 el->size,
1398 GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT); 2267 GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT);
@@ -1421,10 +2290,25 @@ send_full_set (struct Operation *op)
1421 "Dedicing to transmit the full set\n"); 2290 "Dedicing to transmit the full set\n");
1422 /* FIXME: use a more memory-friendly way of doing this with an 2291 /* FIXME: use a more memory-friendly way of doing this with an
1423 iterator, just as we do in the non-full case! */ 2292 iterator, just as we do in the non-full case! */
2293
2294 // Randomize Elements to send
2295 op->set->content->elements_randomized = GNUNET_CONTAINER_multihashmap_create (
2296 32,GNUNET_NO);
2297 op->set->content->elements_randomized_salt = GNUNET_CRYPTO_random_u64 (
2298 GNUNET_CRYPTO_QUALITY_NONCE,
2299 UINT64_MAX);
1424 (void) GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements, 2300 (void) GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
1425 &send_full_element_iterator, 2301 &
2302 create_randomized_element_iterator,
1426 op); 2303 op);
1427 perf_rtt.full_done.sent += 1; 2304
2305 (void) GNUNET_CONTAINER_multihashmap_iterate (
2306 op->set->content->elements_randomized,
2307 &send_full_element_iterator,
2308 op);
2309#if MEASURE_PERFORMANCE
2310 perf_store.full_done.sent += 1;
2311#endif
1428 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE); 2312 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE);
1429 GNUNET_MQ_send (op->mq, 2313 GNUNET_MQ_send (op->mq,
1430 ev); 2314 ev);
@@ -1454,7 +2338,7 @@ check_union_p2p_strata_estimator (void *cls,
1454 msg->header.type)); 2338 msg->header.type));
1455 len = ntohs (msg->header.size) - sizeof(struct StrataEstimatorMessage); 2339 len = ntohs (msg->header.size) - sizeof(struct StrataEstimatorMessage);
1456 if ((GNUNET_NO == is_compressed) && 2340 if ((GNUNET_NO == is_compressed) &&
1457 (len != SE_STRATA_COUNT * SE_IBF_SIZE * IBF_BUCKET_SIZE)) 2341 (len != SE_STRATA_COUNT * SE_IBFS_TOTAL_SIZE * IBF_BUCKET_SIZE))
1458 { 2342 {
1459 GNUNET_break (0); 2343 GNUNET_break (0);
1460 return GNUNET_SYSERR; 2344 return GNUNET_SYSERR;
@@ -1473,14 +2357,44 @@ static void
1473handle_union_p2p_strata_estimator (void *cls, 2357handle_union_p2p_strata_estimator (void *cls,
1474 const struct StrataEstimatorMessage *msg) 2358 const struct StrataEstimatorMessage *msg)
1475{ 2359{
1476 perf_rtt.se.received += 1; 2360#if MEASURE_PERFORMANCE
1477 perf_rtt.se.received_var_bytes += ntohs (msg->header.size) - sizeof(struct StrataEstimatorMessage); 2361 perf_store.se.received += 1;
2362 perf_store.se.received_var_bytes += ntohs (msg->header.size) - sizeof(struct
2363 StrataEstimatorMessage);
2364#endif
1478 struct Operation *op = cls; 2365 struct Operation *op = cls;
1479 struct StrataEstimator *remote_se; 2366 struct MultiStrataEstimator *remote_se;
1480 unsigned int diff; 2367 unsigned int diff;
1481 uint64_t other_size; 2368 uint64_t other_size;
1482 size_t len; 2369 size_t len;
1483 int is_compressed; 2370 int is_compressed;
2371 op->local_element_count = GNUNET_CONTAINER_multihashmap_size (
2372 op->set->content->elements);
2373 // Setting peer site to receiving peer
2374 op->peer_site = 1;
2375
2376 /**
2377 * Check that the message is received only in supported phase
2378 */
2379 uint8_t allowed_phases[] = {PHASE_EXPECT_SE};
2380 if (GNUNET_OK !=
2381 check_valid_phase (allowed_phases,sizeof(allowed_phases),op))
2382 {
2383 GNUNET_break (0);
2384 fail_union_operation (op);
2385 return;
2386 }
2387
2388 /** Only allow 1,2,4,8 SEs **/
2389 if ((msg->se_count > 8) || (__builtin_popcount ((int) msg->se_count) != 1))
2390 {
2391 LOG (GNUNET_ERROR_TYPE_ERROR,
2392 "PROTOCOL VIOLATION: Invalid number of se transmitted by other peer %u\n",
2393 msg->se_count);
2394 GNUNET_break_op (0);
2395 fail_union_operation (op);
2396 return;
2397 }
1484 2398
1485 is_compressed = (GNUNET_MESSAGE_TYPE_SETU_P2P_SEC == htons ( 2399 is_compressed = (GNUNET_MESSAGE_TYPE_SETU_P2P_SEC == htons (
1486 msg->header.type)); 2400 msg->header.type));
@@ -1490,8 +2404,20 @@ handle_union_p2p_strata_estimator (void *cls,
1490 GNUNET_NO); 2404 GNUNET_NO);
1491 len = ntohs (msg->header.size) - sizeof(struct StrataEstimatorMessage); 2405 len = ntohs (msg->header.size) - sizeof(struct StrataEstimatorMessage);
1492 other_size = GNUNET_ntohll (msg->set_size); 2406 other_size = GNUNET_ntohll (msg->set_size);
2407 op->remote_element_count = other_size;
2408
2409 if (op->byzantine_upper_bound < op->remote_element_count)
2410 {
2411 LOG (GNUNET_ERROR_TYPE_ERROR,
2412 "Exceeded configured upper bound <%lu> of element: %u\n",
2413 op->byzantine_upper_bound,
2414 op->remote_element_count);
2415 fail_union_operation (op);
2416 return;
2417 }
2418
1493 remote_se = strata_estimator_create (SE_STRATA_COUNT, 2419 remote_se = strata_estimator_create (SE_STRATA_COUNT,
1494 SE_IBF_SIZE, 2420 SE_IBFS_TOTAL_SIZE,
1495 SE_IBF_HASH_NUM); 2421 SE_IBF_HASH_NUM);
1496 if (NULL == remote_se) 2422 if (NULL == remote_se)
1497 { 2423 {
@@ -1503,6 +2429,8 @@ handle_union_p2p_strata_estimator (void *cls,
1503 strata_estimator_read (&msg[1], 2429 strata_estimator_read (&msg[1],
1504 len, 2430 len,
1505 is_compressed, 2431 is_compressed,
2432 msg->se_count,
2433 SE_IBFS_TOTAL_SIZE,
1506 remote_se)) 2434 remote_se))
1507 { 2435 {
1508 /* decompression failed */ 2436 /* decompression failed */
@@ -1511,11 +2439,76 @@ handle_union_p2p_strata_estimator (void *cls,
1511 return; 2439 return;
1512 } 2440 }
1513 GNUNET_assert (NULL != op->se); 2441 GNUNET_assert (NULL != op->se);
1514 diff = strata_estimator_difference (remote_se, 2442 strata_estimator_difference (remote_se,
1515 op->se); 2443 op->se);
2444
2445 /* Calculate remote local diff */
2446 long diff_remote = remote_se->stratas[0]->strata[0]->remote_decoded_count;
2447 long diff_local = remote_se->stratas[0]->strata[0]->local_decoded_count;
2448
2449 /* Prevent estimations from overshooting max element */
2450 if (diff_remote + op->remote_element_count > op->byzantine_upper_bound)
2451 diff_remote = op->byzantine_upper_bound - op->remote_element_count;
2452 if (diff_local + op->local_element_count > op->byzantine_upper_bound)
2453 diff_local = op->byzantine_upper_bound - op->local_element_count;
2454 if ((diff_remote < 0) || (diff_local < 0))
2455 {
2456 strata_estimator_destroy (remote_se);
2457 LOG (GNUNET_ERROR_TYPE_ERROR,
2458 "PROTOCOL VIOLATION: More element is set as upper boundary or other peer is "
2459 "malicious: remote diff %ld, local diff: %ld\n",
2460 diff_remote, diff_local);
2461 GNUNET_break_op (0);
2462 fail_union_operation (op);
2463 return;
2464 }
1516 2465
1517 if (diff > 200) 2466 /* Make estimation more precise in initial sync cases */
1518 diff = diff * 3 / 2; 2467 if (0 == op->remote_element_count)
2468 {
2469 diff_remote = 0;
2470 diff_local = op->local_element_count;
2471 }
2472 if (0 == op->local_element_count)
2473 {
2474 diff_local = 0;
2475 diff_remote = op->remote_element_count;
2476 }
2477
2478 diff = diff_remote + diff_local;
2479 op->remote_set_diff = diff_remote;
2480
2481 /** Calculate avg element size if not initial sync **/
2482 uint64_t avg_element_size = 0;
2483 if (0 < op->local_element_count)
2484 {
2485 op->total_elements_size_local = 0;
2486 GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
2487 &
2488 determinate_avg_element_size_iterator,
2489 op);
2490 avg_element_size = op->total_elements_size_local / op->local_element_count;
2491 }
2492
2493 op->mode_of_operation = estimate_best_mode_of_operation (avg_element_size,
2494 GNUNET_CONTAINER_multihashmap_size (
2495 op->set->content->
2496 elements),
2497 op->
2498 remote_element_count,
2499 diff_remote,
2500 diff_local,
2501 op->
2502 rtt_bandwidth_tradeoff,
2503 op->
2504 ibf_bucket_number_factor);
2505
2506#if MEASURE_PERFORMANCE
2507 perf_store.se_diff_local = diff_local;
2508 perf_store.se_diff_remote = diff_remote;
2509 perf_store.se_diff = diff;
2510 perf_store.mode_of_operation = op->mode_of_operation;
2511#endif
1519 2512
1520 strata_estimator_destroy (remote_se); 2513 strata_estimator_destroy (remote_se);
1521 strata_estimator_destroy (op->se); 2514 strata_estimator_destroy (op->se);
@@ -1523,7 +2516,8 @@ handle_union_p2p_strata_estimator (void *cls,
1523 LOG (GNUNET_ERROR_TYPE_DEBUG, 2516 LOG (GNUNET_ERROR_TYPE_DEBUG,
1524 "got se diff=%d, using ibf size %d\n", 2517 "got se diff=%d, using ibf size %d\n",
1525 diff, 2518 diff,
1526 1U << get_order_from_difference (diff)); 2519 1U << get_size_from_difference (diff, op->ibf_number_buckets_per_element,
2520 op->ibf_bucket_number_factor));
1527 2521
1528 { 2522 {
1529 char *set_debug; 2523 char *set_debug;
@@ -1546,16 +2540,8 @@ handle_union_p2p_strata_estimator (void *cls,
1546 return; 2540 return;
1547 } 2541 }
1548 2542
1549 LOG (GNUNET_ERROR_TYPE_ERROR,
1550 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: %f\n", op->rtt_bandwidth_tradeoff);
1551
1552
1553 /**
1554 * Added rtt_bandwidth_tradeoff directly need future improvements
1555 */
1556 if ((GNUNET_YES == op->force_full) || 2543 if ((GNUNET_YES == op->force_full) ||
1557 (diff > op->initial_size / 4) || 2544 (op->mode_of_operation != DIFFERENTIAL_SYNC))
1558 (0 == other_size))
1559 { 2545 {
1560 LOG (GNUNET_ERROR_TYPE_DEBUG, 2546 LOG (GNUNET_ERROR_TYPE_DEBUG,
1561 "Deciding to go for full set transmission (diff=%d, own set=%llu)\n", 2547 "Deciding to go for full set transmission (diff=%d, own set=%llu)\n",
@@ -1565,9 +2551,17 @@ handle_union_p2p_strata_estimator (void *cls,
1565 "# of full sends", 2551 "# of full sends",
1566 1, 2552 1,
1567 GNUNET_NO); 2553 GNUNET_NO);
1568 if ((op->initial_size <= other_size) || 2554 if (FULL_SYNC_LOCAL_SENDING_FIRST == op->mode_of_operation)
1569 (0 == other_size))
1570 { 2555 {
2556 struct TransmitFullMessage *signal_msg;
2557 struct GNUNET_MQ_Envelope *ev;
2558 ev = GNUNET_MQ_msg_extra (signal_msg,sizeof(struct TransmitFullMessage),
2559 GNUNET_MESSAGE_TYPE_SETU_P2P_SEND_FULL);
2560 signal_msg->remote_set_difference = htonl (diff_local);
2561 signal_msg->remote_set_size = htonl (op->local_element_count);
2562 signal_msg->local_set_difference = htonl (diff_remote);
2563 GNUNET_MQ_send (op->mq,
2564 ev);
1571 send_full_set (op); 2565 send_full_set (op);
1572 } 2566 }
1573 else 2567 else
@@ -1577,9 +2571,15 @@ handle_union_p2p_strata_estimator (void *cls,
1577 LOG (GNUNET_ERROR_TYPE_DEBUG, 2571 LOG (GNUNET_ERROR_TYPE_DEBUG,
1578 "Telling other peer that we expect its full set\n"); 2572 "Telling other peer that we expect its full set\n");
1579 op->phase = PHASE_FULL_RECEIVING; 2573 op->phase = PHASE_FULL_RECEIVING;
1580 perf_rtt.request_full.sent += 1; 2574#if MEASURE_PERFORMANCE
1581 ev = GNUNET_MQ_msg_header ( 2575 perf_store.request_full.sent += 1;
1582 GNUNET_MESSAGE_TYPE_SETU_P2P_REQUEST_FULL); 2576#endif
2577 struct TransmitFullMessage *signal_msg;
2578 ev = GNUNET_MQ_msg_extra (signal_msg,sizeof(struct TransmitFullMessage),
2579 GNUNET_MESSAGE_TYPE_SETU_P2P_REQUEST_FULL);
2580 signal_msg->remote_set_difference = htonl (diff_local);
2581 signal_msg->remote_set_size = htonl (op->local_element_count);
2582 signal_msg->local_set_difference = htonl (diff_remote);
1583 GNUNET_MQ_send (op->mq, 2583 GNUNET_MQ_send (op->mq,
1584 ev); 2584 ev);
1585 } 2585 }
@@ -1592,7 +2592,9 @@ handle_union_p2p_strata_estimator (void *cls,
1592 GNUNET_NO); 2592 GNUNET_NO);
1593 if (GNUNET_OK != 2593 if (GNUNET_OK !=
1594 send_ibf (op, 2594 send_ibf (op,
1595 get_order_from_difference (diff))) 2595 get_size_from_difference (diff,
2596 op->ibf_number_buckets_per_element,
2597 op->ibf_bucket_number_factor)))
1596 { 2598 {
1597 /* Internal error, best we can do is shut the connection */ 2599 /* Internal error, best we can do is shut the connection */
1598 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2600 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -1625,15 +2627,64 @@ send_offers_iterator (void *cls,
1625 2627
1626 /* Detect 32-bit key collision for the 64-bit IBF keys. */ 2628 /* Detect 32-bit key collision for the 64-bit IBF keys. */
1627 if (ke->ibf_key.key_val != sec->ibf_key.key_val) 2629 if (ke->ibf_key.key_val != sec->ibf_key.key_val)
2630 {
2631 op->active_passive_switch_required = true;
1628 return GNUNET_YES; 2632 return GNUNET_YES;
2633 }
1629 2634
1630 perf_rtt.offer.sent += 1; 2635 /* Prevent implementation from sending a offer multiple times in case of roll switch */
1631 perf_rtt.offer.sent_var_bytes += sizeof(struct GNUNET_HashCode); 2636 if (GNUNET_YES ==
2637 is_message_in_message_control_flow (
2638 op->message_control_flow,
2639 &ke->element->element_hash,
2640 OFFER_MESSAGE)
2641 )
2642 {
2643 LOG (GNUNET_ERROR_TYPE_DEBUG,
2644 "Skipping already sent processed element offer!\n");
2645 return GNUNET_YES;
2646 }
1632 2647
2648 /* Save send offer message for message control */
2649 if (GNUNET_YES !=
2650 update_message_control_flow (
2651 op->message_control_flow,
2652 MSG_CFS_SENT,
2653 &ke->element->element_hash,
2654 OFFER_MESSAGE)
2655 )
2656 {
2657 LOG (GNUNET_ERROR_TYPE_ERROR,
2658 "Double offer message sent found!\n");
2659 GNUNET_break (0);
2660 fail_union_operation (op);
2661 return GNUNET_NO;
2662 }
2663 ;
2664
2665 /* Mark element to be expected to received */
2666 if (GNUNET_YES !=
2667 update_message_control_flow (
2668 op->message_control_flow,
2669 MSG_CFS_EXPECTED,
2670 &ke->element->element_hash,
2671 DEMAND_MESSAGE)
2672 )
2673 {
2674 LOG (GNUNET_ERROR_TYPE_ERROR,
2675 "Double demand received found!\n");
2676 GNUNET_break (0);
2677 fail_union_operation (op);
2678 return GNUNET_NO;
2679 }
2680 ;
2681#if MEASURE_PERFORMANCE
2682 perf_store.offer.sent += 1;
2683 perf_store.offer.sent_var_bytes += sizeof(struct GNUNET_HashCode);
2684#endif
1633 ev = GNUNET_MQ_msg_header_extra (mh, 2685 ev = GNUNET_MQ_msg_header_extra (mh,
1634 sizeof(struct GNUNET_HashCode), 2686 sizeof(struct GNUNET_HashCode),
1635 GNUNET_MESSAGE_TYPE_SETU_P2P_OFFER); 2687 GNUNET_MESSAGE_TYPE_SETU_P2P_OFFER);
1636
1637 GNUNET_assert (NULL != ev); 2688 GNUNET_assert (NULL != ev);
1638 *(struct GNUNET_HashCode *) &mh[1] = ke->element->element_hash; 2689 *(struct GNUNET_HashCode *) &mh[1] = ke->element->element_hash;
1639 LOG (GNUNET_ERROR_TYPE_DEBUG, 2690 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -1651,7 +2702,7 @@ send_offers_iterator (void *cls,
1651 * @param op union operation 2702 * @param op union operation
1652 * @param ibf_key IBF key of interest 2703 * @param ibf_key IBF key of interest
1653 */ 2704 */
1654static void 2705void
1655send_offers_for_key (struct Operation *op, 2706send_offers_for_key (struct Operation *op,
1656 struct IBF_Key ibf_key) 2707 struct IBF_Key ibf_key)
1657{ 2708{
@@ -1694,6 +2745,7 @@ decode_and_send (struct Operation *op)
1694 /* allocation failed */ 2745 /* allocation failed */
1695 return GNUNET_SYSERR; 2746 return GNUNET_SYSERR;
1696 } 2747 }
2748
1697 diff_ibf = ibf_dup (op->local_ibf); 2749 diff_ibf = ibf_dup (op->local_ibf);
1698 ibf_subtract (diff_ibf, 2750 ibf_subtract (diff_ibf,
1699 op->remote_ibf); 2751 op->remote_ibf);
@@ -1706,7 +2758,7 @@ decode_and_send (struct Operation *op)
1706 diff_ibf->size); 2758 diff_ibf->size);
1707 2759
1708 num_decoded = 0; 2760 num_decoded = 0;
1709 key.key_val = 0; /* just to avoid compiler thinking we use undef'ed variable */ 2761 key.key_val = 0; /* just to avoid compiler thinking we use undef'ed variable */
1710 2762
1711 while (1) 2763 while (1)
1712 { 2764 {
@@ -1738,23 +2790,36 @@ decode_and_send (struct Operation *op)
1738 if ((GNUNET_SYSERR == res) || 2790 if ((GNUNET_SYSERR == res) ||
1739 (GNUNET_YES == cycle_detected)) 2791 (GNUNET_YES == cycle_detected))
1740 { 2792 {
1741 int next_order; 2793 uint32_t next_size;
1742 next_order = 0; 2794 /** Enforce odd ibf size **/
1743 while (1 << next_order < diff_ibf->size) 2795
1744 next_order++; 2796 next_size = get_next_ibf_size (op->ibf_bucket_number_factor, num_decoded,
1745 next_order++; 2797 diff_ibf->size);
1746 if (next_order <= MAX_IBF_ORDER) 2798 /** Make ibf estimation size odd reasoning can be found in BSc Thesis of
2799 * Elias Summermatter (2021) in section 3.11 **/
2800 uint32_t ibf_min_size = IBF_MIN_SIZE | 1;
2801
2802 if (next_size<ibf_min_size)
2803 next_size = ibf_min_size;
2804
2805
2806 if (next_size <= MAX_IBF_SIZE)
1747 { 2807 {
1748 LOG (GNUNET_ERROR_TYPE_DEBUG, 2808 LOG (GNUNET_ERROR_TYPE_DEBUG,
1749 "decoding failed, sending larger ibf (size %u)\n", 2809 "decoding failed, sending larger ibf (size %u)\n",
1750 1 << next_order); 2810 next_size);
1751 GNUNET_STATISTICS_update (_GSS_statistics, 2811 GNUNET_STATISTICS_update (_GSS_statistics,
1752 "# of IBF retries", 2812 "# of IBF retries",
1753 1, 2813 1,
1754 GNUNET_NO); 2814 GNUNET_NO);
1755 op->salt_send++; 2815#if MEASURE_PERFORMANCE
2816 perf_store.active_passive_switches += 1;
2817#endif
2818
2819 op->salt_send = op->salt_receive++;
2820
1756 if (GNUNET_OK != 2821 if (GNUNET_OK !=
1757 send_ibf (op, next_order)) 2822 send_ibf (op, next_size))
1758 { 2823 {
1759 /* Internal error, best we can do is shut the connection */ 2824 /* Internal error, best we can do is shut the connection */
1760 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2825 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -1786,7 +2851,9 @@ decode_and_send (struct Operation *op)
1786 LOG (GNUNET_ERROR_TYPE_DEBUG, 2851 LOG (GNUNET_ERROR_TYPE_DEBUG,
1787 "transmitted all values, sending DONE\n"); 2852 "transmitted all values, sending DONE\n");
1788 2853
1789 perf_rtt.done.sent += 1; 2854#if MEASURE_PERFORMANCE
2855 perf_store.done.sent += 1;
2856#endif
1790 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SETU_P2P_DONE); 2857 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SETU_P2P_DONE);
1791 GNUNET_MQ_send (op->mq, ev); 2858 GNUNET_MQ_send (op->mq, ev);
1792 /* We now wait until we get a DONE message back 2859 /* We now wait until we get a DONE message back
@@ -1797,7 +2864,6 @@ decode_and_send (struct Operation *op)
1797 if (1 == side) 2864 if (1 == side)
1798 { 2865 {
1799 struct IBF_Key unsalted_key; 2866 struct IBF_Key unsalted_key;
1800
1801 unsalt_key (&key, 2867 unsalt_key (&key,
1802 op->salt_receive, 2868 op->salt_receive,
1803 &unsalted_key); 2869 &unsalted_key);
@@ -1809,8 +2875,29 @@ decode_and_send (struct Operation *op)
1809 struct GNUNET_MQ_Envelope *ev; 2875 struct GNUNET_MQ_Envelope *ev;
1810 struct InquiryMessage *msg; 2876 struct InquiryMessage *msg;
1811 2877
1812 perf_rtt.inquery.sent += 1; 2878#if MEASURE_PERFORMANCE
1813 perf_rtt.inquery.sent_var_bytes += sizeof(struct IBF_Key); 2879 perf_store.inquery.sent += 1;
2880 perf_store.inquery.sent_var_bytes += sizeof(struct IBF_Key);
2881#endif
2882
2883 /** Add sent inquiries to hashmap for flow control **/
2884 struct GNUNET_HashContext *hashed_key_context =
2885 GNUNET_CRYPTO_hash_context_start ();
2886 struct GNUNET_HashCode *hashed_key = (struct
2887 GNUNET_HashCode*) GNUNET_malloc (
2888 sizeof(struct GNUNET_HashCode));
2889 enum MESSAGE_CONTROL_FLOW_STATE mcfs = MSG_CFS_SENT;
2890 GNUNET_CRYPTO_hash_context_read (hashed_key_context,
2891 &key,
2892 sizeof(struct IBF_Key));
2893 GNUNET_CRYPTO_hash_context_finish (hashed_key_context,
2894 hashed_key);
2895 GNUNET_CONTAINER_multihashmap_put (op->inquiries_sent,
2896 hashed_key,
2897 &mcfs,
2898 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE
2899 );
2900
1814 /* It may be nice to merge multiple requests, but with CADET's corking it is not worth 2901 /* It may be nice to merge multiple requests, but with CADET's corking it is not worth
1815 * the effort additional complexity. */ 2902 * the effort additional complexity. */
1816 ev = GNUNET_MQ_msg_extra (msg, 2903 ev = GNUNET_MQ_msg_extra (msg,
@@ -1836,6 +2923,100 @@ decode_and_send (struct Operation *op)
1836 2923
1837 2924
1838/** 2925/**
2926 * Check send full message received from other peer
2927 * @param cls
2928 * @param msg
2929 * @return
2930 */
2931
2932static int
2933check_union_p2p_send_full (void *cls,
2934 const struct TransmitFullMessage *msg)
2935{
2936 return GNUNET_OK;
2937}
2938
2939
2940/**
2941 * Handle send full message received from other peer
2942 *
2943 * @param cls
2944 * @param msg
2945 */
2946static void
2947handle_union_p2p_send_full (void *cls,
2948 const struct TransmitFullMessage *msg)
2949{
2950 struct Operation *op = cls;
2951
2952 /**
2953 * Check that the message is received only in supported phase
2954 */
2955 uint8_t allowed_phases[] = {PHASE_EXPECT_IBF};
2956 if (GNUNET_OK !=
2957 check_valid_phase (allowed_phases,sizeof(allowed_phases),op))
2958 {
2959 GNUNET_break (0);
2960 fail_union_operation (op);
2961 return;
2962 }
2963
2964 /** write received values to operator**/
2965 op->remote_element_count = ntohl (msg->remote_set_size);
2966 op->remote_set_diff = ntohl (msg->remote_set_difference);
2967 op->local_set_diff = ntohl (msg->local_set_difference);
2968
2969 /** Check byzantine limits **/
2970 if (check_byzantine_bounds (op) != GNUNET_OK)
2971 {
2972 LOG (GNUNET_ERROR_TYPE_ERROR,
2973 "PROTOCOL VIOLATION: Parameters transmitted from other peer do not satisfie byzantine "
2974 "criteria\n");
2975 GNUNET_break_op (0);
2976 fail_union_operation (op);
2977 return;
2978 }
2979
2980 /** Calculate avg element size if not initial sync **/
2981 op->local_element_count = GNUNET_CONTAINER_multihashmap_size (
2982 op->set->content->elements);
2983 uint64_t avg_element_size = 0;
2984 if (0 < op->local_element_count)
2985 {
2986 op->total_elements_size_local = 0;
2987 GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
2988 &
2989 determinate_avg_element_size_iterator,
2990 op);
2991 avg_element_size = op->total_elements_size_local / op->local_element_count;
2992 }
2993
2994 /** Validate mode of operation **/
2995 int mode_of_operation = estimate_best_mode_of_operation (avg_element_size,
2996 op->
2997 remote_element_count,
2998 op->
2999 local_element_count,
3000 op->local_set_diff,
3001 op->remote_set_diff,
3002 op->
3003 rtt_bandwidth_tradeoff,
3004 op->
3005 ibf_bucket_number_factor);
3006 if (FULL_SYNC_LOCAL_SENDING_FIRST != mode_of_operation)
3007 {
3008 LOG (GNUNET_ERROR_TYPE_ERROR,
3009 "PROTOCOL VIOLATION: Remote peer choose to send his full set first but correct mode would have been"
3010 " : %d\n", mode_of_operation);
3011 GNUNET_break_op (0);
3012 fail_union_operation (op);
3013 return;
3014 }
3015 op->phase = PHASE_FULL_RECEIVING;
3016}
3017
3018
3019/**
1839 * Check an IBF message from a remote peer. 3020 * Check an IBF message from a remote peer.
1840 * 3021 *
1841 * Reassemble the IBF from multiple pieces, and 3022 * Reassemble the IBF from multiple pieces, and
@@ -1872,7 +3053,8 @@ check_union_p2p_ibf (void *cls,
1872 GNUNET_break_op (0); 3053 GNUNET_break_op (0);
1873 return GNUNET_SYSERR; 3054 return GNUNET_SYSERR;
1874 } 3055 }
1875 if (1 << msg->order != op->remote_ibf->size) 3056
3057 if (msg->ibf_size != op->remote_ibf->size)
1876 { 3058 {
1877 GNUNET_break_op (0); 3059 GNUNET_break_op (0);
1878 return GNUNET_SYSERR; 3060 return GNUNET_SYSERR;
@@ -1909,9 +3091,26 @@ handle_union_p2p_ibf (void *cls,
1909{ 3091{
1910 struct Operation *op = cls; 3092 struct Operation *op = cls;
1911 unsigned int buckets_in_message; 3093 unsigned int buckets_in_message;
3094 /**
3095 * Check that the message is received only in supported phase
3096 */
3097 uint8_t allowed_phases[] = {PHASE_EXPECT_IBF, PHASE_EXPECT_IBF_LAST,
3098 PHASE_PASSIVE_DECODING};
3099 if (GNUNET_OK !=
3100 check_valid_phase (allowed_phases,sizeof(allowed_phases),op))
3101 {
3102 GNUNET_break (0);
3103 fail_union_operation (op);
3104 return;
3105 }
3106 op->differential_sync_iterations++;
3107 check_max_differential_rounds (op);
3108 op->active_passive_switch_required = false;
1912 3109
1913 perf_rtt.ibf.received += 1; 3110#if MEASURE_PERFORMANCE
1914 perf_rtt.ibf.received_var_bytes += (ntohs (msg->header.size) - sizeof *msg); 3111 perf_store.ibf.received += 1;
3112 perf_store.ibf.received_var_bytes += (ntohs (msg->header.size) - sizeof *msg);
3113#endif
1915 3114
1916 buckets_in_message = (ntohs (msg->header.size) - sizeof *msg) 3115 buckets_in_message = (ntohs (msg->header.size) - sizeof *msg)
1917 / IBF_BUCKET_SIZE; 3116 / IBF_BUCKET_SIZE;
@@ -1922,8 +3121,10 @@ handle_union_p2p_ibf (void *cls,
1922 GNUNET_assert (NULL == op->remote_ibf); 3121 GNUNET_assert (NULL == op->remote_ibf);
1923 LOG (GNUNET_ERROR_TYPE_DEBUG, 3122 LOG (GNUNET_ERROR_TYPE_DEBUG,
1924 "Creating new ibf of size %u\n", 3123 "Creating new ibf of size %u\n",
1925 1 << msg->order); 3124 ntohl (msg->ibf_size));
1926 op->remote_ibf = ibf_create (1 << msg->order, SE_IBF_HASH_NUM); 3125 // op->remote_ibf = ibf_create (1 << msg->order, SE_IBF_HASH_NUM);
3126 op->remote_ibf = ibf_create (msg->ibf_size,
3127 ((uint8_t) op->ibf_number_buckets_per_element));
1927 op->salt_receive = ntohl (msg->salt); 3128 op->salt_receive = ntohl (msg->salt);
1928 LOG (GNUNET_ERROR_TYPE_DEBUG, 3129 LOG (GNUNET_ERROR_TYPE_DEBUG,
1929 "Receiving new IBF with salt %u\n", 3130 "Receiving new IBF with salt %u\n",
@@ -1954,7 +3155,7 @@ handle_union_p2p_ibf (void *cls,
1954 ibf_read_slice (&msg[1], 3155 ibf_read_slice (&msg[1],
1955 op->ibf_buckets_received, 3156 op->ibf_buckets_received,
1956 buckets_in_message, 3157 buckets_in_message,
1957 op->remote_ibf); 3158 op->remote_ibf, msg->ibf_counter_bit_length);
1958 op->ibf_buckets_received += buckets_in_message; 3159 op->ibf_buckets_received += buckets_in_message;
1959 3160
1960 if (op->ibf_buckets_received == op->remote_ibf->size) 3161 if (op->ibf_buckets_received == op->remote_ibf->size)
@@ -2030,18 +3231,24 @@ maybe_finish (struct Operation *op)
2030 3231
2031 num_demanded = GNUNET_CONTAINER_multihashmap_size ( 3232 num_demanded = GNUNET_CONTAINER_multihashmap_size (
2032 op->demanded_hashes); 3233 op->demanded_hashes);
2033 3234 int send_done = GNUNET_CONTAINER_multihashmap_iterate (
3235 op->message_control_flow,
3236 &
3237 determinate_done_message_iterator,
3238 op);
2034 if (PHASE_FINISH_WAITING == op->phase) 3239 if (PHASE_FINISH_WAITING == op->phase)
2035 { 3240 {
2036 LOG (GNUNET_ERROR_TYPE_DEBUG, 3241 LOG (GNUNET_ERROR_TYPE_DEBUG,
2037 "In PHASE_FINISH_WAITING, pending %u demands\n", 3242 "In PHASE_FINISH_WAITING, pending %u demands -> %d\n",
2038 num_demanded); 3243 num_demanded, op->peer_site);
2039 if (0 == num_demanded) 3244 if (-1 != send_done)
2040 { 3245 {
2041 struct GNUNET_MQ_Envelope *ev; 3246 struct GNUNET_MQ_Envelope *ev;
2042 3247
2043 op->phase = PHASE_FINISHED; 3248 op->phase = PHASE_FINISHED;
2044 perf_rtt.done.sent += 1; 3249#if MEASURE_PERFORMANCE
3250 perf_store.done.sent += 1;
3251#endif
2045 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SETU_P2P_DONE); 3252 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SETU_P2P_DONE);
2046 GNUNET_MQ_send (op->mq, 3253 GNUNET_MQ_send (op->mq,
2047 ev); 3254 ev);
@@ -2052,9 +3259,9 @@ maybe_finish (struct Operation *op)
2052 if (PHASE_FINISH_CLOSING == op->phase) 3259 if (PHASE_FINISH_CLOSING == op->phase)
2053 { 3260 {
2054 LOG (GNUNET_ERROR_TYPE_DEBUG, 3261 LOG (GNUNET_ERROR_TYPE_DEBUG,
2055 "In PHASE_FINISH_CLOSING, pending %u demands\n", 3262 "In PHASE_FINISH_CLOSING, pending %u demands %d\n",
2056 num_demanded); 3263 num_demanded, op->peer_site);
2057 if (0 == num_demanded) 3264 if (-1 != send_done)
2058 { 3265 {
2059 op->phase = PHASE_FINISHED; 3266 op->phase = PHASE_FINISHED;
2060 send_client_done (op); 3267 send_client_done (op);
@@ -2102,11 +3309,25 @@ handle_union_p2p_elements (void *cls,
2102 struct KeyEntry *ke; 3309 struct KeyEntry *ke;
2103 uint16_t element_size; 3310 uint16_t element_size;
2104 3311
3312 /**
3313 * Check that the message is received only in supported phase
3314 */
3315 uint8_t allowed_phases[] = {PHASE_ACTIVE_DECODING, PHASE_PASSIVE_DECODING,
3316 PHASE_FINISH_WAITING, PHASE_FINISH_CLOSING};
3317 if (GNUNET_OK !=
3318 check_valid_phase (allowed_phases,sizeof(allowed_phases),op))
3319 {
3320 GNUNET_break (0);
3321 fail_union_operation (op);
3322 return;
3323 }
2105 3324
2106 element_size = ntohs (emsg->header.size) - sizeof(struct 3325 element_size = ntohs (emsg->header.size) - sizeof(struct
2107 GNUNET_SETU_ElementMessage); 3326 GNUNET_SETU_ElementMessage);
2108 perf_rtt.element.received += 1; 3327#if MEASURE_PERFORMANCE
2109 perf_rtt.element.received_var_bytes += element_size; 3328 perf_store.element.received += 1;
3329 perf_store.element.received_var_bytes += element_size;
3330#endif
2110 3331
2111 ee = GNUNET_malloc (sizeof(struct ElementEntry) + element_size); 3332 ee = GNUNET_malloc (sizeof(struct ElementEntry) + element_size);
2112 GNUNET_memcpy (&ee[1], 3333 GNUNET_memcpy (&ee[1],
@@ -2129,6 +3350,21 @@ handle_union_p2p_elements (void *cls,
2129 return; 3350 return;
2130 } 3351 }
2131 3352
3353 if (GNUNET_OK !=
3354 update_message_control_flow (
3355 op->message_control_flow,
3356 MSG_CFS_RECEIVED,
3357 &ee->element_hash,
3358 ELEMENT_MESSAGE)
3359 )
3360 {
3361 LOG (GNUNET_ERROR_TYPE_ERROR,
3362 "An element has been received more than once!\n");
3363 GNUNET_break (0);
3364 fail_union_operation (op);
3365 return;
3366 }
3367
2132 LOG (GNUNET_ERROR_TYPE_DEBUG, 3368 LOG (GNUNET_ERROR_TYPE_DEBUG,
2133 "Got element (size %u, hash %s) from peer\n", 3369 "Got element (size %u, hash %s) from peer\n",
2134 (unsigned int) element_size, 3370 (unsigned int) element_size,
@@ -2217,33 +3453,25 @@ handle_union_p2p_full_element (void *cls,
2217 struct KeyEntry *ke; 3453 struct KeyEntry *ke;
2218 uint16_t element_size; 3454 uint16_t element_size;
2219 3455
2220 3456 /**
2221 3457 * Check that the message is received only in supported phase
2222 if(PHASE_EXPECT_IBF == op->phase) { 3458 */
2223 op->phase = PHASE_FULL_RECEIVING; 3459 uint8_t allowed_phases[] = {PHASE_FULL_RECEIVING, PHASE_FULL_SENDING};
2224 } 3460 if (GNUNET_OK !=
2225 3461 check_valid_phase (allowed_phases,sizeof(allowed_phases),op))
2226
2227
2228 /* Allow only receiving of full element message if in expect IBF or in PHASE_FULL_RECEIVING state */
2229 if ((PHASE_FULL_RECEIVING != op->phase) &&
2230 (PHASE_FULL_SENDING != op->phase))
2231 { 3462 {
2232 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3463 GNUNET_break (0);
2233 "Handle full element phase is %u\n", 3464 fail_union_operation (op);
2234 (unsigned) op->phase); 3465 return;
2235 GNUNET_break_op (0);
2236 fail_union_operation (op);
2237 return;
2238 } 3466 }
2239 3467
2240
2241
2242 element_size = ntohs (emsg->header.size) 3468 element_size = ntohs (emsg->header.size)
2243 - sizeof(struct GNUNET_SETU_ElementMessage); 3469 - sizeof(struct GNUNET_SETU_ElementMessage);
2244 3470
2245 perf_rtt.element_full.received += 1; 3471#if MEASURE_PERFORMANCE
2246 perf_rtt.element_full.received_var_bytes += element_size; 3472 perf_store.element_full.received += 1;
3473 perf_store.element_full.received_var_bytes += element_size;
3474#endif
2247 3475
2248 ee = GNUNET_malloc (sizeof(struct ElementEntry) + element_size); 3476 ee = GNUNET_malloc (sizeof(struct ElementEntry) + element_size);
2249 GNUNET_memcpy (&ee[1], &emsg[1], element_size); 3477 GNUNET_memcpy (&ee[1], &emsg[1], element_size);
@@ -2268,17 +3496,15 @@ handle_union_p2p_full_element (void *cls,
2268 GNUNET_NO); 3496 GNUNET_NO);
2269 3497
2270 op->received_total++; 3498 op->received_total++;
2271
2272 ke = op_get_element (op, 3499 ke = op_get_element (op,
2273 &ee->element_hash); 3500 &ee->element_hash);
2274 if (NULL != ke) 3501 if (NULL != ke)
2275 { 3502 {
2276 /* Got repeated element. Should not happen since
2277 * we track demands. */
2278 GNUNET_STATISTICS_update (_GSS_statistics, 3503 GNUNET_STATISTICS_update (_GSS_statistics,
2279 "# repeated elements", 3504 "# repeated elements",
2280 1, 3505 1,
2281 GNUNET_NO); 3506 GNUNET_NO);
3507 full_sync_plausibility_check (op);
2282 ke->received = GNUNET_YES; 3508 ke->received = GNUNET_YES;
2283 GNUNET_free (ee); 3509 GNUNET_free (ee);
2284 } 3510 }
@@ -2294,15 +3520,15 @@ handle_union_p2p_full_element (void *cls,
2294 GNUNET_SETU_STATUS_ADD_LOCAL); 3520 GNUNET_SETU_STATUS_ADD_LOCAL);
2295 } 3521 }
2296 3522
3523
2297 if ((GNUNET_YES == op->byzantine) && 3524 if ((GNUNET_YES == op->byzantine) &&
2298 (op->received_total > 384 + op->received_fresh * 4) && 3525 (op->received_total > op->remote_element_count) )
2299 (op->received_fresh < op->received_total / 6))
2300 { 3526 {
2301 /* The other peer gave us lots of old elements, there's something wrong. */ 3527 /* The other peer gave us lots of old elements, there's something wrong. */
2302 LOG (GNUNET_ERROR_TYPE_ERROR, 3528 LOG (GNUNET_ERROR_TYPE_ERROR,
2303 "Other peer sent only %llu/%llu fresh elements, failing operation\n", 3529 "Other peer sent %llu elements while pretending to have %llu elements, failing operation\n",
2304 (unsigned long long) op->received_fresh, 3530 (unsigned long long) op->received_total,
2305 (unsigned long long) op->received_total); 3531 (unsigned long long) op->remote_element_count);
2306 GNUNET_break_op (0); 3532 GNUNET_break_op (0);
2307 fail_union_operation (op); 3533 fail_union_operation (op);
2308 return; 3534 return;
@@ -2356,18 +3582,50 @@ handle_union_p2p_inquiry (void *cls,
2356 const struct IBF_Key *ibf_key; 3582 const struct IBF_Key *ibf_key;
2357 unsigned int num_keys; 3583 unsigned int num_keys;
2358 3584
2359 perf_rtt.inquery.received += 1; 3585 /**
2360 perf_rtt.inquery.received_var_bytes += (ntohs (msg->header.size) - sizeof(struct InquiryMessage)); 3586 * Check that the message is received only in supported phase
3587 */
3588 uint8_t allowed_phases[] = {PHASE_ACTIVE_DECODING, PHASE_PASSIVE_DECODING};
3589 if (GNUNET_OK !=
3590 check_valid_phase (allowed_phases,sizeof(allowed_phases),op))
3591 {
3592 GNUNET_break (0);
3593 fail_union_operation (op);
3594 return;
3595 }
3596
3597#if MEASURE_PERFORMANCE
3598 perf_store.inquery.received += 1;
3599 perf_store.inquery.received_var_bytes += (ntohs (msg->header.size)
3600 - sizeof(struct InquiryMessage));
3601#endif
2361 3602
2362 LOG (GNUNET_ERROR_TYPE_DEBUG, 3603 LOG (GNUNET_ERROR_TYPE_DEBUG,
2363 "Received union inquiry\n"); 3604 "Received union inquiry\n");
2364 num_keys = (ntohs (msg->header.size) - sizeof(struct InquiryMessage)) 3605 num_keys = (ntohs (msg->header.size) - sizeof(struct InquiryMessage))
2365 / sizeof(struct IBF_Key); 3606 / sizeof(struct IBF_Key);
2366 ibf_key = (const struct IBF_Key *) &msg[1]; 3607 ibf_key = (const struct IBF_Key *) &msg[1];
3608
3609 /** Add received inquiries to hashmap for flow control **/
3610 struct GNUNET_HashContext *hashed_key_context =
3611 GNUNET_CRYPTO_hash_context_start ();
3612 struct GNUNET_HashCode *hashed_key = (struct GNUNET_HashCode*) GNUNET_malloc (
3613 sizeof(struct GNUNET_HashCode));;
3614 enum MESSAGE_CONTROL_FLOW_STATE mcfs = MSG_CFS_RECEIVED;
3615 GNUNET_CRYPTO_hash_context_read (hashed_key_context,
3616 &ibf_key,
3617 sizeof(struct IBF_Key));
3618 GNUNET_CRYPTO_hash_context_finish (hashed_key_context,
3619 hashed_key);
3620 GNUNET_CONTAINER_multihashmap_put (op->inquiries_sent,
3621 hashed_key,
3622 &mcfs,
3623 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE
3624 );
3625
2367 while (0 != num_keys--) 3626 while (0 != num_keys--)
2368 { 3627 {
2369 struct IBF_Key unsalted_key; 3628 struct IBF_Key unsalted_key;
2370
2371 unsalt_key (ibf_key, 3629 unsalt_key (ibf_key,
2372 ntohl (msg->salt), 3630 ntohl (msg->salt),
2373 &unsalted_key); 3631 &unsalted_key);
@@ -2402,7 +3660,9 @@ send_missing_full_elements_iter (void *cls,
2402 3660
2403 if (GNUNET_YES == ke->received) 3661 if (GNUNET_YES == ke->received)
2404 return GNUNET_YES; 3662 return GNUNET_YES;
2405 perf_rtt.element_full.received += 1; 3663#if MEASURE_PERFORMANCE
3664 perf_store.element_full.received += 1;
3665#endif
2406 ev = GNUNET_MQ_msg_extra (emsg, 3666 ev = GNUNET_MQ_msg_extra (emsg,
2407 ee->element.size, 3667 ee->element.size,
2408 GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT); 3668 GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT);
@@ -2422,18 +3682,84 @@ send_missing_full_elements_iter (void *cls,
2422 * @param cls closure, a set union operation 3682 * @param cls closure, a set union operation
2423 * @param mh the demand message 3683 * @param mh the demand message
2424 */ 3684 */
3685static int
3686check_union_p2p_request_full (void *cls,
3687 const struct TransmitFullMessage *mh)
3688{
3689 return GNUNET_OK;
3690}
3691
3692
2425static void 3693static void
2426handle_union_p2p_request_full (void *cls, 3694handle_union_p2p_request_full (void *cls,
2427 const struct GNUNET_MessageHeader *mh) 3695 const struct TransmitFullMessage *msg)
2428{ 3696{
2429 struct Operation *op = cls; 3697 struct Operation *op = cls;
2430 3698
2431 perf_rtt.request_full.received += 1; 3699 /**
3700 * Check that the message is received only in supported phase
3701 */
3702 uint8_t allowed_phases[] = {PHASE_EXPECT_IBF};
3703 if (GNUNET_OK !=
3704 check_valid_phase (allowed_phases,sizeof(allowed_phases),op))
3705 {
3706 GNUNET_break (0);
3707 fail_union_operation (op);
3708 return;
3709 }
2432 3710
2433 LOG (GNUNET_ERROR_TYPE_DEBUG, 3711 op->remote_element_count = ntohl (msg->remote_set_size);
3712 op->remote_set_diff = ntohl (msg->remote_set_difference);
3713 op->local_set_diff = ntohl (msg->local_set_difference);
3714
3715
3716 if (check_byzantine_bounds (op) != GNUNET_OK)
3717 {
3718 LOG (GNUNET_ERROR_TYPE_ERROR,
3719 "PROTOCOL VIOLATION: Parameters transmitted from other peer do not satisfie byzantine "
3720 "criteria\n");
3721 GNUNET_break_op (0);
3722 fail_union_operation (op);
3723 return;
3724 }
3725
3726#if MEASURE_PERFORMANCE
3727 perf_store.request_full.received += 1;
3728#endif
3729
3730 LOG (GNUNET_ERROR_TYPE_DEBUG,
2434 "Received request for full set transmission\n"); 3731 "Received request for full set transmission\n");
2435 if (PHASE_EXPECT_IBF != op->phase) 3732
3733 /** Calculate avg element size if not initial sync **/
3734 op->local_element_count = GNUNET_CONTAINER_multihashmap_size (
3735 op->set->content->elements);
3736 uint64_t avg_element_size = 0;
3737 if (0 < op->local_element_count)
3738 {
3739 op->total_elements_size_local = 0;
3740 GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
3741 &
3742 determinate_avg_element_size_iterator,
3743 op);
3744 avg_element_size = op->total_elements_size_local / op->local_element_count;
3745 }
3746
3747 int mode_of_operation = estimate_best_mode_of_operation (avg_element_size,
3748 op->
3749 remote_element_count,
3750 op->
3751 local_element_count,
3752 op->local_set_diff,
3753 op->remote_set_diff,
3754 op->
3755 rtt_bandwidth_tradeoff,
3756 op->
3757 ibf_bucket_number_factor);
3758 if (FULL_SYNC_REMOTE_SENDING_FIRST != mode_of_operation)
2436 { 3759 {
3760 LOG (GNUNET_ERROR_TYPE_ERROR,
3761 "PROTOCOL VIOLATION: Remote peer choose to request the full set first but correct mode would have been"
3762 " : %d\n", mode_of_operation);
2437 GNUNET_break_op (0); 3763 GNUNET_break_op (0);
2438 fail_union_operation (op); 3764 fail_union_operation (op);
2439 return; 3765 return;
@@ -2458,7 +3784,21 @@ handle_union_p2p_full_done (void *cls,
2458{ 3784{
2459 struct Operation *op = cls; 3785 struct Operation *op = cls;
2460 3786
2461 perf_rtt.full_done.received += 1; 3787 /**
3788 * Check that the message is received only in supported phase
3789 */
3790 uint8_t allowed_phases[] = {PHASE_FULL_SENDING, PHASE_FULL_RECEIVING};
3791 if (GNUNET_OK !=
3792 check_valid_phase (allowed_phases,sizeof(allowed_phases),op))
3793 {
3794 GNUNET_break (0);
3795 fail_union_operation (op);
3796 return;
3797 }
3798
3799#if MEASURE_PERFORMANCE
3800 perf_store.full_done.received += 1;
3801#endif
2462 3802
2463 switch (op->phase) 3803 switch (op->phase)
2464 { 3804 {
@@ -2466,6 +3806,19 @@ handle_union_p2p_full_done (void *cls,
2466 { 3806 {
2467 struct GNUNET_MQ_Envelope *ev; 3807 struct GNUNET_MQ_Envelope *ev;
2468 3808
3809 if ((GNUNET_YES == op->byzantine) &&
3810 (op->received_total != op->remote_element_count) )
3811 {
3812 /* The other peer gave not enough elements before sending full done, there's something wrong. */
3813 LOG (GNUNET_ERROR_TYPE_ERROR,
3814 "Other peer sent only %llu/%llu fresh elements, failing operation\n",
3815 (unsigned long long) op->received_total,
3816 (unsigned long long) op->remote_element_count);
3817 GNUNET_break_op (0);
3818 fail_union_operation (op);
3819 return;
3820 }
3821
2469 LOG (GNUNET_ERROR_TYPE_DEBUG, 3822 LOG (GNUNET_ERROR_TYPE_DEBUG,
2470 "got FULL DONE, sending elements that other peer is missing\n"); 3823 "got FULL DONE, sending elements that other peer is missing\n");
2471 3824
@@ -2473,7 +3826,9 @@ handle_union_p2p_full_done (void *cls,
2473 GNUNET_CONTAINER_multihashmap32_iterate (op->key_to_element, 3826 GNUNET_CONTAINER_multihashmap32_iterate (op->key_to_element,
2474 &send_missing_full_elements_iter, 3827 &send_missing_full_elements_iter,
2475 op); 3828 op);
2476 perf_rtt.full_done.sent += 1; 3829#if MEASURE_PERFORMANCE
3830 perf_store.full_done.sent += 1;
3831#endif
2477 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE); 3832 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE);
2478 GNUNET_MQ_send (op->mq, 3833 GNUNET_MQ_send (op->mq,
2479 ev); 3834 ev);
@@ -2552,8 +3907,23 @@ handle_union_p2p_demand (void *cls,
2552 unsigned int num_hashes; 3907 unsigned int num_hashes;
2553 struct GNUNET_MQ_Envelope *ev; 3908 struct GNUNET_MQ_Envelope *ev;
2554 3909
2555 perf_rtt.demand.received += 1; 3910 /**
2556 perf_rtt.demand.received_var_bytes += (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader)); 3911 * Check that the message is received only in supported phase
3912 */
3913 uint8_t allowed_phases[] = {PHASE_ACTIVE_DECODING, PHASE_PASSIVE_DECODING,
3914 PHASE_FINISH_WAITING};
3915 if (GNUNET_OK !=
3916 check_valid_phase (allowed_phases,sizeof(allowed_phases),op))
3917 {
3918 GNUNET_break (0);
3919 fail_union_operation (op);
3920 return;
3921 }
3922#if MEASURE_PERFORMANCE
3923 perf_store.demand.received += 1;
3924 perf_store.demand.received_var_bytes += (ntohs (mh->size) - sizeof(struct
3925 GNUNET_MessageHeader));
3926#endif
2557 3927
2558 num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader)) 3928 num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2559 / sizeof(struct GNUNET_HashCode); 3929 / sizeof(struct GNUNET_HashCode);
@@ -2570,6 +3940,39 @@ handle_union_p2p_demand (void *cls,
2570 fail_union_operation (op); 3940 fail_union_operation (op);
2571 return; 3941 return;
2572 } 3942 }
3943
3944 /* Save send demand message for message control */
3945 if (GNUNET_YES !=
3946 update_message_control_flow (
3947 op->message_control_flow,
3948 MSG_CFS_RECEIVED,
3949 &ee->element_hash,
3950 DEMAND_MESSAGE)
3951 )
3952 {
3953 LOG (GNUNET_ERROR_TYPE_ERROR,
3954 "Double demand message received found!\n");
3955 GNUNET_break (0);
3956 fail_union_operation (op);
3957 return;
3958 }
3959 ;
3960
3961 /* Mark element to be expected to received */
3962 if (GNUNET_YES !=
3963 update_message_control_flow (
3964 op->message_control_flow,
3965 MSG_CFS_SENT,
3966 &ee->element_hash,
3967 ELEMENT_MESSAGE)
3968 )
3969 {
3970 LOG (GNUNET_ERROR_TYPE_ERROR,
3971 "Double element message sent found!\n");
3972 GNUNET_break (0);
3973 fail_union_operation (op);
3974 return;
3975 }
2573 if (GNUNET_NO == _GSS_is_element_of_operation (ee, op)) 3976 if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
2574 { 3977 {
2575 /* Probably confused lazily copied sets. */ 3978 /* Probably confused lazily copied sets. */
@@ -2577,8 +3980,10 @@ handle_union_p2p_demand (void *cls,
2577 fail_union_operation (op); 3980 fail_union_operation (op);
2578 return; 3981 return;
2579 } 3982 }
2580 perf_rtt.element.sent += 1; 3983#if MEASURE_PERFORMANCE
2581 perf_rtt.element.sent_var_bytes += ee->element.size; 3984 perf_store.element.sent += 1;
3985 perf_store.element.sent_var_bytes += ee->element.size;
3986#endif
2582 ev = GNUNET_MQ_msg_extra (emsg, 3987 ev = GNUNET_MQ_msg_extra (emsg,
2583 ee->element.size, 3988 ee->element.size,
2584 GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENTS); 3989 GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENTS);
@@ -2600,9 +4005,10 @@ handle_union_p2p_demand (void *cls,
2600 if (op->symmetric) 4005 if (op->symmetric)
2601 send_client_element (op, 4006 send_client_element (op,
2602 &ee->element, 4007 &ee->element,
2603 GNUNET_SET_STATUS_ADD_REMOTE); 4008 GNUNET_SETU_STATUS_ADD_REMOTE);
2604 } 4009 }
2605 GNUNET_CADET_receive_done (op->channel); 4010 GNUNET_CADET_receive_done (op->channel);
4011 maybe_finish (op);
2606} 4012}
2607 4013
2608 4014
@@ -2653,9 +4059,23 @@ handle_union_p2p_offer (void *cls,
2653 struct Operation *op = cls; 4059 struct Operation *op = cls;
2654 const struct GNUNET_HashCode *hash; 4060 const struct GNUNET_HashCode *hash;
2655 unsigned int num_hashes; 4061 unsigned int num_hashes;
4062 /**
4063 * Check that the message is received only in supported phase
4064 */
4065 uint8_t allowed_phases[] = {PHASE_ACTIVE_DECODING, PHASE_PASSIVE_DECODING};
4066 if (GNUNET_OK !=
4067 check_valid_phase (allowed_phases,sizeof(allowed_phases),op))
4068 {
4069 GNUNET_break (0);
4070 fail_union_operation (op);
4071 return;
4072 }
2656 4073
2657 perf_rtt.offer.received += 1; 4074#if MEASURE_PERFORMANCE
2658 perf_rtt.offer.received_var_bytes += (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader)); 4075 perf_store.offer.received += 1;
4076 perf_store.offer.received_var_bytes += (ntohs (mh->size) - sizeof(struct
4077 GNUNET_MessageHeader));
4078#endif
2659 4079
2660 num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader)) 4080 num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2661 / sizeof(struct GNUNET_HashCode); 4081 / sizeof(struct GNUNET_HashCode);
@@ -2693,8 +4113,53 @@ handle_union_p2p_offer (void *cls,
2693 "[OP %p] Requesting element (hash %s)\n", 4113 "[OP %p] Requesting element (hash %s)\n",
2694 op, GNUNET_h2s (hash)); 4114 op, GNUNET_h2s (hash));
2695 4115
2696 perf_rtt.demand.sent += 1; 4116#if MEASURE_PERFORMANCE
2697 perf_rtt.demand.sent_var_bytes += sizeof(struct GNUNET_HashCode); 4117 perf_store.demand.sent += 1;
4118 perf_store.demand.sent_var_bytes += sizeof(struct GNUNET_HashCode);
4119#endif
4120 /* Save send demand message for message control */
4121 if (GNUNET_YES !=
4122 update_message_control_flow (
4123 op->message_control_flow,
4124 MSG_CFS_SENT,
4125 hash,
4126 DEMAND_MESSAGE))
4127 {
4128 LOG (GNUNET_ERROR_TYPE_ERROR,
4129 "Double demand message sent found!\n");
4130 GNUNET_break (0);
4131 fail_union_operation (op);
4132 return;
4133 }
4134
4135 /* Mark offer as received received */
4136 if (GNUNET_YES !=
4137 update_message_control_flow (
4138 op->message_control_flow,
4139 MSG_CFS_RECEIVED,
4140 hash,
4141 OFFER_MESSAGE))
4142 {
4143 LOG (GNUNET_ERROR_TYPE_ERROR,
4144 "Double offer message received found!\n");
4145 GNUNET_break (0);
4146 fail_union_operation (op);
4147 return;
4148 }
4149 /* Mark element to be expected to received */
4150 if (GNUNET_YES !=
4151 update_message_control_flow (
4152 op->message_control_flow,
4153 MSG_CFS_EXPECTED,
4154 hash,
4155 ELEMENT_MESSAGE))
4156 {
4157 LOG (GNUNET_ERROR_TYPE_ERROR,
4158 "Element already expected!\n");
4159 GNUNET_break (0);
4160 fail_union_operation (op);
4161 return;
4162 }
2698 ev = GNUNET_MQ_msg_header_extra (demands, 4163 ev = GNUNET_MQ_msg_header_extra (demands,
2699 sizeof(struct GNUNET_HashCode), 4164 sizeof(struct GNUNET_HashCode),
2700 GNUNET_MESSAGE_TYPE_SETU_P2P_DEMAND); 4165 GNUNET_MESSAGE_TYPE_SETU_P2P_DEMAND);
@@ -2719,7 +4184,30 @@ handle_union_p2p_done (void *cls,
2719{ 4184{
2720 struct Operation *op = cls; 4185 struct Operation *op = cls;
2721 4186
2722 perf_rtt.done.received += 1; 4187 /**
4188 * Check that the message is received only in supported phase
4189 */
4190 uint8_t allowed_phases[] = {PHASE_ACTIVE_DECODING, PHASE_PASSIVE_DECODING};
4191 if (GNUNET_OK !=
4192 check_valid_phase (allowed_phases,sizeof(allowed_phases),op))
4193 {
4194 GNUNET_break (0);
4195 fail_union_operation (op);
4196 return;
4197 }
4198
4199 if (op->active_passive_switch_required)
4200 {
4201 LOG (GNUNET_ERROR_TYPE_ERROR,
4202 "PROTOCOL VIOLATION: Received done but role change is necessary\n");
4203 GNUNET_break (0);
4204 fail_union_operation (op);
4205 return;
4206 }
4207
4208#if MEASURE_PERFORMANCE
4209 perf_store.done.received += 1;
4210#endif
2723 switch (op->phase) 4211 switch (op->phase)
2724 { 4212 {
2725 case PHASE_PASSIVE_DECODING: 4213 case PHASE_PASSIVE_DECODING:
@@ -2728,26 +4216,26 @@ handle_union_p2p_done (void *cls,
2728 LOG (GNUNET_ERROR_TYPE_DEBUG, 4216 LOG (GNUNET_ERROR_TYPE_DEBUG,
2729 "got DONE (as passive partner), waiting for our demands to be satisfied\n"); 4217 "got DONE (as passive partner), waiting for our demands to be satisfied\n");
2730 /* The active peer is done sending offers 4218 /* The active peer is done sending offers
2731 * and inquiries. This means that all 4219 * and inquiries. This means that all
2732 * our responses to that (demands and offers) 4220 * our responses to that (demands and offers)
2733 * must be in flight (queued or in mesh). 4221 * must be in flight (queued or in mesh).
2734 * 4222 *
2735 * We should notify the active peer once 4223 * We should notify the active peer once
2736 * all our demands are satisfied, so that the active 4224 * all our demands are satisfied, so that the active
2737 * peer can quit if we gave it everything. 4225 * peer can quit if we gave it everything.
2738 */GNUNET_CADET_receive_done (op->channel); 4226 */GNUNET_CADET_receive_done (op->channel);
2739 maybe_finish (op); 4227 maybe_finish (op);
2740 return; 4228 return;
2741 case PHASE_ACTIVE_DECODING: 4229 case PHASE_ACTIVE_DECODING:
2742 LOG (GNUNET_ERROR_TYPE_DEBUG, 4230 LOG (GNUNET_ERROR_TYPE_DEBUG,
2743 "got DONE (as active partner), waiting to finish\n"); 4231 "got DONE (as active partner), waiting to finish\n");
2744 /* All demands of the other peer are satisfied, 4232 /* All demands of the other peer are satisfied,
2745 * and we processed all offers, thus we know 4233 * and we processed all offers, thus we know
2746 * exactly what our demands must be. 4234 * exactly what our demands must be.
2747 * 4235 *
2748 * We'll close the channel 4236 * We'll close the channel
2749 * to the other peer once our demands are met. 4237 * to the other peer once our demands are met.
2750 */op->phase = PHASE_FINISH_CLOSING; 4238 */op->phase = PHASE_FINISH_CLOSING;
2751 GNUNET_CADET_receive_done (op->channel); 4239 GNUNET_CADET_receive_done (op->channel);
2752 maybe_finish (op); 4240 maybe_finish (op);
2753 return; 4241 return;
@@ -2769,7 +4257,9 @@ static void
2769handle_union_p2p_over (void *cls, 4257handle_union_p2p_over (void *cls,
2770 const struct GNUNET_MessageHeader *mh) 4258 const struct GNUNET_MessageHeader *mh)
2771{ 4259{
2772 perf_rtt.over.received += 1; 4260#if MEASURE_PERFORMANCE
4261 perf_store.over.received += 1;
4262#endif
2773 send_client_done (cls); 4263 send_client_done (cls);
2774} 4264}
2775 4265
@@ -2943,7 +4433,7 @@ check_incoming_msg (void *cls,
2943 struct Listener *listener = op->listener; 4433 struct Listener *listener = op->listener;
2944 const struct GNUNET_MessageHeader *nested_context; 4434 const struct GNUNET_MessageHeader *nested_context;
2945 4435
2946 /* double operation request */ 4436 /* double operation request */
2947 if (0 != op->suggest_id) 4437 if (0 != op->suggest_id)
2948 { 4438 {
2949 GNUNET_break_op (0); 4439 GNUNET_break_op (0);
@@ -3053,10 +4543,10 @@ handle_client_create_set (void *cls,
3053 } 4543 }
3054 set = GNUNET_new (struct Set); 4544 set = GNUNET_new (struct Set);
3055 { 4545 {
3056 struct StrataEstimator *se; 4546 struct MultiStrataEstimator *se;
3057 4547
3058 se = strata_estimator_create (SE_STRATA_COUNT, 4548 se = strata_estimator_create (SE_STRATA_COUNT,
3059 SE_IBF_SIZE, 4549 SE_IBFS_TOTAL_SIZE,
3060 SE_IBF_HASH_NUM); 4550 SE_IBF_HASH_NUM);
3061 if (NULL == se) 4551 if (NULL == se)
3062 { 4552 {
@@ -3198,6 +4688,7 @@ channel_window_cb (void *cls,
3198 * @param cls client that sent the message 4688 * @param cls client that sent the message
3199 * @param msg message sent by the client 4689 * @param msg message sent by the client
3200 */ 4690 */
4691
3201static void 4692static void
3202handle_client_listen (void *cls, 4693handle_client_listen (void *cls,
3203 const struct GNUNET_SETU_ListenMessage *msg) 4694 const struct GNUNET_SETU_ListenMessage *msg)
@@ -3240,10 +4731,10 @@ handle_client_listen (void *cls,
3240 GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE, 4731 GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE,
3241 struct GNUNET_MessageHeader, 4732 struct GNUNET_MessageHeader,
3242 NULL), 4733 NULL),
3243 GNUNET_MQ_hd_fixed_size (union_p2p_request_full, 4734 GNUNET_MQ_hd_var_size (union_p2p_request_full,
3244 GNUNET_MESSAGE_TYPE_SETU_P2P_REQUEST_FULL, 4735 GNUNET_MESSAGE_TYPE_SETU_P2P_REQUEST_FULL,
3245 struct GNUNET_MessageHeader, 4736 struct TransmitFullMessage,
3246 NULL), 4737 NULL),
3247 GNUNET_MQ_hd_var_size (union_p2p_strata_estimator, 4738 GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
3248 GNUNET_MESSAGE_TYPE_SETU_P2P_SE, 4739 GNUNET_MESSAGE_TYPE_SETU_P2P_SE,
3249 struct StrataEstimatorMessage, 4740 struct StrataEstimatorMessage,
@@ -3256,6 +4747,10 @@ handle_client_listen (void *cls,
3256 GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT, 4747 GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT,
3257 struct GNUNET_SETU_ElementMessage, 4748 struct GNUNET_SETU_ElementMessage,
3258 NULL), 4749 NULL),
4750 GNUNET_MQ_hd_var_size (union_p2p_send_full,
4751 GNUNET_MESSAGE_TYPE_SETU_P2P_SEND_FULL,
4752 struct TransmitFullMessage,
4753 NULL),
3259 GNUNET_MQ_handler_end () 4754 GNUNET_MQ_handler_end ()
3260 }; 4755 };
3261 struct Listener *listener; 4756 struct Listener *listener;
@@ -3451,6 +4946,7 @@ handle_client_evaluate (void *cls,
3451{ 4946{
3452 struct ClientState *cs = cls; 4947 struct ClientState *cs = cls;
3453 struct Operation *op = GNUNET_new (struct Operation); 4948 struct Operation *op = GNUNET_new (struct Operation);
4949
3454 const struct GNUNET_MQ_MessageHandler cadet_handlers[] = { 4950 const struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
3455 GNUNET_MQ_hd_var_size (incoming_msg, 4951 GNUNET_MQ_hd_var_size (incoming_msg,
3456 GNUNET_MESSAGE_TYPE_SETU_P2P_OPERATION_REQUEST, 4952 GNUNET_MESSAGE_TYPE_SETU_P2P_OPERATION_REQUEST,
@@ -3488,10 +4984,10 @@ handle_client_evaluate (void *cls,
3488 GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE, 4984 GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE,
3489 struct GNUNET_MessageHeader, 4985 struct GNUNET_MessageHeader,
3490 op), 4986 op),
3491 GNUNET_MQ_hd_fixed_size (union_p2p_request_full, 4987 GNUNET_MQ_hd_var_size (union_p2p_request_full,
3492 GNUNET_MESSAGE_TYPE_SETU_P2P_REQUEST_FULL, 4988 GNUNET_MESSAGE_TYPE_SETU_P2P_REQUEST_FULL,
3493 struct GNUNET_MessageHeader, 4989 struct TransmitFullMessage,
3494 op), 4990 op),
3495 GNUNET_MQ_hd_var_size (union_p2p_strata_estimator, 4991 GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
3496 GNUNET_MESSAGE_TYPE_SETU_P2P_SE, 4992 GNUNET_MESSAGE_TYPE_SETU_P2P_SE,
3497 struct StrataEstimatorMessage, 4993 struct StrataEstimatorMessage,
@@ -3504,6 +5000,10 @@ handle_client_evaluate (void *cls,
3504 GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT, 5000 GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT,
3505 struct GNUNET_SETU_ElementMessage, 5001 struct GNUNET_SETU_ElementMessage,
3506 op), 5002 op),
5003 GNUNET_MQ_hd_var_size (union_p2p_send_full,
5004 GNUNET_MESSAGE_TYPE_SETU_P2P_SEND_FULL,
5005 struct TransmitFullMessage,
5006 NULL),
3507 GNUNET_MQ_handler_end () 5007 GNUNET_MQ_handler_end ()
3508 }; 5008 };
3509 struct Set *set; 5009 struct Set *set;
@@ -3525,8 +5025,23 @@ handle_client_evaluate (void *cls,
3525 op->force_full = msg->force_full; 5025 op->force_full = msg->force_full;
3526 op->force_delta = msg->force_delta; 5026 op->force_delta = msg->force_delta;
3527 op->symmetric = msg->symmetric; 5027 op->symmetric = msg->symmetric;
5028 op->rtt_bandwidth_tradeoff = msg->bandwidth_latency_tradeoff;
5029 op->ibf_bucket_number_factor = msg->ibf_bucket_number_factor;
5030 op->ibf_number_buckets_per_element = msg->ibf_number_of_buckets_per_element;
5031 op->byzantine_upper_bound = msg->byzantine_upper_bond;
5032 op->active_passive_switch_required = false;
3528 context = GNUNET_MQ_extract_nested_mh (msg); 5033 context = GNUNET_MQ_extract_nested_mh (msg);
3529 5034
5035 /* create hashmap for message control */
5036 op->message_control_flow = GNUNET_CONTAINER_multihashmap_create (32,
5037 GNUNET_NO);
5038 op->inquiries_sent = GNUNET_CONTAINER_multihashmap_create (32,GNUNET_NO);
5039
5040#if MEASURE_PERFORMANCE
5041 /* load config */
5042 load_config (op);
5043#endif
5044
3530 /* Advance generation values, so that 5045 /* Advance generation values, so that
3531 mutations won't interfer with the running operation. */ 5046 mutations won't interfer with the running operation. */
3532 op->set = set; 5047 op->set = set;
@@ -3550,7 +5065,9 @@ handle_client_evaluate (void *cls,
3550 struct GNUNET_MQ_Envelope *ev; 5065 struct GNUNET_MQ_Envelope *ev;
3551 struct OperationRequestMessage *msg; 5066 struct OperationRequestMessage *msg;
3552 5067
3553 perf_rtt.operation_request.sent += 1; 5068#if MEASURE_PERFORMANCE
5069 perf_store.operation_request.sent += 1;
5070#endif
3554 ev = GNUNET_MQ_msg_nested_mh (msg, 5071 ev = GNUNET_MQ_msg_nested_mh (msg,
3555 GNUNET_MESSAGE_TYPE_SETU_P2P_OPERATION_REQUEST, 5072 GNUNET_MESSAGE_TYPE_SETU_P2P_OPERATION_REQUEST,
3556 context); 5073 context);
@@ -3567,7 +5084,11 @@ handle_client_evaluate (void *cls,
3567 op->se = strata_estimator_dup (op->set->se); 5084 op->se = strata_estimator_dup (op->set->se);
3568 /* we started the operation, thus we have to send the operation request */ 5085 /* we started the operation, thus we have to send the operation request */
3569 op->phase = PHASE_EXPECT_SE; 5086 op->phase = PHASE_EXPECT_SE;
3570 op->salt_receive = op->salt_send = 42; // FIXME????? 5087
5088 op->salt_receive = (op->peer_site + 1) % 2;
5089 op->salt_send = op->peer_site; // FIXME?????
5090
5091
3571 LOG (GNUNET_ERROR_TYPE_DEBUG, 5092 LOG (GNUNET_ERROR_TYPE_DEBUG,
3572 "Initiating union operation evaluation\n"); 5093 "Initiating union operation evaluation\n");
3573 GNUNET_STATISTICS_update (_GSS_statistics, 5094 GNUNET_STATISTICS_update (_GSS_statistics,
@@ -3711,6 +5232,20 @@ handle_client_accept (void *cls,
3711 op->force_full = msg->force_full; 5232 op->force_full = msg->force_full;
3712 op->force_delta = msg->force_delta; 5233 op->force_delta = msg->force_delta;
3713 op->symmetric = msg->symmetric; 5234 op->symmetric = msg->symmetric;
5235 op->rtt_bandwidth_tradeoff = msg->bandwidth_latency_tradeoff;
5236 op->ibf_bucket_number_factor = msg->ibf_bucket_number_factor;
5237 op->ibf_number_buckets_per_element = msg->ibf_number_of_buckets_per_element;
5238 op->byzantine_upper_bound = msg->byzantine_upper_bond;
5239 op->active_passive_switch_required = false;
5240 /* create hashmap for message control */
5241 op->message_control_flow = GNUNET_CONTAINER_multihashmap_create (32,
5242 GNUNET_NO);
5243 op->inquiries_sent = GNUNET_CONTAINER_multihashmap_create (32,GNUNET_NO);
5244
5245#if MEASURE_PERFORMANCE
5246 /* load config */
5247 load_config (op);
5248#endif
3714 5249
3715 /* Advance generation values, so that future mutations do not 5250 /* Advance generation values, so that future mutations do not
3716 interfer with the running operation. */ 5251 interfer with the running operation. */
@@ -3729,7 +5264,7 @@ handle_client_accept (void *cls,
3729 1, 5264 1,
3730 GNUNET_NO); 5265 GNUNET_NO);
3731 { 5266 {
3732 const struct StrataEstimator *se; 5267 struct MultiStrataEstimator *se;
3733 struct GNUNET_MQ_Envelope *ev; 5268 struct GNUNET_MQ_Envelope *ev;
3734 struct StrataEstimatorMessage *strata_msg; 5269 struct StrataEstimatorMessage *strata_msg;
3735 char *buf; 5270 char *buf;
@@ -3739,20 +5274,40 @@ handle_client_accept (void *cls,
3739 op->se = strata_estimator_dup (op->set->se); 5274 op->se = strata_estimator_dup (op->set->se);
3740 op->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32, 5275 op->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32,
3741 GNUNET_NO); 5276 GNUNET_NO);
3742 op->salt_receive = op->salt_send = 42; // FIXME????? 5277 op->salt_receive = (op->peer_site + 1) % 2;
5278 op->salt_send = op->peer_site; // FIXME?????
3743 initialize_key_to_element (op); 5279 initialize_key_to_element (op);
3744 op->initial_size = GNUNET_CONTAINER_multihashmap32_size ( 5280 op->initial_size = GNUNET_CONTAINER_multihashmap32_size (
3745 op->key_to_element); 5281 op->key_to_element);
3746 5282
3747 /* kick off the operation */ 5283 /* kick off the operation */
3748 se = op->se; 5284 se = op->se;
3749 buf = GNUNET_malloc (se->strata_count * IBF_BUCKET_SIZE * se->ibf_size); 5285
5286 uint8_t se_count = 1;
5287 if (op->initial_size > 0)
5288 {
5289 op->total_elements_size_local = 0;
5290 GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
5291 &
5292 determinate_avg_element_size_iterator,
5293 op);
5294 se_count = determine_strata_count (
5295 op->total_elements_size_local / op->initial_size,
5296 op->initial_size);
5297 }
5298 buf = GNUNET_malloc (se->stratas[0]->strata_count * IBF_BUCKET_SIZE
5299 * ((SE_IBFS_TOTAL_SIZE / 8) * se_count));
3750 len = strata_estimator_write (se, 5300 len = strata_estimator_write (se,
5301 SE_IBFS_TOTAL_SIZE,
5302 se_count,
3751 buf); 5303 buf);
3752 perf_rtt.se.sent += 1; 5304#if MEASURE_PERFORMANCE
3753 perf_rtt.se.sent_var_bytes += len; 5305 perf_store.se.sent += 1;
5306 perf_store.se.sent_var_bytes += len;
5307#endif
3754 5308
3755 if (len < se->strata_count * IBF_BUCKET_SIZE * se->ibf_size) 5309 if (len < se->stratas[0]->strata_count * IBF_BUCKET_SIZE
5310 * SE_IBFS_TOTAL_SIZE)
3756 type = GNUNET_MESSAGE_TYPE_SETU_P2P_SEC; 5311 type = GNUNET_MESSAGE_TYPE_SETU_P2P_SEC;
3757 else 5312 else
3758 type = GNUNET_MESSAGE_TYPE_SETU_P2P_SE; 5313 type = GNUNET_MESSAGE_TYPE_SETU_P2P_SE;
@@ -3766,6 +5321,7 @@ handle_client_accept (void *cls,
3766 strata_msg->set_size 5321 strata_msg->set_size
3767 = GNUNET_htonll (GNUNET_CONTAINER_multihashmap_size ( 5322 = GNUNET_htonll (GNUNET_CONTAINER_multihashmap_size (
3768 op->set->content->elements)); 5323 op->set->content->elements));
5324 strata_msg->se_count = se_count;
3769 GNUNET_MQ_send (op->mq, 5325 GNUNET_MQ_send (op->mq,
3770 ev); 5326 ev);
3771 op->phase = PHASE_EXPECT_IBF; 5327 op->phase = PHASE_EXPECT_IBF;
@@ -3800,8 +5356,9 @@ shutdown_task (void *cls)
3800 GNUNET_YES); 5356 GNUNET_YES);
3801 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5357 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3802 "handled shutdown request\n"); 5358 "handled shutdown request\n");
3803 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 5359#if MEASURE_PERFORMANCE
3804 "RTT:%f\n", calculate_perf_rtt()); 5360 calculate_perf_store ();
5361#endif
3805} 5362}
3806 5363
3807 5364
diff --git a/src/setu/gnunet-service-setu_protocol.h b/src/setu/gnunet-service-setu_protocol.h
index a2803ee47..c2a166e60 100644
--- a/src/setu/gnunet-service-setu_protocol.h
+++ b/src/setu/gnunet-service-setu_protocol.h
@@ -40,11 +40,6 @@ struct OperationRequestMessage
40 struct GNUNET_MessageHeader header; 40 struct GNUNET_MessageHeader header;
41 41
42 /** 42 /**
43 * Operation to request, values from `enum GNUNET_SET_OperationType`
44 */
45 uint32_t operation GNUNET_PACKED;
46
47 /**
48 * For Intersection: my element count 43 * For Intersection: my element count
49 */ 44 */
50 uint32_t element_count GNUNET_PACKED; 45 uint32_t element_count GNUNET_PACKED;
@@ -72,20 +67,9 @@ struct IBFMessage
72 struct GNUNET_MessageHeader header; 67 struct GNUNET_MessageHeader header;
73 68
74 /** 69 /**
75 * Order of the whole ibf, where 70 * Size of the whole ibf (number of buckets)
76 * num_buckets = 2^order
77 */
78 uint8_t order;
79
80 /**
81 * Padding, must be 0.
82 */ 71 */
83 uint8_t reserved1; 72 uint32_t ibf_size;
84
85 /**
86 * Padding, must be 0.
87 */
88 uint16_t reserved2 GNUNET_PACKED;
89 73
90 /** 74 /**
91 * Offset of the strata in the rest of the message 75 * Offset of the strata in the rest of the message
@@ -95,12 +79,25 @@ struct IBFMessage
95 /** 79 /**
96 * Salt used when hashing elements for this IBF. 80 * Salt used when hashing elements for this IBF.
97 */ 81 */
98 uint32_t salt GNUNET_PACKED; 82 uint16_t salt GNUNET_PACKED;
99 83
84 /**
85 * The bit length of the counter
86 */
87 uint16_t ibf_counter_bit_length;
100 /* rest: buckets */ 88 /* rest: buckets */
101}; 89};
102 90
103 91
92/**
93estimate_best_mode_of_operation (uint64_t avg_element_size,
94uint64_t local_set_size,
95 uint64_t remote_set_size,
96uint64_t est_set_diff_remote,
97 uint64_t est_set_diff_local,)
98 **/
99
100
104struct InquiryMessage 101struct InquiryMessage
105{ 102{
106 /** 103 /**
@@ -113,11 +110,6 @@ struct InquiryMessage
113 */ 110 */
114 uint32_t salt GNUNET_PACKED; 111 uint32_t salt GNUNET_PACKED;
115 112
116 /**
117 * Reserved, set to 0.
118 */
119 uint32_t reserved GNUNET_PACKED;
120
121 /* rest: inquiry IBF keys */ 113 /* rest: inquiry IBF keys */
122}; 114};
123 115
@@ -218,9 +210,47 @@ struct StrataEstimatorMessage
218 */ 210 */
219 struct GNUNET_MessageHeader header; 211 struct GNUNET_MessageHeader header;
220 212
213 /**
214 * The number of ses transmitted
215 */
216 uint8_t se_count;
217
218 /**
219 * Size of the local set
220 */
221 uint64_t set_size; 221 uint64_t set_size;
222}; 222};
223 223
224
225/**
226 * Message which signals to other peer that we are sending full set
227 *
228 */
229struct TransmitFullMessage
230{
231 /**
232 * Type: #GNUNET_MESSAGE_TYPE_SETU_P2P_SEND_FULL
233 */
234 struct GNUNET_MessageHeader header;
235
236 /**
237 * Remote set difference calculated with strata estimator
238 */
239 uint32_t remote_set_difference;
240
241 /**
242 * Total remote set size
243 */
244 uint32_t remote_set_size;
245
246 /**
247 * Local set difference calculated with strata estimator
248 */
249 uint32_t local_set_difference;
250
251};
252
253
224GNUNET_NETWORK_STRUCT_END 254GNUNET_NETWORK_STRUCT_END
225 255
226#endif 256#endif
diff --git a/src/setu/gnunet-service-setu_strata_estimator.c b/src/setu/gnunet-service-setu_strata_estimator.c
index 7c9a4deb6..7981cc847 100644
--- a/src/setu/gnunet-service-setu_strata_estimator.c
+++ b/src/setu/gnunet-service-setu_strata_estimator.c
@@ -22,6 +22,7 @@
22 * @brief invertible bloom filter 22 * @brief invertible bloom filter
23 * @author Florian Dold 23 * @author Florian Dold
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Elias Summermatter
25 */ 26 */
26#include "platform.h" 27#include "platform.h"
27#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
@@ -30,6 +31,82 @@
30 31
31 32
32/** 33/**
34 * Should we try compressing the strata estimator? This will
35 * break compatibility with the 0.10.1-network.
36 */
37#define FAIL_10_1_COMPATIBILTIY 1
38
39/**
40 * Number of strata estimators in memory NOT transmitted
41 */
42
43#define MULTI_SE_BASE_COUNT 8
44
45/**
46 * The avg size of 1 se
47 * Based on the bsc thesis of Elias Summermatter (2021)
48 */
49
50#define AVG_BYTE_SIZE_SE 4221
51
52/**
53 * Calculates the optimal number of strata Estimators to send
54 * @param avg_element_size
55 * @param element_count
56 * @return
57 */
58uint8_t
59determine_strata_count (uint64_t avg_element_size, uint64_t element_count)
60{
61 uint64_t base_size = avg_element_size * element_count;
62 /* >67kb total size of elements in set */
63 if (base_size < AVG_BYTE_SIZE_SE * 16)
64 return 1;
65 /* >270kb total size of elements in set */
66 if (base_size < AVG_BYTE_SIZE_SE * 64)
67 return 2;
68 /* >1mb total size of elements in set */
69 if (base_size < AVG_BYTE_SIZE_SE * 256)
70 return 4;
71 return 8;
72}
73
74
75/**
76 * Modify an IBF key @a k_in based on the @a salt, returning a
77 * salted key in @a k_out.
78 */
79static void
80salt_key (const struct IBF_Key *k_in,
81 uint32_t salt,
82 struct IBF_Key *k_out)
83{
84 int s = (salt * 7) % 64;
85 uint64_t x = k_in->key_val;
86
87 /* rotate ibf key */
88 x = (x >> s) | (x << (64 - s));
89 k_out->key_val = x;
90}
91
92
93/**
94 * Reverse modification done in the salt_key function
95 */
96static void
97unsalt_key (const struct IBF_Key *k_in,
98 uint32_t salt,
99 struct IBF_Key *k_out)
100{
101 int s = (salt * 7) % 64;
102 uint64_t x = k_in->key_val;
103
104 x = (x << s) | (x >> (64 - s));
105 k_out->key_val = x;
106}
107
108
109/**
33 * Write the given strata estimator to the buffer. 110 * Write the given strata estimator to the buffer.
34 * 111 *
35 * @param se strata estimator to serialize 112 * @param se strata estimator to serialize
@@ -37,21 +114,33 @@
37 * @return number of bytes written to @a buf 114 * @return number of bytes written to @a buf
38 */ 115 */
39size_t 116size_t
40strata_estimator_write (const struct StrataEstimator *se, 117strata_estimator_write (struct MultiStrataEstimator *se,
118 uint16_t se_ibf_total_size,
119 uint8_t number_se_send,
41 void *buf) 120 void *buf)
42{ 121{
43 char *sbuf = buf; 122 char *sbuf = buf;
123 unsigned int i;
44 size_t osize; 124 size_t osize;
125 uint64_t sbuf_offset = 0;
126 se->size = number_se_send;
45 127
46 GNUNET_assert (NULL != se); 128 GNUNET_assert (NULL != se);
47 for (unsigned int i = 0; i < se->strata_count; i++) 129 for (uint8_t strata_ctr = 0; strata_ctr < number_se_send; strata_ctr++)
48 { 130 {
49 ibf_write_slice (se->strata[i], 131 for (i = 0; i < se->stratas[strata_ctr]->strata_count; i++)
50 0, 132 {
51 se->ibf_size, 133 ibf_write_slice (se->stratas[strata_ctr]->strata[i],
52 &sbuf[se->ibf_size * IBF_BUCKET_SIZE * i]); 134 0,
135 se->stratas[strata_ctr]->ibf_size,
136 &sbuf[sbuf_offset],
137 8);
138 sbuf_offset += se->stratas[strata_ctr]->ibf_size * IBF_BUCKET_SIZE;
139 }
53 } 140 }
54 osize = se->ibf_size * IBF_BUCKET_SIZE * se->strata_count; 141 osize = ((se_ibf_total_size / 8) * number_se_send) * IBF_BUCKET_SIZE
142 * se->stratas[0]->strata_count;
143#if FAIL_10_1_COMPATIBILTIY
55 { 144 {
56 char *cbuf; 145 char *cbuf;
57 size_t nsize; 146 size_t nsize;
@@ -62,13 +151,12 @@ strata_estimator_write (const struct StrataEstimator *se,
62 &cbuf, 151 &cbuf,
63 &nsize)) 152 &nsize))
64 { 153 {
65 GNUNET_memcpy (buf, 154 GNUNET_memcpy (buf, cbuf, nsize);
66 cbuf,
67 nsize);
68 osize = nsize; 155 osize = nsize;
69 GNUNET_free (cbuf); 156 GNUNET_free (cbuf);
70 } 157 }
71 } 158 }
159#endif
72 return osize; 160 return osize;
73} 161}
74 162
@@ -87,15 +175,19 @@ int
87strata_estimator_read (const void *buf, 175strata_estimator_read (const void *buf,
88 size_t buf_len, 176 size_t buf_len,
89 int is_compressed, 177 int is_compressed,
90 struct StrataEstimator *se) 178 uint8_t number_se_received,
179 uint16_t se_ibf_total_size,
180 struct MultiStrataEstimator *se)
91{ 181{
182 unsigned int i;
92 size_t osize; 183 size_t osize;
93 char *dbuf; 184 char *dbuf;
94 185
95 dbuf = NULL; 186 dbuf = NULL;
96 if (GNUNET_YES == is_compressed) 187 if (GNUNET_YES == is_compressed)
97 { 188 {
98 osize = se->ibf_size * IBF_BUCKET_SIZE * se->strata_count; 189 osize = ((se_ibf_total_size / 8) * number_se_received) * IBF_BUCKET_SIZE
190 * se->stratas[0]->strata_count;
99 dbuf = GNUNET_decompress (buf, 191 dbuf = GNUNET_decompress (buf,
100 buf_len, 192 buf_len,
101 osize); 193 osize);
@@ -108,18 +200,25 @@ strata_estimator_read (const void *buf,
108 buf_len = osize; 200 buf_len = osize;
109 } 201 }
110 202
111 if (buf_len != se->strata_count * se->ibf_size * IBF_BUCKET_SIZE) 203 if (buf_len != se->stratas[0]->strata_count * ((se_ibf_total_size / 8)
204 * number_se_received)
205 * IBF_BUCKET_SIZE)
112 { 206 {
113 GNUNET_break (0); /* very odd error */ 207 GNUNET_break (0); /* very odd error */
114 GNUNET_free (dbuf); 208 GNUNET_free (dbuf);
115 return GNUNET_SYSERR; 209 return GNUNET_SYSERR;
116 } 210 }
117 211
118 for (unsigned int i = 0; i < se->strata_count; i++) 212 for (uint8_t strata_ctr = 0; strata_ctr < number_se_received; strata_ctr++)
119 { 213 {
120 ibf_read_slice (buf, 0, se->ibf_size, se->strata[i]); 214 for (i = 0; i < se->stratas[strata_ctr]->strata_count; i++)
121 buf += se->ibf_size * IBF_BUCKET_SIZE; 215 {
216 ibf_read_slice (buf, 0, se->stratas[strata_ctr]->ibf_size,
217 se->stratas[strata_ctr]->strata[i], 8);
218 buf += se->stratas[strata_ctr]->ibf_size * IBF_BUCKET_SIZE;
219 }
122 } 220 }
221 se->size = number_se_received;
123 GNUNET_free (dbuf); 222 GNUNET_free (dbuf);
124 return GNUNET_OK; 223 return GNUNET_OK;
125} 224}
@@ -132,38 +231,61 @@ strata_estimator_read (const void *buf,
132 * @param key key to add 231 * @param key key to add
133 */ 232 */
134void 233void
135strata_estimator_insert (struct StrataEstimator *se, 234strata_estimator_insert (struct MultiStrataEstimator *se,
136 struct IBF_Key key) 235 struct IBF_Key key)
137{ 236{
138 uint64_t v;
139 unsigned int i;
140 237
141 v = key.key_val; 238
142 /* count trailing '1'-bits of v */ 239 /* count trailing '1'-bits of v */
143 for (i = 0; v & 1; v >>= 1, i++) 240 for (int strata_ctr = 0; strata_ctr < MULTI_SE_BASE_COUNT; strata_ctr++)
144 /* empty */; 241 {
145 ibf_insert (se->strata[i], key); 242 unsigned int i;
243 uint64_t v;
244
245 struct IBF_Key salted_key;
246 salt_key (&key,
247 strata_ctr * (64 / MULTI_SE_BASE_COUNT),
248 &salted_key);
249 v = salted_key.key_val;
250 for (i = 0; v & 1; v >>= 1, i++)
251 {
252 ibf_insert (se->stratas[strata_ctr]->strata[i], salted_key);
253 }
254 }
255 /* empty */;
256
146} 257}
147 258
148 259
149/** 260/**
150 * Remove a key from the strata estimator. 261 * Remove a key from the strata estimator. (NOT USED)
151 * 262 *
152 * @param se strata estimator to remove the key from 263 * @param se strata estimator to remove the key from
153 * @param key key to remove 264 * @param key key to remove
154 */ 265 */
155void 266void
156strata_estimator_remove (struct StrataEstimator *se, 267strata_estimator_remove (struct MultiStrataEstimator *se,
157 struct IBF_Key key) 268 struct IBF_Key key)
158{ 269{
159 uint64_t v;
160 unsigned int i;
161 270
162 v = key.key_val;
163 /* count trailing '1'-bits of v */ 271 /* count trailing '1'-bits of v */
164 for (i = 0; v & 1; v >>= 1, i++) 272 for (int strata_ctr = 0; strata_ctr < se->size; strata_ctr++)
165 /* empty */; 273 {
166 ibf_remove (se->strata[i], key); 274 uint64_t v;
275 unsigned int i;
276
277 struct IBF_Key unsalted_key;
278 unsalt_key (&key,
279 strata_ctr * (64 / MULTI_SE_BASE_COUNT),
280 &unsalted_key);
281
282 v = unsalted_key.key_val;
283 for (i = 0; v & 1; v >>= 1, i++)
284 {
285 /* empty */;
286 ibf_remove (se->stratas[strata_ctr]->strata[i], unsalted_key);
287 }
288 }
167} 289}
168 290
169 291
@@ -175,29 +297,42 @@ strata_estimator_remove (struct StrataEstimator *se,
175 * @param ibf_hashnum hashnum parameter of each ibf 297 * @param ibf_hashnum hashnum parameter of each ibf
176 * @return a freshly allocated, empty strata estimator, NULL on error 298 * @return a freshly allocated, empty strata estimator, NULL on error
177 */ 299 */
178struct StrataEstimator * 300struct MultiStrataEstimator *
179strata_estimator_create (unsigned int strata_count, 301strata_estimator_create (unsigned int strata_count,
180 uint32_t ibf_size, 302 uint32_t ibf_size,
181 uint8_t ibf_hashnum) 303 uint8_t ibf_hashnum)
182{ 304{
183 struct StrataEstimator *se; 305 struct MultiStrataEstimator *se;
184 306 unsigned int i;
185 se = GNUNET_new (struct StrataEstimator); 307 unsigned int j;
186 se->strata_count = strata_count; 308 se = GNUNET_new (struct MultiStrataEstimator);
187 se->ibf_size = ibf_size; 309
188 se->strata = GNUNET_new_array (strata_count, 310 se->size = MULTI_SE_BASE_COUNT;
189 struct InvertibleBloomFilter *); 311 se->stratas = GNUNET_new_array (MULTI_SE_BASE_COUNT,struct StrataEstimator *);
190 for (unsigned int i = 0; i < strata_count; i++) 312
313 uint8_t ibf_prime_sizes[] = {79,79,79,79,79,79,79,79};
314
315 for (uint8_t strata_ctr = 0; strata_ctr < MULTI_SE_BASE_COUNT; strata_ctr++)
191 { 316 {
192 se->strata[i] = ibf_create (ibf_size, ibf_hashnum); 317 se->stratas[strata_ctr] = GNUNET_new (struct StrataEstimator);
193 if (NULL == se->strata[i]) 318 se->stratas[strata_ctr]->strata_count = strata_count;
319 se->stratas[strata_ctr]->ibf_size = ibf_prime_sizes[strata_ctr];
320 se->stratas[strata_ctr]->strata = GNUNET_new_array (strata_count * 4,
321 struct
322 InvertibleBloomFilter *);
323 for (i = 0; i < strata_count; i++)
194 { 324 {
195 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 325 se->stratas[strata_ctr]->strata[i] = ibf_create (
196 "Failed to allocate memory for strata estimator\n"); 326 ibf_prime_sizes[strata_ctr], ibf_hashnum);
197 for (unsigned int j = 0; j < i; j++) 327 if (NULL == se->stratas[strata_ctr]->strata[i])
198 ibf_destroy (se->strata[i]); 328 {
199 GNUNET_free (se); 329 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
200 return NULL; 330 "Failed to allocate memory for strata estimator\n");
331 for (j = 0; j < i; j++)
332 ibf_destroy (se->stratas[strata_ctr]->strata[i]);
333 GNUNET_free (se);
334 return NULL;
335 }
201 } 336 }
202 } 337 }
203 return se; 338 return se;
@@ -213,46 +348,71 @@ strata_estimator_create (unsigned int strata_count,
213 * @param se2 second strata estimator 348 * @param se2 second strata estimator
214 * @return the estimated difference 349 * @return the estimated difference
215 */ 350 */
216unsigned int 351void
217strata_estimator_difference (const struct StrataEstimator *se1, 352strata_estimator_difference (const struct MultiStrataEstimator *se1,
218 const struct StrataEstimator *se2) 353 const struct MultiStrataEstimator *se2)
219{ 354{
220 unsigned int count; 355 int avg_local_diff = 0;
356 int avg_remote_diff = 0;
357 uint8_t number_of_estimators = se1->size;
221 358
222 GNUNET_assert (se1->strata_count == se2->strata_count); 359 for (uint8_t strata_ctr = 0; strata_ctr < number_of_estimators; strata_ctr++)
223 count = 0;
224 for (int i = se1->strata_count - 1; i >= 0; i--)
225 { 360 {
226 struct InvertibleBloomFilter *diff; 361 GNUNET_assert (se1->stratas[strata_ctr]->strata_count ==
227 /* number of keys decoded from the ibf */ 362 se2->stratas[strata_ctr]->strata_count);
228 363
229 /* FIXME: implement this without always allocating new IBFs */ 364
230 diff = ibf_dup (se1->strata[i]); 365 for (int i = se1->stratas[strata_ctr]->strata_count - 1; i >= 0; i--)
231 ibf_subtract (diff,
232 se2->strata[i]);
233 for (int ibf_count = 0; GNUNET_YES; ibf_count++)
234 { 366 {
235 int more; 367 struct InvertibleBloomFilter *diff;
368 /* number of keys decoded from the ibf */
236 369
237 more = ibf_decode (diff, 370 /* FIXME: implement this without always allocating new IBFs */
238 NULL, 371 diff = ibf_dup (se1->stratas[strata_ctr]->strata[i]);
239 NULL); 372 diff->local_decoded_count = 0;
240 if (GNUNET_NO == more) 373 diff->remote_decoded_count = 0;
241 { 374
242 count += ibf_count; 375 ibf_subtract (diff, se2->stratas[strata_ctr]->strata[i]);
243 break; 376
244 } 377 for (int ibf_count = 0; GNUNET_YES; ibf_count++)
245 /* Estimate if decoding fails or would not terminate */
246 if ( (GNUNET_SYSERR == more) ||
247 (ibf_count > diff->size) )
248 { 378 {
249 ibf_destroy (diff); 379 int more;
250 return count * (1 << (i + 1)); 380
381 more = ibf_decode (diff, NULL, NULL);
382 if (GNUNET_NO == more)
383 {
384 se1->stratas[strata_ctr]->strata[0]->local_decoded_count +=
385 diff->local_decoded_count;
386 se1->stratas[strata_ctr]->strata[0]->remote_decoded_count +=
387 diff->remote_decoded_count;
388 break;
389 }
390 /* Estimate if decoding fails or would not terminate */
391 if ((GNUNET_SYSERR == more) || (ibf_count > diff->size))
392 {
393 se1->stratas[strata_ctr]->strata[0]->local_decoded_count =
394 se1->stratas[strata_ctr]->strata[0]->local_decoded_count * (1 << (i
395 +
396 1));
397 se1->stratas[strata_ctr]->strata[0]->remote_decoded_count =
398 se1->stratas[strata_ctr]->strata[0]->remote_decoded_count * (1 << (i
399 +
400 1));
401 ibf_destroy (diff);
402 goto break_all_counting_loops;
403 }
251 } 404 }
405 ibf_destroy (diff);
252 } 406 }
253 ibf_destroy (diff); 407break_all_counting_loops:;
408 avg_local_diff += se1->stratas[strata_ctr]->strata[0]->local_decoded_count;
409 avg_remote_diff +=
410 se1->stratas[strata_ctr]->strata[0]->remote_decoded_count;
254 } 411 }
255 return count; 412 se1->stratas[0]->strata[0]->local_decoded_count = avg_local_diff
413 / number_of_estimators;
414 se1->stratas[0]->strata[0]->remote_decoded_count = avg_remote_diff
415 / number_of_estimators;
256} 416}
257 417
258 418
@@ -262,18 +422,28 @@ strata_estimator_difference (const struct StrataEstimator *se1,
262 * @param se the strata estimator to copy 422 * @param se the strata estimator to copy
263 * @return the copy 423 * @return the copy
264 */ 424 */
265struct StrataEstimator * 425struct MultiStrataEstimator *
266strata_estimator_dup (struct StrataEstimator *se) 426strata_estimator_dup (struct MultiStrataEstimator *se)
267{ 427{
268 struct StrataEstimator *c; 428 struct MultiStrataEstimator *c;
269 429 unsigned int i;
270 c = GNUNET_new (struct StrataEstimator); 430
271 c->strata_count = se->strata_count; 431 c = GNUNET_new (struct MultiStrataEstimator);
272 c->ibf_size = se->ibf_size; 432 c->stratas = GNUNET_new_array (MULTI_SE_BASE_COUNT,struct StrataEstimator *);
273 c->strata = GNUNET_new_array (se->strata_count, 433 for (uint8_t strata_ctr = 0; strata_ctr < MULTI_SE_BASE_COUNT; strata_ctr++)
274 struct InvertibleBloomFilter *); 434 {
275 for (unsigned int i = 0; i < se->strata_count; i++) 435 c->stratas[strata_ctr] = GNUNET_new (struct StrataEstimator);
276 c->strata[i] = ibf_dup (se->strata[i]); 436 c->stratas[strata_ctr]->strata_count =
437 se->stratas[strata_ctr]->strata_count;
438 c->stratas[strata_ctr]->ibf_size = se->stratas[strata_ctr]->ibf_size;
439 c->stratas[strata_ctr]->strata = GNUNET_new_array (
440 se->stratas[strata_ctr]->strata_count,
441 struct
442 InvertibleBloomFilter *);
443 for (i = 0; i < se->stratas[strata_ctr]->strata_count; i++)
444 c->stratas[strata_ctr]->strata[i] = ibf_dup (
445 se->stratas[strata_ctr]->strata[i]);
446 }
277 return c; 447 return c;
278} 448}
279 449
@@ -284,10 +454,14 @@ strata_estimator_dup (struct StrataEstimator *se)
284 * @param se strata estimator to destroy. 454 * @param se strata estimator to destroy.
285 */ 455 */
286void 456void
287strata_estimator_destroy (struct StrataEstimator *se) 457strata_estimator_destroy (struct MultiStrataEstimator *se)
288{ 458{
289 for (unsigned int i = 0; i < se->strata_count; i++) 459 unsigned int i;
290 ibf_destroy (se->strata[i]); 460 for (uint8_t strata_ctr = 0; strata_ctr < MULTI_SE_BASE_COUNT; strata_ctr++)
291 GNUNET_free (se->strata); 461 {
462 for (i = 0; i < se->stratas[strata_ctr]->strata_count; i++)
463 ibf_destroy (se->stratas[strata_ctr]->strata[i]);
464 GNUNET_free (se->stratas[strata_ctr]->strata);
465 }
292 GNUNET_free (se); 466 GNUNET_free (se);
293} 467}
diff --git a/src/setu/gnunet-service-setu_strata_estimator.h b/src/setu/gnunet-service-setu_strata_estimator.h
index afdbcdbbf..4871a7fcd 100644
--- a/src/setu/gnunet-service-setu_strata_estimator.h
+++ b/src/setu/gnunet-service-setu_strata_estimator.h
@@ -22,6 +22,7 @@
22 * @file set/gnunet-service-setu_strata_estimator.h 22 * @file set/gnunet-service-setu_strata_estimator.h
23 * @brief estimator of set difference 23 * @brief estimator of set difference
24 * @author Florian Dold 24 * @author Florian Dold
25 * @author Elias Summermatter
25 */ 26 */
26 27
27#ifndef GNUNET_SERVICE_SETU_STRATA_ESTIMATOR_H 28#ifndef GNUNET_SERVICE_SETU_STRATA_ESTIMATOR_H
@@ -61,6 +62,31 @@ struct StrataEstimator
61 unsigned int ibf_size; 62 unsigned int ibf_size;
62}; 63};
63 64
65struct MultiStrataEstimator
66{
67 /**
68 * Array of strata estimators
69 */
70 struct StrataEstimator **stratas;
71
72 /**
73 * Number of strata estimators in struct
74 */
75 uint8_t size;
76
77};
78
79/**
80 * Deteminate how many strata estimators in the message are necessary
81 * @param avg_element_size
82 * @param element_count
83 * @return number of strata's
84 */
85
86uint8_t
87determine_strata_count (uint64_t avg_element_size,
88 uint64_t element_count);
89
64 90
65/** 91/**
66 * Write the given strata estimator to the buffer. 92 * Write the given strata estimator to the buffer.
@@ -70,7 +96,9 @@ struct StrataEstimator
70 * @return number of bytes written to @a buf 96 * @return number of bytes written to @a buf
71 */ 97 */
72size_t 98size_t
73strata_estimator_write (const struct StrataEstimator *se, 99strata_estimator_write (struct MultiStrataEstimator *se,
100 uint16_t se_ibf_total_size,
101 uint8_t number_se_send,
74 void *buf); 102 void *buf);
75 103
76 104
@@ -88,7 +116,9 @@ int
88strata_estimator_read (const void *buf, 116strata_estimator_read (const void *buf,
89 size_t buf_len, 117 size_t buf_len,
90 int is_compressed, 118 int is_compressed,
91 struct StrataEstimator *se); 119 uint8_t number_se_received,
120 uint16_t se_ibf_total_size,
121 struct MultiStrataEstimator *se);
92 122
93 123
94/** 124/**
@@ -99,7 +129,7 @@ strata_estimator_read (const void *buf,
99 * @param ibf_hashnum hashnum parameter of each ibf 129 * @param ibf_hashnum hashnum parameter of each ibf
100 * @return a freshly allocated, empty strata estimator, NULL on error 130 * @return a freshly allocated, empty strata estimator, NULL on error
101 */ 131 */
102struct StrataEstimator * 132struct MultiStrataEstimator *
103strata_estimator_create (unsigned int strata_count, 133strata_estimator_create (unsigned int strata_count,
104 uint32_t ibf_size, 134 uint32_t ibf_size,
105 uint8_t ibf_hashnum); 135 uint8_t ibf_hashnum);
@@ -111,11 +141,11 @@ strata_estimator_create (unsigned int strata_count,
111 * 141 *
112 * @param se1 first strata estimator 142 * @param se1 first strata estimator
113 * @param se2 second strata estimator 143 * @param se2 second strata estimator
114 * @return abs(|se1| - |se2|) 144 * @return nothing
115 */ 145 */
116unsigned int 146void
117strata_estimator_difference (const struct StrataEstimator *se1, 147strata_estimator_difference (const struct MultiStrataEstimator *se1,
118 const struct StrataEstimator *se2); 148 const struct MultiStrataEstimator *se2);
119 149
120 150
121/** 151/**
@@ -125,7 +155,7 @@ strata_estimator_difference (const struct StrataEstimator *se1,
125 * @param key key to add 155 * @param key key to add
126 */ 156 */
127void 157void
128strata_estimator_insert (struct StrataEstimator *se, 158strata_estimator_insert (struct MultiStrataEstimator *se,
129 struct IBF_Key key); 159 struct IBF_Key key);
130 160
131 161
@@ -136,7 +166,7 @@ strata_estimator_insert (struct StrataEstimator *se,
136 * @param key key to remove 166 * @param key key to remove
137 */ 167 */
138void 168void
139strata_estimator_remove (struct StrataEstimator *se, 169strata_estimator_remove (struct MultiStrataEstimator *se,
140 struct IBF_Key key); 170 struct IBF_Key key);
141 171
142 172
@@ -146,7 +176,7 @@ strata_estimator_remove (struct StrataEstimator *se,
146 * @param se strata estimator to destroy. 176 * @param se strata estimator to destroy.
147 */ 177 */
148void 178void
149strata_estimator_destroy (struct StrataEstimator *se); 179strata_estimator_destroy (struct MultiStrataEstimator *se);
150 180
151 181
152/** 182/**
@@ -155,8 +185,8 @@ strata_estimator_destroy (struct StrataEstimator *se);
155 * @param se the strata estimator to copy 185 * @param se the strata estimator to copy
156 * @return the copy 186 * @return the copy
157 */ 187 */
158struct StrataEstimator * 188struct MultiStrataEstimator *
159strata_estimator_dup (struct StrataEstimator *se); 189strata_estimator_dup (struct MultiStrataEstimator *se);
160 190
161 191
162#if 0 /* keep Emacsens' auto-indent happy */ 192#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/setu/ibf.c b/src/setu/ibf.c
index 1beba9065..dbd23c320 100644
--- a/src/setu/ibf.c
+++ b/src/setu/ibf.c
@@ -20,11 +20,15 @@
20 20
21/** 21/**
22 * @file set/ibf.c 22 * @file set/ibf.c
23 * @brief implementation of the invertible Bloom filter 23 * @brief implementation of the invertible bloom filter
24 * @author Florian Dold 24 * @author Florian Dold
25 * @author Elias Summermatter
25 */ 26 */
26 27
27#include "ibf.h" 28#include "ibf.h"
29#include "gnunet_util_lib.h"
30#define LOG(kind, ...) GNUNET_log_from (kind, "setu", __VA_ARGS__)
31
28 32
29/** 33/**
30 * Compute the key's hash from the key. 34 * Compute the key's hash from the key.
@@ -58,11 +62,12 @@ ibf_hashcode_from_key (struct IBF_Key key,
58 struct GNUNET_HashCode *dst) 62 struct GNUNET_HashCode *dst)
59{ 63{
60 struct IBF_Key *p; 64 struct IBF_Key *p;
65 unsigned int i;
61 const unsigned int keys_per_hashcode = sizeof(struct GNUNET_HashCode) 66 const unsigned int keys_per_hashcode = sizeof(struct GNUNET_HashCode)
62 / sizeof(struct IBF_Key); 67 / sizeof(struct IBF_Key);
63 68
64 p = (struct IBF_Key *) dst; 69 p = (struct IBF_Key *) dst;
65 for (unsigned int i = 0; i < keys_per_hashcode; i++) 70 for (i = 0; i < keys_per_hashcode; i++)
66 *p++ = key; 71 *p++ = key;
67} 72}
68 73
@@ -75,14 +80,14 @@ ibf_hashcode_from_key (struct IBF_Key key,
75 * @return the newly created invertible bloom filter, NULL on error 80 * @return the newly created invertible bloom filter, NULL on error
76 */ 81 */
77struct InvertibleBloomFilter * 82struct InvertibleBloomFilter *
78ibf_create (uint32_t size, 83ibf_create (uint32_t size, uint8_t hash_num)
79 uint8_t hash_num)
80{ 84{
81 struct InvertibleBloomFilter *ibf; 85 struct InvertibleBloomFilter *ibf;
82 86
83 GNUNET_assert (0 != size); 87 GNUNET_assert (0 != size);
88
84 ibf = GNUNET_new (struct InvertibleBloomFilter); 89 ibf = GNUNET_new (struct InvertibleBloomFilter);
85 ibf->count = GNUNET_malloc_large (size * sizeof(uint8_t)); 90 ibf->count = GNUNET_malloc_large (size * sizeof(uint64_t));
86 if (NULL == ibf->count) 91 if (NULL == ibf->count)
87 { 92 {
88 GNUNET_free (ibf); 93 GNUNET_free (ibf);
@@ -105,6 +110,7 @@ ibf_create (uint32_t size,
105 } 110 }
106 ibf->size = size; 111 ibf->size = size;
107 ibf->hash_num = hash_num; 112 ibf->hash_num = hash_num;
113
108 return ibf; 114 return ibf;
109} 115}
110 116
@@ -121,8 +127,7 @@ ibf_get_indices (const struct InvertibleBloomFilter *ibf,
121 uint32_t i; 127 uint32_t i;
122 uint32_t bucket; 128 uint32_t bucket;
123 129
124 bucket = GNUNET_CRYPTO_crc32_n (&key, 130 bucket = GNUNET_CRYPTO_crc32_n (&key, sizeof key);
125 sizeof (key));
126 for (i = 0, filled = 0; filled < ibf->hash_num; i++) 131 for (i = 0, filled = 0; filled < ibf->hash_num; i++)
127 { 132 {
128 uint64_t x; 133 uint64_t x;
@@ -133,8 +138,7 @@ ibf_get_indices (const struct InvertibleBloomFilter *ibf,
133 dst[filled++] = bucket % ibf->size; 138 dst[filled++] = bucket % ibf->size;
134try_next: 139try_next:
135 x = ((uint64_t) bucket << 32) | i; 140 x = ((uint64_t) bucket << 32) | i;
136 bucket = GNUNET_CRYPTO_crc32_n (&x, 141 bucket = GNUNET_CRYPTO_crc32_n (&x, sizeof x);
137 sizeof (x));
138 } 142 }
139} 143}
140 144
@@ -170,13 +174,8 @@ ibf_insert (struct InvertibleBloomFilter *ibf,
170 int buckets[ibf->hash_num]; 174 int buckets[ibf->hash_num];
171 175
172 GNUNET_assert (ibf->hash_num <= ibf->size); 176 GNUNET_assert (ibf->hash_num <= ibf->size);
173 ibf_get_indices (ibf, 177 ibf_get_indices (ibf, key, buckets);
174 key, 178 ibf_insert_into (ibf, key, buckets, 1);
175 buckets);
176 ibf_insert_into (ibf,
177 key,
178 buckets,
179 1);
180} 179}
181 180
182 181
@@ -193,13 +192,8 @@ ibf_remove (struct InvertibleBloomFilter *ibf,
193 int buckets[ibf->hash_num]; 192 int buckets[ibf->hash_num];
194 193
195 GNUNET_assert (ibf->hash_num <= ibf->size); 194 GNUNET_assert (ibf->hash_num <= ibf->size);
196 ibf_get_indices (ibf, 195 ibf_get_indices (ibf, key, buckets);
197 key, 196 ibf_insert_into (ibf, key, buckets, -1);
198 buckets);
199 ibf_insert_into (ibf,
200 key,
201 buckets,
202 -1);
203} 197}
204 198
205 199
@@ -244,6 +238,8 @@ ibf_decode (struct InvertibleBloomFilter *ibf,
244 238
245 for (uint32_t i = 0; i < ibf->size; i++) 239 for (uint32_t i = 0; i < ibf->size; i++)
246 { 240 {
241 int hit;
242
247 /* we can only decode from pure buckets */ 243 /* we can only decode from pure buckets */
248 if ( (1 != ibf->count[i].count_val) && 244 if ( (1 != ibf->count[i].count_val) &&
249 (-1 != ibf->count[i].count_val) ) 245 (-1 != ibf->count[i].count_val) )
@@ -257,30 +253,33 @@ ibf_decode (struct InvertibleBloomFilter *ibf,
257 253
258 /* test if key in bucket hits its own location, 254 /* test if key in bucket hits its own location,
259 * if not, the key hash was subject to collision */ 255 * if not, the key hash was subject to collision */
260 { 256 hit = GNUNET_NO;
261 bool hit = false; 257 ibf_get_indices (ibf, ibf->key_sum[i], buckets);
258 for (int j = 0; j < ibf->hash_num; j++)
259 if (buckets[j] == i)
260 hit = GNUNET_YES;
262 261
263 ibf_get_indices (ibf, 262 if (GNUNET_NO == hit)
264 ibf->key_sum[i], 263 continue;
265 buckets); 264
266 for (int j = 0; j < ibf->hash_num; j++) 265 if (1 == ibf->count[i].count_val)
267 if (buckets[j] == i) 266 {
268 { 267 ibf->remote_decoded_count++;
269 hit = true;
270 break;
271 }
272 if (! hit)
273 continue;
274 } 268 }
269 else
270 {
271 ibf->local_decoded_count++;
272 }
273
274
275 if (NULL != ret_side) 275 if (NULL != ret_side)
276 *ret_side = ibf->count[i].count_val; 276 *ret_side = ibf->count[i].count_val;
277 if (NULL != ret_id) 277 if (NULL != ret_id)
278 *ret_id = ibf->key_sum[i]; 278 *ret_id = ibf->key_sum[i];
279 279
280 /* insert on the opposite side, effectively removing the element */ 280 /* insert on the opposite side, effectively removing the element */
281 ibf_insert_into (ibf, 281 ibf_insert_into (ibf, ibf->key_sum[i], buckets, -ibf->count[i].count_val);
282 ibf->key_sum[i], buckets, 282
283 -ibf->count[i].count_val);
284 return GNUNET_YES; 283 return GNUNET_YES;
285 } 284 }
286 285
@@ -291,6 +290,26 @@ ibf_decode (struct InvertibleBloomFilter *ibf,
291 290
292 291
293/** 292/**
293 * Returns the minimal bytes needed to store the counter of the IBF
294 *
295 * @param ibf the IBF
296 */
297uint8_t
298ibf_get_max_counter (struct InvertibleBloomFilter *ibf)
299{
300 long long max_counter = 0;
301 for (uint64_t i = 0; i < ibf->size; i++)
302 {
303 if (ibf->count[i].count_val > max_counter)
304 {
305 max_counter = ibf->count[i].count_val;
306 }
307 }
308 return 64 - __builtin_clzll (max_counter);
309}
310
311
312/**
294 * Write buckets from an ibf to a buffer. 313 * Write buckets from an ibf to a buffer.
295 * Exactly (IBF_BUCKET_SIZE*ibf->size) bytes are written to buf. 314 * Exactly (IBF_BUCKET_SIZE*ibf->size) bytes are written to buf.
296 * 315 *
@@ -298,16 +317,17 @@ ibf_decode (struct InvertibleBloomFilter *ibf,
298 * @param start with which bucket to start 317 * @param start with which bucket to start
299 * @param count how many buckets to write 318 * @param count how many buckets to write
300 * @param buf buffer to write the data to 319 * @param buf buffer to write the data to
320 * @param max bit length of a counter for unpacking
301 */ 321 */
302void 322void
303ibf_write_slice (const struct InvertibleBloomFilter *ibf, 323ibf_write_slice (const struct InvertibleBloomFilter *ibf,
304 uint32_t start, 324 uint32_t start,
305 uint32_t count, 325 uint64_t count,
306 void *buf) 326 void *buf,
327 uint8_t counter_max_length)
307{ 328{
308 struct IBF_Key *key_dst; 329 struct IBF_Key *key_dst;
309 struct IBF_KeyHash *key_hash_dst; 330 struct IBF_KeyHash *key_hash_dst;
310 struct IBF_Count *count_dst;
311 331
312 GNUNET_assert (start + count <= ibf->size); 332 GNUNET_assert (start + count <= ibf->size);
313 333
@@ -315,19 +335,178 @@ ibf_write_slice (const struct InvertibleBloomFilter *ibf,
315 key_dst = (struct IBF_Key *) buf; 335 key_dst = (struct IBF_Key *) buf;
316 GNUNET_memcpy (key_dst, 336 GNUNET_memcpy (key_dst,
317 ibf->key_sum + start, 337 ibf->key_sum + start,
318 count * sizeof *key_dst); 338 count * sizeof(*key_dst));
319 key_dst += count; 339 key_dst += count;
320 /* copy key hashes */ 340 /* copy key hashes */
321 key_hash_dst = (struct IBF_KeyHash *) key_dst; 341 key_hash_dst = (struct IBF_KeyHash *) key_dst;
322 GNUNET_memcpy (key_hash_dst, 342 GNUNET_memcpy (key_hash_dst,
323 ibf->key_hash_sum + start, 343 ibf->key_hash_sum + start,
324 count * sizeof *key_hash_dst); 344 count * sizeof(*key_hash_dst));
325 key_hash_dst += count; 345 key_hash_dst += count;
326 /* copy counts */ 346
327 count_dst = (struct IBF_Count *) key_hash_dst; 347 /* pack and copy counter */
328 GNUNET_memcpy (count_dst, 348 pack_counter (ibf,
329 ibf->count + start, 349 start,
330 count * sizeof *count_dst); 350 count,
351 (uint8_t *) key_hash_dst,
352 counter_max_length);
353
354
355}
356
357
358/**
359 * Packs the counter to transmit only the smallest possible amount of bytes and
360 * preventing overflow of the counter
361 * @param ibf the ibf to write
362 * @param start with which bucket to start
363 * @param count how many buckets to write
364 * @param buf buffer to write the data to
365 * @param max bit length of a counter for unpacking
366 */
367
368void
369pack_counter (const struct InvertibleBloomFilter *ibf,
370 uint32_t start,
371 uint64_t count,
372 uint8_t *buf,
373 uint8_t counter_max_length)
374{
375 uint8_t store_size = 0;
376 uint8_t store = 0;
377 uint16_t byte_ctr = 0;
378
379 /**
380 * Iterate over IBF bucket
381 */
382 for (uint64_t i = start; i< (count + start);)
383 {
384 uint64_t count_val_to_write = ibf->count[i].count_val;
385 uint8_t count_len_to_write = counter_max_length;
386
387 /**
388 * Pack and compose counters to byte values
389 */
390 while ((count_len_to_write + store_size) >= 8)
391 {
392 uint8_t bit_shift = 0;
393
394 /**
395 * Shift bits if more than a byte has to be written
396 * or the store size is not empty
397 */
398 if ((store_size > 0) || (count_len_to_write > 8))
399 {
400 uint8_t bit_unused = 8 - store_size;
401 bit_shift = count_len_to_write - bit_unused;
402 store = store << bit_unused;
403 }
404
405 buf[byte_ctr] = ((count_val_to_write >> bit_shift) | store) & 0xFF;
406 byte_ctr++;
407 count_len_to_write -= (8 - store_size);
408 count_val_to_write = count_val_to_write & ((1ULL <<
409 count_len_to_write) - 1);
410 store = 0;
411 store_size = 0;
412 }
413 store = (store << count_len_to_write) | count_val_to_write;
414 store_size = store_size + count_len_to_write;
415 count_len_to_write = 0;
416 i++;
417 }
418
419 /**
420 * Pack data left in story before finishing
421 */
422 if (store_size > 0)
423 {
424 buf[byte_ctr] = store << (8 - store_size);
425 byte_ctr++;
426 }
427
428}
429
430
431/**
432 * Unpacks the counter to transmit only the smallest possible amount of bytes and
433 * preventing overflow of the counter
434 * @param ibf the ibf to write
435 * @param start with which bucket to start
436 * @param count how many buckets to write
437 * @param buf buffer to write the data to
438 * @param max bit length of a counter for unpacking
439 */
440
441void
442unpack_counter (const struct InvertibleBloomFilter *ibf,
443 uint32_t start,
444 uint64_t count,
445 uint8_t *buf,
446 uint8_t counter_max_length)
447{
448 uint64_t ibf_counter_ctr = 0;
449 uint64_t store = 0;
450 uint64_t store_bit_ctr = 0;
451 uint64_t byte_ctr = 0;
452
453 /**
454 * Iterate over received bytes
455 */
456 while (true)
457 {
458 uint8_t byte_read = buf[byte_ctr];
459 uint8_t bit_to_read_left = 8;
460 byte_ctr++;
461
462 /**
463 * Pack data left in story before finishing
464 */
465 while (true)
466 {
467 /**
468 * Stop decoding when end is reached
469 */
470 if (ibf_counter_ctr > (count - 1))
471 return;
472
473 /*
474 * Unpack the counter
475 */
476 if ((store_bit_ctr + bit_to_read_left) >= counter_max_length)
477 {
478 uint8_t bytes_used = counter_max_length - store_bit_ctr;
479 if (store_bit_ctr > 0)
480 {
481 store = store << bytes_used;
482 }
483
484 uint8_t bytes_to_shift = bit_to_read_left - bytes_used;
485 uint64_t counter_part = byte_read >> bytes_to_shift;
486 store = store | counter_part;
487 ibf->count[ibf_counter_ctr + start].count_val = store;
488 byte_read = byte_read & ((1 << bytes_to_shift) - 1);
489 bit_to_read_left -= bytes_used;
490 ibf_counter_ctr++;
491 store = 0;
492 store_bit_ctr = 0;
493 }
494 else
495 {
496 store_bit_ctr += bit_to_read_left;
497 if (0 == store)
498 {
499 store = byte_read;
500 }
501 else
502 {
503 store = store << bit_to_read_left;
504 store = store | byte_read;
505 }
506 break;
507 }
508 }
509 }
331} 510}
332 511
333 512
@@ -338,12 +517,14 @@ ibf_write_slice (const struct InvertibleBloomFilter *ibf,
338 * @param start which bucket to start at 517 * @param start which bucket to start at
339 * @param count how many buckets to read 518 * @param count how many buckets to read
340 * @param ibf the ibf to read from 519 * @param ibf the ibf to read from
520 * @param max bit length of a counter for unpacking
341 */ 521 */
342void 522void
343ibf_read_slice (const void *buf, 523ibf_read_slice (const void *buf,
344 uint32_t start, 524 uint32_t start,
345 uint32_t count, 525 uint64_t count,
346 struct InvertibleBloomFilter *ibf) 526 struct InvertibleBloomFilter *ibf,
527 uint8_t counter_max_length)
347{ 528{
348 struct IBF_Key *key_src; 529 struct IBF_Key *key_src;
349 struct IBF_KeyHash *key_hash_src; 530 struct IBF_KeyHash *key_hash_src;
@@ -364,11 +545,10 @@ ibf_read_slice (const void *buf,
364 key_hash_src, 545 key_hash_src,
365 count * sizeof *key_hash_src); 546 count * sizeof *key_hash_src);
366 key_hash_src += count; 547 key_hash_src += count;
367 /* copy counts */ 548
549 /* copy and unpack counts */
368 count_src = (struct IBF_Count *) key_hash_src; 550 count_src = (struct IBF_Count *) key_hash_src;
369 GNUNET_memcpy (ibf->count + start, 551 unpack_counter (ibf,start,count,(uint8_t *) count_src,counter_max_length);
370 count_src,
371 count * sizeof *count_src);
372} 552}
373 553
374 554
diff --git a/src/setu/ibf.h b/src/setu/ibf.h
index 7c2ab33b1..5628405dc 100644
--- a/src/setu/ibf.h
+++ b/src/setu/ibf.h
@@ -22,6 +22,7 @@
22 * @file set/ibf.h 22 * @file set/ibf.h
23 * @brief invertible bloom filter 23 * @brief invertible bloom filter
24 * @author Florian Dold 24 * @author Florian Dold
25 * @author Elias Summermatter
25 */ 26 */
26 27
27#ifndef GNUNET_CONSENSUS_IBF_H 28#ifndef GNUNET_CONSENSUS_IBF_H
@@ -62,7 +63,7 @@ struct IBF_KeyHash
62 */ 63 */
63struct IBF_Count 64struct IBF_Count
64{ 65{
65 int8_t count_val; 66 int64_t count_val;
66}; 67};
67 68
68 69
@@ -93,6 +94,20 @@ struct InvertibleBloomFilter
93 uint8_t hash_num; 94 uint8_t hash_num;
94 95
95 /** 96 /**
97 * If an IBF is decoded this count stores how many
98 * elements are on the local site. This is used
99 * to estimate the set difference on a site
100 */
101 int local_decoded_count;
102
103 /**
104 * If an IBF is decoded this count stores how many
105 * elements are on the remote site. This is used
106 * to estimate the set difference on a site
107 */
108 int remote_decoded_count;
109
110 /**
96 * Xor sums of the elements' keys, used to identify the elements. 111 * Xor sums of the elements' keys, used to identify the elements.
97 * Array of 'size' elements. 112 * Array of 'size' elements.
98 */ 113 */
@@ -125,8 +140,9 @@ struct InvertibleBloomFilter
125void 140void
126ibf_write_slice (const struct InvertibleBloomFilter *ibf, 141ibf_write_slice (const struct InvertibleBloomFilter *ibf,
127 uint32_t start, 142 uint32_t start,
128 uint32_t count, 143 uint64_t count,
129 void *buf); 144 void *buf,
145 uint8_t counter_max_length);
130 146
131 147
132/** 148/**
@@ -140,8 +156,9 @@ ibf_write_slice (const struct InvertibleBloomFilter *ibf,
140void 156void
141ibf_read_slice (const void *buf, 157ibf_read_slice (const void *buf,
142 uint32_t start, 158 uint32_t start,
143 uint32_t count, 159 uint64_t count,
144 struct InvertibleBloomFilter *ibf); 160 struct InvertibleBloomFilter *ibf,
161 uint8_t counter_max_length);
145 162
146 163
147/** 164/**
@@ -244,6 +261,44 @@ ibf_dup (const struct InvertibleBloomFilter *ibf);
244void 261void
245ibf_destroy (struct InvertibleBloomFilter *ibf); 262ibf_destroy (struct InvertibleBloomFilter *ibf);
246 263
264uint8_t
265ibf_get_max_counter (struct InvertibleBloomFilter *ibf);
266
267
268/**
269 * Packs the counter to transmit only the smallest possible amount of bytes and
270 * preventing overflow of the counter
271 * @param ibf the ibf to write
272 * @param start with which bucket to start
273 * @param count how many buckets to write
274 * @param buf buffer to write the data to
275 * @param max bit length of a counter for unpacking
276 */
277
278void
279pack_counter (const struct InvertibleBloomFilter *ibf,
280 uint32_t start,
281 uint64_t count,
282 uint8_t *buf,
283 uint8_t counter_max_length);
284
285/**
286 * Unpacks the counter to transmit only the smallest possible amount of bytes and
287 * preventing overflow of the counter
288 * @param ibf the ibf to write
289 * @param start with which bucket to start
290 * @param count how many buckets to write
291 * @param buf buffer to write the data to
292 * @param max bit length of a counter for unpacking
293 */
294
295void
296unpack_counter (const struct InvertibleBloomFilter *ibf,
297 uint32_t start,
298 uint64_t count,
299 uint8_t *buf,
300 uint8_t counter_max_length);
301
247 302
248#if 0 /* keep Emacsens' auto-indent happy */ 303#if 0 /* keep Emacsens' auto-indent happy */
249{ 304{
diff --git a/src/setu/perf_setu_api.c b/src/setu/perf_setu_api.c
index b273f9c71..7f4d64f74 100644
--- a/src/setu/perf_setu_api.c
+++ b/src/setu/perf_setu_api.c
@@ -22,11 +22,14 @@
22 * @file set/test_setu_api.c 22 * @file set/test_setu_api.c
23 * @brief testcase for setu_api.c 23 * @brief testcase for setu_api.c
24 * @author Florian Dold 24 * @author Florian Dold
25 * @author Elias Summermatter
25 */ 26 */
26#include "platform.h" 27#include "platform.h"
27#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
28#include "gnunet_testing_lib.h" 29#include "gnunet_testing_lib.h"
29#include "gnunet_setu_service.h" 30#include "gnunet_setu_service.h"
31#include <sys/sysinfo.h>
32#include <pthread.h>
30 33
31 34
32static struct GNUNET_PeerIdentity local_id; 35static struct GNUNET_PeerIdentity local_id;
@@ -50,6 +53,12 @@ static int ret;
50static struct GNUNET_SCHEDULER_Task *tt; 53static struct GNUNET_SCHEDULER_Task *tt;
51 54
52 55
56/**
57 * Handles configuration file for setu performance test
58 *
59 */
60static struct GNUNET_CONFIGURATION_Handle *setu_cfg;
61
53 62
54static void 63static void
55result_cb_set1 (void *cls, 64result_cb_set1 (void *cls,
@@ -57,44 +66,44 @@ result_cb_set1 (void *cls,
57 uint64_t size, 66 uint64_t size,
58 enum GNUNET_SETU_Status status) 67 enum GNUNET_SETU_Status status)
59{ 68{
60 switch (status) 69 switch (status)
70 {
71 case GNUNET_SETU_STATUS_ADD_LOCAL:
72 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "set 1: got element\n");
73 break;
74
75 case GNUNET_SETU_STATUS_FAILURE:
76 GNUNET_break (0);
77 oh1 = NULL;
78 fprintf (stderr, "set 1: received failure status!\n");
79 ret = 1;
80 if (NULL != tt)
81 {
82 GNUNET_SCHEDULER_cancel (tt);
83 tt = NULL;
84 }
85 GNUNET_SCHEDULER_shutdown ();
86 break;
87
88 case GNUNET_SETU_STATUS_DONE:
89 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "set 1: done\n");
90 oh1 = NULL;
91 if (NULL != set1)
61 { 92 {
62 case GNUNET_SETU_STATUS_ADD_LOCAL: 93 GNUNET_SETU_destroy (set1);
63 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "set 1: got element\n"); 94 set1 = NULL;
64 break;
65
66 case GNUNET_SETU_STATUS_FAILURE:
67 GNUNET_break (0);
68 oh1 = NULL;
69 fprintf (stderr, "set 1: received failure status!\n");
70 ret = 1;
71 if (NULL != tt)
72 {
73 GNUNET_SCHEDULER_cancel (tt);
74 tt = NULL;
75 }
76 GNUNET_SCHEDULER_shutdown ();
77 break;
78
79 case GNUNET_SETU_STATUS_DONE:
80 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "set 1: done\n");
81 oh1 = NULL;
82 if (NULL != set1)
83 {
84 GNUNET_SETU_destroy (set1);
85 set1 = NULL;
86 }
87 if (NULL == set2)
88 {
89 GNUNET_SCHEDULER_cancel (tt);
90 tt = NULL;
91 GNUNET_SCHEDULER_shutdown ();
92 }
93 break;
94
95 default:
96 GNUNET_assert (0);
97 } 95 }
96 if (NULL == set2)
97 {
98 GNUNET_SCHEDULER_cancel (tt);
99 tt = NULL;
100 GNUNET_SCHEDULER_shutdown ();
101 }
102 break;
103
104 default:
105 GNUNET_assert (0);
106 }
98} 107}
99 108
100 109
@@ -104,36 +113,36 @@ result_cb_set2 (void *cls,
104 uint64_t size, 113 uint64_t size,
105 enum GNUNET_SETU_Status status) 114 enum GNUNET_SETU_Status status)
106{ 115{
107 switch (status) 116 switch (status)
117 {
118 case GNUNET_SETU_STATUS_ADD_LOCAL:
119 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "set 2: got element\n");
120 break;
121
122 case GNUNET_SETU_STATUS_FAILURE:
123 GNUNET_break (0);
124 oh2 = NULL;
125 fprintf (stderr, "set 2: received failure status\n");
126 GNUNET_SCHEDULER_shutdown ();
127 ret = 1;
128 break;
129
130 case GNUNET_SETU_STATUS_DONE:
131 oh2 = NULL;
132 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "set 2: done\n");
133 GNUNET_SETU_destroy (set2);
134 set2 = NULL;
135 if (NULL == set1)
108 { 136 {
109 case GNUNET_SETU_STATUS_ADD_LOCAL: 137 GNUNET_SCHEDULER_cancel (tt);
110 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "set 2: got element\n"); 138 tt = NULL;
111 break; 139 GNUNET_SCHEDULER_shutdown ();
112
113 case GNUNET_SETU_STATUS_FAILURE:
114 GNUNET_break (0);
115 oh2 = NULL;
116 fprintf (stderr, "set 2: received failure status\n");
117 GNUNET_SCHEDULER_shutdown ();
118 ret = 1;
119 break;
120
121 case GNUNET_SETU_STATUS_DONE:
122 oh2 = NULL;
123 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "set 2: done\n");
124 GNUNET_SETU_destroy (set2);
125 set2 = NULL;
126 if (NULL == set1)
127 {
128 GNUNET_SCHEDULER_cancel (tt);
129 tt = NULL;
130 GNUNET_SCHEDULER_shutdown ();
131 }
132 break;
133
134 default:
135 GNUNET_assert (0);
136 } 140 }
141 break;
142
143 default:
144 GNUNET_assert (0);
145 }
137} 146}
138 147
139 148
@@ -143,14 +152,14 @@ listen_cb (void *cls,
143 const struct GNUNET_MessageHeader *context_msg, 152 const struct GNUNET_MessageHeader *context_msg,
144 struct GNUNET_SETU_Request *request) 153 struct GNUNET_SETU_Request *request)
145{ 154{
146 GNUNET_assert (NULL != context_msg); 155 GNUNET_assert (NULL != context_msg);
147 GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_DUMMY); 156 GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_DUMMY);
148 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "listen cb called\n"); 157 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "listen cb called\n");
149 oh2 = GNUNET_SETU_accept (request, 158 oh2 = GNUNET_SETU_accept (request,
150 (struct GNUNET_SETU_Option[]){ 0 }, 159 (struct GNUNET_SETU_Option[]){ 0 },
151 &result_cb_set2, 160 &result_cb_set2,
152 NULL); 161 NULL);
153 GNUNET_SETU_commit (oh2, set2); 162 GNUNET_SETU_commit (oh2, set2);
154} 163}
155 164
156 165
@@ -162,122 +171,89 @@ listen_cb (void *cls,
162static void 171static void
163start (void *cls) 172start (void *cls)
164{ 173{
165 struct GNUNET_MessageHeader context_msg; 174 struct GNUNET_MessageHeader context_msg;
166 175
167 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting reconciliation\n"); 176 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting reconciliation\n");
168 context_msg.size = htons (sizeof context_msg); 177 context_msg.size = htons (sizeof context_msg);
169 context_msg.type = htons (GNUNET_MESSAGE_TYPE_DUMMY); 178 context_msg.type = htons (GNUNET_MESSAGE_TYPE_DUMMY);
170 listen_handle = GNUNET_SETU_listen (config, 179 listen_handle = GNUNET_SETU_listen (config,
171 &app_id, 180 &app_id,
172 &listen_cb, 181 &listen_cb,
173 NULL); 182 NULL);
174 oh1 = GNUNET_SETU_prepare (&local_id, 183 oh1 = GNUNET_SETU_prepare (&local_id,
175 &app_id, 184 &app_id,
176 &context_msg, 185 &context_msg,
177 (struct GNUNET_SETU_Option[]){ 0 }, 186 (struct GNUNET_SETU_Option[]){ 0 },
178 &result_cb_set1, 187 &result_cb_set1,
179 NULL); 188 NULL);
180 GNUNET_SETU_commit (oh1, set1); 189 GNUNET_SETU_commit (oh1, set1);
181} 190}
182 191
183 192
184/** 193/**
185 * Initialize the second set, continue
186 *
187 * @param cls closure, unused
188 */
189static void
190init_set2 (void *cls)
191{
192 struct GNUNET_SETU_Element element;
193
194 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initializing set 2\n");
195
196 element.element_type = 0;
197 element.data = "hello1";
198 element.size = strlen (element.data);
199 GNUNET_SETU_add_element (set2, &element, NULL, NULL);
200 element.data = "quux";
201 element.size = strlen (element.data);
202 GNUNET_SETU_add_element (set2, &element, NULL, NULL);
203 element.data = "baz";
204 element.size = strlen (element.data);
205 GNUNET_SETU_add_element (set2, &element, &start, NULL);
206}
207
208/**
209 * Generate random byte stream 194 * Generate random byte stream
210 */ 195 */
211 196
212unsigned char *gen_rdm_bytestream (size_t num_bytes) 197unsigned char *
198gen_rdm_bytestream (size_t num_bytes)
213{ 199{
214 unsigned char *stream = GNUNET_malloc (num_bytes); 200 unsigned char *stream = GNUNET_malloc (num_bytes);
215 GNUNET_CRYPTO_random_block(GNUNET_CRYPTO_QUALITY_WEAK, stream, num_bytes); 201 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, stream, num_bytes);
216 return stream; 202 return stream;
217} 203}
218 204
205
219/** 206/**
220 * Generate random sets 207 * Generate random sets
221 */ 208 */
222 209
223static void 210static void
224initRandomSets(int overlap, int set1_size, int set2_size, int element_size_in_bytes) 211initRandomSets (int overlap, int set1_size, int set2_size, int
212 element_size_in_bytes)
225{ 213{
226 struct GNUNET_SETU_Element element; 214 struct GNUNET_SETU_Element element;
227 element.element_type = 0; 215 element.element_type = 0;
228 216
229 // Add elements to both sets 217 // Add elements to both sets
230 for (int i = 0; i < overlap; i++) { 218 for (int i = 0; i < overlap; i++)
231 element.data = gen_rdm_bytestream(element_size_in_bytes); 219 {
232 element.size = element_size_in_bytes; 220 element.data = gen_rdm_bytestream (element_size_in_bytes);
233 GNUNET_SETU_add_element (set1, &element, NULL, NULL); 221 element.size = element_size_in_bytes;
234 GNUNET_SETU_add_element (set2, &element, NULL, NULL); 222 GNUNET_SETU_add_element (set1, &element, NULL, NULL);
235 set1_size--; 223 GNUNET_SETU_add_element (set2, &element, NULL, NULL);
236 set2_size--; 224 set1_size--;
237 } 225 set2_size--;
238 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized elements in both sets\n"); 226 }
239 227 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized elements in both sets\n");
240 // Add other elements to set 1 228
241 while(set1_size>0) { 229 // Add other elements to set 1
242 element.data = gen_rdm_bytestream(element_size_in_bytes); 230 while (set1_size>0)
243 element.size = element_size_in_bytes; 231 {
244 GNUNET_SETU_add_element (set1, &element, NULL, NULL); 232 element.data = gen_rdm_bytestream (element_size_in_bytes);
245 set1_size--; 233 element.size = element_size_in_bytes;
246 } 234 GNUNET_SETU_add_element (set1, &element, NULL, NULL);
247 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized elements in set1\n"); 235 set1_size--;
248 236 }
249 // Add other elements to set 2 237 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized elements in set1\n");
250 while(set2_size > 0) {
251 element.data = gen_rdm_bytestream(element_size_in_bytes);
252 element.size = element_size_in_bytes;
253 238
254 if(set2_size != 1) { 239 // Add other elements to set 2
255 GNUNET_SETU_add_element (set2, &element,NULL, NULL); 240 while (set2_size > 0)
256 } else { 241 {
257 GNUNET_SETU_add_element (set2, &element,&start, NULL); 242 element.data = gen_rdm_bytestream (element_size_in_bytes);
258 } 243 element.size = element_size_in_bytes;
259 244
260 set2_size--; 245 if (set2_size != 1)
246 {
247 GNUNET_SETU_add_element (set2, &element,NULL, NULL);
248 }
249 else
250 {
251 GNUNET_SETU_add_element (set2, &element,&start, NULL);
261 } 252 }
262 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized elements in set2\n");
263}
264
265/**
266 * Initialize the first set, continue.
267 */
268static void
269init_set1 (void)
270{
271 struct GNUNET_SETU_Element element;
272 253
273 element.element_type = 0; 254 set2_size--;
274 element.data = "hello"; 255 }
275 element.size = strlen (element.data); 256 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized elements in set2\n");
276 GNUNET_SETU_add_element (set1, &element, NULL, NULL);
277 element.data = "bar";
278 element.size = strlen (element.data);
279 GNUNET_SETU_add_element (set1, &element, &init_set2, NULL);
280 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized set 1\n");
281} 257}
282 258
283 259
@@ -289,10 +265,10 @@ init_set1 (void)
289static void 265static void
290timeout_fail (void *cls) 266timeout_fail (void *cls)
291{ 267{
292 tt = NULL; 268 tt = NULL;
293 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Testcase failed with timeout\n"); 269 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Testcase failed with timeout\n");
294 GNUNET_SCHEDULER_shutdown (); 270 GNUNET_SCHEDULER_shutdown ();
295 ret = 1; 271 ret = 1;
296} 272}
297 273
298 274
@@ -304,36 +280,36 @@ timeout_fail (void *cls)
304static void 280static void
305do_shutdown (void *cls) 281do_shutdown (void *cls)
306{ 282{
307 if (NULL != tt) 283 if (NULL != tt)
308 { 284 {
309 GNUNET_SCHEDULER_cancel (tt); 285 GNUNET_SCHEDULER_cancel (tt);
310 tt = NULL; 286 tt = NULL;
311 } 287 }
312 if (NULL != oh1) 288 if (NULL != oh1)
313 { 289 {
314 GNUNET_SETU_operation_cancel (oh1); 290 GNUNET_SETU_operation_cancel (oh1);
315 oh1 = NULL; 291 oh1 = NULL;
316 } 292 }
317 if (NULL != oh2) 293 if (NULL != oh2)
318 { 294 {
319 GNUNET_SETU_operation_cancel (oh2); 295 GNUNET_SETU_operation_cancel (oh2);
320 oh2 = NULL; 296 oh2 = NULL;
321 } 297 }
322 if (NULL != set1) 298 if (NULL != set1)
323 { 299 {
324 GNUNET_SETU_destroy (set1); 300 GNUNET_SETU_destroy (set1);
325 set1 = NULL; 301 set1 = NULL;
326 } 302 }
327 if (NULL != set2) 303 if (NULL != set2)
328 { 304 {
329 GNUNET_SETU_destroy (set2); 305 GNUNET_SETU_destroy (set2);
330 set2 = NULL; 306 set2 = NULL;
331 } 307 }
332 if (NULL != listen_handle) 308 if (NULL != listen_handle)
333 { 309 {
334 GNUNET_SETU_listen_cancel (listen_handle); 310 GNUNET_SETU_listen_cancel (listen_handle);
335 listen_handle = NULL; 311 listen_handle = NULL;
336 } 312 }
337} 313}
338 314
339 315
@@ -350,79 +326,148 @@ run (void *cls,
350 const struct GNUNET_CONFIGURATION_Handle *cfg, 326 const struct GNUNET_CONFIGURATION_Handle *cfg,
351 struct GNUNET_TESTING_Peer *peer) 327 struct GNUNET_TESTING_Peer *peer)
352{ 328{
353 struct GNUNET_SETU_OperationHandle *my_oh; 329 struct GNUNET_SETU_OperationHandle *my_oh;
354 330
355 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 331 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
356 "Running preparatory tests\n"); 332 "Running preparatory tests\n");
357 tt = GNUNET_SCHEDULER_add_delayed ( 333 tt = GNUNET_SCHEDULER_add_delayed (
358 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), 334 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
359 &timeout_fail, 335 &timeout_fail,
360 NULL); 336 NULL);
361 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); 337 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
362 338
363 config = cfg; 339 config = cfg;
364 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_get_peer_identity (cfg, 340 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_get_peer_identity (cfg,
365 &local_id)); 341 &local_id));
366 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 342 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
367 "my id (from CRYPTO): %s\n", 343 "my id (from CRYPTO): %s\n",
368 GNUNET_i2s (&local_id)); 344 GNUNET_i2s (&local_id));
369 GNUNET_TESTING_peer_get_identity (peer, 345 GNUNET_TESTING_peer_get_identity (peer,
370 &local_id); 346 &local_id);
371 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
372 "my id (from TESTING): %s\n", 348 "my id (from TESTING): %s\n",
373 GNUNET_i2s (&local_id)); 349 GNUNET_i2s (&local_id));
374 set1 = GNUNET_SETU_create (cfg); 350 set1 = GNUNET_SETU_create (cfg);
375 set2 = GNUNET_SETU_create (cfg); 351 set2 = GNUNET_SETU_create (cfg);
376 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 352 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
377 "Created sets %p and %p for union operation\n", 353 "Created sets %p and %p for union operation\n",
378 set1, 354 set1,
379 set2); 355 set2);
380 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &app_id); 356 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &app_id);
381 357
382 /* test if canceling an uncommitted request works! */ 358 /* test if canceling an uncommitted request works! */
383 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 359 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
384 "Launching and instantly stopping set operation\n"); 360 "Launching and instantly stopping set operation\n");
385 my_oh = GNUNET_SETU_prepare (&local_id, 361 my_oh = GNUNET_SETU_prepare (&local_id,
386 &app_id, 362 &app_id,
387 NULL, 363 NULL,
388 (struct GNUNET_SETU_Option[]){ 0 }, 364 (struct GNUNET_SETU_Option[]){ 0 },
389 NULL, 365 NULL,
390 NULL); 366 NULL);
391 GNUNET_SETU_operation_cancel (my_oh); 367 GNUNET_SETU_operation_cancel (my_oh);
392 368
393 /* test the real set reconciliation */ 369 /* test the real set reconciliation */
394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 370 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
395 "Running real set-reconciliation\n"); 371 "Running real set-reconciliation\n");
396 //init_set1 (); 372 // init_set1 ();
397 // limit ~23800 element total 373 // limit ~23800 element total
398 initRandomSets(50,100,100,128); 374 initRandomSets (490, 500,500,32);
399} 375}
400 376
401static void execute_perf() 377
378void
379perf_thread ()
402{ 380{
403 for( int repeat_ctr = 0; repeat_ctr<1; repeat_ctr++ ) { 381 GNUNET_TESTING_service_run ("perf_setu_api",
382 "arm",
383 "test_setu.conf",
384 &run,
385 NULL);
386
387}
404 388
405 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
406 "Executing perf round %d\n", repeat_ctr);
407 389
408 GNUNET_TESTING_service_run ("perf_setu_api", 390static void
409 "arm", 391run_petf_thread (int total_runs)
410 "test_setu.conf", 392{
411 &run, 393 int core_count = get_nprocs_conf ();
412 NULL); 394 pid_t child_pid, wpid;
395 int status = 0;
396
397// Father code (before child processes start)
398 for (int processed = 0; processed < total_runs;)
399 {
400 for (int id = 0; id < core_count; id++)
401 {
402 if (processed >= total_runs)
403 break;
404
405 if ((child_pid = fork ()) == 0)
406 {
407 perf_thread ();
408 exit (0);
409 }
410 processed += 1;
413 } 411 }
414 return 0; 412 while ((wpid = wait (&status)) > 0)
413 ;
414
415 }
415} 416}
416 417
417 418
419static void
420execute_perf ()
421{
422
423 /**
424 * Erase statfile
425 */
426 remove ("perf_stats.csv");
427 remove ("perf_failure_bucket_number_factor.csv");
428 for (int out_out_ctr = 3; out_out_ctr <= 3; out_out_ctr++)
429 {
430
431 for (int out_ctr = 20; out_ctr <= 20; out_ctr++)
432 {
433 float base = 0.1;
434 float x = out_ctr * base;
435 char factor[10];
436 char *buffer = gcvt (x, 4, factor);
437 setu_cfg = GNUNET_CONFIGURATION_create ();
438 GNUNET_CONFIGURATION_set_value_string (setu_cfg, "IBF",
439 "BUCKET_NUMBER_FACTOR",
440 buffer); // Factor default=4
441 GNUNET_CONFIGURATION_set_value_number (setu_cfg, "IBF",
442 "NUMBER_PER_BUCKET", 3); // K default=4
443 GNUNET_CONFIGURATION_set_value_string (setu_cfg, "PERFORMANCE",
444 "TRADEOFF", "2"); // default=0.25
445 GNUNET_CONFIGURATION_set_value_string (setu_cfg, "PERFORMANCE",
446 "MAX_SET_DIFF_FACTOR_DIFFERENTIAL",
447 "20000"); // default=0.25
448 GNUNET_CONFIGURATION_set_value_number (setu_cfg, "BOUNDARIES",
449 "UPPER_ELEMENT", 5000);
450
451
452 if (GNUNET_OK != GNUNET_CONFIGURATION_write (setu_cfg, "perf_setu.conf"))
453 GNUNET_log (
454 GNUNET_ERROR_TYPE_ERROR,
455 _ ("Failed to write subsystem default identifier map'.\n"));
456 run_petf_thread (100);
457 }
458
459 }
460 return;
461}
462
418 463
419int 464int
420main (int argc, char **argv) 465main (int argc, char **argv)
421{ 466{
422 GNUNET_log_setup ("perf_setu_api",
423 "WARNING",
424 NULL);
425 467
426 execute_perf(); 468 GNUNET_log_setup ("perf_setu_api",
427 return 0; 469 "WARNING",
470 NULL);
471 execute_perf ();
472 return 0;
428} 473}
diff --git a/src/setu/setu.h b/src/setu/setu.h
index 7c2a98a02..7b606f12c 100644
--- a/src/setu/setu.h
+++ b/src/setu/setu.h
@@ -122,6 +122,31 @@ struct GNUNET_SETU_AcceptMessage
122 */ 122 */
123 uint32_t byzantine_lower_bound; 123 uint32_t byzantine_lower_bound;
124 124
125
126 /**
127 * Upper bound for the set size, used only when
128 * byzantine mode is enabled.
129 */
130 uint64_t byzantine_upper_bond;
131
132 /**
133 * Bandwidth latency tradeoff determines how much bytes a single RTT is
134 * worth, which is a performance setting
135 */
136 uint64_t bandwidth_latency_tradeoff;
137
138 /**
139 * The factor determines the number of buckets an IBF has which is
140 * multiplied by the estimated setsize default: 2
141 */
142 uint64_t ibf_bucket_number_factor;
143
144 /**
145 * This setting determines to how many IBF buckets an single elements
146 * is mapped to.
147 */
148 uint64_t ibf_number_of_buckets_per_element;
149
125}; 150};
126 151
127 152
@@ -226,6 +251,30 @@ struct GNUNET_SETU_EvaluateMessage
226 */ 251 */
227 uint32_t byzantine_lower_bound; 252 uint32_t byzantine_lower_bound;
228 253
254 /**
255 * Upper bound for the set size, used only when
256 * byzantine mode is enabled.
257 */
258 uint64_t byzantine_upper_bond;
259
260 /**
261 * Bandwidth latency tradeoff determines how much bytes a single RTT is
262 * worth, which is a performance setting
263 */
264 uint64_t bandwidth_latency_tradeoff;
265
266 /**
267 * The factor determines the number of buckets an IBF has which is
268 * multiplied by the estimated setsize default: 2
269 */
270 uint64_t ibf_bucket_number_factor;
271
272 /**
273 * This setting determines to how many IBF buckets an single elements
274 * is mapped to.
275 */
276 uint64_t ibf_number_of_buckets_per_element;
277
229 /* rest: context message, that is, application-specific 278 /* rest: context message, that is, application-specific
230 message to convince listener to pick up */ 279 message to convince listener to pick up */
231}; 280};
diff --git a/src/setu/setu_api.c b/src/setu/setu_api.c
index 0a09b18b2..faa57aaba 100644
--- a/src/setu/setu_api.c
+++ b/src/setu/setu_api.c
@@ -22,6 +22,7 @@
22 * @brief api for the set union service 22 * @brief api for the set union service
23 * @author Florian Dold 23 * @author Florian Dold
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Elias Summermatter
25 */ 26 */
26#include "platform.h" 27#include "platform.h"
27#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
@@ -526,6 +527,14 @@ GNUNET_SETU_prepare (const struct GNUNET_PeerIdentity *other_peer,
526 context_msg); 527 context_msg);
527 msg->app_id = *app_id; 528 msg->app_id = *app_id;
528 msg->target_peer = *other_peer; 529 msg->target_peer = *other_peer;
530
531 /* Set default values */
532 msg->byzantine_upper_bond = UINT64_MAX;
533 msg->bandwidth_latency_tradeoff = 0;
534 msg->ibf_bucket_number_factor = 2;
535 msg->ibf_number_of_buckets_per_element = 3;
536
537
529 for (const struct GNUNET_SETU_Option *opt = options; opt->type != 0; opt++) 538 for (const struct GNUNET_SETU_Option *opt = options; opt->type != 0; opt++)
530 { 539 {
531 switch (opt->type) 540 switch (opt->type)
@@ -534,6 +543,18 @@ GNUNET_SETU_prepare (const struct GNUNET_PeerIdentity *other_peer,
534 msg->byzantine = GNUNET_YES; 543 msg->byzantine = GNUNET_YES;
535 msg->byzantine_lower_bound = htonl (opt->v.num); 544 msg->byzantine_lower_bound = htonl (opt->v.num);
536 break; 545 break;
546 case GNUNET_SETU_OPTION_CUSTOM_BYZANTINE_UPPER_BOUND:
547 msg->byzantine_upper_bond = htonl (opt->v.num);
548 break;
549 case GNUNET_SETU_OPTION_CUSTOM_BANDWIDTH_LATENCY_TRADEOFF:
550 msg->bandwidth_latency_tradeoff = htonl (opt->v.num);
551 break;
552 case GNUNET_SETU_OPTION_CUSTOM_IBF_BUCKET_NUMBER_FACTOR:
553 msg->ibf_bucket_number_factor = htonl (opt->v.num);
554 break;
555 case GNUNET_SETU_OPTION_CUSTOM_IBF_BUCKETS_PER_ELEMENT:
556 msg->ibf_number_of_buckets_per_element = htonl (opt->v.num);
557 break;
537 case GNUNET_SETU_OPTION_FORCE_FULL: 558 case GNUNET_SETU_OPTION_FORCE_FULL:
538 msg->force_full = GNUNET_YES; 559 msg->force_full = GNUNET_YES;
539 break; 560 break;
@@ -788,6 +809,13 @@ GNUNET_SETU_accept (struct GNUNET_SETU_Request *request,
788 mqm = GNUNET_MQ_msg (msg, 809 mqm = GNUNET_MQ_msg (msg,
789 GNUNET_MESSAGE_TYPE_SETU_ACCEPT); 810 GNUNET_MESSAGE_TYPE_SETU_ACCEPT);
790 msg->accept_reject_id = htonl (request->accept_id); 811 msg->accept_reject_id = htonl (request->accept_id);
812
813 /* Set default values */
814 msg->byzantine_upper_bond = UINT64_MAX;
815 msg->bandwidth_latency_tradeoff = 0;
816 msg->ibf_bucket_number_factor = 2;
817 msg->ibf_number_of_buckets_per_element = 3;
818
791 for (const struct GNUNET_SETU_Option *opt = options; opt->type != 0; opt++) 819 for (const struct GNUNET_SETU_Option *opt = options; opt->type != 0; opt++)
792 { 820 {
793 switch (opt->type) 821 switch (opt->type)
@@ -796,6 +824,18 @@ GNUNET_SETU_accept (struct GNUNET_SETU_Request *request,
796 msg->byzantine = GNUNET_YES; 824 msg->byzantine = GNUNET_YES;
797 msg->byzantine_lower_bound = htonl (opt->v.num); 825 msg->byzantine_lower_bound = htonl (opt->v.num);
798 break; 826 break;
827 case GNUNET_SETU_OPTION_CUSTOM_BYZANTINE_UPPER_BOUND:
828 msg->byzantine_upper_bond = htonl (opt->v.num);
829 break;
830 case GNUNET_SETU_OPTION_CUSTOM_BANDWIDTH_LATENCY_TRADEOFF:
831 msg->bandwidth_latency_tradeoff = htonl (opt->v.num);
832 break;
833 case GNUNET_SETU_OPTION_CUSTOM_IBF_BUCKET_NUMBER_FACTOR:
834 msg->ibf_bucket_number_factor = htonl (opt->v.num);
835 break;
836 case GNUNET_SETU_OPTION_CUSTOM_IBF_BUCKETS_PER_ELEMENT:
837 msg->ibf_number_of_buckets_per_element = htonl (opt->v.num);
838 break;
799 case GNUNET_SETU_OPTION_FORCE_FULL: 839 case GNUNET_SETU_OPTION_FORCE_FULL:
800 msg->force_full = GNUNET_YES; 840 msg->force_full = GNUNET_YES;
801 break; 841 break;
diff --git a/src/setu/test_setu_api.c b/src/setu/test_setu_api.c
index 2fb7d015e..5a0c9d70d 100644
--- a/src/setu/test_setu_api.c
+++ b/src/setu/test_setu_api.c
@@ -204,62 +204,6 @@ init_set2 (void *cls)
204 GNUNET_SETU_add_element (set2, &element, &start, NULL); 204 GNUNET_SETU_add_element (set2, &element, &start, NULL);
205} 205}
206 206
207/**
208 * Generate random byte stream
209 */
210
211unsigned char *gen_rdm_bytestream (size_t num_bytes)
212{
213 unsigned char *stream = GNUNET_malloc (num_bytes);
214 GNUNET_CRYPTO_random_block(GNUNET_CRYPTO_QUALITY_WEAK, stream, num_bytes);
215 return stream;
216}
217
218/**
219 * Generate random sets
220 */
221
222static void
223initRandomSets(int overlap, int set1_size, int set2_size, int element_size_in_bytes)
224{
225 struct GNUNET_SETU_Element element;
226 element.element_type = 0;
227
228 // Add elements to both sets
229 for (int i = 0; i < overlap; i++) {
230 element.data = gen_rdm_bytestream(element_size_in_bytes);
231 element.size = element_size_in_bytes;
232 GNUNET_SETU_add_element (set1, &element, NULL, NULL);
233 GNUNET_SETU_add_element (set2, &element, NULL, NULL);
234 set1_size--;
235 set2_size--;
236 }
237 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized elements in both sets\n");
238
239 // Add other elements to set 1
240 while(set1_size>0) {
241 element.data = gen_rdm_bytestream(element_size_in_bytes);
242 element.size = element_size_in_bytes;
243 GNUNET_SETU_add_element (set1, &element, NULL, NULL);
244 set1_size--;
245 }
246 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized elements in set1\n");
247
248 // Add other elements to set 2
249 while(set2_size > 0) {
250 element.data = gen_rdm_bytestream(element_size_in_bytes);
251 element.size = element_size_in_bytes;
252
253 if(set2_size != 1) {
254 GNUNET_SETU_add_element (set2, &element,NULL, NULL);
255 } else {
256 GNUNET_SETU_add_element (set2, &element,&start, NULL);
257 }
258
259 set2_size--;
260 }
261 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized elements in set2\n");
262}
263 207
264/** 208/**
265 * Initialize the first set, continue. 209 * Initialize the first set, continue.
@@ -392,9 +336,7 @@ run (void *cls,
392 /* test the real set reconciliation */ 336 /* test the real set reconciliation */
393 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
394 "Running real set-reconciliation\n"); 338 "Running real set-reconciliation\n");
395 //init_set1 (); 339 init_set1 ();
396 initRandomSets(19500,20000,20000,4096);
397 //initRandomSets(19500,20000,20000,32);
398} 340}
399 341
400 342
diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am
index a9837daf5..11399e77c 100644
--- a/src/testbed/Makefile.am
+++ b/src/testbed/Makefile.am
@@ -23,8 +23,6 @@ if HAVE_SQLITE
23endif 23endif
24 24
25libexec_PROGRAMS = \ 25libexec_PROGRAMS = \
26 gnunet-cmd \
27 gnunet-cmds-helper \
28 gnunet-service-testbed \ 26 gnunet-service-testbed \
29 gnunet-helper-testbed \ 27 gnunet-helper-testbed \
30 gnunet-daemon-testbed-blacklist \ 28 gnunet-daemon-testbed-blacklist \
@@ -37,20 +35,6 @@ bin_PROGRAMS = \
37noinst_PROGRAMS = \ 35noinst_PROGRAMS = \
38 $(generate_underlay) 36 $(generate_underlay)
39 37
40plugin_LTLIBRARIES = \
41 libgnunet_plugin_testcmd.la
42
43libgnunet_plugin_testcmd_la_SOURCES = \
44 plugin_testcmd.c
45libgnunet_plugin_testcmd_la_LIBADD = \
46 $(top_builddir)/src/util/libgnunetutil.la \
47 $(top_builddir)/src/testing/libgnunettesting.la \
48 $(top_builddir)/src/statistics/libgnunetstatistics.la \
49 libgnunettestbed.la \
50 $(LTLIBINTL)
51libgnunet_plugin_testcmd_la_LDFLAGS = \
52 $(GN_PLUGIN_LDFLAGS)
53
54gnunet_service_testbed_SOURCES = \ 38gnunet_service_testbed_SOURCES = \
55 gnunet-service-testbed.c gnunet-service-testbed.h \ 39 gnunet-service-testbed.c gnunet-service-testbed.h \
56 gnunet-service-testbed_links.c gnunet-service-testbed_links.h \ 40 gnunet-service-testbed_links.c gnunet-service-testbed_links.h \
@@ -75,6 +59,7 @@ gnunet_service_testbed_LDADD = $(XLIB) \
75gnunet_testbed_profiler_SOURCES = \ 59gnunet_testbed_profiler_SOURCES = \
76 gnunet-testbed-profiler.c 60 gnunet-testbed-profiler.c
77gnunet_testbed_profiler_LDADD = $(XLIB) \ 61gnunet_testbed_profiler_LDADD = $(XLIB) \
62 $(top_builddir)/src/testing/libgnunettesting.la \
78 $(top_builddir)/src/util/libgnunetutil.la \ 63 $(top_builddir)/src/util/libgnunetutil.la \
79 libgnunettestbed.la 64 libgnunettestbed.la
80gnunet_testbed_profiler_LDFLAGS = \ 65gnunet_testbed_profiler_LDFLAGS = \
@@ -88,23 +73,6 @@ gnunet_helper_testbed_LDADD = $(XLIB) \
88 libgnunettestbed.la \ 73 libgnunettestbed.la \
89 $(LTLIBINTL) $(Z_LIBS) 74 $(LTLIBINTL) $(Z_LIBS)
90 75
91gnunet_cmd_SOURCES = \
92 gnunet-cmd.c
93gnunet_cmd_LDADD = $(XLIB) \
94 $(top_builddir)/src/util/libgnunetutil.la \
95 $(top_builddir)/src/testing/libgnunettesting.la \
96 libgnunettestbed.la \
97 $(LTLIBINTL) $(Z_LIBS)
98
99gnunet_cmds_helper_SOURCES = \
100 gnunet-cmds-helper.c
101gnunet_cmds_helper_LDADD = $(XLIB) \
102 $(top_builddir)/src/util/libgnunetutil.la \
103 $(top_builddir)/src/testing/libgnunettesting.la \
104 $(top_builddir)/src/transport/libgnunettransport.la \
105 libgnunettestbed.la \
106 $(LTLIBINTL) $(Z_LIBS)
107
108gnunet_daemon_testbed_blacklist_SOURCES = gnunet-daemon-testbed-blacklist.c 76gnunet_daemon_testbed_blacklist_SOURCES = gnunet-daemon-testbed-blacklist.c
109gnunet_daemon_testbed_blacklist_LDADD = $(XLIB) \ 77gnunet_daemon_testbed_blacklist_LDADD = $(XLIB) \
110 $(top_builddir)/src/transport/libgnunettransport.la \ 78 $(top_builddir)/src/transport/libgnunettransport.la \
@@ -127,17 +95,8 @@ lib_LTLIBRARIES = \
127 libgnunettestbed.la 95 libgnunettestbed.la
128 96
129libgnunettestbed_la_SOURCES = \ 97libgnunettestbed_la_SOURCES = \
130 testbed_api_cmd_local_test_finished.c \
131 testbed_api_cmd_send_peer_ready.c \
132 testbed_api_cmd_block_until_all_peers_started.c \
133 testbed_api_cmd_netjail_start.c \
134 testbed_api_cmd_netjail_start_testbed.c \
135 testbed_api_cmd_netjail_stop_testbed.c \
136 testbed_api_cmd_netjail_stop.c \
137 testbed_api.c testbed_api.h testbed.h \ 98 testbed_api.c testbed_api.h testbed.h \
138 testbed_api_hosts.c testbed_api_hosts.h testbed_helper.h \ 99 testbed_api_hosts.c testbed_api_hosts.h testbed_helper.h \
139 testbed_api_cmd_controller.c \
140 testbed_api_cmd_peer.c \
141 testbed_api_operations.c testbed_api_operations.h \ 100 testbed_api_operations.c testbed_api_operations.h \
142 testbed_api_peers.c testbed_api_peers.h \ 101 testbed_api_peers.c testbed_api_peers.h \
143 testbed_api_services.c \ 102 testbed_api_services.c \
@@ -156,24 +115,18 @@ libgnunettestbed_la_LIBADD = $(XLIB) \
156 $(top_builddir)/src/arm/libgnunetarm.la \ 115 $(top_builddir)/src/arm/libgnunetarm.la \
157 $(top_builddir)/src/util/libgnunetutil.la \ 116 $(top_builddir)/src/util/libgnunetutil.la \
158 $(LTLIBINTL) 117 $(LTLIBINTL)
159libgnunettestbed_la_DEPENDENCIES = \
160 $(top_builddir)/src/statistics/libgnunetstatistics.la \
161 $(top_builddir)/src/transport/libgnunettransport.la \
162 $(top_builddir)/src/hello/libgnunethello.la \
163 $(top_builddir)/src/testing/libgnunettesting.la \
164 $(top_builddir)/src/util/libgnunetutil.la
165libgnunettestbed_la_LDFLAGS = \ 118libgnunettestbed_la_LDFLAGS = \
166 $(GN_LIB_LDFLAGS) \ 119 $(GN_LIB_LDFLAGS) \
167 -version-info 0:0:0 120 -version-info 0:0:0
168 121
169generate_underlay_topology_SOURCES = generate-underlay-topology.c 122generate_underlay_topology_SOURCES = generate-underlay-topology.c
170generate_underlay_topology_LDADD = $(XLIB) \ 123generate_underlay_topology_LDADD = $(XLIB) \
124 $(top_builddir)/src/testing/libgnunettesting.la \
171 $(top_builddir)/src/util/libgnunetutil.la \ 125 $(top_builddir)/src/util/libgnunetutil.la \
172 libgnunettestbed.la \ 126 libgnunettestbed.la \
173 $(LTLIBINTL) -lsqlite3 127 $(LTLIBINTL) -lsqlite3
174 128
175check_PROGRAMS = \ 129check_PROGRAMS = \
176 test_testbed_api_cmd_netjail \
177 test_testbed_api_hosts \ 130 test_testbed_api_hosts \
178 test_gnunet_helper_testbed \ 131 test_gnunet_helper_testbed \
179 test_testbed_api_controllerlink \ 132 test_testbed_api_controllerlink \
@@ -208,7 +161,6 @@ check_PROGRAMS = \
208if ENABLE_TEST_RUN 161if ENABLE_TEST_RUN
209 AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; 162 AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
210 TESTS = \ 163 TESTS = \
211 test_testbed_api_cmd_netjail \
212 test_testbed_api \ 164 test_testbed_api \
213 test_testbed_api_sd \ 165 test_testbed_api_sd \
214 test_testbed_api_operations \ 166 test_testbed_api_operations \
@@ -239,13 +191,6 @@ if ENABLE_TEST_RUN
239 $(underlay_testcases) 191 $(underlay_testcases)
240endif 192endif
241 193
242test_testbed_api_cmd_netjail_SOURCES = \
243 test_testbed_api_cmd_netjail.c
244test_testbed_api_cmd_netjail_LDADD = \
245 $(top_builddir)/src/testing/libgnunettesting.la \
246 $(top_builddir)/src/util/libgnunetutil.la \
247 libgnunettestbed.la
248
249test_testbed_api_SOURCES = \ 194test_testbed_api_SOURCES = \
250 test_testbed_api.c 195 test_testbed_api.c
251test_testbed_api_LDADD = \ 196test_testbed_api_LDADD = \
diff --git a/src/testbed/gnunet-cmd.c b/src/testbed/gnunet-cmd.c
deleted file mode 100644
index f232bd805..000000000
--- a/src/testbed/gnunet-cmd.c
+++ /dev/null
@@ -1,123 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2008--2013, 2016 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-cmd.c
23 *
24 * @brief Binary to start testcase plugins
25 *
26 * @author t3sserakt
27 */
28
29#include "platform.h"
30#include "gnunet_util_lib.h"
31#include "gnunet_testing_lib.h"
32#include "gnunet_testing_plugin.h"
33
34/**
35 * Generic logging shortcut
36 */
37#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
38
39#define NODE_BASE_IP "192.168.15."
40
41#define ROUTER_BASE_IP "92.68.150."
42
43/**
44 * Handle for a plugin.
45 */
46struct Plugin
47{
48 /**
49 * Name of the shared library.
50 */
51 char *library_name;
52
53 /**
54 * Plugin API.
55 */
56 struct GNUNET_TESTING_PluginFunctions *api;
57
58 char *node_ip;
59
60 char *plugin_name;
61
62 char *global_n;
63
64 char *local_m;
65
66 char *n;
67
68 char *m;
69};
70
71
72/**
73 * Main function to run the test cases.
74 *
75 * @param cls plugin to use.
76 *
77 */
78static void
79run (void *cls)
80{
81 struct Plugin *plugin = cls;
82 char *router_ip;
83 char *node_ip;
84
85 router_ip = GNUNET_malloc (strlen (ROUTER_BASE_IP) + strlen (plugin->m) + 1);
86 strcpy (router_ip, ROUTER_BASE_IP);
87 strcat (router_ip, plugin->m);
88
89 node_ip = GNUNET_malloc (strlen (NODE_BASE_IP) + strlen (plugin->n) + 1);
90 strcat (node_ip, NODE_BASE_IP);
91 strcat (node_ip, plugin->n);
92
93 plugin->api->start_testcase (NULL, router_ip, node_ip, NULL, NULL);
94
95}
96
97
98int
99main (int argc, char *const *argv)
100{
101 int rv = 0;
102 struct Plugin *plugin;
103
104 GNUNET_log_setup ("gnunet-cmd",
105 "DEBUG",
106 NULL);
107
108 plugin = GNUNET_new (struct Plugin);
109 plugin->api = GNUNET_PLUGIN_load (argv[0],
110 NULL);
111 plugin->library_name = GNUNET_strdup (argv[0]);
112
113 plugin->global_n = argv[1];
114 plugin->local_m = argv[2];
115 plugin->n = argv[3];
116 plugin->m = argv[4];
117
118 GNUNET_SCHEDULER_run (&run,
119 plugin);
120
121 GNUNET_free (plugin);
122 return rv;
123}
diff --git a/src/testbed/testbed_api.h b/src/testbed/testbed_api.h
index 9a54ca36c..d4ef832ad 100644
--- a/src/testbed/testbed_api.h
+++ b/src/testbed/testbed_api.h
@@ -37,11 +37,6 @@
37 */ 37 */
38#define HELPER_TESTBED_BINARY "gnunet-helper-testbed" 38#define HELPER_TESTBED_BINARY "gnunet-helper-testbed"
39 39
40/**
41 * Cmds Helper binary name
42 */
43#define HELPER_CMDS_BINARY "gnunet-cmds-helper"
44
45 40
46/** 41/**
47 * Enumeration of operations 42 * Enumeration of operations
@@ -185,6 +180,7 @@ struct OperationContext
185typedef void 180typedef void
186(*TESTBED_opcq_empty_cb) (void *cls); 181(*TESTBED_opcq_empty_cb) (void *cls);
187 182
183
188/** 184/**
189 * Handle to interact with a GNUnet testbed controller. Each 185 * Handle to interact with a GNUnet testbed controller. Each
190 * controller has at least one master handle which is created when the 186 * controller has at least one master handle which is created when the
diff --git a/src/testbed/testbed_api_cmd_controller.c b/src/testbed/testbed_api_cmd_controller.c
deleted file mode 100644
index 794b1ccf3..000000000
--- a/src/testbed/testbed_api_cmd_controller.c
+++ /dev/null
@@ -1,203 +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/testbed_api_cmd_controller.c
23 * @brief Command to create a controller.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29#include "gnunet-service-testbed.h"
30#include "testbed_api_hosts.h"
31#include "gnunet_testbed_ng_service.h"
32
33
34/**
35 * Generic logging shortcut
36 */
37#define LOG(kind, ...) \
38 GNUNET_log (kind, __VA_ARGS__)
39
40
41/**
42*
43*
44* @param cls closure
45* @param cmd current CMD being cleaned up.
46*/
47static void
48controller_cleanup (void *cls,
49 const struct GNUNET_TESTING_Command *cmd)
50{
51 (void) cls;
52}
53
54
55/**
56 * Signature of the event handler function called by the
57 * respective event controller.
58 *
59 * @param cls closure
60 * @param event information about the event
61 */
62static void
63controller_cb (void *cls,
64 const struct GNUNET_TESTBED_EventInformation *event)
65{
66 struct ControllerState *cs = cls;
67
68 if (NULL != event->details.operation_finished.emsg)
69 {
70 LOG (GNUNET_ERROR_TYPE_ERROR, "There was an operation error: %s\n",
71 event->details.operation_finished.emsg);
72 GNUNET_TESTBED_shutdown_controller (cs);
73 }
74 else if (NULL == event->details.operation_finished.generic)
75 {
76 GNUNET_TESTBED_operation_done (event->op);
77 }
78}
79
80
81static void
82controller_run (void *cls,
83 const struct GNUNET_TESTING_Command *cmd,
84 struct GNUNET_TESTING_Interpreter *is)
85{
86 struct ControllerState *cs = cls;
87
88 cs->is = is;
89
90 cs->controller =
91 GNUNET_TESTBED_controller_connect (cs->host, cs->event_mask, &controller_cb,
92 cs);
93
94
95}
96
97/**
98*
99*
100* @param cls closure.
101* @param[out] ret result
102* @param trait name of the trait.
103* @param index index number of the object to offer.
104* @return #GNUNET_OK on success.
105*/
106static int
107controller_traits (void *cls,
108 const void **ret,
109 const char *trait,
110 unsigned int index)
111{
112 (void) cls;
113
114 struct ControllerState *cs = cls;
115
116
117 struct GNUNET_TESTING_Trait traits[] = {
118 {
119 .index = 0,
120 .trait_name = "controller",
121 .ptr = (const void *) cs->controller,
122 },
123 GNUNET_TESTING_trait_end ()
124 };
125
126 return GNUNET_TESTING_get_trait (traits,
127 ret,
128 trait,
129 index);
130 return GNUNET_OK;
131}
132
133
134/**
135 * Offer data from trait
136 *
137 * @param cmd command to extract the controller from.
138 * @param pt pointer to controller.
139 * @return #GNUNET_OK on success.
140 */
141int
142GNUNET_TESTBED_get_trait_controller (const struct GNUNET_TESTING_Command *cmd,
143 struct GNUNET_TESTBED_Controller **
144 controller)
145{
146 return cmd->traits (cmd->cls,
147 (const void **) controller,
148 "controller",
149 (unsigned int) 0);
150}
151
152
153/**
154 * Shutdown nicely
155 *
156 * @param cs controller state.
157 */
158void
159GNUNET_TESTBED_shutdown_controller (struct ControllerState *cs)
160{
161 LOG (GNUNET_ERROR_TYPE_DEBUG,
162 "Shutting down...\n");
163
164 cs->controller_going_down = GNUNET_YES;
165
166 if (NULL != cs->abort_task)
167 GNUNET_SCHEDULER_cancel (cs->abort_task);
168 if (NULL != cs->reg_handle)
169 GNUNET_TESTBED_cancel_registration (cs->reg_handle);
170 if (NULL != cs->controller)
171 GNUNET_TESTBED_controller_disconnect (cs->controller);
172 if (NULL != cs->cfg)
173 GNUNET_CONFIGURATION_destroy (cs->cfg);
174 if (NULL != cs->cp)
175 GNUNET_TESTBED_controller_stop (cs->cp);
176 if (NULL != cs->host)
177 GNUNET_TESTBED_host_destroy (cs->host);
178}
179
180
181
182struct GNUNET_TESTING_Command
183GNUNET_TESTBED_cmd_controller (const char *label,
184 const char *host,
185 uint64_t event_mask)
186{
187 struct ControllerState *cs;
188
189 cs = GNUNET_new (struct ControllerState);
190 cs->event_mask = event_mask;
191 cs->hostname = host;
192
193
194 struct GNUNET_TESTING_Command cmd = {
195 .cls = cs,
196 .label = label,
197 .run = &controller_run,
198 .cleanup = &controller_cleanup,
199 .traits = &controller_traits
200 };
201
202 return cmd;
203}
diff --git a/src/testbed/testbed_api_cmd_peer.c b/src/testbed/testbed_api_cmd_peer.c
deleted file mode 100644
index 2e253e408..000000000
--- a/src/testbed/testbed_api_cmd_peer.c
+++ /dev/null
@@ -1,281 +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 * @file testbed/testbed_api_cmd_peer.c
24 * @brief Command to create a peer.
25 * @author t3sserakt
26 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_testing_ng_lib.h"
30#include "gnunet_testbed_ng_service.h"
31#include "gnunet-service-testbed.h"
32#include "testbed_api_peers.h"
33
34
35/**
36 * Generic logging shortcut
37 */
38#define LOG(kind, ...) \
39 GNUNET_log (kind, __VA_ARGS__)
40
41
42/**
43*
44*
45* @param cls closure.
46* @param[out] ret result
47* @param trait name of the trait.
48* @param index index number of the object to offer.
49* @return #GNUNET_OK on success.
50*/
51static int
52peer_traits (void *cls,
53 const void **ret,
54 const char *trait,
55 unsigned int index)
56{
57 struct PeerCmdState *ps = cls;
58
59 struct GNUNET_TESTING_Trait traits[] = {
60 {
61 .index = 0,
62 .trait_name = "peer",
63 .ptr = (const void *) ps->peer,
64 },
65 GNUNET_TESTING_trait_end ()
66 };
67
68 return GNUNET_TESTING_get_trait (traits,
69 ret,
70 trait,
71 index);
72
73 return GNUNET_OK;
74}
75
76/**
77 * Offer data from trait
78 *
79 * @param cmd command to extract the controller from.
80 * @param peer pointer GNUNET_TESTBED_PEER
81 * @return #GNUNET_OK on success.
82 */
83int
84GNUNET_TESTBED_get_trait_peer (const struct GNUNET_TESTING_Command *cmd,
85 struct GNUNET_TESTBED_Peer **
86 peer)
87{
88 return cmd->traits (cmd->cls,
89 (const void **) peer,
90 "peer",
91 (unsigned int) 0);
92}
93
94
95/**
96*
97*
98* @param cls closure
99* @param cmd current CMD being cleaned up.
100*/
101static void
102peer_cleanup (void *cls,
103 const struct GNUNET_TESTING_Command *cmd)
104{
105 (void) cls;
106}
107
108
109/**
110 * abort task to run on test timed out
111 *
112 * @param cls NULL
113 * @param tc the task context
114 */
115static void
116do_abort (void *cls)
117{
118 struct PeerCmdState *ps = cls;
119
120 if (GNUNET_NO == ps->peer_ready)
121 {
122 LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
123 ps->abort_task = NULL;
124 GNUNET_TESTBED_shutdown_peer (ps);
125 }
126}
127
128
129/**
130 * Functions of this signature are called when a peer has been successfully
131 * created
132 *
133 * @param cls the closure from GNUNET_TESTBED_peer_create()
134 * @param emsg MAY contain an error description, if starting peer failed.
135 */
136static void
137peer_started_cb (void *cls,
138 const char *emsg)
139{
140 struct PeerCmdState *ps = cls;
141
142 GNUNET_TESTBED_operation_done (ps->operation);
143 if (NULL == emsg)
144 {
145 ps->peer_ready = GNUNET_YES;
146 }
147 else
148 {
149 LOG (GNUNET_ERROR_TYPE_ERROR, "There was an error starting a peer: %s\n",
150 emsg);
151 }
152
153}
154
155
156/**
157 * Functions of this signature are called when a peer has been successfully
158 * created
159 *
160 * @param cls the closure from GNUNET_TESTBED_peer_create()
161 * @param peer the handle for the created peer; NULL on any error during
162 * creation
163 * @param emsg NULL if peer is not NULL; else MAY contain the error description
164 */
165static void
166peer_create_cb (void *cls,
167 struct GNUNET_TESTBED_Peer *peer,
168 const char *emsg)
169{
170 struct PeerCmdState *ps = cls;
171
172 ps->peer = peer;
173 GNUNET_TESTBED_operation_done (ps->operation);
174 ps->operation = GNUNET_TESTBED_peer_start (NULL,
175 peer,
176 &peer_started_cb,
177 ps);
178}
179
180
181static void
182peer_run (void *cls,
183 const struct GNUNET_TESTING_Command *cmd,
184 struct GNUNET_TESTING_Interpreter *is)
185{
186 struct PeerCmdState *ps = cls;
187 const struct GNUNET_TESTING_Command *controller_cmd;
188 struct GNUNET_TESTBED_Controller *controller;
189
190 ps->is = is;
191 controller_cmd = GNUNET_TESTING_interpreter_lookup_command (
192 ps->controller_label);
193 GNUNET_TESTBED_get_trait_controller (controller_cmd,
194 &controller);
195 ps->host = GNUNET_TESTBED_host_create (ps->hostname, ps->username, ps->cfg,
196 ps->port);
197 ps->operation =
198 GNUNET_TESTBED_peer_create (controller,
199 ps->host,
200 ps->cfg,
201 &peer_create_cb,
202 ps);
203
204 ps->abort_task =
205 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
206 (GNUNET_TIME_UNIT_MINUTES, 5),
207 &do_abort,
208 ps);
209}
210
211
212void
213peer_stopped_cb (void *cls,
214 const char *emsg)
215{
216 struct PeerCmdState *ps = cls;
217
218 if (NULL != emsg)
219 {
220 LOG (GNUNET_ERROR_TYPE_ERROR, "There was an error stopping a peer: %s\n",
221 emsg);
222 }
223 GNUNET_TESTBED_operation_done (ps->operation);
224 GNUNET_TESTBED_peer_destroy (ps->peer);
225}
226
227
228/**
229 * Shutdown nicely
230 *
231 * @param cs controller state.
232 */
233void
234GNUNET_TESTBED_shutdown_peer (struct PeerCmdState *ps)
235{
236 LOG (GNUNET_ERROR_TYPE_DEBUG,
237 "Shutting down...\n");
238
239 ps->peer_going_down = GNUNET_YES;
240
241 if (NULL != ps->abort_task)
242 GNUNET_SCHEDULER_cancel (ps->abort_task);
243 if (NULL != ps->cfg)
244 GNUNET_CONFIGURATION_destroy (ps->cfg);
245 if (NULL != ps->host)
246 GNUNET_TESTBED_host_destroy (ps->host);
247
248 GNUNET_TESTBED_operation_done (ps->operation);
249 ps->operation = GNUNET_TESTBED_peer_stop (NULL, ps->peer, peer_stopped_cb,
250 ps);
251
252}
253
254
255struct GNUNET_TESTING_Command
256GNUNET_TESTBED_cmd_peer (const char *label,
257 const char *controller_label,
258 const char *hostname,
259 const char *username,
260 uint16_t port,
261 struct GNUNET_CONFIGURATION_Handle *cfg)
262{
263 struct PeerCmdState *ps;
264
265 ps = GNUNET_new (struct PeerCmdState);
266 ps->hostname = hostname;
267 ps->username = username;
268 ps->port = port;
269 ps->cfg = cfg;
270 ps->controller_label = controller_label;
271
272 struct GNUNET_TESTING_Command cmd = {
273 .cls = ps,
274 .label = label,
275 .run = &peer_run,
276 .cleanup = &peer_cleanup,
277 .traits = &peer_traits
278 };
279
280 return cmd;
281}
diff --git a/src/testbed/testbed_api_cmd_peer_store.c b/src/testbed/testbed_api_cmd_peer_store.c
deleted file mode 100644
index fc96f589c..000000000
--- a/src/testbed/testbed_api_cmd_peer_store.c
+++ /dev/null
@@ -1,60 +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/testbed_api_cmd_peer_store.c
23 * @brief Command to start the peer store service of a peer.
24 * @author t3sserakt
25 */
26
27
28static void
29service_run (void *cls,
30 const struct GNUNET_TESTING_Command *cmd,
31 struct GNUNET_TESTING_Interpreter *is)
32{
33 struct PeerStoreState *pss = cls;
34
35 pss->psh = GNUNET_PEERSTORE_connect (pss->cfg);
36 GNUNET_TESTING_interpreter_next (ps->is);
37}
38
39
40struct GNUNET_TESTING_Command
41GNUNET_TESTBED_cmd_peer_store (const char *label,
42 struct GNUNET_CONFIGURATION_Handle *cfg)
43{
44
45 struct PeerStoreState *pss;
46
47 pss = GNUNET_new (struct PeerStoreState);
48 pss->cfg = cfg;
49
50 struct GNUNET_TESTING_Command cmd = {
51 .cls = pss,
52 .label = label,
53 .run = &peer_store_run,
54 .cleanup = &peer_store_cleanup,
55 .traits = &peer_store_traits
56 };
57
58 return cmd;
59
60}
diff --git a/src/testbed/testbed_api_cmd_send_peer_ready.c b/src/testbed/testbed_api_cmd_send_peer_ready.c
deleted file mode 100644
index f175a3e18..000000000
--- a/src/testbed/testbed_api_cmd_send_peer_ready.c
+++ /dev/null
@@ -1,103 +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 "testbed_helper.h"
30
31
32struct SendPeerReadyState
33{
34 TESTBED_CMD_HELPER_write_cb write_message;
35
36 struct GNUNET_CMDS_PEER_STARTED *reply;
37};
38
39
40static int
41send_peer_ready_traits (void *cls,
42 const void **ret,
43 const char *trait,
44 unsigned int index)
45{
46 return GNUNET_OK;
47}
48
49
50static void
51send_peer_ready_cleanup (void *cls,
52 const struct GNUNET_TESTING_Command *cmd)
53{
54 struct SendPeerReadyState *sprs = cls;
55
56 GNUNET_free (sprs->reply);
57 GNUNET_free (sprs);
58}
59
60
61static void
62send_peer_ready_run (void *cls,
63 const struct GNUNET_TESTING_Command *cmd,
64 struct GNUNET_TESTING_Interpreter *is)
65{
66 struct SendPeerReadyState *sprs = cls;
67 struct GNUNET_CMDS_PEER_STARTED *reply;
68 size_t msg_length;
69
70 msg_length = sizeof(struct GNUNET_CMDS_PEER_STARTED);
71 reply = GNUNET_new (struct GNUNET_CMDS_PEER_STARTED);
72 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED);
73 reply->header.size = htons ((uint16_t) msg_length);
74 sprs->reply = reply;
75 sprs->write_message ((struct GNUNET_MessageHeader *) reply, msg_length);
76}
77
78
79/**
80 * Create command.
81 *
82 * @param label name for command.
83 * @return command.
84 */
85struct GNUNET_TESTING_Command
86GNUNET_TESTING_cmd_send_peer_ready (const char *label,
87 TESTBED_CMD_HELPER_write_cb write_message)
88{
89 struct SendPeerReadyState *sprs;
90
91 sprs = GNUNET_new (struct SendPeerReadyState);
92 sprs->write_message = write_message;
93
94 struct GNUNET_TESTING_Command cmd = {
95 .cls = sprs,
96 .label = label,
97 .run = &send_peer_ready_run,
98 .cleanup = &send_peer_ready_cleanup,
99 .traits = &send_peer_ready_traits
100 };
101
102 return cmd;
103}
diff --git a/src/testbed/testbed_api_cmd_tng_connect.c b/src/testbed/testbed_api_cmd_tng_connect.c
deleted file mode 100644
index e52cd3c76..000000000
--- a/src/testbed/testbed_api_cmd_tng_connect.c
+++ /dev/null
@@ -1,55 +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 * @file testbed/testbed_api_cmd_peer.c
24 * @brief Command to create a peer.
25 * @author t3sserakt
26 */
27
28
29static void
30tng_connect_run (void *cls,
31 const struct GNUNET_TESTING_Command *cmd,
32 struct GNUNET_TESTING_Interpreter *is)
33{
34 struct TngConnectState *tcs = cls;
35
36 tcs->ah = GNUNET_TRANSPORT_application_init (tcs->cfg);
37}
38
39struct GNUNET_TESTING_Command
40GNUNET_TESTBED_cmd_tng_connect (const char *label)
41{
42 struct TngConnectState *tcs;
43
44 ts = GNUNET_new (struct TngConnectState);
45
46 struct GNUNET_TESTING_Command cmd = {
47 .cls = tcs,
48 .label = label,
49 .run = &tng_connect_run,
50 .cleanup = &tmg_connect_cleanup,
51 .traits = &tng_connect_traits
52 };
53
54 return cmd;
55}
diff --git a/src/testbed/testbed_api_cmd_tng_service.c b/src/testbed/testbed_api_cmd_tng_service.c
deleted file mode 100644
index cce2e14e3..000000000
--- a/src/testbed/testbed_api_cmd_tng_service.c
+++ /dev/null
@@ -1,276 +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/testbed_api_cmd_tng.c
23 * @brief Command to start the transport service of a peer.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29#include "gnunet-service-testbed.h"
30#include "testbed_api_hosts.h"
31#include "gnunet_testbed_ng_service.h"
32
33/**
34 * Generic logging shortcut
35 */
36#define LOG(kind, ...) \
37 GNUNET_log (kind, __VA_ARGS__)
38
39
40/**
41 * abort task to run on test timed out
42 *
43 * @param cls NULL
44 * @param tc the task context
45 */
46static void
47do_abort (void *cls)
48{
49 struct TngState *ts = cls;
50
51 if (GNUNET_NO == ts->service_ready)
52 {
53 LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
54 ts->abort_task = NULL;
55 GNUNET_TESTBED_shutdown_service (ts);
56 }
57}
58
59/**
60*
61*
62* @param cls closure
63* @param cmd current CMD being cleaned up.
64*/
65static void
66tng_service_cleanup (void *cls,
67 const struct GNUNET_TESTING_Command *cmd)
68{
69 (void) cls;
70}
71
72/**
73*
74*
75* @param cls closure.
76* @param[out] ret result
77* @param trait name of the trait.
78* @param index index number of the object to offer.
79* @return #GNUNET_OK on success.
80*/
81static int
82tng_service_traits (void *cls,
83 const void **ret,
84 const char *trait,
85 unsigned int index)
86{
87 (void) cls;
88 return GNUNET_OK;
89}
90
91
92static void *
93notify_connect (void *cls,
94 const struct GNUNET_PeerIdentity *peer,
95 struct GNUNET_MQ_Handle *mq)
96{
97 struct TngState *ts = cls;
98
99 if (NULL != emsg)
100 {
101 LOG (GNUNET_ERROR_TYPE_ERROR,
102 "There was an error starting the transport subsystem: %s\n",
103 emsg);
104 }
105 GNUNET_TESTING_interpreter_next (ps->is);
106 return ts->nc (ts->cb_cls);
107
108}
109
110
111static void
112notify_disconnect (void *cls,
113 const struct GNUNET_PeerIdentity *peer,
114 void *handler_cls)
115{
116}
117
118
119
120
121/**
122 * Adapter function called to establish a connection to
123 * a service.
124 *
125 * @param cls closure
126 * @param cfg configuration of the peer to connect to; will be available until
127 * GNUNET_TESTBED_operation_done() is called on the operation returned
128 * from GNUNET_TESTBED_service_connect()
129 * @return service handle to return in 'op_result', NULL on error
130 */
131static void *
132connect_adapter (void *cls,
133 const struct GNUNET_CONFIGURATION_Handle *cfg)
134{
135 struct TngState *ts = cls;
136
137 service_handle = GNUNET_TRANSPORT_core_connect (cfg,
138 ts->peer_identity,
139 ts->handlers,
140 ts,
141 &notify_connect,
142 &notify_disconnect);
143 return service_handle;
144}
145
146
147/**
148 * Adapter function called to destroy a connection to
149 * a service.
150 *
151 * @param cls closure
152 * @param op_result service handle returned from the connect adapter
153 */
154static void
155disconnect_adapter (void *cls,
156 void *op_result)
157{
158}
159
160/**
161 * Callback to be called when a service connect operation is completed
162 *
163 * @param cls the callback closure from functions generating an operation
164 * @param op the operation that has been finished
165 * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter()
166 * @param emsg error message in case the operation has failed; will be NULL if
167 * operation has executed successfully.
168 */
169static void
170service_connect_comp_cb (void *cls,
171 struct GNUNET_TESTBED_Operation *op,
172 void *ca_result,
173 const char *emsg)
174{
175 struct TngState *ts = cls;
176
177 if (NULL != emsg)
178 {
179 LOG (GNUNET_ERROR_TYPE_DEBUG,
180 "An error occurred connecting to service %s\n",
181 emsg);
182 GNUNET_TESTBED_operation_done (ts->operation);
183 }
184}
185
186
187/**
188 * Callback to be called when the requested peer information is available
189 *
190 * @param cls the closure from GNUNET_TESTBED_peer_getinformation()
191 * @param op the operation this callback corresponds to
192 * @param pinfo the result; will be NULL if the operation has failed
193 * @param emsg error message if the operation has failed;
194 * NULL if the operation is successful
195 */
196static void
197pi_cb (void *cls,
198 struct GNUNET_TESTBED_Operation *op,
199 const struct GNUNET_TESTBED_PeerInformation *pinfo,
200 const char *emsg)
201{
202 struct TngState *ts = cls;
203
204 ts->peer_identity = pinfo->id;
205 ts->operation =
206 GNUNET_TESTBED_service_connect (NULL, peer, NULL,
207 &service_connect_comp_cb, ts,
208 &connect_adapter,
209 &disconnect_adapter,
210 ts);
211}
212
213
214static void
215tng_service_run (void *cls,
216 const struct GNUNET_TESTING_Command *cmd,
217 struct GNUNET_TESTING_Interpreter *is)
218{
219 struct TngState *ts = cls;
220 struct GNUNET_TESTBED_Peer *peer;
221 const struct GNUNET_TESTING_Command *peer_cmd;
222
223 ts->is = is;
224 peer_cmd = GNUNET_TESTING_interpreter_lookup_command (
225 ts->peer_label);
226 GNUNET_TESTBED_get_trait_peer (peer_cmd,
227 &peer);
228
229 ts->operation = GNUNET_TESTBED_peer_get_information (peer,
230 GNUNET_TESTBED_PIT_IDENTITY,
231 &pi_cb,
232 ts);
233}
234
235/**
236 * Shutdown nicely
237 *
238 * @param cs service state.
239 */
240void
241GNUNET_TESTBED_shutdown_service (struct TngState *cs)
242{
243 LOG (GNUNET_ERROR_TYPE_DEBUG,
244 "Shutting down...\n");
245}
246
247
248struct GNUNET_TESTING_Command
249GNUNET_TESTBED_cmd_tng_service (const char *label,
250 const char *peer_label,
251 const struct GNUNET_MQ_MessageHandler *handlers,
252 GNUNET_TRANSPORT_NotifyConnect nc,
253 void *cb_cls)
254
255{
256 struct TngState *ts;
257
258 ts = GNUNET_new (struct TngState);
259 ts->servicename = servicename;
260 ts->peer_label = peer_label;
261 ts->handlers = handlers;
262 ts->nc = nc;
263 ts->nd = nd;
264 ts->cb_cls;
265
266
267 struct GNUNET_TESTING_Command cmd = {
268 .cls = ts,
269 .label = label,
270 .run = &tng_service_run,
271 .cleanup = &tmg_service_cleanup,
272 .traits = &tng_service_traits
273 };
274
275 return cmd;
276}
diff --git a/src/testbed/testbed_api_hosts.c b/src/testbed/testbed_api_hosts.c
index d0a460fe6..1a8d9976d 100644
--- a/src/testbed/testbed_api_hosts.c
+++ b/src/testbed/testbed_api_hosts.c
@@ -964,10 +964,22 @@ gen_rsh_suffix_args (const char *const *append_args)
964} 964}
965 965
966 966
967void 967/**
968GNUNET_TESTBED_extract_cfg (struct GNUNET_TESTBED_Host *host, const struct 968 * Functions with this signature are called whenever a
969 GNUNET_MessageHeader *message) 969 * complete message is received by the tokenizer.
970 *
971 * Do not call GNUNET_SERVER_mst_destroy in callback
972 *
973 * @param cls closure
974 * @param client identification of the client
975 * @param message the actual message
976 *
977 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
978 */
979static int
980helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
970{ 981{
982 struct GNUNET_TESTBED_ControllerProc *cp = cls;
971 const struct GNUNET_TESTBED_HelperReply *msg; 983 const struct GNUNET_TESTBED_HelperReply *msg;
972 const char *hostname; 984 const char *hostname;
973 char *config; 985 char *config;
@@ -989,43 +1001,22 @@ GNUNET_TESTBED_extract_cfg (struct GNUNET_TESTBED_Host *host, const struct
989 xconfig_size)); 1001 xconfig_size));
990 /* Replace the configuration template present in the host with the 1002 /* Replace the configuration template present in the host with the
991 controller's running configuration */ 1003 controller's running configuration */
992 GNUNET_CONFIGURATION_destroy (host->cfg); 1004 GNUNET_CONFIGURATION_destroy (cp->host->cfg);
993 host->cfg = GNUNET_CONFIGURATION_create (); 1005 cp->host->cfg = GNUNET_CONFIGURATION_create ();
994 GNUNET_assert (GNUNET_CONFIGURATION_deserialize (host->cfg, 1006 GNUNET_assert (GNUNET_CONFIGURATION_deserialize (cp->host->cfg,
995 config, 1007 config,
996 config_size, 1008 config_size,
997 NULL)); 1009 NULL));
998 GNUNET_free (config); 1010 GNUNET_free (config);
999 if (NULL == (hostname = GNUNET_TESTBED_host_get_hostname (host))) 1011 if (NULL == (hostname = GNUNET_TESTBED_host_get_hostname (cp->host)))
1000 hostname = "localhost"; 1012 hostname = "localhost";
1001 /* Change the hostname so that we can connect to it */ 1013 /* Change the hostname so that we can connect to it */
1002 GNUNET_CONFIGURATION_set_value_string (host->cfg, 1014 GNUNET_CONFIGURATION_set_value_string (cp->host->cfg,
1003 "testbed", 1015 "testbed",
1004 "hostname", 1016 "hostname",
1005 hostname); 1017 hostname);
1006 host->locked = GNUNET_NO; 1018 cp->host->locked = GNUNET_NO;
1007} 1019 cp->host->controller_started = GNUNET_YES;
1008
1009/**
1010 * Functions with this signature are called whenever a
1011 * complete message is received by the tokenizer.
1012 *
1013 * Do not call GNUNET_SERVER_mst_destroy in callback
1014 *
1015 * @param cls closure
1016 * @param client identification of the client
1017 * @param message the actual message
1018 *
1019 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
1020 */
1021static int
1022helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
1023{
1024 struct GNUNET_TESTBED_ControllerProc *cp = cls;
1025 struct GNUNET_TESTBED_Host *host = cp->host;
1026
1027 GNUNET_TESTBED_extract_cfg (host, message);
1028
1029 cp->cb (cp->cls, cp->host->cfg, GNUNET_OK); 1020 cp->cb (cp->cls, cp->host->cfg, GNUNET_OK);
1030 return GNUNET_OK; 1021 return GNUNET_OK;
1031} 1022}
diff --git a/src/testbed/testbed_helper.h b/src/testbed/testbed_helper.h
index af90ce85d..817ad559d 100644
--- a/src/testbed/testbed_helper.h
+++ b/src/testbed/testbed_helper.h
@@ -84,60 +84,6 @@ struct GNUNET_TESTBED_HelperReply
84 * un-compressed */ 84 * un-compressed */
85}; 85};
86 86
87/**
88 * Initialization message for gnunet-cmds-testbed to start cmd binary.
89 */
90struct GNUNET_CMDS_HelperInit
91{
92 /**
93 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT
94 */
95 struct GNUNET_MessageHeader header;
96
97 /**
98 *
99 */
100 uint16_t plugin_name_size GNUNET_PACKED;
101
102 /* Followed by plugin name of the plugin running the test case. This is not NULL
103 * terminated */
104};
105
106/**
107 * Reply message from cmds helper process
108 */
109struct GNUNET_CMDS_HelperReply
110{
111 /**
112 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY
113 */
114 struct GNUNET_MessageHeader header;
115};
116
117struct GNUNET_CMDS_PEER_STARTED
118{
119 /**
120 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED
121 */
122 struct GNUNET_MessageHeader header;
123};
124
125struct GNUNET_CMDS_ALL_PEERS_STARTED
126{
127 /**
128 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED
129 */
130 struct GNUNET_MessageHeader header;
131};
132
133struct GNUNET_CMDS_LOCAL_FINISHED
134{
135 /**
136 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED
137 */
138 struct GNUNET_MessageHeader header;
139};
140
141GNUNET_NETWORK_STRUCT_END 87GNUNET_NETWORK_STRUCT_END
142#endif 88#endif
143/* end of testbed_helper.h */ 89/* end of testbed_helper.h */
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
index 868e3fcec..038f0cb08 100644
--- a/src/testing/Makefile.am
+++ b/src/testing/Makefile.am
@@ -11,12 +11,46 @@ pkgcfgdir= $(pkgdatadir)/config.d/
11dist_pkgcfg_DATA = \ 11dist_pkgcfg_DATA = \
12 testing.conf 12 testing.conf
13 13
14libexec_PROGRAMS = \
15 gnunet-cmds-helper
16
17plugindir = $(libdir)/gnunet
18
19plugin_LTLIBRARIES = \
20 libgnunet_test_testing_plugin_testcmd.la
21
14lib_LTLIBRARIES = \ 22lib_LTLIBRARIES = \
15 libgnunettesting.la 23 libgnunettesting.la
16 24
25gnunet_cmds_helper_SOURCES = \
26 gnunet-cmds-helper.c
27gnunet_cmds_helper_LDADD = $(XLIB) \
28 $(top_builddir)/src/util/libgnunetutil.la \
29 libgnunettesting.la \
30 $(LTLIBINTL) $(Z_LIBS)
31
32libgnunet_test_testing_plugin_testcmd_la_SOURCES = \
33 test_testing_plugin_testcmd.c
34libgnunet_test_testing_plugin_testcmd_la_LIBADD = \
35 $(top_builddir)/src/util/libgnunetutil.la \
36 $(top_builddir)/src/arm/libgnunetarm.la \
37 libgnunettesting.la \
38 $(top_builddir)/src/statistics/libgnunetstatistics.la \
39 $(LTLIBINTL)
40libgnunet_test_testing_plugin_testcmd_la_LDFLAGS = \
41 $(GN_PLUGIN_LDFLAGS)
42
17libgnunettesting_la_SOURCES = \ 43libgnunettesting_la_SOURCES = \
18 testing.c \ 44 testing_api_cmd_local_test_finished.c \
45 testing_api_cmd_send_peer_ready.c \
46 testing_api_cmd_block_until_all_peers_started.c \
47 testing_api_cmd_netjail_start.c \
48 testing_api_cmd_netjail_start_testsystem.c \
49 testing_api_cmd_netjail_stop_testsystem.c \
50 testing_api_cmd_netjail_stop.c \
51 testing.c testing.h \
19 testing_api_cmd_system_create.c \ 52 testing_api_cmd_system_create.c \
53 testing_api_cmd_system_destroy.c \
20 testing_api_cmd_batch.c \ 54 testing_api_cmd_batch.c \
21 testing_api_cmd_hello_world.c \ 55 testing_api_cmd_hello_world.c \
22 testing_api_cmd_hello_world_birth.c \ 56 testing_api_cmd_hello_world_birth.c \
@@ -28,9 +62,6 @@ libgnunettesting_la_LIBADD = \
28 $(top_builddir)/src/arm/libgnunetarm.la \ 62 $(top_builddir)/src/arm/libgnunetarm.la \
29 $(top_builddir)/src/util/libgnunetutil.la \ 63 $(top_builddir)/src/util/libgnunetutil.la \
30 $(LTLIBINTL) 64 $(LTLIBINTL)
31libgnunettesting_la_DEPENDENCIES = \
32 $(top_builddir)/src/arm/libgnunetarm.la \
33 $(top_builddir)/src/util/libgnunetutil.la
34libgnunettesting_la_LDFLAGS = \ 65libgnunettesting_la_LDFLAGS = \
35 $(GN_LIB_LDFLAGS) \ 66 $(GN_LIB_LDFLAGS) \
36 -version-info 2:0:1 67 -version-info 2:0:1
@@ -56,6 +87,7 @@ list_keys_LDADD = \
56 87
57 88
58check_PROGRAMS = \ 89check_PROGRAMS = \
90 test_testing_api_cmd_netjail \
59 test_testing_hello_world \ 91 test_testing_hello_world \
60 test_testing_portreservation \ 92 test_testing_portreservation \
61 test_testing_servicestartup \ 93 test_testing_servicestartup \
@@ -66,6 +98,7 @@ check_PROGRAMS = \
66if ENABLE_TEST_RUN 98if ENABLE_TEST_RUN
67AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; 99AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
68TESTS = \ 100TESTS = \
101 test_testing_api_cmd_netjail \
69 test_testing_hello_world \ 102 test_testing_hello_world \
70 test_testing_portreservation \ 103 test_testing_portreservation \
71 test_testing_peerstartup \ 104 test_testing_peerstartup \
@@ -73,6 +106,12 @@ TESTS = \
73 test_testing_servicestartup 106 test_testing_servicestartup
74endif 107endif
75 108
109test_testing_api_cmd_netjail_SOURCES = \
110 test_testing_api_cmd_netjail.c
111test_testing_api_cmd_netjail_LDADD = \
112 libgnunettesting.la \
113 $(top_builddir)/src/util/libgnunetutil.la
114
76test_testing_hello_world_SOURCES = \ 115test_testing_hello_world_SOURCES = \
77 test_testing_hello_world.c 116 test_testing_hello_world.c
78test_testing_hello_world_LDADD = \ 117test_testing_hello_world_LDADD = \
@@ -111,4 +150,5 @@ test_testing_sharedservices_LDADD = \
111 150
112EXTRA_DIST = \ 151EXTRA_DIST = \
113 test_testing_defaults.conf \ 152 test_testing_defaults.conf \
114 test_testing_sharedservices.conf 153 test_testing_sharedservices.conf \
154 testing_cmds.h
diff --git a/src/testbed/gnunet-cmds-helper.c b/src/testing/gnunet-cmds-helper.c
index 113e3c386..21ea33888 100644
--- a/src/testbed/gnunet-cmds-helper.c
+++ b/src/testing/gnunet-cmds-helper.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2008--2013, 2016 GNUnet e.V. 3 Copyright (C) 2021 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
@@ -39,16 +39,15 @@
39#include "platform.h" 39#include "platform.h"
40#include "gnunet_util_lib.h" 40#include "gnunet_util_lib.h"
41#include "gnunet_testing_lib.h" 41#include "gnunet_testing_lib.h"
42#include "gnunet_testbed_service.h" 42#include "gnunet_testing_ng_lib.h"
43#include "testbed_helper.h" 43#include "testing_cmds.h"
44#include "testbed_api.h"
45#include "gnunet_testing_plugin.h" 44#include "gnunet_testing_plugin.h"
46#include <zlib.h> 45#include <zlib.h>
47 46
48 47
49/** 48/**
50 * Generic logging shortcut 49 * Generic logging shortcut
51 */ 50testing_api_cmd_block_until_all_peers_started.c */
52#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) 51#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
53 52
54/** 53/**
@@ -75,27 +74,71 @@ struct Plugin
75 */ 74 */
76 struct GNUNET_TESTING_PluginFunctions *api; 75 struct GNUNET_TESTING_PluginFunctions *api;
77 76
77 /**
78 * IP address of the specific node the helper is running for.
79 *
80 */
78 char *node_ip; 81 char *node_ip;
79 82
83 /**
84 * Name of the test case plugin.
85 *
86 */
80 char *plugin_name; 87 char *plugin_name;
81 88
89 /**
90 * The number of namespaces
91 *
92 */
82 char *global_n; 93 char *global_n;
83 94
95 /**
96 * The number of local nodes per namespace.
97 *
98 */
84 char *local_m; 99 char *local_m;
85 100
101 /**
102 * The number of the namespace this node is in.
103 *
104 */
86 char *n; 105 char *n;
87 106
107 /**
108 * The number of the node in the namespace.
109 *
110 */
88 char *m; 111 char *m;
89}; 112};
90 113
114/**
115 * Struct with information about a specific node and the whole network namespace setup.
116 *
117 */
91struct NodeIdentifier 118struct NodeIdentifier
92{ 119{
120 /**
121 * The number of the namespace this node is in.
122 *
123 */
93 char *n; 124 char *n;
94 125
126 /**
127 * The number of the node in the namespace.
128 *
129 */
95 char *m; 130 char *m;
96 131
132 /**
133 * The number of namespaces
134 *
135 */
97 char *global_n; 136 char *global_n;
98 137
138 /**
139 * The number of local nodes per namespace.
140 *
141 */
99 char *local_m; 142 char *local_m;
100}; 143};
101 144
@@ -124,8 +167,8 @@ struct Plugin *plugin;
124 167
125/** 168/**
126 * The process handle to the testbed service 169 * The process handle to the testbed service
127 */ 170
128static struct GNUNET_OS_Process *cmd_binary_process; 171static struct GNUNET_OS_Process *cmd_binary_process;*/
129 172
130/** 173/**
131 * Handle to the testing system 174 * Handle to the testing system
@@ -163,11 +206,6 @@ static struct GNUNET_SCHEDULER_Task *read_task_id;
163static struct GNUNET_SCHEDULER_Task *write_task_id; 206static struct GNUNET_SCHEDULER_Task *write_task_id;
164 207
165/** 208/**
166 * Task to kill the child
167 */
168static struct GNUNET_SCHEDULER_Task *child_death_task_id;
169
170/**
171 * Are we done reading messages from stdin? 209 * Are we done reading messages from stdin?
172 */ 210 */
173static int done_reading; 211static int done_reading;
@@ -188,8 +226,6 @@ shutdown_task (void *cls)
188{ 226{
189 227
190 LOG_DEBUG ("Shutting down.\n"); 228 LOG_DEBUG ("Shutting down.\n");
191 LOG (GNUNET_ERROR_TYPE_ERROR,
192 "Shutting down tokenizer!\n");
193 229
194 if (NULL != read_task_id) 230 if (NULL != read_task_id)
195 { 231 {
@@ -205,11 +241,6 @@ shutdown_task (void *cls)
205 GNUNET_free (wc->data); 241 GNUNET_free (wc->data);
206 GNUNET_free (wc); 242 GNUNET_free (wc);
207 } 243 }
208 if (NULL != child_death_task_id)
209 {
210 GNUNET_SCHEDULER_cancel (child_death_task_id);
211 child_death_task_id = NULL;
212 }
213 if (NULL != stdin_fd) 244 if (NULL != stdin_fd)
214 (void) GNUNET_DISK_file_close (stdin_fd); 245 (void) GNUNET_DISK_file_close (stdin_fd);
215 if (NULL != stdout_fd) 246 if (NULL != stdout_fd)
@@ -236,9 +267,6 @@ write_task (void *cls)
236 struct WriteContext *wc = cls; 267 struct WriteContext *wc = cls;
237 ssize_t bytes_wrote; 268 ssize_t bytes_wrote;
238 269
239 LOG (GNUNET_ERROR_TYPE_ERROR,
240 "Writing data!\n");
241
242 GNUNET_assert (NULL != wc); 270 GNUNET_assert (NULL != wc);
243 write_task_id = NULL; 271 write_task_id = NULL;
244 bytes_wrote = GNUNET_DISK_file_write (stdout_fd, 272 bytes_wrote = GNUNET_DISK_file_write (stdout_fd,
@@ -257,12 +285,8 @@ write_task (void *cls)
257 { 285 {
258 GNUNET_free (wc->data); 286 GNUNET_free (wc->data);
259 GNUNET_free (wc); 287 GNUNET_free (wc);
260 LOG (GNUNET_ERROR_TYPE_ERROR,
261 "Written successfully!\n");
262 return; 288 return;
263 } 289 }
264 LOG (GNUNET_ERROR_TYPE_ERROR,
265 "Written data!\n");
266 write_task_id = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, 290 write_task_id = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
267 stdout_fd, 291 stdout_fd,
268 &write_task, 292 &write_task,
@@ -271,39 +295,14 @@ write_task (void *cls)
271 295
272 296
273/** 297/**
274 * Task triggered whenever we receive a SIGCHLD (child 298 * Callback to write a message to the master loop.
275 * process died).
276 * 299 *
277 * @param cls closure, NULL if we need to self-restart
278 */ 300 */
279static void 301static void
280child_death_task (void *cls)
281{
282 const struct GNUNET_DISK_FileHandle *pr;
283 char c[16];
284
285 pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
286 child_death_task_id = NULL;
287 /* consume the signal */
288 GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof(c)));
289 LOG_DEBUG ("Got SIGCHLD\n");
290
291 LOG_DEBUG ("Child hasn't died. Resuming to monitor its status\n");
292 child_death_task_id =
293 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
294 pr,
295 &child_death_task,
296 NULL);
297}
298
299
300static void
301write_message (struct GNUNET_MessageHeader *message, size_t msg_length) 302write_message (struct GNUNET_MessageHeader *message, size_t msg_length)
302{ 303{
303 struct WriteContext *wc; 304 struct WriteContext *wc;
304 305
305 LOG (GNUNET_ERROR_TYPE_ERROR,
306 "enter write_message!\n");
307 wc = GNUNET_new (struct WriteContext); 306 wc = GNUNET_new (struct WriteContext);
308 wc->length = msg_length; 307 wc->length = msg_length;
309 wc->data = message; 308 wc->data = message;
@@ -312,38 +311,10 @@ write_message (struct GNUNET_MessageHeader *message, size_t msg_length)
312 stdout_fd, 311 stdout_fd,
313 &write_task, 312 &write_task,
314 wc); 313 wc);
315 LOG (GNUNET_ERROR_TYPE_ERROR,
316 "leave write_message!\n");
317} 314}
318 315
319 316
320/** 317/**
321 * Function to run the test cases.
322 *
323 * @param cls plugin to use.
324 *
325 */
326/*static void
327run_plugin (void *cls)
328{
329 struct Plugin *plugin = cls;
330 char *router_ip;
331 char *node_ip;
332
333 router_ip = GNUNET_malloc (strlen (ROUTER_BASE_IP) + strlen (plugin->m) + 1);
334 strcpy (router_ip, ROUTER_BASE_IP);
335 strcat (router_ip, plugin->m);
336
337 node_ip = GNUNET_malloc (strlen (NODE_BASE_IP) + strlen (plugin->n) + 1);
338 strcat (node_ip, NODE_BASE_IP);
339 strcat (node_ip, plugin->n);
340
341 plugin->api->start_testcase (&write_message, router_ip, node_ip);
342
343}*/
344
345
346/**
347 * Functions with this signature are called whenever a 318 * Functions with this signature are called whenever a
348 * complete message is received by the tokenizer. 319 * complete message is received by the tokenizer.
349 * 320 *
@@ -369,9 +340,6 @@ tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
369 char *router_ip; 340 char *router_ip;
370 char *node_ip; 341 char *node_ip;
371 342
372 LOG (GNUNET_ERROR_TYPE_ERROR,
373 "tokenizer \n");
374
375 msize = ntohs (message->size); 343 msize = ntohs (message->size);
376 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT == ntohs (message->type)) 344 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT == ntohs (message->type))
377 { 345 {
@@ -391,27 +359,10 @@ tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
391 359
392 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-cmd"); 360 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-cmd");
393 361
394 LOG (GNUNET_ERROR_TYPE_ERROR,
395 "plugin_name: %s \n",
396 plugin_name);
397
398 // cmd_binary_process = GNUNET_OS_start_process (
399 /*GNUNET_OS_INHERIT_STD_ERR verbose? ,
400 NULL,
401 NULL,
402 NULL,
403 binary,
404 plugin_name,
405 ni->global_n,
406 ni->local_m,
407 ni->n,
408 ni->m,
409 NULL);*/
410
411 plugin = GNUNET_new (struct Plugin); 362 plugin = GNUNET_new (struct Plugin);
412 plugin->api = GNUNET_PLUGIN_load (plugin_name, 363 plugin->api = GNUNET_PLUGIN_load (plugin_name,
413 NULL); 364 NULL);
414 plugin->library_name = GNUNET_strdup (plugin_name); 365 plugin->library_name = GNUNET_strdup (basename (plugin_name));
415 366
416 plugin->global_n = ni->global_n; 367 plugin->global_n = ni->global_n;
417 plugin->local_m = ni->local_m; 368 plugin->local_m = ni->local_m;
@@ -428,53 +379,17 @@ tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
428 strcat (node_ip, plugin->n); 379 strcat (node_ip, plugin->n);
429 380
430 plugin->api->start_testcase (&write_message, router_ip, node_ip, plugin->m, 381 plugin->api->start_testcase (&write_message, router_ip, node_ip, plugin->m,
431 plugin->n); 382 plugin->n, plugin->local_m);
432
433 LOG (GNUNET_ERROR_TYPE_ERROR,
434 "We got here!\n");
435
436 /*if (NULL == cmd_binary_process)
437 {
438 LOG (GNUNET_ERROR_TYPE_ERROR,
439 "Starting plugin failed!\n");
440 return GNUNET_SYSERR;
441 }*/
442
443 LOG (GNUNET_ERROR_TYPE_ERROR,
444 "We got here 2!\n");
445
446 LOG (GNUNET_ERROR_TYPE_ERROR,
447 "global_n: %s local_n: %s n: %s m: %s.\n",
448 ni->global_n,
449 ni->local_m,
450 ni->n,
451 ni->m);
452
453 LOG (GNUNET_ERROR_TYPE_ERROR,
454 "We got here 3!\n");
455 383
456 GNUNET_free (binary); 384 GNUNET_free (binary);
457 385
458 // done_reading = GNUNET_YES;
459
460 msg_length = sizeof(struct GNUNET_CMDS_HelperReply); 386 msg_length = sizeof(struct GNUNET_CMDS_HelperReply);
461 reply = GNUNET_new (struct GNUNET_CMDS_HelperReply); 387 reply = GNUNET_new (struct GNUNET_CMDS_HelperReply);
462 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY); 388 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY);
463 reply->header.size = htons ((uint16_t) msg_length); 389 reply->header.size = htons ((uint16_t) msg_length);
464 390
465 LOG (GNUNET_ERROR_TYPE_ERROR,
466 "We got here 4!\n");
467
468 write_message ((struct GNUNET_MessageHeader *) reply, msg_length); 391 write_message ((struct GNUNET_MessageHeader *) reply, msg_length);
469 392
470 LOG (GNUNET_ERROR_TYPE_ERROR,
471 "We got here 5!\n");
472
473 /*child_death_task_id = GNUNET_SCHEDULER_add_read_file (
474 GNUNET_TIME_UNIT_FOREVER_REL,
475 GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ),
476 &child_death_task,
477 NULL);*/
478 return GNUNET_OK; 393 return GNUNET_OK;
479 } 394 }
480 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED == ntohs ( 395 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED == ntohs (
@@ -515,8 +430,6 @@ read_task (void *cls)
515 if ((GNUNET_SYSERR == sread) || (0 == sread)) 430 if ((GNUNET_SYSERR == sread) || (0 == sread))
516 { 431 {
517 LOG_DEBUG ("STDIN closed\n"); 432 LOG_DEBUG ("STDIN closed\n");
518 LOG (GNUNET_ERROR_TYPE_ERROR,
519 "tokenizer shutting down during reading!\n");
520 GNUNET_SCHEDULER_shutdown (); 433 GNUNET_SCHEDULER_shutdown ();
521 return; 434 return;
522 } 435 }
@@ -530,8 +443,6 @@ read_task (void *cls)
530 return; 443 return;
531 } 444 }
532 LOG_DEBUG ("Read %u bytes\n", (unsigned int) sread); 445 LOG_DEBUG ("Read %u bytes\n", (unsigned int) sread);
533 LOG (GNUNET_ERROR_TYPE_ERROR,
534 "Read %u bytes\n", (unsigned int) sread);
535 /* FIXME: could introduce a GNUNET_MST_read2 to read 446 /* FIXME: could introduce a GNUNET_MST_read2 to read
536 directly from 'stdin_fd' and save a memcpy() here */ 447 directly from 'stdin_fd' and save a memcpy() here */
537 if (GNUNET_OK != 448 if (GNUNET_OK !=
@@ -625,13 +536,6 @@ main (int argc, char **argv)
625 ni->n = argv[3]; 536 ni->n = argv[3];
626 ni->m = argv[4]; 537 ni->m = argv[4];
627 538
628 LOG (GNUNET_ERROR_TYPE_ERROR,
629 "global_n: %s local_n: %s n: %s m: %s.\n",
630 ni->global_n,
631 ni->local_m,
632 ni->n,
633 ni->m);
634
635 status = GNUNET_OK; 539 status = GNUNET_OK;
636 if (NULL == 540 if (NULL ==
637 (sigpipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE))) 541 (sigpipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE)))
@@ -648,8 +552,7 @@ main (int argc, char **argv)
648 options, 552 options,
649 &run, 553 &run,
650 ni); 554 ni);
651 LOG (GNUNET_ERROR_TYPE_ERROR, 555
652 "run finished\n");
653 GNUNET_SIGNAL_handler_uninstall (shc_chld); 556 GNUNET_SIGNAL_handler_uninstall (shc_chld);
654 shc_chld = NULL; 557 shc_chld = NULL;
655 GNUNET_DISK_pipe_close (sigpipe); 558 GNUNET_DISK_pipe_close (sigpipe);
diff --git a/src/testbed/netjail_core.sh b/src/testing/netjail_core.sh
index 792b1df24..cf350d3fa 100755
--- a/src/testbed/netjail_core.sh
+++ b/src/testing/netjail_core.sh
@@ -1,7 +1,7 @@
1#!/bin/sh 1#!/bin/sh
2# 2#
3 3
4JAILOR=${SUDO_USER:?must run in sudo} 4
5 5
6# running with `sudo` is required to be 6# running with `sudo` is required to be
7# able running the actual commands as the 7# able running the actual commands as the
@@ -90,18 +90,27 @@ netjail_node_add_default() {
90} 90}
91 91
92netjail_node_exec() { 92netjail_node_exec() {
93 JAILOR=${SUDO_USER:?must run in sudo}
93 NODE=$1 94 NODE=$1
94 FD_IN=$2 95 FD_IN=$2
95 FD_OUT=$3 96 FD_OUT=$3
96 shift 3 97 shift 3
97 98
98 unshare -fp --kill-child -- ip netns exec $NODE sudo -u $JAILOR -- $@ 1>& $FD_OUT 0<& $FD_IN 99 ip netns exec $NODE sudo -u $JAILOR -- $@ 1>& $FD_OUT 0<& $FD_IN
99} 100}
100 101
101netjail_node_exec_without_fds() { 102netjail_node_exec_without_fds() {
103 JAILOR=${SUDO_USER:?must run in sudo}
104 NODE=$1
105 shift 1
106
107 ip netns exec $NODE sudo -u $JAILOR -- $@
108}
109
110netjail_node_exec_without_fds_and_sudo() {
102 NODE=$1 111 NODE=$1
103 shift 1 112 shift 1
104 113
105 unshare -fp --kill-child -- ip netns exec $NODE sudo -u $JAILOR -- $@ 114 ip netns exec $NODE $@
106} 115}
107 116
diff --git a/src/testbed/netjail_exec.sh b/src/testing/netjail_exec.sh
index b76d2e444..17a7caaac 100755
--- a/src/testbed/netjail_exec.sh
+++ b/src/testing/netjail_exec.sh
@@ -1,5 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2. "./../testbed/netjail_core.sh" 2. "./../testing/netjail_core.sh"
3 3
4set -eu 4set -eu
5set -x 5set -x
@@ -13,4 +13,4 @@ NODE=$(netjail_print_name "N" $N $M)
13 13
14 14
15 15
16netjail_node_exec_without_fds $NODE $3 $4 $5 $1 $2 16netjail_node_exec_without_fds_and_sudo $NODE $3 $4 $5 $1 $2
diff --git a/src/testbed/netjail_start.sh b/src/testing/netjail_start.sh
index 4c1c33c83..0984a3c42 100755
--- a/src/testbed/netjail_start.sh
+++ b/src/testing/netjail_start.sh
@@ -1,5 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2. "./../testbed/netjail_core.sh" 2. "./../testing/netjail_core.sh"
3 3
4set -eu 4set -eu
5set -x 5set -x
diff --git a/src/testbed/netjail_stop.sh b/src/testing/netjail_stop.sh
index 689bf7ae9..08f68cf7f 100755
--- a/src/testbed/netjail_stop.sh
+++ b/src/testing/netjail_stop.sh
@@ -1,5 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2. "./../testbed/netjail_core.sh" 2. "./../testing/netjail_core.sh"
3 3
4set -eu 4set -eu
5set -x 5set -x
diff --git a/src/testbed/test_testbed_api_cmd_netjail.c b/src/testing/test_testing_api_cmd_netjail.c
index 8bb9e40e8..543642109 100644
--- a/src/testbed/test_testbed_api_cmd_netjail.c
+++ b/src/testing/test_testing_api_cmd_netjail.c
@@ -25,7 +25,6 @@
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_testing_ng_lib.h" 27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_testbed_ng_service.h"
29#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
30 29
31 30
@@ -39,18 +38,18 @@ static void
39run (void *cls) 38run (void *cls)
40{ 39{
41 struct GNUNET_TESTING_Command commands[] = { 40 struct GNUNET_TESTING_Command commands[] = {
42 GNUNET_TESTBED_cmd_netjail_start ("netjail-start-1", 41 GNUNET_TESTING_cmd_netjail_start ("netjail-start-1",
43 "2", 42 "2",
44 "2"), 43 "2"),
45 GNUNET_TESTBED_cmd_netjail_start_testbed ("netjail-start-testbed-1", 44 GNUNET_TESTING_cmd_netjail_start_testing_system ("netjail-start-testbed-1",
46 "2", 45 "2",
47 "2", 46 "2",
48 "libgnunet_plugin_testcmd"), 47 "libgnunet_plugin_testcmd"),
49 GNUNET_TESTBED_cmd_stop_testbed ("stop-testbed", 48 GNUNET_TESTING_cmd_stop_testing_system ("stop-testbed",
50 "netjail-start-testbed-1", 49 "netjail-start-testbed-1",
51 "2", 50 "2",
52 "2"), 51 "2"),
53 GNUNET_TESTBED_cmd_netjail_stop ("netjail-stop-1", 52 GNUNET_TESTING_cmd_netjail_stop ("netjail-stop-1",
54 "2", 53 "2",
55 "2"), 54 "2"),
56 GNUNET_TESTING_cmd_end () 55 GNUNET_TESTING_cmd_end ()
diff --git a/src/testbed/plugin_testcmd.c b/src/testing/test_testing_plugin_testcmd.c
index 797826781..444272fcd 100644
--- a/src/testbed/plugin_testcmd.c
+++ b/src/testing/test_testing_plugin_testcmd.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2013, 2014 GNUnet e.V. 3 Copyright (C) 2021 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
@@ -26,7 +26,7 @@
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_testing_ng_lib.h" 27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
29#include "gnunet_testbed_ng_service.h" 29#include "gnunet_testing_ng_lib.h"
30 30
31/** 31/**
32 * Generic logging shortcut 32 * Generic logging shortcut
@@ -45,10 +45,11 @@ all_peers_started ()
45} 45}
46 46
47static void 47static void
48start_testcase (TESTBED_CMD_HELPER_write_cb write_message, char *router_ip, 48start_testcase (TESTING_CMD_HELPER_write_cb write_message, char *router_ip,
49 char *node_ip, 49 char *node_ip,
50 char *n, 50 char *n,
51 char *m) 51 char *m,
52 char *local_m)
52{ 53{
53 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); 54 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
54 55
diff --git a/src/testbed/testbed_api_cmd_block_until_all_peers_started.c b/src/testing/testing_api_cmd_block_until_all_peers_started.c
index 8659fbb46..e9d3f0ed3 100644
--- a/src/testbed/testbed_api_cmd_block_until_all_peers_started.c
+++ b/src/testing/testing_api_cmd_block_until_all_peers_started.c
@@ -32,12 +32,24 @@
32 */ 32 */
33#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) 33#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
34 34
35/**
36 * Struct with information for callbacks.
37 *
38 */
35struct BlockState 39struct BlockState
36{ 40{
41 /**
42 * Flag to indicate if all peers have started.
43 *
44 */
37 unsigned int *all_peers_started; 45 unsigned int *all_peers_started;
38}; 46};
39 47
40 48
49/**
50 * Trait function of this cmd does nothing.
51 *
52 */
41static int 53static int
42block_until_all_peers_started_traits (void *cls, 54block_until_all_peers_started_traits (void *cls,
43 const void **ret, 55 const void **ret,
@@ -48,6 +60,10 @@ block_until_all_peers_started_traits (void *cls,
48} 60}
49 61
50 62
63/**
64 * The cleanup function of this cmd frees resources the cmd allocated.
65 *
66 */
51static void 67static void
52block_until_all_peers_started_cleanup (void *cls, 68block_until_all_peers_started_cleanup (void *cls,
53 const struct GNUNET_TESTING_Command *cmd) 69 const struct GNUNET_TESTING_Command *cmd)
@@ -58,16 +74,24 @@ block_until_all_peers_started_cleanup (void *cls,
58} 74}
59 75
60 76
77/**
78 * This function does nothing but to start the cmd.
79 *
80 */
61static void 81static void
62block_until_all_peers_started_run (void *cls, 82block_until_all_peers_started_run (void *cls,
63 const struct GNUNET_TESTING_Command *cmd, 83 const struct GNUNET_TESTING_Command *cmd,
64 struct GNUNET_TESTING_Interpreter *is) 84 struct GNUNET_TESTING_Interpreter *is)
65{ 85{
66 LOG (GNUNET_ERROR_TYPE_ERROR, 86 LOG (GNUNET_ERROR_TYPE_DEBUG,
67 "block_until_all_peers_started_run!\n"); 87 "block_until_all_peers_started_run!\n");
68} 88}
69 89
70 90
91/**
92 * Function to check if BlockState#all_peers_started is GNUNET_YES. In that case interpreter_next will be called.
93 *
94 */
71static int 95static int
72block_until_all_peers_started_finish (void *cls, 96block_until_all_peers_started_finish (void *cls,
73 GNUNET_SCHEDULER_TaskCallback cont, 97 GNUNET_SCHEDULER_TaskCallback cont,
@@ -76,20 +100,10 @@ block_until_all_peers_started_finish (void *cls,
76 struct BlockState *bs = cls; 100 struct BlockState *bs = cls;
77 unsigned int *ret = bs->all_peers_started; 101 unsigned int *ret = bs->all_peers_started;
78 102
79 LOG (GNUNET_ERROR_TYPE_ERROR,
80 "We got here 10\n");
81
82 if (GNUNET_YES == *ret) 103 if (GNUNET_YES == *ret)
83 { 104 {
84 LOG (GNUNET_ERROR_TYPE_ERROR,
85 "We do not need to block anymore!\n");
86 cont (cont_cls); 105 cont (cont_cls);
87 } 106 }
88 else
89 {
90 LOG (GNUNET_ERROR_TYPE_ERROR,
91 "You shall not pass!\n");
92 }
93 107
94 return *ret; 108 return *ret;
95} 109}
@@ -99,6 +113,7 @@ block_until_all_peers_started_finish (void *cls,
99 * Create command. 113 * Create command.
100 * 114 *
101 * @param label name for command. 115 * @param label name for command.
116 * @param all_peers_started Flag which will be set from outside.
102 * @return command. 117 * @return command.
103 */ 118 */
104struct GNUNET_TESTING_Command 119struct GNUNET_TESTING_Command
@@ -108,10 +123,6 @@ GNUNET_TESTING_cmd_block_until_all_peers_started (const char *label,
108{ 123{
109 struct BlockState *bs; 124 struct BlockState *bs;
110 125
111 LOG (GNUNET_ERROR_TYPE_ERROR,
112 "we have all_peers_started: %u\n",
113 *all_peers_started);
114
115 bs = GNUNET_new (struct BlockState); 126 bs = GNUNET_new (struct BlockState);
116 bs->all_peers_started = all_peers_started; 127 bs->all_peers_started = all_peers_started;
117 128
diff --git a/src/testbed/testbed_api_cmd_local_test_finished.c b/src/testing/testing_api_cmd_local_test_finished.c
index 8829f1b9a..383de4c10 100644
--- a/src/testbed/testbed_api_cmd_local_test_finished.c
+++ b/src/testing/testing_api_cmd_local_test_finished.c
@@ -26,21 +26,38 @@
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_ng_lib.h"
29#include "testbed_helper.h" 29#include "testing_cmds.h"
30 30
31/** 31/**
32 * Generic logging shortcut 32 * Generic logging shortcut
33 */ 33 */
34#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) 34#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
35 35
36
37/**
38 * Struct to hold information for callbacks.
39 *
40 */
36struct LocalFinishedState 41struct LocalFinishedState
37{ 42{
38 TESTBED_CMD_HELPER_write_cb write_message; 43 /**
39 44 * Callback to write messages to the master loop.
45 *
46 */
47 TESTING_CMD_HELPER_write_cb write_message;
48
49 /**
50 * The message send back to the master loop.
51 *
52 */
40 struct GNUNET_CMDS_LOCAL_FINISHED *reply; 53 struct GNUNET_CMDS_LOCAL_FINISHED *reply;
41}; 54};
42 55
43 56
57/**
58 * Trait function of this cmd does nothing.
59 *
60 */
44static int 61static int
45local_test_finished_traits (void *cls, 62local_test_finished_traits (void *cls,
46 const void **ret, 63 const void **ret,
@@ -51,6 +68,10 @@ local_test_finished_traits (void *cls,
51} 68}
52 69
53 70
71/**
72 * The cleanup function of this cmd frees resources the cmd allocated.
73 *
74 */
54static void 75static void
55local_test_finished_cleanup (void *cls, 76local_test_finished_cleanup (void *cls,
56 const struct GNUNET_TESTING_Command *cmd) 77 const struct GNUNET_TESTING_Command *cmd)
@@ -62,6 +83,10 @@ local_test_finished_cleanup (void *cls,
62} 83}
63 84
64 85
86/**
87 * This function sends a GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED message to the master loop.
88 *
89 */
65static void 90static void
66local_test_finished_run (void *cls, 91local_test_finished_run (void *cls,
67 const struct GNUNET_TESTING_Command *cmd, 92 const struct GNUNET_TESTING_Command *cmd,
@@ -72,27 +97,26 @@ local_test_finished_run (void *cls,
72 struct GNUNET_CMDS_LOCAL_FINISHED *reply; 97 struct GNUNET_CMDS_LOCAL_FINISHED *reply;
73 size_t msg_length; 98 size_t msg_length;
74 99
75 LOG (GNUNET_ERROR_TYPE_ERROR,
76 "We got here 12!\n");
77
78 msg_length = sizeof(struct GNUNET_CMDS_LOCAL_FINISHED); 100 msg_length = sizeof(struct GNUNET_CMDS_LOCAL_FINISHED);
79 reply = GNUNET_new (struct GNUNET_CMDS_LOCAL_FINISHED); 101 reply = GNUNET_new (struct GNUNET_CMDS_LOCAL_FINISHED);
80 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED); 102 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED);
81 reply->header.size = htons ((uint16_t) msg_length); 103 reply->header.size = htons ((uint16_t) msg_length);
82 lfs->reply = reply; 104 lfs->reply = reply;
83 lfs->write_message ((struct GNUNET_MessageHeader *) reply, msg_length); 105 lfs->write_message ((struct GNUNET_MessageHeader *) reply, msg_length);
84
85 LOG (GNUNET_ERROR_TYPE_ERROR,
86 "We got here 13!\n");
87} 106}
88 107
89 108
109/**
110 * This finish function will stop the local loop without shutting down the scheduler, because we do not call the continuation, which is the interpreter_next method.
111 *
112 */
90static int 113static int
91local_test_finished_finish (void *cls, 114local_test_finished_finish (void *cls,
92 GNUNET_SCHEDULER_TaskCallback cont, 115 GNUNET_SCHEDULER_TaskCallback cont,
93 void *cont_cls) 116 void *cont_cls)
94{ 117{
95 // This will stop the local loop without shutting down the scheduler, because we do not call the continuation, which is the interpreter_next method. 118 LOG (GNUNET_ERROR_TYPE_DEBUG,
119 "Stopping local loop\n");
96 return GNUNET_YES; 120 return GNUNET_YES;
97} 121}
98 122
@@ -101,18 +125,16 @@ local_test_finished_finish (void *cls,
101 * Create command. 125 * Create command.
102 * 126 *
103 * @param label name for command. 127 * @param label name for command.
128 * @param write_message Callback to write messages to the master loop.
104 * @return command. 129 * @return command.
105 */ 130 */
106struct GNUNET_TESTING_Command 131struct GNUNET_TESTING_Command
107GNUNET_TESTING_cmd_local_test_finished (const char *label, 132GNUNET_TESTING_cmd_local_test_finished (const char *label,
108 TESTBED_CMD_HELPER_write_cb 133 TESTING_CMD_HELPER_write_cb
109 write_message) 134 write_message)
110{ 135{
111 struct LocalFinishedState *lfs; 136 struct LocalFinishedState *lfs;
112 137
113 LOG (GNUNET_ERROR_TYPE_ERROR,
114 "We got here 11!\n");
115
116 lfs = GNUNET_new (struct LocalFinishedState); 138 lfs = GNUNET_new (struct LocalFinishedState);
117 lfs->write_message = write_message; 139 lfs->write_message = write_message;
118 140
diff --git a/src/testbed/testbed_api_cmd_netjail_start.c b/src/testing/testing_api_cmd_netjail_start.c
index bc035abe7..536b356a6 100644
--- a/src/testbed/testbed_api_cmd_netjail_start.c
+++ b/src/testing/testing_api_cmd_netjail_start.c
@@ -26,16 +26,22 @@
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_ng_lib.h"
29#include "gnunet_testbed_ng_service.h"
30 29
31#define NETJAIL_START_SCRIPT "./../testbed/netjail_start.sh" 30#define NETJAIL_START_SCRIPT "./../testing/netjail_start.sh"
32 31
32/**
33 * Struct to hold information for callbacks.
34 *
35 */
33struct NetJailState 36struct NetJailState
34{ 37{
38 // Child Wait handle
35 struct GNUNET_ChildWaitHandle *cwh; 39 struct GNUNET_ChildWaitHandle *cwh;
36 40
41 // Number of local nodes in each namespace.
37 char *local_m; 42 char *local_m;
38 43
44 // The number of namespaces.
39 char *global_n; 45 char *global_n;
40 46
41 /** 47 /**
@@ -43,16 +49,15 @@ struct NetJailState
43 */ 49 */
44 struct GNUNET_OS_Process *start_proc; 50 struct GNUNET_OS_Process *start_proc;
45 51
52 // Flag indication if the script finished.
46 unsigned int finished; 53 unsigned int finished;
47}; 54};
48 55
49 56
50/** 57/**
51* 58 * The cleanup function of this cmd frees resources the cmd allocated.
52* 59 *
53* @param cls closure 60 */
54* @param cmd current CMD being cleaned up.
55*/
56static void 61static void
57netjail_start_cleanup (void *cls, 62netjail_start_cleanup (void *cls,
58 const struct GNUNET_TESTING_Command *cmd) 63 const struct GNUNET_TESTING_Command *cmd)
@@ -82,14 +87,9 @@ netjail_start_cleanup (void *cls,
82 87
83 88
84/** 89/**
85* 90 * Trait function of this cmd does nothing.
86* 91 *
87* @param cls closure. 92 */
88* @param[out] ret result
89* @param trait name of the trait.
90* @param index index number of the object to offer.
91* @return #GNUNET_OK on success.
92*/
93static int 93static int
94netjail_start_traits (void *cls, 94netjail_start_traits (void *cls,
95 const void **ret, 95 const void **ret,
@@ -99,6 +99,11 @@ netjail_start_traits (void *cls,
99 return GNUNET_OK; 99 return GNUNET_OK;
100} 100}
101 101
102
103/**
104 * Callback which will be called if the setup script finished.
105 *
106 */
102static void 107static void
103child_completed_callback (void *cls, 108child_completed_callback (void *cls,
104 enum GNUNET_OS_ProcessStatusType type, 109 enum GNUNET_OS_ProcessStatusType type,
@@ -123,7 +128,7 @@ child_completed_callback (void *cls,
123 128
124 129
125/** 130/**
126* Run the "hello world" CMD. 131* The run method starts the script which setup the network namespaces.
127* 132*
128* @param cls closure. 133* @param cls closure.
129* @param cmd CMD being run. 134* @param cmd CMD being run.
@@ -139,6 +144,25 @@ netjail_start_run (void *cls,
139 ns->local_m, 144 ns->local_m,
140 ns->global_n, 145 ns->global_n,
141 NULL}; 146 NULL};
147 unsigned int helper_check = GNUNET_OS_check_helper_binary (
148 NETJAIL_START_SCRIPT,
149 GNUNET_YES,
150 NULL);
151
152 if (GNUNET_NO == helper_check)
153 {
154 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
155 "No SUID for %s!\n",
156 NETJAIL_START_SCRIPT);
157 GNUNET_TESTING_interpreter_fail ();
158 }
159 else if (GNUNET_NO == helper_check)
160 {
161 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
162 "%s not found!\n",
163 NETJAIL_START_SCRIPT);
164 GNUNET_TESTING_interpreter_fail ();
165 }
142 166
143 ns->start_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR, 167 ns->start_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
144 NULL, 168 NULL,
@@ -153,6 +177,11 @@ netjail_start_run (void *cls,
153 GNUNET_break (NULL != ns->cwh); 177 GNUNET_break (NULL != ns->cwh);
154} 178}
155 179
180
181/**
182 * This function checks the flag NetJailState#finished, if this cmd finished.
183 *
184 */
156static int 185static int
157netjail_start_finish (void *cls, 186netjail_start_finish (void *cls,
158 GNUNET_SCHEDULER_TaskCallback cont, 187 GNUNET_SCHEDULER_TaskCallback cont,
@@ -171,11 +200,12 @@ netjail_start_finish (void *cls,
171 * Create command. 200 * Create command.
172 * 201 *
173 * @param label name for command. 202 * @param label name for command.
174 * @param binaryname to start. 203 * @param local_m Number of local nodes in each namespace.
204 * @param global_n The number of namespaces.
175 * @return command. 205 * @return command.
176 */ 206 */
177struct GNUNET_TESTING_Command 207struct GNUNET_TESTING_Command
178GNUNET_TESTBED_cmd_netjail_start (const char *label, 208GNUNET_TESTING_cmd_netjail_start (const char *label,
179 char *local_m, 209 char *local_m,
180 char *global_n) 210 char *global_n)
181{ 211{
diff --git a/src/testbed/testbed_api_cmd_netjail_start_testbed.c b/src/testing/testing_api_cmd_netjail_start_testsystem.c
index 67f0ef55c..0fe0541b0 100644
--- a/src/testbed/testbed_api_cmd_netjail_start_testbed.c
+++ b/src/testing/testing_api_cmd_netjail_start_testsystem.c
@@ -25,20 +25,25 @@
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_testing_ng_lib.h" 27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_testbed_ng_service.h" 28#include "testing_cmds.h"
29#include "testbed_api.h"
30#include "testbed_api_hosts.h"
31#include "testbed_helper.h"
32 29
33#define NETJAIL_EXEC_SCRIPT "./../testbed/netjail_exec.sh" 30#define NETJAIL_EXEC_SCRIPT "./../testing/netjail_exec.sh"
34
35struct HelperMessage;
36 31
32/**
33 * Struct to store messages send/received by the helper into a DLL
34 *
35 */
37struct HelperMessage 36struct HelperMessage
38{ 37{
39 38
39 /**
40 * Kept in a DLL.
41 */
40 struct HelperMessage *next; 42 struct HelperMessage *next;
41 43
44 /**
45 * Kept in a DLL.
46 */
42 struct HelperMessage *prev; 47 struct HelperMessage *prev;
43 48
44 /** 49 /**
@@ -50,25 +55,51 @@ struct HelperMessage
50}; 55};
51 56
52 57
53 58/**
59 * Struct to store information handed over to callbacks.
60 *
61 */
54struct NetJailState 62struct NetJailState
55{ 63{
64 /**
65 * Pointer to the return value of the test.
66 *
67 */
68 unsigned int *rv;
56 69
70 /**
71 * Head of the DLL which stores messages received by the helper.
72 *
73 */
57 struct HelperMessage *hp_messages_head; 74 struct HelperMessage *hp_messages_head;
58 75
76 /**
77 * Tail of the DLL which stores messages received by the helper.
78 *
79 */
59 struct HelperMessage *hp_messages_tail; 80 struct HelperMessage *hp_messages_tail;
60 81
61 /** 82 /**
62 * The process handle 83 * Array with handles of helper processes.
63 */ 84 */
64 struct GNUNET_HELPER_Handle **helper; 85 struct GNUNET_HELPER_Handle **helper;
65 86
87 /**
88 * Size of the array NetJailState#helper.
89 *
90 */
66 unsigned int n_helper; 91 unsigned int n_helper;
67 92
68 char *binary_name; 93 /**
69 94 * Number of nodes in a network namespace. //TODO make this a unsigned int
95 *
96 */
70 char *local_m; 97 char *local_m;
71 98
99 /**
100 * Number of network namespaces. //TODO make this a unsigned int
101 *
102 */
72 char *global_n; 103 char *global_n;
73 104
74 /** 105 /**
@@ -76,40 +107,91 @@ struct NetJailState
76 */ 107 */
77 struct GNUNET_HELPER_SendHandle **shandle; 108 struct GNUNET_HELPER_SendHandle **shandle;
78 109
110 /**
111 * Size of the array NetJailState#shandle.
112 *
113 */
79 unsigned int n_shandle; 114 unsigned int n_shandle;
80 115
81 /** 116 /**
82 * The message corresponding to send handle 117 * The messages send to the helper.
83 */ 118 */
84 struct GNUNET_MessageHeader **msg; 119 struct GNUNET_MessageHeader **msg;
85 120
121 /**
122 * Size of the array NetJailState#msg.
123 *
124 */
86 unsigned int n_msg; 125 unsigned int n_msg;
87 126
88 unsigned int number_of_testbeds_started; 127 /**
128 * Number of test environments started.
129 *
130 */
131 unsigned int number_of_testsystems_started;
89 132
133 /**
134 * Number of peers started.
135 *
136 */
90 unsigned int number_of_peers_started; 137 unsigned int number_of_peers_started;
91 138
139 /**
140 * Number of local tests finished.
141 *
142 */
92 unsigned int number_of_local_test_finished; 143 unsigned int number_of_local_test_finished;
93 144
94 /** 145 /**
95 * The host where the controller is running 146 * Name of the test case plugin the helper will load.
147 *
96 */ 148 */
97 struct GNUNET_TESTBED_Host **host; 149 char *plugin_name;
98 150
99 unsigned int n_host; 151 /**
152 * HEAD of the DLL containing TestingSystemCount.
153 *
154 */
155 struct TestingSystemCount *tbcs_head;
100 156
101 char *plugin_name; 157 /**
158 * TAIL of the DLL containing TestingSystemCount.
159 *
160 */
161 struct TestingSystemCount *tbcs_tail;
102}; 162};
103 163
104struct TestbedCount 164/**
165 * Struct containing the number of the test environment and the NetJailState which
166 * will be handed to callbacks specific to a test environment.
167 */
168struct TestingSystemCount
105{ 169{
170 /**
171 * Kept in a DLL.
172 */
173 struct TestingSystemCount *next;
174
175 /**
176 * Kept in a DLL.
177 */
178 struct TestingSystemCount *prev;
179
180 /**
181 * The number of the test environment.
182 *
183 */
106 unsigned int count; 184 unsigned int count;
107 185
186 /**
187 * Struct to store information handed over to callbacks.
188 *
189 */
108 struct NetJailState *ns; 190 struct NetJailState *ns;
109}; 191};
110 192
111/** 193/**
112* 194* Code to clean up resource this cmd used.
113* 195*
114* @param cls closure 196* @param cls closure
115* @param cmd current CMD being cleaned up. 197* @param cmd current CMD being cleaned up.
@@ -119,20 +201,31 @@ netjail_exec_cleanup (void *cls,
119 const struct GNUNET_TESTING_Command *cmd) 201 const struct GNUNET_TESTING_Command *cmd)
120{ 202{
121 struct NetJailState *ns = cls; 203 struct NetJailState *ns = cls;
204 struct HelperMessage *message_pos;
205 struct TestingSystemCount *tbc_pos;
122 206
123 GNUNET_free (ns->binary_name); 207 while (NULL != (message_pos = ns->hp_messages_head))
208 {
209 GNUNET_CONTAINER_DLL_remove (ns->hp_messages_head,
210 ns->hp_messages_tail,
211 message_pos);
212 GNUNET_free (message_pos);
213 }
214 while (NULL != (tbc_pos = ns->tbcs_head))
215 {
216 GNUNET_CONTAINER_DLL_remove (ns->tbcs_head,
217 ns->tbcs_tail,
218 tbc_pos);
219 GNUNET_free (tbc_pos);
220 }
221 GNUNET_free (ns);
124} 222}
125 223
126 224
127/** 225/**
128* 226 * This function prepares an array with traits.
129* 227 *
130* @param cls closure. 228 */
131* @param[out] ret result
132* @param trait name of the trait.
133* @param index index number of the object to offer.
134* @return #GNUNET_OK on success.
135*/
136static int 229static int
137netjail_exec_traits (void *cls, 230netjail_exec_traits (void *cls,
138 const void **ret, 231 const void **ret,
@@ -166,14 +259,14 @@ netjail_exec_traits (void *cls,
166 259
167 260
168/** 261/**
169 * Offer handles to testbed helper from trait 262 * Offer handles to testing cmd helper from trait
170 * 263 *
171 * @param cmd command to extract the message from. 264 * @param cmd command to extract the message from.
172 * @param pt pointer to message. 265 * @param pt pointer to message.
173 * @return #GNUNET_OK on success. 266 * @return #GNUNET_OK on success.
174 */ 267 */
175int 268int
176GNUNET_TESTBED_get_trait_helper_handles (const struct 269GNUNET_TESTING_get_trait_helper_handles (const struct
177 GNUNET_TESTING_Command *cmd, 270 GNUNET_TESTING_Command *cmd,
178 struct GNUNET_HELPER_Handle ***helper) 271 struct GNUNET_HELPER_Handle ***helper)
179{ 272{
@@ -183,15 +276,16 @@ GNUNET_TESTBED_get_trait_helper_handles (const struct
183 (unsigned int) 0); 276 (unsigned int) 0);
184} 277}
185 278
279
186/** 280/**
187 * Offer handles to testbed helper from trait 281 * Offer messages received via testing cmd helper from trait
188 * 282 *
189 * @param cmd command to extract the message from. 283 * @param cmd command to extract the message from.
190 * @param pt pointer to message. 284 * @param pt pointer to message.
191 * @return #GNUNET_OK on success. 285 * @return #GNUNET_OK on success.
192 */ 286 */
193int 287int
194GNUNET_TESTBED_get_trait_helper_messages (const struct 288GNUNET_TESTING_get_trait_helper_messages (const struct
195 GNUNET_TESTING_Command *cmd, 289 GNUNET_TESTING_Command *cmd,
196 struct HelperMessage *** 290 struct HelperMessage ***
197 hp_messages_head) 291 hp_messages_head)
@@ -214,12 +308,9 @@ GNUNET_TESTBED_get_trait_helper_messages (const struct
214static void 308static void
215clear_msg (void *cls, int result) 309clear_msg (void *cls, int result)
216{ 310{
217 struct TestbedCount *tbc = cls; 311 struct TestingSystemCount *tbc = cls;
218 struct NetJailState *ns = tbc->ns; 312 struct NetJailState *ns = tbc->ns;
219 313
220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
221 "clear_msg tbc->count: %d\n",
222 tbc->count);
223 GNUNET_assert (NULL != ns->shandle[tbc->count - 1]); 314 GNUNET_assert (NULL != ns->shandle[tbc->count - 1]);
224 ns->shandle[tbc->count - 1] = NULL; 315 ns->shandle[tbc->count - 1] = NULL;
225 GNUNET_free (ns->msg[tbc->count - 1]); 316 GNUNET_free (ns->msg[tbc->count - 1]);
@@ -242,27 +333,18 @@ clear_msg (void *cls, int result)
242static int 333static int
243helper_mst (void *cls, const struct GNUNET_MessageHeader *message) 334helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
244{ 335{
245 struct TestbedCount *tbc = cls; 336 struct TestingSystemCount *tbc = cls;
246 struct NetJailState *ns = tbc->ns; 337 struct NetJailState *ns = tbc->ns;
247 struct HelperMessage *hp_msg; 338 struct HelperMessage *hp_msg;
248 339
249 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type)) 340 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type))
250 { 341 {
251 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 342 ns->number_of_testsystems_started++;
252 "helper_mst tbc->count: %d\n",
253 tbc->count);
254 // GNUNET_TESTBED_extract_cfg (host, message);
255 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
256 "Received message from helper.\n");
257 ns->number_of_testbeds_started++;
258 } 343 }
259 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED == ntohs ( 344 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED == ntohs (
260 message->type)) 345 message->type))
261 { 346 {
262 ns->number_of_peers_started++; 347 ns->number_of_peers_started++;
263 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
264 "number_of_peers_started: %d\n",
265 ns->number_of_peers_started);
266 } 348 }
267 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED == ntohs ( 349 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED == ntohs (
268 message->type)) 350 message->type))
@@ -282,14 +364,27 @@ helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
282} 364}
283 365
284 366
367/**
368 * Callback called if there was an exception during execution of the helper.
369 *
370 */
285static void 371static void
286exp_cb (void *cls) 372exp_cb (void *cls)
287{ 373{
374 struct NetJailState *ns = cls;
288 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n"); 375 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n");
289 GNUNET_TESTING_interpreter_fail (); 376 *ns->rv = 1;
290} 377}
291 378
292 379
380/**
381 * Function to initialize a init message for the helper.
382 *
383 * @param m_char The actual node in a namespace. //TODO Change this to unsigned int
384 * @param n_char The actual namespace. //TODO Change this to unsigned int
385 * @param plugin_name Name of the test case plugin the helper will load.
386 *
387 */
293static struct GNUNET_CMDS_HelperInit * 388static struct GNUNET_CMDS_HelperInit *
294create_helper_init_msg_ (char *m_char, 389create_helper_init_msg_ (char *m_char,
295 char *n_char, 390 char *n_char,
@@ -302,9 +397,6 @@ create_helper_init_msg_ (char *m_char,
302 GNUNET_assert (NULL != plugin_name); 397 GNUNET_assert (NULL != plugin_name);
303 plugin_name_len = strlen (plugin_name); 398 plugin_name_len = strlen (plugin_name);
304 msg_size = sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_len; 399 msg_size = sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_len;
305 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
306 "msg_size: %d \n",
307 msg_size);
308 msg = GNUNET_malloc (msg_size); 400 msg = GNUNET_malloc (msg_size);
309 msg->header.size = htons (msg_size); 401 msg->header.size = htons (msg_size);
310 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT); 402 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT);
@@ -316,15 +408,19 @@ create_helper_init_msg_ (char *m_char,
316} 408}
317 409
318 410
411/**
412 * Function which start a single helper process.
413 *
414 */
319static void 415static void
320start_testbed (struct NetJailState *ns, struct 416start_helper (struct NetJailState *ns, struct
321 GNUNET_CONFIGURATION_Handle *config, 417 GNUNET_CONFIGURATION_Handle *config,
322 char *m_char, 418 char *m_char,
323 char *n_char) 419 char *n_char)
324{ 420{
325 // struct GNUNET_CONFIGURATION_Handle *cfg; 421 struct GNUNET_HELPER_Handle *helper;
326 struct GNUNET_CMDS_HelperInit *msg; 422 struct GNUNET_CMDS_HelperInit *msg;
327 struct TestbedCount *tbc; 423 struct TestingSystemCount *tbc;
328 char *const script_argv[] = {NETJAIL_EXEC_SCRIPT, 424 char *const script_argv[] = {NETJAIL_EXEC_SCRIPT,
329 m_char, 425 m_char,
330 n_char, 426 n_char,
@@ -335,35 +431,33 @@ start_testbed (struct NetJailState *ns, struct
335 NULL}; 431 NULL};
336 unsigned int m = atoi (m_char); 432 unsigned int m = atoi (m_char);
337 unsigned int n = atoi (n_char); 433 unsigned int n = atoi (n_char);
434 unsigned int helper_check = GNUNET_OS_check_helper_binary (
435 NETJAIL_EXEC_SCRIPT,
436 GNUNET_YES,
437 NULL);
338 438
339 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 439 tbc = GNUNET_new (struct TestingSystemCount);
340 "m: %d n: %d\n",
341 m,
342 n);
343
344 tbc = GNUNET_new (struct TestbedCount);
345 tbc->ns = ns; 440 tbc->ns = ns;
346 tbc->count = (n - 1) * atoi (ns->local_m) + m; 441 tbc->count = (n - 1) * atoi (ns->local_m) + m;
347 442
348 // cfg = GNUNET_CONFIGURATION_dup (config); 443 GNUNET_CONTAINER_DLL_insert (ns->tbcs_head, ns->tbcs_tail,
444 tbc);
349 445
350 // TODO We do not need this?
351 /*GNUNET_array_append (ns->host, ns->n_host,
352 GNUNET_TESTBED_host_create_with_id (tbc->count - 1,
353 NULL,
354 NULL,
355 cfg,
356 0));*/
357 446
358 /*if ((GNUNET_YES != GNUNET_DISK_file_test ("test_testbed_api.conf")) || 447 if (GNUNET_NO == helper_check)
359 (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (config, 448 {
360 "test_testbed_api.conf"))) 449 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
450 "No SUID for %s!\n",
451 NETJAIL_EXEC_SCRIPT);
452 *ns->rv = 1;
453 }
454 else if (GNUNET_NO == helper_check)
361 { 455 {
362 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 456 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
363 _ ( 457 "%s not found!\n",
364 "Unreadable or malformed configuration file `%s', exit ...\n"), 458 NETJAIL_EXEC_SCRIPT);
365 "test_testbed_api.conf"); 459 *ns->rv = 1;
366 }*/ 460 }
367 461
368 GNUNET_array_append (ns->helper, ns->n_helper, GNUNET_HELPER_start ( 462 GNUNET_array_append (ns->helper, ns->n_helper, GNUNET_HELPER_start (
369 GNUNET_YES, 463 GNUNET_YES,
@@ -373,7 +467,7 @@ start_testbed (struct NetJailState *ns, struct
373 &exp_cb, 467 &exp_cb,
374 tbc)); 468 tbc));
375 469
376 struct GNUNET_HELPER_Handle *helper = ns->helper[tbc->count - 1]; 470 helper = ns->helper[tbc->count - 1];
377 471
378 msg = create_helper_init_msg_ (m_char, 472 msg = create_helper_init_msg_ (m_char,
379 n_char, 473 n_char,
@@ -387,22 +481,18 @@ start_testbed (struct NetJailState *ns, struct
387 &clear_msg, 481 &clear_msg,
388 tbc)); 482 tbc));
389 483
390 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
391 "Message %d send!\n",
392 tbc->count);
393
394 if (NULL == ns->shandle[tbc->count - 1]) 484 if (NULL == ns->shandle[tbc->count - 1])
395 { 485 {
396 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 486 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
397 "Send handle is NULL!\n"); 487 "Send handle is NULL!\n");
398 GNUNET_free (msg); 488 GNUNET_free (msg);
399 GNUNET_TESTING_interpreter_fail (); 489 *ns->rv = 1;
400 } 490 }
401} 491}
402 492
403 493
404/** 494/**
405* Run the "hello world" CMD. 495* This function starts a helper process for each node.
406* 496*
407* @param cls closure. 497* @param cls closure.
408* @param cmd CMD being run. 498* @param cmd CMD being run.
@@ -419,19 +509,29 @@ netjail_exec_run (void *cls,
419 struct GNUNET_CONFIGURATION_Handle *config = 509 struct GNUNET_CONFIGURATION_Handle *config =
420 GNUNET_CONFIGURATION_create (); 510 GNUNET_CONFIGURATION_create ();
421 511
422 for (int i = 1; i <= atoi (ns->global_n); i++) { 512 for (int i = 1; i <= atoi (ns->global_n); i++)
513 {
423 for (int j = 1; j <= atoi (ns->local_m); j++) 514 for (int j = 1; j <= atoi (ns->local_m); j++)
424 { 515 {
425 sprintf (str_n, "%d", i); 516 sprintf (str_n, "%d", i);
426 sprintf (str_m, "%d", j); 517 sprintf (str_m, "%d", j);
427 start_testbed (ns, config, 518 start_helper (ns, config,
428 str_m, 519 str_m,
429 str_n); 520 str_n);
430 } 521 }
431 } 522 }
432} 523}
433 524
434 525
526/**
527 * This function checks on three different information.
528 *
529 * 1. Did all helpers start. This is only logged.
530 * 2. Did all peer start.
531 * In this case a GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED is send to all peers.
532 * 3. Did all peers finished the test case. In this case interpreter_next will be called.
533 *
534 */
435static int 535static int
436netjail_start_finish (void *cls, 536netjail_start_finish (void *cls,
437 GNUNET_SCHEDULER_TaskCallback cont, 537 GNUNET_SCHEDULER_TaskCallback cont,
@@ -443,7 +543,7 @@ netjail_start_finish (void *cls,
443 struct GNUNET_CMDS_ALL_PEERS_STARTED *reply; 543 struct GNUNET_CMDS_ALL_PEERS_STARTED *reply;
444 size_t msg_length; 544 size_t msg_length;
445 struct GNUNET_HELPER_Handle *helper; 545 struct GNUNET_HELPER_Handle *helper;
446 struct TestbedCount *tbc; 546 struct TestingSystemCount *tbc;
447 547
448 if (ns->number_of_local_test_finished == total_number) 548 if (ns->number_of_local_test_finished == total_number)
449 { 549 {
@@ -451,25 +551,22 @@ netjail_start_finish (void *cls,
451 cont (cont_cls); 551 cont (cont_cls);
452 } 552 }
453 553
454 if (ns->number_of_testbeds_started == total_number) 554 if (ns->number_of_testsystems_started == total_number)
455 { 555 {
456 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 556 ns->number_of_testsystems_started = 0;
457 "All helpers started!\n");
458 ns->number_of_testbeds_started = 0;
459 } 557 }
460 558
461 if (ns->number_of_peers_started == total_number) 559 if (ns->number_of_peers_started == total_number)
462 { 560 {
463 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 561 for (int i = 1; i <= atoi (ns->global_n); i++)
464 "All peers started!\n"); 562 {
465
466 for (int i = 1; i <= atoi (ns->global_n); i++) {
467 for (int j = 1; j <= atoi (ns->local_m); j++) 563 for (int j = 1; j <= atoi (ns->local_m); j++)
468 { 564 {
469 tbc = GNUNET_new (struct TestbedCount); 565 tbc = GNUNET_new (struct TestingSystemCount);
470 tbc->ns = ns; 566 tbc->ns = ns;
471 // TODO This needs to be more generic. As we send more messages back and forth, we can not grow the arrays again and again, because this is to error prone. 567 // TODO This needs to be more generic. As we send more messages back and forth, we can not grow the arrays again and again, because this is to error prone.
472 tbc->count = (j - 1) * atoi (ns->local_m) + i + total_number; 568 tbc->count = (i - 1) * atoi (ns->local_m) + j + total_number;
569
473 helper = ns->helper[tbc->count - 1 - total_number]; 570 helper = ns->helper[tbc->count - 1 - total_number];
474 msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED); 571 msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED);
475 reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED); 572 reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED);
@@ -487,10 +584,6 @@ netjail_start_finish (void *cls,
487 tbc); 584 tbc);
488 585
489 GNUNET_array_append (ns->shandle, ns->n_shandle, sh); 586 GNUNET_array_append (ns->shandle, ns->n_shandle, sh);
490
491 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
492 "All peers started message %d send!\n",
493 tbc->count);
494 } 587 }
495 } 588 }
496 ns->number_of_peers_started = 0; 589 ns->number_of_peers_started = 0;
@@ -502,15 +595,19 @@ netjail_start_finish (void *cls,
502/** 595/**
503 * Create command. 596 * Create command.
504 * 597 *
505 * @param label name for command. 598 * @param label Name for the command.
506 * @param binaryname to exec. 599 * @param local_m Number of nodes in a network namespace. //TODO make this a unsigned int
600 * @param global_n Number of network namespaces. //TODO make this a unsigned int
601 * @param plugin_name Name of the test case plugin the helper will load.
602 * @param rv Pointer to the return value of the test.
507 * @return command. 603 * @return command.
508 */ 604 */
509struct GNUNET_TESTING_Command 605struct GNUNET_TESTING_Command
510GNUNET_TESTBED_cmd_netjail_start_testbed (const char *label, 606GNUNET_TESTING_cmd_netjail_start_testing_system (const char *label,
511 char *local_m, 607 char *local_m,
512 char *global_n, 608 char *global_n,
513 char *plugin_name) 609 char *plugin_name,
610 unsigned int *rv)
514{ 611{
515 struct NetJailState *ns; 612 struct NetJailState *ns;
516 613
@@ -518,6 +615,7 @@ GNUNET_TESTBED_cmd_netjail_start_testbed (const char *label,
518 ns->local_m = local_m; 615 ns->local_m = local_m;
519 ns->global_n = global_n; 616 ns->global_n = global_n;
520 ns->plugin_name = plugin_name; 617 ns->plugin_name = plugin_name;
618 ns->rv = rv;
521 619
522 struct GNUNET_TESTING_Command cmd = { 620 struct GNUNET_TESTING_Command cmd = {
523 .cls = ns, 621 .cls = ns,
diff --git a/src/testbed/testbed_api_cmd_netjail_stop.c b/src/testing/testing_api_cmd_netjail_stop.c
index c0fc33ff9..99084d9af 100644
--- a/src/testbed/testbed_api_cmd_netjail_stop.c
+++ b/src/testing/testing_api_cmd_netjail_stop.c
@@ -26,17 +26,23 @@
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_ng_lib.h"
29#include "gnunet_testbed_ng_service.h"
30 29
31 30
32#define NETJAIL_STOP_SCRIPT "./../testbed/netjail_stop.sh" 31#define NETJAIL_STOP_SCRIPT "./../testing/netjail_stop.sh"
33 32
33// Child Wait handle
34struct GNUNET_ChildWaitHandle *cwh; 34struct GNUNET_ChildWaitHandle *cwh;
35 35
36/**
37 * Struct to hold information for callbacks.
38 *
39 */
36struct NetJailState 40struct NetJailState
37{ 41{
42 // Number of local nodes in each namespace.
38 char *local_m; 43 char *local_m;
39 44
45 // The number of namespaces.
40 char *global_n; 46 char *global_n;
41 47
42 /** 48 /**
@@ -44,16 +50,15 @@ struct NetJailState
44 */ 50 */
45 struct GNUNET_OS_Process *stop_proc; 51 struct GNUNET_OS_Process *stop_proc;
46 52
53 // Flag indication if the script finished.
47 unsigned int finished; 54 unsigned int finished;
48}; 55};
49 56
50 57
51/** 58/**
52* 59 * The cleanup function of this cmd frees resources the cmd allocated.
53* 60 *
54* @param cls closure 61 */
55* @param cmd current CMD being cleaned up.
56*/
57static void 62static void
58netjail_stop_cleanup (void *cls, 63netjail_stop_cleanup (void *cls,
59 const struct GNUNET_TESTING_Command *cmd) 64 const struct GNUNET_TESTING_Command *cmd)
@@ -79,14 +84,9 @@ netjail_stop_cleanup (void *cls,
79 84
80 85
81/** 86/**
82* 87 * Trait function of this cmd does nothing.
83* 88 *
84* @param cls closure. 89 */
85* @param[out] ret result
86* @param trait name of the trait.
87* @param index index number of the object to offer.
88* @return #GNUNET_OK on success.
89*/
90static int 90static int
91netjail_stop_traits (void *cls, 91netjail_stop_traits (void *cls,
92 const void **ret, 92 const void **ret,
@@ -97,6 +97,10 @@ netjail_stop_traits (void *cls,
97} 97}
98 98
99 99
100/**
101 * Callback which will be called if the setup script finished.
102 *
103 */
100static void 104static void
101child_completed_callback (void *cls, 105child_completed_callback (void *cls,
102 enum GNUNET_OS_ProcessStatusType type, 106 enum GNUNET_OS_ProcessStatusType type,
@@ -119,7 +123,7 @@ child_completed_callback (void *cls,
119 123
120 124
121/** 125/**
122* Run the "hello world" CMD. 126* The run method starts the script which deletes the network namespaces.
123* 127*
124* @param cls closure. 128* @param cls closure.
125* @param cmd CMD being run. 129* @param cmd CMD being run.
@@ -135,6 +139,25 @@ netjail_stop_run (void *cls,
135 ns->local_m, 139 ns->local_m,
136 ns->global_n, 140 ns->global_n,
137 NULL}; 141 NULL};
142 unsigned int helper_check = GNUNET_OS_check_helper_binary (
143 NETJAIL_STOP_SCRIPT,
144 GNUNET_YES,
145 NULL);
146
147 if (GNUNET_NO == helper_check)
148 {
149 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
150 "No SUID for %s!\n",
151 NETJAIL_STOP_SCRIPT);
152 GNUNET_TESTING_interpreter_fail ();
153 }
154 else if (GNUNET_NO == helper_check)
155 {
156 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
157 "%s not found!\n",
158 NETJAIL_STOP_SCRIPT);
159 GNUNET_TESTING_interpreter_fail ();
160 }
138 161
139 ns->stop_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR, 162 ns->stop_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
140 NULL, 163 NULL,
@@ -151,6 +174,10 @@ netjail_stop_run (void *cls,
151} 174}
152 175
153 176
177/**
178 * This function checks the flag NetJailState#finished, if this cmd finished.
179 *
180 */
154static int 181static int
155netjail_stop_finish (void *cls, 182netjail_stop_finish (void *cls,
156 GNUNET_SCHEDULER_TaskCallback cont, 183 GNUNET_SCHEDULER_TaskCallback cont,
@@ -170,11 +197,12 @@ netjail_stop_finish (void *cls,
170 * Create command. 197 * Create command.
171 * 198 *
172 * @param label name for command. 199 * @param label name for command.
173 * @param binaryname to stop. 200 * @param local_m Number of local nodes in each namespace.
201 * @param global_n The number of namespaces.
174 * @return command. 202 * @return command.
175 */ 203 */
176struct GNUNET_TESTING_Command 204struct GNUNET_TESTING_Command
177GNUNET_TESTBED_cmd_netjail_stop (const char *label, 205GNUNET_TESTING_cmd_netjail_stop (const char *label,
178 char *local_m, 206 char *local_m,
179 char *global_n) 207 char *global_n)
180{ 208{
diff --git a/src/testbed/testbed_api_cmd_netjail_stop_testbed.c b/src/testing/testing_api_cmd_netjail_stop_testsystem.c
index 9a9d489a7..0ae82a26a 100644
--- a/src/testbed/testbed_api_cmd_netjail_stop_testbed.c
+++ b/src/testing/testing_api_cmd_netjail_stop_testsystem.c
@@ -25,11 +25,13 @@
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_testing_ng_lib.h" 27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_testbed_ng_service.h" 28#include "testing_cmds.h"
29#include "testbed_api.h"
30#include "testbed_api_hosts.h"
31 29
32 30
31/**
32 * Struct to store information handed over to callbacks.
33 *
34 */
33struct StopHelperState 35struct StopHelperState
34{ 36{
35 37
@@ -47,49 +49,44 @@ struct StopHelperState
47 49
48 50
49/** 51/**
50* 52* Code to clean up resource this cmd used.
51* 53*
52* @param cls closure 54* @param cls closure
53* @param cmd current CMD being cleaned up. 55* @param cmd current CMD being cleaned up.
54*/ 56*/
55static void 57static void
56stop_testbed_cleanup (void *cls, 58stop_testing_system_cleanup (void *cls,
57 const struct GNUNET_TESTING_Command *cmd) 59 const struct GNUNET_TESTING_Command *cmd)
58{ 60{
59 61
60} 62}
61 63
62 64
63/** 65/**
64* 66 * Trait function of this cmd does nothing.
65* 67 *
66* @param cls closure. 68 */
67* @param[out] ret result
68* @param trait name of the trait.
69* @param index index number of the object to offer.
70* @return #GNUNET_OK on success.
71*/
72static int 69static int
73stop_testbed_traits (void *cls, 70stop_testing_system_traits (void *cls,
74 const void **ret, 71 const void **ret,
75 const char *trait, 72 const char *trait,
76 unsigned int index) 73 unsigned int index)
77{ 74{
78 return GNUNET_OK; 75 return GNUNET_OK;
79} 76}
80 77
81 78
82/** 79/**
83* Run the "hello world" CMD. 80* This function stops the helper process for each node.
84* 81*
85* @param cls closure. 82* @param cls closure.
86* @param cmd CMD being run. 83* @param cmd CMD being run.
87* @param is interpreter state. 84* @param is interpreter state.
88*/ 85*/
89static void 86static void
90stop_testbed_run (void *cls, 87stop_testing_system_run (void *cls,
91 const struct GNUNET_TESTING_Command *cmd, 88 const struct GNUNET_TESTING_Command *cmd,
92 struct GNUNET_TESTING_Interpreter *is) 89 struct GNUNET_TESTING_Interpreter *is)
93{ 90{
94 struct StopHelperState *shs = cls; 91 struct StopHelperState *shs = cls;
95 struct GNUNET_HELPER_Handle **helper; 92 struct GNUNET_HELPER_Handle **helper;
@@ -97,10 +94,11 @@ stop_testbed_run (void *cls,
97 94
98 start_helper_cmd = GNUNET_TESTING_interpreter_lookup_command ( 95 start_helper_cmd = GNUNET_TESTING_interpreter_lookup_command (
99 shs->helper_start_label); 96 shs->helper_start_label);
100 GNUNET_TESTBED_get_trait_helper_handles (start_helper_cmd, 97 GNUNET_TESTING_get_trait_helper_handles (start_helper_cmd,
101 &helper); 98 &helper);
102 99
103 for (int i = 1; i <= atoi (shs->global_n); i++) { 100 for (int i = 1; i <= atoi (shs->global_n); i++)
101 {
104 for (int j = 1; j <= atoi (shs->local_m); j++) 102 for (int j = 1; j <= atoi (shs->local_m); j++)
105 { 103 {
106 GNUNET_HELPER_stop (helper[(i - 1) * atoi (shs->local_m) + j - 1], 104 GNUNET_HELPER_stop (helper[(i - 1) * atoi (shs->local_m) + j - 1],
@@ -112,17 +110,19 @@ stop_testbed_run (void *cls,
112 110
113/** 111/**
114 * Create command. 112 * Create command.
115 * 113 * @param helper_start_label label of the cmd to start the test system.
116 * @param label name for command. 114 * @param label name for command.
117 * @param binaryname to exec. 115 * @param .
116 * @param local_m Number of nodes in a network namespace. //TODO make this a unsigned int
117 * @param global_n Number of network namespaces. //TODO make this a unsigned int
118 * @return command. 118 * @return command.
119 */ 119 */
120struct GNUNET_TESTING_Command 120struct GNUNET_TESTING_Command
121GNUNET_TESTBED_cmd_stop_testbed (const char *label, 121GNUNET_TESTING_cmd_stop_testing_system (const char *label,
122 const char *helper_start_label, 122 const char *helper_start_label,
123 char *local_m, 123 char *local_m,
124 char *global_n 124 char *global_n
125 ) 125 )
126{ 126{
127 struct StopHelperState *shs; 127 struct StopHelperState *shs;
128 128
@@ -134,9 +134,9 @@ GNUNET_TESTBED_cmd_stop_testbed (const char *label,
134 struct GNUNET_TESTING_Command cmd = { 134 struct GNUNET_TESTING_Command cmd = {
135 .cls = shs, 135 .cls = shs,
136 .label = label, 136 .label = label,
137 .run = &stop_testbed_run, 137 .run = &stop_testing_system_run,
138 .cleanup = &stop_testbed_cleanup, 138 .cleanup = &stop_testing_system_cleanup,
139 .traits = &stop_testbed_traits 139 .traits = &stop_testing_system_traits
140 }; 140 };
141 141
142 return cmd; 142 return cmd;
diff --git a/src/testing/testing_api_cmd_send_peer_ready.c b/src/testing/testing_api_cmd_send_peer_ready.c
index 27761c4d5..016837214 100644
--- a/src/testing/testing_api_cmd_send_peer_ready.c
+++ b/src/testing/testing_api_cmd_send_peer_ready.c
@@ -26,18 +26,33 @@
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_ng_lib.h"
29#include "testbed_api.h" 29#include "testing_cmds.h"
30#include "testbed_helper.h"
31 30
32 31
32/**
33 * Struct to hold information for callbacks.
34 *
35 */
33struct SendPeerReadyState 36struct SendPeerReadyState
34{ 37{
35 TESTBED_CMD_HELPER_write_cb write_message; 38 /**
36 39 * Callback to write messages to the master loop.
40 *
41 */
42 TESTING_CMD_HELPER_write_cb write_message;
43
44 /**
45 * The message send back to the master loop.
46 *
47 */
37 struct GNUNET_CMDS_PEER_STARTED *reply; 48 struct GNUNET_CMDS_PEER_STARTED *reply;
38}; 49};
39 50
40 51
52/**
53 * Trait function of this cmd does nothing.
54 *
55 */
41static int 56static int
42send_peer_ready_traits (void *cls, 57send_peer_ready_traits (void *cls,
43 const void **ret, 58 const void **ret,
@@ -48,6 +63,10 @@ send_peer_ready_traits (void *cls,
48} 63}
49 64
50 65
66/**
67 * The cleanup function of this cmd frees resources the cmd allocated.
68 *
69 */
51static void 70static void
52send_peer_ready_cleanup (void *cls, 71send_peer_ready_cleanup (void *cls,
53 const struct GNUNET_TESTING_Command *cmd) 72 const struct GNUNET_TESTING_Command *cmd)
@@ -59,6 +78,10 @@ send_peer_ready_cleanup (void *cls,
59} 78}
60 79
61 80
81/**
82 * This function sends a GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED message to the master loop.
83 *
84 */
62static void 85static void
63send_peer_ready_run (void *cls, 86send_peer_ready_run (void *cls,
64 const struct GNUNET_TESTING_Command *cmd, 87 const struct GNUNET_TESTING_Command *cmd,
@@ -68,7 +91,7 @@ send_peer_ready_run (void *cls,
68 struct GNUNET_CMDS_PEER_STARTED *reply; 91 struct GNUNET_CMDS_PEER_STARTED *reply;
69 size_t msg_length; 92 size_t msg_length;
70 93
71 msg_length = sizeof(struct GNUNET_CMDS_HelperInit);// GNUNET_CMDS_PEER_STARTED); 94 msg_length = sizeof(struct GNUNET_CMDS_PEER_STARTED);
72 reply = GNUNET_new (struct GNUNET_CMDS_PEER_STARTED); 95 reply = GNUNET_new (struct GNUNET_CMDS_PEER_STARTED);
73 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED); 96 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED);
74 reply->header.size = htons ((uint16_t) msg_length); 97 reply->header.size = htons ((uint16_t) msg_length);
@@ -81,11 +104,12 @@ send_peer_ready_run (void *cls,
81 * Create command. 104 * Create command.
82 * 105 *
83 * @param label name for command. 106 * @param label name for command.
107 * @param write_message Callback to write messages to the master loop.
84 * @return command. 108 * @return command.
85 */ 109 */
86struct GNUNET_TESTING_Command 110struct GNUNET_TESTING_Command
87GNUNET_TESTING_cmd_send_peer_ready (const char *label, 111GNUNET_TESTING_cmd_send_peer_ready (const char *label,
88 TESTBED_CMD_HELPER_write_cb write_message) 112 TESTING_CMD_HELPER_write_cb write_message)
89{ 113{
90 struct SendPeerReadyState *sprs; 114 struct SendPeerReadyState *sprs;
91 115
diff --git a/src/testing/testing_api_cmd_system_create.c b/src/testing/testing_api_cmd_system_create.c
index 2007b4ef3..f3a0b1a4c 100644
--- a/src/testing/testing_api_cmd_system_create.c
+++ b/src/testing/testing_api_cmd_system_create.c
@@ -28,6 +28,10 @@
28#include "gnunet_testing_ng_lib.h" 28#include "gnunet_testing_ng_lib.h"
29#include "gnunet_testing_lib.h" 29#include "gnunet_testing_lib.h"
30 30
31/**
32 * Struct to hold information for callbacks.
33 *
34 */
31struct TestSystemState 35struct TestSystemState
32{ 36{
33 struct GNUNET_TESTING_System *test_system; 37 struct GNUNET_TESTING_System *test_system;
@@ -36,6 +40,10 @@ struct TestSystemState
36}; 40};
37 41
38 42
43/**
44 * The run method of this cmd will setup a test environment for a node.
45 *
46 */
39static void 47static void
40system_create_run (void *cls, 48system_create_run (void *cls,
41 const struct GNUNET_TESTING_Command *cmd, 49 const struct GNUNET_TESTING_Command *cmd,
@@ -54,6 +62,11 @@ system_create_run (void *cls,
54 "system created\n"); 62 "system created\n");
55} 63}
56 64
65
66/**
67 * This function prepares an array with traits.
68 *
69 */
57static int 70static int
58system_create_traits (void *cls, 71system_create_traits (void *cls,
59 const void **ret, 72 const void **ret,
@@ -79,6 +92,12 @@ system_create_traits (void *cls,
79} 92}
80 93
81 94
95/**
96 * Function to get the trait with struct GNUNET_TESTING_System
97 *
98 * @param[out] test_system The struct GNUNET_TESTING_System.
99 * @return #GNUNET_OK if no error occurred, #GNUNET_SYSERR otherwise.
100 */
82int 101int
83GNUNET_TESTING_get_trait_test_system (const struct 102GNUNET_TESTING_get_trait_test_system (const struct
84 GNUNET_TESTING_Command *cmd, 103 GNUNET_TESTING_Command *cmd,
@@ -91,13 +110,16 @@ GNUNET_TESTING_get_trait_test_system (const struct
91} 110}
92 111
93 112
113/**
114 * The cleanup function of this cmd frees resources the cmd allocated.
115 *
116 */
94static void 117static void
95system_create_cleanup (void *cls, 118system_create_cleanup (void *cls,
96 const struct GNUNET_TESTING_Command *cmd) 119 const struct GNUNET_TESTING_Command *cmd)
97{ 120{
98 struct TestSystemState *tss = cls; 121 struct TestSystemState *tss = cls;
99 122
100 GNUNET_free (tss->test_system);
101 GNUNET_free (tss); 123 GNUNET_free (tss);
102} 124}
103 125
@@ -106,6 +128,7 @@ system_create_cleanup (void *cls,
106 * Create command. 128 * Create command.
107 * 129 *
108 * @param label name for command. 130 * @param label name for command.
131 * @param label name for the test environment directory.
109 * @return command. 132 * @return command.
110 */ 133 */
111struct GNUNET_TESTING_Command 134struct GNUNET_TESTING_Command
diff --git a/src/testing/testing_api_cmd_system_destroy.c b/src/testing/testing_api_cmd_system_destroy.c
new file mode 100644
index 000000000..5ed0c2fd2
--- /dev/null
+++ b/src/testing/testing_api_cmd_system_destroy.c
@@ -0,0 +1,116 @@
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_lib.h"
30
31
32/**
33 * Struct to hold information for callbacks.
34 *
35 */
36struct TestSystemState
37{
38 // Label of the cmd which started the test system.
39 const char *create_label;
40};
41
42
43/**
44 * The run method of this cmd will remove the test environment for a node.
45 *
46 */
47static void
48system_destroy_run (void *cls,
49 const struct GNUNET_TESTING_Command *cmd,
50 struct GNUNET_TESTING_Interpreter *is)
51{
52 struct TestSystemState *tss = cls;
53 const struct GNUNET_TESTING_Command *system_cmd;
54 struct GNUNET_TESTING_System *tl_system;
55
56 system_cmd = GNUNET_TESTING_interpreter_lookup_command (tss->create_label);
57 GNUNET_TESTING_get_trait_test_system (system_cmd,
58 &tl_system);
59 GNUNET_TESTING_system_destroy (tl_system, GNUNET_YES);
60}
61
62
63/**
64 * The cleanup function of this cmd frees resources the cmd allocated.
65 *
66 */
67static void
68system_destroy_cleanup (void *cls,
69 const struct GNUNET_TESTING_Command *cmd)
70{
71 struct TestSystemState *tss = cls;
72
73 GNUNET_free (tss);
74}
75
76
77/**
78 * Trait function of this cmd does nothing.
79 *
80 */
81static int
82system_destroy_traits (void *cls,
83 const void **ret,
84 const char *trait,
85 unsigned int index)
86{
87 return GNUNET_OK;
88}
89
90
91/**
92 * Create command.
93 *
94 * @param label name for command.
95 * @param create_label Label of the cmd which started the test system.
96 * @return command.
97 */
98struct GNUNET_TESTING_Command
99GNUNET_TESTING_cmd_system_destroy (const char *label,
100 const char *create_label)
101{
102 struct TestSystemState *tss;
103
104 tss = GNUNET_new (struct TestSystemState);
105 tss->create_label = create_label;
106
107 struct GNUNET_TESTING_Command cmd = {
108 .cls = tss,
109 .label = label,
110 .run = &system_destroy_run,
111 .cleanup = &system_destroy_cleanup,
112 .traits = &system_destroy_traits
113 };
114
115 return cmd;
116}
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c
index f4fa4e17e..0c24c0e26 100644
--- a/src/testing/testing_api_loop.c
+++ b/src/testing/testing_api_loop.c
@@ -35,6 +35,7 @@
35 35
36struct GNUNET_TESTING_Interpreter *is; 36struct GNUNET_TESTING_Interpreter *is;
37 37
38
38/** 39/**
39 * Closure used to sync an asynchronous with an synchronous command. 40 * Closure used to sync an asynchronous with an synchronous command.
40 */ 41 */
@@ -57,6 +58,7 @@ struct SyncTaskClosure
57 struct GNUNET_TESTING_Interpreter *is; 58 struct GNUNET_TESTING_Interpreter *is;
58}; 59};
59 60
61
60/** 62/**
61* Closure used to run the finish task. 63* Closure used to run the finish task.
62*/ 64*/
@@ -74,6 +76,7 @@ struct FinishTaskClosure
74 struct GNUNET_TESTING_Interpreter *is; 76 struct GNUNET_TESTING_Interpreter *is;
75}; 77};
76 78
79
77/** 80/**
78 * Lookup command by label. 81 * Lookup command by label.
79 * 82 *
@@ -185,6 +188,10 @@ interpreter_next (void *cls)
185} 188}
186 189
187 190
191/**
192 * This function checks if the finish function of a command returns GNUNET_YES, when the command is finished. In this case the finish function might have called interpreter_next. IF GNUNET_NO was returned this function is added to the scheduler again. In case of an error interpreter_fail is called.
193 *
194 */
188static void 195static void
189run_finish_task_next (void *cls) 196run_finish_task_next (void *cls)
190{ 197{
@@ -212,6 +219,12 @@ run_finish_task_next (void *cls)
212} 219}
213 220
214 221
222/**
223 * This function checks if the finish function of an asynchronous command returns GNUNET_YES, when the command is finished. In this case the finish function might have called interpreter_next. IF GNUNET_NO was returned this function is added to the scheduler again. In case of an error interpreter_fail is called.
224 *
225 * //TODO run_finish_task_next and this function can be merged.
226 *
227 */
215static void 228static void
216run_finish_task_sync (void *cls) 229run_finish_task_sync (void *cls)
217{ 230{
@@ -248,13 +261,17 @@ run_finish_task_sync (void *cls)
248 } 261 }
249 else 262 else
250 { 263 {
251 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 264 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
252 "Sync task finished with an error.\n"); 265 "Sync task finished with an error.\n");
253 GNUNET_TESTING_interpreter_fail (); 266 GNUNET_TESTING_interpreter_fail ();
254 } 267 }
255} 268}
256 269
257 270
271/**
272 * run method of the command created by the interpreter to wait for another command to finish.
273 *
274 */
258static void 275static void
259start_finish_on_ref (void *cls, 276start_finish_on_ref (void *cls,
260 const struct GNUNET_TESTING_Command *cmd, 277 const struct GNUNET_TESTING_Command *cmd,
@@ -277,6 +294,17 @@ start_finish_on_ref (void *cls,
277} 294}
278 295
279 296
297/**
298 * Create (synchronous) command that waits for another command to finish.
299 * If @a cmd_ref did not finish after @a timeout, this command will fail
300 * the test case.
301 *
302 * @param finish_label label for this command
303 * @param cmd_ref reference to a previous command which we should
304 * wait for (call `finish()` on)
305 * @param timeout how long to wait at most for @a cmd_ref to finish
306 * @return a finish-command.
307 */
280const struct GNUNET_TESTING_Command 308const struct GNUNET_TESTING_Command
281GNUNET_TESTING_cmd_finish (const char *finish_label, 309GNUNET_TESTING_cmd_finish (const char *finish_label,
282 const char *cmd_ref, 310 const char *cmd_ref,
@@ -340,7 +368,7 @@ GNUNET_TESTING_interpreter_fail ()
340 while (GNUNET_TESTING_cmd_is_batch (cmd)) 368 while (GNUNET_TESTING_cmd_is_batch (cmd))
341 { 369 {
342 cmd = GNUNET_TESTING_cmd_batch_get_current (cmd); 370 cmd = GNUNET_TESTING_cmd_batch_get_current (cmd);
343 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 371 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
344 "Batch is at command `%s'\n", 372 "Batch is at command `%s'\n",
345 cmd->label); 373 cmd->label);
346 } 374 }
@@ -354,7 +382,7 @@ GNUNET_TESTING_interpreter_fail ()
354 382
355 if (NULL == cmd->label) 383 if (NULL == cmd->label)
356 { 384 {
357 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 385 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
358 "Failed at command `%s'\n", 386 "Failed at command `%s'\n",
359 cmd->label); 387 cmd->label);
360 388
@@ -415,7 +443,7 @@ interpreter_run (void *cls)
415 if (NULL == cmd->label) 443 if (NULL == cmd->label)
416 { 444 {
417 445
418 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 446 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
419 "Running command END %p\n", 447 "Running command END %p\n",
420 is); 448 is);
421 is->result = GNUNET_OK; 449 is->result = GNUNET_OK;
@@ -424,7 +452,7 @@ interpreter_run (void *cls)
424 } 452 }
425 else if (NULL != cmd) 453 else if (NULL != cmd)
426 { 454 {
427 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 455 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
428 "Running command `%s' %p\n", 456 "Running command `%s' %p\n",
429 cmd->label, 457 cmd->label,
430 is); 458 is);
@@ -478,8 +506,14 @@ do_shutdown (void *cls)
478 for (unsigned int j = 0; 506 for (unsigned int j = 0;
479 NULL != (cmd = &is->commands[j])->label; 507 NULL != (cmd = &is->commands[j])->label;
480 j++) { 508 j++) {
509 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
510 "Cleaning up cmd %s\n",
511 cmd->label);
481 cmd->cleanup (cmd->cls, 512 cmd->cleanup (cmd->cls,
482 cmd); 513 cmd);
514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
515 "Cleaned up cmd %s\n",
516 cmd->label);
483 } 517 }
484 518
485 if (NULL != is->finish_task) 519 if (NULL != is->finish_task)
diff --git a/src/testing/testing_cmds.h b/src/testing/testing_cmds.h
new file mode 100644
index 000000000..7a5860aea
--- /dev/null
+++ b/src/testing/testing_cmds.h
@@ -0,0 +1,90 @@
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
32GNUNET_NETWORK_STRUCT_BEGIN
33
34/**
35 * Initialization message for gnunet-cmds-testbed to start cmd binary.
36 */
37struct GNUNET_CMDS_HelperInit
38{
39 /**
40 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT
41 */
42 struct GNUNET_MessageHeader header;
43
44 /**
45 *
46 */
47 uint16_t plugin_name_size GNUNET_PACKED;
48
49 /* Followed by plugin name of the plugin running the test case. This is not NULL
50 * terminated */
51};
52
53/**
54 * Reply message from cmds helper process
55 */
56struct GNUNET_CMDS_HelperReply
57{
58 /**
59 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY
60 */
61 struct GNUNET_MessageHeader header;
62};
63
64struct GNUNET_CMDS_PEER_STARTED
65{
66 /**
67 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED
68 */
69 struct GNUNET_MessageHeader header;
70};
71
72struct GNUNET_CMDS_ALL_PEERS_STARTED
73{
74 /**
75 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED
76 */
77 struct GNUNET_MessageHeader header;
78};
79
80struct GNUNET_CMDS_LOCAL_FINISHED
81{
82 /**
83 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED
84 */
85 struct GNUNET_MessageHeader header;
86};
87
88GNUNET_NETWORK_STRUCT_END
89#endif
90/* end of testing_cmds.h */
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 3d8fa7774..4ea3b58c4 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -156,21 +156,17 @@ libgnunettransporttesting_la_LIBADD = \
156 $(top_builddir)/src/testing/libgnunettesting.la \ 156 $(top_builddir)/src/testing/libgnunettesting.la \
157 $(top_builddir)/src/arm/libgnunetarm.la \ 157 $(top_builddir)/src/arm/libgnunetarm.la \
158 $(GN_LIBINTL) 158 $(GN_LIBINTL)
159libgnunettransporttesting_la_DEPENDENCIES = \
160 libgnunettransport.la \
161 $(top_builddir)/src/hello/libgnunethello.la \
162 $(top_builddir)/src/ats/libgnunetats.la \
163 $(top_builddir)/src/util/libgnunetutil.la \
164 $(top_builddir)/src/testing/libgnunettesting.la \
165 $(top_builddir)/src/arm/libgnunetarm.la
166libgnunettransporttesting_la_LDFLAGS = \ 159libgnunettransporttesting_la_LDFLAGS = \
167 $(GN_LIB_LDFLAGS) 160 $(GN_LIB_LDFLAGS)
168 161
169libgnunettransporttesting2_la_SOURCES = \ 162libgnunettransporttesting2_la_SOURCES = \
170 transport_api_cmd_connecting_peers.c \ 163 transport_api_cmd_connecting_peers.c \
171 transport_api_cmd_start_peer.c \ 164 transport_api_cmd_start_peer.c \
165 transport_api_cmd_stop_peer.c \
172 transport_api_cmd_send_simple.c \ 166 transport_api_cmd_send_simple.c \
173 transport-testing2.c transport-testing2.h \ 167 transport-testing2.c transport-testing2.h \
168 transport-testing-ng.h \
169 transport-testing-cmds.h \
174 transport-testing-filenames2.c \ 170 transport-testing-filenames2.c \
175 transport-testing-loggers2.c \ 171 transport-testing-loggers2.c \
176 transport-testing-main2.c \ 172 transport-testing-main2.c \
@@ -187,7 +183,8 @@ libgnunettransporttesting2_la_LIBADD = \
187 $(top_builddir)/src/util/libgnunetutil.la 183 $(top_builddir)/src/util/libgnunetutil.la
188libgnunettransporttesting2_la_LDFLAGS = \ 184libgnunettransporttesting2_la_LDFLAGS = \
189 $(GN_LIBINTL) \ 185 $(GN_LIBINTL) \
190 $(GN_LIB_LDFLAGS) 186 $(GN_LIB_LDFLAGS) \
187 -version-info 0:0:0
191 188
192libgnunettransport_la_SOURCES = \ 189libgnunettransport_la_SOURCES = \
193 transport.h \ 190 transport.h \
@@ -205,10 +202,6 @@ libgnunettransport_la_LIBADD = \
205 $(top_builddir)/src/ats/libgnunetats.la \ 202 $(top_builddir)/src/ats/libgnunetats.la \
206 $(top_builddir)/src/util/libgnunetutil.la \ 203 $(top_builddir)/src/util/libgnunetutil.la \
207 $(GN_LIBINTL) 204 $(GN_LIBINTL)
208libgnunettransport_la_DEPENDENCIES = \
209 $(top_builddir)/src/hello/libgnunethello.la \
210 $(top_builddir)/src/ats/libgnunetats.la \
211 $(top_builddir)/src/util/libgnunetutil.la
212libgnunettransport_la_LDFLAGS = \ 205libgnunettransport_la_LDFLAGS = \
213 $(GN_LIB_LDFLAGS) \ 206 $(GN_LIB_LDFLAGS) \
214 -version-info 4:0:2 207 -version-info 4:0:2
@@ -397,23 +390,29 @@ plugin_LTLIBRARIES = \
397 $(HTTP_SERVER_PLUGIN_LA) \ 390 $(HTTP_SERVER_PLUGIN_LA) \
398 $(HTTPS_SERVER_PLUGIN_LA) \ 391 $(HTTPS_SERVER_PLUGIN_LA) \
399 $(WLAN_PLUGIN_LA) \ 392 $(WLAN_PLUGIN_LA) \
400 $(BT_PLUGIN_LA) 393 $(BT_PLUGIN_LA) \
401# libgnunet_plugin_cmd_simple_send.la 394 libgnunet_test_transport_plugin_cmd_simple_send.la
402 395
403#libgnunet_plugin_cmd_simple_send_la_SOURCES = \ 396libgnunet_test_transport_plugin_cmd_simple_send_la_SOURCES = \
404# plugin_cmd_simple_send.c 397 test_transport_plugin_cmd_simple_send.c
405#libgnunet_plugin_cmd_simple_send_la_LIBADD = \ 398libgnunet_test_transport_plugin_cmd_simple_send_la_LIBADD = \
406# $(top_builddir)/src/util/libgnunetutil.la \ 399 libgnunettransporttesting2.la \
407# $(top_builddir)/src/testing/libgnunettesting.la \ 400 libgnunettransportapplication.la \
408# $(top_builddir)/src/statistics/libgnunetstatistics.la \ 401 libgnunettransport.la \
409# $(top_builddir)/src/testbed/libgnunettestbed.la \ 402 $(top_builddir)/src/testing/libgnunettesting.la \
410# libgnunettransporttesting2.la \ 403 $(top_builddir)/src/peerstore/libgnunetpeerstore.la \
411# $(LTLIBINTL) 404 $(top_builddir)/src/statistics/libgnunetstatistics.la \
412#libgnunet_plugin_cmd_simple_send_la_LDFLAGS = \ 405 $(top_builddir)/src/hello/libgnunethello.la \
413# $(GN_PLUGIN_LDFLAGS) 406 $(top_builddir)/src/ats/libgnunetats.la \
407 $(top_builddir)/src/arm/libgnunetarm.la \
408 $(top_builddir)/src/util/libgnunetutil.la \
409 $(LTLIBINTL)
410libgnunet_test_transport_plugin_cmd_simple_send_la_LDFLAGS = \
411 $(GN_PLUGIN_LDFLAGS)
414 412
415if HAVE_EXPERIMENTAL 413if HAVE_EXPERIMENTAL
416plugin_LTLIBRARIES += libgnunet_plugin_transport_udp.la 414plugin_LTLIBRARIES += \
415 libgnunet_plugin_transport_udp.la
417endif 416endif
418 417
419# Note: real plugins of course need to be added 418# Note: real plugins of course need to be added
@@ -557,7 +556,7 @@ libgnunet_plugin_transport_https_server_la_CFLAGS = \
557 556
558if HAVE_TESTING 557if HAVE_TESTING
559check_PROGRAMS = \ 558check_PROGRAMS = \
560 test_transport_api_cmd_simple_send \ 559 test_transport_simple_send \
561 test_transport_address_switch_tcp \ 560 test_transport_address_switch_tcp \
562 test_transport_testing_startstop \ 561 test_transport_testing_startstop \
563 test_transport_testing_restart \ 562 test_transport_testing_restart \
@@ -646,7 +645,6 @@ endif
646if ENABLE_TEST_RUN 645if ENABLE_TEST_RUN
647AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; 646AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
648TESTS = \ 647TESTS = \
649 test_transport_api_cmd_simple_send \
650 test_transport_address_switch_tcp \ 648 test_transport_address_switch_tcp \
651 $(HTTP_SWITCH) \ 649 $(HTTP_SWITCH) \
652 $(HTTPS_SWITCH) \ 650 $(HTTPS_SWITCH) \
@@ -699,13 +697,15 @@ TESTS = \
699 $(HTTP_API_TIMEOUT_TEST) \ 697 $(HTTP_API_TIMEOUT_TEST) \
700 $(HTTPS_API_TIMEOUT_TEST) \ 698 $(HTTPS_API_TIMEOUT_TEST) \
701 $(WLAN_TIMEOUT_TEST) \ 699 $(WLAN_TIMEOUT_TEST) \
702 $(BT_TIMEOUT_TEST) 700 $(BT_TIMEOUT_TEST) \
701 $(check_SCRIPTS)
703if HAVE_GETOPT_BINARY 702if HAVE_GETOPT_BINARY
704TESTS += \ 703TESTS += \
705test_transport_api_slow_ats 704test_transport_api_slow_ats
706endif 705endif
707if HAVE_EXPERIMENTAL 706if HAVE_EXPERIMENTAL
708TESTS += \ 707TESTS += \
708 test_transport_simple_send \
709 test_transport_address_switch_udp \ 709 test_transport_address_switch_udp \
710 test_plugin_udp \ 710 test_plugin_udp \
711 test_transport_api_udp \ 711 test_transport_api_udp \
@@ -723,14 +723,17 @@ TESTS += \
723endif 723endif
724endif 724endif
725 725
726test_transport_api_cmd_simple_send_SOURCES = \ 726check_SCRIPTS= \
727 test_transport_api_cmd_simple_send.c 727 test_transport_simple_send.sh
728test_transport_api_cmd_simple_send_LDADD = \ 728
729test_transport_simple_send_SOURCES = \
730 test_transport_simple_send.c
731test_transport_simple_send_LDADD = \
729 $(top_builddir)/src/testing/libgnunettesting.la \ 732 $(top_builddir)/src/testing/libgnunettesting.la \
730 $(top_builddir)/src/util/libgnunetutil.la \ 733 $(top_builddir)/src/util/libgnunetutil.la \
731 $(top_builddir)/src/testbed/libgnunettestbed.la \ 734 $(top_builddir)/src/testbed/libgnunettestbed.la \
732 libgnunettransport.la \
733 $(top_builddir)/src/hello/libgnunethello.la \ 735 $(top_builddir)/src/hello/libgnunethello.la \
736 libgnunettransport.la \
734 libgnunettransporttesting.la 737 libgnunettransporttesting.la
735 738
736test_transport_testing_startstop_SOURCES = \ 739test_transport_testing_startstop_SOURCES = \
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c
index 1b838bf9c..d8bf7c1a8 100644
--- a/src/transport/gnunet-communicator-tcp.c
+++ b/src/transport/gnunet-communicator-tcp.c
@@ -879,12 +879,15 @@ queue_destroy (struct Queue *queue)
879 struct GNUNET_HashCode h_sock; 879 struct GNUNET_HashCode h_sock;
880 int sockfd; 880 int sockfd;
881 881
882 sockfd = GNUNET_NETWORK_get_fd (queue->listen_sock); 882 if (NULL != queue->listen_sock)
883 GNUNET_CRYPTO_hash (&sockfd, 883 {
884 sizeof(int), 884 sockfd = GNUNET_NETWORK_get_fd (queue->listen_sock);
885 &h_sock); 885 GNUNET_CRYPTO_hash (&sockfd,
886 sizeof(int),
887 &h_sock);
886 888
887 lt = GNUNET_CONTAINER_multihashmap_get (lt_map, &h_sock); 889 lt = GNUNET_CONTAINER_multihashmap_get (lt_map, &h_sock);
890 }
888 891
889 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 892 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
890 "Disconnecting queue for peer `%s'\n", 893 "Disconnecting queue for peer `%s'\n",
@@ -1900,6 +1903,9 @@ queue_read (void *cls)
1900 BUF_SIZE - queue->cread_off); 1903 BUF_SIZE - queue->cread_off);
1901 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1904 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1902 "Received %lu bytes from TCP queue\n", rcvd); 1905 "Received %lu bytes from TCP queue\n", rcvd);
1906 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
1907 "transport",
1908 "Received %lu bytes from TCP queue\n", rcvd);
1903 if (-1 == rcvd) 1909 if (-1 == rcvd)
1904 { 1910 {
1905 if ((EAGAIN != errno) && (EINTR != errno)) 1911 if ((EAGAIN != errno) && (EINTR != errno))
@@ -2675,6 +2681,9 @@ proto_read_kx (void *cls)
2675 sizeof(pq->ibuf) - pq->ibuf_off); 2681 sizeof(pq->ibuf) - pq->ibuf_off);
2676 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2682 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2677 "Received %lu bytes for KX\n", rcvd); 2683 "Received %lu bytes for KX\n", rcvd);
2684 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
2685 "transport",
2686 "Received %lu bytes for KX\n", rcvd);
2678 if (-1 == rcvd) 2687 if (-1 == rcvd)
2679 { 2688 {
2680 if ((EAGAIN != errno) && (EINTR != errno)) 2689 if ((EAGAIN != errno) && (EINTR != errno))
@@ -2704,7 +2713,7 @@ proto_read_kx (void *cls)
2704 { 2713 {
2705 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2714 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2706 "Invalid TCP KX received from %s\n", 2715 "Invalid TCP KX received from %s\n",
2707 GNUNET_a2s (queue->address, queue->address_len)); 2716 GNUNET_a2s (pq->address, pq->address_len));
2708 gcry_cipher_close (queue->in_cipher); 2717 gcry_cipher_close (queue->in_cipher);
2709 GNUNET_free (queue); 2718 GNUNET_free (queue);
2710 free_proto_queue (pq); 2719 free_proto_queue (pq);
@@ -2824,6 +2833,10 @@ queue_read_kx (void *cls)
2824 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2833 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2825 "Received %lu bytes for KX\n", 2834 "Received %lu bytes for KX\n",
2826 rcvd); 2835 rcvd);
2836 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
2837 "transport",
2838 "Received %lu bytes for KX\n",
2839 rcvd);
2827 if (-1 == rcvd) 2840 if (-1 == rcvd)
2828 { 2841 {
2829 if ((EAGAIN != errno) && (EINTR != errno)) 2842 if ((EAGAIN != errno) && (EINTR != errno))
@@ -2918,6 +2931,9 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
2918 2931
2919 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2932 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2920 "Connecting to %s\n", address); 2933 "Connecting to %s\n", address);
2934 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
2935 "transport",
2936 "Connecting to %s\n", address);
2921 if (0 != strncmp (address, 2937 if (0 != strncmp (address,
2922 COMMUNICATOR_ADDRESS_PREFIX "-", 2938 COMMUNICATOR_ADDRESS_PREFIX "-",
2923 strlen (COMMUNICATOR_ADDRESS_PREFIX "-"))) 2939 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
@@ -3069,9 +3085,9 @@ do_shutdown (void *cls)
3069 GNUNET_CONTAINER_multihashmap_iterate (lt_map, &get_lt_delete_it, NULL); 3085 GNUNET_CONTAINER_multihashmap_iterate (lt_map, &get_lt_delete_it, NULL);
3070 GNUNET_CONTAINER_multipeermap_iterate (queue_map, &get_queue_delete_it, NULL); 3086 GNUNET_CONTAINER_multipeermap_iterate (queue_map, &get_queue_delete_it, NULL);
3071 GNUNET_CONTAINER_multipeermap_destroy (queue_map); 3087 GNUNET_CONTAINER_multipeermap_destroy (queue_map);
3072 GNUNET_TRANSPORT_communicator_address_remove_all (ch);
3073 if (NULL != ch) 3088 if (NULL != ch)
3074 { 3089 {
3090 GNUNET_TRANSPORT_communicator_address_remove_all (ch);
3075 GNUNET_TRANSPORT_communicator_disconnect (ch); 3091 GNUNET_TRANSPORT_communicator_disconnect (ch);
3076 ch = NULL; 3092 ch = NULL;
3077 } 3093 }
@@ -3238,7 +3254,7 @@ init_socket (struct sockaddr *addr,
3238 return GNUNET_SYSERR; 3254 return GNUNET_SYSERR;
3239 } 3255 }
3240 3256
3241 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3257 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3242 "address %s\n", 3258 "address %s\n",
3243 GNUNET_a2s (addr, in_len)); 3259 GNUNET_a2s (addr, in_len));
3244 3260
diff --git a/src/transport/plugin_cmd_simple_send.c b/src/transport/plugin_cmd_simple_send.c
deleted file mode 100644
index 62bb7544b..000000000
--- a/src/transport/plugin_cmd_simple_send.c
+++ /dev/null
@@ -1,188 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2013, 2014 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/plugin_cmd_simple_send.c
23 * @brief a plugin to provide the API for running test cases.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_transport_application_service.h"
30// #include "gnunet_transport_service.h"
31#include "gnunet_testbed_ng_service.h"
32#include "transport-testing2.h"
33
34/**
35 * Generic logging shortcut
36 */
37#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
38
39#define BASE_DIR "testdir"
40
41struct GNUNET_MQ_MessageHandler *handlers;
42
43unsigned int are_all_peers_started;
44
45static int
46check_test (void *cls,
47 const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
48{
49 return GNUNET_OK;
50}
51
52static void
53handle_test (void *cls,
54 const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
55{
56 LOG (GNUNET_ERROR_TYPE_ERROR,
57 "message received\n");
58}
59
60static int
61check_test2 (void *cls,
62 const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
63{
64 return GNUNET_OK;
65}
66
67static void
68handle_test2 (void *cls,
69 const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
70{
71 LOG (GNUNET_ERROR_TYPE_ERROR,
72 "message received\n");
73}
74
75static void
76all_peers_started ()
77{
78 are_all_peers_started = GNUNET_YES;
79 LOG (GNUNET_ERROR_TYPE_ERROR,
80 "setting are_all_peers_started: %d\n",
81 are_all_peers_started);
82}
83
84static void
85start_testcase (TESTBED_CMD_HELPER_write_cb write_message, char *router_ip,
86 char *node_ip,
87 char *m,
88 char *n)
89{
90 char *testdir;
91 char *cfgname;
92
93 GNUNET_asprintf (&cfgname,
94 "%s%s.conf",
95 "test_transport_api2_tcp_peer",
96 n);
97
98 LOG (GNUNET_ERROR_TYPE_ERROR,
99 "cfgname: %s\n",
100 cfgname);
101
102 testdir = GNUNET_malloc (strlen (BASE_DIR) + strlen (m) + strlen (n)
103 + 1);
104
105 strcpy (testdir, BASE_DIR);
106 strcat (testdir, m);
107 strcat (testdir, n);
108
109 struct GNUNET_MQ_MessageHandler handlers[] = {
110 GNUNET_MQ_hd_var_size (test,
111 GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE,
112 struct GNUNET_TRANSPORT_TESTING_TestMessage,
113 NULL),
114 GNUNET_MQ_hd_var_size (test2,
115 GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE2,
116 struct GNUNET_TRANSPORT_TESTING_TestMessage,
117 NULL),
118 GNUNET_MQ_handler_end ()
119 };
120
121 struct GNUNET_TESTING_Command commands[] = {
122 GNUNET_TESTING_cmd_system_create ("system-create-1",
123 testdir),
124 GNUNET_TRANSPORT_cmd_start_peer ("start-peer-1",
125 "system-create-1",
126 m,
127 n,
128 handlers,
129 cfgname),
130 GNUNET_TESTING_cmd_send_peer_ready ("send-peer-ready-1",
131 write_message),
132 GNUNET_TESTING_cmd_block_until_all_peers_started ("block-1",
133 &are_all_peers_started),
134 GNUNET_TRANSPORT_cmd_connect_peers ("connect-peers-1",
135 "start-peer-1",
136 "this is useless"),
137 /*GNUNET_TESTING_cmd_send_simple ("send-simple-1",
138 char *m,
139 char *n,
140 uint32_t num,
141 const char *peer1_label,
142 const char *peer2_label),*/
143 GNUNET_TESTING_cmd_local_test_finished ("local-test-finished-1",
144 write_message)
145 };
146
147 GNUNET_TESTING_run (NULL,
148 commands,
149 GNUNET_TIME_UNIT_FOREVER_REL);
150
151}
152
153
154/**
155 * Entry point for the plugin.
156 *
157 * @param cls NULL
158 * @return the exported block API
159 */
160void *
161libgnunet_plugin_cmd_simple_send_init (void *cls)
162{
163 struct GNUNET_TESTING_PluginFunctions *api;
164
165 api = GNUNET_new (struct GNUNET_TESTING_PluginFunctions);
166 api->start_testcase = &start_testcase;
167 api->all_peers_started = &all_peers_started;
168 return api;
169}
170
171
172/**
173 * Exit point from the plugin.
174 *
175 * @param cls the return value from #libgnunet_plugin_block_test_init
176 * @return NULL
177 */
178void *
179libgnunet_plugin_cmd_simple_send_done (void *cls)
180{
181 struct GNUNET_TESTING_PluginFunctions *api = cls;
182
183 GNUNET_free (api);
184 return NULL;
185}
186
187
188/* end of plugin_cmd_simple_send.c */
diff --git a/src/transport/test_transport_api2_tcp_node1.conf b/src/transport/test_transport_api2_tcp_node1.conf
new file mode 100644
index 000000000..a867ea81a
--- /dev/null
+++ b/src/transport/test_transport_api2_tcp_node1.conf
@@ -0,0 +1,23 @@
1@INLINE@ template_cfg_peer1.conf
2[PATHS]
3GNUNET_TEST_HOME = $GNUNET_TMP/test-transport/api-tcp-p1/
4
5[transport]
6BINARY = gnunet-service-tng
7PLUGINS = tcp
8#PREFIX = valgrind --log-file=/tmp/vg_peer1-%p
9UNIXPATH = $GNUNET_RUNTIME_DIR/tng-p1.sock
10
11[communicator-tcp]
12BINARY = gnunet-communicator-tcp
13BINDTO = 192.168.15.1:60002
14DISABLE_V6 = YES
15IMMEDIATE_START = YES
16UNIXPATH = $GNUNET_RUNTIME_DIR/tcp-comm-p1.sock
17#PREFIX = valgrind --log-file=/tmp/vg_cpeer1-%p
18
19[peerstore]
20IMMEDIATE_START = YES
21
22#[transport]
23#PREFIX = valgrind
diff --git a/src/transport/test_transport_api2_tcp_node2.conf b/src/transport/test_transport_api2_tcp_node2.conf
new file mode 100644
index 000000000..f94368b3f
--- /dev/null
+++ b/src/transport/test_transport_api2_tcp_node2.conf
@@ -0,0 +1,22 @@
1@INLINE@ template_cfg_peer2.conf
2[PATHS]
3GNUNET_TEST_HOME = $GNUNET_TMP/test-transport/api-tcp-p2/
4
5[transport]
6BINARY = gnunet-service-tng
7#PREFIX = valgrind --log-file=/tmp/vg_peer2-%p
8UNIXPATH = $GNUNET_RUNTIME_DIR/tng-p2.sock
9
10[communicator-tcp]
11BINARY = gnunet-communicator-tcp
12BINDTO = 192.168.15.2:60003
13DISABLE_V6 = YES
14IMMEDIATE_START = YES
15#PREFIX = valgrind --log-file=/tmp/vg_comm2-%p
16UNIXPATH = $GNUNET_RUNTIME_DIR/tcp-comm-p2.sock
17
18[peerstore]
19IMMEDIATE_START = YES
20
21#[transport]
22#PREFIX = valgrind
diff --git a/src/transport/test_transport_api_cmd_simple_send.c b/src/transport/test_transport_api_cmd_simple_send.c
deleted file mode 100644
index 9ae8fcc2b..000000000
--- a/src/transport/test_transport_api_cmd_simple_send.c
+++ /dev/null
@@ -1,80 +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_api_cmd_simple_send.c
23 * @brief Test case executing a script which sends a test message between two peers.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_testbed_ng_service.h"
29#include "gnunet_util_lib.h"
30
31
32/**
33 * Main function to run the test cases.
34 *
35 * @param cls not used.
36 *
37 */
38static void
39run (void *cls)
40{
41 struct GNUNET_TESTING_Command commands[] = {
42 GNUNET_TESTBED_cmd_netjail_start ("netjail-start-1",
43 "2",
44 "1"),
45 GNUNET_TESTBED_cmd_netjail_start_testbed ("netjail-start-testbed-1",
46 "2",
47 "1",
48 "libgnunet_plugin_cmd_simple_send"),
49 GNUNET_TESTBED_cmd_stop_testbed ("stop-testbed",
50 "netjail-start-testbed-1",
51 "2",
52 "1"),
53 GNUNET_TESTBED_cmd_netjail_stop ("netjail-stop-1",
54 "2",
55 "1"),
56 GNUNET_TESTING_cmd_end ()
57 };
58
59 GNUNET_TESTING_run (NULL,
60 commands,
61 GNUNET_TIME_UNIT_FOREVER_REL);
62}
63
64
65int
66main (int argc,
67 char *const *argv)
68{
69 int rv = 0;
70
71 GNUNET_log_setup ("test-netjail",
72 "DEBUG",
73 NULL);
74 GNUNET_SCHEDULER_run (&run,
75 NULL);
76
77 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
78 "Test finished!\n");
79 return rv;
80}
diff --git a/src/transport/test_transport_plugin_cmd_simple_send.c b/src/transport/test_transport_plugin_cmd_simple_send.c
new file mode 100644
index 000000000..4b5018b60
--- /dev/null
+++ b/src/transport/test_transport_plugin_cmd_simple_send.c
@@ -0,0 +1,248 @@
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/plugin_cmd_simple_send.c
23 * @brief a plugin to provide the API for running test cases.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_transport_application_service.h"
30#include "transport-testing2.h"
31#include "transport-testing-cmds.h"
32
33/**
34 * Generic logging shortcut
35 */
36#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
37
38#define BASE_DIR "testdir"
39
40/**
41 * The name for a specific test environment directory.
42 *
43 */
44char *testdir;
45
46/**
47 * The name for the configuration file of the specific node.
48 *
49 */
50char *cfgname;
51
52/**
53 * Flag indicating if all peers have been started.
54 *
55 */
56unsigned int are_all_peers_started;
57
58
59/**
60 * Function called to check a message of type GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE being
61 * received.
62 *
63 */
64static int
65check_test (void *cls,
66 const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
67{
68 return GNUNET_OK;
69}
70
71
72/**
73 * Function called to handle a message of type GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE
74 * being received.
75 *
76 */
77static void
78handle_test (void *cls,
79 const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
80{
81 LOG (GNUNET_ERROR_TYPE_ERROR,
82 "message received\n");
83}
84
85
86/**
87 * Function called to check a message of type GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE2
88 * being received.
89 *
90 */
91static int
92check_test2 (void *cls,
93 const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
94{
95 return GNUNET_OK;
96}
97
98
99/**
100 * Function called to handle a message of type GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE2
101 * being received.
102 *
103 */
104static void
105handle_test2 (void *cls,
106 const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
107{
108 LOG (GNUNET_ERROR_TYPE_ERROR,
109 "message received\n");
110}
111
112
113/**
114 * Callback to set the flag indicating all peers started. Will be called via the plugin api.
115 *
116 */
117static void
118all_peers_started ()
119{
120 are_all_peers_started = GNUNET_YES;
121 LOG (GNUNET_ERROR_TYPE_ERROR,
122 "setting are_all_peers_started: %d\n",
123 are_all_peers_started);
124}
125
126
127/**
128 * Function to start a local test case.
129 *
130 * @param write_message Callback to send a message to the master loop.
131 * @param router_ip Global address of the network namespace.
132 * @param node_ip Local address of a node i a network namespace.
133 * @param m The number of the node in a network namespace.
134 * @param n The number of the network namespace.
135 * @param local_m The number of nodes in a network namespace.
136 */
137static void
138start_testcase (TESTING_CMD_HELPER_write_cb write_message, char *router_ip,
139 char *node_ip,
140 char *m,
141 char *n,
142 char *local_m)
143{
144
145 GNUNET_asprintf (&cfgname,
146 "test_transport_api2_tcp_node%s.conf",
147 n);
148
149 LOG (GNUNET_ERROR_TYPE_ERROR,
150 "plugin cfgname: %s\n",
151 cfgname);
152
153 LOG (GNUNET_ERROR_TYPE_ERROR,
154 "node ip: %s\n",
155 node_ip);
156
157 GNUNET_asprintf (&testdir,
158 "%s%s%s",
159 BASE_DIR,
160 m,
161 n);
162
163 struct GNUNET_MQ_MessageHandler handlers[] = {
164 GNUNET_MQ_hd_var_size (test,
165 GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE,
166 struct GNUNET_TRANSPORT_TESTING_TestMessage,
167 NULL),
168 GNUNET_MQ_hd_var_size (test2,
169 GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE2,
170 struct GNUNET_TRANSPORT_TESTING_TestMessage,
171 NULL),
172 GNUNET_MQ_handler_end ()
173 };
174
175 struct GNUNET_TESTING_Command commands[] = {
176 GNUNET_TESTING_cmd_system_create ("system-create",
177 testdir),
178 GNUNET_TRANSPORT_cmd_start_peer ("start-peer",
179 "system-create",
180 m,
181 n,
182 local_m,
183 handlers,
184 cfgname),
185 GNUNET_TESTING_cmd_send_peer_ready ("send-peer-ready",
186 write_message),
187 GNUNET_TESTING_cmd_block_until_all_peers_started ("block",
188 &are_all_peers_started),
189 GNUNET_TRANSPORT_cmd_connect_peers ("connect-peers",
190 "start-peer"),
191 GNUNET_TRANSPORT_cmd_send_simple ("send-simple",
192 m,
193 n,
194 (atoi (n) - 1) * atoi (local_m) + atoi (
195 m),
196 "start-peer"),
197 GNUNET_TRANSPORT_cmd_stop_peer ("stop-peer",
198 "start-peer"),
199 GNUNET_TESTING_cmd_system_destroy ("system-destroy",
200 "system-create"),
201 GNUNET_TESTING_cmd_local_test_finished ("local-test-finished",
202 write_message)
203 };
204
205 GNUNET_TESTING_run (NULL,
206 commands,
207 GNUNET_TIME_UNIT_FOREVER_REL);
208
209}
210
211
212/**
213 * Entry point for the plugin.
214 *
215 * @param cls NULL
216 * @return the exported block API
217 */
218void *
219libgnunet_test_transport_plugin_cmd_simple_send_init (void *cls)
220{
221 struct GNUNET_TESTING_PluginFunctions *api;
222
223 api = GNUNET_new (struct GNUNET_TESTING_PluginFunctions);
224 api->start_testcase = &start_testcase;
225 api->all_peers_started = &all_peers_started;
226 return api;
227}
228
229
230/**
231 * Exit point from the plugin.
232 *
233 * @param cls the return value from #libgnunet_test_transport_plugin_block_test_init
234 * @return NULL
235 */
236void *
237libgnunet_test_transport_plugin_cmd_simple_send_done (void *cls)
238{
239 struct GNUNET_TESTING_PluginFunctions *api = cls;
240
241 GNUNET_free (api);
242 GNUNET_free (testdir);
243 GNUNET_free (cfgname);
244 return NULL;
245}
246
247
248/* end of plugin_cmd_simple_send.c */
diff --git a/src/transport/test_transport_simple_send.sh b/src/transport/test_transport_simple_send.sh
new file mode 100755
index 000000000..25d5b6797
--- /dev/null
+++ b/src/transport/test_transport_simple_send.sh
@@ -0,0 +1,2 @@
1#!/bin/bash
2exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; ./test_transport_simple_send"
diff --git a/src/transport/transport-testing-cmds.h b/src/transport/transport-testing-cmds.h
new file mode 100644
index 000000000..1461a3d4d
--- /dev/null
+++ b/src/transport/transport-testing-cmds.h
@@ -0,0 +1,81 @@
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-testing.h
23 * @brief testing lib for transport service
24 * @author Matthias Wachs
25 * @author Christian Grothoff
26 */
27#ifndef TRANSPORT_TESTING_CMDS_H
28#define TRANSPORT_TESTING_CMDS_H
29#include "gnunet_testing_lib.h"
30
31struct GNUNET_TESTING_Command
32GNUNET_TRANSPORT_cmd_start_peer (const char *label,
33 const char *system_label,
34 char *m,
35 char *n,
36 char *local_m,
37 struct GNUNET_MQ_MessageHandler *handlers,
38 const char *cfgname);
39
40struct GNUNET_TESTING_Command
41GNUNET_TRANSPORT_cmd_stop_peer (const char *label,
42 const char *start_label);
43
44struct GNUNET_TESTING_Command
45GNUNET_TRANSPORT_cmd_connect_peers (const char *label,
46 const char *start_peer_label);
47
48struct GNUNET_TESTING_Command
49GNUNET_TRANSPORT_cmd_send_simple (const char *label,
50 char *m,
51 char *n,
52 uint32_t num,
53 const char *start_peer_label);
54
55int
56GNUNET_TRANSPORT_get_trait_peer_id (const struct
57 GNUNET_TESTING_Command *cmd,
58 struct GNUNET_PeerIdentity **id);
59
60int
61GNUNET_TRANSPORT_get_trait_connected_peers_map (const struct
62 GNUNET_TESTING_Command
63 *cmd,
64 struct
65 GNUNET_CONTAINER_MultiShortmap *
66 *
67 connected_peers_map);
68int
69GNUNET_TRANSPORT_get_trait_hello_size (const struct
70 GNUNET_TESTING_Command
71 *cmd,
72 size_t **hello_size);
73
74int
75GNUNET_TRANSPORT_get_trait_hello (const struct
76 GNUNET_TESTING_Command
77 *cmd,
78 char **hello);
79
80#endif
81/* end of transport_testing.h */
diff --git a/src/transport/transport-testing-ng.h b/src/transport/transport-testing-ng.h
index cd5ba65a9..cd4e1f3fe 100644
--- a/src/transport/transport-testing-ng.h
+++ b/src/transport/transport-testing-ng.h
@@ -22,50 +22,86 @@
22 * @author t3sserakt 22 * @author t3sserakt
23 */ 23 */
24 24
25struct TngState 25struct StartPeerState
26{ 26{
27 /** 27 /**
28 * Handle to operation 28 * Receive callback
29 */ 29 */
30 struct GNUNET_TESTBED_Operation *operation; 30 struct GNUNET_MQ_MessageHandler *handlers;
31
32 const char *cfgname;
33
34 /**
35 * Peer's configuration
36 */
37 struct GNUNET_CONFIGURATION_Handle *cfg;
38
39 struct GNUNET_TESTING_Peer *peer;
31 40
32 /** 41 /**
33 * Flag indicating if service is ready. 42 * Peer identity
34 */ 43 */
35 int service_ready; 44 struct GNUNET_PeerIdentity id;
36 45
37 /** 46 /**
38 * Abort task identifier 47 * Peer's transport service handle
39 */ 48 */
40 struct GNUNET_SCHEDULER_Task *abort_task; 49 struct GNUNET_TRANSPORT_CoreHandle *th;
41 50
42 /** 51 /**
43 * Label of peer command. 52 * Application handle
44 */ 53 */
45 const char *peer_label; 54 struct GNUNET_TRANSPORT_ApplicationHandle *ah;
46 55
47 /** 56 /**
48 * Name of service to start. 57 * Peer's PEERSTORE Handle
49 */ 58 */
50 const char *servicename; 59 struct GNUNET_PEERSTORE_Handle *ph;
51 60
52 /** 61 /**
53 * Peer identity of the system. 62 * Hello get task
54 */ 63 */
55 struct GNUNET_PeerIdentity *peer_identity; 64 struct GNUNET_SCHEDULER_Task *rh_task;
56 65
57 /** 66 /**
58 * Message handler for transport service. 67 * Peer's transport get hello handle to retrieve peer's HELLO message
59 */ 68 */
60 const struct GNUNET_MQ_MessageHandler *handlers; 69 struct GNUNET_PEERSTORE_IterateContext *pic;
61 70
62 /** 71 /**
63 * Notify connect callback 72 * Hello
64 */ 73 */
65 GNUNET_TRANSPORT_NotifyConnect nc; 74 char *hello;
75
76 /**
77 * Hello size
78 */
79 size_t hello_size;
80
81 char *m;
82
83 char *n;
84
85 char *local_m;
86
87 unsigned int finished;
88
89 const char *system_label;
66 90
67 /** 91 /**
68 * Closure for the @a nc callback 92 * An unique number to identify the peer
69 */ 93 */
70 void *cb_cls; 94 unsigned int no;
95
96 struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map;
97
98 struct GNUNET_TESTING_System *tl_system;
99
71}; 100};
101
102
103int
104GNUNET_TRANSPORT_get_trait_state (const struct
105 GNUNET_TESTING_Command
106 *cmd,
107 struct StartPeerState **sps);
diff --git a/src/transport/transport-testing2.h b/src/transport/transport-testing2.h
index a6732e308..e2167ca7e 100644
--- a/src/transport/transport-testing2.h
+++ b/src/transport/transport-testing2.h
@@ -920,42 +920,5 @@ GNUNET_TRANSPORT_TESTING_get_test_plugin_name (const char *executable,
920char * 920char *
921GNUNET_TRANSPORT_TESTING_get_test_source_name (const char *file); 921GNUNET_TRANSPORT_TESTING_get_test_source_name (const char *file);
922 922
923struct GNUNET_TESTING_Command
924GNUNET_TRANSPORT_cmd_start_peer (const char *label,
925 const char *system_label,
926 char *m,
927 char *n,
928 struct GNUNET_MQ_MessageHandler *handlers,
929 const char *cfgname);
930
931struct GNUNET_TESTING_Command
932GNUNET_TRANSPORT_cmd_connect_peers (const char *label,
933 const char *peer1_label,
934 const char *peer2_label);
935
936int
937GNUNET_TRANSPORT_get_trait_peer_id (const struct
938 GNUNET_TESTING_Command *cmd,
939 struct GNUNET_PeerIdentity **id);
940
941int
942GNUNET_TRANSPORT_get_trait_connected_peers_map (const struct
943 GNUNET_TESTING_Command
944 *cmd,
945 struct
946 GNUNET_CONTAINER_MultiPeerMap **
947 connected_peers_map);
948int
949GNUNET_TRANSPORT_get_trait_hello_size (const struct
950 GNUNET_TESTING_Command
951 *cmd,
952 size_t **hello_size);
953
954int
955GNUNET_TRANSPORT_get_trait_hello (const struct
956 GNUNET_TESTING_Command
957 *cmd,
958 char **hello);
959
960#endif 923#endif
961/* end of transport_testing.h */ 924/* end of transport_testing.h */
diff --git a/src/transport/transport_api_cmd_connecting_peers.c b/src/transport/transport_api_cmd_connecting_peers.c
index 0f2154c46..34b3d5925 100644
--- a/src/transport/transport_api_cmd_connecting_peers.c
+++ b/src/transport/transport_api_cmd_connecting_peers.c
@@ -29,20 +29,37 @@
29#include "gnunet_transport_application_service.h" 29#include "gnunet_transport_application_service.h"
30#include "gnunet_hello_lib.h" 30#include "gnunet_hello_lib.h"
31#include "gnunet_transport_service.h" 31#include "gnunet_transport_service.h"
32#include "transport-testing-cmds.h"
32 33
33/** 34/**
34 * Generic logging shortcut 35 * Generic logging shortcut
35 */ 36 */
36#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) 37#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
37 38
39/**
40 * Struct to store information needed in callbacks.
41 *
42 */
38struct ConnectPeersState 43struct ConnectPeersState
39{ 44{
40 const char *peer1_label; 45 /**
41 46 * Label of the cmd to start a peer.
42 const char *peer2_label; 47 *
48 */
49 const char *start_peer_label;
50
51 /**
52 * The peer identity of this peer.
53 *
54 */
55 struct GNUNET_PeerIdentity *id;
43}; 56};
44 57
45 58
59/**
60 * The run method of this cmd will connect to peers.
61 *
62 */
46static void 63static void
47connect_peers_run (void *cls, 64connect_peers_run (void *cls,
48 const struct GNUNET_TESTING_Command *cmd, 65 const struct GNUNET_TESTING_Command *cmd,
@@ -50,25 +67,43 @@ connect_peers_run (void *cls,
50{ 67{
51 struct ConnectPeersState *cps = cls; 68 struct ConnectPeersState *cps = cls;
52 const struct GNUNET_TESTING_Command *peer1_cmd; 69 const struct GNUNET_TESTING_Command *peer1_cmd;
53 const struct GNUNET_TESTING_Command *peer2_cmd; 70 // const struct GNUNET_TESTING_Command *peer2_cmd;
54 struct GNUNET_TRANSPORT_ApplicationHandle *ah; 71 struct GNUNET_TRANSPORT_ApplicationHandle *ah;
55 struct GNUNET_PeerIdentity *id; 72 struct GNUNET_PeerIdentity *peer = GNUNET_new (struct GNUNET_PeerIdentity);
56 char *addr; 73 char *addr;
57 struct GNUNET_TIME_Absolute t; 74 // struct GNUNET_TIME_Absolute t;
58 char *hello; 75 char *hello;
59 size_t *hello_size; 76 // size_t *hello_size;
60 enum GNUNET_NetworkType nt = 0; 77 enum GNUNET_NetworkType nt = 0;
78 char *peer_id;
79 struct GNUNET_PeerIdentity *id;
61 80
62 peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (cps->peer1_label); 81 peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (cps->start_peer_label);
63 GNUNET_TRANSPORT_get_trait_application_handle (peer1_cmd, 82 GNUNET_TRANSPORT_get_trait_application_handle (peer1_cmd,
64 &ah); 83 &ah);
65 84
66 GNUNET_TRANSPORT_get_trait_hello (peer1_cmd, 85 GNUNET_TRANSPORT_get_trait_hello (peer1_cmd,
67 &hello); 86 &hello);
68 87
69 LOG (GNUNET_ERROR_TYPE_ERROR, 88 GNUNET_TRANSPORT_get_trait_peer_id (peer1_cmd,
70 "hello: %s\n", 89 &id);
71 hello); 90
91 if (strstr (hello, "60002") != NULL)
92 {
93 addr = "tcp-192.168.15.2:60003";
94 peer_id = "F2F3X9G1YNCTXKK7A4J6M4ZM4BBSKC9DEXZVHCWQ475M0C7PNWCG";
95 }
96 else
97 {
98 addr = "tcp-192.168.15.1:60002";
99 peer_id = "4TTC9WBSVP9RJT6DVEZ7E0TDW7TQXC11NR1EMR2F8ARS87WZ2730";
100 }
101
102 GNUNET_CRYPTO_eddsa_public_key_from_string (peer_id,
103 strlen (peer_id),
104 &peer->public_key);
105
106 cps->id = peer;
72 107
73 // TODO This does not work, because the other peer is running in another local loop. We need to message between different local loops. For now we will create the hello manually with the known information about the other local peers. 108 // TODO This does not work, because the other peer is running in another local loop. We need to message between different local loops. For now we will create the hello manually with the known information about the other local peers.
74 // --------------------------------------------- 109 // ---------------------------------------------
@@ -84,50 +119,63 @@ connect_peers_run (void *cls,
84 *hello_size, 119 *hello_size,
85 id, 120 id,
86 &nt, 121 &nt,
87 &t); 122 &t);*/
123
124 // ----------------------------------------------
88 125
89 //----------------------------------------------
90 126
91 GNUNET_TRANSPORT_application_validate (ah, 127 GNUNET_TRANSPORT_application_validate (ah,
92 id, 128 peer,
93 nt, 129 nt,
94 addr);*/ 130 addr);
95} 131}
96 132
97 133
134/**
135 * The finish function of this cmd will check if the peer we are trying to connect to is in the connected peers map of the start peer cmd for this peer.
136 *
137 */
98static int 138static int
99connect_peers_finish (void *cls, 139connect_peers_finish (void *cls,
100 GNUNET_SCHEDULER_TaskCallback cont, 140 GNUNET_SCHEDULER_TaskCallback cont,
101 void *cont_cls) 141 void *cont_cls)
102{ 142{
103 /*struct ConnectPeersState *cps = cls; 143 struct ConnectPeersState *cps = cls;
104 const struct GNUNET_TESTING_Command *peer1_cmd; 144 const struct GNUNET_TESTING_Command *peer1_cmd;
105 const struct GNUNET_TESTING_Command *peer2_cmd; 145 struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map;
106 struct GNUNET_CONTAINER_MultiPeerMap *connected_peers_map;
107 unsigned int ret; 146 unsigned int ret;
108 struct GNUNET_PeerIdentity *id; 147 struct GNUNET_ShortHashCode *key = GNUNET_new (struct GNUNET_ShortHashCode);
148 struct GNUNET_HashCode hc;
149 int node_number;
109 150
110 peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (cps->peer1_label); 151 peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (cps->start_peer_label);
111 GNUNET_TRANSPORT_get_trait_peer_id (peer1_cmd, 152 GNUNET_TRANSPORT_get_trait_connected_peers_map (peer1_cmd,
112 &id); 153 &connected_peers_map);
113 154
114 peer2_cmd = GNUNET_TESTING_interpreter_lookup_command (cps->peer2_label); 155 node_number = 1;
115 GNUNET_TRANSPORT_get_trait_connected_peers_map (peer2_cmd, 156 GNUNET_CRYPTO_hash (&node_number, sizeof(node_number), &hc);
116 &connected_peers_map);
117 157
118 ret = GNUNET_CONTAINER_multipeermap_contains (connected_peers_map, 158 // TODO we need to store with a key identifying the netns node in the future. For now we have only one connecting node.
119 id); 159 memcpy (key,
160 &hc,
161 sizeof (*key));
162 ret = GNUNET_CONTAINER_multishortmap_contains (connected_peers_map,
163 key);
120 164
121 if (GNUNET_YES == ret) 165 if (GNUNET_YES == ret)
122 { 166 {
123 cont (cont_cls); 167 cont (cont_cls);
124 } 168 }
125 169
126 return ret;*/ 170 GNUNET_free (key);
127 return GNUNET_OK; 171 return ret;
128} 172}
129 173
130 174
175/**
176 * Trait function of this cmd does nothing.
177 *
178 */
131static int 179static int
132connect_peers_traits (void *cls, 180connect_peers_traits (void *cls,
133 const void **ret, 181 const void **ret,
@@ -138,12 +186,17 @@ connect_peers_traits (void *cls,
138} 186}
139 187
140 188
189/**
190 * The cleanup function of this cmd frees resources the cmd allocated.
191 *
192 */
141static void 193static void
142connect_peers_cleanup (void *cls, 194connect_peers_cleanup (void *cls,
143 const struct GNUNET_TESTING_Command *cmd) 195 const struct GNUNET_TESTING_Command *cmd)
144{ 196{
145 struct ConnectPeersState *cps = cls; 197 struct ConnectPeersState *cps = cls;
146 198
199 GNUNET_free (cps->id);
147 GNUNET_free (cps); 200 GNUNET_free (cps);
148} 201}
149 202
@@ -152,18 +205,17 @@ connect_peers_cleanup (void *cls,
152 * Create command. 205 * Create command.
153 * 206 *
154 * @param label name for command. 207 * @param label name for command.
208 * @param start_peer_label Label of the cmd to start a peer.
155 * @return command. 209 * @return command.
156 */ 210 */
157struct GNUNET_TESTING_Command 211struct GNUNET_TESTING_Command
158GNUNET_TRANSPORT_cmd_connect_peers (const char *label, 212GNUNET_TRANSPORT_cmd_connect_peers (const char *label,
159 const char *peer1_label, 213 const char *start_peer_label)
160 const char *peer2_label)
161{ 214{
162 struct ConnectPeersState *cps; 215 struct ConnectPeersState *cps;
163 216
164 cps = GNUNET_new (struct ConnectPeersState); 217 cps = GNUNET_new (struct ConnectPeersState);
165 cps->peer1_label = peer1_label; 218 cps->start_peer_label = start_peer_label;
166 cps->peer2_label = peer2_label;
167 219
168 220
169 struct GNUNET_TESTING_Command cmd = { 221 struct GNUNET_TESTING_Command cmd = {
diff --git a/src/transport/transport_api_cmd_send_simple.c b/src/transport/transport_api_cmd_send_simple.c
index 4a60f1a12..f9e515c0f 100644
--- a/src/transport/transport_api_cmd_send_simple.c
+++ b/src/transport/transport_api_cmd_send_simple.c
@@ -26,21 +26,45 @@
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_ng_lib.h"
29#include "transport-testing.h" 29#include "transport-testing2.h"
30#include "transport-testing-cmds.h"
30 31
32/**
33 * Struct to hold information for callbacks.
34 *
35 */
31struct SendSimpleState 36struct SendSimpleState
32{ 37{
38 /**
39 * The number of the local node of the actual network namespace.
40 *
41 */
33 char *m; 42 char *m;
34 43
44 /**
45 * The number of the actual namespace.
46 *
47 */
35 char *n; 48 char *n;
36 49
50 /**
51 * Number globally identifying the node.
52 *
53 */
37 uint32_t num; 54 uint32_t num;
38 55
39 const char *peer1_label; 56 /**
40 57 * Label of the cmd to start a peer.
41 const char *peer2_label; 58 *
59 */
60 const char *start_peer_label;
42}; 61};
43 62
63
64/**
65 * Trait function of this cmd does nothing.
66 *
67 */
44static int 68static int
45send_simple_traits (void *cls, 69send_simple_traits (void *cls,
46 const void **ret, 70 const void **ret,
@@ -51,6 +75,10 @@ send_simple_traits (void *cls,
51} 75}
52 76
53 77
78/**
79 * The cleanup function of this cmd frees resources the cmd allocated.
80 *
81 */
54static void 82static void
55send_simple_cleanup (void *cls, 83send_simple_cleanup (void *cls,
56 const struct GNUNET_TESTING_Command *cmd) 84 const struct GNUNET_TESTING_Command *cmd)
@@ -61,6 +89,10 @@ send_simple_cleanup (void *cls,
61} 89}
62 90
63 91
92/**
93 * The run method of this cmd will send a simple message to the connected peer.
94 *
95 */
64static void 96static void
65send_simple_run (void *cls, 97send_simple_run (void *cls,
66 const struct GNUNET_TESTING_Command *cmd, 98 const struct GNUNET_TESTING_Command *cmd,
@@ -70,21 +102,24 @@ send_simple_run (void *cls,
70 struct GNUNET_MQ_Envelope *env; 102 struct GNUNET_MQ_Envelope *env;
71 struct GNUNET_TRANSPORT_TESTING_TestMessage *test; 103 struct GNUNET_TRANSPORT_TESTING_TestMessage *test;
72 struct GNUNET_MQ_Handle *mq; 104 struct GNUNET_MQ_Handle *mq;
73 struct GNUNET_CONTAINER_MultiPeerMap *connected_peers_map; 105 struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map;
74 struct GNUNET_PeerIdentity *id;
75 const struct GNUNET_TESTING_Command *peer1_cmd; 106 const struct GNUNET_TESTING_Command *peer1_cmd;
76 const struct GNUNET_TESTING_Command *peer2_cmd; 107 struct GNUNET_ShortHashCode *key = GNUNET_new (struct GNUNET_ShortHashCode);
108 struct GNUNET_HashCode hc;
109 int node_number;
77 110
78 peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (sss->peer1_label); 111 peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (sss->start_peer_label);
79 GNUNET_TRANSPORT_get_trait_connected_peers_map (peer1_cmd, 112 GNUNET_TRANSPORT_get_trait_connected_peers_map (peer1_cmd,
80 &connected_peers_map); 113 &connected_peers_map);
81 114
82 peer2_cmd = GNUNET_TESTING_interpreter_lookup_command (sss->peer2_label); 115 node_number = 1;
83 GNUNET_TRANSPORT_get_trait_peer_id (peer2_cmd, 116 GNUNET_CRYPTO_hash (&node_number, sizeof(node_number), &hc);
84 &id); 117 memcpy (key,
118 &hc,
119 sizeof (*key));
85 120
86 mq = GNUNET_CONTAINER_multipeermap_get (connected_peers_map, 121 mq = GNUNET_CONTAINER_multishortmap_get (connected_peers_map,
87 id); 122 key);
88 123
89 env = GNUNET_MQ_msg_extra (test, 124 env = GNUNET_MQ_msg_extra (test,
90 2600 - sizeof(*test), 125 2600 - sizeof(*test),
@@ -93,12 +128,9 @@ send_simple_run (void *cls,
93 memset (&test[1], 128 memset (&test[1],
94 sss->num, 129 sss->num,
95 2600 - sizeof(*test)); 130 2600 - sizeof(*test));
96 /*GNUNET_MQ_notify_sent (env,
97 cont,
98 cont_cls);*/
99 GNUNET_MQ_send (mq, 131 GNUNET_MQ_send (mq,
100 env); 132 env);
101 133 GNUNET_free (key);
102 134
103} 135}
104 136
@@ -107,15 +139,18 @@ send_simple_run (void *cls,
107 * Create command. 139 * Create command.
108 * 140 *
109 * @param label name for command. 141 * @param label name for command.
142 * @param m The number of the local node of the actual network namespace.
143 * @param n The number of the actual namespace.
144 * @param num Number globally identifying the node.
145 * @param start_peer_label Label of the cmd to start a peer.
110 * @return command. 146 * @return command.
111 */ 147 */
112struct GNUNET_TESTING_Command 148struct GNUNET_TESTING_Command
113GNUNET_TESTING_cmd_send_simple (const char *label, 149GNUNET_TRANSPORT_cmd_send_simple (const char *label,
114 char *m, 150 char *m,
115 char *n, 151 char *n,
116 uint32_t num, 152 uint32_t num,
117 const char *peer1_label, 153 const char *start_peer_label)
118 const char *peer2_label)
119{ 154{
120 struct SendSimpleState *sss; 155 struct SendSimpleState *sss;
121 156
@@ -123,6 +158,7 @@ GNUNET_TESTING_cmd_send_simple (const char *label,
123 sss->m = m; 158 sss->m = m;
124 sss->n = n; 159 sss->n = n;
125 sss->num = num; 160 sss->num = num;
161 sss->start_peer_label = start_peer_label;
126 162
127 struct GNUNET_TESTING_Command cmd = { 163 struct GNUNET_TESTING_Command cmd = {
128 .cls = sss, 164 .cls = sss,
diff --git a/src/transport/transport_api_cmd_start_peer.c b/src/transport/transport_api_cmd_start_peer.c
index c9af497ae..729d981c0 100644
--- a/src/transport/transport_api_cmd_start_peer.c
+++ b/src/transport/transport_api_cmd_start_peer.c
@@ -29,91 +29,22 @@
29#include "gnunet_peerstore_service.h" 29#include "gnunet_peerstore_service.h"
30#include "gnunet_transport_core_service.h" 30#include "gnunet_transport_core_service.h"
31#include "gnunet_transport_application_service.h" 31#include "gnunet_transport_application_service.h"
32#include "transport-testing-ng.h"
32 33
33/** 34/**
34 * Generic logging shortcut 35 * Generic logging shortcut
35 */ 36 */
36#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) 37#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
37 38
38struct StartPeerState
39{
40 /**
41 * Receive callback
42 */
43 struct GNUNET_MQ_MessageHandler *handlers;
44
45 const char *cfgname;
46
47 /**
48 * Peer's configuration
49 */
50 struct GNUNET_CONFIGURATION_Handle *cfg;
51
52 struct GNUNET_TESTING_Peer *peer;
53
54 /**
55 * Peer identity
56 */
57 struct GNUNET_PeerIdentity *id;
58
59 /**
60 * Peer's transport service handle
61 */
62 struct GNUNET_TRANSPORT_CoreHandle *th;
63
64 /**
65 * Application handle
66 */
67 struct GNUNET_TRANSPORT_ApplicationHandle *ah;
68
69 /**
70 * Peer's PEERSTORE Handle
71 */
72 struct GNUNET_PEERSTORE_Handle *ph;
73
74 /**
75 * Hello get task
76 */
77 struct GNUNET_SCHEDULER_Task *rh_task;
78
79 /**
80 * Peer's transport get hello handle to retrieve peer's HELLO message
81 */
82 struct GNUNET_PEERSTORE_IterateContext *pic;
83
84 /**
85 * Hello
86 */
87 char *hello;
88
89 /**
90 * Hello size
91 */
92 size_t hello_size;
93
94 char *m;
95
96 char *n;
97
98 unsigned int finished;
99
100 const char *system_label;
101
102 /**
103 * An unique number to identify the peer
104 */
105 unsigned int no;
106
107 struct GNUNET_CONTAINER_MultiPeerMap *connected_peers_map;
108
109 struct GNUNET_TESTING_System *tl_system;
110
111};
112
113 39
114static void 40static void
115retrieve_hello (void *cls); 41retrieve_hello (void *cls);
116 42
43
44/**
45 * Callback delivering the hello of this peer from peerstore.
46 *
47 */
117static void 48static void
118hello_iter_cb (void *cb_cls, 49hello_iter_cb (void *cb_cls,
119 const struct GNUNET_PEERSTORE_Record *record, 50 const struct GNUNET_PEERSTORE_Record *record,
@@ -138,6 +69,11 @@ hello_iter_cb (void *cb_cls,
138} 69}
139 70
140 71
72/**
73 * Function to start the retrieval task to retrieve the hello of this peer
74 * from the peerstore.
75 *
76 */
141static void 77static void
142retrieve_hello (void *cls) 78retrieve_hello (void *cls)
143{ 79{
@@ -145,13 +81,18 @@ retrieve_hello (void *cls)
145 sps->rh_task = NULL; 81 sps->rh_task = NULL;
146 sps->pic = GNUNET_PEERSTORE_iterate (sps->ph, 82 sps->pic = GNUNET_PEERSTORE_iterate (sps->ph,
147 "transport", 83 "transport",
148 sps->id, 84 &sps->id,
149 GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY, 85 GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY,
150 hello_iter_cb, 86 hello_iter_cb,
151 sps); 87 sps);
152 88
153} 89}
154 90
91
92/**
93 * This function checks StartPeerState#finished, which is set when the hello was retrieved.
94 *
95 */
155static int 96static int
156start_peer_finish (void *cls, 97start_peer_finish (void *cls,
157 GNUNET_SCHEDULER_TaskCallback cont, 98 GNUNET_SCHEDULER_TaskCallback cont,
@@ -168,6 +109,10 @@ start_peer_finish (void *cls,
168} 109}
169 110
170 111
112/**
113 * Disconnect callback for the connection to the core service.
114 *
115 */
171static void 116static void
172notify_disconnect (void *cls, 117notify_disconnect (void *cls,
173 const struct GNUNET_PeerIdentity *peer, 118 const struct GNUNET_PeerIdentity *peer,
@@ -179,38 +124,57 @@ notify_disconnect (void *cls,
179 "Peer %s disconnected from peer %u (`%s')\n", 124 "Peer %s disconnected from peer %u (`%s')\n",
180 GNUNET_i2s (peer), 125 GNUNET_i2s (peer),
181 sps->no, 126 sps->no,
182 GNUNET_i2s (sps->id)); 127 GNUNET_i2s (&sps->id));
183 128
184} 129}
185 130
186 131
132/**
133 * Connect callback for the connection to the core service.
134 *
135 */
187static void * 136static void *
188notify_connect (void *cls, 137notify_connect (void *cls,
189 const struct GNUNET_PeerIdentity *peer, 138 const struct GNUNET_PeerIdentity *peer,
190 struct GNUNET_MQ_Handle *mq) 139 struct GNUNET_MQ_Handle *mq)
191{ 140{
192 struct StartPeerState *sps = cls; 141 struct StartPeerState *sps = cls;
142 struct GNUNET_ShortHashCode *key = GNUNET_new (struct GNUNET_ShortHashCode);
143 struct GNUNET_HashCode hc;
144 int node_number;
193 145
194 146 void *ret = NULL;
195 void *ret;
196 147
197 148
198 LOG (GNUNET_ERROR_TYPE_DEBUG, 149 LOG (GNUNET_ERROR_TYPE_DEBUG,
199 "Peer %s connected to peer %u (`%s')\n", 150 "Peer %s connected to peer %u (`%s')\n",
200 GNUNET_i2s (peer), 151 GNUNET_i2s (peer),
201 sps->no, 152 sps->no,
202 GNUNET_i2s (sps->id)); 153 GNUNET_i2s (&sps->id));
154
155 // TODO we need to store with a key identifying the netns node in the future. For now we have only one connecting node.
156 node_number = 1;
157 GNUNET_CRYPTO_hash (&node_number, sizeof(node_number), &hc);
158
203 159
204 GNUNET_CONTAINER_multipeermap_put (sps->connected_peers_map, 160 memcpy (key,
205 peer, 161 &hc,
206 mq, 162 sizeof (*key));
207 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 163 GNUNET_CONTAINER_multishortmap_put (sps->connected_peers_map,
164 key,
165 mq,
166 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
208 167
168 GNUNET_free (key);
209 // TODO what does the handler function need? 169 // TODO what does the handler function need?
210 return ret; 170 return ret;
211} 171}
212 172
213 173
174/**
175 * The run method of this cmd will start all services of a peer to test the transport service.
176 *
177 */
214static void 178static void
215start_peer_run (void *cls, 179start_peer_run (void *cls,
216 const struct GNUNET_TESTING_Command *cmd, 180 const struct GNUNET_TESTING_Command *cmd,
@@ -251,6 +215,7 @@ start_peer_run (void *cls,
251 sps->cfgname); 215 sps->cfgname);
252 GNUNET_CONFIGURATION_destroy (sps->cfg); 216 GNUNET_CONFIGURATION_destroy (sps->cfg);
253 GNUNET_TESTING_interpreter_fail (); 217 GNUNET_TESTING_interpreter_fail ();
218 return;
254 } 219 }
255 220
256 sps->peer = GNUNET_TESTING_peer_configure (sps->tl_system, 221 sps->peer = GNUNET_TESTING_peer_configure (sps->tl_system,
@@ -266,6 +231,7 @@ start_peer_run (void *cls,
266 emsg); 231 emsg);
267 GNUNET_free (emsg); 232 GNUNET_free (emsg);
268 GNUNET_TESTING_interpreter_fail (); 233 GNUNET_TESTING_interpreter_fail ();
234 return;
269 } 235 }
270 236
271 if (GNUNET_OK != GNUNET_TESTING_peer_start (sps->peer)) 237 if (GNUNET_OK != GNUNET_TESTING_peer_start (sps->peer))
@@ -275,13 +241,16 @@ start_peer_run (void *cls,
275 sps->cfgname); 241 sps->cfgname);
276 GNUNET_free (emsg); 242 GNUNET_free (emsg);
277 GNUNET_TESTING_interpreter_fail (); 243 GNUNET_TESTING_interpreter_fail ();
244 return;
278 } 245 }
279 246
280 memset (&dummy, 247 memset (&dummy,
281 '\0', 248 '\0',
282 sizeof(dummy)); 249 sizeof(dummy));
250
283 GNUNET_TESTING_peer_get_identity (sps->peer, 251 GNUNET_TESTING_peer_get_identity (sps->peer,
284 sps->id); 252 &sps->id);
253
285 if (0 == memcmp (&dummy, 254 if (0 == memcmp (&dummy,
286 &sps->id, 255 &sps->id,
287 sizeof(struct GNUNET_PeerIdentity))) 256 sizeof(struct GNUNET_PeerIdentity)))
@@ -291,11 +260,13 @@ start_peer_run (void *cls,
291 sps->no); 260 sps->no);
292 GNUNET_free (emsg); 261 GNUNET_free (emsg);
293 GNUNET_TESTING_interpreter_fail (); 262 GNUNET_TESTING_interpreter_fail ();
263 return;
294 } 264 }
295 LOG (GNUNET_ERROR_TYPE_DEBUG, 265 LOG (GNUNET_ERROR_TYPE_DEBUG,
296 "Peer %u configured with identity `%s'\n", 266 "Peer %u configured with identity `%s'\n",
297 sps->no, 267 sps->no,
298 GNUNET_i2s_full (sps->id)); 268 GNUNET_i2s_full (&sps->id));
269
299 sps->th = GNUNET_TRANSPORT_core_connect (sps->cfg, 270 sps->th = GNUNET_TRANSPORT_core_connect (sps->cfg,
300 NULL, 271 NULL,
301 sps->handlers, 272 sps->handlers,
@@ -310,7 +281,9 @@ start_peer_run (void *cls,
310 emsg); 281 emsg);
311 GNUNET_free (emsg); 282 GNUNET_free (emsg);
312 GNUNET_TESTING_interpreter_fail (); 283 GNUNET_TESTING_interpreter_fail ();
284 return;
313 } 285 }
286
314 sps->ph = GNUNET_PEERSTORE_connect (sps->cfg); 287 sps->ph = GNUNET_PEERSTORE_connect (sps->cfg);
315 if (NULL == sps->th) 288 if (NULL == sps->th)
316 { 289 {
@@ -320,7 +293,9 @@ start_peer_run (void *cls,
320 emsg); 293 emsg);
321 GNUNET_free (emsg); 294 GNUNET_free (emsg);
322 GNUNET_TESTING_interpreter_fail (); 295 GNUNET_TESTING_interpreter_fail ();
296 return;
323 } 297 }
298
324 sps->ah = GNUNET_TRANSPORT_application_init (sps->cfg); 299 sps->ah = GNUNET_TRANSPORT_application_init (sps->cfg);
325 if (NULL == sps->ah) 300 if (NULL == sps->ah)
326 { 301 {
@@ -330,32 +305,22 @@ start_peer_run (void *cls,
330 emsg); 305 emsg);
331 GNUNET_free (emsg); 306 GNUNET_free (emsg);
332 GNUNET_TESTING_interpreter_fail (); 307 GNUNET_TESTING_interpreter_fail ();
308 return;
333 } 309 }
334 sps->rh_task = GNUNET_SCHEDULER_add_now (retrieve_hello, sps); 310 sps->rh_task = GNUNET_SCHEDULER_add_now (retrieve_hello, sps);
335} 311}
336 312
337 313
314/**
315 * The cleanup function of this cmd frees resources the cmd allocated.
316 *
317 */
338static void 318static void
339start_peer_cleanup (void *cls, 319start_peer_cleanup (void *cls,
340 const struct GNUNET_TESTING_Command *cmd) 320 const struct GNUNET_TESTING_Command *cmd)
341{ 321{
342 struct StartPeerState *sps = cls; 322 struct StartPeerState *sps = cls;
343 323
344 if (NULL != sps->rh_task)
345 GNUNET_SCHEDULER_cancel (sps->rh_task);
346 sps->rh_task = NULL;
347 if (NULL != sps->ah)
348 {
349 GNUNET_TRANSPORT_application_done (sps->ah);
350 sps->ah = NULL;
351 }
352 if (NULL != sps->ph)
353 {
354 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
355 "Disconnecting from PEERSTORE service\n");
356 GNUNET_PEERSTORE_disconnect (sps->ph, GNUNET_NO);
357 sps->ph = NULL;
358 }
359 if (NULL != sps->handlers) 324 if (NULL != sps->handlers)
360 { 325 {
361 GNUNET_free (sps->handlers); 326 GNUNET_free (sps->handlers);
@@ -366,34 +331,16 @@ start_peer_cleanup (void *cls,
366 GNUNET_CONFIGURATION_destroy (sps->cfg); 331 GNUNET_CONFIGURATION_destroy (sps->cfg);
367 sps->cfg = NULL; 332 sps->cfg = NULL;
368 } 333 }
369 if (NULL != sps->peer)
370 {
371 if (GNUNET_OK !=
372 GNUNET_TESTING_peer_stop (sps->peer))
373 {
374 LOG (GNUNET_ERROR_TYPE_DEBUG,
375 "Testing lib failed to stop peer %u (`%s')\n",
376 sps->no,
377 GNUNET_i2s (sps->id));
378 }
379 GNUNET_TESTING_peer_destroy (sps->peer);
380 sps->peer = NULL;
381 }
382 if (NULL != sps->th)
383 {
384 GNUNET_TRANSPORT_core_disconnect (sps->th);
385 sps->th = NULL;
386 }
387 if (NULL != sps->tl_system)
388 {
389 GNUNET_free (sps->tl_system);
390 }
391 GNUNET_free (sps->hello); 334 GNUNET_free (sps->hello);
392 GNUNET_free (sps->connected_peers_map); 335 GNUNET_free (sps->connected_peers_map);
393 GNUNET_free (sps); 336 GNUNET_free (sps);
394} 337}
395 338
396 339
340/**
341 * This function prepares an array with traits.
342 *
343 */
397static int 344static int
398start_peer_traits (void *cls, 345start_peer_traits (void *cls,
399 const void **ret, 346 const void **ret,
@@ -402,8 +349,8 @@ start_peer_traits (void *cls,
402{ 349{
403 struct StartPeerState *sps = cls; 350 struct StartPeerState *sps = cls;
404 struct GNUNET_TRANSPORT_ApplicationHandle *ah = sps->ah; 351 struct GNUNET_TRANSPORT_ApplicationHandle *ah = sps->ah;
405 struct GNUNET_PeerIdentity *id = sps->id; 352 struct GNUNET_PeerIdentity *id = &sps->id;
406 struct GNUNET_CONTAINER_MultiPeerMap *connected_peers_map = 353 struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map =
407 sps->connected_peers_map; 354 sps->connected_peers_map;
408 char *hello = sps->hello; 355 char *hello = sps->hello;
409 size_t hello_size = sps->hello_size; 356 size_t hello_size = sps->hello_size;
@@ -435,6 +382,11 @@ start_peer_traits (void *cls,
435 .trait_name = "hello_size", 382 .trait_name = "hello_size",
436 .ptr = (const void *) hello_size, 383 .ptr = (const void *) hello_size,
437 }, 384 },
385 {
386 .index = 5,
387 .trait_name = "state",
388 .ptr = (const void *) sps,
389 },
438 GNUNET_TESTING_trait_end () 390 GNUNET_TESTING_trait_end ()
439 }; 391 };
440 392
@@ -444,6 +396,34 @@ start_peer_traits (void *cls,
444 index); 396 index);
445} 397}
446 398
399
400/**
401 * Function to get the trait with the struct StartPeerState.
402 *
403 * @param[out] sps struct StartPeerState.
404 * @return #GNUNET_OK if no error occurred, #GNUNET_SYSERR otherwise.
405 *
406 */
407int
408GNUNET_TRANSPORT_get_trait_state (const struct
409 GNUNET_TESTING_Command
410 *cmd,
411 struct StartPeerState **sps)
412{
413 return cmd->traits (cmd->cls,
414 (const void **) sps,
415 "state",
416 (unsigned int) 5);
417}
418
419
420/**
421 * Function to get the trait with the size of the hello.
422 *
423 * @param[out] hello_size size of hello.
424 * @return #GNUNET_OK if no error occurred, #GNUNET_SYSERR otherwise.
425 *
426 */
447int 427int
448GNUNET_TRANSPORT_get_trait_hello_size (const struct 428GNUNET_TRANSPORT_get_trait_hello_size (const struct
449 GNUNET_TESTING_Command 429 GNUNET_TESTING_Command
@@ -456,6 +436,14 @@ GNUNET_TRANSPORT_get_trait_hello_size (const struct
456 (unsigned int) 4); 436 (unsigned int) 4);
457} 437}
458 438
439
440/**
441 * Function to get the trait with the hello.
442 *
443 * @param[out] hello The hello for the peer.
444 * @return #GNUNET_OK if no error occurred, #GNUNET_SYSERR otherwise.
445 *
446 */
459int 447int
460GNUNET_TRANSPORT_get_trait_hello (const struct 448GNUNET_TRANSPORT_get_trait_hello (const struct
461 GNUNET_TESTING_Command 449 GNUNET_TESTING_Command
@@ -468,12 +456,21 @@ GNUNET_TRANSPORT_get_trait_hello (const struct
468 (unsigned int) 3); 456 (unsigned int) 3);
469} 457}
470 458
459
460/**
461 * Function to get the trait with the map of connected peers.
462 *
463 * @param[out] connected_peers_map The map with connected peers.
464 * @return #GNUNET_OK if no error occurred, #GNUNET_SYSERR otherwise.
465 *
466 */
471int 467int
472GNUNET_TRANSPORT_get_trait_connected_peers_map (const struct 468GNUNET_TRANSPORT_get_trait_connected_peers_map (const struct
473 GNUNET_TESTING_Command 469 GNUNET_TESTING_Command
474 *cmd, 470 *cmd,
475 struct 471 struct
476 GNUNET_CONTAINER_MultiPeerMap ** 472 GNUNET_CONTAINER_MultiShortmap *
473 *
477 connected_peers_map) 474 connected_peers_map)
478{ 475{
479 return cmd->traits (cmd->cls, 476 return cmd->traits (cmd->cls,
@@ -483,6 +480,12 @@ GNUNET_TRANSPORT_get_trait_connected_peers_map (const struct
483} 480}
484 481
485 482
483/**
484 * Function to get the trait with the transport application handle.
485 *
486 * @param[out] ah The application handle.
487 * @return #GNUNET_OK if no error occurred, #GNUNET_SYSERR otherwise.
488 */
486int 489int
487GNUNET_TRANSPORT_get_trait_application_handle (const struct 490GNUNET_TRANSPORT_get_trait_application_handle (const struct
488 GNUNET_TESTING_Command *cmd, 491 GNUNET_TESTING_Command *cmd,
@@ -497,6 +500,12 @@ GNUNET_TRANSPORT_get_trait_application_handle (const struct
497} 500}
498 501
499 502
503/**
504 * Function to get the trait with the peer id.
505 *
506 * @param[out] id The peer id.
507 * @return #GNUNET_OK if no error occurred, #GNUNET_SYSERR otherwise.
508 */
500int 509int
501GNUNET_TRANSPORT_get_trait_peer_id (const struct 510GNUNET_TRANSPORT_get_trait_peer_id (const struct
502 GNUNET_TESTING_Command *cmd, 511 GNUNET_TESTING_Command *cmd,
@@ -513,6 +522,12 @@ GNUNET_TRANSPORT_get_trait_peer_id (const struct
513 * Create command. 522 * Create command.
514 * 523 *
515 * @param label name for command. 524 * @param label name for command.
525 * @param system_label Label of the cmd to setup a test environment.
526 * @param m The number of the local node of the actual network namespace.
527 * @param n The number of the actual namespace.
528 * @param local_m Number of local nodes in each namespace.
529 * @param handlers Handler for messages received by this peer.
530 * @param cfgname Configuration file name for this peer.
516 * @return command. 531 * @return command.
517 */ 532 */
518struct GNUNET_TESTING_Command 533struct GNUNET_TESTING_Command
@@ -520,17 +535,20 @@ GNUNET_TRANSPORT_cmd_start_peer (const char *label,
520 const char *system_label, 535 const char *system_label,
521 char *m, 536 char *m,
522 char *n, 537 char *n,
538 char *local_m,
523 struct GNUNET_MQ_MessageHandler *handlers, 539 struct GNUNET_MQ_MessageHandler *handlers,
524 const char *cfgname) 540 const char *cfgname)
525{ 541{
526 struct StartPeerState *sps; 542 struct StartPeerState *sps;
527 struct GNUNET_CONTAINER_MultiPeerMap *connected_peers_map = 543 struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map =
528 GNUNET_CONTAINER_multipeermap_create (1,GNUNET_NO); 544 GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
529 unsigned int i; 545 unsigned int i;
530 546
531 sps = GNUNET_new (struct StartPeerState); 547 sps = GNUNET_new (struct StartPeerState);
532 sps->m = m; 548 sps->m = m;
533 sps->n = n; 549 sps->n = n;
550 sps->local_m = local_m;
551 sps->no = (atoi (n) - 1) * atoi (sps->local_m) + atoi (m);
534 sps->system_label = system_label; 552 sps->system_label = system_label;
535 sps->connected_peers_map = connected_peers_map; 553 sps->connected_peers_map = connected_peers_map;
536 sps->cfgname = cfgname; 554 sps->cfgname = cfgname;
diff --git a/src/transport/transport_api_cmd_stop_peer.c b/src/transport/transport_api_cmd_stop_peer.c
new file mode 100644
index 000000000..7a0050a63
--- /dev/null
+++ b/src/transport/transport_api_cmd_stop_peer.c
@@ -0,0 +1,163 @@
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_stop_peer.c
23 * @brief cmd to stop a peer.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29#include "gnunet_peerstore_service.h"
30#include "gnunet_transport_core_service.h"
31#include "gnunet_transport_application_service.h"
32#include "transport-testing-ng.h"
33
34/**
35 * Generic logging shortcut
36 */
37#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
38
39
40/**
41 * Struct to hold information for callbacks.
42 *
43 */
44struct StopPeerState
45{
46 // Label of the cmd to start the peer.
47 const char *start_label;
48};
49
50
51/**
52 * The run method of this cmd will stop all services of a peer which were used to test the transport service.
53 *
54 */
55static void
56stop_peer_run (void *cls,
57 const struct GNUNET_TESTING_Command *cmd,
58 struct GNUNET_TESTING_Interpreter *is)
59{
60 struct StopPeerState *stop_ps = cls;
61 struct StartPeerState *sps;
62 const struct GNUNET_TESTING_Command *start_cmd;
63
64 start_cmd = GNUNET_TESTING_interpreter_lookup_command (stop_ps->start_label);
65 GNUNET_TRANSPORT_get_trait_state (start_cmd,
66 &sps);
67
68 if (NULL != sps->pic)
69 {
70 GNUNET_PEERSTORE_iterate_cancel (sps->pic);
71 sps->pic = NULL;
72 }
73 if (NULL != sps->th)
74 {
75 GNUNET_TRANSPORT_core_disconnect (sps->th);
76 sps->th = NULL;
77 }
78 if (NULL != sps->ah)
79 {
80 GNUNET_TRANSPORT_application_done (sps->ah);
81 sps->ah = NULL;
82 }
83 if (NULL != sps->ph)
84 {
85 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
86 "Disconnecting from PEERSTORE service\n");
87 GNUNET_PEERSTORE_disconnect (sps->ph, GNUNET_NO);
88 sps->ph = NULL;
89 }
90 if (NULL != sps->peer)
91 {
92 if (GNUNET_OK !=
93 GNUNET_TESTING_peer_stop (sps->peer))
94 {
95 LOG (GNUNET_ERROR_TYPE_ERROR,
96 "Testing lib failed to stop peer %u (`%s')\n",
97 sps->no,
98 GNUNET_i2s (&sps->id));
99 }
100 GNUNET_TESTING_peer_destroy (sps->peer);
101 sps->peer = NULL;
102 }
103 if (NULL != sps->rh_task)
104 GNUNET_SCHEDULER_cancel (sps->rh_task);
105 sps->rh_task = NULL;
106
107}
108
109
110/**
111 * The cleanup function of this cmd frees resources the cmd allocated.
112 *
113 */
114static void
115stop_peer_cleanup (void *cls,
116 const struct GNUNET_TESTING_Command *cmd)
117{
118 struct StopPeerState *sps = cls;
119
120 GNUNET_free (sps);
121}
122
123
124/**
125 * Trait function of this cmd does nothing.
126 *
127 */
128static int
129stop_peer_traits (void *cls,
130 const void **ret,
131 const char *trait,
132 unsigned int index)
133{
134 return GNUNET_OK;
135}
136
137
138/**
139 * Create command.
140 *
141 * @param label name for command.
142 * @param start_label Label of the cmd to start the peer.
143 * @return command.
144 */
145struct GNUNET_TESTING_Command
146GNUNET_TRANSPORT_cmd_stop_peer (const char *label,
147 const char *start_label)
148{
149 struct StopPeerState *sps;
150
151 sps = GNUNET_new (struct StopPeerState);
152 sps->start_label = start_label;
153
154 struct GNUNET_TESTING_Command cmd = {
155 .cls = sps,
156 .label = label,
157 .run = &stop_peer_run,
158 .cleanup = &stop_peer_cleanup,
159 .traits = &stop_peer_traits
160 };
161
162 return cmd;
163}
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index e720112be..a3a77073e 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -49,7 +49,7 @@ libgnunetutil_la_SOURCES = \
49 common_endian.c \ 49 common_endian.c \
50 common_logging.c \ 50 common_logging.c \
51 configuration.c \ 51 configuration.c \
52 configuration_loader.c \ 52 configuration_helper.c \
53 consttime_memcmp.c \ 53 consttime_memcmp.c \
54 container_bloomfilter.c \ 54 container_bloomfilter.c \
55 container_heap.c \ 55 container_heap.c \
@@ -243,11 +243,11 @@ gnunet_qr_LDADD = \
243gnunet_qr_LDFLAGS= -lzbar 243gnunet_qr_LDFLAGS= -lzbar
244 244
245plugin_LTLIBRARIES = \ 245plugin_LTLIBRARIES = \
246 libgnunet_plugin_test.la 246 libgnunet_plugin_utiltest.la
247 247
248libgnunet_plugin_test_la_SOURCES = \ 248libgnunet_plugin_utiltest_la_SOURCES = \
249 test_plugin_plug.c 249 test_plugin_plug.c
250libgnunet_plugin_test_la_LDFLAGS = \ 250libgnunet_plugin_utiltest_la_LDFLAGS = \
251 $(GN_PLUGIN_LDFLAGS) 251 $(GN_PLUGIN_LDFLAGS)
252 252
253if HAVE_BENCHMARKS 253if HAVE_BENCHMARKS
@@ -362,8 +362,6 @@ test_os_start_process_SOURCES = \
362 test_os_start_process.c 362 test_os_start_process.c
363test_os_start_process_LDADD = \ 363test_os_start_process_LDADD = \
364 libgnunetutil.la 364 libgnunetutil.la
365test_os_start_process_DEPENDENCIES = \
366 libgnunetutil.la
367 365
368test_client_nc_SOURCES = \ 366test_client_nc_SOURCES = \
369 test_client.c 367 test_client.c
diff --git a/src/util/client.c b/src/util/client.c
index afd2fe900..4e5eca32a 100644
--- a/src/util/client.c
+++ b/src/util/client.c
@@ -745,6 +745,7 @@ test_service_configuration (const char *service_name,
745 service_name, 745 service_name,
746 "UNIXPATH", 746 "UNIXPATH",
747 _ ("not a valid filename")); 747 _ ("not a valid filename"));
748 GNUNET_free (unixpath);
748 return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */ 749 return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */
749 } 750 }
750 GNUNET_free (unixpath); 751 GNUNET_free (unixpath);
diff --git a/src/util/common_logging.c b/src/util/common_logging.c
index 48cc6fe3b..cba37cd2f 100644
--- a/src/util/common_logging.c
+++ b/src/util/common_logging.c
@@ -1014,8 +1014,10 @@ mylog (enum GNUNET_ErrorType kind,
1014 } 1014 }
1015 else 1015 else
1016 { 1016 {
1017 if (0 == strftime (date2, DATE_STR_SIZE, "%b %d %H:%M:%S-%%06u", tmptr)) 1017 /* RFC 3339 timestamp, with snprintf placeholder for microseconds */
1018 if (0 == strftime (date2, DATE_STR_SIZE, "%Y-%m-%dT%H:%M:%S.%%06u%z", tmptr))
1018 abort (); 1019 abort ();
1020 /* Fill in microseconds */
1019 if (0 > snprintf (date, sizeof(date), date2, timeofday.tv_usec)) 1021 if (0 > snprintf (date, sizeof(date), date2, timeofday.tv_usec))
1020 abort (); 1022 abort ();
1021 } 1023 }
diff --git a/src/util/configuration.c b/src/util/configuration.c
index d0090ae53..09a3a7d93 100644
--- a/src/util/configuration.c
+++ b/src/util/configuration.c
@@ -28,6 +28,8 @@
28#include "gnunet_os_lib.h" 28#include "gnunet_os_lib.h"
29#include "gnunet_configuration_lib.h" 29#include "gnunet_configuration_lib.h"
30#include "gnunet_disk_lib.h" 30#include "gnunet_disk_lib.h"
31#include "gnunet_buffer_lib.h"
32#include "gnunet_container_lib.h"
31 33
32#define LOG(kind, ...) GNUNET_log_from (kind, "util", __VA_ARGS__) 34#define LOG(kind, ...) GNUNET_log_from (kind, "util", __VA_ARGS__)
33 35
@@ -53,6 +55,16 @@ struct ConfigEntry
53 * current, committed value 55 * current, committed value
54 */ 56 */
55 char *val; 57 char *val;
58
59 /**
60 * Diagnostics information for the filename.
61 */
62 char *hint_filename;
63
64 /**
65 * Diagnostics information for the line number.
66 */
67 unsigned int hint_lineno;
56}; 68};
57 69
58 70
@@ -75,6 +87,62 @@ struct ConfigSection
75 * name of the section 87 * name of the section
76 */ 88 */
77 char *name; 89 char *name;
90
91 /**
92 * Is the configuration section marked as inaccessible?
93 *
94 * This can happen if the section name is used in an @inline-secret@
95 * directive, but the referenced file can't be found or accessed.
96 */
97 bool inaccessible;
98
99 /**
100 * Diagnostics hint for the secret file.
101 */
102 char *hint_secret_filename;
103
104 /**
105 * Extra information regarding permissions of the secret file.
106 */
107 char *hint_secret_stat;
108
109 /**
110 * For secret sections: Where was this inlined from?
111 */
112 char *hint_inlined_from_filename;
113
114 /**
115 * For secret sections: Where was this inlined from?
116 */
117 unsigned int hint_inlined_from_line;
118};
119
120struct ConfigFile
121{
122 /**
123 * Source filename.
124 */
125 char *source_filename;
126
127 /**
128 * Level in the tree of loaded config files.
129 */
130 unsigned int level;
131
132 struct ConfigFile *prev;
133
134 struct ConfigFile *next;
135
136 /**
137 * Was this configuration file parsed via
138 * @inline-secret@?
139 */
140 char *hint_restrict_section;
141
142 /**
143 * Was this configuration file inaccessible?
144 */
145 bool hint_inaccessible;
78}; 146};
79 147
80 148
@@ -89,11 +157,48 @@ struct GNUNET_CONFIGURATION_Handle
89 struct ConfigSection *sections; 157 struct ConfigSection *sections;
90 158
91 /** 159 /**
160 * Linked list of loaded files.
161 */
162 struct ConfigFile *loaded_files_head;
163
164 /**
165 * Linked list of loaded files.
166 */
167 struct ConfigFile *loaded_files_tail;
168
169 /**
170 * Current nesting level of file loading.
171 */
172 unsigned int current_nest_level;
173
174 /**
175 * Enable diagnostics.
176 */
177 bool diagnostics;
178
179 /**
92 * Modification indication since last save 180 * Modification indication since last save
93 * #GNUNET_NO if clean, #GNUNET_YES if dirty, 181 * #GNUNET_NO if clean, #GNUNET_YES if dirty,
94 * #GNUNET_SYSERR on error (i.e. last save failed) 182 * #GNUNET_SYSERR on error (i.e. last save failed)
95 */ 183 */
96 enum GNUNET_GenericReturnValue dirty; 184 enum GNUNET_GenericReturnValue dirty;
185
186 /**
187 * Was the configuration ever loaded via GNUNET_CONFIGURATION_load?
188 */
189 bool load_called;
190
191 /**
192 * Name of the entry point configuration file.
193 */
194 char *main_filename;
195
196 /**
197 * When parsing into this configuration, and this value
198 * is non-NULL, only parse sections of the same name,
199 * and ban import statements.
200 */
201 const char *restrict_section;
97}; 202};
98 203
99 204
@@ -109,6 +214,14 @@ struct DiffHandle
109}; 214};
110 215
111 216
217void
218GNUNET_CONFIGURATION_enable_diagnostics (struct
219 GNUNET_CONFIGURATION_Handle *cfg)
220{
221 cfg->diagnostics = true;
222}
223
224
112struct GNUNET_CONFIGURATION_Handle * 225struct GNUNET_CONFIGURATION_Handle *
113GNUNET_CONFIGURATION_create () 226GNUNET_CONFIGURATION_create ()
114{ 227{
@@ -198,9 +311,20 @@ void
198GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg) 311GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg)
199{ 312{
200 struct ConfigSection *sec; 313 struct ConfigSection *sec;
314 struct ConfigFile *cf;
201 315
202 while (NULL != (sec = cfg->sections)) 316 while (NULL != (sec = cfg->sections))
203 GNUNET_CONFIGURATION_remove_section (cfg, sec->name); 317 GNUNET_CONFIGURATION_remove_section (cfg, sec->name);
318 while (NULL != (cf = cfg->loaded_files_head))
319 {
320 GNUNET_free (cf->hint_restrict_section);
321 GNUNET_free (cf->source_filename);
322 GNUNET_CONTAINER_DLL_remove (cfg->loaded_files_head,
323 cfg->loaded_files_tail,
324 cf);
325 GNUNET_free (cf);
326 }
327 GNUNET_free (cfg->main_filename);
204 GNUNET_free (cfg); 328 GNUNET_free (cfg);
205} 329}
206 330
@@ -214,7 +338,9 @@ GNUNET_CONFIGURATION_parse_and_run (const char *filename,
214 enum GNUNET_GenericReturnValue ret; 338 enum GNUNET_GenericReturnValue ret;
215 339
216 cfg = GNUNET_CONFIGURATION_create (); 340 cfg = GNUNET_CONFIGURATION_create ();
217 if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, filename)) 341 if (GNUNET_OK !=
342 GNUNET_CONFIGURATION_load (cfg,
343 filename))
218 { 344 {
219 GNUNET_break (0); 345 GNUNET_break (0);
220 GNUNET_CONFIGURATION_destroy (cfg); 346 GNUNET_CONFIGURATION_destroy (cfg);
@@ -226,34 +352,381 @@ GNUNET_CONFIGURATION_parse_and_run (const char *filename,
226} 352}
227 353
228 354
355/**
356 * Closure to collect_files_cb.
357 */
358struct CollectFilesContext
359{
360 /**
361 * Collected files from globbing.
362 */
363 char **files;
364
365 /**
366 * Size of the files array.
367 */
368 unsigned int files_length;
369};
370
371
372/**
373 * Function called with a filename.
374 *
375 * @param cls closure
376 * @param filename complete filename (absolute path)
377 * @return #GNUNET_OK to continue to iterate,
378 * #GNUNET_NO to stop iteration with no error,
379 * #GNUNET_SYSERR to abort iteration with error!
380 */
381static int
382collect_files_cb (void *cls,
383 const char *filename)
384{
385 struct CollectFilesContext *igc = cls;
386
387 GNUNET_array_append (igc->files,
388 igc->files_length,
389 GNUNET_strdup (filename));
390 return GNUNET_OK;
391}
392
393
394/**
395 * Find a section entry from a configuration.
396 *
397 * @param cfg configuration to search in
398 * @param section name of the section to look for
399 * @return matching entry, NULL if not found
400 */
401static struct ConfigSection *
402find_section (const struct GNUNET_CONFIGURATION_Handle *cfg,
403 const char *section)
404{
405 struct ConfigSection *pos;
406
407 pos = cfg->sections;
408 while ((pos != NULL) && (0 != strcasecmp (section, pos->name)))
409 pos = pos->next;
410 return pos;
411}
412
413
414static int
415pstrcmp (const void *a, const void *b)
416{
417 return strcmp (*((const char **) a), *((const char **) b));
418}
419
420
421/**
422 * Handle an inline directive.
423 *
424 * @returns #GNUNET_SYSERR on error, #GNUNET_OK otherwise
425 */
426enum GNUNET_GenericReturnValue
427handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg,
428 const char *path_or_glob,
429 bool path_is_glob,
430 const char *restrict_section,
431 const char *source_filename,
432 unsigned int source_lineno)
433{
434 char *inline_path = NULL;
435 struct GNUNET_CONFIGURATION_Handle *other_cfg = NULL;
436 struct CollectFilesContext igc = {
437 .files = NULL,
438 .files_length = 0,
439 };
440 enum GNUNET_GenericReturnValue fun_ret;
441 unsigned int old_nest_level = cfg->current_nest_level++;
442
443 /* We support the section restriction only for non-globs */
444 GNUNET_assert (! (path_is_glob && (NULL != restrict_section)));
445
446 if (NULL == source_filename)
447 {
448 LOG (GNUNET_ERROR_TYPE_DEBUG,
449 "Refusing to parse inline configurations, "
450 "not allowed without source filename!\n");
451 fun_ret = GNUNET_SYSERR;
452 goto cleanup;
453 }
454
455 if ('/' == *path_or_glob)
456 inline_path = GNUNET_strdup (path_or_glob);
457 else
458 {
459 /* We compute the canonical, absolute path first,
460 so that relative imports resolve properly with symlinked
461 config files. */
462 char *source_realpath;
463 char *endsep;
464
465 source_realpath = realpath (source_filename,
466 NULL);
467 if (NULL == source_realpath)
468 {
469 /* Couldn't even resolve path of base dir. */
470 GNUNET_break (0);
471 /* failed to parse included config */
472 fun_ret = GNUNET_SYSERR;
473 goto cleanup;
474 }
475 endsep = strrchr (source_realpath, '/');
476 GNUNET_assert (NULL != endsep);
477 *endsep = '\0';
478 GNUNET_asprintf (&inline_path,
479 "%s/%s",
480 source_realpath,
481 path_or_glob);
482 free (source_realpath);
483 }
484
485 if (path_is_glob)
486 {
487 int nret;
488
489 LOG (GNUNET_ERROR_TYPE_DEBUG,
490 "processing config glob '%s'\n",
491 inline_path);
492
493 nret = GNUNET_DISK_glob (inline_path, collect_files_cb, &igc);
494 if (-1 == nret)
495 {
496 fun_ret = GNUNET_SYSERR;
497 goto cleanup;
498 }
499 GNUNET_assert (nret == igc.files_length);
500 qsort (igc.files, igc.files_length, sizeof (char *), pstrcmp);
501 for (int i = 0; i < nret; i++)
502 {
503 if (GNUNET_OK !=
504 GNUNET_CONFIGURATION_parse (cfg,
505 igc.files[i]))
506 {
507 fun_ret = GNUNET_SYSERR;
508 goto cleanup;
509 }
510 }
511 fun_ret = GNUNET_OK;
512 }
513 else if (NULL != restrict_section)
514 {
515 enum GNUNET_GenericReturnValue inner_ret;
516 struct ConfigSection *cs;
517 struct ConfigFile *cf = GNUNET_new (struct ConfigFile);
518
519 inner_ret = GNUNET_DISK_file_test_read (inline_path);
520
521 cs = find_section (cfg, restrict_section);
522
523 if (NULL == cs)
524 {
525 cs = GNUNET_new (struct ConfigSection);
526 cs->name = GNUNET_strdup (restrict_section);
527 cs->next = cfg->sections;
528 cfg->sections = cs;
529 cs->entries = NULL;
530 }
531 if (cfg->diagnostics)
532 {
533 char *sfn = GNUNET_STRINGS_filename_expand (inline_path);
534 struct stat istat;
535
536 cs->hint_secret_filename = sfn;
537 if (0 == stat (sfn, &istat))
538 {
539 struct passwd *pw = getpwuid (istat.st_uid);
540 struct group *gr = getgrgid (istat.st_gid);
541 char *pwname = (NULL == pw) ? "<unknown>" : pw->pw_name;
542 char *grname = (NULL == gr) ? "<unknown>" : gr->gr_name;
543
544 GNUNET_asprintf (&cs->hint_secret_stat,
545 "%s:%s %o",
546 pwname,
547 grname,
548 istat.st_mode);
549 }
550 else
551 {
552 cs->hint_secret_stat = GNUNET_strdup ("<can't stat file>");
553 }
554 if (source_filename)
555 {
556 /* Possible that this secret section has been inlined before */
557 GNUNET_free (cs->hint_inlined_from_filename);
558 cs->hint_inlined_from_filename = GNUNET_strdup (source_filename);
559 cs->hint_inlined_from_line = source_lineno;
560 }
561 }
562
563 /* Put file in the load list for diagnostics, even if we can't access it. */
564 {
565 cf->level = cfg->current_nest_level;
566 cf->source_filename = GNUNET_strdup (inline_path);
567 cf->hint_restrict_section = GNUNET_strdup (restrict_section);
568 GNUNET_CONTAINER_DLL_insert_tail (cfg->loaded_files_head,
569 cfg->loaded_files_tail,
570 cf);
571 }
572
573 if (GNUNET_OK != inner_ret)
574 {
575 cs->inaccessible = true;
576 cf->hint_inaccessible = true;
577 /* File can't be accessed, but that's okay. */
578 fun_ret = GNUNET_OK;
579 goto cleanup;
580 }
581
582 other_cfg = GNUNET_CONFIGURATION_create ();
583 other_cfg->restrict_section = restrict_section;
584 inner_ret = GNUNET_CONFIGURATION_parse (other_cfg,
585 inline_path);
586 if (GNUNET_OK != inner_ret)
587 {
588 cf->hint_inaccessible = true;
589 fun_ret = inner_ret;
590 goto cleanup;
591 }
592
593 cs = find_section (other_cfg, restrict_section);
594 if (NULL == cs)
595 {
596 LOG (GNUNET_ERROR_TYPE_INFO,
597 "Configuration file '%s' loaded with @inline-secret@ "
598 "does not contain section '%s'.\n",
599 inline_path,
600 restrict_section);
601 /* Inlined onfiguration is accessible but doesn't contain any values.
602 We treat this as if the inlined section was empty, and do not
603 consider it an error. */
604 fun_ret = GNUNET_OK;
605 goto cleanup;
606 }
607 for (struct ConfigEntry *ce = cs->entries;
608 NULL != ce;
609 ce = ce->next)
610 GNUNET_CONFIGURATION_set_value_string (cfg,
611 restrict_section,
612 ce->key,
613 ce->val);
614 fun_ret = GNUNET_OK;
615 }
616 else if (GNUNET_OK !=
617 GNUNET_CONFIGURATION_parse (cfg,
618 inline_path))
619 {
620 fun_ret = GNUNET_SYSERR;
621 goto cleanup;
622 }
623 else
624 {
625 fun_ret = GNUNET_OK;
626 }
627cleanup:
628 cfg->current_nest_level = old_nest_level;
629 if (NULL != other_cfg)
630 GNUNET_CONFIGURATION_destroy (other_cfg);
631 GNUNET_free (inline_path);
632 if (igc.files_length > 0)
633 {
634 for (size_t i = 0; i < igc.files_length; i++)
635 GNUNET_free (igc.files[i]);
636 GNUNET_array_grow (igc.files, igc.files_length, 0);
637 }
638 return fun_ret;
639}
640
641
642/**
643 * Find an entry from a configuration.
644 *
645 * @param cfg handle to the configuration
646 * @param section section the option is in
647 * @param key the option
648 * @return matching entry, NULL if not found
649 */
650static struct ConfigEntry *
651find_entry (const struct GNUNET_CONFIGURATION_Handle *cfg,
652 const char *section,
653 const char *key)
654{
655 struct ConfigSection *sec;
656 struct ConfigEntry *pos;
657
658 if (NULL == (sec = find_section (cfg, section)))
659 return NULL;
660 if (sec->inaccessible)
661 {
662 LOG (GNUNET_ERROR_TYPE_WARNING,
663 "Section '%s' is marked as inaccessible, because the configuration "
664 " file that contains the section can't be read. Attempts to use "
665 "option '%s' will fail.\n",
666 section,
667 key);
668 return NULL;
669 }
670 pos = sec->entries;
671 while ((pos != NULL) && (0 != strcasecmp (key, pos->key)))
672 pos = pos->next;
673 return pos;
674}
675
676
677/**
678 * Set a configuration hint.
679 *
680 * @param cfg configuration handle
681 * @param section section
682 * @param option config option
683 * @param hint_filename
684 * @param hint_line
685 */
686static void
687set_entry_hint (struct GNUNET_CONFIGURATION_Handle *cfg,
688 const char *section,
689 const char *option,
690 const char *hint_filename,
691 unsigned int hint_line)
692{
693 struct ConfigEntry *e = find_entry (cfg, section, option);
694 if (! cfg->diagnostics)
695 return;
696 if (! e)
697 return;
698 e->hint_filename = GNUNET_strdup (hint_filename);
699 e->hint_lineno = hint_line;
700}
701
702
229enum GNUNET_GenericReturnValue 703enum GNUNET_GenericReturnValue
230GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, 704GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg,
231 const char *mem, 705 const char *mem,
232 size_t size, 706 size_t size,
233 const char *basedir) 707 const char *source_filename)
234{ 708{
235 char *line;
236 char *line_orig;
237 size_t line_size; 709 size_t line_size;
238 char *pos;
239 unsigned int nr; 710 unsigned int nr;
240 size_t r_bytes; 711 size_t r_bytes;
241 size_t to_read; 712 size_t to_read;
242 size_t i;
243 int emptyline;
244 enum GNUNET_GenericReturnValue ret; 713 enum GNUNET_GenericReturnValue ret;
245 char *section; 714 char *section;
246 char *eq; 715 char *eq;
247 char *tag; 716 char *tag;
248 char *value; 717 char *value;
718 char *line_orig = NULL;
249 719
250 ret = GNUNET_OK; 720 ret = GNUNET_OK;
251 section = GNUNET_strdup (""); 721 section = NULL;
252 nr = 0; 722 nr = 0;
253 r_bytes = 0; 723 r_bytes = 0;
254 line_orig = NULL;
255 while (r_bytes < size) 724 while (r_bytes < size)
256 { 725 {
726 char *pos;
727 char *line;
728 bool emptyline;
729
257 GNUNET_free (line_orig); 730 GNUNET_free (line_orig);
258 /* fgets-like behaviour on buffer */ 731 /* fgets-like behaviour on buffer */
259 to_read = size - r_bytes; 732 to_read = size - r_bytes;
@@ -275,7 +748,7 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg,
275 nr++; 748 nr++;
276 /* tabs and '\r' are whitespace */ 749 /* tabs and '\r' are whitespace */
277 emptyline = GNUNET_YES; 750 emptyline = GNUNET_YES;
278 for (i = 0; i < line_size; i++) 751 for (size_t i = 0; i < line_size; i++)
279 { 752 {
280 if (line[i] == '\t') 753 if (line[i] == '\t')
281 line[i] = ' '; 754 line[i] = ' ';
@@ -289,7 +762,7 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg,
289 continue; 762 continue;
290 763
291 /* remove tailing whitespace */ 764 /* remove tailing whitespace */
292 for (i = line_size - 1; 765 for (size_t i = line_size - 1;
293 (i >= 1) && (isspace ((unsigned char) line[i])); 766 (i >= 1) && (isspace ((unsigned char) line[i]));
294 i--) 767 i--)
295 line[i] = '\0'; 768 line[i] = '\0';
@@ -303,50 +776,113 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg,
303 ('%' == line[0]) ) 776 ('%' == line[0]) )
304 continue; 777 continue;
305 778
306 /* handle special "@INLINE@" directive */ 779 /* Handle special directives. */
307 if (0 == strncasecmp (line, 780 if ('@' == line[0])
308 "@INLINE@ ",
309 strlen ("@INLINE@ ")))
310 { 781 {
311 /* @INLINE@ value */ 782 char *end = strchr (line + 1, '@');
312 value = &line[strlen ("@INLINE@ ")]; 783 char *directive;
313 if (NULL != basedir) 784 enum GNUNET_GenericReturnValue directive_ret;
785
786 if (NULL != cfg->restrict_section)
314 { 787 {
315 if ('/' == *value) 788 LOG (GNUNET_ERROR_TYPE_WARNING,
316 { 789 _ (
317 if (GNUNET_OK != 790 "Illegal directive in line %u (parsing restricted section %s)\n"),
318 GNUNET_CONFIGURATION_parse (cfg, 791 nr,
319 value)) 792 cfg->restrict_section);
320 { 793 ret = GNUNET_SYSERR;
321 ret = GNUNET_SYSERR; /* failed to parse included config */ 794 break;
322 break; 795 }
323 } 796
324 } 797 if (NULL == end)
325 else 798 {
799 LOG (GNUNET_ERROR_TYPE_WARNING,
800 _ ("Bad directive in line %u\n"),
801 nr);
802 ret = GNUNET_SYSERR;
803 break;
804 }
805 *end = '\0';
806 directive = line + 1;
807
808 if (0 == strcasecmp (directive, "INLINE"))
809 {
810 const char *path = end + 1;
811
812 /* Skip space before path */
813 for (; isspace (*path); path++)
814 ;
815
816 directive_ret = handle_inline (cfg,
817 path,
818 false,
819 NULL,
820 source_filename,
821 nr);
822 }
823 else if (0 == strcasecmp (directive, "INLINE-MATCHING"))
824 {
825 const char *path = end + 1;
826
827 /* Skip space before path */
828 for (; isspace (*path); path++)
829 ;
830
831 directive_ret = handle_inline (cfg,
832 path,
833 true,
834 NULL,
835 source_filename,
836 nr);
837 }
838 else if (0 == strcasecmp (directive, "INLINE-SECRET"))
839 {
840 char *secname = end + 1;
841 char *secname_end;
842 const char *path;
843
844 /* Skip space before secname */
845 for (; isspace (*secname); secname++)
846 ;
847
848 secname_end = strchr (secname, ' ');
849
850 if (NULL == secname_end)
326 { 851 {
327 char *fn; 852 LOG (GNUNET_ERROR_TYPE_WARNING,
328 853 _ ("Bad inline-secret directive in line %u\n"),
329 GNUNET_asprintf (&fn, "%s/%s", 854 nr);
330 basedir, 855 ret = GNUNET_SYSERR;
331 value); 856 break;
332 if (GNUNET_OK !=
333 GNUNET_CONFIGURATION_parse (cfg,
334 fn))
335 {
336 GNUNET_free (fn);
337 ret = GNUNET_SYSERR; /* failed to parse included config */
338 break;
339 }
340 GNUNET_free (fn);
341 } 857 }
858 *secname_end = '\0';
859 path = secname_end + 1;
860
861 /* Skip space before path */
862 for (; isspace (*path); path++)
863 ;
864
865 directive_ret = handle_inline (cfg,
866 path,
867 false,
868 secname,
869 source_filename,
870 nr);
342 } 871 }
343 else 872 else
344 { 873 {
345 LOG (GNUNET_ERROR_TYPE_DEBUG, 874 LOG (GNUNET_ERROR_TYPE_WARNING,
346 "Ignoring parsing @INLINE@ configurations, not allowed!\n"); 875 _ ("Unknown or malformed directive '%s' in line %u\n"),
876 directive,
877 nr);
347 ret = GNUNET_SYSERR; 878 ret = GNUNET_SYSERR;
348 break; 879 break;
349 } 880 }
881 if (GNUNET_OK != directive_ret)
882 {
883 ret = directive_ret;
884 break;
885 }
350 continue; 886 continue;
351 } 887 }
352 if (('[' == line[0]) && (']' == line[line_size - 1])) 888 if (('[' == line[0]) && (']' == line[line_size - 1]))
@@ -360,10 +896,23 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg,
360 } 896 }
361 if (NULL != (eq = strchr (line, '='))) 897 if (NULL != (eq = strchr (line, '=')))
362 { 898 {
899 size_t i;
900
901 if (NULL == section)
902 {
903 LOG (GNUNET_ERROR_TYPE_WARNING,
904 _ (
905 "Syntax error while deserializing in line %u (option without section)\n"),
906 nr);
907 ret = GNUNET_SYSERR;
908 break;
909 }
910
363 /* tag = value */ 911 /* tag = value */
364 tag = GNUNET_strndup (line, eq - line); 912 tag = GNUNET_strndup (line, eq - line);
365 /* remove tailing whitespace */ 913 /* remove tailing whitespace */
366 for (i = strlen (tag) - 1; (i >= 1) && (isspace ((unsigned char) tag[i])); 914 for (i = strlen (tag) - 1;
915 (i >= 1) && (isspace ((unsigned char) tag[i]));
367 i--) 916 i--)
368 tag[i] = '\0'; 917 tag[i] = '\0';
369 918
@@ -384,6 +933,14 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg,
384 value++; 933 value++;
385 } 934 }
386 GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, &value[i]); 935 GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, &value[i]);
936 if (cfg->diagnostics)
937 {
938 set_entry_hint (cfg,
939 section,
940 tag,
941 source_filename ? source_filename : "<input>",
942 nr);
943 }
387 GNUNET_free (tag); 944 GNUNET_free (tag);
388 continue; 945 continue;
389 } 946 }
@@ -410,7 +967,6 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg,
410 size_t fs; 967 size_t fs;
411 char *fn; 968 char *fn;
412 char *mem; 969 char *mem;
413 char *endsep;
414 int dirty; 970 int dirty;
415 enum GNUNET_GenericReturnValue ret; 971 enum GNUNET_GenericReturnValue ret;
416 ssize_t sret; 972 ssize_t sret;
@@ -419,6 +975,56 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg,
419 LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to parse config file `%s'\n", fn); 975 LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to parse config file `%s'\n", fn);
420 if (NULL == fn) 976 if (NULL == fn)
421 return GNUNET_SYSERR; 977 return GNUNET_SYSERR;
978
979
980 /* Check for cycles */
981 {
982 unsigned int lvl = cfg->current_nest_level;
983 struct ConfigFile *cf = cfg->loaded_files_tail;
984 struct ConfigFile *parent = NULL;
985
986
987 for (; NULL != cf; parent = cf, cf = cf->prev)
988 {
989 /* Check parents based on level, skipping children of siblings. */
990 if (cf->level >= lvl)
991 continue;
992 lvl = cf->level;
993 if ( (NULL == cf->source_filename) || (NULL == filename))
994 continue;
995 if (0 == strcmp (cf->source_filename, filename))
996 {
997 if (NULL == parent)
998 {
999 LOG (GNUNET_ERROR_TYPE_ERROR,
1000 "Forbidden direct cyclic configuration import (%s -> %s)\n",
1001 cf->source_filename,
1002 filename);
1003 }
1004 else
1005 LOG (GNUNET_ERROR_TYPE_ERROR,
1006 "Forbidden indirect cyclic configuration import (%s -> ... -> %s -> %s)\n",
1007 cf->source_filename,
1008 parent->source_filename,
1009 filename);
1010 GNUNET_free (fn);
1011 return GNUNET_SYSERR;
1012 }
1013 }
1014
1015 }
1016
1017 /* Keep track of loaded files.*/
1018 {
1019 struct ConfigFile *cf = GNUNET_new (struct ConfigFile);
1020
1021 cf->level = cfg->current_nest_level;
1022 cf->source_filename = GNUNET_strdup (filename ? filename : "<input>");
1023 GNUNET_CONTAINER_DLL_insert_tail (cfg->loaded_files_head,
1024 cfg->loaded_files_tail,
1025 cf);
1026 }
1027
422 dirty = cfg->dirty; /* back up value! */ 1028 dirty = cfg->dirty; /* back up value! */
423 if (GNUNET_SYSERR == 1029 if (GNUNET_SYSERR ==
424 GNUNET_DISK_file_size (fn, &fs64, GNUNET_YES, GNUNET_YES)) 1030 GNUNET_DISK_file_size (fn, &fs64, GNUNET_YES, GNUNET_YES))
@@ -446,14 +1052,11 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg,
446 return GNUNET_SYSERR; 1052 return GNUNET_SYSERR;
447 } 1053 }
448 LOG (GNUNET_ERROR_TYPE_DEBUG, "Deserializing contents of file `%s'\n", fn); 1054 LOG (GNUNET_ERROR_TYPE_DEBUG, "Deserializing contents of file `%s'\n", fn);
449 endsep = strrchr (fn, (int) '/');
450 if (NULL != endsep)
451 *endsep = '\0';
452 ret = GNUNET_CONFIGURATION_deserialize (cfg, 1055 ret = GNUNET_CONFIGURATION_deserialize (cfg,
453 mem, 1056 mem,
454 fs, 1057 fs,
455 fn); 1058 fn);
456 if (GNUNET_OK != ret) 1059 if (GNUNET_SYSERR == ret)
457 { 1060 {
458 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1061 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
459 _ ("Failed to parse configuration file `%s'\n"), 1062 _ ("Failed to parse configuration file `%s'\n"),
@@ -527,6 +1130,8 @@ GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg,
527 NULL != sec; 1130 NULL != sec;
528 sec = sec->next) 1131 sec = sec->next)
529 { 1132 {
1133 if (sec->inaccessible)
1134 continue;
530 /* For each section we need to add 3 characters: {'[',']','\n'} */ 1135 /* For each section we need to add 3 characters: {'[',']','\n'} */
531 m_size += strlen (sec->name) + 3; 1136 m_size += strlen (sec->name) + 3;
532 for (struct ConfigEntry *ent = sec->entries; 1137 for (struct ConfigEntry *ent = sec->entries;
@@ -606,6 +1211,117 @@ GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg,
606} 1211}
607 1212
608 1213
1214char *
1215GNUNET_CONFIGURATION_serialize_diagnostics (const struct
1216 GNUNET_CONFIGURATION_Handle *cfg)
1217{
1218 struct GNUNET_Buffer buf = { 0 };
1219
1220 GNUNET_buffer_write_fstr (&buf,
1221 "#\n# Configuration file diagnostics\n#\n");
1222 GNUNET_buffer_write_fstr (&buf,
1223 "# Entry point: %s\n",
1224 cfg->main_filename ? cfg->main_filename :
1225 "<none>");
1226 GNUNET_buffer_write_fstr (&buf,
1227 "#\n# Files Loaded:\n");
1228
1229 for (struct ConfigFile *cfil = cfg->loaded_files_head;
1230 NULL != cfil;
1231 cfil = cfil->next)
1232 {
1233 GNUNET_buffer_write_fstr (&buf,
1234 "# ");
1235 for (unsigned int i = 0; i < cfil->level; i++)
1236 GNUNET_buffer_write_fstr (&buf,
1237 "+");
1238 if (0 != cfil->level)
1239 GNUNET_buffer_write_fstr (&buf,
1240 " ");
1241
1242 GNUNET_buffer_write_fstr (&buf,
1243 "%s",
1244 cfil->source_filename);
1245
1246 if (NULL != cfil->hint_restrict_section)
1247 GNUNET_buffer_write_fstr (&buf,
1248 " (%s secret section %s)",
1249 cfil->hint_inaccessible
1250 ? "inaccessible"
1251 : "loaded",
1252 cfil->hint_restrict_section);
1253
1254 GNUNET_buffer_write_str (&buf,
1255 "\n");
1256 }
1257
1258 GNUNET_buffer_write_fstr (&buf,
1259 "#\n\n");
1260
1261 for (struct ConfigSection *sec = cfg->sections;
1262 NULL != sec;
1263 sec = sec->next)
1264 {
1265 if (sec->hint_secret_filename)
1266 GNUNET_buffer_write_fstr (&buf,
1267 "# secret section from %s\n# secret file stat %s\n",
1268 sec->hint_secret_filename,
1269 sec->hint_secret_stat);
1270 if (sec->hint_inlined_from_filename)
1271 {
1272 GNUNET_buffer_write_fstr (&buf,
1273 "# inlined from %s:%u\n",
1274 sec->hint_inlined_from_filename,
1275 sec->hint_inlined_from_line);
1276 }
1277 GNUNET_buffer_write_fstr (&buf,
1278 "[%s]\n\n",
1279 sec->name);
1280 if (sec->inaccessible)
1281 {
1282 GNUNET_buffer_write_fstr (&buf,
1283 "# <section contents inaccessible>\n\n\n");
1284 continue;
1285 }
1286 for (struct ConfigEntry *ent = sec->entries;
1287 NULL != ent;
1288 ent = ent->next)
1289 {
1290 if (do_skip (sec->name,
1291 ent->key))
1292 continue;
1293 if (NULL != ent->val)
1294 {
1295 char *pos;
1296 char *val = GNUNET_malloc (strlen (ent->val) * 2 + 1);
1297 strcpy (val, ent->val);
1298 while (NULL != (pos = strstr (val, "\n")))
1299 {
1300 memmove (&pos[2], &pos[1], strlen (&pos[1]));
1301 pos[0] = '\\';
1302 pos[1] = 'n';
1303 }
1304 if (NULL != ent->hint_filename)
1305 {
1306 GNUNET_buffer_write_fstr (&buf,
1307 "# %s:%u\n",
1308 ent->hint_filename,
1309 ent->hint_lineno);
1310 }
1311 GNUNET_buffer_write_fstr (&buf,
1312 "%s = %s\n",
1313 ent->key,
1314 val);
1315 GNUNET_free (val);
1316 }
1317 GNUNET_buffer_write_str (&buf, "\n");
1318 }
1319 GNUNET_buffer_write_str (&buf, "\n");
1320 }
1321 return GNUNET_buffer_reap_str (&buf);
1322}
1323
1324
609enum GNUNET_GenericReturnValue 1325enum GNUNET_GenericReturnValue
610GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg, 1326GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg,
611 const char *filename) 1327 const char *filename)
@@ -700,6 +1416,14 @@ GNUNET_CONFIGURATION_iterate_section_values (
700 spos = spos->next; 1416 spos = spos->next;
701 if (NULL == spos) 1417 if (NULL == spos)
702 return; 1418 return;
1419 if (spos->inaccessible)
1420 {
1421 LOG (GNUNET_ERROR_TYPE_WARNING,
1422 "Section '%s' is marked as inaccessible, because the configuration "
1423 " file that contains the section can't be read.\n",
1424 section);
1425 return;
1426 }
703 for (epos = spos->entries; NULL != epos; epos = epos->next) 1427 for (epos = spos->entries; NULL != epos; epos = epos->next)
704 if (NULL != epos->val) 1428 if (NULL != epos->val)
705 iter (iter_cls, spos->name, epos->key, epos->val); 1429 iter (iter_cls, spos->name, epos->key, epos->val);
@@ -748,10 +1472,14 @@ GNUNET_CONFIGURATION_remove_section (struct GNUNET_CONFIGURATION_Handle *cfg,
748 spos->entries = ent->next; 1472 spos->entries = ent->next;
749 GNUNET_free (ent->key); 1473 GNUNET_free (ent->key);
750 GNUNET_free (ent->val); 1474 GNUNET_free (ent->val);
1475 GNUNET_free (ent->hint_filename);
751 GNUNET_free (ent); 1476 GNUNET_free (ent);
752 cfg->dirty = GNUNET_YES; 1477 cfg->dirty = GNUNET_YES;
753 } 1478 }
754 GNUNET_free (spos->name); 1479 GNUNET_free (spos->name);
1480 GNUNET_free (spos->hint_secret_filename);
1481 GNUNET_free (spos->hint_secret_stat);
1482 GNUNET_free (spos->hint_inlined_from_filename);
755 GNUNET_free (spos); 1483 GNUNET_free (spos);
756 return; 1484 return;
757 } 1485 }
@@ -794,51 +1522,6 @@ GNUNET_CONFIGURATION_dup (const struct GNUNET_CONFIGURATION_Handle *cfg)
794 1522
795 1523
796/** 1524/**
797 * Find a section entry from a configuration.
798 *
799 * @param cfg configuration to search in
800 * @param section name of the section to look for
801 * @return matching entry, NULL if not found
802 */
803static struct ConfigSection *
804find_section (const struct GNUNET_CONFIGURATION_Handle *cfg,
805 const char *section)
806{
807 struct ConfigSection *pos;
808
809 pos = cfg->sections;
810 while ((pos != NULL) && (0 != strcasecmp (section, pos->name)))
811 pos = pos->next;
812 return pos;
813}
814
815
816/**
817 * Find an entry from a configuration.
818 *
819 * @param cfg handle to the configuration
820 * @param section section the option is in
821 * @param key the option
822 * @return matching entry, NULL if not found
823 */
824static struct ConfigEntry *
825find_entry (const struct GNUNET_CONFIGURATION_Handle *cfg,
826 const char *section,
827 const char *key)
828{
829 struct ConfigSection *sec;
830 struct ConfigEntry *pos;
831
832 if (NULL == (sec = find_section (cfg, section)))
833 return NULL;
834 pos = sec->entries;
835 while ((pos != NULL) && (0 != strcasecmp (key, pos->key)))
836 pos = pos->next;
837 return pos;
838}
839
840
841/**
842 * A callback function, compares entries from two configurations 1525 * A callback function, compares entries from two configurations
843 * (default against a new configuration) and write the diffs in a 1526 * (default against a new configuration) and write the diffs in a
844 * diff-configuration object (the callback object). 1527 * diff-configuration object (the callback object).
@@ -1601,41 +2284,93 @@ GNUNET_CONFIGURATION_remove_value_filename (
1601} 2284}
1602 2285
1603 2286
1604/** 2287enum GNUNET_GenericReturnValue
1605 * Wrapper around #GNUNET_CONFIGURATION_parse. Called on each 2288GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg,
1606 * file in a directory, we trigger parsing on those files that 2289 const char *defaults_d)
1607 * end with ".conf".
1608 *
1609 * @param cls the cfg
1610 * @param filename file to parse
1611 * @return #GNUNET_OK on success
1612 */
1613static enum GNUNET_GenericReturnValue
1614parse_configuration_file (void *cls, const char *filename)
1615{ 2290{
1616 struct GNUNET_CONFIGURATION_Handle *cfg = cls; 2291 struct CollectFilesContext files_context = {
1617 char *ext; 2292 .files = NULL,
2293 .files_length = 0,
2294 };
2295 enum GNUNET_GenericReturnValue fun_ret;
1618 2296
1619 /* Examine file extension */ 2297 if (GNUNET_SYSERR ==
1620 ext = strrchr (filename, '.'); 2298 GNUNET_DISK_directory_scan (defaults_d, &collect_files_cb,
1621 if ((NULL == ext) || (0 != strcmp (ext, ".conf"))) 2299 &files_context))
2300 return GNUNET_SYSERR; /* no configuration at all found */
2301 qsort (files_context.files,
2302 files_context.files_length,
2303 sizeof (char *),
2304 pstrcmp);
2305 for (unsigned int i = 0; i < files_context.files_length; i++)
1622 { 2306 {
1623 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Skipping file `%s'\n", filename); 2307 char *ext;
1624 return GNUNET_OK; 2308 const char *filename = files_context.files[i];
1625 }
1626 2309
1627 return GNUNET_CONFIGURATION_parse (cfg, filename); 2310 /* Examine file extension */
2311 ext = strrchr (filename, '.');
2312 if ((NULL == ext) || (0 != strcmp (ext, ".conf")))
2313 {
2314 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Skipping file `%s'\n", filename);
2315 fun_ret = GNUNET_OK;
2316 goto cleanup;
2317 }
2318 fun_ret = GNUNET_CONFIGURATION_parse (cfg, filename);
2319 if (fun_ret != GNUNET_OK)
2320 break;
2321 }
2322cleanup:
2323 if (files_context.files_length > 0)
2324 {
2325 for (size_t i = 0; i < files_context.files_length; i++)
2326 GNUNET_free (files_context.files[i]);
2327 GNUNET_array_grow (files_context.files,
2328 files_context.files_length,
2329 0);
2330 }
2331 return fun_ret;
1628} 2332}
1629 2333
1630 2334
1631enum GNUNET_GenericReturnValue 2335char *
1632GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg, 2336GNUNET_CONFIGURATION_default_filename (void)
1633 const char *defaults_d)
1634{ 2337{
1635 if (GNUNET_SYSERR == 2338 char *cfg_fn;
1636 GNUNET_DISK_directory_scan (defaults_d, &parse_configuration_file, cfg)) 2339 const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
1637 return GNUNET_SYSERR; /* no configuration at all found */ 2340 const char *xdg = getenv ("XDG_CONFIG_HOME");
1638 return GNUNET_OK; 2341
2342 if (NULL != xdg)
2343 GNUNET_asprintf (&cfg_fn,
2344 "%s%s%s",
2345 xdg,
2346 DIR_SEPARATOR_STR,
2347 pd->config_file);
2348 else
2349 cfg_fn = GNUNET_strdup (pd->user_config_file);
2350
2351 if (GNUNET_OK == GNUNET_DISK_file_test_read (cfg_fn))
2352 return cfg_fn;
2353 GNUNET_free (cfg_fn);
2354
2355 /* Fall back to /etc/ for the default configuration.
2356 Should be okay to use forward slashes here. */
2357
2358 GNUNET_asprintf (&cfg_fn,
2359 "/etc/%s",
2360 pd->config_file);
2361 if (GNUNET_OK == GNUNET_DISK_file_test_read (cfg_fn))
2362 return cfg_fn;
2363 GNUNET_free (cfg_fn);
2364
2365 GNUNET_asprintf (&cfg_fn,
2366 "/etc/%s/%s",
2367 pd->project_dirname,
2368 pd->config_file);
2369 if (GNUNET_OK == GNUNET_DISK_file_test_read (cfg_fn))
2370 return cfg_fn;
2371
2372 GNUNET_free (cfg_fn);
2373 return NULL;
1639} 2374}
1640 2375
1641 2376
@@ -1648,12 +2383,47 @@ GNUNET_CONFIGURATION_default (void)
1648 char *cfgname = NULL; 2383 char *cfgname = NULL;
1649 struct GNUNET_CONFIGURATION_Handle *cfg; 2384 struct GNUNET_CONFIGURATION_Handle *cfg;
1650 2385
2386 /* FIXME: Why are we doing this? Needs some commentary! */
1651 GNUNET_OS_init (dpd); 2387 GNUNET_OS_init (dpd);
2388
1652 cfg = GNUNET_CONFIGURATION_create (); 2389 cfg = GNUNET_CONFIGURATION_create ();
2390
2391 /* First, try user configuration. */
1653 if (NULL != xdg) 2392 if (NULL != xdg)
1654 GNUNET_asprintf (&cfgname, "%s/%s", xdg, pd->config_file); 2393 GNUNET_asprintf (&cfgname, "%s/%s", xdg, pd->config_file);
1655 else 2394 else
1656 cfgname = GNUNET_strdup (pd->user_config_file); 2395 cfgname = GNUNET_strdup (pd->user_config_file);
2396
2397 /* If user config doesn't exist, try in
2398 /etc/<projdir>/<cfgfile> and /etc/<cfgfile> */
2399 if (GNUNET_OK != GNUNET_DISK_file_test (cfgname))
2400 {
2401 GNUNET_free (cfgname);
2402 GNUNET_asprintf (&cfgname, "/etc/%s", pd->config_file);
2403 }
2404 if (GNUNET_OK != GNUNET_DISK_file_test (cfgname))
2405 {
2406 GNUNET_free (cfgname);
2407 GNUNET_asprintf (&cfgname,
2408 "/etc/%s/%s",
2409 pd->project_dirname,
2410 pd->config_file);
2411 }
2412 if (GNUNET_OK != GNUNET_DISK_file_test (cfgname))
2413 {
2414 LOG (GNUNET_ERROR_TYPE_ERROR,
2415 "Unable to top-level configuration file.\n");
2416 GNUNET_OS_init (pd);
2417 GNUNET_CONFIGURATION_destroy (cfg);
2418 GNUNET_free (cfgname);
2419 return NULL;
2420 }
2421
2422 /* We found a configuration file that looks good, try to load it. */
2423
2424 LOG (GNUNET_ERROR_TYPE_DEBUG,
2425 "Loading top-level configuration from '%s'\n",
2426 cfgname);
1657 if (GNUNET_OK != 2427 if (GNUNET_OK !=
1658 GNUNET_CONFIGURATION_load (cfg, cfgname)) 2428 GNUNET_CONFIGURATION_load (cfg, cfgname))
1659 { 2429 {
@@ -1668,4 +2438,84 @@ GNUNET_CONFIGURATION_default (void)
1668} 2438}
1669 2439
1670 2440
2441/**
2442 * Load configuration (starts with defaults, then loads
2443 * system-specific configuration).
2444 *
2445 * @param cfg configuration to update
2446 * @param filename name of the configuration file, NULL to load defaults
2447 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2448 */
2449int
2450GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg,
2451 const char *filename)
2452{
2453 char *baseconfig;
2454 const char *base_config_varname;
2455
2456 if (cfg->load_called)
2457 {
2458 /* FIXME: Make this a GNUNET_assert later */
2459 GNUNET_break (0);
2460 GNUNET_free (cfg->main_filename);
2461 }
2462 cfg->load_called = true;
2463 if (NULL != filename)
2464 {
2465 GNUNET_free (cfg->main_filename);
2466 cfg->main_filename = GNUNET_strdup (filename);
2467 }
2468
2469 base_config_varname = GNUNET_OS_project_data_get ()->base_config_varname;
2470
2471 if ((NULL != base_config_varname)
2472 && (NULL != (baseconfig = getenv (base_config_varname))))
2473 {
2474 baseconfig = GNUNET_strdup (baseconfig);
2475 }
2476 else
2477 {
2478 char *ipath;
2479
2480 ipath = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
2481 if (NULL == ipath)
2482 {
2483 GNUNET_break (0);
2484 return GNUNET_SYSERR;
2485 }
2486 GNUNET_asprintf (&baseconfig, "%s%s", ipath, "config.d");
2487 GNUNET_free (ipath);
2488 }
2489
2490 char *dname = GNUNET_STRINGS_filename_expand (baseconfig);
2491 GNUNET_free (baseconfig);
2492
2493 if ((GNUNET_YES == GNUNET_DISK_directory_test (dname, GNUNET_YES)) &&
2494 (GNUNET_SYSERR == GNUNET_CONFIGURATION_load_from (cfg, dname)))
2495 {
2496 LOG (GNUNET_ERROR_TYPE_WARNING,
2497 "Failed to load base configuration from '%s'\n",
2498 filename);
2499 GNUNET_free (dname);
2500 return GNUNET_SYSERR; /* no configuration at all found */
2501 }
2502 GNUNET_free (dname);
2503 if ((NULL != filename) &&
2504 (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, filename)))
2505 {
2506 /* specified configuration not found */
2507 LOG (GNUNET_ERROR_TYPE_WARNING,
2508 "Failed to load configuration from file '%s'\n",
2509 filename);
2510 return GNUNET_SYSERR;
2511 }
2512 if (((GNUNET_YES !=
2513 GNUNET_CONFIGURATION_have_value (cfg, "PATHS", "DEFAULTCONFIG"))) &&
2514 (filename != NULL))
2515 GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "DEFAULTCONFIG",
2516 filename);
2517 return GNUNET_OK;
2518}
2519
2520
1671/* end of configuration.c */ 2521/* end of configuration.c */
diff --git a/src/util/configuration_helper.c b/src/util/configuration_helper.c
new file mode 100644
index 000000000..8f995ec03
--- /dev/null
+++ b/src/util/configuration_helper.c
@@ -0,0 +1,302 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2006, 2007, 2008, 2009, 2013, 2020, 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 src/util/configuration_helper.c
22 * @brief helper logic for gnunet-config
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "gnunet_util_lib.h"
27
28/**
29 * Print each option in a given section as a filename.
30 *
31 * @param cls closure
32 * @param section name of the section
33 * @param option name of the option
34 * @param value value of the option
35 */
36static void
37print_filename_option (void *cls,
38 const char *section,
39 const char *option,
40 const char *value)
41{
42 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
43
44 char *value_fn;
45 char *fn;
46
47 GNUNET_assert (GNUNET_OK ==
48 GNUNET_CONFIGURATION_get_value_filename (cfg,
49 section,
50 option,
51 &value_fn));
52 fn = GNUNET_STRINGS_filename_expand (value_fn);
53 if (NULL == fn)
54 fn = value_fn;
55 else
56 GNUNET_free (value_fn);
57 fprintf (stdout,
58 "%s = %s\n",
59 option,
60 fn);
61 GNUNET_free (fn);
62}
63
64
65/**
66 * Print each option in a given section.
67 *
68 * @param cls closure
69 * @param section name of the section
70 * @param option name of the option
71 * @param value value of the option
72 */
73static void
74print_option (void *cls,
75 const char *section,
76 const char *option,
77 const char *value)
78{
79 (void) cls;
80 (void) section;
81
82 fprintf (stdout,
83 "%s = %s\n",
84 option,
85 value);
86}
87
88
89/**
90 * Print out given section name.
91 *
92 * @param cls unused
93 * @param section a section in the configuration file
94 */
95static void
96print_section_name (void *cls,
97 const char *section)
98{
99 (void) cls;
100 fprintf (stdout,
101 "%s\n",
102 section);
103}
104
105
106void
107GNUNET_CONFIGURATION_config_tool_run (
108 void *cls,
109 char *const *args,
110 const char *cfgfile,
111 const struct GNUNET_CONFIGURATION_Handle *cfg)
112{
113 struct GNUNET_CONFIGURATION_ConfigSettings *cs = cls;
114 struct GNUNET_CONFIGURATION_Handle *out = NULL;
115 struct GNUNET_CONFIGURATION_Handle *ncfg = NULL;
116
117 (void) args;
118 if (cs->diagnostics)
119 {
120 /* Re-parse the configuration with diagnostics enabled. */
121 ncfg = GNUNET_CONFIGURATION_create ();
122 GNUNET_CONFIGURATION_enable_diagnostics (ncfg);
123 GNUNET_CONFIGURATION_load (ncfg,
124 cfgfile);
125 cfg = ncfg;
126 }
127
128 if (cs->full)
129 cs->rewrite = GNUNET_YES;
130 if (cs->list_sections)
131 {
132 fprintf (stderr,
133 _ ("The following sections are available:\n"));
134 GNUNET_CONFIGURATION_iterate_sections (cfg,
135 &print_section_name,
136 NULL);
137 return;
138 }
139 if ( (! cs->rewrite) &&
140 (NULL == cs->section) )
141 {
142 char *serialization;
143
144 if (! cs->diagnostics)
145 {
146 fprintf (stderr,
147 _ ("%s, %s or %s argument is required\n"),
148 "--section",
149 "--list-sections",
150 "--diagnostics");
151 cs->global_ret = EXIT_INVALIDARGUMENT;
152 return;
153 }
154 serialization = GNUNET_CONFIGURATION_serialize_diagnostics (cfg);
155 fprintf (stdout,
156 "%s",
157 serialization);
158 GNUNET_free (serialization);
159 }
160 else if ( (NULL != cs->section) &&
161 (NULL == cs->value) )
162 {
163 if (NULL == cs->option)
164 {
165 GNUNET_CONFIGURATION_iterate_section_values (
166 cfg,
167 cs->section,
168 cs->is_filename
169 ? &print_filename_option
170 : &print_option,
171 (void *) cfg);
172 }
173 else
174 {
175 char *value;
176
177 if (cs->is_filename)
178 {
179 if (GNUNET_OK !=
180 GNUNET_CONFIGURATION_get_value_filename (cfg,
181 cs->section,
182 cs->option,
183 &value))
184 {
185 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
186 cs->section,
187 cs->option);
188 cs->global_ret = EXIT_NOTCONFIGURED;
189 return;
190 }
191 }
192 else
193 {
194 if (GNUNET_OK !=
195 GNUNET_CONFIGURATION_get_value_string (cfg,
196 cs->section,
197 cs->option,
198 &value))
199 {
200 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
201 cs->section,
202 cs->option);
203 cs->global_ret = EXIT_NOTCONFIGURED;
204 return;
205 }
206 }
207 fprintf (stdout,
208 "%s\n",
209 value);
210 GNUNET_free (value);
211 }
212 }
213 else if (NULL != cs->section)
214 {
215 if (NULL == cs->option)
216 {
217 fprintf (stderr,
218 _ ("--option argument required to set value\n"));
219 cs->global_ret = EXIT_INVALIDARGUMENT;
220 return;
221 }
222 out = GNUNET_CONFIGURATION_dup (cfg);
223 GNUNET_CONFIGURATION_set_value_string (out,
224 cs->section,
225 cs->option,
226 cs->value);
227 cs->rewrite = GNUNET_YES;
228 }
229 if (cs->rewrite)
230 {
231 char *cfg_fn = NULL;
232
233 if (NULL == out)
234 out = GNUNET_CONFIGURATION_dup (cfg);
235
236 if (NULL == cfgfile)
237 {
238 const char *xdg = getenv ("XDG_CONFIG_HOME");
239
240 if (NULL != xdg)
241 GNUNET_asprintf (&cfg_fn,
242 "%s%s%s",
243 xdg,
244 DIR_SEPARATOR_STR,
245 GNUNET_OS_project_data_get ()->config_file);
246 else
247 cfg_fn = GNUNET_strdup (
248 GNUNET_OS_project_data_get ()->user_config_file);
249 cfgfile = cfg_fn;
250 }
251
252 if (! cs->full)
253 {
254 struct GNUNET_CONFIGURATION_Handle *def;
255
256 def = GNUNET_CONFIGURATION_create ();
257 if (GNUNET_OK !=
258 GNUNET_CONFIGURATION_load (def,
259 NULL))
260 {
261 fprintf (stderr,
262 _ ("failed to load configuration defaults"));
263 cs->global_ret = 1;
264 GNUNET_CONFIGURATION_destroy (def);
265 GNUNET_CONFIGURATION_destroy (out);
266 GNUNET_free (cfg_fn);
267 return;
268 }
269 if (GNUNET_OK !=
270 GNUNET_CONFIGURATION_write_diffs (def,
271 out,
272 cfgfile))
273 cs->global_ret = 2;
274 GNUNET_CONFIGURATION_destroy (def);
275 }
276 else
277 {
278 if (GNUNET_OK !=
279 GNUNET_CONFIGURATION_write (out,
280 cfgfile))
281 cs->global_ret = 2;
282 }
283 GNUNET_free (cfg_fn);
284 }
285 if (NULL != out)
286 GNUNET_CONFIGURATION_destroy (out);
287 if (NULL != ncfg)
288 GNUNET_CONFIGURATION_destroy (ncfg);
289}
290
291
292void
293GNUNET_CONFIGURATION_config_settings_free (
294 struct GNUNET_CONFIGURATION_ConfigSettings *cs)
295{
296 GNUNET_free (cs->option);
297 GNUNET_free (cs->section);
298 GNUNET_free (cs->value);
299}
300
301
302/* end of configuration_helper.c */
diff --git a/src/util/configuration_loader.c b/src/util/configuration_loader.c
deleted file mode 100644
index a59477b25..000000000
--- a/src/util/configuration_loader.c
+++ /dev/null
@@ -1,91 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2006, 2007, 2008, 2009, 2013 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 src/util/configuration_loader.c
23 * @brief configuration loading
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29
30#define LOG(kind, ...) GNUNET_log_from (kind, "util-configuration", __VA_ARGS__)
31
32
33/**
34 * Load configuration (starts with defaults, then loads
35 * system-specific configuration).
36 *
37 * @param cfg configuration to update
38 * @param filename name of the configuration file, NULL to load defaults
39 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
40 */
41int
42GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg,
43 const char *filename)
44{
45 char *baseconfig;
46 const char *base_config_varname;
47
48 base_config_varname = GNUNET_OS_project_data_get ()->base_config_varname;
49
50 if (NULL != base_config_varname
51 && NULL != (baseconfig = getenv (base_config_varname)))
52 {
53 baseconfig = GNUNET_strdup (baseconfig);
54 }
55 else
56 {
57 char *ipath;
58
59 ipath = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
60 if (NULL == ipath)
61 return GNUNET_SYSERR;
62 GNUNET_asprintf (&baseconfig, "%s%s", ipath, "config.d");
63 GNUNET_free (ipath);
64 }
65
66 char *dname = GNUNET_STRINGS_filename_expand (baseconfig);
67 GNUNET_free (baseconfig);
68
69 if (GNUNET_YES == GNUNET_DISK_directory_test (dname, GNUNET_YES) &&
70 GNUNET_SYSERR == GNUNET_CONFIGURATION_load_from (cfg, dname))
71 {
72 GNUNET_free (dname);
73 return GNUNET_SYSERR; /* no configuration at all found */
74 }
75 GNUNET_free (dname);
76 if ((NULL != filename) &&
77 (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, filename)))
78 {
79 /* specified configuration not found */
80 return GNUNET_SYSERR;
81 }
82 if (((GNUNET_YES !=
83 GNUNET_CONFIGURATION_have_value (cfg, "PATHS", "DEFAULTCONFIG"))) &&
84 (filename != NULL))
85 GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "DEFAULTCONFIG",
86 filename);
87 return GNUNET_OK;
88}
89
90
91/* end of configuration_loader.c */
diff --git a/src/util/crypto_hkdf.c b/src/util/crypto_hkdf.c
index 86a814b12..7270b87b6 100644
--- a/src/util/crypto_hkdf.c
+++ b/src/util/crypto_hkdf.c
@@ -77,7 +77,11 @@ static const void *
77doHMAC (gcry_md_hd_t mac, const void *key, size_t key_len, const void *buf, 77doHMAC (gcry_md_hd_t mac, const void *key, size_t key_len, const void *buf,
78 size_t buf_len) 78 size_t buf_len)
79{ 79{
80 gcry_md_setkey (mac, key, key_len); 80 if (GPG_ERR_NO_ERROR != gcry_md_setkey (mac, key, key_len))
81 {
82 GNUNET_break (0);
83 return NULL;
84 }
81 gcry_md_write (mac, buf, buf_len); 85 gcry_md_write (mac, buf, buf_len);
82 86
83 return (const void *) gcry_md_read (mac, 0); 87 return (const void *) gcry_md_read (mac, 0);
diff --git a/src/util/disk.c b/src/util/disk.c
index 3bafe311d..2efb52d46 100644
--- a/src/util/disk.c
+++ b/src/util/disk.c
@@ -432,9 +432,15 @@ GNUNET_DISK_directory_test (const char *fil, int is_readable)
432 return GNUNET_YES; 432 return GNUNET_YES;
433} 433}
434 434
435 435/**
436enum GNUNET_GenericReturnValue 436 * Check if fil can be accessed using amode.
437GNUNET_DISK_file_test (const char *fil) 437 *
438 * @param fil file to check for
439 * @param amode access mode
440 * @returns GNUnet error code
441 */
442static enum GNUNET_GenericReturnValue
443file_test_internal (const char *fil, int amode)
438{ 444{
439 struct stat filestat; 445 struct stat filestat;
440 int ret; 446 int ret;
@@ -449,7 +455,7 @@ GNUNET_DISK_file_test (const char *fil)
449 { 455 {
450 if (errno != ENOENT) 456 if (errno != ENOENT)
451 { 457 {
452 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", rdir); 458 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "stat", rdir);
453 GNUNET_free (rdir); 459 GNUNET_free (rdir);
454 return GNUNET_SYSERR; 460 return GNUNET_SYSERR;
455 } 461 }
@@ -461,9 +467,9 @@ GNUNET_DISK_file_test (const char *fil)
461 GNUNET_free (rdir); 467 GNUNET_free (rdir);
462 return GNUNET_NO; 468 return GNUNET_NO;
463 } 469 }
464 if (access (rdir, F_OK) < 0) 470 if (access (rdir, amode) < 0)
465 { 471 {
466 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "access", rdir); 472 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "access", rdir);
467 GNUNET_free (rdir); 473 GNUNET_free (rdir);
468 return GNUNET_SYSERR; 474 return GNUNET_SYSERR;
469 } 475 }
@@ -473,6 +479,20 @@ GNUNET_DISK_file_test (const char *fil)
473 479
474 480
475enum GNUNET_GenericReturnValue 481enum GNUNET_GenericReturnValue
482GNUNET_DISK_file_test (const char *fil)
483{
484 return file_test_internal (fil, F_OK);
485}
486
487
488enum GNUNET_GenericReturnValue
489GNUNET_DISK_file_test_read (const char *fil)
490{
491 return file_test_internal (fil, R_OK);
492}
493
494
495enum GNUNET_GenericReturnValue
476GNUNET_DISK_directory_create (const char *dir) 496GNUNET_DISK_directory_create (const char *dir)
477{ 497{
478 char *rdir; 498 char *rdir;
@@ -882,6 +902,166 @@ GNUNET_DISK_directory_scan (const char *dir_name,
882 return count; 902 return count;
883} 903}
884 904
905/**
906 * Check for a simple wildcard match.
907 * Only asterisks are allowed.
908 * Asterisks match everything, including slashes.
909 *
910 * @param pattern pattern with wildcards
911 * @param str string to match against
912 * @returns true on match, false otherwise
913 */
914static bool
915glob_match (const char *pattern, const char *str)
916{
917 /* Position in the input string */
918 const char *str_pos = str;
919 /* Position in the pattern */
920 const char *pat_pos = pattern;
921 /* Backtrack position in string */
922 const char *str_bt = NULL;
923 /* Backtrack position in pattern */
924 const char *pat_bt = NULL;
925
926 for (;;)
927 {
928 if (*pat_pos == '*')
929 {
930 str_bt = str_pos;
931 pat_bt = pat_pos++;
932 }
933 else if (*pat_pos == *str_pos)
934 {
935 if ('\0' == *pat_pos)
936 return true;
937 str_pos++;
938 pat_pos++;
939 }
940 else
941 {
942 if (NULL == str_bt)
943 return false;
944 /* Backtrack to match one more
945 character as part of the asterisk. */
946 str_pos = str_bt + 1;
947 if ('\0' == *str_pos)
948 return false;
949 pat_pos = pat_bt;
950 }
951 }
952}
953
954struct GlobClosure
955{
956 const char *glob;
957 GNUNET_FileNameCallback cb;
958 void *cls;
959
960 /**
961 * Number of files that actually matched the glob pattern.
962 */
963 int nres;
964};
965
966/**
967 * Function called with a filename.
968 *
969 * @param cls closure
970 * @param filename complete filename (absolute path)
971 * @return #GNUNET_OK to continue to iterate,
972 * #GNUNET_NO to stop iteration with no error,
973 * #GNUNET_SYSERR to abort iteration with error!
974 */
975static enum GNUNET_GenericReturnValue
976glob_cb (void *cls,
977 const char *filename)
978{
979 struct GlobClosure *gc = cls;
980 const char *fn;
981
982 fn = strrchr (filename, DIR_SEPARATOR);
983 fn = (NULL == fn) ? filename : (fn + 1);
984
985 LOG (GNUNET_ERROR_TYPE_DEBUG,
986 "checking glob '%s' against '%s'\n",
987 gc->glob,
988 fn);
989
990 if (glob_match (gc->glob, fn))
991 {
992 enum GNUNET_GenericReturnValue cbret;
993
994 LOG (GNUNET_ERROR_TYPE_DEBUG,
995 "found glob match '%s'\n",
996 filename);
997 gc->nres++;
998 cbret = gc->cb (gc->cls, filename);
999 if (GNUNET_OK != cbret)
1000 return cbret;
1001 }
1002 return GNUNET_OK;
1003}
1004
1005
1006int
1007GNUNET_DISK_glob (const char *glob_pattern,
1008 GNUNET_FileNameCallback callback,
1009 void *callback_cls)
1010{
1011 char *mypat = GNUNET_strdup (glob_pattern);
1012 char *sep;
1013 int ret;
1014
1015 if ( (NULL != strrchr (glob_pattern, '+')) ||
1016 (NULL != strrchr (glob_pattern, '[')) ||
1017 (NULL != strrchr (glob_pattern, '+')) ||
1018 (NULL != strrchr (glob_pattern, '~')) )
1019 {
1020 LOG (GNUNET_ERROR_TYPE_ERROR,
1021 "unsupported glob pattern: '%s'\n",
1022 glob_pattern);
1023 GNUNET_free (mypat);
1024 return -1;
1025 }
1026
1027 sep = strrchr (mypat, DIR_SEPARATOR);
1028 if (NULL == sep)
1029 {
1030 GNUNET_free (mypat);
1031 return -1;
1032 }
1033
1034 *sep = '\0';
1035
1036 if (NULL != strchr (mypat, '*'))
1037 {
1038 GNUNET_free (mypat);
1039 GNUNET_break (0);
1040 LOG (GNUNET_ERROR_TYPE_ERROR,
1041 "glob pattern may only contain '*' in the final path component\n");
1042 return -1;
1043 }
1044
1045 {
1046 struct GlobClosure gc = {
1047 .glob = sep + 1,
1048 .cb = callback,
1049 .cls = callback_cls,
1050 .nres = 0,
1051 };
1052 LOG (GNUNET_ERROR_TYPE_DEBUG,
1053 "scanning directory '%s' for glob matches on '%s'\n",
1054 mypat,
1055 gc.glob);
1056 ret = GNUNET_DISK_directory_scan (mypat,
1057 glob_cb,
1058 &gc
1059 );
1060 GNUNET_free (mypat);
1061 return (ret < 0) ? ret : gc.nres;
1062 }
1063}
1064
885 1065
886/** 1066/**
887 * Function that removes the given directory by calling 1067 * Function that removes the given directory by calling
@@ -997,7 +1177,7 @@ GNUNET_DISK_file_copy (const char *src,
997 GNUNET_DISK_file_close (in); 1177 GNUNET_DISK_file_close (in);
998 GNUNET_DISK_file_close (out); 1178 GNUNET_DISK_file_close (out);
999 return GNUNET_OK; 1179 return GNUNET_OK;
1000FAIL: 1180 FAIL:
1001 GNUNET_free (buf); 1181 GNUNET_free (buf);
1002 GNUNET_DISK_file_close (in); 1182 GNUNET_DISK_file_close (in);
1003 GNUNET_DISK_file_close (out); 1183 GNUNET_DISK_file_close (out);
diff --git a/src/util/gnunet-config.c b/src/util/gnunet-config.c
index 11682daea..a195d6014 100644
--- a/src/util/gnunet-config.c
+++ b/src/util/gnunet-config.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012 GNUnet e.V. 3 Copyright (C) 2012-2021 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
@@ -28,51 +28,12 @@
28 28
29 29
30/** 30/**
31 * Name of the section
32 */
33static char *section;
34
35/**
36 * Name of the option
37 */
38static char *option;
39
40/**
41 * Value to set
42 */
43static char *value;
44
45/**
46 * Backend to check if the respective plugin is 31 * Backend to check if the respective plugin is
47 * loadable. NULL if no check is to be performed. 32 * loadable. NULL if no check is to be performed.
48 * The value is the "basename" of the plugin to load. 33 * The value is the "basename" of the plugin to load.
49 */ 34 */
50static char *backend_check; 35static char *backend_check;
51 36
52/**
53 * Treat option as a filename.
54 */
55static int is_filename;
56
57/**
58 * Whether to show the sections.
59 */
60static int list_sections;
61
62/**
63 * Return value from 'main'.
64 */
65static int global_ret;
66
67/**
68 * Should we write out the configuration file, even if no value was changed?
69 */
70static int rewrite;
71
72/**
73 * Should the generated configuration file contain the whole configuration?
74 */
75static int full;
76 37
77/** 38/**
78 * If printing the value of CFLAGS has been requested. 39 * If printing the value of CFLAGS has been requested.
@@ -92,64 +53,11 @@ static int prefix;
92 53
93/** 54/**
94 * Print each option in a given section. 55 * Print each option in a given section.
56 * Main task to run to perform operations typical for
57 * gnunet-config as per the configuration settings
58 * given in @a cls.
95 * 59 *
96 * @param cls closure 60 * @param cls closure with the `struct GNUNET_CONFIGURATION_ConfigSettings`
97 * @param section name of the section
98 * @param option name of the option
99 * @param value value of the option
100 */
101static void
102print_option (void *cls,
103 const char *section,
104 const char *option,
105 const char *value)
106{
107 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
108
109 (void) section;
110 if (is_filename)
111 {
112 char *value_fn;
113 char *fn;
114
115 GNUNET_assert (GNUNET_OK ==
116 GNUNET_CONFIGURATION_get_value_filename (cfg,
117 section,
118 option,
119 &value_fn));
120 fn = GNUNET_STRINGS_filename_expand (value_fn);
121 if (NULL == fn)
122 fn = value_fn;
123 else
124 GNUNET_free (value_fn);
125 fprintf (stdout, "%s = %s\n", option, fn);
126 GNUNET_free (fn);
127 }
128 else
129 {
130 fprintf (stdout, "%s = %s\n", option, value);
131 }
132}
133
134
135/**
136 * Print out given section name.
137 *
138 * @param cls unused
139 * @param section a section in the configuration file
140 */
141static void
142print_section_name (void *cls, const char *section)
143{
144 (void) cls;
145 fprintf (stdout, "%s\n", section);
146}
147
148
149/**
150 * Main function that will be run by the scheduler.
151 *
152 * @param cls closure
153 * @param args remaining command-line arguments 61 * @param args remaining command-line arguments
154 * @param cfgfile name of the configuration file used (for saving, 62 * @param cfgfile name of the configuration file used (for saving,
155 * can be NULL!) 63 * can be NULL!)
@@ -161,10 +69,8 @@ run (void *cls,
161 const char *cfgfile, 69 const char *cfgfile,
162 const struct GNUNET_CONFIGURATION_Handle *cfg) 70 const struct GNUNET_CONFIGURATION_Handle *cfg)
163{ 71{
164 struct GNUNET_CONFIGURATION_Handle *out = NULL; 72 struct GNUNET_CONFIGURATION_ConfigSettings *cs = cls;
165 73
166 (void) cls;
167 (void) args;
168 if (1 == cflags || 1 == libs || 1 == prefix) 74 if (1 == cflags || 1 == libs || 1 == prefix)
169 { 75 {
170 char *prefixdir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_PREFIX); 76 char *prefixdir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_PREFIX);
@@ -192,153 +98,15 @@ run (void *cls,
192 GNUNET_asprintf (&name, 98 GNUNET_asprintf (&name,
193 "libgnunet_plugin_%s", 99 "libgnunet_plugin_%s",
194 backend_check); 100 backend_check);
195 global_ret = (GNUNET_OK == 101 cs->global_ret = (GNUNET_OK ==
196 GNUNET_PLUGIN_test (name)) ? 0 : 77; 102 GNUNET_PLUGIN_test (name)) ? 0 : 77;
197 GNUNET_free (name); 103 GNUNET_free (name);
198 return; 104 return;
199 } 105 }
200 if (full) 106 GNUNET_CONFIGURATION_config_tool_run (cs,
201 rewrite = GNUNET_YES; 107 args,
202 if (list_sections) 108 cfgfile,
203 { 109 cfg);
204 fprintf (stderr,
205 _ ("The following sections are available:\n"));
206 GNUNET_CONFIGURATION_iterate_sections (cfg,
207 &print_section_name,
208 NULL);
209 return;
210 }
211 if ( (! rewrite) &&
212 (NULL == section) )
213 {
214 fprintf (stderr,
215 _ ("%s or %s argument is required\n"),
216 "--section",
217 "--list-sections");
218 global_ret = 1;
219 return;
220 }
221
222 if ( (NULL != section) &&
223 (NULL == value) )
224 {
225 if (NULL == option)
226 {
227 GNUNET_CONFIGURATION_iterate_section_values (cfg,
228 section,
229 &print_option,
230 (void *) cfg);
231 }
232 else
233 {
234 if (is_filename)
235 {
236 if (GNUNET_OK !=
237 GNUNET_CONFIGURATION_get_value_filename (cfg,
238 section,
239 option,
240 &value))
241 {
242 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
243 section,
244 option);
245 global_ret = 3;
246 return;
247 }
248 }
249 else
250 {
251 if (GNUNET_OK !=
252 GNUNET_CONFIGURATION_get_value_string (cfg,
253 section,
254 option,
255 &value))
256 {
257 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
258 section,
259 option);
260 global_ret = 3;
261 return;
262 }
263 }
264 fprintf (stdout,
265 "%s\n",
266 value);
267 }
268 }
269 else if (NULL != section)
270 {
271 if (NULL == option)
272 {
273 fprintf (stderr,
274 _ ("--option argument required to set value\n"));
275 global_ret = 1;
276 return;
277 }
278 out = GNUNET_CONFIGURATION_dup (cfg);
279 GNUNET_CONFIGURATION_set_value_string (out,
280 section,
281 option,
282 value);
283 rewrite = GNUNET_YES;
284 }
285 if (rewrite)
286 {
287 char *cfg_fn = NULL;
288
289 if (NULL == out)
290 out = GNUNET_CONFIGURATION_dup (cfg);
291
292 if (NULL == cfgfile)
293 {
294 const char *xdg = getenv ("XDG_CONFIG_HOME");
295 if (NULL != xdg)
296 GNUNET_asprintf (&cfg_fn,
297 "%s%s%s",
298 xdg,
299 DIR_SEPARATOR_STR,
300 GNUNET_OS_project_data_get ()->config_file);
301 else
302 cfg_fn = GNUNET_strdup (
303 GNUNET_OS_project_data_get ()->user_config_file);
304 cfgfile = cfg_fn;
305 }
306
307 if (! full)
308 {
309 struct GNUNET_CONFIGURATION_Handle *def;
310
311 def = GNUNET_CONFIGURATION_create ();
312 if (GNUNET_OK !=
313 GNUNET_CONFIGURATION_load (def,
314 NULL))
315 {
316 fprintf (stderr,
317 _ ("failed to load configuration defaults"));
318 global_ret = 1;
319 GNUNET_CONFIGURATION_destroy (def);
320 GNUNET_CONFIGURATION_destroy (out);
321 GNUNET_free (cfg_fn);
322 return;
323 }
324 if (GNUNET_OK !=
325 GNUNET_CONFIGURATION_write_diffs (def,
326 out,
327 cfgfile))
328 global_ret = 2;
329 GNUNET_CONFIGURATION_destroy (def);
330 }
331 else
332 {
333 if (GNUNET_OK !=
334 GNUNET_CONFIGURATION_write (out,
335 cfgfile))
336 global_ret = 2;
337 }
338 GNUNET_free (cfg_fn);
339 }
340 if (NULL != out)
341 GNUNET_CONFIGURATION_destroy (out);
342} 110}
343 111
344 112
@@ -350,8 +118,13 @@ run (void *cls,
350 * @return 0 ok, 1 on error 118 * @return 0 ok, 1 on error
351 */ 119 */
352int 120int
353main (int argc, char *const *argv) 121main (int argc,
122 char *const *argv)
354{ 123{
124 struct GNUNET_CONFIGURATION_ConfigSettings cs = {
125 .api_version = GNUNET_UTIL_VERSION,
126 .global_ret = EXIT_SUCCESS
127 };
355 struct GNUNET_GETOPT_CommandLineOption options[] = { 128 struct GNUNET_GETOPT_CommandLineOption options[] = {
356 GNUNET_GETOPT_option_exclusive ( 129 GNUNET_GETOPT_option_exclusive (
357 GNUNET_GETOPT_option_string ( 130 GNUNET_GETOPT_option_string (
@@ -361,44 +134,6 @@ main (int argc, char *const *argv)
361 gettext_noop ( 134 gettext_noop (
362 "test if the current installation supports the specified BACKEND"), 135 "test if the current installation supports the specified BACKEND"),
363 &backend_check)), 136 &backend_check)),
364 GNUNET_GETOPT_option_flag (
365 'F',
366 "full",
367 gettext_noop (
368 "write the full configuration file, including default values"),
369 &full),
370 GNUNET_GETOPT_option_flag (
371 'f',
372 "filename",
373 gettext_noop ("interpret option value as a filename (with $-expansion)"),
374 &is_filename),
375 GNUNET_GETOPT_option_string ('o',
376 "option",
377 "OPTION",
378 gettext_noop ("name of the option to access"),
379 &option),
380 GNUNET_GETOPT_option_flag (
381 'r',
382 "rewrite",
383 gettext_noop (
384 "rewrite the configuration file, even if nothing changed"),
385 &rewrite),
386 GNUNET_GETOPT_option_flag ('S',
387 "list-sections",
388 gettext_noop (
389 "print available configuration sections"),
390 &list_sections),
391 GNUNET_GETOPT_option_string ('s',
392 "section",
393 "SECTION",
394 gettext_noop (
395 "name of the section to access"),
396 &section),
397 GNUNET_GETOPT_option_string ('V',
398 "value",
399 "VALUE",
400 gettext_noop ("value to set"),
401 &value),
402 GNUNET_GETOPT_option_flag ('C', 137 GNUNET_GETOPT_option_flag ('C',
403 "cflags", 138 "cflags",
404 gettext_noop ( 139 gettext_noop (
@@ -414,15 +149,15 @@ main (int argc, char *const *argv)
414 gettext_noop ( 149 gettext_noop (
415 "Provide the path under which GNUnet was installed"), 150 "Provide the path under which GNUnet was installed"),
416 &prefix), 151 &prefix),
152 GNUNET_CONFIGURATION_CONFIG_OPTIONS (&cs),
417 GNUNET_GETOPT_OPTION_END 153 GNUNET_GETOPT_OPTION_END
418 }; 154 };
419 int ret; 155 enum GNUNET_GenericReturnValue ret;
420 156
421 if (GNUNET_OK != 157 if (GNUNET_OK !=
422 GNUNET_STRINGS_get_utf8_args (argc, argv, 158 GNUNET_STRINGS_get_utf8_args (argc, argv,
423 &argc, &argv)) 159 &argc, &argv))
424 return 2; 160 return EXIT_FAILURE;
425
426 ret = 161 ret =
427 GNUNET_PROGRAM_run (argc, 162 GNUNET_PROGRAM_run (argc,
428 argv, 163 argv,
@@ -430,11 +165,14 @@ main (int argc, char *const *argv)
430 gettext_noop ("Manipulate GNUnet configuration files"), 165 gettext_noop ("Manipulate GNUnet configuration files"),
431 options, 166 options,
432 &run, 167 &run,
433 NULL); 168 &cs);
434 GNUNET_free_nz ((void *) argv); 169 GNUNET_free_nz ((void *) argv);
435 if (GNUNET_OK == ret) 170 GNUNET_CONFIGURATION_config_settings_free (&cs);
436 return global_ret; 171 if (GNUNET_NO == ret)
437 return ret; 172 return 0;
173 if (GNUNET_SYSERR == ret)
174 return EXIT_INVALIDARGUMENT;
175 return cs.global_ret;
438} 176}
439 177
440 178
diff --git a/src/util/network.c b/src/util/network.c
index e771a9834..014701e02 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -122,7 +122,7 @@ GNUNET_NETWORK_test_pf (int pf)
122 } 122 }
123 else 123 else
124 { 124 {
125 close (s); 125 GNUNET_break (0 == close (s));
126 ret = GNUNET_OK; 126 ret = GNUNET_OK;
127 } 127 }
128 switch (pf) 128 switch (pf)
@@ -506,15 +506,15 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
506#endif 506#endif
507 if (AF_UNIX == address->sa_family) 507 if (AF_UNIX == address->sa_family)
508 GNUNET_NETWORK_unix_precheck ((const struct sockaddr_un *) address); 508 GNUNET_NETWORK_unix_precheck ((const struct sockaddr_un *) address);
509
509 { 510 {
510 const int on = 1; 511 const int on = 1;
511 512
512 /* This is required here for TCP sockets, but only on UNIX */ 513 if ( (SOCK_STREAM == desc->type) &&
513 if ((SOCK_STREAM == desc->type) && 514 (0 != setsockopt (desc->fd,
514 (0 != setsockopt (desc->fd, 515 SOL_SOCKET,
515 SOL_SOCKET, 516 SO_REUSEADDR,
516 SO_REUSEADDR, 517 &on, sizeof(on))) )
517 &on, sizeof(on))))
518 LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, 518 LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG,
519 "setsockopt"); 519 "setsockopt");
520 } 520 }
@@ -883,15 +883,13 @@ GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd,
883 const void *option_value, 883 const void *option_value,
884 socklen_t option_len) 884 socklen_t option_len)
885{ 885{
886 int ret; 886 return (0 == setsockopt (fd->fd,
887 887 level,
888 ret = setsockopt (fd->fd, 888 option_name,
889 level, 889 option_value,
890 option_name, 890 option_len))
891 option_value, 891 ? GNUNET_OK
892 option_len); 892 : GNUNET_SYSERR;
893
894 return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
895} 893}
896 894
897 895
diff --git a/src/util/os_installation.c b/src/util/os_installation.c
index 02d4d439d..f15e1871a 100644
--- a/src/util/os_installation.c
+++ b/src/util/os_installation.c
@@ -68,7 +68,7 @@ static const struct GNUNET_OS_ProjectData default_pd = {
68 .config_file = "gnunet.conf", 68 .config_file = "gnunet.conf",
69 .user_config_file = "~/.config/gnunet.conf", 69 .user_config_file = "~/.config/gnunet.conf",
70 .is_gnu = 1, 70 .is_gnu = 1,
71 .gettext_domain = PACKAGE, 71 .gettext_domain = "gnunet",
72 .gettext_path = NULL, 72 .gettext_path = NULL,
73 .agpl_url = GNUNET_AGPL_URL, 73 .agpl_url = GNUNET_AGPL_URL,
74}; 74};
diff --git a/src/util/os_priority.c b/src/util/os_priority.c
index 1ed9bcbf7..08320b291 100644
--- a/src/util/os_priority.c
+++ b/src/util/os_priority.c
@@ -47,7 +47,6 @@ struct GNUNET_OS_Process
47 */ 47 */
48 pid_t pid; 48 pid_t pid;
49 49
50
51 /** 50 /**
52 * Pipe we use to signal the process. 51 * Pipe we use to signal the process.
53 * NULL if unused, or if process was deemed uncontrollable. 52 * NULL if unused, or if process was deemed uncontrollable.
@@ -301,7 +300,8 @@ GNUNET_OS_process_destroy (struct GNUNET_OS_Process *proc)
301 * @param flags open flags (O_RDONLY, O_WRONLY) 300 * @param flags open flags (O_RDONLY, O_WRONLY)
302 */ 301 */
303static void 302static void
304open_dev_null (int target_fd, int flags) 303open_dev_null (int target_fd,
304 int flags)
305{ 305{
306 int fd; 306 int fd;
307 307
@@ -316,7 +316,7 @@ open_dev_null (int target_fd, int flags)
316 if (-1 == dup2 (fd, target_fd)) 316 if (-1 == dup2 (fd, target_fd))
317 { 317 {
318 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup2"); 318 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup2");
319 (void) close (fd); 319 GNUNET_break (0 == close (fd));
320 return; 320 return;
321 } 321 }
322 GNUNET_break (0 == close (fd)); 322 GNUNET_break (0 == close (fd));
@@ -395,7 +395,7 @@ start_process (enum GNUNET_OS_InheritStdioFlags std_inheritance,
395 if (NULL != childpipe_write) 395 if (NULL != childpipe_write)
396 GNUNET_DISK_file_close (childpipe_write); 396 GNUNET_DISK_file_close (childpipe_write);
397 if (0 <= dup_childpipe_read_fd) 397 if (0 <= dup_childpipe_read_fd)
398 close (dup_childpipe_read_fd); 398 GNUNET_break (0 == close (dup_childpipe_read_fd));
399 return NULL; 399 return NULL;
400 } 400 }
401 childpipe_read_fd = dup_childpipe_read_fd; 401 childpipe_read_fd = dup_childpipe_read_fd;
@@ -474,7 +474,7 @@ start_process (enum GNUNET_OS_InheritStdioFlags std_inheritance,
474 if (NULL != childpipe_write) 474 if (NULL != childpipe_write)
475 GNUNET_DISK_file_close (childpipe_write); 475 GNUNET_DISK_file_close (childpipe_write);
476 if (0 <= childpipe_read_fd) 476 if (0 <= childpipe_read_fd)
477 close (childpipe_read_fd); 477 GNUNET_break (0 == close (childpipe_read_fd));
478 errno = eno; 478 errno = eno;
479 return NULL; 479 return NULL;
480 } 480 }
@@ -486,7 +486,7 @@ start_process (enum GNUNET_OS_InheritStdioFlags std_inheritance,
486 gnunet_proc->control_pipe = childpipe_write; 486 gnunet_proc->control_pipe = childpipe_write;
487 if (0 != (std_inheritance & GNUNET_OS_USE_PIPE_CONTROL)) 487 if (0 != (std_inheritance & GNUNET_OS_USE_PIPE_CONTROL))
488 { 488 {
489 close (childpipe_read_fd); 489 GNUNET_break (0 == close (childpipe_read_fd));
490 } 490 }
491 GNUNET_array_grow (lscp, ls, 0); 491 GNUNET_array_grow (lscp, ls, 0);
492 return gnunet_proc; 492 return gnunet_proc;
@@ -564,7 +564,7 @@ start_process (enum GNUNET_OS_InheritStdioFlags std_inheritance,
564 { 564 {
565 /* Bury any existing FD, no matter what; they should all be closed 565 /* Bury any existing FD, no matter what; they should all be closed
566 * on exec anyway and the important ones have been dup'ed away */ 566 * on exec anyway and the important ones have been dup'ed away */
567 (void) close (tgt); 567 GNUNET_break (0 == close (tgt));
568 GNUNET_assert (-1 != dup2 (lscp[i], tgt)); 568 GNUNET_assert (-1 != dup2 (lscp[i], tgt));
569 } 569 }
570 /* unset close-on-exec flag */ 570 /* unset close-on-exec flag */
diff --git a/src/util/plugin.c b/src/util/plugin.c
index feb661f24..39874a588 100644
--- a/src/util/plugin.c
+++ b/src/util/plugin.c
@@ -447,8 +447,12 @@ GNUNET_PLUGIN_load_all_in_context (const struct GNUNET_OS_ProjectData *ctx,
447 void *cb_cls) 447 void *cb_cls)
448{ 448{
449 const struct GNUNET_OS_ProjectData *cpd = GNUNET_OS_project_data_get (); 449 const struct GNUNET_OS_ProjectData *cpd = GNUNET_OS_project_data_get ();
450
450 GNUNET_OS_init (ctx); 451 GNUNET_OS_init (ctx);
451 GNUNET_PLUGIN_load_all (basename, arg, cb, cb_cls); 452 GNUNET_PLUGIN_load_all (basename,
453 arg,
454 cb,
455 cb_cls);
452 GNUNET_OS_init (cpd); 456 GNUNET_OS_init (cpd);
453} 457}
454 458
diff --git a/src/util/program.c b/src/util/program.c
index e34b37370..b9da14572 100644
--- a/src/util/program.c
+++ b/src/util/program.c
@@ -140,7 +140,6 @@ GNUNET_PROGRAM_run2 (int argc,
140 char *loglev; 140 char *loglev;
141 char *logfile; 141 char *logfile;
142 char *cfg_fn; 142 char *cfg_fn;
143 const char *xdg;
144 enum GNUNET_GenericReturnValue ret; 143 enum GNUNET_GenericReturnValue ret;
145 int iret; 144 int iret;
146 unsigned int cnt; 145 unsigned int cnt;
@@ -149,12 +148,13 @@ GNUNET_PROGRAM_run2 (int argc,
149 long long clock_offset; 148 long long clock_offset;
150 struct GNUNET_CONFIGURATION_Handle *cfg; 149 struct GNUNET_CONFIGURATION_Handle *cfg;
151 const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get (); 150 const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
152 struct GNUNET_GETOPT_CommandLineOption defoptions[] = 151 struct GNUNET_GETOPT_CommandLineOption defoptions[] = {
153 { GNUNET_GETOPT_option_cfgfile (&cc.cfgfile), 152 GNUNET_GETOPT_option_cfgfile (&cc.cfgfile),
154 GNUNET_GETOPT_option_help (binaryHelp), 153 GNUNET_GETOPT_option_help (binaryHelp),
155 GNUNET_GETOPT_option_loglevel (&loglev), 154 GNUNET_GETOPT_option_loglevel (&loglev),
156 GNUNET_GETOPT_option_logfile (&logfile), 155 GNUNET_GETOPT_option_logfile (&logfile),
157 GNUNET_GETOPT_option_version (pd->version) }; 156 GNUNET_GETOPT_option_version (pd->version)
157 };
158 struct GNUNET_GETOPT_CommandLineOption *allopts; 158 struct GNUNET_GETOPT_CommandLineOption *allopts;
159 const char *gargs; 159 const char *gargs;
160 char *lpfx; 160 char *lpfx;
@@ -219,17 +219,7 @@ GNUNET_PROGRAM_run2 (int argc,
219 &cmd_sorter); 219 &cmd_sorter);
220 loglev = NULL; 220 loglev = NULL;
221 if ((NULL != pd->config_file) && (NULL != pd->user_config_file)) 221 if ((NULL != pd->config_file) && (NULL != pd->user_config_file))
222 { 222 cfg_fn = GNUNET_CONFIGURATION_default_filename ();
223 xdg = getenv ("XDG_CONFIG_HOME");
224 if (NULL != xdg)
225 GNUNET_asprintf (&cfg_fn,
226 "%s%s%s",
227 xdg,
228 DIR_SEPARATOR_STR,
229 pd->config_file);
230 else
231 cfg_fn = GNUNET_strdup (pd->user_config_file);
232 }
233 else 223 else
234 cfg_fn = NULL; 224 cfg_fn = NULL;
235 lpfx = GNUNET_strdup (binaryName); 225 lpfx = GNUNET_strdup (binaryName);
@@ -251,12 +241,26 @@ GNUNET_PROGRAM_run2 (int argc,
251 } 241 }
252 if (NULL != cc.cfgfile) 242 if (NULL != cc.cfgfile)
253 { 243 {
254 if ((GNUNET_YES != GNUNET_DISK_file_test (cc.cfgfile)) || 244 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
255 (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cc.cfgfile))) 245 "Loading configuration from entry point specified as option (%s)\n",
246 cc.cfgfile);
247 if (GNUNET_YES !=
248 GNUNET_DISK_file_test (cc.cfgfile))
256 { 249 {
257 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 250 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
258 _ ( 251 _ ("Unreadable configuration file `%s', exiting ...\n"),
259 "Unreadable or malformed configuration file `%s', exit ...\n"), 252 cc.cfgfile);
253 ret = GNUNET_SYSERR;
254 GNUNET_free (allopts);
255 GNUNET_free (lpfx);
256 goto cleanup;
257 }
258 if (GNUNET_SYSERR ==
259 GNUNET_CONFIGURATION_load (cfg,
260 cc.cfgfile))
261 {
262 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
263 _ ("Malformed configuration file `%s', exiting ...\n"),
260 cc.cfgfile); 264 cc.cfgfile);
261 ret = GNUNET_SYSERR; 265 ret = GNUNET_SYSERR;
262 GNUNET_free (allopts); 266 GNUNET_free (allopts);
@@ -266,34 +270,31 @@ GNUNET_PROGRAM_run2 (int argc,
266 } 270 }
267 else 271 else
268 { 272 {
269 if ((NULL != cfg_fn) && (GNUNET_YES == GNUNET_DISK_file_test (cfg_fn))) 273 if ( (NULL != cfg_fn) &&
274 (GNUNET_YES !=
275 GNUNET_DISK_file_test (cfg_fn)) )
270 { 276 {
271 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_fn)) 277 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
272 { 278 _ ("Unreadable configuration file `%s'. Exiting ...\n"),
273 GNUNET_log ( 279 cfg_fn);
274 GNUNET_ERROR_TYPE_ERROR, 280 ret = GNUNET_SYSERR;
275 _ ( 281 GNUNET_free (allopts);
276 "Unreadable or malformed default configuration file `%s', exit ...\n"), 282 GNUNET_free (lpfx);
277 cfg_fn); 283 goto cleanup;
278 ret = GNUNET_SYSERR;
279 GNUNET_free (allopts);
280 GNUNET_free (lpfx);
281 goto cleanup;
282 }
283 } 284 }
284 else if (NULL != cfg_fn) 285 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
286 "Loading configuration from entry point `%s'\n",
287 cc.cfgfile);
288 if (GNUNET_SYSERR ==
289 GNUNET_CONFIGURATION_load (cfg,
290 cfg_fn))
285 { 291 {
286 GNUNET_free (cfg_fn); 292 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
287 cfg_fn = NULL; 293 _ ("Malformed configuration. Exiting ...\n"));
288 if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, NULL)) 294 ret = GNUNET_SYSERR;
289 { 295 GNUNET_free (allopts);
290 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 296 GNUNET_free (lpfx);
291 _ ("Unreadable or malformed configuration, exit ...\n")); 297 goto cleanup;
292 ret = GNUNET_SYSERR;
293 GNUNET_free (allopts);
294 GNUNET_free (lpfx);
295 goto cleanup;
296 }
297 } 298 }
298 } 299 }
299 GNUNET_free (allopts); 300 GNUNET_free (allopts);
diff --git a/src/util/strings.c b/src/util/strings.c
index 24335e444..673915888 100644
--- a/src/util/strings.c
+++ b/src/util/strings.c
@@ -1600,7 +1600,7 @@ GNUNET_STRINGS_base64_encode (const void *in,
1600 char *opt; 1600 char *opt;
1601 1601
1602 ret = 0; 1602 ret = 0;
1603 GNUNET_assert (len / 4 < SIZE_MAX); 1603 GNUNET_assert (len < SIZE_MAX / 4 * 3 );
1604 opt = GNUNET_malloc (2 + (len * 4 / 3) + 8); 1604 opt = GNUNET_malloc (2 + (len * 4 / 3) + 8);
1605 for (size_t i = 0; i < len; ++i) 1605 for (size_t i = 0; i < len; ++i)
1606 { 1606 {
diff --git a/src/util/test_plugin.c b/src/util/test_plugin.c
index c0eb717d6..e739d17c9 100644
--- a/src/util/test_plugin.c
+++ b/src/util/test_plugin.c
@@ -26,15 +26,22 @@
26 26
27 27
28static void 28static void
29test_cb (void *cls, const char *libname, void *lib_ret) 29test_cb (void *cls,
30 const char *libname,
31 void *lib_ret)
30{ 32{
31 void *ret; 33 const char *test_cls = cls;
34 char *ret;
32 35
33 GNUNET_assert (0 == strcmp (cls, "test")); 36 GNUNET_assert (0 == strcmp (test_cls,
34 GNUNET_assert (0 == strcmp (lib_ret, "Hello")); 37 "test-closure"));
35 ret = GNUNET_PLUGIN_unload (libname, "out"); 38 GNUNET_assert (0 == strcmp (lib_ret,
39 "Hello"));
40 ret = GNUNET_PLUGIN_unload (libname,
41 "out");
36 GNUNET_assert (NULL != ret); 42 GNUNET_assert (NULL != ret);
37 GNUNET_assert (0 == strcmp (ret, "World")); 43 GNUNET_assert (0 == strcmp (ret,
44 "World"));
38 free (ret); 45 free (ret);
39} 46}
40 47
@@ -44,24 +51,35 @@ main (int argc, char *argv[])
44{ 51{
45 void *ret; 52 void *ret;
46 53
47 GNUNET_log_setup ("test-plugin", "WARNING", NULL); 54 GNUNET_log_setup ("test-plugin",
48 GNUNET_log_skip (1, GNUNET_NO); 55 "WARNING",
49 ret = GNUNET_PLUGIN_load ("libgnunet_plugin_missing", NULL); 56 NULL);
57 GNUNET_log_skip (1,
58 GNUNET_NO);
59 ret = GNUNET_PLUGIN_load ("libgnunet_plugin_missing",
60 NULL);
50 GNUNET_log_skip (0, GNUNET_NO); 61 GNUNET_log_skip (0, GNUNET_NO);
51 if (ret != NULL) 62 if (NULL != ret)
52 return 1; 63 return 1;
53 ret = GNUNET_PLUGIN_load ("libgnunet_plugin_test", "in"); 64 ret = GNUNET_PLUGIN_load ("libgnunet_plugin_utiltest",
54 if (ret == NULL) 65 "in");
66 if (NULL == ret)
55 return 1; 67 return 1;
56 if (0 != strcmp (ret, "Hello")) 68 if (0 != strcmp (ret,
69 "Hello"))
57 return 2; 70 return 2;
58 ret = GNUNET_PLUGIN_unload ("libgnunet_plugin_test", "out"); 71 ret = GNUNET_PLUGIN_unload ("libgnunet_plugin_utiltest",
59 if (ret == NULL) 72 "out");
73 if (NULL == ret)
60 return 3; 74 return 3;
61 if (0 != strcmp (ret, "World")) 75 if (0 != strcmp (ret,
76 "World"))
62 return 4; 77 return 4;
63 free (ret); 78 free (ret);
64 GNUNET_PLUGIN_load_all ("libgnunet_plugin_tes", "in", &test_cb, "test"); 79 GNUNET_PLUGIN_load_all ("libgnunet_plugin_utiltes",
80 "in",
81 &test_cb,
82 "test-closure");
65 return 0; 83 return 0;
66} 84}
67 85
diff --git a/src/util/test_plugin_plug.c b/src/util/test_plugin_plug.c
index 39c8774b1..bfaad52e8 100644
--- a/src/util/test_plugin_plug.c
+++ b/src/util/test_plugin_plug.c
@@ -23,8 +23,9 @@
23 */ 23 */
24#include "platform.h" 24#include "platform.h"
25 25
26
26void * 27void *
27libgnunet_plugin_test_init (void *arg) 28libgnunet_plugin_utiltest_init (void *arg)
28{ 29{
29 if (0 == strcmp (arg, "in")) 30 if (0 == strcmp (arg, "in"))
30 return "Hello"; 31 return "Hello";
@@ -33,7 +34,7 @@ libgnunet_plugin_test_init (void *arg)
33 34
34 35
35void * 36void *
36libgnunet_plugin_test_done (void *arg) 37libgnunet_plugin_utiltest_done (void *arg)
37{ 38{
38 if (0 == strcmp (arg, "out")) 39 if (0 == strcmp (arg, "out"))
39 return strdup ("World"); 40 return strdup ("World");
diff --git a/src/vpn/Makefile.am b/src/vpn/Makefile.am
index d1ecd9f98..a5bbb6e22 100644
--- a/src/vpn/Makefile.am
+++ b/src/vpn/Makefile.am
@@ -31,7 +31,10 @@ bin_PROGRAMS = \
31 gnunet-vpn 31 gnunet-vpn
32 32
33gnunet_helper_vpn_SOURCES = \ 33gnunet_helper_vpn_SOURCES = \
34gnunet-helper-vpn.c 34 gnunet-helper-vpn.c
35gnunet_helper_vpn_LDADD = \
36 $(top_builddir)/src/util/libgnunetutil.la \
37 $(GN_LIBINTL)
35 38
36gnunet_service_vpn_SOURCES = \ 39gnunet_service_vpn_SOURCES = \
37 gnunet-service-vpn.c 40 gnunet-service-vpn.c
diff --git a/src/vpn/gnunet-helper-vpn.c b/src/vpn/gnunet-helper-vpn.c
index 7eeb07379..7686d51d5 100644
--- a/src/vpn/gnunet-helper-vpn.c
+++ b/src/vpn/gnunet-helper-vpn.c
@@ -246,7 +246,8 @@ set_address6 (const char *dev,
246 if (0 != close (fd)) 246 if (0 != close (fd))
247 { 247 {
248 fprintf (stderr, 248 fprintf (stderr,
249 "close failed: %s\n", 249 "close failed at line %d: %s\n",
250 __LINE__,
250 strerror (errno)); 251 strerror (errno));
251 exit (1); 252 exit (1);
252 } 253 }
@@ -367,9 +368,9 @@ set_address4 (const char *dev,
367 if (0 != close (fd)) 368 if (0 != close (fd))
368 { 369 {
369 fprintf (stderr, 370 fprintf (stderr,
370 "close failed: %s\n", 371 "close failed at line %d: %s\n",
372 __LINE__,
371 strerror (errno)); 373 strerror (errno));
372 (void) close (fd);
373 exit (1); 374 exit (1);
374 } 375 }
375} 376}
@@ -653,7 +654,7 @@ main (int argc, char **argv)
653 { 654 {
654 fprintf (stderr, 655 fprintf (stderr,
655 "Fatal: prefix_len out of range\n"); 656 "Fatal: prefix_len out of range\n");
656 close (fd_tun); 657 (void) close (fd_tun);
657 return 1; 658 return 1;
658 } 659 }
659 660
@@ -701,6 +702,6 @@ main (int argc, char **argv)
701 run (fd_tun); 702 run (fd_tun);
702 global_ret = 0; 703 global_ret = 0;
703cleanup: 704cleanup:
704 close (fd_tun); 705 (void) close (fd_tun);
705 return global_ret; 706 return global_ret;
706} 707}