diff options
Diffstat (limited to 'src')
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 @@ | |||
3 | if HAVE_TESTING | 3 | if HAVE_TESTING |
4 | TESTING = testing | 4 | TESTING = testing |
5 | TESTBED = testbed-logger testbed | 5 | TESTBED = testbed-logger testbed |
6 | ATS_TESTS = ats-tests | ||
7 | endif | 6 | endif |
8 | 7 | ||
9 | if HAVE_EXPERIMENTAL | 8 | if 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 @@ | |||
1 | gnunet-solver-eval | ||
2 | gnunet-ats-sim | ||
3 | perf_ats_proportional_core_bandwidth | ||
4 | perf_ats_proportional_core_latency | ||
5 | perf_ats_proportional_core_none | ||
6 | perf_ats_proportional_transport_bandwidth | ||
7 | perf_ats_proportional_transport_latency | ||
8 | perf_ats_proportional_transport_none | ||
9 | perf_ats_mlp_core_bandwidth | ||
10 | perf_ats_mlp_core_latency | ||
11 | perf_ats_mlp_core_none | ||
12 | perf_ats_mlp_transport_bandwidth | ||
13 | perf_ats_mlp_transport_latency | ||
14 | perf_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 | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | ||
3 | |||
4 | pkgcfgdir= $(pkgdatadir)/config.d/ | ||
5 | |||
6 | libexecdir= $(pkglibdir)/libexec/ | ||
7 | |||
8 | if USE_COVERAGE | ||
9 | AM_CFLAGS = -fprofile-arcs -ftest-coverage | ||
10 | endif | ||
11 | |||
12 | if HAVE_TESTING | ||
13 | TESTING_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 | |||
22 | endif | ||
23 | |||
24 | lib_LTLIBRARIES = \ | ||
25 | libgnunetatstesting.la | ||
26 | |||
27 | check_PROGRAMS = \ | ||
28 | $(TESTING_TESTS) | ||
29 | |||
30 | if ENABLE_TEST_RUN | ||
31 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | ||
32 | TESTS = $(check_PROGRAMS) | ||
33 | endif | ||
34 | |||
35 | noinst_PROGRAMS = \ | ||
36 | gnunet-ats-sim gnunet-solver-eval | ||
37 | |||
38 | libgnunetatstesting_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 | ||
42 | libgnunetatstesting_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) | ||
53 | libgnunetatstesting_la_DEPENDENCIES = \ | ||
54 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
55 | $(top_builddir)/src/ats/libgnunetats.la | ||
56 | libgnunetatstesting_la_LDFLAGS = \ | ||
57 | $(GN_LIB_LDFLAGS) | ||
58 | |||
59 | gnunet_ats_sim_SOURCES = \ | ||
60 | gnunet-ats-sim.c | ||
61 | gnunet_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 | ||
68 | gnunet_ats_sim_DEPENDENCIES = \ | ||
69 | libgnunetatstesting.la \ | ||
70 | $(top_builddir)/src/util/libgnunetutil.la | ||
71 | gnunet_ats_sim_LDFLAGS = \ | ||
72 | $(GN_LIBINTL) | ||
73 | |||
74 | |||
75 | gnunet_solver_eval_SOURCES = \ | ||
76 | gnunet-solver-eval.c | ||
77 | gnunet_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 | ||
82 | gnunet_solver_eval_DEPENDENCIES = \ | ||
83 | $(top_builddir)/src/util/libgnunetutil.la | ||
84 | gnunet_solver_eval_LDFLAGS = \ | ||
85 | $(GN_LIBINTL) | ||
86 | |||
87 | perf_ats_proportional_core_none_SOURCES = \ | ||
88 | perf_ats.c | ||
89 | perf_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 | ||
96 | perf_ats_proportional_core_none_DEPENDENCIES = \ | ||
97 | libgnunetatstesting.la \ | ||
98 | $(top_builddir)/src/util/libgnunetutil.la | ||
99 | |||
100 | perf_ats_proportional_transport_none_SOURCES = \ | ||
101 | perf_ats.c | ||
102 | perf_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 | ||
109 | perf_ats_proportional_transport_none_DEPENDENCIES = \ | ||
110 | libgnunetatstesting.la \ | ||
111 | $(top_builddir)/src/util/libgnunetutil.la | ||
112 | |||
113 | perf_ats_proportional_core_bandwidth_SOURCES = \ | ||
114 | perf_ats.c | ||
115 | perf_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 | ||
122 | perf_ats_proportional_core_bandwidth_DEPENDENCIES = \ | ||
123 | libgnunetatstesting.la \ | ||
124 | $(top_builddir)/src/util/libgnunetutil.la | ||
125 | |||
126 | perf_ats_proportional_transport_bandwidth_SOURCES = \ | ||
127 | perf_ats.c | ||
128 | perf_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 | ||
135 | perf_ats_proportional_transport_bandwidth_DEPENDENCIES = \ | ||
136 | libgnunetatstesting.la \ | ||
137 | $(top_builddir)/src/util/libgnunetutil.la | ||
138 | |||
139 | perf_ats_proportional_core_latency_SOURCES = \ | ||
140 | perf_ats.c | ||
141 | perf_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 | ||
148 | perf_ats_proportional_core_latency_DEPENDENCIES = \ | ||
149 | libgnunetatstesting.la \ | ||
150 | $(top_builddir)/src/util/libgnunetutil.la | ||
151 | |||
152 | perf_ats_proportional_transport_latency_SOURCES = \ | ||
153 | perf_ats.c | ||
154 | perf_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 | ||
161 | perf_ats_proportional_transport_latency_DEPENDENCIES = \ | ||
162 | libgnunetatstesting.la \ | ||
163 | $(top_builddir)/src/util/libgnunetutil.la | ||
164 | |||
165 | EXTRA_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 | |||
30 | const char * | ||
31 | print_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 | |||
54 | static struct Experiment * | ||
55 | create_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 | |||
69 | static void | ||
70 | free_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 | |||
97 | static int | ||
98 | load_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 | |||
399 | static int | ||
400 | load_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 | |||
456 | static void | ||
457 | timeout_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 | |||
475 | static void | ||
476 | enforce_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 | |||
514 | static void | ||
515 | enforce_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 | |||
538 | static void | ||
539 | enforce_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 | |||
578 | static void | ||
579 | enforce_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 | |||
602 | static void | ||
603 | enforce_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 | |||
636 | static void | ||
637 | timeout_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 | |||
672 | void | ||
673 | GNUNET_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 | |||
703 | struct Experiment * | ||
704 | GNUNET_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 | |||
803 | void | ||
804 | GNUNET_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 | */ | ||
75 | struct 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 | */ | ||
146 | struct 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 | */ | ||
202 | struct 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 | |||
225 | struct 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 | |||
249 | static void | ||
250 | write_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 | |||
324 | static void | ||
325 | write_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 | |||
383 | static void | ||
384 | write_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 | |||
446 | void | ||
447 | GNUNET_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 | */ | ||
676 | void | ||
677 | GNUNET_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 | |||
867 | static void | ||
868 | collect_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 | */ | ||
885 | void | ||
886 | GNUNET_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 | */ | ||
908 | void | ||
909 | GNUNET_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 | */ | ||
943 | struct LoggingHandle * | ||
944 | GNUNET_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 | |||
30 | static struct PreferenceGenerator *pg_head; | ||
31 | static struct PreferenceGenerator *pg_tail; | ||
32 | |||
33 | extern struct GNUNET_ATS_TEST_Topology *top; | ||
34 | |||
35 | static double | ||
36 | get_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 | |||
102 | static void | ||
103 | set_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 | */ | ||
156 | struct PreferenceGenerator * | ||
157 | GNUNET_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 | |||
231 | void | ||
232 | GNUNET_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 | */ | ||
250 | void | ||
251 | GNUNET_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 | |||
30 | static struct TrafficGenerator *tg_head; | ||
31 | static struct TrafficGenerator *tg_tail; | ||
32 | |||
33 | extern struct GNUNET_ATS_TEST_Topology *top; | ||
34 | |||
35 | static struct GNUNET_TIME_Relative | ||
36 | get_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 | |||
117 | static void | ||
118 | update_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 | |||
144 | static void | ||
145 | comm_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 | |||
170 | static void | ||
171 | update_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 | |||
182 | void | ||
183 | GNUNET_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 | |||
211 | void | ||
212 | GNUNET_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 | */ | ||
272 | struct TrafficGenerator * | ||
273 | GNUNET_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 | |||
359 | void | ||
360 | GNUNET_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 | */ | ||
378 | void | ||
379 | GNUNET_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 | */ | ||
33 | struct 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 | |||
51 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
52 | |||
53 | struct GNUNET_ATS_TEST_Topology *top; | ||
54 | |||
55 | |||
56 | /** | ||
57 | * Shutdown nicely | ||
58 | * | ||
59 | * @param cls NULL | ||
60 | */ | ||
61 | static void | ||
62 | do_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 | |||
145 | static struct BenchmarkPartner * | ||
146 | find_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 | |||
165 | static struct BenchmarkPeer * | ||
166 | find_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 | */ | ||
195 | static void * | ||
196 | comm_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 | */ | ||
272 | static void | ||
273 | comm_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 | |||
305 | static void | ||
306 | handle_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 | |||
315 | static void | ||
316 | handle_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 | |||
325 | static void * | ||
326 | transport_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 | |||
356 | static void | ||
357 | transport_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 | |||
367 | static void * | ||
368 | core_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 | |||
397 | static void | ||
398 | core_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 | |||
408 | static void | ||
409 | connect_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 | |||
446 | static void | ||
447 | do_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 | |||
495 | static void | ||
496 | comm_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 | |||
525 | static void | ||
526 | do_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 | |||
588 | static void | ||
589 | ats_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 | |||
649 | static void * | ||
650 | ats_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 | |||
666 | static void | ||
667 | ats_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 | |||
677 | static void | ||
678 | ats_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 | |||
705 | static void | ||
706 | do_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 | |||
741 | static void | ||
742 | peerinformation_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 | */ | ||
785 | static void | ||
786 | main_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 | */ | ||
874 | static void | ||
875 | controller_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 | |||
893 | struct BenchmarkPeer * | ||
894 | GNUNET_ATS_TEST_get_peer (int src) | ||
895 | { | ||
896 | if (src > top->num_masters) | ||
897 | return NULL; | ||
898 | return &top->mps[src]; | ||
899 | } | ||
900 | |||
901 | |||
902 | struct BenchmarkPartner * | ||
903 | GNUNET_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 | */ | ||
926 | void | ||
927 | GNUNET_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 | */ | ||
966 | void | ||
967 | GNUNET_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 | |||
51 | struct TestMessage | ||
52 | { | ||
53 | struct GNUNET_MessageHeader header; | ||
54 | |||
55 | uint8_t padding[TEST_MESSAGE_SIZE - sizeof(struct GNUNET_MessageHeader)]; | ||
56 | }; | ||
57 | |||
58 | |||
59 | struct BenchmarkPartner; | ||
60 | |||
61 | struct BenchmarkPeer; | ||
62 | |||
63 | struct GNUNET_ATS_TEST_Topology; | ||
64 | |||
65 | struct TrafficGenerator; | ||
66 | |||
67 | struct LoggingHandle; | ||
68 | |||
69 | enum 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 | */ | ||
85 | typedef 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 | */ | ||
100 | typedef 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 | */ | ||
111 | struct 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 | |||
230 | struct 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 | |||
250 | struct 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 | */ | ||
275 | struct 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 | */ | ||
362 | struct 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 | |||
391 | struct 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 | |||
470 | enum OperationType | ||
471 | { | ||
472 | START_SEND, | ||
473 | STOP_SEND, | ||
474 | START_PREFERENCE, | ||
475 | STOP_PREFERENCE | ||
476 | }; | ||
477 | |||
478 | struct Episode; | ||
479 | |||
480 | struct Experiment; | ||
481 | |||
482 | typedef void (*GNUNET_ATS_TESTING_EpisodeDoneCallback) (struct Episode *e); | ||
483 | |||
484 | typedef 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 | */ | ||
492 | struct 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 | |||
510 | struct 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 | |||
521 | struct 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 | |||
543 | extern 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 | */ | ||
552 | void | ||
553 | GNUNET_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 | */ | ||
565 | struct Experiment * | ||
566 | GNUNET_ATS_TEST_experimentation_load (const char *filename); | ||
567 | |||
568 | |||
569 | /** | ||
570 | * Stop an experiment | ||
571 | * | ||
572 | * @param e the experiment | ||
573 | */ | ||
574 | void | ||
575 | GNUNET_ATS_TEST_experimentation_stop (struct Experiment *e); | ||
576 | |||
577 | |||
578 | void | ||
579 | GNUNET_ATS_TEST_traffic_handle_ping (struct BenchmarkPartner *p); | ||
580 | |||
581 | |||
582 | void | ||
583 | GNUNET_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 | */ | ||
599 | struct TrafficGenerator * | ||
600 | GNUNET_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 | |||
609 | void | ||
610 | GNUNET_ATS_TEST_generate_traffic_stop (struct TrafficGenerator *tg); | ||
611 | |||
612 | |||
613 | /** | ||
614 | * Stop all traffic generators | ||
615 | */ | ||
616 | void | ||
617 | GNUNET_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 | */ | ||
634 | struct PreferenceGenerator * | ||
635 | GNUNET_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 | |||
646 | void | ||
647 | GNUNET_ATS_TEST_generate_preferences_stop (struct PreferenceGenerator *pg); | ||
648 | |||
649 | |||
650 | void | ||
651 | GNUNET_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 | */ | ||
665 | struct LoggingHandle * | ||
666 | GNUNET_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 | */ | ||
679 | void | ||
680 | GNUNET_ATS_TEST_logging_clean_up (struct LoggingHandle *l); | ||
681 | |||
682 | |||
683 | /** | ||
684 | * Stop logging | ||
685 | * | ||
686 | * @param l the logging handle | ||
687 | */ | ||
688 | void | ||
689 | GNUNET_ATS_TEST_logging_stop (struct LoggingHandle *l); | ||
690 | |||
691 | |||
692 | /** | ||
693 | * Log all data now | ||
694 | * | ||
695 | * @param l logging handle to use | ||
696 | */ | ||
697 | void | ||
698 | GNUNET_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 | */ | ||
708 | void | ||
709 | GNUNET_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 | */ | ||
717 | struct BenchmarkPeer * | ||
718 | GNUNET_ATS_TEST_get_peer (int src); | ||
719 | |||
720 | |||
721 | struct BenchmarkPartner * | ||
722 | GNUNET_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 | */ | ||
738 | void | ||
739 | GNUNET_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 | */ | ||
753 | void | ||
754 | GNUNET_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] | ||
4 | plugins = unix | ||
5 | |||
6 | [ats] | ||
7 | MODE = MLP | ||
8 | UNSPECIFIED_QUOTA_IN = 128 KiB | ||
9 | UNSPECIFIED_QUOTA_OUT = 128 KiB | ||
10 | # LOOPBACK | ||
11 | LOOPBACK_QUOTA_IN = 128 KiB | ||
12 | LOOPBACK_QUOTA_OUT = 128 KiB | ||
13 | # LAN | ||
14 | LAN_QUOTA_IN = 128 KiB | ||
15 | LAN_QUOTA_OUT = 128 KiB | ||
16 | # WAN | ||
17 | WAN_QUOTA_IN = 128 KiB | ||
18 | WAN_QUOTA_OUT = 128 KiB | ||
19 | # WLAN | ||
20 | WLAN_QUOTA_IN = 128 KiB | ||
21 | WLAN_QUOTA_OUT = 128 KiB | ||
22 | # BLUETOOTH | ||
23 | BLUETOOTH_QUOTA_IN = 128 KiB | ||
24 | BLUETOOTH_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] | ||
2 | name = sc1_eval_dru_prop | ||
3 | masters = 1 | ||
4 | slaves = 3 | ||
5 | max_duration = 20 s | ||
6 | log_freq = 100 ms | ||
7 | cfg_file = experiments/evaluation1_dru_3_peers_1addr_1scope_prop.conf | ||
8 | |||
9 | [episode-0] | ||
10 | # operations = start_send, stop_send, start_preference, stop_preference | ||
11 | duration = 10 s | ||
12 | op-0-operation = start_send | ||
13 | op-0-src = 0 | ||
14 | op-0-dest = 0 | ||
15 | op-0-type = constant | ||
16 | #op-0-period = 10 s | ||
17 | op-0-base-rate= 10000 | ||
18 | #op-0-max-rate = 10000 | ||
19 | |||
20 | op-1-operation = start_send | ||
21 | op-1-src = 0 | ||
22 | op-1-dest = 1 | ||
23 | op-1-type = constant | ||
24 | #op-1-period = 10 s | ||
25 | op-1-base-rate= 10000 | ||
26 | #op-1-max-rate = 10000 | ||
27 | |||
28 | op-2-operation = start_send | ||
29 | op-2-src = 0 | ||
30 | op-2-dest = 2 | ||
31 | op-2-type = constant | ||
32 | #op-1-period = 10 s | ||
33 | op-2-base-rate= 10000 | ||
34 | #op-1-max-rate = 10000 | ||
35 | |||
36 | [episode-1] | ||
37 | duration = 10 s | ||
38 | op-0-operation = start_preference | ||
39 | op-0-src = 0 | ||
40 | op-0-dest = 2 | ||
41 | op-0-type = constant | ||
42 | #op-0-period = 10 s | ||
43 | op-0-pref = bandwidth | ||
44 | op-0-frequency = 1 s | ||
45 | op-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 | ||
10 | duration = 2 s | ||
11 | op-0-operation = set_rate | ||
12 | op-0-src = 0 | ||
13 | op-0-dest = 0 | ||
14 | op-0-type = constant | ||
15 | op-0-base-rate= 10000 | ||
16 | op-0-max-rate = 10000 | ||
17 | |||
18 | op-1-operation = set_rate | ||
19 | op-1-src = 0 | ||
20 | op-1-dest = 1 | ||
21 | op-1-type = constant | ||
22 | op-1-base-rate= 10000 | ||
23 | op-1-max-rate = 10000 | ||
24 | |||
25 | op-2-operation = set_rate | ||
26 | op-2-src = 0 | ||
27 | op-2-dest = 2 | ||
28 | op-2-type = constant | ||
29 | op-2-base-rate= 10000 | ||
30 | op-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 | ||
11 | duration = 10 s | ||
12 | op-0-operation = start_send | ||
13 | op-0-src = 0 | ||
14 | op-0-dest = 0 | ||
15 | op-0-type = constant | ||
16 | op-0-base-rate= 10000 | ||
17 | op-0-max-rate = 10000 | ||
18 | |||
19 | op-1-operation = start_send | ||
20 | op-1-src = 0 | ||
21 | op-1-dest = 1 | ||
22 | op-1-type = sinus | ||
23 | op-1-period = 5 s | ||
24 | op-1-base-rate= 10000 | ||
25 | op-1-max-rate = 15000 | ||
26 | |||
27 | op-2-operation = start_preference | ||
28 | op-2-src = 0 | ||
29 | op-2-dest = 0 | ||
30 | op-2-type = constant | ||
31 | op-2-period = 5 s | ||
32 | op-2-base-rate= 10 | ||
33 | op-2-max-rate = 5 | ||
34 | op-2-pref = latency | ||
35 | op-2-frequency = 2 s | ||
36 | |||
37 | op-3-operation = start_preference | ||
38 | op-3-src = 0 | ||
39 | op-3-dest = 1 | ||
40 | op-3-type = linear | ||
41 | op-3-period = 5 s | ||
42 | op-3-base-rate= 40 | ||
43 | op-3-max-rate = 50 | ||
44 | op-3-pref = bandwidth | ||
45 | op-3-frequency = 750 ms | ||
46 | |||
47 | [episode-1] | ||
48 | duration = 5 s | ||
49 | op-0-operation = stop_preference | ||
50 | op-0-src = 0 | ||
51 | op-0-dest = 0 | ||
52 | |||
53 | op-1-operation = stop_preference | ||
54 | op-1-src = 0 | ||
55 | op-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 | |||
38 | static struct BenchmarkPeer *masters_p; | ||
39 | static struct BenchmarkPeer *slaves_p; | ||
40 | |||
41 | /** | ||
42 | * cmd option -e: experiment file | ||
43 | */ | ||
44 | static char *opt_exp_file; | ||
45 | |||
46 | /** | ||
47 | * cmd option -l: enable logging | ||
48 | */ | ||
49 | static int opt_log; | ||
50 | |||
51 | /** | ||
52 | * cmd option -p: enable plots | ||
53 | */ | ||
54 | static int opt_plot; | ||
55 | |||
56 | /** | ||
57 | * cmd option -v: verbose logs | ||
58 | */ | ||
59 | static int opt_verbose; | ||
60 | |||
61 | static struct GNUNET_SCHEDULER_Task *timeout_task; | ||
62 | |||
63 | static struct Experiment *e; | ||
64 | |||
65 | static struct LoggingHandle *l; | ||
66 | |||
67 | |||
68 | static void | ||
69 | evaluate (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 | |||
138 | static void | ||
139 | do_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 | |||
169 | static void | ||
170 | do_timeout (void *cls) | ||
171 | { | ||
172 | timeout_task = NULL; | ||
173 | GNUNET_SCHEDULER_shutdown (); | ||
174 | } | ||
175 | |||
176 | |||
177 | static void | ||
178 | log_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 | |||
193 | static void | ||
194 | experiment_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 | |||
222 | static void | ||
223 | episode_done_cb (struct Episode *ep) | ||
224 | { | ||
225 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
226 | "Episode %u done\n", | ||
227 | ep->id); | ||
228 | } | ||
229 | |||
230 | |||
231 | static void | ||
232 | topology_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 | |||
329 | static void | ||
330 | parse_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 | |||
361 | int | ||
362 | main (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 | */ | ||
36 | const char * | ||
37 | print_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 | |||
60 | static struct Experiment * | ||
61 | create_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 | |||
75 | static void | ||
76 | free_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 | |||
103 | static int | ||
104 | load_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 | |||
412 | static int | ||
413 | load_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 | |||
469 | static void | ||
470 | timeout_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 | |||
488 | static void | ||
489 | enforce_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 | |||
524 | static void | ||
525 | enforce_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 | |||
548 | static void | ||
549 | enforce_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 | |||
585 | static void | ||
586 | enforce_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 | |||
609 | static void | ||
610 | enforce_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 | |||
643 | static void | ||
644 | timeout_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 | |||
679 | void | ||
680 | GNUNET_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 | |||
710 | struct Experiment * | ||
711 | GNUNET_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 | |||
810 | void | ||
811 | GNUNET_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 | |||
831 | struct GNUNET_ATS_TESTING_SolverHandle | ||
832 | { | ||
833 | char *plugin; | ||
834 | struct GNUNET_ATS_PluginEnvironment env; | ||
835 | void *solver; | ||
836 | }; | ||
837 | |||
838 | enum GNUNET_ATS_Solvers | ||
839 | { | ||
840 | GNUNET_ATS_SOLVER_PROPORTIONAL, | ||
841 | GNUNET_ATS_SOLVER_MLP, | ||
842 | GNUNET_ATS_SOLVER_RIL, | ||
843 | }; | ||
844 | |||
845 | void | ||
846 | GNUNET_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 | |||
854 | struct GNUNET_ATS_TESTING_SolverHandle * | ||
855 | GNUNET_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 | |||
893 | static struct Experiment *e; | ||
894 | |||
895 | static struct GNUNET_ATS_TESTING_SolverHandle *sh; | ||
896 | |||
897 | /** | ||
898 | * cmd option -e: experiment file | ||
899 | */ | ||
900 | static char *opt_exp_file; | ||
901 | |||
902 | static char *opt_solver; | ||
903 | |||
904 | /** | ||
905 | * cmd option -l: enable logging | ||
906 | */ | ||
907 | static int opt_log; | ||
908 | |||
909 | /** | ||
910 | * cmd option -p: enable plots | ||
911 | */ | ||
912 | static int opt_plot; | ||
913 | |||
914 | /** | ||
915 | * cmd option -v: verbose logs | ||
916 | */ | ||
917 | static int opt_verbose; | ||
918 | |||
919 | static void | ||
920 | run (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 | */ | ||
985 | int | ||
986 | main (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] | ||
3 | plugins = unix | ||
4 | |||
5 | [ats] | ||
6 | MODE = 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 | */ | ||
55 | static struct GNUNET_SCHEDULER_Task *timeout_task; | ||
56 | |||
57 | /** | ||
58 | * Progress task | ||
59 | */ | ||
60 | static struct GNUNET_SCHEDULER_Task *progress_task; | ||
61 | |||
62 | /** | ||
63 | * Test result | ||
64 | */ | ||
65 | static int result; | ||
66 | |||
67 | /** | ||
68 | * Test result logging | ||
69 | */ | ||
70 | static int logging; | ||
71 | |||
72 | /** | ||
73 | * Test core (#GNUNET_YES) or transport (#GNUNET_NO) | ||
74 | */ | ||
75 | static int test_core; | ||
76 | |||
77 | /** | ||
78 | * Solver string | ||
79 | */ | ||
80 | static char *solver; | ||
81 | |||
82 | /** | ||
83 | * Preference string | ||
84 | */ | ||
85 | static char *testname; | ||
86 | |||
87 | /** | ||
88 | * Preference string | ||
89 | */ | ||
90 | static char *pref_str; | ||
91 | |||
92 | /** | ||
93 | * ATS preference value | ||
94 | */ | ||
95 | static int pref_val; | ||
96 | |||
97 | /** | ||
98 | * Benchmark duration | ||
99 | */ | ||
100 | static struct GNUNET_TIME_Relative perf_duration; | ||
101 | |||
102 | /** | ||
103 | * Logging frequency | ||
104 | */ | ||
105 | static struct GNUNET_TIME_Relative log_frequency; | ||
106 | |||
107 | /** | ||
108 | * Number master peers | ||
109 | */ | ||
110 | static unsigned int num_masters; | ||
111 | |||
112 | /** | ||
113 | * Array of master peers | ||
114 | */ | ||
115 | static struct BenchmarkPeer *mps; | ||
116 | |||
117 | /** | ||
118 | * Number slave peers | ||
119 | */ | ||
120 | static unsigned int num_slaves; | ||
121 | |||
122 | /** | ||
123 | * Array of master peers | ||
124 | */ | ||
125 | static struct BenchmarkPeer *sps; | ||
126 | |||
127 | static struct LoggingHandle *l; | ||
128 | |||
129 | |||
130 | static void | ||
131 | evaluate () | ||
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 | */ | ||
198 | static void | ||
199 | do_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 | */ | ||
225 | static void | ||
226 | do_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 | |||
236 | static void | ||
237 | print_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 | |||
254 | static void | ||
255 | ats_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 | |||
274 | static void | ||
275 | start_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 | |||
312 | static void | ||
313 | do_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 | |||
329 | static struct BenchmarkPartner * | ||
330 | find_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 | |||
350 | static void | ||
351 | log_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 | */ | ||
392 | int | ||
393 | main (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 | */ | ||
57 | struct 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 | */ | ||
136 | struct 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 | */ | ||
75 | static struct GNUNET_SCHEDULER_Task *log_task; | ||
76 | |||
77 | /** | ||
78 | * Reference to perf_ats' masters | ||
79 | */ | ||
80 | static int num_peers; | ||
81 | static int running; | ||
82 | static char *name; | ||
83 | static struct GNUNET_TIME_Relative frequency; | ||
84 | |||
85 | /** | ||
86 | * A single logging time step for a partner | ||
87 | */ | ||
88 | struct 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 | */ | ||
162 | struct 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 | */ | ||
218 | struct 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 | */ | ||
244 | static struct LoggingPeer *lp; | ||
245 | |||
246 | |||
247 | static void | ||
248 | write_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 | |||
319 | static void | ||
320 | write_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 | |||
376 | static void | ||
377 | write_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 | |||
437 | static void | ||
438 | write_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 | |||
555 | void | ||
556 | collect_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 | |||
707 | static void | ||
708 | collect_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 | |||
717 | void | ||
718 | perf_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 | |||
752 | void | ||
753 | perf_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] | ||
4 | MODE = 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] | ||
4 | MODE = 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] | ||
4 | MODE = 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? | ||
5 | OPERATION_TIMEOUT = 60 s | ||
6 | |||
7 | [transport-udp] | ||
8 | BROADCAST = NO | ||
9 | |||
10 | [peerinfo] | ||
11 | USE_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 | ||
20 | UNSPECIFIED_QUOTA_IN = 128 KiB | ||
21 | UNSPECIFIED_QUOTA_OUT = 128 KiB | ||
22 | # LOOPBACK | ||
23 | LOOPBACK_QUOTA_IN = 128 KiB | ||
24 | LOOPBACK_QUOTA_OUT = 128 KiB | ||
25 | # LAN | ||
26 | LAN_QUOTA_IN = 128 KiB | ||
27 | LAN_QUOTA_OUT = 128 KiB | ||
28 | # WAN | ||
29 | WAN_QUOTA_IN = 128 KiB | ||
30 | WAN_QUOTA_OUT = 128 KiB | ||
31 | # WLAN | ||
32 | WLAN_QUOTA_IN = 128 KiB | ||
33 | WLAN_QUOTA_OUT = 128 KiB | ||
34 | # BLUETOOTH | ||
35 | BLUETOOTH_QUOTA_IN = 128 KiB | ||
36 | BLUETOOTH_QUOTA_OUT = 128 KiB | ||
37 | |||
38 | [transport-blacklist-M1RGJB4FQSM17JJ3M9BF7Q0I8MCO8C462NMOHI26RLT7C7A2KE6HCOPRA4ARM5HPL1J9IDDK5G8SFU5GUSHCTBH90ECETK1BFQD76R0] | ||
39 | HIJN5O404QNUR37OSJUTNJ6H2KJS198DHI2J3I8SE3DMKVRG1RNQPODN1IJBF14KEMPPPRM0B9F9ILFKHOFCA655CH6M5OCNCMR0FE0 = | ||
40 | CDTU8QQ8UPLGHR3B91V0CLTDOHONLB8QGHGUEM2JM1GANTEV0O6T20SD2N2HDN2QSHDG6IDTBR48KRDCS601FI6VHG59E7DQA98JD2O = | ||
41 | |||
42 | [transport-blacklist-93ARIS6Q347RPU9EFPS9LA00VPHQLG3RBLKEKTHV4D6UVGEAC75KIIBFB5U9KK9P9P1RU1CBPV4BSSDUTB2AL2N2LG9KSO9APQNLS0O] | ||
43 | HIJN5O404QNUR37OSJUTNJ6H2KJS198DHI2J3I8SE3DMKVRG1RNQPODN1IJBF14KEMPPPRM0B9F9ILFKHOFCA655CH6M5OCNCMR0FE0 = | ||
44 | CDTU8QQ8UPLGHR3B91V0CLTDOHONLB8QGHGUEM2JM1GANTEV0O6T20SD2N2HDN2QSHDG6IDTBR48KRDCS601FI6VHG59E7DQA98JD2O = | ||
45 | |||
46 | [transport-blacklist-OF84RAOAU2B1SOSEHJH6350MA0F7C98U55RI76LGIQOM7O33TFHPNUFB47CDBSCOLIINMVJ2U82445ABOBQRIVREG20L31KVDV5HG60] | ||
47 | HIJN5O404QNUR37OSJUTNJ6H2KJS198DHI2J3I8SE3DMKVRG1RNQPODN1IJBF14KEMPPPRM0B9F9ILFKHOFCA655CH6M5OCNCMR0FE0 = | ||
48 | CDTU8QQ8UPLGHR3B91V0CLTDOHONLB8QGHGUEM2JM1GANTEV0O6T20SD2N2HDN2QSHDG6IDTBR48KRDCS601FI6VHG59E7DQA98JD2O = | ||
49 | |||
50 | [transport-blacklist-548J7M14O4I0F8I84U0UFARVJ97DB6QOT3MCA8O8SNAIT5JJ8TR95LUVAP3N5L7DN33IB49SNMF3Q3C0VPLTGP9ASCULA9S2OIMHHH8] | ||
51 | HIJN5O404QNUR37OSJUTNJ6H2KJS198DHI2J3I8SE3DMKVRG1RNQPODN1IJBF14KEMPPPRM0B9F9ILFKHOFCA655CH6M5OCNCMR0FE0 = | ||
52 | CDTU8QQ8UPLGHR3B91V0CLTDOHONLB8QGHGUEM2JM1GANTEV0O6T20SD2N2HDN2QSHDG6IDTBR48KRDCS601FI6VHG59E7DQA98JD2O = | ||
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) |
29 | libgnunet_plugin_block_template_la_DEPENDENCIES = \ | ||
30 | libgnunetblockgroup.la \ | ||
31 | libgnunetblock.la \ | ||
32 | $(top_builddir)/src/util/libgnunetutil.la | ||
33 | libgnunet_plugin_block_template_la_LDFLAGS = \ | 29 | libgnunet_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) |
43 | libgnunet_plugin_block_test_la_DEPENDENCIES = \ | ||
44 | libgnunetblockgroup.la \ | ||
45 | libgnunetblock.la \ | ||
46 | $(top_builddir)/src/util/libgnunetutil.la | ||
47 | libgnunet_plugin_block_test_la_LDFLAGS = \ | 39 | libgnunet_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 |
52 | libgnunetblock_la_LIBADD = \ | 44 | libgnunetblock_la_LIBADD = \ |
53 | $(top_builddir)/src/util/libgnunetutil.la | 45 | $(top_builddir)/src/util/libgnunetutil.la |
54 | libgnunetblock_la_DEPENDENCIES = \ | ||
55 | $(top_builddir)/src/util/libgnunetutil.la | ||
56 | libgnunetblock_la_LDFLAGS = \ | 46 | libgnunetblock_la_LDFLAGS = \ |
57 | $(GN_LIB_LDFLAGS) \ | 47 | $(GN_LIB_LDFLAGS) \ |
58 | $(GN_LIBINTL) \ | 48 | $(GN_LIBINTL) \ |
@@ -63,9 +53,6 @@ libgnunetblockgroup_la_SOURCES = \ | |||
63 | libgnunetblockgroup_la_LIBADD = \ | 53 | libgnunetblockgroup_la_LIBADD = \ |
64 | libgnunetblock.la \ | 54 | libgnunetblock.la \ |
65 | $(top_builddir)/src/util/libgnunetutil.la | 55 | $(top_builddir)/src/util/libgnunetutil.la |
66 | libgnunetblockgroup_la_DEPENDENCIES = \ | ||
67 | libgnunetblock.la \ | ||
68 | $(top_builddir)/src/util/libgnunetutil.la | ||
69 | libgnunetblockgroup_la_LDFLAGS = \ | 56 | libgnunetblockgroup_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 = \ | |||
40 | gnunet_consensus_profiler_LDADD = \ | 40 | gnunet_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 | */ |
828 | int | 830 | enum GNUNET_GenericReturnValue |
829 | GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, const char *header) | 831 | GNUNET_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 |
116 | gnunet_dht_profiler_LDFLAGS = \ | 117 | gnunet_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 | */ |
171 | struct Plugin | 171 | struct 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 | |||
511 | ip_drop (struct GNUNET_DHTU_PreferenceHandle *ph) | 511 | ip_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 | */ |
538 | static void | 538 | static 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 |
86 | libgnunet_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 | ||
90 | libgnunet_plugin_block_dns_la_LDFLAGS = \ | 86 | libgnunet_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 | ||
100 | EXTRA_DIST = \ | 96 | EXTRA_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 |
52 | libgnunetfs_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 | ||
57 | if HAVE_LIBEXTRACTOR | 53 | if HAVE_LIBEXTRACTOR |
58 | libgnunetfs_la_LIBADD += \ | 54 | libgnunetfs_la_LIBADD += \ |
@@ -105,6 +101,7 @@ endif | |||
105 | gnunet_fs_profiler_SOURCES = \ | 101 | gnunet_fs_profiler_SOURCES = \ |
106 | gnunet-fs-profiler.c | 102 | gnunet-fs-profiler.c |
107 | gnunet_fs_profiler_LDADD = \ | 103 | gnunet_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) |
56 | libgnunetgnsrecord_la_DEPENDENCIES = \ | ||
57 | $(top_builddir)/src/identity/libgnunetidentity.la | ||
58 | libgnunetgnsrecord_la_LDFLAGS = \ | 56 | libgnunetgnsrecord_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 | |||
20 | OPTIONS = -b | 20 | OPTIONS = -b |
21 | 21 | ||
22 | # Default list of hostlist servers for bootstrapping | 22 | # Default list of hostlist servers for bootstrapping |
23 | SERVERS = http://v14.gnunet.org/hostlist https://gnunet.io/hostlist | 23 | SERVERS = 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 | */ | ||
123 | char * | ||
124 | GNUNET_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 | */ | ||
162 | char * | ||
163 | GNUNET_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 | */ |
152 | enum GNUNET_GenericReturnValue | 176 | enum GNUNET_GenericReturnValue |
153 | GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, | 177 | GNUNET_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 | */ | ||
268 | void | ||
269 | GNUNET_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 | */ | ||
641 | struct 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 | */ | ||
762 | void | ||
763 | GNUNET_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 | */ | ||
778 | void | ||
779 | GNUNET_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 | */ |
2611 | typedef int (*GNUNET_CONTAINER_HeapIterator) ( | 2611 | typedef 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 | */ |
153 | int | 153 | enum GNUNET_GenericReturnValue |
154 | GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, | 154 | GNUNET_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 | */ | ||
69 | struct 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 | */ | ||
78 | typedef void | ||
79 | (*GNUNET_DB_EventCallback)(void *cls, | ||
80 | const void *extra, | ||
81 | size_t extra_size); | ||
82 | |||
83 | GNUNET_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 | */ | ||
90 | struct 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 | |||
105 | GNUNET_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); | |||
266 | enum GNUNET_GenericReturnValue | 266 | enum GNUNET_GenericReturnValue |
267 | GNUNET_DISK_file_test (const char *fil); | 267 | GNUNET_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 | */ | ||
277 | enum GNUNET_GenericReturnValue | ||
278 | GNUNET_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 | */ | ||
678 | int | ||
679 | GNUNET_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 | */ | ||
531 | struct 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 | */ | ||
541 | typedef 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 | */ | ||
548 | struct 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 | */ | ||
577 | json_t * | ||
578 | GNUNET_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 | */ | ||
598 | struct GNUNET_JSON_PackSpec | ||
599 | GNUNET_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 | */ | ||
608 | struct GNUNET_JSON_PackSpec | ||
609 | GNUNET_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 | */ | ||
620 | struct GNUNET_JSON_PackSpec | ||
621 | GNUNET_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 | */ | ||
633 | struct GNUNET_JSON_PackSpec | ||
634 | GNUNET_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 | */ | ||
647 | struct GNUNET_JSON_PackSpec | ||
648 | GNUNET_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 | */ | ||
660 | struct GNUNET_JSON_PackSpec | ||
661 | GNUNET_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 | */ | ||
674 | struct GNUNET_JSON_PackSpec | ||
675 | GNUNET_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 | */ | ||
688 | struct GNUNET_JSON_PackSpec | ||
689 | GNUNET_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 | */ | ||
702 | struct GNUNET_JSON_PackSpec | ||
703 | GNUNET_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 | */ | ||
716 | struct GNUNET_JSON_PackSpec | ||
717 | GNUNET_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 | */ | ||
730 | struct GNUNET_JSON_PackSpec | ||
731 | GNUNET_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 | */ | ||
757 | struct GNUNET_JSON_PackSpec | ||
758 | GNUNET_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 | */ | ||
771 | struct GNUNET_JSON_PackSpec | ||
772 | GNUNET_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 | */ | ||
784 | struct GNUNET_JSON_PackSpec | ||
785 | GNUNET_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 | */ | ||
797 | struct GNUNET_JSON_PackSpec | ||
798 | GNUNET_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 | */ | ||
810 | struct GNUNET_JSON_PackSpec | ||
811 | GNUNET_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 | */ | ||
823 | struct GNUNET_JSON_PackSpec | ||
824 | GNUNET_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 | */ |
503 | enum GNUNET_MESSENGER_MessageFlags | 504 | enum 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 | */ | ||
862 | typedef 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 | */ | ||
876 | void | ||
877 | GNUNET_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 | */ | ||
891 | void | ||
892 | GNUNET_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 | */ | ||
900 | void | ||
901 | GNUNET_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 | */ | ||
909 | void | ||
910 | GNUNET_PQ_event_scheduler_stop (struct GNUNET_PQ_Context *db); | ||
911 | |||
912 | |||
913 | /** | ||
914 | * Handle for an active LISTENer to the database. | ||
915 | */ | ||
916 | struct 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 | */ | ||
925 | typedef void | ||
926 | (*GNUNET_PQ_EventCallback)(void *cls, | ||
927 | const void *extra, | ||
928 | size_t extra_size); | ||
929 | |||
930 | GNUNET_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 | */ | ||
937 | struct 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 | |||
952 | GNUNET_NETWORK_STRUCT_END | ||
953 | |||
954 | |||
955 | /** | ||
956 | * Handle for an active LISTENer to the database. | ||
957 | */ | ||
958 | struct 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 | */ |
976 | struct GNUNET_PQ_EventHandler * | 872 | struct GNUNET_DB_EventHandler * |
977 | GNUNET_PQ_event_listen (struct GNUNET_PQ_Context *db, | 873 | GNUNET_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 | */ |
994 | void | 891 | void |
995 | GNUNET_PQ_event_listen_cancel (struct GNUNET_PQ_EventHandler *eh); | 892 | GNUNET_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 | */ |
1012 | void | 909 | void |
1013 | GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db, | 910 | GNUNET_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 | |||
41 | struct TngState; | ||
42 | |||
43 | struct 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 | |||
108 | struct 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 | */ | ||
193 | int | ||
194 | GNUNET_TESTBED_get_trait_controller (const struct GNUNET_TESTING_Command *cmd, | ||
195 | struct GNUNET_TESTBED_Controller ** | ||
196 | controller); | ||
197 | |||
198 | struct GNUNET_TESTING_Command | ||
199 | GNUNET_TESTBED_cmd_controller (const char *label, | ||
200 | const char *host, | ||
201 | uint64_t event_mask); | ||
202 | |||
203 | void | ||
204 | GNUNET_TESTBED_shutdown_controller (struct ControllerState *cs); | ||
205 | |||
206 | void | ||
207 | GNUNET_TESTBED_shutdown_peer (struct PeerCmdState *ps); | ||
208 | |||
209 | void | ||
210 | GNUNET_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 | */ | ||
219 | struct GNUNET_TESTING_Command | ||
220 | GNUNET_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 | */ | ||
232 | struct GNUNET_TESTING_Command | ||
233 | GNUNET_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 | */ | ||
246 | struct GNUNET_TESTING_Command | ||
247 | GNUNET_TESTBED_cmd_netjail_stop (const char *label, | ||
248 | char *local_m, | ||
249 | char *global_n); | ||
250 | |||
251 | |||
252 | struct GNUNET_TESTING_Command | ||
253 | GNUNET_TESTBED_cmd_stop_testbed (const char *label, | ||
254 | const char *helper_start_label, | ||
255 | char *local_m, | ||
256 | char *global_n); | ||
257 | |||
258 | |||
259 | int | ||
260 | GNUNET_TESTBED_get_trait_helper_handles (const struct | ||
261 | GNUNET_TESTING_Command *cmd, | ||
262 | struct GNUNET_HELPER_Handle ***helper); | ||
263 | |||
264 | |||
265 | int | ||
266 | GNUNET_TESTBED_get_trait_hosts (const struct | ||
267 | GNUNET_TESTING_Command *cmd, | ||
268 | struct GNUNET_TESTBED_Host ***hosts); | ||
269 | |||
270 | struct GNUNET_TESTING_Command | ||
271 | GNUNET_TESTING_cmd_block_until_all_peers_started (const char *label, | ||
272 | unsigned int * | ||
273 | all_peers_started); | ||
274 | |||
275 | struct GNUNET_TESTING_Command | ||
276 | GNUNET_TESTING_cmd_send_peer_ready (const char *label, | ||
277 | TESTBED_CMD_HELPER_write_cb write_message); | ||
278 | |||
279 | struct GNUNET_TESTING_Command | ||
280 | GNUNET_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 | |||
841 | struct GNUNET_TESTING_Command | 842 | struct GNUNET_TESTING_Command |
842 | GNUNET_TESTING_cmd_system_create (const char *label, | 843 | GNUNET_TESTING_cmd_system_create (const char *label, |
843 | const char *testdir); | 844 | const char *testdir); |
844 | 845 | ||
846 | |||
847 | struct GNUNET_TESTING_Command | ||
848 | GNUNET_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 | */ | ||
859 | struct GNUNET_TESTING_Command | ||
860 | GNUNET_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 | */ | ||
872 | struct GNUNET_TESTING_Command | ||
873 | GNUNET_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 | */ | ||
887 | struct GNUNET_TESTING_Command | ||
888 | GNUNET_TESTING_cmd_netjail_stop (const char *label, | ||
889 | char *local_m, | ||
890 | char *global_n); | ||
891 | |||
892 | |||
893 | struct GNUNET_TESTING_Command | ||
894 | GNUNET_TESTING_cmd_stop_testing_system (const char *label, | ||
895 | const char *helper_start_label, | ||
896 | char *local_m, | ||
897 | char *global_n); | ||
898 | |||
899 | |||
900 | int | ||
901 | GNUNET_TESTING_get_trait_helper_handles (const struct | ||
902 | GNUNET_TESTING_Command *cmd, | ||
903 | struct GNUNET_HELPER_Handle ***helper); | ||
904 | |||
905 | |||
906 | struct GNUNET_TESTING_Command | ||
907 | GNUNET_TESTING_cmd_block_until_all_peers_started (const char *label, | ||
908 | unsigned int * | ||
909 | all_peers_started); | ||
910 | |||
911 | struct GNUNET_TESTING_Command | ||
912 | GNUNET_TESTING_cmd_send_peer_ready (const char *label, | ||
913 | TESTING_CMD_HELPER_write_cb write_message); | ||
914 | |||
915 | struct GNUNET_TESTING_Command | ||
916 | GNUNET_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 | ||
39 | typedef void | 39 | typedef 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 | ||
43 | typedef void | 43 | typedef 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 | ||
50 | typedef void | 51 | typedef 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 |
16 | libgnunetjson_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS) | 16 | libgnunetjson_la_CFLAGS = \ |
17 | $(MHD_CFLAGS) \ | ||
18 | $(AM_CFLAGS) | ||
17 | libgnunetjson_la_SOURCES = \ | 19 | libgnunetjson_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 | ||
22 | libgnunetjson_la_LIBADD = \ | 25 | libgnunetjson_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) |
28 | libgnunetjson_la_DEPENDENCIES = \ | ||
29 | $(top_builddir)/src/util/libgnunetutil.la | ||
30 | |||
31 | 31 | ||
32 | check_PROGRAMS = \ | 32 | check_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 | */ | ||
44 | enum GNUNET_GenericReturnValue | 31 | enum GNUNET_GenericReturnValue |
45 | GNUNET_JSON_parse (const json_t *root, | 32 | GNUNET_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 | */ | ||
94 | struct GNUNET_JSON_Specification | 75 | struct GNUNET_JSON_Specification |
95 | GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec) | 76 | GNUNET_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 | */ | ||
110 | void | 85 | void |
111 | GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec) | 86 | GNUNET_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 | */ | ||
163 | struct GNUNET_GETOPT_CommandLineOption | 130 | struct GNUNET_GETOPT_CommandLineOption |
164 | GNUNET_JSON_getopt (char shortName, | 131 | GNUNET_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 | |||
29 | json_t * | ||
30 | GNUNET_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 | |||
57 | struct GNUNET_JSON_PackSpec | ||
58 | GNUNET_JSON_pack_end_ (void) | ||
59 | { | ||
60 | struct GNUNET_JSON_PackSpec ps = { | ||
61 | .field_name = NULL | ||
62 | }; | ||
63 | |||
64 | return ps; | ||
65 | } | ||
66 | |||
67 | |||
68 | struct GNUNET_JSON_PackSpec | ||
69 | GNUNET_JSON_pack_allow_null (struct GNUNET_JSON_PackSpec in) | ||
70 | { | ||
71 | in.allow_null = true; | ||
72 | return in; | ||
73 | } | ||
74 | |||
75 | |||
76 | struct GNUNET_JSON_PackSpec | ||
77 | GNUNET_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 | |||
89 | struct GNUNET_JSON_PackSpec | ||
90 | GNUNET_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 | |||
102 | struct GNUNET_JSON_PackSpec | ||
103 | GNUNET_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 | |||
120 | struct GNUNET_JSON_PackSpec | ||
121 | GNUNET_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 | |||
140 | struct GNUNET_JSON_PackSpec | ||
141 | GNUNET_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 | |||
162 | struct GNUNET_JSON_PackSpec | ||
163 | GNUNET_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 | |||
185 | struct GNUNET_JSON_PackSpec | ||
186 | GNUNET_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 | |||
207 | struct GNUNET_JSON_PackSpec | ||
208 | GNUNET_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 | |||
230 | struct GNUNET_JSON_PackSpec | ||
231 | GNUNET_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 | |||
247 | struct GNUNET_JSON_PackSpec | ||
248 | GNUNET_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 | |||
268 | struct GNUNET_JSON_PackSpec | ||
269 | GNUNET_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 | |||
277 | struct GNUNET_JSON_PackSpec | ||
278 | GNUNET_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 | |||
290 | struct GNUNET_JSON_PackSpec | ||
291 | GNUNET_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 | |||
299 | struct GNUNET_JSON_PackSpec | ||
300 | GNUNET_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 | |||
312 | struct GNUNET_JSON_PackSpec | ||
313 | GNUNET_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 | ||
477 | static const struct GNUNET_MESSENGER_MemberSession* | ||
478 | get_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 | |||
477 | void | 499 | void |
478 | notify_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, | 500 | notify_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 @@ | |||
1 | p‘Ñç¨Â¡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 @@ | |||
1 | XJèµMíŠÀ …¬½ | ||
2 | dú胦ӌò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) |
29 | libgnunet_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 | ||
37 | libgnunet_plugin_rest_peerinfo_la_LDFLAGS = \ | 29 | libgnunet_plugin_rest_peerinfo_la_LDFLAGS = \ |
38 | $(GN_PLUGIN_LDFLAGS) | 30 | $(GN_PLUGIN_LDFLAGS) |
39 | libgnunet_plugin_rest_peerinfo_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS) | 31 | libgnunet_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 \ | |||
24 | libgnunetpq_la_LDFLAGS = \ | 24 | libgnunetpq_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 | ||
30 | if ENABLE_TEST_RUN | 29 | if 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 | */ | ||
86 | void | ||
87 | GNUNET_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 | */ | ||
88 | struct GNUNET_PQ_Context * | 67 | struct GNUNET_PQ_Context * |
89 | GNUNET_PQ_connect (const char *config_str, | 68 | GNUNET_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 | */ |
145 | static int | 126 | static enum GNUNET_GenericReturnValue |
146 | apply_patch (struct GNUNET_PQ_Context *db, | 127 | apply_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 | */ | ||
212 | enum GNUNET_GenericReturnValue | 184 | enum GNUNET_GenericReturnValue |
213 | GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db, | 185 | GNUNET_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 | */ | ||
312 | void | 279 | void |
313 | GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db) | 280 | GNUNET_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 | */ | ||
329 | void | 291 | void |
330 | GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) | 292 | GNUNET_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 | */ | ||
471 | struct GNUNET_PQ_Context * | 420 | struct GNUNET_PQ_Context * |
472 | GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, | 421 | GNUNET_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 | */ | ||
518 | void | 461 | void |
519 | GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db) | 462 | GNUNET_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 | */ |
33 | struct GNUNET_PQ_EventHandler | 33 | struct 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 | */ |
65 | static void | 68 | static void |
66 | es_to_sh (const struct GNUNET_PQ_EventHeaderP *es, | 69 | es_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 | */ | ||
115 | static enum GNUNET_GenericReturnValue | ||
116 | channel_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 | */ |
113 | static char * | 134 | static char * |
114 | es_to_channel (const struct GNUNET_PQ_EventHeaderP *es, | 135 | es_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 | */ |
152 | static int | 173 | static 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 | |||
167 | void | ||
168 | GNUNET_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 | ||
190 | void | 188 | static void |
191 | GNUNET_PQ_event_do_poll (struct GNUNET_PQ_Context *db) | 189 | event_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 | ||
238 | void | 254 | /** |
239 | GNUNET_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 | */ | ||
260 | static void | ||
261 | do_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 | ||
245 | void | 278 | /** |
246 | GNUNET_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 | */ | ||
285 | static void | ||
286 | scheduler_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 | */ | ||
252 | static void | 323 | static void |
253 | manage_subscribe (struct GNUNET_PQ_Context *db, | 324 | manage_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 | ||
285 | struct 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 | */ | ||
367 | static int | ||
368 | register_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 | |||
382 | void | ||
383 | GNUNET_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 | ®ister_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 | */ | ||
403 | static void | ||
404 | event_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 | |||
415 | struct GNUNET_DB_EventHandler * | ||
286 | GNUNET_PQ_event_listen (struct GNUNET_PQ_Context *db, | 416 | GNUNET_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 | ||
326 | void | 452 | void |
327 | GNUNET_PQ_event_listen_cancel (struct GNUNET_PQ_EventHandler *eh) | 453 | GNUNET_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 | ||
352 | void | 484 | void |
353 | GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db, | 485 | GNUNET_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 | */ | ||
31 | static struct GNUNET_PQ_Context *db; | ||
32 | |||
33 | /** | ||
34 | * Global return value, 0 on success. | ||
35 | */ | ||
36 | static int ret; | ||
37 | |||
38 | /** | ||
39 | * An event handler. | ||
40 | */ | ||
41 | static struct GNUNET_DB_EventHandler *eh; | ||
42 | |||
43 | /** | ||
44 | * Timeout task. | ||
45 | */ | ||
46 | static 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 | */ | ||
248 | static void | ||
249 | event_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 | */ | ||
267 | static void | ||
268 | timeout_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 | */ | ||
282 | static void | ||
283 | event_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 | */ | ||
301 | static void | ||
302 | sched_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 | |||
223 | int | 328 | int |
224 | main (int argc, | 329 | main (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) |
64 | libgnunet_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 | ||
72 | libgnunet_plugin_rest_reclaim_la_LDFLAGS = \ | 64 | libgnunet_plugin_rest_reclaim_la_LDFLAGS = \ |
73 | $(GN_PLUGIN_LDFLAGS) | 65 | $(GN_PLUGIN_LDFLAGS) |
74 | libgnunet_plugin_rest_reclaim_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS) | 66 | libgnunet_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) |
105 | libgnunet_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 | ||
110 | libgnunet_plugin_rest_pabc_la_LDFLAGS = \ | 97 | libgnunet_plugin_rest_pabc_la_LDFLAGS = \ |
111 | $(GN_PLUGIN_LDFLAGS) | 98 | $(GN_PLUGIN_LDFLAGS) |
112 | libgnunet_plugin_rest_pabc_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS) | 99 | libgnunet_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 |
56 | libgnunetregex_internal_a_DEPENDENCIES = \ | ||
57 | libgnunetregexblock.la | ||
58 | |||
59 | 56 | ||
60 | libgnunetregex_la_SOURCES = \ | 57 | libgnunetregex_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 |
127 | gnunet_regex_profiler_LDADD = -lm \ | 124 | gnunet_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; | |||
91 | static struct RequestHandle *requests_tail; | 91 | static 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) |
35 | libgnunet_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 | ||
40 | libgnunet_plugin_block_revocation_la_LDFLAGS = \ | 35 | libgnunet_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 |
25 | gnunet_secretsharing_profiler_LDADD = \ | 25 | gnunet_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 | |||
245 | ibf_destroy (struct InvertibleBloomFilter *ibf); | 245 | ibf_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 | |||
182 | enum 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 | */ |
636 | static uint32_t suggest_id; | 759 | static uint32_t suggest_id; |
637 | 760 | ||
761 | #if MEASURE_PERFORMANCE | ||
762 | /** | ||
763 | * Handles configuration file for setu performance test | ||
764 | * | ||
765 | */ | ||
766 | static const struct GNUNET_CONFIGURATION_Handle *setu_cfg; | ||
767 | |||
768 | |||
769 | /** | ||
770 | * Stores the performance data for induvidual message | ||
771 | */ | ||
772 | |||
773 | |||
774 | struct 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 | */ | ||
785 | struct 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 | |||
806 | struct per_store_struct perf_store; | ||
807 | #endif | ||
808 | |||
809 | /** | ||
810 | * Different states to control the messages flow in differential mode | ||
811 | */ | ||
812 | |||
813 | enum 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 | ||
840 | enum MESSAGE_TYPE | ||
841 | { | ||
842 | /** | ||
843 | * Offer message type | ||
844 | */ | ||
845 | OFFER_MESSAGE, | ||
643 | 846 | ||
644 | struct 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 | ||
652 | struct 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; | 862 | struct 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 | ||
668 | struct 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 | */ | ||
886 | static void | ||
887 | load_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 | */ | ||
671 | static int | 925 | static int |
672 | sum_sent_received_bytes(int size, struct perf_num_send_resived_msg perf_rtt_struct) { | 926 | sum_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 | ||
679 | static float | ||
680 | calculate_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 ) || | 940 | static void |
691 | ( perf_rtt.element_full.sent != 0) | 941 | calculate_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 | */ | ||
1050 | static uint8_t | ||
1051 | estimate_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 | */ | ||
1190 | static enum GNUNET_GenericReturnValue | ||
1191 | check_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 | */ | ||
1225 | static int | ||
1226 | update_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 | */ | ||
1315 | static int | ||
1316 | is_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 | */ | ||
1371 | static int | ||
1372 | determinate_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 | */ | ||
1395 | static int | ||
1396 | determinate_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 | */ | ||
1416 | static int | ||
1417 | create_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 | |||
1531 | static int | ||
1532 | check_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 | |||
1733 | static void | ||
1734 | full_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 | */ | ||
1799 | static void | ||
1800 | check_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) | |||
1004 | struct GetElementContext | 1843 | struct 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 | */ |
1137 | static void | 1976 | static void |
1138 | unsalt_key (const struct IBF_Key *k_in, | 1977 | unsalt_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 | */ |
1284 | static int | 2125 | static int |
1285 | send_ibf (struct Operation *op, | 2126 | send_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 | */ |
1356 | static unsigned int | 2214 | static unsigned int |
1357 | get_order_from_difference (unsigned int diff) | 2215 | get_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) || | 2225 | static unsigned int |
1363 | ((1 << ibf_order) < SE_IBF_HASH_NUM)) && | 2226 | get_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 | |||
1473 | handle_union_p2p_strata_estimator (void *cls, | 2357 | handle_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 | */ |
1654 | static void | 2705 | void |
1655 | send_offers_for_key (struct Operation *op, | 2706 | send_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 | |||
2932 | static int | ||
2933 | check_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 | */ | ||
2946 | static void | ||
2947 | handle_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 | */ |
3685 | static int | ||
3686 | check_union_p2p_request_full (void *cls, | ||
3687 | const struct TransmitFullMessage *mh) | ||
3688 | { | ||
3689 | return GNUNET_OK; | ||
3690 | } | ||
3691 | |||
3692 | |||
2425 | static void | 3693 | static void |
2426 | handle_union_p2p_request_full (void *cls, | 3694 | handle_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 | |||
2769 | handle_union_p2p_over (void *cls, | 4257 | handle_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 | |||
3201 | static void | 4692 | static void |
3202 | handle_client_listen (void *cls, | 4693 | handle_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 | /** | ||
93 | estimate_best_mode_of_operation (uint64_t avg_element_size, | ||
94 | uint64_t local_set_size, | ||
95 | uint64_t remote_set_size, | ||
96 | uint64_t est_set_diff_remote, | ||
97 | uint64_t est_set_diff_local,) | ||
98 | **/ | ||
99 | |||
100 | |||
104 | struct InquiryMessage | 101 | struct 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 | */ | ||
229 | struct 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 | |||
224 | GNUNET_NETWORK_STRUCT_END | 254 | GNUNET_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 | */ | ||
58 | uint8_t | ||
59 | determine_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 | */ | ||
79 | static void | ||
80 | salt_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 | */ | ||
96 | static void | ||
97 | unsalt_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 | */ |
39 | size_t | 116 | size_t |
40 | strata_estimator_write (const struct StrataEstimator *se, | 117 | strata_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 | |||
87 | strata_estimator_read (const void *buf, | 175 | strata_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 | */ |
134 | void | 233 | void |
135 | strata_estimator_insert (struct StrataEstimator *se, | 234 | strata_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 | */ |
155 | void | 266 | void |
156 | strata_estimator_remove (struct StrataEstimator *se, | 267 | strata_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 | */ |
178 | struct StrataEstimator * | 300 | struct MultiStrataEstimator * |
179 | strata_estimator_create (unsigned int strata_count, | 301 | strata_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 | */ |
216 | unsigned int | 351 | void |
217 | strata_estimator_difference (const struct StrataEstimator *se1, | 352 | strata_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); | 407 | break_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 | */ |
265 | struct StrataEstimator * | 425 | struct MultiStrataEstimator * |
266 | strata_estimator_dup (struct StrataEstimator *se) | 426 | strata_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 | */ |
286 | void | 456 | void |
287 | strata_estimator_destroy (struct StrataEstimator *se) | 457 | strata_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 | ||
65 | struct 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 | |||
86 | uint8_t | ||
87 | determine_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 | */ |
72 | size_t | 98 | size_t |
73 | strata_estimator_write (const struct StrataEstimator *se, | 99 | strata_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 | |||
88 | strata_estimator_read (const void *buf, | 116 | strata_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 | */ |
102 | struct StrataEstimator * | 132 | struct MultiStrataEstimator * |
103 | strata_estimator_create (unsigned int strata_count, | 133 | strata_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 | */ |
116 | unsigned int | 146 | void |
117 | strata_estimator_difference (const struct StrataEstimator *se1, | 147 | strata_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 | */ |
127 | void | 157 | void |
128 | strata_estimator_insert (struct StrataEstimator *se, | 158 | strata_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 | */ |
138 | void | 168 | void |
139 | strata_estimator_remove (struct StrataEstimator *se, | 169 | strata_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 | */ |
148 | void | 178 | void |
149 | strata_estimator_destroy (struct StrataEstimator *se); | 179 | strata_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 | */ |
158 | struct StrataEstimator * | 188 | struct MultiStrataEstimator * |
159 | strata_estimator_dup (struct StrataEstimator *se); | 189 | strata_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 | */ |
77 | struct InvertibleBloomFilter * | 82 | struct InvertibleBloomFilter * |
78 | ibf_create (uint32_t size, | 83 | ibf_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; |
134 | try_next: | 139 | try_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 | */ | ||
297 | uint8_t | ||
298 | ibf_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 | */ |
302 | void | 322 | void |
303 | ibf_write_slice (const struct InvertibleBloomFilter *ibf, | 323 | ibf_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 | |||
368 | void | ||
369 | pack_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 | |||
441 | void | ||
442 | unpack_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 | */ |
342 | void | 522 | void |
343 | ibf_read_slice (const void *buf, | 523 | ibf_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 | */ |
63 | struct IBF_Count | 64 | struct 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 | |||
125 | void | 140 | void |
126 | ibf_write_slice (const struct InvertibleBloomFilter *ibf, | 141 | ibf_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, | |||
140 | void | 156 | void |
141 | ibf_read_slice (const void *buf, | 157 | ibf_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); | |||
244 | void | 261 | void |
245 | ibf_destroy (struct InvertibleBloomFilter *ibf); | 262 | ibf_destroy (struct InvertibleBloomFilter *ibf); |
246 | 263 | ||
264 | uint8_t | ||
265 | ibf_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 | |||
278 | void | ||
279 | pack_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 | |||
295 | void | ||
296 | unpack_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 | ||
32 | static struct GNUNET_PeerIdentity local_id; | 35 | static struct GNUNET_PeerIdentity local_id; |
@@ -50,6 +53,12 @@ static int ret; | |||
50 | static struct GNUNET_SCHEDULER_Task *tt; | 53 | static struct GNUNET_SCHEDULER_Task *tt; |
51 | 54 | ||
52 | 55 | ||
56 | /** | ||
57 | * Handles configuration file for setu performance test | ||
58 | * | ||
59 | */ | ||
60 | static struct GNUNET_CONFIGURATION_Handle *setu_cfg; | ||
61 | |||
53 | 62 | ||
54 | static void | 63 | static void |
55 | result_cb_set1 (void *cls, | 64 | result_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, | |||
162 | static void | 171 | static void |
163 | start (void *cls) | 172 | start (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 | */ | ||
189 | static void | ||
190 | init_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 | ||
212 | unsigned char *gen_rdm_bytestream (size_t num_bytes) | 197 | unsigned char * |
198 | gen_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 | ||
223 | static void | 210 | static void |
224 | initRandomSets(int overlap, int set1_size, int set2_size, int element_size_in_bytes) | 211 | initRandomSets (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 | */ | ||
268 | static void | ||
269 | init_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) | |||
289 | static void | 265 | static void |
290 | timeout_fail (void *cls) | 266 | timeout_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) | |||
304 | static void | 280 | static void |
305 | do_shutdown (void *cls) | 281 | do_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 | ||
401 | static void execute_perf() | 377 | |
378 | void | ||
379 | perf_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", | 390 | static void |
409 | "arm", | 391 | run_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 | ||
419 | static void | ||
420 | execute_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 | ||
419 | int | 464 | int |
420 | main (int argc, char **argv) | 465 | main (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 | |||
211 | unsigned 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 | |||
222 | static void | ||
223 | initRandomSets(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 | |||
23 | endif | 23 | endif |
24 | 24 | ||
25 | libexec_PROGRAMS = \ | 25 | libexec_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 = \ | |||
37 | noinst_PROGRAMS = \ | 35 | noinst_PROGRAMS = \ |
38 | $(generate_underlay) | 36 | $(generate_underlay) |
39 | 37 | ||
40 | plugin_LTLIBRARIES = \ | ||
41 | libgnunet_plugin_testcmd.la | ||
42 | |||
43 | libgnunet_plugin_testcmd_la_SOURCES = \ | ||
44 | plugin_testcmd.c | ||
45 | libgnunet_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) | ||
51 | libgnunet_plugin_testcmd_la_LDFLAGS = \ | ||
52 | $(GN_PLUGIN_LDFLAGS) | ||
53 | |||
54 | gnunet_service_testbed_SOURCES = \ | 38 | gnunet_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) \ | |||
75 | gnunet_testbed_profiler_SOURCES = \ | 59 | gnunet_testbed_profiler_SOURCES = \ |
76 | gnunet-testbed-profiler.c | 60 | gnunet-testbed-profiler.c |
77 | gnunet_testbed_profiler_LDADD = $(XLIB) \ | 61 | gnunet_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 |
80 | gnunet_testbed_profiler_LDFLAGS = \ | 65 | gnunet_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 | ||
91 | gnunet_cmd_SOURCES = \ | ||
92 | gnunet-cmd.c | ||
93 | gnunet_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 | |||
99 | gnunet_cmds_helper_SOURCES = \ | ||
100 | gnunet-cmds-helper.c | ||
101 | gnunet_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 | |||
108 | gnunet_daemon_testbed_blacklist_SOURCES = gnunet-daemon-testbed-blacklist.c | 76 | gnunet_daemon_testbed_blacklist_SOURCES = gnunet-daemon-testbed-blacklist.c |
109 | gnunet_daemon_testbed_blacklist_LDADD = $(XLIB) \ | 77 | gnunet_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 | ||
129 | libgnunettestbed_la_SOURCES = \ | 97 | libgnunettestbed_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) |
159 | libgnunettestbed_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 | ||
165 | libgnunettestbed_la_LDFLAGS = \ | 118 | libgnunettestbed_la_LDFLAGS = \ |
166 | $(GN_LIB_LDFLAGS) \ | 119 | $(GN_LIB_LDFLAGS) \ |
167 | -version-info 0:0:0 | 120 | -version-info 0:0:0 |
168 | 121 | ||
169 | generate_underlay_topology_SOURCES = generate-underlay-topology.c | 122 | generate_underlay_topology_SOURCES = generate-underlay-topology.c |
170 | generate_underlay_topology_LDADD = $(XLIB) \ | 123 | generate_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 | ||
175 | check_PROGRAMS = \ | 129 | check_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 = \ | |||
208 | if ENABLE_TEST_RUN | 161 | if 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) |
240 | endif | 192 | endif |
241 | 193 | ||
242 | test_testbed_api_cmd_netjail_SOURCES = \ | ||
243 | test_testbed_api_cmd_netjail.c | ||
244 | test_testbed_api_cmd_netjail_LDADD = \ | ||
245 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
246 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
247 | libgnunettestbed.la | ||
248 | |||
249 | test_testbed_api_SOURCES = \ | 194 | test_testbed_api_SOURCES = \ |
250 | test_testbed_api.c | 195 | test_testbed_api.c |
251 | test_testbed_api_LDADD = \ | 196 | test_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 | */ | ||
46 | struct 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 | */ | ||
78 | static void | ||
79 | run (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 | |||
98 | int | ||
99 | main (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 | |||
185 | typedef void | 180 | typedef 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 | */ | ||
47 | static void | ||
48 | controller_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 | */ | ||
62 | static void | ||
63 | controller_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 | |||
81 | static void | ||
82 | controller_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 | */ | ||
106 | static int | ||
107 | controller_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 | */ | ||
141 | int | ||
142 | GNUNET_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 | */ | ||
158 | void | ||
159 | GNUNET_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 | |||
182 | struct GNUNET_TESTING_Command | ||
183 | GNUNET_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 | */ | ||
51 | static int | ||
52 | peer_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 | */ | ||
83 | int | ||
84 | GNUNET_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 | */ | ||
101 | static void | ||
102 | peer_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 | */ | ||
115 | static void | ||
116 | do_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 | */ | ||
136 | static void | ||
137 | peer_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 | */ | ||
165 | static void | ||
166 | peer_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 | |||
181 | static void | ||
182 | peer_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 | |||
212 | void | ||
213 | peer_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 | */ | ||
233 | void | ||
234 | GNUNET_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 | |||
255 | struct GNUNET_TESTING_Command | ||
256 | GNUNET_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 | |||
28 | static void | ||
29 | service_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 | |||
40 | struct GNUNET_TESTING_Command | ||
41 | GNUNET_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 | |||
32 | struct SendPeerReadyState | ||
33 | { | ||
34 | TESTBED_CMD_HELPER_write_cb write_message; | ||
35 | |||
36 | struct GNUNET_CMDS_PEER_STARTED *reply; | ||
37 | }; | ||
38 | |||
39 | |||
40 | static int | ||
41 | send_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 | |||
50 | static void | ||
51 | send_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 | |||
61 | static void | ||
62 | send_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 | */ | ||
85 | struct GNUNET_TESTING_Command | ||
86 | GNUNET_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 | |||
29 | static void | ||
30 | tng_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 | |||
39 | struct GNUNET_TESTING_Command | ||
40 | GNUNET_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 | */ | ||
46 | static void | ||
47 | do_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 | */ | ||
65 | static void | ||
66 | tng_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 | */ | ||
81 | static int | ||
82 | tng_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 | |||
92 | static void * | ||
93 | notify_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 | |||
111 | static void | ||
112 | notify_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 | */ | ||
131 | static void * | ||
132 | connect_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 | ¬ify_connect, | ||
142 | ¬ify_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 | */ | ||
154 | static void | ||
155 | disconnect_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 | */ | ||
169 | static void | ||
170 | service_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 | */ | ||
196 | static void | ||
197 | pi_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 | |||
214 | static void | ||
215 | tng_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 | */ | ||
240 | void | ||
241 | GNUNET_TESTBED_shutdown_service (struct TngState *cs) | ||
242 | { | ||
243 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
244 | "Shutting down...\n"); | ||
245 | } | ||
246 | |||
247 | |||
248 | struct GNUNET_TESTING_Command | ||
249 | GNUNET_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 | ||
967 | void | 967 | /** |
968 | GNUNET_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 | */ | ||
979 | static int | ||
980 | helper_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 | */ | ||
1021 | static int | ||
1022 | helper_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 | */ | ||
90 | struct 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 | */ | ||
109 | struct GNUNET_CMDS_HelperReply | ||
110 | { | ||
111 | /** | ||
112 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY | ||
113 | */ | ||
114 | struct GNUNET_MessageHeader header; | ||
115 | }; | ||
116 | |||
117 | struct GNUNET_CMDS_PEER_STARTED | ||
118 | { | ||
119 | /** | ||
120 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED | ||
121 | */ | ||
122 | struct GNUNET_MessageHeader header; | ||
123 | }; | ||
124 | |||
125 | struct 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 | |||
133 | struct GNUNET_CMDS_LOCAL_FINISHED | ||
134 | { | ||
135 | /** | ||
136 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED | ||
137 | */ | ||
138 | struct GNUNET_MessageHeader header; | ||
139 | }; | ||
140 | |||
141 | GNUNET_NETWORK_STRUCT_END | 87 | GNUNET_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/ | |||
11 | dist_pkgcfg_DATA = \ | 11 | dist_pkgcfg_DATA = \ |
12 | testing.conf | 12 | testing.conf |
13 | 13 | ||
14 | libexec_PROGRAMS = \ | ||
15 | gnunet-cmds-helper | ||
16 | |||
17 | plugindir = $(libdir)/gnunet | ||
18 | |||
19 | plugin_LTLIBRARIES = \ | ||
20 | libgnunet_test_testing_plugin_testcmd.la | ||
21 | |||
14 | lib_LTLIBRARIES = \ | 22 | lib_LTLIBRARIES = \ |
15 | libgnunettesting.la | 23 | libgnunettesting.la |
16 | 24 | ||
25 | gnunet_cmds_helper_SOURCES = \ | ||
26 | gnunet-cmds-helper.c | ||
27 | gnunet_cmds_helper_LDADD = $(XLIB) \ | ||
28 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
29 | libgnunettesting.la \ | ||
30 | $(LTLIBINTL) $(Z_LIBS) | ||
31 | |||
32 | libgnunet_test_testing_plugin_testcmd_la_SOURCES = \ | ||
33 | test_testing_plugin_testcmd.c | ||
34 | libgnunet_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) | ||
40 | libgnunet_test_testing_plugin_testcmd_la_LDFLAGS = \ | ||
41 | $(GN_PLUGIN_LDFLAGS) | ||
42 | |||
17 | libgnunettesting_la_SOURCES = \ | 43 | libgnunettesting_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) |
31 | libgnunettesting_la_DEPENDENCIES = \ | ||
32 | $(top_builddir)/src/arm/libgnunetarm.la \ | ||
33 | $(top_builddir)/src/util/libgnunetutil.la | ||
34 | libgnunettesting_la_LDFLAGS = \ | 65 | libgnunettesting_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 | ||
58 | check_PROGRAMS = \ | 89 | check_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 = \ | |||
66 | if ENABLE_TEST_RUN | 98 | if ENABLE_TEST_RUN |
67 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | 99 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; |
68 | TESTS = \ | 100 | TESTS = \ |
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 |
74 | endif | 107 | endif |
75 | 108 | ||
109 | test_testing_api_cmd_netjail_SOURCES = \ | ||
110 | test_testing_api_cmd_netjail.c | ||
111 | test_testing_api_cmd_netjail_LDADD = \ | ||
112 | libgnunettesting.la \ | ||
113 | $(top_builddir)/src/util/libgnunetutil.la | ||
114 | |||
76 | test_testing_hello_world_SOURCES = \ | 115 | test_testing_hello_world_SOURCES = \ |
77 | test_testing_hello_world.c | 116 | test_testing_hello_world.c |
78 | test_testing_hello_world_LDADD = \ | 117 | test_testing_hello_world_LDADD = \ |
@@ -111,4 +150,5 @@ test_testing_sharedservices_LDADD = \ | |||
111 | 150 | ||
112 | EXTRA_DIST = \ | 151 | EXTRA_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 | */ | 50 | testing_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 | */ | ||
91 | struct NodeIdentifier | 118 | struct 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 | |
128 | static struct GNUNET_OS_Process *cmd_binary_process; | 171 | static 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; | |||
163 | static struct GNUNET_SCHEDULER_Task *write_task_id; | 206 | static struct GNUNET_SCHEDULER_Task *write_task_id; |
164 | 207 | ||
165 | /** | 208 | /** |
166 | * Task to kill the child | ||
167 | */ | ||
168 | static 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 | */ |
173 | static int done_reading; | 211 | static 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 | */ |
279 | static void | 301 | static void |
280 | child_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 | |||
300 | static void | ||
301 | write_message (struct GNUNET_MessageHeader *message, size_t msg_length) | 302 | write_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 | ||
327 | run_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 | ||
4 | JAILOR=${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 | ||
92 | netjail_node_exec() { | 92 | netjail_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 | ||
101 | netjail_node_exec_without_fds() { | 102 | netjail_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 | |||
110 | netjail_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 | ||
4 | set -eu | 4 | set -eu |
5 | set -x | 5 | set -x |
@@ -13,4 +13,4 @@ NODE=$(netjail_print_name "N" $N $M) | |||
13 | 13 | ||
14 | 14 | ||
15 | 15 | ||
16 | netjail_node_exec_without_fds $NODE $3 $4 $5 $1 $2 | 16 | netjail_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 | ||
4 | set -eu | 4 | set -eu |
5 | set -x | 5 | set -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 | ||
4 | set -eu | 4 | set -eu |
5 | set -x | 5 | set -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 | |||
39 | run (void *cls) | 38 | run (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 | ||
47 | static void | 47 | static void |
48 | start_testcase (TESTBED_CMD_HELPER_write_cb write_message, char *router_ip, | 48 | start_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 | */ | ||
35 | struct BlockState | 39 | struct 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 | */ | ||
41 | static int | 53 | static int |
42 | block_until_all_peers_started_traits (void *cls, | 54 | block_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 | */ | ||
51 | static void | 67 | static void |
52 | block_until_all_peers_started_cleanup (void *cls, | 68 | block_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 | */ | ||
61 | static void | 81 | static void |
62 | block_until_all_peers_started_run (void *cls, | 82 | block_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 | */ | ||
71 | static int | 95 | static int |
72 | block_until_all_peers_started_finish (void *cls, | 96 | block_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 | */ |
104 | struct GNUNET_TESTING_Command | 119 | struct 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 | */ | ||
36 | struct LocalFinishedState | 41 | struct 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 | */ | ||
44 | static int | 61 | static int |
45 | local_test_finished_traits (void *cls, | 62 | local_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 | */ | ||
54 | static void | 75 | static void |
55 | local_test_finished_cleanup (void *cls, | 76 | local_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 | */ | ||
65 | static void | 90 | static void |
66 | local_test_finished_run (void *cls, | 91 | local_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 | */ | ||
90 | static int | 113 | static int |
91 | local_test_finished_finish (void *cls, | 114 | local_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 | */ |
106 | struct GNUNET_TESTING_Command | 131 | struct GNUNET_TESTING_Command |
107 | GNUNET_TESTING_cmd_local_test_finished (const char *label, | 132 | GNUNET_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 | */ | ||
33 | struct NetJailState | 36 | struct 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 | */ | ||
56 | static void | 61 | static void |
57 | netjail_start_cleanup (void *cls, | 62 | netjail_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 | */ | ||
93 | static int | 93 | static int |
94 | netjail_start_traits (void *cls, | 94 | netjail_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 | */ | ||
102 | static void | 107 | static void |
103 | child_completed_callback (void *cls, | 108 | child_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 | */ | ||
156 | static int | 185 | static int |
157 | netjail_start_finish (void *cls, | 186 | netjail_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 | */ |
177 | struct GNUNET_TESTING_Command | 207 | struct GNUNET_TESTING_Command |
178 | GNUNET_TESTBED_cmd_netjail_start (const char *label, | 208 | GNUNET_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 | |||
35 | struct HelperMessage; | ||
36 | 31 | ||
32 | /** | ||
33 | * Struct to store messages send/received by the helper into a DLL | ||
34 | * | ||
35 | */ | ||
37 | struct HelperMessage | 36 | struct 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 | */ | ||
54 | struct NetJailState | 62 | struct 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 | ||
104 | struct 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 | */ | ||
168 | struct 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 | */ | ||
136 | static int | 229 | static int |
137 | netjail_exec_traits (void *cls, | 230 | netjail_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 | */ |
175 | int | 268 | int |
176 | GNUNET_TESTBED_get_trait_helper_handles (const struct | 269 | GNUNET_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 | */ |
193 | int | 287 | int |
194 | GNUNET_TESTBED_get_trait_helper_messages (const struct | 288 | GNUNET_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 | |||
214 | static void | 308 | static void |
215 | clear_msg (void *cls, int result) | 309 | clear_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) | |||
242 | static int | 333 | static int |
243 | helper_mst (void *cls, const struct GNUNET_MessageHeader *message) | 334 | helper_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 | */ | ||
285 | static void | 371 | static void |
286 | exp_cb (void *cls) | 372 | exp_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 | */ | ||
293 | static struct GNUNET_CMDS_HelperInit * | 388 | static struct GNUNET_CMDS_HelperInit * |
294 | create_helper_init_msg_ (char *m_char, | 389 | create_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 | */ | ||
319 | static void | 415 | static void |
320 | start_testbed (struct NetJailState *ns, struct | 416 | start_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 | */ | ||
435 | static int | 535 | static int |
436 | netjail_start_finish (void *cls, | 536 | netjail_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 | */ |
509 | struct GNUNET_TESTING_Command | 605 | struct GNUNET_TESTING_Command |
510 | GNUNET_TESTBED_cmd_netjail_start_testbed (const char *label, | 606 | GNUNET_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 | ||
34 | struct GNUNET_ChildWaitHandle *cwh; | 34 | struct GNUNET_ChildWaitHandle *cwh; |
35 | 35 | ||
36 | /** | ||
37 | * Struct to hold information for callbacks. | ||
38 | * | ||
39 | */ | ||
36 | struct NetJailState | 40 | struct 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 | */ | ||
57 | static void | 62 | static void |
58 | netjail_stop_cleanup (void *cls, | 63 | netjail_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 | */ | ||
90 | static int | 90 | static int |
91 | netjail_stop_traits (void *cls, | 91 | netjail_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 | */ | ||
100 | static void | 104 | static void |
101 | child_completed_callback (void *cls, | 105 | child_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 | */ | ||
154 | static int | 181 | static int |
155 | netjail_stop_finish (void *cls, | 182 | netjail_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 | */ |
176 | struct GNUNET_TESTING_Command | 204 | struct GNUNET_TESTING_Command |
177 | GNUNET_TESTBED_cmd_netjail_stop (const char *label, | 205 | GNUNET_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 | */ | ||
33 | struct StopHelperState | 35 | struct 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 | */ |
55 | static void | 57 | static void |
56 | stop_testbed_cleanup (void *cls, | 58 | stop_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 | */ | ||
72 | static int | 69 | static int |
73 | stop_testbed_traits (void *cls, | 70 | stop_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 | */ |
89 | static void | 86 | static void |
90 | stop_testbed_run (void *cls, | 87 | stop_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 | */ |
120 | struct GNUNET_TESTING_Command | 120 | struct GNUNET_TESTING_Command |
121 | GNUNET_TESTBED_cmd_stop_testbed (const char *label, | 121 | GNUNET_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 | */ | ||
33 | struct SendPeerReadyState | 36 | struct 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 | */ | ||
41 | static int | 56 | static int |
42 | send_peer_ready_traits (void *cls, | 57 | send_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 | */ | ||
51 | static void | 70 | static void |
52 | send_peer_ready_cleanup (void *cls, | 71 | send_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 | */ | ||
62 | static void | 85 | static void |
63 | send_peer_ready_run (void *cls, | 86 | send_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 | */ |
86 | struct GNUNET_TESTING_Command | 110 | struct GNUNET_TESTING_Command |
87 | GNUNET_TESTING_cmd_send_peer_ready (const char *label, | 111 | GNUNET_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 | */ | ||
31 | struct TestSystemState | 35 | struct 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 | */ | ||
39 | static void | 47 | static void |
40 | system_create_run (void *cls, | 48 | system_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 | */ | ||
57 | static int | 70 | static int |
58 | system_create_traits (void *cls, | 71 | system_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 | */ | ||
82 | int | 101 | int |
83 | GNUNET_TESTING_get_trait_test_system (const struct | 102 | GNUNET_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 | */ | ||
94 | static void | 117 | static void |
95 | system_create_cleanup (void *cls, | 118 | system_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 | */ |
111 | struct GNUNET_TESTING_Command | 134 | struct 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 | */ | ||
36 | struct 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 | */ | ||
47 | static void | ||
48 | system_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 | */ | ||
67 | static void | ||
68 | system_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 | */ | ||
81 | static int | ||
82 | system_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 | */ | ||
98 | struct GNUNET_TESTING_Command | ||
99 | GNUNET_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 | ||
36 | struct GNUNET_TESTING_Interpreter *is; | 36 | struct 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 | */ | ||
188 | static void | 195 | static void |
189 | run_finish_task_next (void *cls) | 196 | run_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 | */ | ||
215 | static void | 228 | static void |
216 | run_finish_task_sync (void *cls) | 229 | run_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 | */ | ||
258 | static void | 275 | static void |
259 | start_finish_on_ref (void *cls, | 276 | start_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 | */ | ||
280 | const struct GNUNET_TESTING_Command | 308 | const struct GNUNET_TESTING_Command |
281 | GNUNET_TESTING_cmd_finish (const char *finish_label, | 309 | GNUNET_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 | |||
32 | GNUNET_NETWORK_STRUCT_BEGIN | ||
33 | |||
34 | /** | ||
35 | * Initialization message for gnunet-cmds-testbed to start cmd binary. | ||
36 | */ | ||
37 | struct 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 | */ | ||
56 | struct GNUNET_CMDS_HelperReply | ||
57 | { | ||
58 | /** | ||
59 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY | ||
60 | */ | ||
61 | struct GNUNET_MessageHeader header; | ||
62 | }; | ||
63 | |||
64 | struct GNUNET_CMDS_PEER_STARTED | ||
65 | { | ||
66 | /** | ||
67 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED | ||
68 | */ | ||
69 | struct GNUNET_MessageHeader header; | ||
70 | }; | ||
71 | |||
72 | struct 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 | |||
80 | struct GNUNET_CMDS_LOCAL_FINISHED | ||
81 | { | ||
82 | /** | ||
83 | * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED | ||
84 | */ | ||
85 | struct GNUNET_MessageHeader header; | ||
86 | }; | ||
87 | |||
88 | GNUNET_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) |
159 | libgnunettransporttesting_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 | ||
166 | libgnunettransporttesting_la_LDFLAGS = \ | 159 | libgnunettransporttesting_la_LDFLAGS = \ |
167 | $(GN_LIB_LDFLAGS) | 160 | $(GN_LIB_LDFLAGS) |
168 | 161 | ||
169 | libgnunettransporttesting2_la_SOURCES = \ | 162 | libgnunettransporttesting2_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 |
188 | libgnunettransporttesting2_la_LDFLAGS = \ | 184 | libgnunettransporttesting2_la_LDFLAGS = \ |
189 | $(GN_LIBINTL) \ | 185 | $(GN_LIBINTL) \ |
190 | $(GN_LIB_LDFLAGS) | 186 | $(GN_LIB_LDFLAGS) \ |
187 | -version-info 0:0:0 | ||
191 | 188 | ||
192 | libgnunettransport_la_SOURCES = \ | 189 | libgnunettransport_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) |
208 | libgnunettransport_la_DEPENDENCIES = \ | ||
209 | $(top_builddir)/src/hello/libgnunethello.la \ | ||
210 | $(top_builddir)/src/ats/libgnunetats.la \ | ||
211 | $(top_builddir)/src/util/libgnunetutil.la | ||
212 | libgnunettransport_la_LDFLAGS = \ | 205 | libgnunettransport_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 = \ | 396 | libgnunet_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 = \ | 398 | libgnunet_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) | ||
410 | libgnunet_test_transport_plugin_cmd_simple_send_la_LDFLAGS = \ | ||
411 | $(GN_PLUGIN_LDFLAGS) | ||
414 | 412 | ||
415 | if HAVE_EXPERIMENTAL | 413 | if HAVE_EXPERIMENTAL |
416 | plugin_LTLIBRARIES += libgnunet_plugin_transport_udp.la | 414 | plugin_LTLIBRARIES += \ |
415 | libgnunet_plugin_transport_udp.la | ||
417 | endif | 416 | endif |
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 | ||
558 | if HAVE_TESTING | 557 | if HAVE_TESTING |
559 | check_PROGRAMS = \ | 558 | check_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 | |||
646 | if ENABLE_TEST_RUN | 645 | if ENABLE_TEST_RUN |
647 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | 646 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; |
648 | TESTS = \ | 647 | TESTS = \ |
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) | ||
703 | if HAVE_GETOPT_BINARY | 702 | if HAVE_GETOPT_BINARY |
704 | TESTS += \ | 703 | TESTS += \ |
705 | test_transport_api_slow_ats | 704 | test_transport_api_slow_ats |
706 | endif | 705 | endif |
707 | if HAVE_EXPERIMENTAL | 706 | if HAVE_EXPERIMENTAL |
708 | TESTS += \ | 707 | TESTS += \ |
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 += \ | |||
723 | endif | 723 | endif |
724 | endif | 724 | endif |
725 | 725 | ||
726 | test_transport_api_cmd_simple_send_SOURCES = \ | 726 | check_SCRIPTS= \ |
727 | test_transport_api_cmd_simple_send.c | 727 | test_transport_simple_send.sh |
728 | test_transport_api_cmd_simple_send_LDADD = \ | 728 | |
729 | test_transport_simple_send_SOURCES = \ | ||
730 | test_transport_simple_send.c | ||
731 | test_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 | ||
736 | test_transport_testing_startstop_SOURCES = \ | 739 | test_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 | |||
41 | struct GNUNET_MQ_MessageHandler *handlers; | ||
42 | |||
43 | unsigned int are_all_peers_started; | ||
44 | |||
45 | static int | ||
46 | check_test (void *cls, | ||
47 | const struct GNUNET_TRANSPORT_TESTING_TestMessage *message) | ||
48 | { | ||
49 | return GNUNET_OK; | ||
50 | } | ||
51 | |||
52 | static void | ||
53 | handle_test (void *cls, | ||
54 | const struct GNUNET_TRANSPORT_TESTING_TestMessage *message) | ||
55 | { | ||
56 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
57 | "message received\n"); | ||
58 | } | ||
59 | |||
60 | static int | ||
61 | check_test2 (void *cls, | ||
62 | const struct GNUNET_TRANSPORT_TESTING_TestMessage *message) | ||
63 | { | ||
64 | return GNUNET_OK; | ||
65 | } | ||
66 | |||
67 | static void | ||
68 | handle_test2 (void *cls, | ||
69 | const struct GNUNET_TRANSPORT_TESTING_TestMessage *message) | ||
70 | { | ||
71 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
72 | "message received\n"); | ||
73 | } | ||
74 | |||
75 | static void | ||
76 | all_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 | |||
84 | static void | ||
85 | start_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 | */ | ||
160 | void * | ||
161 | libgnunet_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 | */ | ||
178 | void * | ||
179 | libgnunet_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] | ||
3 | GNUNET_TEST_HOME = $GNUNET_TMP/test-transport/api-tcp-p1/ | ||
4 | |||
5 | [transport] | ||
6 | BINARY = gnunet-service-tng | ||
7 | PLUGINS = tcp | ||
8 | #PREFIX = valgrind --log-file=/tmp/vg_peer1-%p | ||
9 | UNIXPATH = $GNUNET_RUNTIME_DIR/tng-p1.sock | ||
10 | |||
11 | [communicator-tcp] | ||
12 | BINARY = gnunet-communicator-tcp | ||
13 | BINDTO = 192.168.15.1:60002 | ||
14 | DISABLE_V6 = YES | ||
15 | IMMEDIATE_START = YES | ||
16 | UNIXPATH = $GNUNET_RUNTIME_DIR/tcp-comm-p1.sock | ||
17 | #PREFIX = valgrind --log-file=/tmp/vg_cpeer1-%p | ||
18 | |||
19 | [peerstore] | ||
20 | IMMEDIATE_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] | ||
3 | GNUNET_TEST_HOME = $GNUNET_TMP/test-transport/api-tcp-p2/ | ||
4 | |||
5 | [transport] | ||
6 | BINARY = gnunet-service-tng | ||
7 | #PREFIX = valgrind --log-file=/tmp/vg_peer2-%p | ||
8 | UNIXPATH = $GNUNET_RUNTIME_DIR/tng-p2.sock | ||
9 | |||
10 | [communicator-tcp] | ||
11 | BINARY = gnunet-communicator-tcp | ||
12 | BINDTO = 192.168.15.2:60003 | ||
13 | DISABLE_V6 = YES | ||
14 | IMMEDIATE_START = YES | ||
15 | #PREFIX = valgrind --log-file=/tmp/vg_comm2-%p | ||
16 | UNIXPATH = $GNUNET_RUNTIME_DIR/tcp-comm-p2.sock | ||
17 | |||
18 | [peerstore] | ||
19 | IMMEDIATE_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 | */ | ||
38 | static void | ||
39 | run (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 | |||
65 | int | ||
66 | main (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 | */ | ||
44 | char *testdir; | ||
45 | |||
46 | /** | ||
47 | * The name for the configuration file of the specific node. | ||
48 | * | ||
49 | */ | ||
50 | char *cfgname; | ||
51 | |||
52 | /** | ||
53 | * Flag indicating if all peers have been started. | ||
54 | * | ||
55 | */ | ||
56 | unsigned 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 | */ | ||
64 | static int | ||
65 | check_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 | */ | ||
77 | static void | ||
78 | handle_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 | */ | ||
91 | static int | ||
92 | check_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 | */ | ||
104 | static void | ||
105 | handle_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 | */ | ||
117 | static void | ||
118 | all_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 | */ | ||
137 | static void | ||
138 | start_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 | */ | ||
218 | void * | ||
219 | libgnunet_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 | */ | ||
236 | void * | ||
237 | libgnunet_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 | ||
2 | exec 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 | |||
31 | struct GNUNET_TESTING_Command | ||
32 | GNUNET_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 | |||
40 | struct GNUNET_TESTING_Command | ||
41 | GNUNET_TRANSPORT_cmd_stop_peer (const char *label, | ||
42 | const char *start_label); | ||
43 | |||
44 | struct GNUNET_TESTING_Command | ||
45 | GNUNET_TRANSPORT_cmd_connect_peers (const char *label, | ||
46 | const char *start_peer_label); | ||
47 | |||
48 | struct GNUNET_TESTING_Command | ||
49 | GNUNET_TRANSPORT_cmd_send_simple (const char *label, | ||
50 | char *m, | ||
51 | char *n, | ||
52 | uint32_t num, | ||
53 | const char *start_peer_label); | ||
54 | |||
55 | int | ||
56 | GNUNET_TRANSPORT_get_trait_peer_id (const struct | ||
57 | GNUNET_TESTING_Command *cmd, | ||
58 | struct GNUNET_PeerIdentity **id); | ||
59 | |||
60 | int | ||
61 | GNUNET_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); | ||
68 | int | ||
69 | GNUNET_TRANSPORT_get_trait_hello_size (const struct | ||
70 | GNUNET_TESTING_Command | ||
71 | *cmd, | ||
72 | size_t **hello_size); | ||
73 | |||
74 | int | ||
75 | GNUNET_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 | ||
25 | struct TngState | 25 | struct 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 | |||
103 | int | ||
104 | GNUNET_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, | |||
920 | char * | 920 | char * |
921 | GNUNET_TRANSPORT_TESTING_get_test_source_name (const char *file); | 921 | GNUNET_TRANSPORT_TESTING_get_test_source_name (const char *file); |
922 | 922 | ||
923 | struct GNUNET_TESTING_Command | ||
924 | GNUNET_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 | |||
931 | struct GNUNET_TESTING_Command | ||
932 | GNUNET_TRANSPORT_cmd_connect_peers (const char *label, | ||
933 | const char *peer1_label, | ||
934 | const char *peer2_label); | ||
935 | |||
936 | int | ||
937 | GNUNET_TRANSPORT_get_trait_peer_id (const struct | ||
938 | GNUNET_TESTING_Command *cmd, | ||
939 | struct GNUNET_PeerIdentity **id); | ||
940 | |||
941 | int | ||
942 | GNUNET_TRANSPORT_get_trait_connected_peers_map (const struct | ||
943 | GNUNET_TESTING_Command | ||
944 | *cmd, | ||
945 | struct | ||
946 | GNUNET_CONTAINER_MultiPeerMap ** | ||
947 | connected_peers_map); | ||
948 | int | ||
949 | GNUNET_TRANSPORT_get_trait_hello_size (const struct | ||
950 | GNUNET_TESTING_Command | ||
951 | *cmd, | ||
952 | size_t **hello_size); | ||
953 | |||
954 | int | ||
955 | GNUNET_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 | */ | ||
38 | struct ConnectPeersState | 43 | struct 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 | */ | ||
46 | static void | 63 | static void |
47 | connect_peers_run (void *cls, | 64 | connect_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 | */ | ||
98 | static int | 138 | static int |
99 | connect_peers_finish (void *cls, | 139 | connect_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 | */ | ||
131 | static int | 179 | static int |
132 | connect_peers_traits (void *cls, | 180 | connect_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 | */ | ||
141 | static void | 193 | static void |
142 | connect_peers_cleanup (void *cls, | 194 | connect_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 | */ |
157 | struct GNUNET_TESTING_Command | 211 | struct GNUNET_TESTING_Command |
158 | GNUNET_TRANSPORT_cmd_connect_peers (const char *label, | 212 | GNUNET_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 | */ | ||
31 | struct SendSimpleState | 36 | struct 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 | */ | ||
44 | static int | 68 | static int |
45 | send_simple_traits (void *cls, | 69 | send_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 | */ | ||
54 | static void | 82 | static void |
55 | send_simple_cleanup (void *cls, | 83 | send_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 | */ | ||
64 | static void | 96 | static void |
65 | send_simple_run (void *cls, | 97 | send_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 | */ |
112 | struct GNUNET_TESTING_Command | 148 | struct GNUNET_TESTING_Command |
113 | GNUNET_TESTING_cmd_send_simple (const char *label, | 149 | GNUNET_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 | ||
38 | struct 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 | ||
114 | static void | 40 | static void |
115 | retrieve_hello (void *cls); | 41 | retrieve_hello (void *cls); |
116 | 42 | ||
43 | |||
44 | /** | ||
45 | * Callback delivering the hello of this peer from peerstore. | ||
46 | * | ||
47 | */ | ||
117 | static void | 48 | static void |
118 | hello_iter_cb (void *cb_cls, | 49 | hello_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 | */ | ||
141 | static void | 77 | static void |
142 | retrieve_hello (void *cls) | 78 | retrieve_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 | */ | ||
155 | static int | 96 | static int |
156 | start_peer_finish (void *cls, | 97 | start_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 | */ | ||
171 | static void | 116 | static void |
172 | notify_disconnect (void *cls, | 117 | notify_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 | */ | ||
187 | static void * | 136 | static void * |
188 | notify_connect (void *cls, | 137 | notify_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 | */ | ||
214 | static void | 178 | static void |
215 | start_peer_run (void *cls, | 179 | start_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 | */ | ||
338 | static void | 318 | static void |
339 | start_peer_cleanup (void *cls, | 319 | start_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 | */ | ||
397 | static int | 344 | static int |
398 | start_peer_traits (void *cls, | 345 | start_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 | */ | ||
407 | int | ||
408 | GNUNET_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 | */ | ||
447 | int | 427 | int |
448 | GNUNET_TRANSPORT_get_trait_hello_size (const struct | 428 | GNUNET_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 | */ | ||
459 | int | 447 | int |
460 | GNUNET_TRANSPORT_get_trait_hello (const struct | 448 | GNUNET_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 | */ | ||
471 | int | 467 | int |
472 | GNUNET_TRANSPORT_get_trait_connected_peers_map (const struct | 468 | GNUNET_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 | */ | ||
486 | int | 489 | int |
487 | GNUNET_TRANSPORT_get_trait_application_handle (const struct | 490 | GNUNET_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 | */ | ||
500 | int | 509 | int |
501 | GNUNET_TRANSPORT_get_trait_peer_id (const struct | 510 | GNUNET_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 | */ |
518 | struct GNUNET_TESTING_Command | 533 | struct 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 | */ | ||
44 | struct 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 | */ | ||
55 | static void | ||
56 | stop_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 | */ | ||
114 | static void | ||
115 | stop_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 | */ | ||
128 | static int | ||
129 | stop_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 | */ | ||
145 | struct GNUNET_TESTING_Command | ||
146 | GNUNET_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 = \ | |||
243 | gnunet_qr_LDFLAGS= -lzbar | 243 | gnunet_qr_LDFLAGS= -lzbar |
244 | 244 | ||
245 | plugin_LTLIBRARIES = \ | 245 | plugin_LTLIBRARIES = \ |
246 | libgnunet_plugin_test.la | 246 | libgnunet_plugin_utiltest.la |
247 | 247 | ||
248 | libgnunet_plugin_test_la_SOURCES = \ | 248 | libgnunet_plugin_utiltest_la_SOURCES = \ |
249 | test_plugin_plug.c | 249 | test_plugin_plug.c |
250 | libgnunet_plugin_test_la_LDFLAGS = \ | 250 | libgnunet_plugin_utiltest_la_LDFLAGS = \ |
251 | $(GN_PLUGIN_LDFLAGS) | 251 | $(GN_PLUGIN_LDFLAGS) |
252 | 252 | ||
253 | if HAVE_BENCHMARKS | 253 | if HAVE_BENCHMARKS |
@@ -362,8 +362,6 @@ test_os_start_process_SOURCES = \ | |||
362 | test_os_start_process.c | 362 | test_os_start_process.c |
363 | test_os_start_process_LDADD = \ | 363 | test_os_start_process_LDADD = \ |
364 | libgnunetutil.la | 364 | libgnunetutil.la |
365 | test_os_start_process_DEPENDENCIES = \ | ||
366 | libgnunetutil.la | ||
367 | 365 | ||
368 | test_client_nc_SOURCES = \ | 366 | test_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 | |||
120 | struct 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 | ||
217 | void | ||
218 | GNUNET_CONFIGURATION_enable_diagnostics (struct | ||
219 | GNUNET_CONFIGURATION_Handle *cfg) | ||
220 | { | ||
221 | cfg->diagnostics = true; | ||
222 | } | ||
223 | |||
224 | |||
112 | struct GNUNET_CONFIGURATION_Handle * | 225 | struct GNUNET_CONFIGURATION_Handle * |
113 | GNUNET_CONFIGURATION_create () | 226 | GNUNET_CONFIGURATION_create () |
114 | { | 227 | { |
@@ -198,9 +311,20 @@ void | |||
198 | GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg) | 311 | GNUNET_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 | */ | ||
358 | struct 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 | */ | ||
381 | static int | ||
382 | collect_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 | */ | ||
401 | static struct ConfigSection * | ||
402 | find_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 | |||
414 | static int | ||
415 | pstrcmp (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 | */ | ||
426 | enum GNUNET_GenericReturnValue | ||
427 | handle_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 | } | ||
627 | cleanup: | ||
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 | */ | ||
650 | static struct ConfigEntry * | ||
651 | find_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 | */ | ||
686 | static void | ||
687 | set_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 | |||
229 | enum GNUNET_GenericReturnValue | 703 | enum GNUNET_GenericReturnValue |
230 | GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, | 704 | GNUNET_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 | ||
1214 | char * | ||
1215 | GNUNET_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 | |||
609 | enum GNUNET_GenericReturnValue | 1325 | enum GNUNET_GenericReturnValue |
610 | GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg, | 1326 | GNUNET_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 | */ | ||
803 | static struct ConfigSection * | ||
804 | find_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 | */ | ||
824 | static struct ConfigEntry * | ||
825 | find_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 | /** | 2287 | enum GNUNET_GenericReturnValue |
1605 | * Wrapper around #GNUNET_CONFIGURATION_parse. Called on each | 2288 | GNUNET_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 | */ | ||
1613 | static enum GNUNET_GenericReturnValue | ||
1614 | parse_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 | } | ||
2322 | cleanup: | ||
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 | ||
1631 | enum GNUNET_GenericReturnValue | 2335 | char * |
1632 | GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg, | 2336 | GNUNET_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 | */ | ||
2449 | int | ||
2450 | GNUNET_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 | */ | ||
36 | static void | ||
37 | print_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 | */ | ||
73 | static void | ||
74 | print_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 | */ | ||
95 | static void | ||
96 | print_section_name (void *cls, | ||
97 | const char *section) | ||
98 | { | ||
99 | (void) cls; | ||
100 | fprintf (stdout, | ||
101 | "%s\n", | ||
102 | section); | ||
103 | } | ||
104 | |||
105 | |||
106 | void | ||
107 | GNUNET_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 | |||
292 | void | ||
293 | GNUNET_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 | */ | ||
41 | int | ||
42 | GNUNET_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 * | |||
77 | doHMAC (gcry_md_hd_t mac, const void *key, size_t key_len, const void *buf, | 77 | doHMAC (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 | /** | |
436 | enum GNUNET_GenericReturnValue | 436 | * Check if fil can be accessed using amode. |
437 | GNUNET_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 | */ | ||
442 | static enum GNUNET_GenericReturnValue | ||
443 | file_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 | ||
475 | enum GNUNET_GenericReturnValue | 481 | enum GNUNET_GenericReturnValue |
482 | GNUNET_DISK_file_test (const char *fil) | ||
483 | { | ||
484 | return file_test_internal (fil, F_OK); | ||
485 | } | ||
486 | |||
487 | |||
488 | enum GNUNET_GenericReturnValue | ||
489 | GNUNET_DISK_file_test_read (const char *fil) | ||
490 | { | ||
491 | return file_test_internal (fil, R_OK); | ||
492 | } | ||
493 | |||
494 | |||
495 | enum GNUNET_GenericReturnValue | ||
476 | GNUNET_DISK_directory_create (const char *dir) | 496 | GNUNET_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 | */ | ||
914 | static bool | ||
915 | glob_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 | |||
954 | struct 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 | */ | ||
975 | static enum GNUNET_GenericReturnValue | ||
976 | glob_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 | |||
1006 | int | ||
1007 | GNUNET_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; |
1000 | FAIL: | 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 | */ | ||
33 | static char *section; | ||
34 | |||
35 | /** | ||
36 | * Name of the option | ||
37 | */ | ||
38 | static char *option; | ||
39 | |||
40 | /** | ||
41 | * Value to set | ||
42 | */ | ||
43 | static 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 | */ |
50 | static char *backend_check; | 35 | static char *backend_check; |
51 | 36 | ||
52 | /** | ||
53 | * Treat option as a filename. | ||
54 | */ | ||
55 | static int is_filename; | ||
56 | |||
57 | /** | ||
58 | * Whether to show the sections. | ||
59 | */ | ||
60 | static int list_sections; | ||
61 | |||
62 | /** | ||
63 | * Return value from 'main'. | ||
64 | */ | ||
65 | static int global_ret; | ||
66 | |||
67 | /** | ||
68 | * Should we write out the configuration file, even if no value was changed? | ||
69 | */ | ||
70 | static int rewrite; | ||
71 | |||
72 | /** | ||
73 | * Should the generated configuration file contain the whole configuration? | ||
74 | */ | ||
75 | static 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 | */ | ||
101 | static void | ||
102 | print_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 | */ | ||
141 | static void | ||
142 | print_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 | */ |
352 | int | 120 | int |
353 | main (int argc, char *const *argv) | 121 | main (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 | §ion), | ||
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 | */ |
303 | static void | 302 | static void |
304 | open_dev_null (int target_fd, int flags) | 303 | open_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 | ||
28 | static void | 28 | static void |
29 | test_cb (void *cls, const char *libname, void *lib_ret) | 29 | test_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 | |||
26 | void * | 27 | void * |
27 | libgnunet_plugin_test_init (void *arg) | 28 | libgnunet_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 | ||
35 | void * | 36 | void * |
36 | libgnunet_plugin_test_done (void *arg) | 37 | libgnunet_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 | ||
33 | gnunet_helper_vpn_SOURCES = \ | 33 | gnunet_helper_vpn_SOURCES = \ |
34 | gnunet-helper-vpn.c | 34 | gnunet-helper-vpn.c |
35 | gnunet_helper_vpn_LDADD = \ | ||
36 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
37 | $(GN_LIBINTL) | ||
35 | 38 | ||
36 | gnunet_service_vpn_SOURCES = \ | 39 | gnunet_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; |
703 | cleanup: | 704 | cleanup: |
704 | close (fd_tun); | 705 | (void) close (fd_tun); |
705 | return global_ret; | 706 | return global_ret; |
706 | } | 707 | } |