diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-04-09 19:39:17 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-04-09 19:39:17 +0000 |
commit | 26852f8f658a38a7e3a5f47e5eb2057080eec3b8 (patch) | |
tree | 41e659fc5944a16aa98b6a764f79447a720911ce | |
parent | a59b71b601cc302a77309dcb8c3db33993117097 (diff) | |
download | gnunet-26852f8f658a38a7e3a5f47e5eb2057080eec3b8.tar.gz gnunet-26852f8f658a38a7e3a5f47e5eb2057080eec3b8.zip |
killing untested, unmaintained, unused sensor/sensordashboard code
49 files changed, 1 insertions, 9437 deletions
diff --git a/configure.ac b/configure.ac index 5b843f249..2b90bc1ee 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -1589,10 +1589,6 @@ src/rps/Makefile | |||
1589 | src/rps/rps.conf | 1589 | src/rps/rps.conf |
1590 | src/secretsharing/Makefile | 1590 | src/secretsharing/Makefile |
1591 | src/secretsharing/secretsharing.conf | 1591 | src/secretsharing/secretsharing.conf |
1592 | src/sensor/Makefile | ||
1593 | src/sensor/sensor.conf | ||
1594 | src/sensordashboard/Makefile | ||
1595 | src/sensordashboard/sensordashboard.conf | ||
1596 | src/scalarproduct/Makefile | 1592 | src/scalarproduct/Makefile |
1597 | src/scalarproduct/scalarproduct.conf | 1593 | src/scalarproduct/scalarproduct.conf |
1598 | src/set/Makefile | 1594 | src/set/Makefile |
diff --git a/src/Makefile.am b/src/Makefile.am index 47d6896cb..38fa42356 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
@@ -8,8 +8,6 @@ if HAVE_TESTING | |||
8 | TESTBED = testbed | 8 | TESTBED = testbed |
9 | CONSENSUS = consensus | 9 | CONSENSUS = consensus |
10 | SECRETSHARING = secretsharing | 10 | SECRETSHARING = secretsharing |
11 | SENSOR = sensor | ||
12 | SENSORDASHBOARD = sensordashboard | ||
13 | endif | 11 | endif |
14 | 12 | ||
15 | if HAVE_EXPERIMENTAL | 13 | if HAVE_EXPERIMENTAL |
@@ -22,9 +20,7 @@ if HAVE_EXPERIMENTAL | |||
22 | rps \ | 20 | rps \ |
23 | social \ | 21 | social \ |
24 | $(CONSENSUS) \ | 22 | $(CONSENSUS) \ |
25 | $(SECRETSHARING) \ | 23 | $(SECRETSHARING) |
26 | $(SENSOR) \ | ||
27 | $(SENSORDASHBOARD) | ||
28 | endif | 24 | endif |
29 | 25 | ||
30 | if HAVE_REST | 26 | if HAVE_REST |
diff --git a/src/sensor/Makefile.am b/src/sensor/Makefile.am deleted file mode 100644 index b62885d0c..000000000 --- a/src/sensor/Makefile.am +++ /dev/null | |||
@@ -1,140 +0,0 @@ | |||
1 | # 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 | plugindir = $(libdir)/gnunet | ||
9 | |||
10 | dist_pkgcfg_DATA = \ | ||
11 | sensor.conf | ||
12 | |||
13 | if MINGW | ||
14 | WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols | ||
15 | endif | ||
16 | |||
17 | if USE_COVERAGE | ||
18 | AM_CFLAGS = -fprofile-arcs -ftest-coverage | ||
19 | endif | ||
20 | |||
21 | bin_PROGRAMS = \ | ||
22 | gnunet-sensor | ||
23 | |||
24 | noinst_PROGRAMS = \ | ||
25 | gnunet-sensor-profiler \ | ||
26 | perf-pow-sign | ||
27 | |||
28 | libexec_PROGRAMS = \ | ||
29 | gnunet-service-sensor | ||
30 | |||
31 | lib_LTLIBRARIES = \ | ||
32 | libgnunetsensor.la \ | ||
33 | libgnunetsensorutil.la | ||
34 | |||
35 | gnunet_sensor_SOURCES = \ | ||
36 | gnunet-sensor.c | ||
37 | gnunet_sensor_LDADD = \ | ||
38 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
39 | libgnunetsensor.la \ | ||
40 | $(GN_LIBINTL) | ||
41 | |||
42 | gnunet_service_sensor_SOURCES = \ | ||
43 | gnunet-service-sensor.c \ | ||
44 | gnunet-service-sensor_monitoring.c \ | ||
45 | gnunet-service-sensor_analysis.c \ | ||
46 | gnunet-service-sensor_reporting.c \ | ||
47 | gnunet-service-sensor_update.c | ||
48 | gnunet_service_sensor_LDADD = \ | ||
49 | libgnunetsensorutil.la \ | ||
50 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
51 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
52 | $(top_builddir)/src/peerstore/libgnunetpeerstore.la \ | ||
53 | $(top_builddir)/src/cadet/libgnunetcadet.la \ | ||
54 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
55 | $(GN_LIBINTL) | ||
56 | |||
57 | libgnunetsensor_la_SOURCES = \ | ||
58 | sensor_api.c | ||
59 | libgnunetsensor_la_LIBADD = \ | ||
60 | $(top_builddir)/src/util/libgnunetutil.la | ||
61 | libgnunetsensor_la_LDFLAGS = \ | ||
62 | $(GN_LIB_LDFLAGS) | ||
63 | |||
64 | libgnunetsensorutil_la_SOURCES = \ | ||
65 | sensor_util_lib.c \ | ||
66 | sensor_util_lib_crypto.c | ||
67 | libgnunetsensorutil_la_LIBADD = \ | ||
68 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
69 | $(top_builddir)/src/statistics/libgnunetstatistics.la | ||
70 | libgnunetsensorutil_la_LDFLAGS = \ | ||
71 | $(GN_LIB_LDFLAGS) | ||
72 | |||
73 | plugin_LTLIBRARIES = \ | ||
74 | libgnunet_plugin_sensor_model_gaussian.la | ||
75 | |||
76 | libgnunet_plugin_sensor_model_gaussian_la_SOURCES = \ | ||
77 | plugin_sensor_model_gaussian.c | ||
78 | libgnunet_plugin_sensor_model_gaussian_la_LIBADD = \ | ||
79 | libgnunetsensor.la \ | ||
80 | $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ | ||
81 | $(LTLIBINTL) | ||
82 | libgnunet_plugin_sensor_model_gaussian_la_LDFLAGS = \ | ||
83 | $(GN_PLUGIN_LDFLAGS) | ||
84 | |||
85 | check_PROGRAMS = \ | ||
86 | test_sensor_api \ | ||
87 | test_gnunet-service-sensor_reporting \ | ||
88 | test_pow_sign | ||
89 | |||
90 | if ENABLE_TEST_RUN | ||
91 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; | ||
92 | TESTS = $(check_PROGRAMS) | ||
93 | endif | ||
94 | |||
95 | test_sensor_api_SOURCES = \ | ||
96 | test_sensor_api.c | ||
97 | test_sensor_api_LDADD = \ | ||
98 | $(top_builddir)/src/util/libgnunetutil.la | ||
99 | |||
100 | test_gnunet_service_sensor_reporting_SOURCES = \ | ||
101 | test_gnunet-service-sensor_reporting.c | ||
102 | test_gnunet_service_sensor_reporting_LDADD = \ | ||
103 | libgnunetsensor.la \ | ||
104 | libgnunetsensorutil.la \ | ||
105 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
106 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
107 | $(top_builddir)/src/peerstore/libgnunetpeerstore.la | ||
108 | |||
109 | test_pow_sign_SOURCES = \ | ||
110 | test_pow_sign.c | ||
111 | test_pow_sign_LDADD = \ | ||
112 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
113 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
114 | libgnunetsensorutil.la | ||
115 | |||
116 | gnunet_sensor_profiler_SOURCES = \ | ||
117 | gnunet-sensor-profiler.c | ||
118 | gnunet_sensor_profiler_LDADD = \ | ||
119 | libgnunetsensor.la \ | ||
120 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
121 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
122 | $(top_builddir)/src/peerstore/libgnunetpeerstore.la \ | ||
123 | $(top_builddir)/src/statistics/libgnunetstatistics.la | ||
124 | |||
125 | perf_pow_sign_SOURCES = \ | ||
126 | perf_pow_sign.c | ||
127 | perf_pow_sign_LDADD = \ | ||
128 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
129 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
130 | libgnunetsensorutil.la | ||
131 | |||
132 | EXTRA_DIST = sensors | ||
133 | pkgsensordir = sensors | ||
134 | |||
135 | install-data-local: | ||
136 | $(mkinstalldirs) $(DESTDIR)$(datadir)/$(PACKAGE)/$(pkgsensordir) | ||
137 | @$(NORMAL_INSTALL) | ||
138 | for sensor in $(pkgsensordir)/*; do \ | ||
139 | cp -a $$sensor $(DESTDIR)$(datadir)/$(PACKAGE)/$(pkgsensordir)/ ; \ | ||
140 | done | ||
diff --git a/src/sensor/gnunet-sensor-profiler.c b/src/sensor/gnunet-sensor-profiler.c deleted file mode 100644 index 716fbd625..000000000 --- a/src/sensor/gnunet-sensor-profiler.c +++ /dev/null | |||
@@ -1,801 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensor/gnunet-sensor-profiler.c | ||
23 | * @brief Profiler for the sensor service | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testbed_service.h" | ||
29 | #include "gnunet_peerstore_service.h" | ||
30 | #include "gnunet_sensor_service.h" | ||
31 | #include "gnunet_sensor_util_lib.h" | ||
32 | #include "gnunet_transport_service.h" | ||
33 | |||
34 | /** | ||
35 | * Time to wait for the peer to startup completely | ||
36 | */ | ||
37 | #define PEER_STARTUP_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) | ||
38 | |||
39 | /** | ||
40 | * Information about a single peer | ||
41 | */ | ||
42 | struct PeerInfo | ||
43 | { | ||
44 | |||
45 | /** | ||
46 | * Peer Identity | ||
47 | */ | ||
48 | struct GNUNET_PeerIdentity peer_id; | ||
49 | |||
50 | /** | ||
51 | * Testbed peer handle | ||
52 | */ | ||
53 | struct GNUNET_TESTBED_Peer *testbed_peer; | ||
54 | |||
55 | /** | ||
56 | * Index of this peer within our list | ||
57 | */ | ||
58 | int index; | ||
59 | |||
60 | /** | ||
61 | * TESTBED operation used to connect to statistics service | ||
62 | */ | ||
63 | struct GNUNET_TESTBED_Operation *statistics_op; | ||
64 | |||
65 | /** | ||
66 | * Handle to the peer's statistics service | ||
67 | */ | ||
68 | struct GNUNET_STATISTICS_Handle *statistics; | ||
69 | |||
70 | }; | ||
71 | |||
72 | /** | ||
73 | * Name of the configuration file used | ||
74 | */ | ||
75 | static const char *cfg_filename = "gnunet-sensor-profiler.conf"; | ||
76 | |||
77 | /** | ||
78 | * Directory to read sensor definitions from | ||
79 | */ | ||
80 | static const char *sensor_src_dir = "sensors"; | ||
81 | |||
82 | /** | ||
83 | * Directory to write new sensor definitions to | ||
84 | */ | ||
85 | static const char *sensor_dst_dir = "/tmp/gnunet-sensor-profiler"; | ||
86 | |||
87 | /** | ||
88 | * Scheduled task to shutdown | ||
89 | */ | ||
90 | static struct GNUNET_SCHEDULER_Task * shutdown_task = NULL; | ||
91 | |||
92 | /** | ||
93 | * GNUnet configuration | ||
94 | */ | ||
95 | static struct GNUNET_CONFIGURATION_Handle *cfg; | ||
96 | |||
97 | /** | ||
98 | * Number of peers to run (Option -p) | ||
99 | */ | ||
100 | static unsigned int num_peers = 0; | ||
101 | |||
102 | /** | ||
103 | * Set sensors running interval to this value (Option -i) | ||
104 | */ | ||
105 | static unsigned int sensors_interval = 0; | ||
106 | |||
107 | /** | ||
108 | * Path to topology file (Option -t) | ||
109 | */ | ||
110 | static char *topology_file; | ||
111 | |||
112 | /** | ||
113 | * Number of peers to simulate anomalies on (Option -a) | ||
114 | */ | ||
115 | static unsigned int anomalous_peers = 0; | ||
116 | |||
117 | /** | ||
118 | * Array of peer info for all peers | ||
119 | */ | ||
120 | static struct PeerInfo *all_peers_info; | ||
121 | |||
122 | /** | ||
123 | * Number of peers that we already collected and start their info | ||
124 | */ | ||
125 | static int peers_known = 0; | ||
126 | |||
127 | /** | ||
128 | * TESTBED operation connecting us to peerstore service on collection point | ||
129 | */ | ||
130 | static struct GNUNET_TESTBED_Operation *peerstore_op; | ||
131 | |||
132 | /** | ||
133 | * Handle to peerstore service on collection point | ||
134 | */ | ||
135 | static struct GNUNET_PEERSTORE_Handle *peerstore; | ||
136 | |||
137 | /** | ||
138 | * Dashboard service on collection point started? | ||
139 | */ | ||
140 | static int dashboard_service_started = GNUNET_NO; | ||
141 | |||
142 | /** | ||
143 | * Number of peers started the sensor service successfully | ||
144 | */ | ||
145 | static int sensor_services_started = 0; | ||
146 | |||
147 | /** | ||
148 | * Array of sensor names to be used for watching peerstore records | ||
149 | */ | ||
150 | static char **sensor_names; | ||
151 | |||
152 | /** | ||
153 | * Size of 'sensor_names' array | ||
154 | */ | ||
155 | static unsigned int sensor_names_size = 0; | ||
156 | |||
157 | /** | ||
158 | * Task run after any waiting period | ||
159 | */ | ||
160 | static struct GNUNET_SCHEDULER_Task * delayed_task = NULL; | ||
161 | |||
162 | |||
163 | /** | ||
164 | * Copy directory recursively | ||
165 | * | ||
166 | * @param src Path to source directory | ||
167 | * @param dst Destination directory, will be created if it does not exist | ||
168 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
169 | */ | ||
170 | static int | ||
171 | copy_dir (const char *src, const char *dst); | ||
172 | |||
173 | |||
174 | /** | ||
175 | * Do clean up and shutdown scheduler | ||
176 | */ | ||
177 | static void | ||
178 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
179 | { | ||
180 | int i; | ||
181 | |||
182 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down.\n"); | ||
183 | if (NULL != delayed_task) | ||
184 | { | ||
185 | GNUNET_SCHEDULER_cancel (delayed_task); | ||
186 | delayed_task = NULL; | ||
187 | } | ||
188 | for (i = 0; i < num_peers; i++) | ||
189 | { | ||
190 | if (NULL != all_peers_info[i].statistics_op) | ||
191 | { | ||
192 | GNUNET_TESTBED_operation_done (all_peers_info[i].statistics_op); | ||
193 | all_peers_info[i].statistics_op = NULL; | ||
194 | } | ||
195 | } | ||
196 | if (NULL != peerstore_op) | ||
197 | { | ||
198 | GNUNET_TESTBED_operation_done (peerstore_op); | ||
199 | peerstore_op = NULL; | ||
200 | } | ||
201 | if (NULL != all_peers_info) | ||
202 | { | ||
203 | GNUNET_free (all_peers_info); | ||
204 | all_peers_info = NULL; | ||
205 | } | ||
206 | if (NULL != cfg) | ||
207 | { | ||
208 | GNUNET_CONFIGURATION_destroy (cfg); | ||
209 | cfg = NULL; | ||
210 | } | ||
211 | if (NULL != sensor_names) | ||
212 | { | ||
213 | for (i = 0; i < sensor_names_size; i++) | ||
214 | GNUNET_free (sensor_names[i]); | ||
215 | GNUNET_array_grow (sensor_names, sensor_names_size, 0); | ||
216 | } | ||
217 | GNUNET_SCHEDULER_shutdown (); | ||
218 | } | ||
219 | |||
220 | |||
221 | /** | ||
222 | * Function called with each file/folder inside a directory that is being copied. | ||
223 | * | ||
224 | * @param cls closure, destination directory | ||
225 | * @param filename complete filename (absolute path) | ||
226 | * @return #GNUNET_OK to continue to iterate. | ||
227 | * #GNUNET_SYSERR to abort iteration with error | ||
228 | */ | ||
229 | static int | ||
230 | copy_dir_scanner (void *cls, const char *filename) | ||
231 | { | ||
232 | char *dst_dir = cls; | ||
233 | char *dst; | ||
234 | int copy_result; | ||
235 | |||
236 | GNUNET_asprintf (&dst, "%s%s%s", dst_dir, DIR_SEPARATOR_STR, | ||
237 | GNUNET_STRINGS_get_short_name (filename)); | ||
238 | if (GNUNET_YES == GNUNET_DISK_directory_test (filename, GNUNET_YES)) | ||
239 | copy_result = copy_dir (filename, dst); | ||
240 | else | ||
241 | { | ||
242 | if (GNUNET_YES == GNUNET_DISK_file_test (dst)) | ||
243 | GNUNET_DISK_directory_remove (dst); | ||
244 | copy_result = GNUNET_DISK_file_copy (filename, dst); | ||
245 | if (GNUNET_OK == copy_result) | ||
246 | GNUNET_DISK_fix_permissions (dst, GNUNET_NO, GNUNET_NO); | ||
247 | } | ||
248 | GNUNET_free (dst); | ||
249 | return copy_result; | ||
250 | } | ||
251 | |||
252 | |||
253 | /** | ||
254 | * Copy directory recursively | ||
255 | * | ||
256 | * @param src Path to source directory | ||
257 | * @param dst Destination directory, will be created if it does not exist | ||
258 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
259 | */ | ||
260 | static int | ||
261 | copy_dir (const char *src, const char *dst) | ||
262 | { | ||
263 | if (GNUNET_YES != GNUNET_DISK_directory_test (src, GNUNET_YES)) | ||
264 | return GNUNET_SYSERR; | ||
265 | if (GNUNET_OK != GNUNET_DISK_directory_create (dst)) | ||
266 | return GNUNET_SYSERR; | ||
267 | if (GNUNET_SYSERR == | ||
268 | GNUNET_DISK_directory_scan (src, ©_dir_scanner, (char *) dst)) | ||
269 | return GNUNET_SYSERR; | ||
270 | return GNUNET_OK; | ||
271 | } | ||
272 | |||
273 | |||
274 | /** | ||
275 | * Function called with each file/folder inside source sensor directory. | ||
276 | * | ||
277 | * @param cls closure (unused) | ||
278 | * @param filename complete filename (absolute path) | ||
279 | * @return #GNUNET_OK to continue to iterate. | ||
280 | */ | ||
281 | static int | ||
282 | sensor_dir_scanner (void *cls, const char *filename) | ||
283 | { | ||
284 | const char *file_basename; | ||
285 | char *dst_path; | ||
286 | struct GNUNET_CONFIGURATION_Handle *sensor_cfg; | ||
287 | char *sensor_name; | ||
288 | |||
289 | file_basename = GNUNET_STRINGS_get_short_name (filename); | ||
290 | GNUNET_asprintf (&dst_path, "%s%s%s", sensor_dst_dir, DIR_SEPARATOR_STR, | ||
291 | file_basename); | ||
292 | if (GNUNET_YES == GNUNET_DISK_directory_test (filename, GNUNET_NO)) | ||
293 | { | ||
294 | GNUNET_assert (GNUNET_OK == copy_dir (filename, dst_path)); | ||
295 | } | ||
296 | else | ||
297 | { | ||
298 | sensor_name = GNUNET_strdup (file_basename); | ||
299 | GNUNET_array_append (sensor_names, sensor_names_size, sensor_name); | ||
300 | sensor_cfg = GNUNET_CONFIGURATION_create (); | ||
301 | GNUNET_assert (GNUNET_OK == | ||
302 | GNUNET_CONFIGURATION_parse (sensor_cfg, filename)); | ||
303 | GNUNET_CONFIGURATION_set_value_string (sensor_cfg, file_basename, | ||
304 | "COLLECTION_POINT", | ||
305 | GNUNET_i2s_full (&all_peers_info | ||
306 | [0].peer_id)); | ||
307 | if (sensors_interval > 0) | ||
308 | { | ||
309 | GNUNET_CONFIGURATION_set_value_number (sensor_cfg, file_basename, | ||
310 | "INTERVAL", | ||
311 | (unsigned long long int) | ||
312 | sensors_interval); | ||
313 | } | ||
314 | GNUNET_CONFIGURATION_write (sensor_cfg, dst_path); | ||
315 | GNUNET_CONFIGURATION_destroy (sensor_cfg); | ||
316 | } | ||
317 | GNUNET_free (dst_path); | ||
318 | return GNUNET_OK; | ||
319 | } | ||
320 | |||
321 | |||
322 | /** | ||
323 | * Load sensor definitions and rewrite them to tmp location. | ||
324 | * Add collection point peer id and change running interval if needed. | ||
325 | */ | ||
326 | static void | ||
327 | rewrite_sensors () | ||
328 | { | ||
329 | GNUNET_assert (GNUNET_YES == | ||
330 | GNUNET_DISK_directory_test (sensor_src_dir, GNUNET_YES)); | ||
331 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_create (sensor_dst_dir)); | ||
332 | GNUNET_DISK_directory_scan (sensor_src_dir, &sensor_dir_scanner, NULL); | ||
333 | } | ||
334 | |||
335 | |||
336 | /** | ||
337 | * Callback to be called when dashboard service is started | ||
338 | * | ||
339 | * @param cls the callback closure from functions generating an operation | ||
340 | * @param op the operation that has been finished | ||
341 | * @param emsg error message in case the operation has failed; will be NULL if | ||
342 | * operation has executed successfully. | ||
343 | */ | ||
344 | static void | ||
345 | dashboard_started (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
346 | const char *emsg) | ||
347 | { | ||
348 | if (NULL != emsg) | ||
349 | { | ||
350 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ERROR: %s.\n", emsg); | ||
351 | GNUNET_assert (0); | ||
352 | } | ||
353 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Dashboard service started.\n"); | ||
354 | GNUNET_TESTBED_operation_done (op); | ||
355 | dashboard_service_started = GNUNET_YES; | ||
356 | } | ||
357 | |||
358 | |||
359 | /** | ||
360 | * Function called by PEERSTORE for each matching record. | ||
361 | * | ||
362 | * @param cls closure | ||
363 | * @param record peerstore record information | ||
364 | * @param emsg error message, or NULL if no errors | ||
365 | * @return #GNUNET_YES to continue iterating, #GNUNET_NO to stop | ||
366 | */ | ||
367 | static int | ||
368 | peerstore_watch_cb (void *cls, | ||
369 | const struct GNUNET_PEERSTORE_Record *record, | ||
370 | const char *emsg) | ||
371 | { | ||
372 | struct PeerInfo *peer = cls; | ||
373 | struct GNUNET_SENSOR_DashboardAnomalyEntry *anomaly; | ||
374 | |||
375 | if (NULL != emsg) | ||
376 | { | ||
377 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ERROR: %s.\n", emsg); | ||
378 | GNUNET_assert (0); | ||
379 | } | ||
380 | GNUNET_assert (record->value_size == | ||
381 | sizeof (struct GNUNET_SENSOR_DashboardAnomalyEntry)); | ||
382 | anomaly = record->value; | ||
383 | GNUNET_assert (0 == | ||
384 | GNUNET_CRYPTO_cmp_peer_identity (&peer->peer_id, | ||
385 | record->peer)); | ||
386 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
387 | "Anomaly report:{'peerid': '%s'," "'peer': %d," "'sensor': '%s'," | ||
388 | "'anomalous': %d," "'neighbors': %f}\n", | ||
389 | GNUNET_i2s (&peer->peer_id), peer->index, record->key, | ||
390 | anomaly->anomalous, anomaly->anomalous_neighbors); | ||
391 | return GNUNET_YES; | ||
392 | } | ||
393 | |||
394 | |||
395 | /** | ||
396 | * Callback to be called when peerstore service connect operation is completed | ||
397 | * | ||
398 | * @param cls the callback closure from functions generating an operation | ||
399 | * @param op the operation that has been finished | ||
400 | * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() | ||
401 | * @param emsg error message in case the operation has failed; will be NULL if | ||
402 | * operation has executed successfully. | ||
403 | */ | ||
404 | static void | ||
405 | peerstore_connect_cb (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
406 | void *ca_result, const char *emsg) | ||
407 | { | ||
408 | int i; | ||
409 | int j; | ||
410 | struct PeerInfo *peer; | ||
411 | |||
412 | if (NULL != emsg) | ||
413 | { | ||
414 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ERROR: %s.\n", emsg); | ||
415 | GNUNET_assert (0); | ||
416 | } | ||
417 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to peerstore service.\n"); | ||
418 | /* Watch for anomaly reports from other peers */ | ||
419 | for (i = 0; i < num_peers; i++) | ||
420 | { | ||
421 | peer = &all_peers_info[i]; | ||
422 | for (j = 0; j < sensor_names_size; j++) | ||
423 | { | ||
424 | GNUNET_PEERSTORE_watch (peerstore, "sensordashboard-anomalies", | ||
425 | &peer->peer_id, sensor_names[j], | ||
426 | &peerstore_watch_cb, peer); | ||
427 | } | ||
428 | } | ||
429 | } | ||
430 | |||
431 | |||
432 | /** | ||
433 | * Adapter function called to establish a connection to peerstore service. | ||
434 | * | ||
435 | * @param cls closure | ||
436 | * @param cfg configuration of the peer to connect to; will be available until | ||
437 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
438 | * from GNUNET_TESTBED_service_connect() | ||
439 | * @return service handle to return in 'op_result', NULL on error | ||
440 | */ | ||
441 | static void * | ||
442 | peerstore_connect_adapter (void *cls, | ||
443 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
444 | { | ||
445 | peerstore = GNUNET_PEERSTORE_connect (cfg); | ||
446 | GNUNET_assert (NULL != peerstore); | ||
447 | return peerstore; | ||
448 | } | ||
449 | |||
450 | |||
451 | /** | ||
452 | * Adapter function called to destroy a connection to peerstore service. | ||
453 | * | ||
454 | * @param cls closure | ||
455 | * @param op_result service handle returned from the connect adapter | ||
456 | */ | ||
457 | static void | ||
458 | peerstore_disconnect_adapter (void *cls, void *op_result) | ||
459 | { | ||
460 | GNUNET_PEERSTORE_disconnect (peerstore, GNUNET_NO); | ||
461 | peerstore = NULL; | ||
462 | peerstore_op = NULL; | ||
463 | } | ||
464 | |||
465 | |||
466 | /** | ||
467 | * Callback to be called when statistics service connect operation is completed | ||
468 | * | ||
469 | * @param cls the callback closure from functions generating an operation | ||
470 | * @param op the operation that has been finished | ||
471 | * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() | ||
472 | * @param emsg error message in case the operation has failed; will be NULL if | ||
473 | * operation has executed successfully. | ||
474 | */ | ||
475 | static void | ||
476 | statistics_connect_cb (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
477 | void *ca_result, const char *emsg) | ||
478 | { | ||
479 | struct PeerInfo *peer = cls; | ||
480 | |||
481 | if (NULL != emsg) | ||
482 | { | ||
483 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ERROR: %s.\n", emsg); | ||
484 | GNUNET_assert (0); | ||
485 | } | ||
486 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
487 | "Connected to statistics service on peer `%s'.\n", GNUNET_i2s (&peer->peer_id)); | ||
488 | GNUNET_STATISTICS_set (peer->statistics, "# peers connected", 0, GNUNET_NO); | ||
489 | } | ||
490 | |||
491 | |||
492 | /** | ||
493 | * Adapter function called to establish a connection to statistics service. | ||
494 | * | ||
495 | * @param cls closure | ||
496 | * @param cfg configuration of the peer to connect to; will be available until | ||
497 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
498 | * from GNUNET_TESTBED_service_connect() | ||
499 | * @return service handle to return in 'op_result', NULL on error | ||
500 | */ | ||
501 | static void * | ||
502 | statistics_connect_adapter (void *cls, | ||
503 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
504 | { | ||
505 | struct PeerInfo *peer = cls; | ||
506 | |||
507 | peer->statistics = GNUNET_STATISTICS_create ("core", cfg); | ||
508 | GNUNET_assert (NULL != peer->statistics); | ||
509 | return peer->statistics; | ||
510 | } | ||
511 | |||
512 | |||
513 | /** | ||
514 | * Adapter function called to destroy a connection to statistics service. | ||
515 | * | ||
516 | * @param cls closure | ||
517 | * @param op_result service handle returned from the connect adapter | ||
518 | */ | ||
519 | static void | ||
520 | statistics_disconnect_adapter (void *cls, void *op_result) | ||
521 | { | ||
522 | struct PeerInfo *peer = cls; | ||
523 | |||
524 | GNUNET_STATISTICS_destroy (peer->statistics, GNUNET_NO); | ||
525 | peer->statistics = NULL; | ||
526 | } | ||
527 | |||
528 | |||
529 | /** | ||
530 | * This function is called after the estimated training period is over. | ||
531 | */ | ||
532 | static void | ||
533 | simulate_anomalies (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
534 | { | ||
535 | int i; | ||
536 | uint32_t an_peer; | ||
537 | struct GNUNET_TIME_Relative shutdown_delay; | ||
538 | |||
539 | delayed_task = NULL; | ||
540 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
541 | "Training period over, simulating anomalies now.\n"); | ||
542 | GNUNET_assert (anomalous_peers <= num_peers); | ||
543 | for (i = 0; i < anomalous_peers; i++) | ||
544 | { | ||
545 | an_peer = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, num_peers); | ||
546 | if (NULL != all_peers_info[an_peer].statistics_op) | ||
547 | { | ||
548 | i--; | ||
549 | continue; | ||
550 | } | ||
551 | all_peers_info[an_peer].statistics_op = | ||
552 | GNUNET_TESTBED_service_connect (NULL, all_peers_info[an_peer].testbed_peer, | ||
553 | "statistics", &statistics_connect_cb, | ||
554 | &all_peers_info[an_peer], &statistics_connect_adapter, | ||
555 | &statistics_disconnect_adapter, &all_peers_info[an_peer]); | ||
556 | } | ||
557 | shutdown_delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, num_peers * 6); | ||
558 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down in %s\n", | ||
559 | GNUNET_STRINGS_relative_time_to_string (shutdown_delay, GNUNET_NO)); | ||
560 | GNUNET_SCHEDULER_cancel (shutdown_task); | ||
561 | shutdown_task = GNUNET_SCHEDULER_add_delayed (shutdown_delay, &do_shutdown, NULL); | ||
562 | } | ||
563 | |||
564 | |||
565 | /** | ||
566 | * This function is called after a delay which ensures that all peers are | ||
567 | * properly initialized | ||
568 | */ | ||
569 | static void | ||
570 | peers_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
571 | { | ||
572 | unsigned long long int training_points; | ||
573 | struct GNUNET_TIME_Relative training_period; | ||
574 | |||
575 | delayed_task = NULL; | ||
576 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers are ready.\n"); | ||
577 | GNUNET_assert (GNUNET_OK == | ||
578 | GNUNET_CONFIGURATION_get_value_number (cfg, | ||
579 | "sensor-model-gaussian", | ||
580 | "TRAINING_WINDOW", | ||
581 | &training_points)); | ||
582 | training_period = | ||
583 | GNUNET_TIME_relative_multiply (GNUNET_TIME_relative_multiply | ||
584 | (GNUNET_TIME_UNIT_SECONDS, | ||
585 | (sensors_interval == | ||
586 | 0) ? 60 : sensors_interval), | ||
587 | training_points); | ||
588 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
589 | "Sleeping for a training period of %s.\n", | ||
590 | GNUNET_STRINGS_relative_time_to_string (training_period, | ||
591 | GNUNET_NO)); | ||
592 | delayed_task = | ||
593 | GNUNET_SCHEDULER_add_delayed (training_period, &simulate_anomalies, NULL); | ||
594 | } | ||
595 | |||
596 | |||
597 | /** | ||
598 | * Callback to be called when sensor service is started | ||
599 | * | ||
600 | * @param cls the callback closure from functions generating an operation | ||
601 | * @param op the operation that has been finished | ||
602 | * @param emsg error message in case the operation has failed; will be NULL if | ||
603 | * operation has executed successfully. | ||
604 | */ | ||
605 | static void | ||
606 | sensor_service_started (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
607 | const char *emsg) | ||
608 | { | ||
609 | struct PeerInfo *peer = cls; | ||
610 | |||
611 | if (NULL != emsg) | ||
612 | { | ||
613 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ERROR: %s.\n", emsg); | ||
614 | GNUNET_assert (0); | ||
615 | } | ||
616 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sensor service started on peer `%s'.\n", | ||
617 | GNUNET_i2s (&peer->peer_id)); | ||
618 | GNUNET_TESTBED_operation_done (op); | ||
619 | sensor_services_started++; | ||
620 | if (sensor_services_started == num_peers) | ||
621 | { | ||
622 | delayed_task = | ||
623 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | ||
624 | (PEER_STARTUP_TIME, num_peers), | ||
625 | &peers_ready, NULL); | ||
626 | } | ||
627 | } | ||
628 | |||
629 | |||
630 | /** | ||
631 | * Callback to be called when the requested peer information is available | ||
632 | * | ||
633 | * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information() | ||
634 | * @param op the operation this callback corresponds to | ||
635 | * @param pinfo the result; will be NULL if the operation has failed | ||
636 | * @param emsg error message if the operation has failed; will be NULL if the | ||
637 | * operation is successfull | ||
638 | */ | ||
639 | static void | ||
640 | peer_info_cb (void *cb_cls, struct GNUNET_TESTBED_Operation *op, | ||
641 | const struct GNUNET_TESTBED_PeerInformation *pinfo, | ||
642 | const char *emsg) | ||
643 | { | ||
644 | struct GNUNET_TESTBED_Peer *testbed_peer = cb_cls; | ||
645 | struct PeerInfo *peer = &all_peers_info[peers_known]; | ||
646 | |||
647 | if (NULL != emsg) | ||
648 | { | ||
649 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ERROR: %s.\n", emsg); | ||
650 | GNUNET_assert (0); | ||
651 | } | ||
652 | peer->testbed_peer = testbed_peer; | ||
653 | GNUNET_CRYPTO_get_peer_identity (pinfo->result.cfg, &peer->peer_id); | ||
654 | peer->index = peers_known; | ||
655 | peers_known++; | ||
656 | if (1 == peers_known) /* First peer is collection point */ | ||
657 | { | ||
658 | /* Rewrite sensors */ | ||
659 | rewrite_sensors (); | ||
660 | /* Start dashboard */ | ||
661 | GNUNET_TESTBED_peer_manage_service (NULL, testbed_peer, "sensordashboard", | ||
662 | &dashboard_started, NULL, 1); | ||
663 | } | ||
664 | /* Start sensor service on every peer */ | ||
665 | GNUNET_TESTBED_peer_manage_service (NULL, testbed_peer, "sensor", | ||
666 | &sensor_service_started, peer, 1); | ||
667 | if (num_peers == peers_known) /* Last peer */ | ||
668 | { | ||
669 | /* Connect to peerstore on first peer (collection point) */ | ||
670 | peerstore_op = | ||
671 | GNUNET_TESTBED_service_connect (NULL, all_peers_info[0].testbed_peer, | ||
672 | "peerstore", &peerstore_connect_cb, | ||
673 | NULL, &peerstore_connect_adapter, | ||
674 | &peerstore_disconnect_adapter, NULL); | ||
675 | } | ||
676 | GNUNET_TESTBED_operation_done (op); | ||
677 | } | ||
678 | |||
679 | |||
680 | /** | ||
681 | * Signature of a main function for a testcase. | ||
682 | * | ||
683 | * @param cls closure | ||
684 | * @param h the run handle | ||
685 | * @param num number of peers in 'peers' | ||
686 | * @param peers handle to peers run in the testbed. NULL upon timeout (see | ||
687 | * GNUNET_TESTBED_test_run()). | ||
688 | * @param links_succeeded the number of overlay link connection attempts that | ||
689 | * succeeded | ||
690 | * @param links_failed the number of overlay link connection attempts that | ||
691 | * failed | ||
692 | * @see GNUNET_TESTBED_test_run() | ||
693 | */ | ||
694 | static void | ||
695 | test_master (void *cls, struct GNUNET_TESTBED_RunHandle *h, unsigned int num, | ||
696 | struct GNUNET_TESTBED_Peer **peers, unsigned int links_succeeded, | ||
697 | unsigned int links_failed) | ||
698 | { | ||
699 | int i; | ||
700 | |||
701 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
702 | "%d peers started. %d links succeeded. %d links failed.\n", | ||
703 | num_peers, links_succeeded, links_failed); | ||
704 | GNUNET_assert (num == num_peers); | ||
705 | /* Collect peer information */ | ||
706 | all_peers_info = GNUNET_new_array (num_peers, struct PeerInfo); | ||
707 | |||
708 | for (i = 0; i < num_peers; i++) | ||
709 | { | ||
710 | GNUNET_TESTBED_peer_get_information (peers[i], | ||
711 | GNUNET_TESTBED_PIT_CONFIGURATION, | ||
712 | &peer_info_cb, peers[i]); | ||
713 | } | ||
714 | } | ||
715 | |||
716 | |||
717 | /** | ||
718 | * Verify that the user passed correct CL args | ||
719 | * | ||
720 | * @return #GNUNET_OK if arguments are valid, #GNUNET_SYSERR otherwise | ||
721 | */ | ||
722 | static int | ||
723 | verify_args () | ||
724 | { | ||
725 | if (num_peers < 2) | ||
726 | { | ||
727 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
728 | _ | ||
729 | ("Invalid or missing number of peers. Set at least 2 peers.\n")); | ||
730 | return GNUNET_SYSERR; | ||
731 | } | ||
732 | if (NULL == topology_file || | ||
733 | GNUNET_YES != GNUNET_DISK_file_test (topology_file)) | ||
734 | { | ||
735 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
736 | _("Missing or invalid topology file.\n")); | ||
737 | return GNUNET_SYSERR; | ||
738 | } | ||
739 | return GNUNET_OK; | ||
740 | } | ||
741 | |||
742 | |||
743 | /** | ||
744 | * Actual main function. | ||
745 | * | ||
746 | * @param cls unused | ||
747 | * @param args remaining args, unused | ||
748 | * @param cfgfile name of the configuration | ||
749 | * @param cfg configuration handle | ||
750 | */ | ||
751 | static void | ||
752 | run (void *cls, char *const *args, const char *cf, | ||
753 | const struct GNUNET_CONFIGURATION_Handle *c) | ||
754 | { | ||
755 | if (GNUNET_OK != verify_args ()) | ||
756 | { | ||
757 | do_shutdown (NULL, NULL); | ||
758 | return; | ||
759 | } | ||
760 | cfg = GNUNET_CONFIGURATION_create (); | ||
761 | GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (cfg, cfg_filename)); | ||
762 | GNUNET_CONFIGURATION_set_value_string ((struct GNUNET_CONFIGURATION_Handle *) | ||
763 | cfg, "TESTBED", | ||
764 | "OVERLAY_TOPOLOGY_FILE", | ||
765 | topology_file); | ||
766 | shutdown_task = | ||
767 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_shutdown, | ||
768 | NULL); | ||
769 | GNUNET_TESTBED_run (NULL, cfg, num_peers, 0, NULL, NULL, &test_master, NULL); | ||
770 | } | ||
771 | |||
772 | |||
773 | /** | ||
774 | * Main function. | ||
775 | * | ||
776 | * @return 0 on success | ||
777 | */ | ||
778 | int | ||
779 | main (int argc, char *const *argv) | ||
780 | { | ||
781 | static struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
782 | {'p', "peers", "COUNT", gettext_noop ("Number of peers to run"), GNUNET_YES, | ||
783 | &GNUNET_GETOPT_set_uint, &num_peers}, | ||
784 | {'t', "topology-file", "FILEPATH", gettext_noop ("Path to topology file"), | ||
785 | GNUNET_YES, &GNUNET_GETOPT_set_filename, &topology_file}, | ||
786 | {'i', "sensors-interval", "INTERVAL", | ||
787 | gettext_noop ("Change the interval of running sensors to given value"), | ||
788 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &sensors_interval}, | ||
789 | {'a', "anomalous-peers", "COUNT", | ||
790 | gettext_noop ("Number of peers to simulate anomalies on"), GNUNET_YES, | ||
791 | &GNUNET_GETOPT_set_uint, &anomalous_peers}, | ||
792 | GNUNET_GETOPT_OPTION_END | ||
793 | }; | ||
794 | |||
795 | return (GNUNET_OK == | ||
796 | GNUNET_PROGRAM_run (argc, argv, "gnunet-sensor-profiler", | ||
797 | gettext_noop ("Profiler for sensor service"), | ||
798 | options, &run, NULL)) ? 0 : 1; | ||
799 | } | ||
800 | |||
801 | /* end of gnunet-sensor-profiler.c */ | ||
diff --git a/src/sensor/gnunet-sensor-profiler.conf b/src/sensor/gnunet-sensor-profiler.conf deleted file mode 100644 index 1c9cdb3bd..000000000 --- a/src/sensor/gnunet-sensor-profiler.conf +++ /dev/null | |||
@@ -1,16 +0,0 @@ | |||
1 | [testbed] | ||
2 | OVERLAY_TOPOLOGY = FROM_FILE | ||
3 | |||
4 | [sensor] | ||
5 | SENSOR_DIR = /tmp/gnunet-sensor-profiler/ | ||
6 | |||
7 | START_MONITORING = YES | ||
8 | START_REPORTING = YES | ||
9 | START_ANALYSIS = YES | ||
10 | START_UPDATE = NO | ||
11 | |||
12 | [transport] | ||
13 | PLUGINS = unix | ||
14 | |||
15 | [nat] | ||
16 | USE_LOCALADDR = YES | ||
diff --git a/src/sensor/gnunet-sensor.c b/src/sensor/gnunet-sensor.c deleted file mode 100644 index 14408f63a..000000000 --- a/src/sensor/gnunet-sensor.c +++ /dev/null | |||
@@ -1,179 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensor/gnunet-sensor.c | ||
23 | * @brief sensor tool | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_sensor_service.h" | ||
29 | |||
30 | static int ret; | ||
31 | |||
32 | /** | ||
33 | * option '-a' | ||
34 | */ | ||
35 | static int get_all; | ||
36 | |||
37 | /** | ||
38 | * option '-g' | ||
39 | */ | ||
40 | static char *get_sensor; | ||
41 | |||
42 | /** | ||
43 | * option '-f' | ||
44 | */ | ||
45 | static char *force_anomaly; | ||
46 | |||
47 | /* | ||
48 | * Handle to sensor service | ||
49 | */ | ||
50 | static struct GNUNET_SENSOR_Handle *sensor_handle; | ||
51 | |||
52 | /** | ||
53 | * Run on shutdown | ||
54 | * | ||
55 | * @param cls unused | ||
56 | * @param tc scheduler context | ||
57 | */ | ||
58 | static void | ||
59 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
60 | { | ||
61 | if (NULL != sensor_handle) | ||
62 | { | ||
63 | GNUNET_SENSOR_disconnect (sensor_handle); | ||
64 | sensor_handle = NULL; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | |||
69 | /** | ||
70 | * Callback for getting sensor info from service | ||
71 | * | ||
72 | * @param cls not used | ||
73 | * @param sensor brief information about sensor (NULL means end of transmission) | ||
74 | * @param err_msg contains error string if any | ||
75 | */ | ||
76 | void | ||
77 | print_sensor_info (void *cls, const struct SensorInfoShort *sensor, | ||
78 | const char *err_msg) | ||
79 | { | ||
80 | if (NULL != err_msg) | ||
81 | { | ||
82 | printf ("Error: %s\n", err_msg); | ||
83 | GNUNET_SCHEDULER_shutdown (); | ||
84 | return; | ||
85 | } | ||
86 | if (NULL == sensor) /* no more sensors from service */ | ||
87 | { | ||
88 | GNUNET_SCHEDULER_shutdown (); | ||
89 | return; | ||
90 | } | ||
91 | printf ("Name: %s\nVersion: %d.%d\n", sensor->name, sensor->version_major, | ||
92 | sensor->version_minor); | ||
93 | if (NULL != sensor->description) | ||
94 | printf ("Description: %s\n", sensor->description); | ||
95 | printf ("\n"); | ||
96 | } | ||
97 | |||
98 | |||
99 | /** | ||
100 | * Continuation called after a force anomaly request is sent. | ||
101 | * | ||
102 | * @param cls Closure (unused) | ||
103 | * @param emsg Error message, NULL of no error | ||
104 | */ | ||
105 | void | ||
106 | force_anomaly_cont (void *cls, const char *emsg) | ||
107 | { | ||
108 | if (NULL != emsg) | ||
109 | printf ("Error: %s\n", emsg); | ||
110 | GNUNET_SCHEDULER_shutdown (); | ||
111 | } | ||
112 | |||
113 | |||
114 | /** | ||
115 | * Main function that will be run by the scheduler. | ||
116 | * | ||
117 | * @param cls closure | ||
118 | * @param args remaining command-line arguments | ||
119 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
120 | * @param cfg configuration | ||
121 | */ | ||
122 | static void | ||
123 | run (void *cls, char *const *args, const char *cfgfile, | ||
124 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
125 | { | ||
126 | sensor_handle = NULL; | ||
127 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, | ||
128 | NULL); | ||
129 | sensor_handle = GNUNET_SENSOR_connect (cfg); | ||
130 | GNUNET_assert (NULL != sensor_handle); | ||
131 | if (GNUNET_YES == get_all) | ||
132 | { | ||
133 | GNUNET_SENSOR_iterate (sensor_handle, GNUNET_TIME_UNIT_FOREVER_REL, NULL, | ||
134 | &print_sensor_info, NULL); | ||
135 | } | ||
136 | else if (NULL != get_sensor) | ||
137 | { | ||
138 | GNUNET_SENSOR_iterate (sensor_handle, GNUNET_TIME_UNIT_FOREVER_REL, | ||
139 | get_sensor, &print_sensor_info, NULL); | ||
140 | } | ||
141 | else if (NULL != force_anomaly) | ||
142 | { | ||
143 | GNUNET_SENSOR_force_anomaly (sensor_handle, "nse", GNUNET_YES, | ||
144 | &force_anomaly_cont, NULL); | ||
145 | } | ||
146 | ret = 0; | ||
147 | } | ||
148 | |||
149 | |||
150 | /** | ||
151 | * The main function to sensor. | ||
152 | * | ||
153 | * @param argc number of arguments from the command line | ||
154 | * @param argv command line arguments | ||
155 | * @return 0 ok, 1 on error | ||
156 | */ | ||
157 | int | ||
158 | main (int argc, char *const *argv) | ||
159 | { | ||
160 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
161 | {'a', "all", NULL, | ||
162 | gettext_noop ("Retrieve information about all defined sensors"), | ||
163 | 0, &GNUNET_GETOPT_set_one, &get_all}, | ||
164 | {'g', "get-sensor", NULL, | ||
165 | gettext_noop ("Retrieve information about a single sensor"), | ||
166 | 1, &GNUNET_GETOPT_set_string, &get_sensor}, | ||
167 | {'f', "force-anomaly", NULL, | ||
168 | gettext_noop ("Force an anomaly on a sensor, use only for testing"), | ||
169 | 1, &GNUNET_GETOPT_set_string, &force_anomaly}, | ||
170 | GNUNET_GETOPT_OPTION_END | ||
171 | }; | ||
172 | |||
173 | return (GNUNET_OK == | ||
174 | GNUNET_PROGRAM_run (argc, argv, "gnunet-sensor [options [value]]", | ||
175 | gettext_noop ("sensor"), options, &run, | ||
176 | NULL)) ? ret : 1; | ||
177 | } | ||
178 | |||
179 | /* end of gnunet-sensor.c */ | ||
diff --git a/src/sensor/gnunet-service-sensor.c b/src/sensor/gnunet-service-sensor.c deleted file mode 100644 index 535b64fd7..000000000 --- a/src/sensor/gnunet-service-sensor.c +++ /dev/null | |||
@@ -1,385 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensor/gnunet-service-sensor.c | ||
23 | * @brief sensor service implementation | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "sensor.h" | ||
29 | |||
30 | /** | ||
31 | * Our configuration. | ||
32 | */ | ||
33 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
34 | |||
35 | /** | ||
36 | * Path to sensor definitions directory | ||
37 | */ | ||
38 | static char *sensor_dir; | ||
39 | |||
40 | /** | ||
41 | * Hashmap of loaded sensor definitions | ||
42 | */ | ||
43 | static struct GNUNET_CONTAINER_MultiHashMap *sensors; | ||
44 | |||
45 | /** | ||
46 | * Start the monitoring module ? | ||
47 | */ | ||
48 | static int start_monitoring; | ||
49 | |||
50 | /** | ||
51 | * Start the analysis module ? | ||
52 | */ | ||
53 | static int start_analysis; | ||
54 | |||
55 | /** | ||
56 | * Start the reporting module ? | ||
57 | */ | ||
58 | static int start_reporting; | ||
59 | |||
60 | /** | ||
61 | * Start the update module ? | ||
62 | */ | ||
63 | static int start_update; | ||
64 | |||
65 | |||
66 | /** | ||
67 | * Resets the service by stopping components, reloading sensors and starting | ||
68 | * components. This is needed when we receive new sensor updates. | ||
69 | */ | ||
70 | static void | ||
71 | reset (); | ||
72 | |||
73 | |||
74 | /** | ||
75 | * Stops components and destroys sensors | ||
76 | */ | ||
77 | static void | ||
78 | stop () | ||
79 | { | ||
80 | if (GNUNET_YES == start_update) | ||
81 | SENSOR_update_stop (); | ||
82 | if (GNUNET_YES == start_analysis) | ||
83 | SENSOR_analysis_stop (); | ||
84 | if (GNUNET_YES == start_reporting) | ||
85 | SENSOR_reporting_stop (); | ||
86 | if (GNUNET_YES == start_monitoring) | ||
87 | SENSOR_monitoring_stop (); | ||
88 | GNUNET_SENSOR_destroy_sensors (sensors); | ||
89 | } | ||
90 | |||
91 | |||
92 | /** | ||
93 | * Task run during shutdown. | ||
94 | * | ||
95 | * @param cls unused | ||
96 | * @param tc unused | ||
97 | */ | ||
98 | static void | ||
99 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
100 | { | ||
101 | stop (); | ||
102 | if (NULL != sensor_dir) | ||
103 | { | ||
104 | GNUNET_free (sensor_dir); | ||
105 | sensor_dir = NULL; | ||
106 | } | ||
107 | GNUNET_SCHEDULER_shutdown (); | ||
108 | } | ||
109 | |||
110 | |||
111 | /** | ||
112 | * Handle a force anomaly request from client. | ||
113 | * | ||
114 | * @param cls closure | ||
115 | * @param client identification of the client | ||
116 | * @param message the actual message | ||
117 | */ | ||
118 | static void | ||
119 | handle_anomaly_force (void *cls, struct GNUNET_SERVER_Client *client, | ||
120 | const struct GNUNET_MessageHeader *message) | ||
121 | { | ||
122 | struct ForceAnomalyMessage *anomaly_msg; | ||
123 | struct GNUNET_SENSOR_SensorInfo *sensor; | ||
124 | |||
125 | anomaly_msg = (struct ForceAnomalyMessage *) message; | ||
126 | sensor = | ||
127 | GNUNET_CONTAINER_multihashmap_get (sensors, | ||
128 | &anomaly_msg->sensor_name_hash); | ||
129 | if (NULL == sensor) | ||
130 | { | ||
131 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
132 | "Force anomaly message received for a sensor we don't have.\n"); | ||
133 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
134 | return; | ||
135 | } | ||
136 | SENSOR_reporting_anomaly_update (sensor, ntohs (anomaly_msg->anomalous)); | ||
137 | GNUNET_SERVER_receive_done (client, GNUNET_YES); | ||
138 | } | ||
139 | |||
140 | |||
141 | /** | ||
142 | * Creates a structure with basic sensor info to be sent to a client. | ||
143 | * | ||
144 | * @param sensor sensor information | ||
145 | * @return message ready to be sent to client | ||
146 | */ | ||
147 | static struct SensorInfoMessage * | ||
148 | create_sensor_info_msg (struct GNUNET_SENSOR_SensorInfo *sensor) | ||
149 | { | ||
150 | struct SensorInfoMessage *msg; | ||
151 | uint16_t len; | ||
152 | size_t name_len; | ||
153 | size_t desc_len; | ||
154 | char *str_ptr; | ||
155 | |||
156 | name_len = strlen (sensor->name); | ||
157 | if (NULL == sensor->description) | ||
158 | desc_len = 0; | ||
159 | else | ||
160 | desc_len = strlen (sensor->description) + 1; | ||
161 | len = 0; | ||
162 | len += sizeof (struct SensorInfoMessage); | ||
163 | len += name_len; | ||
164 | len += desc_len; | ||
165 | msg = GNUNET_malloc (len); | ||
166 | msg->header.size = htons (len); | ||
167 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_INFO); | ||
168 | msg->name_len = htons (name_len); | ||
169 | msg->description_len = htons (desc_len); | ||
170 | msg->version_major = htons (sensor->version_major); | ||
171 | msg->version_minor = htons (sensor->version_minor); | ||
172 | str_ptr = (char *) &msg[1]; | ||
173 | memcpy (str_ptr, sensor->name, name_len); | ||
174 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending sensor name (%d): %.*s\n", | ||
175 | name_len, name_len, str_ptr); | ||
176 | str_ptr += name_len; | ||
177 | memcpy (str_ptr, sensor->description, desc_len); | ||
178 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
179 | "Sending sensor description (%d): %.*s\n", desc_len, desc_len, | ||
180 | str_ptr); | ||
181 | return msg; | ||
182 | } | ||
183 | |||
184 | |||
185 | /** | ||
186 | * Handle GET SENSOR message. | ||
187 | * | ||
188 | * @param cls closure | ||
189 | * @param client identification of the client | ||
190 | * @param message the actual message | ||
191 | */ | ||
192 | static void | ||
193 | handle_get_sensor (void *cls, struct GNUNET_SERVER_Client *client, | ||
194 | const struct GNUNET_MessageHeader *message) | ||
195 | { | ||
196 | struct GNUNET_SERVER_TransmitContext *tc; | ||
197 | char *sensorname; | ||
198 | size_t sensorname_len; | ||
199 | struct GNUNET_HashCode key; | ||
200 | struct GNUNET_SENSOR_SensorInfo *sensorinfo; | ||
201 | struct SensorInfoMessage *msg; | ||
202 | |||
203 | sensorname = (char *) &message[1]; | ||
204 | sensorname_len = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader); | ||
205 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
206 | "`%s' message received for sensor (%d) `%.*s'\n", "GET SENSOR", | ||
207 | sensorname_len, sensorname_len, sensorname); | ||
208 | tc = GNUNET_SERVER_transmit_context_create (client); | ||
209 | GNUNET_CRYPTO_hash (sensorname, sensorname_len, &key); | ||
210 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
211 | "Created key hash for requested sensor\n"); | ||
212 | sensorinfo = | ||
213 | (struct GNUNET_SENSOR_SensorInfo *) | ||
214 | GNUNET_CONTAINER_multihashmap_get (sensors, &key); | ||
215 | if (NULL != sensorinfo) | ||
216 | { | ||
217 | msg = create_sensor_info_msg (sensorinfo); | ||
218 | GNUNET_SERVER_transmit_context_append_message (tc, | ||
219 | (struct GNUNET_MessageHeader | ||
220 | *) msg); | ||
221 | GNUNET_free (msg); | ||
222 | } | ||
223 | else | ||
224 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
225 | "Requested sensor `%.*s' was not found\n", sensorname_len, | ||
226 | sensorname); | ||
227 | GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, | ||
228 | GNUNET_MESSAGE_TYPE_SENSOR_END); | ||
229 | GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); | ||
230 | } | ||
231 | |||
232 | |||
233 | /** | ||
234 | * Iterator for sensors and adds them to transmit context | ||
235 | * | ||
236 | * @param cls a `struct GNUNET_SERVER_TransmitContext *` | ||
237 | * @param key hash of sensor name, key to hashmap | ||
238 | * @param value a `struct GNUNET_SENSOR_SensorInfo *` | ||
239 | */ | ||
240 | static int | ||
241 | add_sensor_to_tc (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
242 | { | ||
243 | struct GNUNET_SERVER_TransmitContext *tc = cls; | ||
244 | struct GNUNET_SENSOR_SensorInfo *sensorinfo = value; | ||
245 | struct SensorInfoMessage *msg; | ||
246 | |||
247 | msg = create_sensor_info_msg (sensorinfo); | ||
248 | GNUNET_SERVER_transmit_context_append_message (tc, | ||
249 | (struct GNUNET_MessageHeader *) | ||
250 | msg); | ||
251 | |||
252 | GNUNET_free (msg); | ||
253 | return GNUNET_YES; | ||
254 | } | ||
255 | |||
256 | |||
257 | /** | ||
258 | * Handle GET ALL SENSORS message. | ||
259 | * | ||
260 | * @param cls closure | ||
261 | * @param client identification of the client | ||
262 | * @param message the actual message | ||
263 | */ | ||
264 | static void | ||
265 | handle_get_all_sensors (void *cls, struct GNUNET_SERVER_Client *client, | ||
266 | const struct GNUNET_MessageHeader *message) | ||
267 | { | ||
268 | struct GNUNET_SERVER_TransmitContext *tc; | ||
269 | |||
270 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "`%s' message received.\n", | ||
271 | "GET ALL SENSOR"); | ||
272 | tc = GNUNET_SERVER_transmit_context_create (client); | ||
273 | GNUNET_CONTAINER_multihashmap_iterate (sensors, &add_sensor_to_tc, tc); | ||
274 | GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, | ||
275 | GNUNET_MESSAGE_TYPE_SENSOR_END); | ||
276 | GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); | ||
277 | } | ||
278 | |||
279 | |||
280 | /** | ||
281 | * Loads sensors and starts different service components | ||
282 | */ | ||
283 | static void | ||
284 | start () | ||
285 | { | ||
286 | sensors = GNUNET_SENSOR_load_all_sensors (sensor_dir); | ||
287 | if (GNUNET_YES == start_monitoring) | ||
288 | SENSOR_monitoring_start (cfg, sensors); | ||
289 | if (GNUNET_YES == start_reporting) | ||
290 | SENSOR_reporting_start (cfg, sensors); | ||
291 | if (GNUNET_YES == start_analysis) | ||
292 | SENSOR_analysis_start (cfg, sensors); | ||
293 | if (GNUNET_YES == start_update) | ||
294 | SENSOR_update_start (cfg, sensors, &reset); | ||
295 | } | ||
296 | |||
297 | |||
298 | /** | ||
299 | * Process statistics requests. | ||
300 | * | ||
301 | * @param cls closure | ||
302 | * @param server the initialized server | ||
303 | * @param c configuration to use | ||
304 | */ | ||
305 | static void | ||
306 | run (void *cls, struct GNUNET_SERVER_Handle *server, | ||
307 | const struct GNUNET_CONFIGURATION_Handle *c) | ||
308 | { | ||
309 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | ||
310 | {&handle_get_sensor, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GET, | ||
311 | 0}, | ||
312 | {&handle_get_all_sensors, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GETALL, | ||
313 | sizeof (struct GNUNET_MessageHeader)}, | ||
314 | { | ||
315 | &handle_anomaly_force, NULL, GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_FORCE, | ||
316 | sizeof (struct ForceAnomalyMessage)}, | ||
317 | {NULL, NULL, 0, 0} | ||
318 | }; | ||
319 | |||
320 | cfg = c; | ||
321 | if (GNUNET_OK != | ||
322 | GNUNET_CONFIGURATION_get_value_filename (cfg, "sensor", "SENSOR_DIR", | ||
323 | &sensor_dir)) | ||
324 | { | ||
325 | sensor_dir = GNUNET_SENSOR_get_default_sensor_dir (); | ||
326 | } | ||
327 | start_monitoring = GNUNET_YES; | ||
328 | start_analysis = GNUNET_YES; | ||
329 | start_reporting = GNUNET_YES; | ||
330 | start_update = GNUNET_YES; | ||
331 | if (GNUNET_NO == | ||
332 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_MONITORING")) | ||
333 | { | ||
334 | start_monitoring = GNUNET_NO; | ||
335 | } | ||
336 | if (GNUNET_NO == | ||
337 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_REPORTING")) | ||
338 | { | ||
339 | start_reporting = GNUNET_NO; | ||
340 | } | ||
341 | if (GNUNET_NO == | ||
342 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_ANALYSIS")) | ||
343 | { | ||
344 | start_analysis = GNUNET_NO; | ||
345 | } | ||
346 | if (GNUNET_NO == | ||
347 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_UPDATE")) | ||
348 | { | ||
349 | start_update = GNUNET_NO; | ||
350 | } | ||
351 | GNUNET_SERVER_add_handlers (server, handlers); | ||
352 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, | ||
353 | NULL); | ||
354 | start (); | ||
355 | } | ||
356 | |||
357 | |||
358 | /** | ||
359 | * Resets the service by stopping components, reloading sensors and starting | ||
360 | * components. This is needed when we receive new sensor updates. | ||
361 | */ | ||
362 | static void | ||
363 | reset () | ||
364 | { | ||
365 | stop (); | ||
366 | start (); | ||
367 | } | ||
368 | |||
369 | |||
370 | /** | ||
371 | * The main function for the sensor service. | ||
372 | * | ||
373 | * @param argc number of arguments from the command line | ||
374 | * @param argv command line arguments | ||
375 | * @return 0 ok, 1 on error | ||
376 | */ | ||
377 | int | ||
378 | main (int argc, char *const *argv) | ||
379 | { | ||
380 | return (GNUNET_OK == | ||
381 | GNUNET_SERVICE_run (argc, argv, "sensor", GNUNET_SERVICE_OPTION_NONE, | ||
382 | &run, NULL)) ? 0 : 1; | ||
383 | } | ||
384 | |||
385 | /* end of gnunet-service-sensor.c */ | ||
diff --git a/src/sensor/gnunet-service-sensor_analysis.c b/src/sensor/gnunet-service-sensor_analysis.c deleted file mode 100644 index d87410923..000000000 --- a/src/sensor/gnunet-service-sensor_analysis.c +++ /dev/null | |||
@@ -1,326 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensor/gnunet-service-sensor_analysis.c | ||
23 | * @brief sensor service analysis functionality | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "sensor.h" | ||
29 | #include "gnunet_peerstore_service.h" | ||
30 | #include "gnunet_sensor_model_plugin.h" | ||
31 | |||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "sensor-analysis",__VA_ARGS__) | ||
33 | |||
34 | /** | ||
35 | * Carries information about the analysis model | ||
36 | * corresponding to one sensor | ||
37 | */ | ||
38 | struct SensorModel | ||
39 | { | ||
40 | |||
41 | /** | ||
42 | * DLL | ||
43 | */ | ||
44 | struct SensorModel *prev; | ||
45 | |||
46 | /** | ||
47 | * DLL | ||
48 | */ | ||
49 | struct SensorModel *next; | ||
50 | |||
51 | /** | ||
52 | * Pointer to sensor info structure | ||
53 | */ | ||
54 | struct GNUNET_SENSOR_SensorInfo *sensor; | ||
55 | |||
56 | /** | ||
57 | * Watcher of sensor values | ||
58 | */ | ||
59 | struct GNUNET_PEERSTORE_WatchContext *wc; | ||
60 | |||
61 | /** | ||
62 | * State of sensor. #GNUNET_YES if anomalous, #GNUNET_NO otherwise. | ||
63 | */ | ||
64 | int anomalous; | ||
65 | |||
66 | /** | ||
67 | * Number of anomalous readings (positive) received in a row. | ||
68 | */ | ||
69 | int positive_count; | ||
70 | |||
71 | /** | ||
72 | * Number of non-anomalous (negative) readings received in a row. | ||
73 | */ | ||
74 | int negative_count; | ||
75 | |||
76 | /** | ||
77 | * Closure for model plugin. | ||
78 | * Usually, the instance of the model created for this sensor. | ||
79 | */ | ||
80 | void *cls; | ||
81 | |||
82 | }; | ||
83 | |||
84 | /** | ||
85 | * Our configuration. | ||
86 | */ | ||
87 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
88 | |||
89 | /** | ||
90 | * Hashmap of loaded sensors | ||
91 | */ | ||
92 | static struct GNUNET_CONTAINER_MultiHashMap *sensors; | ||
93 | |||
94 | /* | ||
95 | * Model library name | ||
96 | */ | ||
97 | static char *model_lib_name; | ||
98 | |||
99 | /** | ||
100 | * Model handle | ||
101 | */ | ||
102 | static struct GNUNET_SENSOR_ModelFunctions *model_api; | ||
103 | |||
104 | /** | ||
105 | * Handle to peerstore service | ||
106 | */ | ||
107 | static struct GNUNET_PEERSTORE_Handle *peerstore; | ||
108 | |||
109 | /** | ||
110 | * Head of DLL of created models | ||
111 | */ | ||
112 | static struct SensorModel *models_head; | ||
113 | |||
114 | /** | ||
115 | * Tail of DLL of created models | ||
116 | */ | ||
117 | static struct SensorModel *models_tail; | ||
118 | |||
119 | /** | ||
120 | * My peer id | ||
121 | */ | ||
122 | static struct GNUNET_PeerIdentity peerid; | ||
123 | |||
124 | /** | ||
125 | * How many subsequent values required to flip anomaly label. | ||
126 | * E.g. After 3 subsequent anomaly reports, status change to anomalous. | ||
127 | */ | ||
128 | static unsigned long long confirmation_count; | ||
129 | |||
130 | /** | ||
131 | * Destroy a created model | ||
132 | */ | ||
133 | static void | ||
134 | destroy_sensor_model (struct SensorModel *sensor_model) | ||
135 | { | ||
136 | GNUNET_assert (NULL != sensor_model); | ||
137 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying sensor model for `%s'.\n", | ||
138 | sensor_model->sensor->name); | ||
139 | if (NULL != sensor_model->wc) | ||
140 | { | ||
141 | GNUNET_PEERSTORE_watch_cancel (sensor_model->wc); | ||
142 | sensor_model->wc = NULL; | ||
143 | } | ||
144 | if (NULL != sensor_model->cls) | ||
145 | { | ||
146 | model_api->destroy_model (sensor_model->cls); | ||
147 | sensor_model->cls = NULL; | ||
148 | } | ||
149 | GNUNET_free (sensor_model); | ||
150 | sensor_model = NULL; | ||
151 | } | ||
152 | |||
153 | |||
154 | /** | ||
155 | * Stop the sensor analysis module | ||
156 | */ | ||
157 | void | ||
158 | SENSOR_analysis_stop () | ||
159 | { | ||
160 | struct SensorModel *sm; | ||
161 | |||
162 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Stopping sensor analysis module.\n"); | ||
163 | while (NULL != models_head) | ||
164 | { | ||
165 | sm = models_head; | ||
166 | GNUNET_CONTAINER_DLL_remove (models_head, models_tail, sm); | ||
167 | destroy_sensor_model (sm); | ||
168 | } | ||
169 | if (NULL != peerstore) | ||
170 | { | ||
171 | GNUNET_PEERSTORE_disconnect (peerstore, GNUNET_YES); | ||
172 | peerstore = NULL; | ||
173 | } | ||
174 | if (NULL != model_api) | ||
175 | { | ||
176 | GNUNET_break (NULL == GNUNET_PLUGIN_unload (model_lib_name, model_api)); | ||
177 | GNUNET_free (model_lib_name); | ||
178 | model_lib_name = NULL; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | |||
183 | /** | ||
184 | * Sensor value watch callback | ||
185 | * | ||
186 | * @param cls Sensor model struct | ||
187 | * @param record Received record from peerstore, should contain new sensor value | ||
188 | * @param emsg Error message from peerstore if any, NULL if no errors | ||
189 | * @return #GNUNET_YES | ||
190 | */ | ||
191 | static int | ||
192 | sensor_watcher (void *cls, | ||
193 | const struct GNUNET_PEERSTORE_Record *record, | ||
194 | const char *emsg) | ||
195 | { | ||
196 | struct SensorModel *model = cls; | ||
197 | double *val; | ||
198 | int anomalous; | ||
199 | |||
200 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
201 | "Received a sensor value, will feed to sensor model.\n"); | ||
202 | if (sizeof (double) != record->value_size) | ||
203 | { | ||
204 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Received an invalid sensor value.")); | ||
205 | return GNUNET_YES; | ||
206 | } | ||
207 | val = (double *) (record->value); | ||
208 | anomalous = model_api->feed_model (model->cls, *val); | ||
209 | if (GNUNET_YES == anomalous) | ||
210 | { | ||
211 | model->positive_count++; | ||
212 | model->negative_count = 0; | ||
213 | if (GNUNET_NO == model->anomalous && | ||
214 | model->positive_count >= confirmation_count) | ||
215 | { | ||
216 | model->anomalous = GNUNET_YES; | ||
217 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
218 | "Anomaly state started for sensor `%s', value: %f.\n", | ||
219 | model->sensor->name, val); | ||
220 | SENSOR_reporting_anomaly_update (model->sensor, model->anomalous); | ||
221 | } | ||
222 | } | ||
223 | else | ||
224 | { | ||
225 | model->negative_count++; | ||
226 | model->positive_count = 0; | ||
227 | if (GNUNET_YES == model->anomalous && | ||
228 | model->negative_count >= confirmation_count) | ||
229 | { | ||
230 | model->anomalous = GNUNET_NO; | ||
231 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
232 | "Anomaly state stopped for sensor `%s', value: %f.\n", | ||
233 | model->sensor->name, val); | ||
234 | SENSOR_reporting_anomaly_update (model->sensor, model->anomalous); | ||
235 | } | ||
236 | } | ||
237 | return GNUNET_YES; | ||
238 | } | ||
239 | |||
240 | |||
241 | /** | ||
242 | * Iterator for defined sensors | ||
243 | * Creates sensor model for numeric sensors | ||
244 | * | ||
245 | * @param cls unused | ||
246 | * @param key unused | ||
247 | * @param value a 'struct GNUNET_SENSOR_SensorInfo *' with sensor information | ||
248 | * @return #GNUNET_YES to continue iterations | ||
249 | */ | ||
250 | static int | ||
251 | init_sensor_model (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
252 | { | ||
253 | struct GNUNET_SENSOR_SensorInfo *sensor = value; | ||
254 | struct SensorModel *sensor_model; | ||
255 | |||
256 | if (0 != strcmp ("numeric", sensor->expected_datatype)) | ||
257 | return GNUNET_YES; | ||
258 | sensor_model = GNUNET_new (struct SensorModel); | ||
259 | sensor_model->sensor = sensor; | ||
260 | sensor_model->wc = | ||
261 | GNUNET_PEERSTORE_watch (peerstore, "sensor", &peerid, sensor->name, | ||
262 | &sensor_watcher, sensor_model); | ||
263 | sensor_model->anomalous = GNUNET_NO; | ||
264 | sensor_model->positive_count = 0; | ||
265 | sensor_model->negative_count = 0; | ||
266 | sensor_model->cls = model_api->create_model (model_api->cls); | ||
267 | GNUNET_CONTAINER_DLL_insert (models_head, models_tail, sensor_model); | ||
268 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Created sensor model for `%s'.\n", | ||
269 | sensor->name); | ||
270 | return GNUNET_YES; | ||
271 | } | ||
272 | |||
273 | |||
274 | /** | ||
275 | * Start the sensor analysis module | ||
276 | * | ||
277 | * @param c our service configuration | ||
278 | * @param sensors multihashmap of loaded sensors | ||
279 | * @return #GNUNET_OK if started successfully, #GNUNET_SYSERR otherwise | ||
280 | */ | ||
281 | int | ||
282 | SENSOR_analysis_start (const struct GNUNET_CONFIGURATION_Handle *c, | ||
283 | struct GNUNET_CONTAINER_MultiHashMap *s) | ||
284 | { | ||
285 | char *model_name; | ||
286 | |||
287 | GNUNET_assert (NULL != s); | ||
288 | cfg = c; | ||
289 | sensors = s; | ||
290 | if (GNUNET_OK != | ||
291 | GNUNET_CONFIGURATION_get_value_string (cfg, "sensor-analysis", "MODEL", | ||
292 | &model_name)) | ||
293 | { | ||
294 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
295 | _("Analysis model not defined in configuration.\n")); | ||
296 | return GNUNET_SYSERR; | ||
297 | } | ||
298 | GNUNET_asprintf (&model_lib_name, "libgnunet_plugin_sensor_model_%s", | ||
299 | model_name); | ||
300 | model_api = GNUNET_PLUGIN_load (model_lib_name, (void *) cfg); | ||
301 | GNUNET_free (model_name); | ||
302 | if (NULL == model_api) | ||
303 | { | ||
304 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Could not load analysis model `%s'.\n"), | ||
305 | model_lib_name); | ||
306 | return GNUNET_SYSERR; | ||
307 | } | ||
308 | peerstore = GNUNET_PEERSTORE_connect (cfg); | ||
309 | if (NULL == peerstore) | ||
310 | { | ||
311 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
312 | _("Could not connect to peerstore service.\n")); | ||
313 | SENSOR_analysis_stop (); | ||
314 | return GNUNET_SYSERR; | ||
315 | } | ||
316 | if (GNUNET_OK != | ||
317 | GNUNET_CONFIGURATION_get_value_number (cfg, "sensor-analysis", | ||
318 | "CONFIRMATION_COUNT", | ||
319 | &confirmation_count)) | ||
320 | confirmation_count = 1; | ||
321 | GNUNET_CRYPTO_get_peer_identity (cfg, &peerid); | ||
322 | GNUNET_CONTAINER_multihashmap_iterate (sensors, &init_sensor_model, NULL); | ||
323 | return GNUNET_OK; | ||
324 | } | ||
325 | |||
326 | /* end of gnunet-service-sensor_analysis.c */ | ||
diff --git a/src/sensor/gnunet-service-sensor_monitoring.c b/src/sensor/gnunet-service-sensor_monitoring.c deleted file mode 100644 index 54c096233..000000000 --- a/src/sensor/gnunet-service-sensor_monitoring.c +++ /dev/null | |||
@@ -1,477 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensor/gnunet-service-sensor_analysis.c | ||
23 | * @brief sensor service analysis functionality | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | #include <inttypes.h> | ||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "sensor.h" | ||
30 | #include "gnunet_statistics_service.h" | ||
31 | #include "gnunet_peerstore_service.h" | ||
32 | |||
33 | #define LOG(kind,...) GNUNET_log_from (kind, "sensor-monitoring",__VA_ARGS__) | ||
34 | |||
35 | /** | ||
36 | * Our configuration. | ||
37 | */ | ||
38 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
39 | |||
40 | /** | ||
41 | * Hashmap of loaded sensor definitions | ||
42 | */ | ||
43 | static struct GNUNET_CONTAINER_MultiHashMap *sensors; | ||
44 | |||
45 | /** | ||
46 | * Path to sensor definitions directory | ||
47 | */ | ||
48 | static char *sensor_dir; | ||
49 | |||
50 | /** | ||
51 | * Handle to statistics service | ||
52 | */ | ||
53 | static struct GNUNET_STATISTICS_Handle *statistics; | ||
54 | |||
55 | /** | ||
56 | * Handle to peerstore service | ||
57 | */ | ||
58 | static struct GNUNET_PEERSTORE_Handle *peerstore; | ||
59 | |||
60 | /** | ||
61 | * My peer id | ||
62 | */ | ||
63 | static struct GNUNET_PeerIdentity peerid; | ||
64 | |||
65 | |||
66 | /** | ||
67 | * Stop the sensor monitoring module | ||
68 | */ | ||
69 | void | ||
70 | SENSOR_monitoring_stop () | ||
71 | { | ||
72 | if (NULL != statistics) | ||
73 | { | ||
74 | GNUNET_STATISTICS_destroy (statistics, GNUNET_YES); | ||
75 | statistics = NULL; | ||
76 | } | ||
77 | if (NULL != peerstore) | ||
78 | { | ||
79 | GNUNET_PEERSTORE_disconnect (peerstore, GNUNET_YES); | ||
80 | peerstore = NULL; | ||
81 | } | ||
82 | if (NULL != sensor_dir) | ||
83 | { | ||
84 | GNUNET_free (sensor_dir); | ||
85 | sensor_dir = NULL; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | |||
90 | /** | ||
91 | * Change the state of the sensor. | ||
92 | * Write the change to file to make it persistent. | ||
93 | * | ||
94 | * @param sensor sensor info struct | ||
95 | * @param state new enabled state: #GNUNET_YES / #GNUNET_NO | ||
96 | */ | ||
97 | static void | ||
98 | set_sensor_enabled (struct GNUNET_SENSOR_SensorInfo *sensor, int state) | ||
99 | { | ||
100 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Sensor `%s': Setting enabled to %d.\n", | ||
101 | sensor->name, state); | ||
102 | sensor->enabled = GNUNET_NO; | ||
103 | GNUNET_assert (NULL != sensor->cfg); | ||
104 | GNUNET_CONFIGURATION_set_value_string (sensor->cfg, sensor->name, "ENABLED", | ||
105 | (GNUNET_YES == state) ? "YES" : "NO"); | ||
106 | GNUNET_CONFIGURATION_write (sensor->cfg, sensor->def_file); | ||
107 | } | ||
108 | |||
109 | |||
110 | /** | ||
111 | * Do a series of checks to determine if sensor should execute | ||
112 | * | ||
113 | * @return #GNUNET_YES / #GNUNET_NO | ||
114 | */ | ||
115 | static int | ||
116 | should_run_sensor (struct GNUNET_SENSOR_SensorInfo *sensorinfo) | ||
117 | { | ||
118 | struct GNUNET_TIME_Absolute now; | ||
119 | |||
120 | if (GNUNET_NO == sensorinfo->enabled) | ||
121 | { | ||
122 | LOG (GNUNET_ERROR_TYPE_INFO, "Sensor `%s' is disabled, will not run\n", | ||
123 | sensorinfo->name); | ||
124 | return GNUNET_NO; | ||
125 | } | ||
126 | now = GNUNET_TIME_absolute_get (); | ||
127 | if (NULL != sensorinfo->start_time && | ||
128 | now.abs_value_us < sensorinfo->start_time->abs_value_us) | ||
129 | { | ||
130 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
131 | "Start time for sensor `%s' not reached yet, will not run\n", | ||
132 | sensorinfo->name); | ||
133 | return GNUNET_NO; | ||
134 | } | ||
135 | if (NULL != sensorinfo->end_time && | ||
136 | now.abs_value_us >= sensorinfo->end_time->abs_value_us) | ||
137 | { | ||
138 | LOG (GNUNET_ERROR_TYPE_INFO, "Sensor `%s' expired, disabling.\n", | ||
139 | sensorinfo->name); | ||
140 | set_sensor_enabled (sensorinfo, GNUNET_NO); | ||
141 | return GNUNET_NO; | ||
142 | } | ||
143 | return GNUNET_YES; | ||
144 | } | ||
145 | |||
146 | |||
147 | /** | ||
148 | * Callback function to process statistic values | ||
149 | * | ||
150 | * @param cls `struct GNUNET_SENSOR_SensorInfo *` | ||
151 | * @param ss name of subsystem that created the statistic | ||
152 | * @param name the name of the datum | ||
153 | * @param value the current value | ||
154 | * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not | ||
155 | * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration | ||
156 | */ | ||
157 | static int | ||
158 | sensor_statistics_iterator (void *cls, const char *ss, const char *name, | ||
159 | uint64_t value, int is_persistent) | ||
160 | { | ||
161 | struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls; | ||
162 | double dvalue = (double) value; | ||
163 | struct GNUNET_TIME_Absolute expiry; | ||
164 | |||
165 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
166 | "Received a value for sensor `%s': %" PRIu64 "\n", sensorinfo->name, | ||
167 | value); | ||
168 | expiry = GNUNET_TIME_relative_to_absolute (sensorinfo->lifetime); | ||
169 | GNUNET_PEERSTORE_store (peerstore, "sensor", &peerid, sensorinfo->name, | ||
170 | &dvalue, sizeof (dvalue), expiry, | ||
171 | GNUNET_PEERSTORE_STOREOPTION_MULTIPLE, NULL, NULL); | ||
172 | return GNUNET_SYSERR; /* We only want one value */ | ||
173 | } | ||
174 | |||
175 | |||
176 | /** | ||
177 | * Continuation called after sensor gets all gnunet statistics values | ||
178 | * | ||
179 | * @param cls `struct GNUNET_SENSOR_SensorInfo *` | ||
180 | * @param success #GNUNET_OK if statistics were | ||
181 | * successfully obtained, #GNUNET_SYSERR if not. | ||
182 | */ | ||
183 | static void | ||
184 | end_sensor_run_stat (void *cls, int success) | ||
185 | { | ||
186 | struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls; | ||
187 | |||
188 | sensorinfo->gnunet_stat_get_handle = NULL; | ||
189 | sensorinfo->running = GNUNET_NO; | ||
190 | } | ||
191 | |||
192 | |||
193 | /** | ||
194 | * Tries to parse a received sensor value to its | ||
195 | * expected datatype | ||
196 | * | ||
197 | * @param value the string value received, should be null terminated | ||
198 | * @param sensor sensor information struct | ||
199 | * @param ret pointer to parsed value | ||
200 | * @return size of new parsed value, 0 for error | ||
201 | */ | ||
202 | static size_t | ||
203 | parse_sensor_value (const char *value, | ||
204 | struct GNUNET_SENSOR_SensorInfo *sensor, | ||
205 | void **ret) | ||
206 | { | ||
207 | double *dval; | ||
208 | char *endptr; | ||
209 | |||
210 | *ret = NULL; | ||
211 | if ('\0' == *value) | ||
212 | return 0; | ||
213 | if (0 == strcmp ("numeric", sensor->expected_datatype)) | ||
214 | { | ||
215 | dval = GNUNET_new (double); | ||
216 | |||
217 | *dval = strtod (value, &endptr); | ||
218 | if (value == endptr) | ||
219 | { | ||
220 | GNUNET_free (dval); | ||
221 | *ret = NULL; | ||
222 | return 0; | ||
223 | } | ||
224 | *ret = dval; | ||
225 | return sizeof (double); | ||
226 | } | ||
227 | if (0 == strcmp ("string", sensor->expected_datatype)) | ||
228 | { | ||
229 | *ret = GNUNET_strdup (value); | ||
230 | return strlen (value) + 1; | ||
231 | } | ||
232 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
233 | _("Unknown value type expected by sensor, this should not happen.\n")); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | |||
238 | /** | ||
239 | * Callback for output of executed sensor process | ||
240 | * | ||
241 | * @param cls `struct GNUNET_SENSOR_SensorInfo *` | ||
242 | * @param line line of output from a command, NULL for the end | ||
243 | */ | ||
244 | static void | ||
245 | sensor_process_callback (void *cls, const char *line) | ||
246 | { | ||
247 | struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls; | ||
248 | void *value; | ||
249 | size_t valsize; | ||
250 | struct GNUNET_TIME_Absolute expiry; | ||
251 | |||
252 | if (NULL == line) | ||
253 | { | ||
254 | GNUNET_OS_command_stop (sensorinfo->ext_cmd); | ||
255 | sensorinfo->ext_cmd = NULL; | ||
256 | sensorinfo->running = GNUNET_NO; | ||
257 | sensorinfo->ext_cmd_value_received = GNUNET_NO; | ||
258 | return; | ||
259 | } | ||
260 | if (GNUNET_YES == sensorinfo->ext_cmd_value_received) | ||
261 | return; /* We only want one *valid* value */ | ||
262 | LOG (GNUNET_ERROR_TYPE_INFO, "Received a value for sensor `%s': %s\n", | ||
263 | sensorinfo->name, line); | ||
264 | valsize = parse_sensor_value (line, sensorinfo, &value); | ||
265 | if (valsize == 0) /* invalid value, FIXME: should we disable the sensor now? */ | ||
266 | { | ||
267 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
268 | _("Received an invalid value for sensor `%s': %s\n"), sensorinfo->name, | ||
269 | line); | ||
270 | } | ||
271 | else | ||
272 | { | ||
273 | sensorinfo->ext_cmd_value_received = GNUNET_YES; | ||
274 | expiry = GNUNET_TIME_relative_to_absolute (sensorinfo->lifetime); | ||
275 | GNUNET_PEERSTORE_store (peerstore, "sensor", &peerid, sensorinfo->name, | ||
276 | value, valsize, expiry, | ||
277 | GNUNET_PEERSTORE_STOREOPTION_MULTIPLE, NULL, NULL); | ||
278 | GNUNET_free (value); | ||
279 | } | ||
280 | } | ||
281 | |||
282 | |||
283 | /** | ||
284 | * Checks if the given file is a path | ||
285 | * | ||
286 | * @return #GNUNET_YES / #GNUNET_NO | ||
287 | */ | ||
288 | static int | ||
289 | is_path (char *filename) | ||
290 | { | ||
291 | size_t filename_len; | ||
292 | int i; | ||
293 | |||
294 | filename_len = strlen (filename); | ||
295 | for (i = 0; i < filename_len; i++) | ||
296 | { | ||
297 | if (DIR_SEPARATOR == filename[i]) | ||
298 | return GNUNET_YES; | ||
299 | } | ||
300 | return GNUNET_NO; | ||
301 | } | ||
302 | |||
303 | |||
304 | /** | ||
305 | * Actual execution of a sensor | ||
306 | * | ||
307 | * @param cls 'struct SensorInfo' | ||
308 | * @param tc unsed | ||
309 | */ | ||
310 | static void | ||
311 | sensor_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
312 | { | ||
313 | struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls; | ||
314 | int check_result; | ||
315 | char *process_path; | ||
316 | |||
317 | sensorinfo->execution_task = | ||
318 | GNUNET_SCHEDULER_add_delayed (sensorinfo->interval, &sensor_run, | ||
319 | sensorinfo); | ||
320 | if (GNUNET_YES == sensorinfo->running) //FIXME: should we try to kill? | ||
321 | { | ||
322 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
323 | "Sensor `%s' running for too long, will try again next interval\n", | ||
324 | sensorinfo->name); | ||
325 | return; | ||
326 | } | ||
327 | if (GNUNET_NO == should_run_sensor (sensorinfo)) | ||
328 | return; | ||
329 | sensorinfo->running = GNUNET_YES; | ||
330 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting the execution of sensor `%s'\n", | ||
331 | sensorinfo->name); | ||
332 | if (0 == strcmp ("gnunet-statistics", sensorinfo->source)) | ||
333 | { | ||
334 | sensorinfo->gnunet_stat_get_handle = GNUNET_STATISTICS_get (statistics, sensorinfo->gnunet_stat_service, sensorinfo->gnunet_stat_name, sensorinfo->interval, //try to get values only for the interval of the sensor | ||
335 | &end_sensor_run_stat, | ||
336 | &sensor_statistics_iterator, | ||
337 | sensorinfo); | ||
338 | if (NULL == sensorinfo->gnunet_stat_get_handle) | ||
339 | sensorinfo->running = GNUNET_NO; | ||
340 | } | ||
341 | else if (0 == strcmp ("process", sensorinfo->source)) | ||
342 | { | ||
343 | if (GNUNET_YES == is_path (sensorinfo->ext_process)) | ||
344 | { | ||
345 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
346 | _ | ||
347 | ("Sensor `%s': External process should not be a path, disabling sensor.\n"), | ||
348 | sensorinfo->name); | ||
349 | set_sensor_enabled (sensorinfo, GNUNET_NO); | ||
350 | return; | ||
351 | } | ||
352 | //check if the process exists in $PATH | ||
353 | process_path = GNUNET_strdup (sensorinfo->ext_process); | ||
354 | check_result = | ||
355 | GNUNET_OS_check_helper_binary (process_path, GNUNET_NO, NULL); | ||
356 | if (GNUNET_SYSERR == check_result) | ||
357 | { | ||
358 | //search in sensor directory | ||
359 | GNUNET_free (process_path); | ||
360 | GNUNET_asprintf (&process_path, "%s%s-files%s%s", sensor_dir, | ||
361 | sensorinfo->name, DIR_SEPARATOR_STR, | ||
362 | sensorinfo->ext_process); | ||
363 | check_result = | ||
364 | GNUNET_OS_check_helper_binary (process_path, GNUNET_NO, NULL); | ||
365 | } | ||
366 | if (GNUNET_SYSERR == check_result) | ||
367 | { | ||
368 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
369 | _ | ||
370 | ("Sensor `%s' process `%s' problem: binary doesn't exist or not executable\n"), | ||
371 | sensorinfo->name, sensorinfo->ext_process); | ||
372 | set_sensor_enabled (sensorinfo, GNUNET_NO); | ||
373 | sensorinfo->running = GNUNET_NO; | ||
374 | GNUNET_free (process_path); | ||
375 | return; | ||
376 | } | ||
377 | sensorinfo->ext_cmd_value_received = GNUNET_NO; | ||
378 | sensorinfo->ext_cmd = | ||
379 | GNUNET_OS_command_run (&sensor_process_callback, sensorinfo, | ||
380 | GNUNET_TIME_UNIT_FOREVER_REL, process_path, | ||
381 | sensorinfo->ext_process, sensorinfo->ext_args, | ||
382 | NULL); | ||
383 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Process started for sensor `%s'\n", | ||
384 | sensorinfo->name); | ||
385 | GNUNET_free (process_path); | ||
386 | } | ||
387 | else | ||
388 | { | ||
389 | sensorinfo->running = GNUNET_NO; | ||
390 | GNUNET_break (0); /* shouldn't happen */ | ||
391 | } | ||
392 | } | ||
393 | |||
394 | |||
395 | /** | ||
396 | * Starts the execution of a sensor | ||
397 | * | ||
398 | * @param cls unused | ||
399 | * @param key hash of sensor name, key to hashmap (unused) | ||
400 | * @param value a `struct GNUNET_SENSOR_SensorInfo *` | ||
401 | * @return #GNUNET_YES if we should continue to | ||
402 | * iterate, | ||
403 | * #GNUNET_NO if not. | ||
404 | */ | ||
405 | static int | ||
406 | schedule_sensor (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
407 | { | ||
408 | struct GNUNET_SENSOR_SensorInfo *sensorinfo = value; | ||
409 | |||
410 | if (GNUNET_NO == should_run_sensor (sensorinfo)) | ||
411 | return GNUNET_YES; | ||
412 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
413 | "Scheduling sensor `%s' to run after %" PRIu64 " microseconds\n", | ||
414 | sensorinfo->name, sensorinfo->interval.rel_value_us); | ||
415 | if (NULL != sensorinfo->execution_task) | ||
416 | { | ||
417 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
418 | _("Sensor `%s' execution task already set, this should not happen\n"), | ||
419 | sensorinfo->name); | ||
420 | return GNUNET_NO; | ||
421 | } | ||
422 | sensorinfo->execution_task = | ||
423 | GNUNET_SCHEDULER_add_delayed (sensorinfo->interval, &sensor_run, | ||
424 | sensorinfo); | ||
425 | return GNUNET_YES; | ||
426 | } | ||
427 | |||
428 | |||
429 | /** | ||
430 | * Starts the execution of all enabled sensors | ||
431 | */ | ||
432 | static void | ||
433 | schedule_all_sensors () | ||
434 | { | ||
435 | GNUNET_CONTAINER_multihashmap_iterate (sensors, &schedule_sensor, NULL); | ||
436 | } | ||
437 | |||
438 | |||
439 | /** | ||
440 | * Start the sensor monitoring module | ||
441 | * | ||
442 | * @param c our service configuration | ||
443 | * @param sensors multihashmap of loaded sensors | ||
444 | * @return #GNUNET_OK if started successfully, #GNUNET_SYSERR otherwise | ||
445 | */ | ||
446 | int | ||
447 | SENSOR_monitoring_start (const struct GNUNET_CONFIGURATION_Handle *c, | ||
448 | struct GNUNET_CONTAINER_MultiHashMap *s) | ||
449 | { | ||
450 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting sensor reporting module.\n"); | ||
451 | GNUNET_assert (NULL != s); | ||
452 | sensors = s; | ||
453 | cfg = c; | ||
454 | statistics = GNUNET_STATISTICS_create ("sensor", cfg); | ||
455 | if (GNUNET_OK != | ||
456 | GNUNET_CONFIGURATION_get_value_filename (cfg, "SENSOR", "SENSOR_DIR", | ||
457 | &sensor_dir)) | ||
458 | { | ||
459 | sensor_dir = GNUNET_SENSOR_get_default_sensor_dir (); | ||
460 | } | ||
461 | if (NULL == statistics) | ||
462 | { | ||
463 | SENSOR_monitoring_stop (); | ||
464 | return GNUNET_SYSERR; | ||
465 | } | ||
466 | peerstore = GNUNET_PEERSTORE_connect (cfg); | ||
467 | if (NULL == peerstore) | ||
468 | { | ||
469 | SENSOR_monitoring_stop (); | ||
470 | return GNUNET_SYSERR; | ||
471 | } | ||
472 | GNUNET_CRYPTO_get_peer_identity (cfg, &peerid); | ||
473 | schedule_all_sensors (); | ||
474 | return GNUNET_OK; | ||
475 | } | ||
476 | |||
477 | /* end of gnunet-service-sensor_analysis.c */ | ||
diff --git a/src/sensor/gnunet-service-sensor_reporting.c b/src/sensor/gnunet-service-sensor_reporting.c deleted file mode 100644 index 4ea570ccd..000000000 --- a/src/sensor/gnunet-service-sensor_reporting.c +++ /dev/null | |||
@@ -1,1437 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensor/gnunet-service-sensor_reporting.c | ||
23 | * @brief sensor service reporting functionality | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "sensor.h" | ||
29 | #include "gnunet_peerstore_service.h" | ||
30 | #include "gnunet_core_service.h" | ||
31 | #include "gnunet_cadet_service.h" | ||
32 | #include "gnunet_applications.h" | ||
33 | |||
34 | #define LOG(kind,...) GNUNET_log_from (kind, "sensor-reporting",__VA_ARGS__) | ||
35 | |||
36 | /** | ||
37 | * Retry time when failing to connect to collection point | ||
38 | */ | ||
39 | #define CP_RETRY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1) | ||
40 | |||
41 | |||
42 | /** | ||
43 | * When we are still generating a proof-of-work and we need to send an anomaly | ||
44 | * report, we queue them until the generation is complete | ||
45 | */ | ||
46 | struct AnomalyReportingQueueItem | ||
47 | { | ||
48 | |||
49 | /** | ||
50 | * DLL | ||
51 | */ | ||
52 | struct AnomalyReportingQueueItem *prev; | ||
53 | |||
54 | /** | ||
55 | * DLL | ||
56 | */ | ||
57 | struct AnomalyReportingQueueItem *next; | ||
58 | |||
59 | /** | ||
60 | * Message queue belonging to the peer that is the destination of the report | ||
61 | */ | ||
62 | struct GNUNET_MQ_Handle *dest_mq; | ||
63 | |||
64 | /** | ||
65 | * Report type | ||
66 | */ | ||
67 | int type; | ||
68 | |||
69 | }; | ||
70 | |||
71 | struct AnomalyInfo | ||
72 | { | ||
73 | |||
74 | /** | ||
75 | * DLL | ||
76 | */ | ||
77 | struct AnomalyInfo *prev; | ||
78 | |||
79 | /** | ||
80 | * DLL | ||
81 | */ | ||
82 | struct AnomalyInfo *next; | ||
83 | |||
84 | /** | ||
85 | * Sensor information | ||
86 | */ | ||
87 | struct GNUNET_SENSOR_SensorInfo *sensor; | ||
88 | |||
89 | /** | ||
90 | * Current anomalous status of sensor | ||
91 | */ | ||
92 | int anomalous; | ||
93 | |||
94 | /** | ||
95 | * List of peers that reported an anomaly for this sensor | ||
96 | */ | ||
97 | struct GNUNET_CONTAINER_MultiPeerMap *anomalous_neighbors; | ||
98 | |||
99 | /** | ||
100 | * Report block with proof-of-work and signature | ||
101 | */ | ||
102 | struct GNUNET_SENSOR_crypto_pow_block *report_block; | ||
103 | |||
104 | /** | ||
105 | * Context of an operation creating pow and signature | ||
106 | */ | ||
107 | struct GNUNET_SENSOR_crypto_pow_context *report_creation_cx; | ||
108 | |||
109 | /** | ||
110 | * Head of the queue of pending report destinations | ||
111 | */ | ||
112 | struct AnomalyReportingQueueItem *reporting_queue_head; | ||
113 | |||
114 | /** | ||
115 | * Head of the queue of pending report destinations | ||
116 | */ | ||
117 | struct AnomalyReportingQueueItem *reporting_queue_tail; | ||
118 | |||
119 | }; | ||
120 | |||
121 | struct ValueInfo | ||
122 | { | ||
123 | |||
124 | /** | ||
125 | * DLL | ||
126 | */ | ||
127 | struct ValueInfo *prev; | ||
128 | |||
129 | /** | ||
130 | * DLL | ||
131 | */ | ||
132 | struct ValueInfo *next; | ||
133 | |||
134 | /** | ||
135 | * Sensor information | ||
136 | */ | ||
137 | struct GNUNET_SENSOR_SensorInfo *sensor; | ||
138 | |||
139 | /** | ||
140 | * Last value read from sensor | ||
141 | */ | ||
142 | void *last_value; | ||
143 | |||
144 | /** | ||
145 | * Size of @e last_value | ||
146 | */ | ||
147 | size_t last_value_size; | ||
148 | |||
149 | /** | ||
150 | * Timestamp of last value reading | ||
151 | */ | ||
152 | struct GNUNET_TIME_Absolute last_value_timestamp; | ||
153 | |||
154 | /** | ||
155 | * Has the last value seen already been reported to collection point? | ||
156 | */ | ||
157 | int last_value_reported; | ||
158 | |||
159 | /** | ||
160 | * Watcher of sensor values | ||
161 | */ | ||
162 | struct GNUNET_PEERSTORE_WatchContext *wc; | ||
163 | |||
164 | /** | ||
165 | * Collection point reporting task (or NULL) | ||
166 | */ | ||
167 | struct GNUNET_SCHEDULER_Task *reporting_task; | ||
168 | |||
169 | }; | ||
170 | |||
171 | /** | ||
172 | * Information about a connected CORE peer. | ||
173 | * Note that we only know about a connected peer if it is running the same | ||
174 | * application (sensor anomaly reporting) as us. | ||
175 | */ | ||
176 | struct CorePeer | ||
177 | { | ||
178 | |||
179 | /** | ||
180 | * DLL | ||
181 | */ | ||
182 | struct CorePeer *prev; | ||
183 | |||
184 | /** | ||
185 | * DLL | ||
186 | */ | ||
187 | struct CorePeer *next; | ||
188 | |||
189 | /** | ||
190 | * Peer identity of connected peer | ||
191 | */ | ||
192 | struct GNUNET_PeerIdentity *peer_id; | ||
193 | |||
194 | /** | ||
195 | * Message queue for messages to be sent to this peer | ||
196 | */ | ||
197 | struct GNUNET_MQ_Handle *mq; | ||
198 | |||
199 | }; | ||
200 | |||
201 | /** | ||
202 | * Information about a connected CADET peer (collection point). | ||
203 | */ | ||
204 | struct CadetPeer | ||
205 | { | ||
206 | |||
207 | /** | ||
208 | * DLL | ||
209 | */ | ||
210 | struct CadetPeer *prev; | ||
211 | |||
212 | /** | ||
213 | * DLL | ||
214 | */ | ||
215 | struct CadetPeer *next; | ||
216 | |||
217 | /** | ||
218 | * Peer Identity | ||
219 | */ | ||
220 | struct GNUNET_PeerIdentity peer_id; | ||
221 | |||
222 | /** | ||
223 | * CADET channel handle | ||
224 | */ | ||
225 | struct GNUNET_CADET_Channel *channel; | ||
226 | |||
227 | /** | ||
228 | * Message queue for messages to be sent to this peer | ||
229 | */ | ||
230 | struct GNUNET_MQ_Handle *mq; | ||
231 | |||
232 | /** | ||
233 | * CADET transmit handle | ||
234 | */ | ||
235 | struct GNUNET_CADET_TransmitHandle *th; | ||
236 | |||
237 | /** | ||
238 | * Task used to try reconnection to collection point after failure | ||
239 | */ | ||
240 | struct GNUNET_SCHEDULER_Task * reconnect_task; | ||
241 | |||
242 | /** | ||
243 | * Are we currently destroying the channel and its context? | ||
244 | */ | ||
245 | int destroying; | ||
246 | |||
247 | }; | ||
248 | |||
249 | |||
250 | /** | ||
251 | * Our configuration. | ||
252 | */ | ||
253 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
254 | |||
255 | /** | ||
256 | * Multihashmap of loaded sensors | ||
257 | */ | ||
258 | static struct GNUNET_CONTAINER_MultiHashMap *sensors; | ||
259 | |||
260 | /** | ||
261 | * Handle to peerstore service | ||
262 | */ | ||
263 | static struct GNUNET_PEERSTORE_Handle *peerstore; | ||
264 | |||
265 | /** | ||
266 | * Handle to core service | ||
267 | */ | ||
268 | static struct GNUNET_CORE_Handle *core; | ||
269 | |||
270 | /** | ||
271 | * Handle to CADET service | ||
272 | */ | ||
273 | static struct GNUNET_CADET_Handle *cadet; | ||
274 | |||
275 | /** | ||
276 | * My peer id | ||
277 | */ | ||
278 | static struct GNUNET_PeerIdentity mypeerid; | ||
279 | |||
280 | /** | ||
281 | * My private key | ||
282 | */ | ||
283 | static struct GNUNET_CRYPTO_EddsaPrivateKey *private_key; | ||
284 | |||
285 | /** | ||
286 | * Head of DLL of anomaly info structs | ||
287 | */ | ||
288 | static struct AnomalyInfo *ai_head; | ||
289 | |||
290 | /** | ||
291 | * Tail of DLL of anomaly info structs | ||
292 | */ | ||
293 | static struct AnomalyInfo *ai_tail; | ||
294 | |||
295 | /** | ||
296 | * Head of DLL of value info structs | ||
297 | */ | ||
298 | static struct ValueInfo *vi_head; | ||
299 | |||
300 | /** | ||
301 | * Tail of DLL of value info structs | ||
302 | */ | ||
303 | static struct ValueInfo *vi_tail; | ||
304 | |||
305 | /** | ||
306 | * Head of DLL of CORE peers | ||
307 | */ | ||
308 | static struct CorePeer *corep_head; | ||
309 | |||
310 | /** | ||
311 | * Tail of DLL of CORE peers | ||
312 | */ | ||
313 | static struct CorePeer *corep_tail; | ||
314 | |||
315 | /** | ||
316 | * Head of DLL of CADET peers | ||
317 | */ | ||
318 | static struct CadetPeer *cadetp_head; | ||
319 | |||
320 | /** | ||
321 | * Tail of DLL of CADET peers | ||
322 | */ | ||
323 | static struct CadetPeer *cadetp_tail; | ||
324 | |||
325 | /** | ||
326 | * Is the module started? | ||
327 | */ | ||
328 | static int module_running = GNUNET_NO; | ||
329 | |||
330 | /** | ||
331 | * Number of known neighborhood peers | ||
332 | */ | ||
333 | static int neighborhood; | ||
334 | |||
335 | /** | ||
336 | * Parameter that defines the complexity of the proof-of-work | ||
337 | */ | ||
338 | static long long unsigned int pow_matching_bits; | ||
339 | |||
340 | |||
341 | |||
342 | /** | ||
343 | * Try reconnecting to collection point and send last queued message | ||
344 | */ | ||
345 | static void | ||
346 | cp_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
347 | |||
348 | |||
349 | /******************************************************************************/ | ||
350 | /****************************** CLEANUP ******************************/ | ||
351 | /******************************************************************************/ | ||
352 | |||
353 | /** | ||
354 | * Destroy anomaly info struct | ||
355 | * | ||
356 | * @param ai struct to destroy | ||
357 | */ | ||
358 | static void | ||
359 | destroy_anomaly_info (struct AnomalyInfo *ai) | ||
360 | { | ||
361 | struct AnomalyReportingQueueItem *ar_item; | ||
362 | |||
363 | ar_item = ai->reporting_queue_head; | ||
364 | while (NULL != ar_item) | ||
365 | { | ||
366 | GNUNET_CONTAINER_DLL_remove (ai->reporting_queue_head, | ||
367 | ai->reporting_queue_tail, ar_item); | ||
368 | GNUNET_free (ar_item); | ||
369 | ar_item = ai->reporting_queue_head; | ||
370 | } | ||
371 | if (NULL != ai->report_creation_cx) | ||
372 | { | ||
373 | GNUNET_SENSOR_crypto_pow_sign_cancel (ai->report_creation_cx); | ||
374 | ai->report_creation_cx = NULL; | ||
375 | } | ||
376 | if (NULL != ai->report_block) | ||
377 | { | ||
378 | GNUNET_free (ai->report_block); | ||
379 | ai->report_block = NULL; | ||
380 | } | ||
381 | if (NULL != ai->anomalous_neighbors) | ||
382 | { | ||
383 | GNUNET_CONTAINER_multipeermap_destroy (ai->anomalous_neighbors); | ||
384 | ai->anomalous_neighbors = NULL; | ||
385 | } | ||
386 | GNUNET_free (ai); | ||
387 | } | ||
388 | |||
389 | |||
390 | /** | ||
391 | * Destroy value info struct | ||
392 | * | ||
393 | * @param vi struct to destroy | ||
394 | */ | ||
395 | static void | ||
396 | destroy_value_info (struct ValueInfo *vi) | ||
397 | { | ||
398 | if (NULL != vi->wc) | ||
399 | { | ||
400 | GNUNET_PEERSTORE_watch_cancel (vi->wc); | ||
401 | vi->wc = NULL; | ||
402 | } | ||
403 | if (NULL != vi->reporting_task) | ||
404 | { | ||
405 | GNUNET_SCHEDULER_cancel (vi->reporting_task); | ||
406 | vi->reporting_task = NULL; | ||
407 | } | ||
408 | if (NULL != vi->last_value) | ||
409 | { | ||
410 | GNUNET_free (vi->last_value); | ||
411 | vi->last_value = NULL; | ||
412 | } | ||
413 | GNUNET_free (vi); | ||
414 | } | ||
415 | |||
416 | |||
417 | /** | ||
418 | * Destroy core peer struct | ||
419 | * | ||
420 | * @param corep struct to destroy | ||
421 | */ | ||
422 | static void | ||
423 | destroy_core_peer (struct CorePeer *corep) | ||
424 | { | ||
425 | struct AnomalyInfo *ai; | ||
426 | struct AnomalyReportingQueueItem *ar_item; | ||
427 | |||
428 | ai = ai_head; | ||
429 | while (NULL != ai) | ||
430 | { | ||
431 | GNUNET_assert (NULL != ai->anomalous_neighbors); | ||
432 | GNUNET_CONTAINER_multipeermap_remove_all (ai->anomalous_neighbors, | ||
433 | corep->peer_id); | ||
434 | /* Remove the core peer from any reporting queues */ | ||
435 | ar_item = ai->reporting_queue_head; | ||
436 | while (NULL != ar_item) | ||
437 | { | ||
438 | if (ar_item->dest_mq == corep->mq) | ||
439 | { | ||
440 | GNUNET_CONTAINER_DLL_remove (ai->reporting_queue_head, | ||
441 | ai->reporting_queue_tail, ar_item); | ||
442 | break; | ||
443 | } | ||
444 | ar_item = ar_item->next; | ||
445 | } | ||
446 | ai = ai->next; | ||
447 | } | ||
448 | if (NULL != corep->mq) | ||
449 | { | ||
450 | GNUNET_MQ_destroy (corep->mq); | ||
451 | corep->mq = NULL; | ||
452 | } | ||
453 | GNUNET_free (corep); | ||
454 | } | ||
455 | |||
456 | |||
457 | /** | ||
458 | * Destroy cadet peer struct | ||
459 | * | ||
460 | * @param cadetp struct to destroy | ||
461 | */ | ||
462 | static void | ||
463 | destroy_cadet_peer (struct CadetPeer *cadetp) | ||
464 | { | ||
465 | cadetp->destroying = GNUNET_YES; | ||
466 | if (NULL != cadetp->reconnect_task) | ||
467 | { | ||
468 | GNUNET_SCHEDULER_cancel (cadetp->reconnect_task); | ||
469 | cadetp->reconnect_task = NULL; | ||
470 | } | ||
471 | if (NULL != cadetp->mq) | ||
472 | { | ||
473 | GNUNET_MQ_destroy (cadetp->mq); | ||
474 | cadetp->mq = NULL; | ||
475 | } | ||
476 | if (NULL != cadetp->channel) | ||
477 | { | ||
478 | GNUNET_CADET_channel_destroy (cadetp->channel); | ||
479 | cadetp->channel = NULL; | ||
480 | } | ||
481 | GNUNET_free (cadetp); | ||
482 | } | ||
483 | |||
484 | |||
485 | /** | ||
486 | * Stop sensor reporting module | ||
487 | */ | ||
488 | void | ||
489 | SENSOR_reporting_stop () | ||
490 | { | ||
491 | struct ValueInfo *vi; | ||
492 | struct CorePeer *corep; | ||
493 | struct AnomalyInfo *ai; | ||
494 | struct CadetPeer *cadetp; | ||
495 | |||
496 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Stopping sensor anomaly reporting module.\n"); | ||
497 | module_running = GNUNET_NO; | ||
498 | neighborhood = 0; | ||
499 | /* Destroy value info's */ | ||
500 | vi = vi_head; | ||
501 | while (NULL != vi) | ||
502 | { | ||
503 | GNUNET_CONTAINER_DLL_remove (vi_head, vi_tail, vi); | ||
504 | destroy_value_info (vi); | ||
505 | vi = vi_head; | ||
506 | } | ||
507 | /* Destroy core peers */ | ||
508 | corep = corep_head; | ||
509 | while (NULL != corep) | ||
510 | { | ||
511 | GNUNET_CONTAINER_DLL_remove (corep_head, corep_tail, corep); | ||
512 | destroy_core_peer (corep); | ||
513 | corep = corep_head; | ||
514 | } | ||
515 | /* Destroy anomaly info's */ | ||
516 | ai = ai_head; | ||
517 | while (NULL != ai) | ||
518 | { | ||
519 | GNUNET_CONTAINER_DLL_remove (ai_head, ai_tail, ai); | ||
520 | destroy_anomaly_info (ai); | ||
521 | ai = ai_head; | ||
522 | } | ||
523 | /* Destroy cadet peers */ | ||
524 | cadetp = cadetp_head; | ||
525 | while (NULL != cadetp) | ||
526 | { | ||
527 | GNUNET_CONTAINER_DLL_remove (cadetp_head, cadetp_tail, cadetp); | ||
528 | destroy_cadet_peer (cadetp); | ||
529 | cadetp = cadetp_head; | ||
530 | } | ||
531 | /* Disconnect from other services */ | ||
532 | if (NULL != core) | ||
533 | { | ||
534 | GNUNET_CORE_disconnect (core); | ||
535 | core = NULL; | ||
536 | } | ||
537 | if (NULL != peerstore) | ||
538 | { | ||
539 | GNUNET_PEERSTORE_disconnect (peerstore, GNUNET_NO); | ||
540 | peerstore = NULL; | ||
541 | } | ||
542 | if (NULL != cadet) | ||
543 | { | ||
544 | GNUNET_CADET_disconnect (cadet); | ||
545 | cadet = NULL; | ||
546 | } | ||
547 | } | ||
548 | |||
549 | |||
550 | /******************************************************************************/ | ||
551 | /****************************** HELPERS ******************************/ | ||
552 | /******************************************************************************/ | ||
553 | |||
554 | |||
555 | /** | ||
556 | * Gets the anomaly info struct related to the given sensor | ||
557 | * | ||
558 | * @param sensor Sensor to search by | ||
559 | */ | ||
560 | static struct AnomalyInfo * | ||
561 | get_anomaly_info_by_sensor (struct GNUNET_SENSOR_SensorInfo *sensor) | ||
562 | { | ||
563 | struct AnomalyInfo *ai; | ||
564 | |||
565 | ai = ai_head; | ||
566 | while (NULL != ai) | ||
567 | { | ||
568 | if (ai->sensor == sensor) | ||
569 | { | ||
570 | return ai; | ||
571 | } | ||
572 | ai = ai->next; | ||
573 | } | ||
574 | return NULL; | ||
575 | } | ||
576 | |||
577 | |||
578 | /** | ||
579 | * Function called to notify a client about the connection | ||
580 | * begin ready to queue more data. "buf" will be | ||
581 | * NULL and "size" zero if the connection was closed for | ||
582 | * writing in the meantime. | ||
583 | * | ||
584 | * @param cls closure | ||
585 | * @param size number of bytes available in buf | ||
586 | * @param buf where the callee should write the message | ||
587 | * @return number of bytes written to buf | ||
588 | */ | ||
589 | static size_t | ||
590 | cp_mq_ntr (void *cls, size_t size, void *buf) | ||
591 | { | ||
592 | struct CadetPeer *cadetp = cls; | ||
593 | const struct GNUNET_MessageHeader *msg = GNUNET_MQ_impl_current (cadetp->mq); | ||
594 | uint16_t msize; | ||
595 | |||
596 | LOG (GNUNET_ERROR_TYPE_DEBUG, "cp_mq_ntr()\n"); | ||
597 | cadetp->th = NULL; | ||
598 | if (NULL == buf) | ||
599 | { | ||
600 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
601 | "Sending anomaly report to collection point failed." | ||
602 | " Retrying connection in %s.\n", | ||
603 | GNUNET_STRINGS_relative_time_to_string (CP_RETRY, GNUNET_NO)); | ||
604 | cadetp->reconnect_task = | ||
605 | GNUNET_SCHEDULER_add_delayed (CP_RETRY, &cp_reconnect, cadetp); | ||
606 | return 0; | ||
607 | } | ||
608 | msize = ntohs (msg->size); | ||
609 | GNUNET_assert (msize <= size); | ||
610 | memcpy (buf, msg, msize); | ||
611 | GNUNET_MQ_impl_send_continue (cadetp->mq); | ||
612 | return msize; | ||
613 | } | ||
614 | |||
615 | |||
616 | /** | ||
617 | * Try reconnecting to collection point and send last queued message | ||
618 | */ | ||
619 | static void | ||
620 | cp_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
621 | { | ||
622 | struct CadetPeer *cadetp = cls; | ||
623 | const struct GNUNET_MessageHeader *msg; | ||
624 | |||
625 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
626 | "Retrying connection to collection point `%s'.\n", | ||
627 | GNUNET_i2s (&cadetp->peer_id)); | ||
628 | cadetp->reconnect_task = NULL; | ||
629 | GNUNET_assert (NULL == cadetp->channel); | ||
630 | cadetp->channel = | ||
631 | GNUNET_CADET_channel_create (cadet, cadetp, &cadetp->peer_id, | ||
632 | GNUNET_APPLICATION_TYPE_SENSORDASHBOARD, | ||
633 | GNUNET_CADET_OPTION_RELIABLE); | ||
634 | msg = GNUNET_MQ_impl_current (cadetp->mq); | ||
635 | cadetp->th = | ||
636 | GNUNET_CADET_notify_transmit_ready (cadetp->channel, GNUNET_NO, | ||
637 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
638 | ntohs (msg->size), cp_mq_ntr, cadetp); | ||
639 | } | ||
640 | |||
641 | |||
642 | /** | ||
643 | * Signature of functions implementing the | ||
644 | * sending functionality of a message queue. | ||
645 | * | ||
646 | * @param mq the message queue | ||
647 | * @param msg the message to send | ||
648 | * @param impl_state state of the implementation | ||
649 | */ | ||
650 | static void | ||
651 | cp_mq_send_impl (struct GNUNET_MQ_Handle *mq, | ||
652 | const struct GNUNET_MessageHeader *msg, void *impl_state) | ||
653 | { | ||
654 | struct CadetPeer *cadetp = impl_state; | ||
655 | |||
656 | LOG (GNUNET_ERROR_TYPE_DEBUG, "cp_mq_send_impl()\n"); | ||
657 | GNUNET_assert (NULL == cadetp->th); | ||
658 | if (NULL == cadetp->channel) | ||
659 | { | ||
660 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
661 | "Sending anomaly report to collection point failed." | ||
662 | " Retrying connection in %s.\n", | ||
663 | GNUNET_STRINGS_relative_time_to_string (CP_RETRY, GNUNET_NO)); | ||
664 | cadetp->reconnect_task = | ||
665 | GNUNET_SCHEDULER_add_delayed (CP_RETRY, &cp_reconnect, cadetp); | ||
666 | return; | ||
667 | } | ||
668 | cadetp->th = | ||
669 | GNUNET_CADET_notify_transmit_ready (cadetp->channel, GNUNET_NO, | ||
670 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
671 | ntohs (msg->size), cp_mq_ntr, cadetp); | ||
672 | } | ||
673 | |||
674 | |||
675 | /** | ||
676 | * Signature of functions implementing the | ||
677 | * destruction of a message queue. | ||
678 | * Implementations must not free 'mq', but should | ||
679 | * take care of 'impl_state'. | ||
680 | * | ||
681 | * @param mq the message queue to destroy | ||
682 | * @param impl_state state of the implementation | ||
683 | */ | ||
684 | static void | ||
685 | cp_mq_destroy_impl (struct GNUNET_MQ_Handle *mq, void *impl_state) | ||
686 | { | ||
687 | struct CadetPeer *cp = impl_state; | ||
688 | |||
689 | LOG (GNUNET_ERROR_TYPE_DEBUG, "cp_mq_destroy_impl()\n"); | ||
690 | if (NULL != cp->th) | ||
691 | { | ||
692 | GNUNET_CADET_notify_transmit_ready_cancel (cp->th); | ||
693 | cp->th = NULL; | ||
694 | } | ||
695 | } | ||
696 | |||
697 | |||
698 | /** | ||
699 | * Create the message queue used to send messages to a collection point. | ||
700 | * This will be used to make sure that the message are queued even if the | ||
701 | * connection to the collection point can not be established at the moment. | ||
702 | * | ||
703 | * @param cp CadetPeer information struct | ||
704 | * @return Message queue handle | ||
705 | */ | ||
706 | static struct GNUNET_MQ_Handle * | ||
707 | cp_mq_create (struct CadetPeer *cp) | ||
708 | { | ||
709 | return GNUNET_MQ_queue_for_callbacks (cp_mq_send_impl, cp_mq_destroy_impl, | ||
710 | NULL, cp, NULL, NULL, NULL); | ||
711 | } | ||
712 | |||
713 | |||
714 | /** | ||
715 | * Returns context of a connected CADET peer. | ||
716 | * Creates it first if didn't exist before. | ||
717 | * | ||
718 | * @param pid Peer Identity | ||
719 | * @return Context of connected CADET peer | ||
720 | */ | ||
721 | static struct CadetPeer * | ||
722 | get_cadet_peer (struct GNUNET_PeerIdentity pid) | ||
723 | { | ||
724 | struct CadetPeer *cadetp; | ||
725 | |||
726 | cadetp = cadetp_head; | ||
727 | while (NULL != cadetp) | ||
728 | { | ||
729 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&pid, &cadetp->peer_id)) | ||
730 | return cadetp; | ||
731 | cadetp = cadetp->next; | ||
732 | } | ||
733 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating a CADET connection to peer `%s'.\n", | ||
734 | GNUNET_i2s (&pid)); | ||
735 | /* Not found, create struct and channel */ | ||
736 | cadetp = GNUNET_new (struct CadetPeer); | ||
737 | cadetp->peer_id = pid; | ||
738 | cadetp->channel = | ||
739 | GNUNET_CADET_channel_create (cadet, cadetp, &pid, | ||
740 | GNUNET_APPLICATION_TYPE_SENSORDASHBOARD, | ||
741 | GNUNET_CADET_OPTION_RELIABLE); | ||
742 | cadetp->mq = cp_mq_create (cadetp); | ||
743 | cadetp->reconnect_task = NULL; | ||
744 | GNUNET_CONTAINER_DLL_insert (cadetp_head, cadetp_tail, cadetp); | ||
745 | return cadetp; | ||
746 | } | ||
747 | |||
748 | |||
749 | /** | ||
750 | * This function is called only when we have a block ready and want to send it | ||
751 | * to the given peer (represented by its message queue) | ||
752 | * | ||
753 | * @param mq Message queue to put the message in | ||
754 | * @param ai Anomaly info to report | ||
755 | * @param type Message type | ||
756 | */ | ||
757 | static void | ||
758 | do_send_anomaly_report (struct GNUNET_MQ_Handle *mq, struct AnomalyInfo *ai, | ||
759 | int type) | ||
760 | { | ||
761 | struct GNUNET_MessageHeader *msg; | ||
762 | struct GNUNET_MQ_Envelope *ev; | ||
763 | size_t block_size; | ||
764 | |||
765 | GNUNET_assert (NULL != ai->report_block); | ||
766 | block_size = | ||
767 | sizeof (struct GNUNET_SENSOR_crypto_pow_block) + | ||
768 | ai->report_block->msg_size; | ||
769 | ev = GNUNET_MQ_msg_header_extra (msg, block_size, type); | ||
770 | memcpy (&msg[1], ai->report_block, block_size); | ||
771 | GNUNET_MQ_send (mq, ev); | ||
772 | } | ||
773 | |||
774 | |||
775 | /** | ||
776 | * Check if we have signed and proof-of-work block ready. | ||
777 | * If yes, we send the report directly, if no, we enqueue the reporting until | ||
778 | * the block is ready. | ||
779 | * | ||
780 | * @param mq Message queue to put the message in | ||
781 | * @param ai Anomaly info to report | ||
782 | * @param p2p Is the report sent to a neighboring peer | ||
783 | */ | ||
784 | static void | ||
785 | send_anomaly_report (struct GNUNET_MQ_Handle *mq, struct AnomalyInfo *ai, | ||
786 | int p2p) | ||
787 | { | ||
788 | struct AnomalyReportingQueueItem *ar_item; | ||
789 | int type; | ||
790 | |||
791 | type = | ||
792 | (GNUNET_YES == | ||
793 | p2p) ? GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_REPORT_P2P : | ||
794 | GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_REPORT; | ||
795 | if (NULL == ai->report_block) | ||
796 | { | ||
797 | ar_item = GNUNET_new (struct AnomalyReportingQueueItem); | ||
798 | |||
799 | ar_item->dest_mq = mq; | ||
800 | ar_item->type = type; | ||
801 | GNUNET_CONTAINER_DLL_insert_tail (ai->reporting_queue_head, | ||
802 | ai->reporting_queue_tail, ar_item); | ||
803 | } | ||
804 | else | ||
805 | { | ||
806 | do_send_anomaly_report (mq, ai, type); | ||
807 | } | ||
808 | } | ||
809 | |||
810 | |||
811 | /** | ||
812 | * Callback when the crypto module finished created proof-of-work and signature | ||
813 | * for an anomaly report. | ||
814 | * | ||
815 | * @param cls Closure, a `struct AnomalyInfo *` | ||
816 | * @param block The resulting block, NULL on error | ||
817 | */ | ||
818 | static void | ||
819 | report_creation_cb (void *cls, struct GNUNET_SENSOR_crypto_pow_block *block) | ||
820 | { | ||
821 | struct AnomalyInfo *ai = cls; | ||
822 | struct AnomalyReportingQueueItem *ar_item; | ||
823 | |||
824 | ai->report_creation_cx = NULL; | ||
825 | if (NULL != ai->report_block) | ||
826 | { | ||
827 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
828 | _("Double creation of proof-of-work, this should not happen.\n")); | ||
829 | return; | ||
830 | } | ||
831 | if (NULL == block) | ||
832 | { | ||
833 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
834 | _("Failed to create pow and signature block.\n")); | ||
835 | return; | ||
836 | } | ||
837 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Anomaly report POW block ready.\n"); | ||
838 | ai->report_block = | ||
839 | GNUNET_memdup (block, | ||
840 | sizeof (struct GNUNET_SENSOR_crypto_pow_block) + | ||
841 | block->msg_size); | ||
842 | ar_item = ai->reporting_queue_head; | ||
843 | while (NULL != ar_item) | ||
844 | { | ||
845 | GNUNET_CONTAINER_DLL_remove (ai->reporting_queue_head, | ||
846 | ai->reporting_queue_tail, ar_item); | ||
847 | do_send_anomaly_report (ar_item->dest_mq, ai, ar_item->type); | ||
848 | GNUNET_free (ar_item); | ||
849 | ar_item = ai->reporting_queue_head; | ||
850 | } | ||
851 | } | ||
852 | |||
853 | |||
854 | /** | ||
855 | * When a change to the anomaly info of a sensor is done, this function should | ||
856 | * be called to create the message, its proof-of-work and signuature ready to | ||
857 | * be sent to other peers or collection point. | ||
858 | * | ||
859 | * @param ai Anomaly Info struct | ||
860 | */ | ||
861 | static void | ||
862 | update_anomaly_report_pow_block (struct AnomalyInfo *ai) | ||
863 | { | ||
864 | struct GNUNET_SENSOR_AnomalyReportMessage *arm; | ||
865 | struct GNUNET_TIME_Absolute timestamp; | ||
866 | |||
867 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
868 | "Updating anomaly report POW block due to data change.\n"); | ||
869 | if (NULL != ai->report_block) | ||
870 | { | ||
871 | GNUNET_free (ai->report_block); | ||
872 | ai->report_block = NULL; | ||
873 | } | ||
874 | if (NULL != ai->report_creation_cx) | ||
875 | { | ||
876 | /* If a creation is already running, cancel it because the data changed */ | ||
877 | GNUNET_SENSOR_crypto_pow_sign_cancel (ai->report_creation_cx); | ||
878 | ai->report_creation_cx = NULL; | ||
879 | } | ||
880 | arm = GNUNET_new (struct GNUNET_SENSOR_AnomalyReportMessage); | ||
881 | |||
882 | GNUNET_CRYPTO_hash (ai->sensor->name, strlen (ai->sensor->name) + 1, | ||
883 | &arm->sensorname_hash); | ||
884 | arm->sensorversion_major = htons (ai->sensor->version_major); | ||
885 | arm->sensorversion_minor = htons (ai->sensor->version_minor); | ||
886 | arm->anomalous = htons (ai->anomalous); | ||
887 | arm->anomalous_neighbors = | ||
888 | (0 == | ||
889 | neighborhood) ? 0 : ((float) | ||
890 | GNUNET_CONTAINER_multipeermap_size | ||
891 | (ai->anomalous_neighbors)) / neighborhood; | ||
892 | timestamp = GNUNET_TIME_absolute_get (); | ||
893 | ai->report_creation_cx = | ||
894 | GNUNET_SENSOR_crypto_pow_sign (arm, | ||
895 | sizeof (struct | ||
896 | GNUNET_SENSOR_AnomalyReportMessage), | ||
897 | ×tamp, &mypeerid.public_key, | ||
898 | private_key, pow_matching_bits, | ||
899 | &report_creation_cb, ai); | ||
900 | GNUNET_free (arm); | ||
901 | } | ||
902 | |||
903 | |||
904 | /** | ||
905 | * Create a sensor value message from a given value info struct inside a MQ | ||
906 | * envelope. | ||
907 | * | ||
908 | * @param vi Value info struct to use | ||
909 | * @return Envelope with message | ||
910 | */ | ||
911 | static struct GNUNET_MQ_Envelope * | ||
912 | create_value_message (struct ValueInfo *vi) | ||
913 | { | ||
914 | struct GNUNET_SENSOR_ValueMessage *vm; | ||
915 | struct GNUNET_MQ_Envelope *ev; | ||
916 | |||
917 | ev = GNUNET_MQ_msg_extra (vm, vi->last_value_size, | ||
918 | GNUNET_MESSAGE_TYPE_SENSOR_READING); | ||
919 | GNUNET_CRYPTO_hash (vi->sensor->name, strlen (vi->sensor->name) + 1, | ||
920 | &vm->sensorname_hash); | ||
921 | vm->sensorversion_major = htons (vi->sensor->version_major); | ||
922 | vm->sensorversion_minor = htons (vi->sensor->version_minor); | ||
923 | vm->timestamp = vi->last_value_timestamp; | ||
924 | vm->value_size = htons (vi->last_value_size); | ||
925 | memcpy (&vm[1], vi->last_value, vi->last_value_size); | ||
926 | return ev; | ||
927 | } | ||
928 | |||
929 | |||
930 | /******************************************************************************/ | ||
931 | /*************************** CORE Handlers ***************************/ | ||
932 | /******************************************************************************/ | ||
933 | |||
934 | |||
935 | /** | ||
936 | * An inbound anomaly report is received from a peer through CORE. | ||
937 | * | ||
938 | * @param cls closure (unused) | ||
939 | * @param peer the other peer involved | ||
940 | * @param message the actual message | ||
941 | * @return #GNUNET_OK to keep the connection open, | ||
942 | * #GNUNET_SYSERR to close connection to the peer (signal serious error) | ||
943 | */ | ||
944 | static int | ||
945 | handle_anomaly_report (void *cls, const struct GNUNET_PeerIdentity *other, | ||
946 | const struct GNUNET_MessageHeader *message) | ||
947 | { | ||
948 | struct GNUNET_SENSOR_crypto_pow_block *report_block; | ||
949 | struct GNUNET_SENSOR_AnomalyReportMessage *arm; | ||
950 | struct GNUNET_SENSOR_SensorInfo *sensor; | ||
951 | struct AnomalyInfo *my_anomaly_info; | ||
952 | struct CadetPeer *cadetp; | ||
953 | int peer_anomalous; | ||
954 | int peer_in_anomalous_list; | ||
955 | |||
956 | /* Verify proof-of-work, signature and extract report message */ | ||
957 | report_block = (struct GNUNET_SENSOR_crypto_pow_block *) &message[1]; | ||
958 | if (sizeof (struct GNUNET_SENSOR_AnomalyReportMessage) != | ||
959 | GNUNET_SENSOR_crypto_verify_pow_sign (report_block, pow_matching_bits, | ||
960 | (struct GNUNET_CRYPTO_EddsaPublicKey | ||
961 | *) &other->public_key, | ||
962 | (void **) &arm)) | ||
963 | { | ||
964 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
965 | "Received invalid anomaly report from peer `%s'.\n", | ||
966 | GNUNET_i2s (other)); | ||
967 | GNUNET_break_op (0); | ||
968 | return GNUNET_SYSERR; | ||
969 | } | ||
970 | /* Now we parse the content of the message */ | ||
971 | sensor = GNUNET_CONTAINER_multihashmap_get (sensors, &arm->sensorname_hash); | ||
972 | if (NULL == sensor || | ||
973 | sensor->version_major != ntohs (arm->sensorversion_major) || | ||
974 | sensor->version_minor != ntohs (arm->sensorversion_minor)) | ||
975 | { | ||
976 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
977 | "I don't have the sensor reported by the peer `%s'.\n", | ||
978 | GNUNET_i2s (other)); | ||
979 | return GNUNET_OK; | ||
980 | } | ||
981 | my_anomaly_info = get_anomaly_info_by_sensor (sensor); | ||
982 | GNUNET_assert (NULL != my_anomaly_info); | ||
983 | peer_in_anomalous_list = | ||
984 | GNUNET_CONTAINER_multipeermap_contains | ||
985 | (my_anomaly_info->anomalous_neighbors, other); | ||
986 | peer_anomalous = ntohs (arm->anomalous); | ||
987 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
988 | "Received an anomaly update from neighbour `%s' (%d).\n", | ||
989 | GNUNET_i2s (other), peer_anomalous); | ||
990 | if (GNUNET_YES == peer_anomalous) | ||
991 | { | ||
992 | if (GNUNET_YES == peer_in_anomalous_list) /* repeated positive report */ | ||
993 | GNUNET_break_op (0); | ||
994 | else | ||
995 | GNUNET_CONTAINER_multipeermap_put (my_anomaly_info->anomalous_neighbors, | ||
996 | other, NULL, | ||
997 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
998 | } | ||
999 | else | ||
1000 | { | ||
1001 | if (GNUNET_NO == peer_in_anomalous_list) /* repeated negative report */ | ||
1002 | GNUNET_break_op (0); | ||
1003 | else | ||
1004 | GNUNET_CONTAINER_multipeermap_remove_all | ||
1005 | (my_anomaly_info->anomalous_neighbors, other); | ||
1006 | } | ||
1007 | /* This is important to create an updated block since the data changed */ | ||
1008 | update_anomaly_report_pow_block (my_anomaly_info); | ||
1009 | /* Send anomaly update to collection point only if I have the same anomaly */ | ||
1010 | if (GNUNET_YES == my_anomaly_info->anomalous && | ||
1011 | NULL != sensor->collection_point && | ||
1012 | GNUNET_YES == sensor->report_anomalies) | ||
1013 | { | ||
1014 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1015 | "Neighbor update triggered sending anomaly report to collection point `%s'.\n", | ||
1016 | GNUNET_i2s (sensor->collection_point)); | ||
1017 | cadetp = get_cadet_peer (*sensor->collection_point); | ||
1018 | send_anomaly_report (cadetp->mq, my_anomaly_info, GNUNET_NO); | ||
1019 | } | ||
1020 | return GNUNET_OK; | ||
1021 | } | ||
1022 | |||
1023 | |||
1024 | /******************************************************************************/ | ||
1025 | /************************ PEERSTORE callbacks ************************/ | ||
1026 | /******************************************************************************/ | ||
1027 | |||
1028 | |||
1029 | /** | ||
1030 | * Sensor value watch callback | ||
1031 | * | ||
1032 | * @param cls Closure, ValueInfo struct related to the sensor we are watching | ||
1033 | * @param record PEERSTORE new record, NULL if error | ||
1034 | * @param emsg Error message, NULL if no error | ||
1035 | * @return #GNUNET_YES to continue watching | ||
1036 | */ | ||
1037 | static int | ||
1038 | value_watch_cb (void *cls, | ||
1039 | const struct GNUNET_PEERSTORE_Record *record, | ||
1040 | const char *emsg) | ||
1041 | { | ||
1042 | struct ValueInfo *vi = cls; | ||
1043 | |||
1044 | if (NULL != emsg) | ||
1045 | { | ||
1046 | LOG (GNUNET_ERROR_TYPE_ERROR, _("PEERSTORE error: %s.\n"), emsg); | ||
1047 | return GNUNET_YES; | ||
1048 | } | ||
1049 | if (NULL != vi->last_value) | ||
1050 | { | ||
1051 | GNUNET_free (vi->last_value); | ||
1052 | vi->last_value_size = 0; | ||
1053 | } | ||
1054 | vi->last_value = GNUNET_memdup (record->value, record->value_size); | ||
1055 | vi->last_value_size = record->value_size; | ||
1056 | vi->last_value_timestamp = GNUNET_TIME_absolute_get (); | ||
1057 | vi->last_value_reported = GNUNET_NO; | ||
1058 | return GNUNET_YES; | ||
1059 | } | ||
1060 | |||
1061 | |||
1062 | /******************************************************************************/ | ||
1063 | /************************** CORE callbacks ***************************/ | ||
1064 | /******************************************************************************/ | ||
1065 | |||
1066 | |||
1067 | /** | ||
1068 | * Method called whenever a CORE peer disconnects. | ||
1069 | * | ||
1070 | * @param cls closure (unused) | ||
1071 | * @param peer peer identity this notification is about | ||
1072 | */ | ||
1073 | static void | ||
1074 | core_disconnect_cb (void *cls, const struct GNUNET_PeerIdentity *peer) | ||
1075 | { | ||
1076 | struct CorePeer *corep; | ||
1077 | |||
1078 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&mypeerid, peer)) | ||
1079 | return; | ||
1080 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Core peer `%s' disconnected.\n", | ||
1081 | GNUNET_i2s (peer)); | ||
1082 | neighborhood--; | ||
1083 | corep = corep_head; | ||
1084 | while (NULL != corep) | ||
1085 | { | ||
1086 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, corep->peer_id)) | ||
1087 | { | ||
1088 | GNUNET_CONTAINER_DLL_remove (corep_head, corep_tail, corep); | ||
1089 | destroy_core_peer (corep); | ||
1090 | return; | ||
1091 | } | ||
1092 | corep = corep->next; | ||
1093 | } | ||
1094 | } | ||
1095 | |||
1096 | |||
1097 | /** | ||
1098 | * Method called whenever a given peer connects through CORE. | ||
1099 | * | ||
1100 | * @param cls closure (unused) | ||
1101 | * @param peer peer identity this notification is about | ||
1102 | */ | ||
1103 | static void | ||
1104 | core_connect_cb (void *cls, const struct GNUNET_PeerIdentity *peer) | ||
1105 | { | ||
1106 | struct CorePeer *corep; | ||
1107 | struct AnomalyInfo *ai; | ||
1108 | |||
1109 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&mypeerid, peer)) | ||
1110 | return; | ||
1111 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Connected to core peer `%s'.\n", | ||
1112 | GNUNET_i2s (peer)); | ||
1113 | neighborhood++; | ||
1114 | corep = GNUNET_new (struct CorePeer); | ||
1115 | corep->peer_id = (struct GNUNET_PeerIdentity *) peer; | ||
1116 | corep->mq = GNUNET_CORE_mq_create (core, peer); | ||
1117 | GNUNET_CONTAINER_DLL_insert (corep_head, corep_tail, corep); | ||
1118 | /* Send any locally anomalous sensors to the new peer */ | ||
1119 | ai = ai_head; | ||
1120 | while (NULL != ai) | ||
1121 | { | ||
1122 | if (GNUNET_YES == ai->anomalous) | ||
1123 | { | ||
1124 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1125 | "Updating newly connected neighbor `%s' with anomalous sensor.\n", | ||
1126 | GNUNET_i2s (peer)); | ||
1127 | send_anomaly_report (corep->mq, ai, GNUNET_YES); | ||
1128 | } | ||
1129 | ai = ai->next; | ||
1130 | } | ||
1131 | } | ||
1132 | |||
1133 | |||
1134 | /** | ||
1135 | * Function called after #GNUNET_CORE_connect has succeeded (or failed | ||
1136 | * for good). Note that the private key of the peer is intentionally | ||
1137 | * not exposed here; if you need it, your process should try to read | ||
1138 | * the private key file directly (which should work if you are | ||
1139 | * authorized...). Implementations of this function must not call | ||
1140 | * #GNUNET_CORE_disconnect (other than by scheduling a new task to | ||
1141 | * do this later). | ||
1142 | * | ||
1143 | * @param cls closure (unused) | ||
1144 | * @param my_identity ID of this peer, NULL if we failed | ||
1145 | */ | ||
1146 | static void | ||
1147 | core_startup_cb (void *cls, const struct GNUNET_PeerIdentity *my_identity) | ||
1148 | { | ||
1149 | if (NULL == my_identity) | ||
1150 | { | ||
1151 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to CORE service.\n")); | ||
1152 | SENSOR_reporting_stop (); | ||
1153 | return; | ||
1154 | } | ||
1155 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&mypeerid, my_identity)) | ||
1156 | { | ||
1157 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1158 | _("Peer identity received from CORE init doesn't match ours.\n")); | ||
1159 | SENSOR_reporting_stop (); | ||
1160 | return; | ||
1161 | } | ||
1162 | } | ||
1163 | |||
1164 | |||
1165 | /******************************************************************************/ | ||
1166 | /************************* CADET callbacks ***************************/ | ||
1167 | /******************************************************************************/ | ||
1168 | |||
1169 | /** | ||
1170 | * Function called whenever a channel is destroyed. Should clean up | ||
1171 | * any associated state. | ||
1172 | * | ||
1173 | * It must NOT call #GNUNET_CADET_channel_destroy on the channel. | ||
1174 | * | ||
1175 | * @param cls closure (set from #GNUNET_CADET_connect) | ||
1176 | * @param channel connection to the other end (henceforth invalid) | ||
1177 | * @param channel_ctx place where local state associated | ||
1178 | * with the channel is stored | ||
1179 | */ | ||
1180 | static void | ||
1181 | cadet_channel_destroyed (void *cls, const struct GNUNET_CADET_Channel *channel, | ||
1182 | void *channel_ctx) | ||
1183 | { | ||
1184 | struct CadetPeer *cadetp = channel_ctx; | ||
1185 | |||
1186 | if (GNUNET_YES == cadetp->destroying) | ||
1187 | return; | ||
1188 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1189 | "CADET channel was destroyed by remote peer `%s' or failed to start.\n", | ||
1190 | GNUNET_i2s (&cadetp->peer_id)); | ||
1191 | if (NULL != cadetp->th) | ||
1192 | { | ||
1193 | GNUNET_CADET_notify_transmit_ready_cancel (cadetp->th); | ||
1194 | cadetp->th = NULL; | ||
1195 | } | ||
1196 | cadetp->channel = NULL; | ||
1197 | } | ||
1198 | |||
1199 | |||
1200 | /******************************************************************************/ | ||
1201 | /********************** Local anomaly receiver ***********************/ | ||
1202 | /******************************************************************************/ | ||
1203 | |||
1204 | |||
1205 | /** | ||
1206 | * Used by the analysis module to tell the reporting module about a change in | ||
1207 | * the anomaly status of a sensor. | ||
1208 | * | ||
1209 | * @param sensor Related sensor | ||
1210 | * @param anomalous The new sensor anomalous status | ||
1211 | */ | ||
1212 | void | ||
1213 | SENSOR_reporting_anomaly_update (struct GNUNET_SENSOR_SensorInfo *sensor, | ||
1214 | int anomalous) | ||
1215 | { | ||
1216 | struct AnomalyInfo *ai; | ||
1217 | struct CorePeer *corep; | ||
1218 | struct CadetPeer *cadetp; | ||
1219 | |||
1220 | if (GNUNET_NO == module_running) | ||
1221 | return; | ||
1222 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received an external anomaly update.\n"); | ||
1223 | ai = get_anomaly_info_by_sensor (sensor); | ||
1224 | GNUNET_assert (NULL != ai); | ||
1225 | ai->anomalous = anomalous; | ||
1226 | /* This is important to create an updated block since the data changed */ | ||
1227 | update_anomaly_report_pow_block (ai); | ||
1228 | /* Report change to all neighbors */ | ||
1229 | corep = corep_head; | ||
1230 | while (NULL != corep) | ||
1231 | { | ||
1232 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1233 | "Sending an anomaly report to neighbor `%s'.\n", | ||
1234 | GNUNET_i2s (corep->peer_id)); | ||
1235 | send_anomaly_report (corep->mq, ai, GNUNET_YES); | ||
1236 | corep = corep->next; | ||
1237 | } | ||
1238 | /* Report change to collection point if need */ | ||
1239 | if (NULL != ai->sensor->collection_point && | ||
1240 | GNUNET_YES == ai->sensor->report_anomalies) | ||
1241 | { | ||
1242 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1243 | "Local anomaly update triggered sending anomaly report to collection point `%s'.\n", | ||
1244 | GNUNET_i2s (ai->sensor->collection_point)); | ||
1245 | cadetp = get_cadet_peer (*ai->sensor->collection_point); | ||
1246 | send_anomaly_report (cadetp->mq, ai, GNUNET_NO); | ||
1247 | } | ||
1248 | } | ||
1249 | |||
1250 | |||
1251 | /******************************************************************************/ | ||
1252 | /******************* Reporting values (periodic) *********************/ | ||
1253 | /******************************************************************************/ | ||
1254 | |||
1255 | |||
1256 | /** | ||
1257 | * Task scheduled to send values to collection point | ||
1258 | * | ||
1259 | * @param cls closure, a `struct ValueReportingContext *` | ||
1260 | * @param tc unused | ||
1261 | */ | ||
1262 | static void | ||
1263 | report_value (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1264 | { | ||
1265 | struct ValueInfo *vi = cls; | ||
1266 | struct GNUNET_SENSOR_SensorInfo *sensor = vi->sensor; | ||
1267 | struct CadetPeer *cadetp; | ||
1268 | struct GNUNET_MQ_Envelope *ev; | ||
1269 | |||
1270 | vi->reporting_task = | ||
1271 | GNUNET_SCHEDULER_add_delayed (sensor->value_reporting_interval, | ||
1272 | &report_value, vi); | ||
1273 | if (0 == vi->last_value_size || GNUNET_YES == vi->last_value_reported) | ||
1274 | { | ||
1275 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1276 | "Did not receive a fresh value from `%s' to report.\n", sensor->name); | ||
1277 | return; | ||
1278 | } | ||
1279 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1280 | "Now trying to report last seen value of `%s' to collection point.\n", | ||
1281 | sensor->name); | ||
1282 | cadetp = get_cadet_peer (*sensor->collection_point); | ||
1283 | if (NULL == cadetp->channel) | ||
1284 | { | ||
1285 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1286 | "Trying to send value to collection point but connection failed, discarding.\n"); | ||
1287 | return; | ||
1288 | } | ||
1289 | ev = create_value_message (vi); | ||
1290 | GNUNET_MQ_send (cadetp->mq, ev); | ||
1291 | vi->last_value_reported = GNUNET_YES; | ||
1292 | } | ||
1293 | |||
1294 | |||
1295 | /******************************************************************************/ | ||
1296 | /******************************** INIT *******************************/ | ||
1297 | /******************************************************************************/ | ||
1298 | |||
1299 | |||
1300 | /** | ||
1301 | * Iterator for defined sensors and creates anomaly info context | ||
1302 | * | ||
1303 | * @param cls unused | ||
1304 | * @param key unused | ||
1305 | * @param value a `struct GNUNET_SENSOR_SensorInfo *` with sensor information | ||
1306 | * @return #GNUNET_YES to continue iterations | ||
1307 | */ | ||
1308 | static int | ||
1309 | init_sensor_reporting (void *cls, const struct GNUNET_HashCode *key, | ||
1310 | void *value) | ||
1311 | { | ||
1312 | struct GNUNET_SENSOR_SensorInfo *sensor = value; | ||
1313 | struct AnomalyInfo *ai; | ||
1314 | struct ValueInfo *vi; | ||
1315 | |||
1316 | /* Create sensor anomaly info context */ | ||
1317 | ai = GNUNET_new (struct AnomalyInfo); | ||
1318 | |||
1319 | ai->sensor = sensor; | ||
1320 | ai->anomalous = GNUNET_NO; | ||
1321 | ai->anomalous_neighbors = | ||
1322 | GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); | ||
1323 | ai->report_block = NULL; | ||
1324 | ai->report_creation_cx = NULL; | ||
1325 | GNUNET_CONTAINER_DLL_insert (ai_head, ai_tail, ai); | ||
1326 | /* Create sensor value info context (if needed to be reported) */ | ||
1327 | if (NULL == sensor->collection_point || GNUNET_NO == sensor->report_values) | ||
1328 | return GNUNET_YES; | ||
1329 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
1330 | "Reporting sensor `%s' values to collection point `%s' every %s.\n", | ||
1331 | sensor->name, GNUNET_i2s_full (sensor->collection_point), | ||
1332 | GNUNET_STRINGS_relative_time_to_string (sensor->value_reporting_interval, | ||
1333 | GNUNET_YES)); | ||
1334 | vi = GNUNET_new (struct ValueInfo); | ||
1335 | vi->sensor = sensor; | ||
1336 | vi->last_value = NULL; | ||
1337 | vi->last_value_size = 0; | ||
1338 | vi->last_value_reported = GNUNET_NO; | ||
1339 | vi->wc = | ||
1340 | GNUNET_PEERSTORE_watch (peerstore, "sensor", &mypeerid, sensor->name, | ||
1341 | &value_watch_cb, vi); | ||
1342 | vi->reporting_task = | ||
1343 | GNUNET_SCHEDULER_add_delayed (sensor->value_reporting_interval, | ||
1344 | &report_value, vi); | ||
1345 | GNUNET_CONTAINER_DLL_insert (vi_head, vi_tail, vi); | ||
1346 | return GNUNET_YES; | ||
1347 | } | ||
1348 | |||
1349 | |||
1350 | /** | ||
1351 | * Start the sensor anomaly reporting module | ||
1352 | * | ||
1353 | * @param c our service configuration | ||
1354 | * @param s multihashmap of loaded sensors | ||
1355 | * @return #GNUNET_OK if started successfully, #GNUNET_SYSERR otherwise | ||
1356 | */ | ||
1357 | int | ||
1358 | SENSOR_reporting_start (const struct GNUNET_CONFIGURATION_Handle *c, | ||
1359 | struct GNUNET_CONTAINER_MultiHashMap *s) | ||
1360 | { | ||
1361 | static struct GNUNET_CORE_MessageHandler core_handlers[] = { | ||
1362 | {&handle_anomaly_report, GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_REPORT_P2P, | ||
1363 | sizeof (struct GNUNET_MessageHeader) + | ||
1364 | sizeof (struct GNUNET_SENSOR_crypto_pow_block) + | ||
1365 | sizeof (struct GNUNET_SENSOR_AnomalyReportMessage)}, | ||
1366 | {NULL, 0, 0} | ||
1367 | }; | ||
1368 | static struct GNUNET_CADET_MessageHandler cadet_handlers[] = { | ||
1369 | {NULL, 0, 0} | ||
1370 | }; | ||
1371 | |||
1372 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting sensor reporting module.\n"); | ||
1373 | GNUNET_assert (NULL != s); | ||
1374 | sensors = s; | ||
1375 | cfg = c; | ||
1376 | if (GNUNET_OK != | ||
1377 | GNUNET_CONFIGURATION_get_value_number (cfg, "sensor-reporting", | ||
1378 | "POW_MATCHING_BITS", | ||
1379 | &pow_matching_bits)) | ||
1380 | { | ||
1381 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "sensor-reporting", | ||
1382 | "POW_MATCHING_BITS"); | ||
1383 | SENSOR_reporting_stop (); | ||
1384 | return GNUNET_SYSERR; | ||
1385 | } | ||
1386 | if (pow_matching_bits > sizeof (struct GNUNET_HashCode)) | ||
1387 | { | ||
1388 | LOG (GNUNET_ERROR_TYPE_ERROR, "Matching bits value too large (%d > %d).\n", | ||
1389 | pow_matching_bits, sizeof (struct GNUNET_HashCode)); | ||
1390 | SENSOR_reporting_stop (); | ||
1391 | return GNUNET_SYSERR; | ||
1392 | } | ||
1393 | /* Connect to PEERSTORE */ | ||
1394 | peerstore = GNUNET_PEERSTORE_connect (cfg); | ||
1395 | if (NULL == peerstore) | ||
1396 | { | ||
1397 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1398 | _("Failed to connect to peerstore service.\n")); | ||
1399 | SENSOR_reporting_stop (); | ||
1400 | return GNUNET_SYSERR; | ||
1401 | } | ||
1402 | /* Connect to CORE */ | ||
1403 | core = | ||
1404 | GNUNET_CORE_connect (cfg, NULL, &core_startup_cb, core_connect_cb, | ||
1405 | &core_disconnect_cb, NULL, GNUNET_YES, NULL, | ||
1406 | GNUNET_YES, core_handlers); | ||
1407 | if (NULL == core) | ||
1408 | { | ||
1409 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to CORE service.\n")); | ||
1410 | SENSOR_reporting_stop (); | ||
1411 | return GNUNET_SYSERR; | ||
1412 | } | ||
1413 | /* Connect to CADET */ | ||
1414 | cadet = | ||
1415 | GNUNET_CADET_connect (cfg, NULL, NULL, &cadet_channel_destroyed, | ||
1416 | cadet_handlers, NULL); | ||
1417 | if (NULL == cadet) | ||
1418 | { | ||
1419 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to CADET service.\n")); | ||
1420 | SENSOR_reporting_stop (); | ||
1421 | return GNUNET_SYSERR; | ||
1422 | } | ||
1423 | private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg); | ||
1424 | if (NULL == private_key) | ||
1425 | { | ||
1426 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to load my private key.\n")); | ||
1427 | SENSOR_reporting_stop (); | ||
1428 | return GNUNET_SYSERR; | ||
1429 | } | ||
1430 | GNUNET_CRYPTO_get_peer_identity (cfg, &mypeerid); | ||
1431 | GNUNET_CONTAINER_multihashmap_iterate (sensors, &init_sensor_reporting, NULL); | ||
1432 | neighborhood = 0; | ||
1433 | module_running = GNUNET_YES; | ||
1434 | return GNUNET_OK; | ||
1435 | } | ||
1436 | |||
1437 | /* end of gnunet-service-sensor_reporting.c */ | ||
diff --git a/src/sensor/gnunet-service-sensor_update.c b/src/sensor/gnunet-service-sensor_update.c deleted file mode 100644 index b2c8b21d4..000000000 --- a/src/sensor/gnunet-service-sensor_update.c +++ /dev/null | |||
@@ -1,801 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensor/gnunet-service-sensor_update.c | ||
23 | * @brief sensor service update functionality | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "sensor.h" | ||
29 | #include "gnunet_cadet_service.h" | ||
30 | #include "gnunet_sensor_model_plugin.h" | ||
31 | #include "gnunet_applications.h" | ||
32 | |||
33 | #define LOG(kind,...) GNUNET_log_from (kind, "sensor-update",__VA_ARGS__) | ||
34 | |||
35 | /** | ||
36 | * Interval at which to contact update points for new sensor updates. | ||
37 | */ | ||
38 | #define SENSOR_UPDATE_CHECK_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, 1) | ||
39 | |||
40 | /** | ||
41 | * Interval at which to retry contacting update point if we were busy. | ||
42 | */ | ||
43 | #define SENSOR_UPDATE_CHECK_RETRY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 1) | ||
44 | |||
45 | |||
46 | /** | ||
47 | * Message queued to be sent to an update point stored in a DLL | ||
48 | */ | ||
49 | struct PendingMessage | ||
50 | { | ||
51 | |||
52 | /** | ||
53 | * DLL | ||
54 | */ | ||
55 | struct PendingMessage *prev; | ||
56 | |||
57 | /** | ||
58 | * DLL | ||
59 | */ | ||
60 | struct PendingMessage *next; | ||
61 | |||
62 | /** | ||
63 | * Actual queued message | ||
64 | */ | ||
65 | struct GNUNET_MessageHeader *msg; | ||
66 | |||
67 | }; | ||
68 | |||
69 | /** | ||
70 | * Sensors update point | ||
71 | */ | ||
72 | struct UpdatePoint | ||
73 | { | ||
74 | |||
75 | /** | ||
76 | * DLL | ||
77 | */ | ||
78 | struct UpdatePoint *prev; | ||
79 | |||
80 | /** | ||
81 | * DLL | ||
82 | */ | ||
83 | struct UpdatePoint *next; | ||
84 | |||
85 | /** | ||
86 | * Identity of peer running update point | ||
87 | */ | ||
88 | struct GNUNET_PeerIdentity peer_id; | ||
89 | |||
90 | /** | ||
91 | * CADET channel to update point | ||
92 | */ | ||
93 | struct GNUNET_CADET_Channel *ch; | ||
94 | |||
95 | /** | ||
96 | * CADET transmit handle for a message to be sent to update point. | ||
97 | */ | ||
98 | struct GNUNET_CADET_TransmitHandle *th; | ||
99 | |||
100 | /** | ||
101 | * Head of DLL of pending requests to be sent to update point. | ||
102 | */ | ||
103 | struct PendingMessage *pm_head; | ||
104 | |||
105 | /** | ||
106 | * Tail of DLL of pending requests to be sent to update point. | ||
107 | */ | ||
108 | struct PendingMessage *pm_tail; | ||
109 | |||
110 | /** | ||
111 | * Are we waiting for a sensor list? | ||
112 | */ | ||
113 | int expecting_sensor_list; | ||
114 | |||
115 | /** | ||
116 | * How many sensor updates did we request and are waiting for. | ||
117 | */ | ||
118 | int expected_sensor_updates; | ||
119 | |||
120 | /** | ||
121 | * Did a failure occur while dealing with this update point before? | ||
122 | */ | ||
123 | int failed; | ||
124 | |||
125 | }; | ||
126 | |||
127 | |||
128 | /** | ||
129 | * Our configuration. | ||
130 | */ | ||
131 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
132 | |||
133 | /** | ||
134 | * Path to sensor definition directory | ||
135 | */ | ||
136 | static char *sensor_dir; | ||
137 | |||
138 | /** | ||
139 | * Hashmap of known sensors | ||
140 | */ | ||
141 | static struct GNUNET_CONTAINER_MultiHashMap *sensors; | ||
142 | |||
143 | /** | ||
144 | * Head of update points DLL. | ||
145 | */ | ||
146 | static struct UpdatePoint *up_head; | ||
147 | |||
148 | /** | ||
149 | * Tail of update points DLL. | ||
150 | */ | ||
151 | static struct UpdatePoint *up_tail; | ||
152 | |||
153 | /** | ||
154 | * The current default update point to use. | ||
155 | */ | ||
156 | static struct UpdatePoint *up_default; | ||
157 | |||
158 | /** | ||
159 | * Handle to CADET service | ||
160 | */ | ||
161 | static struct GNUNET_CADET_Handle *cadet; | ||
162 | |||
163 | /** | ||
164 | * Are we in the process of checking and updating sensors? | ||
165 | */ | ||
166 | static int updating; | ||
167 | |||
168 | /** | ||
169 | * GNUnet scheduler task that starts the update check process. | ||
170 | */ | ||
171 | static struct GNUNET_SCHEDULER_Task * update_task; | ||
172 | |||
173 | /** | ||
174 | * Pointer to service reset function called when we have new sensor updates. | ||
175 | */ | ||
176 | static void (*reset_cb) (); | ||
177 | |||
178 | |||
179 | /** | ||
180 | * Contact update points to check for new updates | ||
181 | * | ||
182 | * @param cls unused | ||
183 | * @param tc GNUnet scheduler task context | ||
184 | */ | ||
185 | static void | ||
186 | check_for_updates (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
187 | |||
188 | |||
189 | /** | ||
190 | * Trigger sending next pending message to the default update point if any. | ||
191 | * | ||
192 | */ | ||
193 | static void | ||
194 | trigger_send_next_msg (); | ||
195 | |||
196 | |||
197 | /** | ||
198 | * Cleanup update point context. This does not destroy the struct itself. | ||
199 | * | ||
200 | * @param up UpdatePoint struct | ||
201 | */ | ||
202 | static void | ||
203 | cleanup_updatepoint (struct UpdatePoint *up) | ||
204 | { | ||
205 | struct PendingMessage *pm; | ||
206 | |||
207 | up->expecting_sensor_list = GNUNET_NO; | ||
208 | up->expected_sensor_updates = 0; | ||
209 | if (NULL != up->th) | ||
210 | { | ||
211 | GNUNET_CADET_notify_transmit_ready_cancel (up->th); | ||
212 | up->th = NULL; | ||
213 | } | ||
214 | pm = up->pm_head; | ||
215 | while (NULL != pm) | ||
216 | { | ||
217 | GNUNET_CONTAINER_DLL_remove (up->pm_head, up->pm_tail, pm); | ||
218 | GNUNET_free (pm->msg); | ||
219 | GNUNET_free (pm); | ||
220 | pm = up->pm_head; | ||
221 | } | ||
222 | if (NULL != up->ch) | ||
223 | { | ||
224 | GNUNET_CADET_channel_destroy (up->ch); | ||
225 | up->ch = NULL; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | |||
230 | /** | ||
231 | * Stop the sensor update module. | ||
232 | */ | ||
233 | void | ||
234 | SENSOR_update_stop () | ||
235 | { | ||
236 | struct UpdatePoint *up; | ||
237 | |||
238 | up_default = NULL; | ||
239 | up = up_head; | ||
240 | if (NULL != update_task) | ||
241 | { | ||
242 | GNUNET_SCHEDULER_cancel (update_task); | ||
243 | update_task = NULL; | ||
244 | } | ||
245 | while (NULL != up) | ||
246 | { | ||
247 | GNUNET_CONTAINER_DLL_remove (up_head, up_tail, up); | ||
248 | cleanup_updatepoint (up); | ||
249 | GNUNET_free (up); | ||
250 | up = up_head; | ||
251 | } | ||
252 | if (NULL != cadet) | ||
253 | { | ||
254 | GNUNET_CADET_disconnect (cadet); | ||
255 | cadet = NULL; | ||
256 | } | ||
257 | if (NULL != sensor_dir) | ||
258 | { | ||
259 | GNUNET_free (sensor_dir); | ||
260 | sensor_dir = NULL; | ||
261 | } | ||
262 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Sensor update module stopped.\n"); | ||
263 | } | ||
264 | |||
265 | |||
266 | /** | ||
267 | * A failure occured in connecting/retrieval/verification with current default | ||
268 | * update point. This method will try to find another update point, do cleanup | ||
269 | * and reschedule update check. | ||
270 | */ | ||
271 | static void | ||
272 | fail () | ||
273 | { | ||
274 | struct UpdatePoint *up; | ||
275 | |||
276 | cleanup_updatepoint (up_default); | ||
277 | if (up_default == up_tail) | ||
278 | { | ||
279 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
280 | "All defined update points failed. Will retry again in %s.\n", | ||
281 | GNUNET_STRINGS_relative_time_to_string (SENSOR_UPDATE_CHECK_INTERVAL, | ||
282 | GNUNET_NO)); | ||
283 | up = up_head; | ||
284 | while (NULL != up) | ||
285 | { | ||
286 | up->failed = GNUNET_NO; | ||
287 | up = up->next; | ||
288 | } | ||
289 | update_task = | ||
290 | GNUNET_SCHEDULER_add_delayed (SENSOR_UPDATE_CHECK_INTERVAL, | ||
291 | &check_for_updates, NULL); | ||
292 | return; | ||
293 | } | ||
294 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
295 | "Update point `%s' failed, trying next one now.\n", | ||
296 | GNUNET_i2s (&up_default->peer_id)); | ||
297 | up_default = up_default->next; | ||
298 | update_task = GNUNET_SCHEDULER_add_now (&check_for_updates, NULL); | ||
299 | } | ||
300 | |||
301 | |||
302 | /** | ||
303 | * Function called to notify a client about the connection begin ready | ||
304 | * to queue more data. @a buf will be NULL and @a size zero if the | ||
305 | * connection was closed for writing in the meantime. | ||
306 | * | ||
307 | * Perform the actual sending of the message to update point. | ||
308 | * | ||
309 | * @param cls closure (unused) | ||
310 | * @param size number of bytes available in @a buf | ||
311 | * @param buf where the callee should write the message | ||
312 | * @return number of bytes written to @a buf | ||
313 | */ | ||
314 | static size_t | ||
315 | do_send_msg (void *cls, size_t size, void *buf) | ||
316 | { | ||
317 | struct PendingMessage *pm; | ||
318 | size_t msg_size; | ||
319 | |||
320 | up_default->th = NULL; | ||
321 | pm = up_default->pm_head; | ||
322 | msg_size = ntohs (pm->msg->size); | ||
323 | GNUNET_CONTAINER_DLL_remove (up_default->pm_head, up_default->pm_tail, pm); | ||
324 | if (NULL == buf || size < msg_size) | ||
325 | { | ||
326 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
327 | _("Error trying to send a message to update point `%s'.\n"), | ||
328 | GNUNET_i2s (&up_default->peer_id)); | ||
329 | fail (); | ||
330 | return 0; | ||
331 | } | ||
332 | memcpy (buf, pm->msg, msg_size); | ||
333 | GNUNET_free (pm->msg); | ||
334 | GNUNET_free (pm); | ||
335 | trigger_send_next_msg (); | ||
336 | return msg_size; | ||
337 | } | ||
338 | |||
339 | |||
340 | /** | ||
341 | * Trigger sending next pending message to the default update point if any. | ||
342 | * | ||
343 | */ | ||
344 | static void | ||
345 | trigger_send_next_msg () | ||
346 | { | ||
347 | struct PendingMessage *pm; | ||
348 | |||
349 | if (NULL == up_default->pm_head) | ||
350 | return; | ||
351 | if (NULL != up_default->th) | ||
352 | return; | ||
353 | pm = up_default->pm_head; | ||
354 | up_default->th = | ||
355 | GNUNET_CADET_notify_transmit_ready (up_default->ch, GNUNET_YES, | ||
356 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
357 | ntohs (pm->msg->size), &do_send_msg, | ||
358 | NULL); | ||
359 | } | ||
360 | |||
361 | |||
362 | /** | ||
363 | * Add a message to the queue to be sent to the current default update point. | ||
364 | * | ||
365 | * @param msg Message to be queued | ||
366 | */ | ||
367 | static void | ||
368 | queue_msg (struct GNUNET_MessageHeader *msg) | ||
369 | { | ||
370 | struct PendingMessage *pm; | ||
371 | |||
372 | pm = GNUNET_new (struct PendingMessage); | ||
373 | |||
374 | pm->msg = msg; | ||
375 | GNUNET_CONTAINER_DLL_insert_tail (up_default->pm_head, up_default->pm_tail, | ||
376 | pm); | ||
377 | trigger_send_next_msg (); | ||
378 | } | ||
379 | |||
380 | |||
381 | /** | ||
382 | * Contact update points to check for new updates | ||
383 | * | ||
384 | * @param cls unused | ||
385 | * @param tc GNUnet scheduler task context | ||
386 | */ | ||
387 | static void | ||
388 | check_for_updates (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
389 | { | ||
390 | struct GNUNET_MessageHeader *msg; | ||
391 | size_t msg_size; | ||
392 | |||
393 | update_task = NULL; | ||
394 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
395 | return; | ||
396 | if (GNUNET_YES == updating) | ||
397 | { | ||
398 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
399 | "Update process still running and update interval already exhausted." | ||
400 | "Retrying in %s.\n", | ||
401 | GNUNET_STRINGS_relative_time_to_string (SENSOR_UPDATE_CHECK_RETRY, | ||
402 | GNUNET_NO)); | ||
403 | update_task = | ||
404 | GNUNET_SCHEDULER_add_delayed (SENSOR_UPDATE_CHECK_RETRY, | ||
405 | &check_for_updates, NULL); | ||
406 | return; | ||
407 | } | ||
408 | updating = GNUNET_YES; | ||
409 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Checking for sensor updates.\n"); | ||
410 | GNUNET_assert (NULL != up_default); | ||
411 | up_default->ch = | ||
412 | GNUNET_CADET_channel_create (cadet, up_default, &up_default->peer_id, | ||
413 | GNUNET_APPLICATION_TYPE_SENSORUPDATE, | ||
414 | GNUNET_CADET_OPTION_DEFAULT); | ||
415 | if (NULL == up_default->ch) | ||
416 | { | ||
417 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
418 | _("Failed to connect to update point `%s'.\n"), | ||
419 | GNUNET_i2s (&up_default->peer_id)); | ||
420 | fail (); | ||
421 | return; | ||
422 | } | ||
423 | /* Start by requesting list of sensors available from update point */ | ||
424 | up_default->expecting_sensor_list = GNUNET_YES; | ||
425 | msg = GNUNET_new (struct GNUNET_MessageHeader); | ||
426 | msg_size = sizeof (struct GNUNET_MessageHeader); | ||
427 | msg->size = htons (msg_size); | ||
428 | msg->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_LIST_REQ); | ||
429 | queue_msg (msg); | ||
430 | update_task = | ||
431 | GNUNET_SCHEDULER_add_delayed (SENSOR_UPDATE_CHECK_INTERVAL, | ||
432 | &check_for_updates, NULL); | ||
433 | } | ||
434 | |||
435 | |||
436 | /** | ||
437 | * Function that reads and validates (correctness not connectivity) of available | ||
438 | * sensor update points. | ||
439 | * | ||
440 | * @return number of update points loaded successfully | ||
441 | */ | ||
442 | static int | ||
443 | load_update_points () | ||
444 | { | ||
445 | char *points_list; | ||
446 | int points_list_len; | ||
447 | int i; | ||
448 | int start; | ||
449 | int len; | ||
450 | struct GNUNET_CRYPTO_EddsaPublicKey public_key; | ||
451 | struct UpdatePoint *up; | ||
452 | int count = 0; | ||
453 | |||
454 | if (GNUNET_OK != | ||
455 | GNUNET_CONFIGURATION_get_value_string (cfg, "sensor-update", | ||
456 | "UPDATE_POINTS", &points_list)) | ||
457 | { | ||
458 | return 0; | ||
459 | } | ||
460 | points_list_len = strlen (points_list) + 1; | ||
461 | for (i = 0; i < points_list_len; i++) | ||
462 | { | ||
463 | if (' ' == points_list[i]) | ||
464 | continue; | ||
465 | start = i; | ||
466 | len = 0; | ||
467 | while (' ' != points_list[i] && '\0' != points_list[i]) | ||
468 | { | ||
469 | len++; | ||
470 | i++; | ||
471 | } | ||
472 | if (GNUNET_OK != | ||
473 | GNUNET_CRYPTO_eddsa_public_key_from_string (points_list + start, len, | ||
474 | &public_key)) | ||
475 | { | ||
476 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
477 | "Invalid EDDSA public key `%.*s' for update point.\n", len, | ||
478 | points_list + len); | ||
479 | continue; | ||
480 | } | ||
481 | up = GNUNET_new (struct UpdatePoint); | ||
482 | |||
483 | up->peer_id.public_key = public_key; | ||
484 | up->ch = NULL; | ||
485 | up->th = NULL; | ||
486 | up->expecting_sensor_list = GNUNET_NO; | ||
487 | up->expected_sensor_updates = 0; | ||
488 | up->failed = GNUNET_NO; | ||
489 | GNUNET_CONTAINER_DLL_insert (up_head, up_tail, up); | ||
490 | count++; | ||
491 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Loaded update point `%s'.\n", | ||
492 | GNUNET_i2s_full (&up->peer_id)); | ||
493 | } | ||
494 | GNUNET_free (points_list); | ||
495 | return count; | ||
496 | } | ||
497 | |||
498 | |||
499 | /** | ||
500 | * Checks if the given sensor name and version (retrieved from an update point) | ||
501 | * is new for us and we would like to install it. This is the case if we don't | ||
502 | * have this sensor or we have an old version of it. | ||
503 | * | ||
504 | * @param sensorname Sensor name | ||
505 | * @param sensorversion_major First part of version number | ||
506 | * @param sensorversion_minor Second part of version number | ||
507 | * @return #GNUNET_YES if we don't have this sensor | ||
508 | * #GNUNET_NO if we have it | ||
509 | */ | ||
510 | static int | ||
511 | update_required (char *sensorname, uint16_t sensorversion_major, | ||
512 | uint16_t sensorversion_minor) | ||
513 | { | ||
514 | struct GNUNET_HashCode key; | ||
515 | struct GNUNET_SENSOR_SensorInfo *local_sensor; | ||
516 | |||
517 | GNUNET_CRYPTO_hash (sensorname, strlen (sensorname) + 1, &key); | ||
518 | local_sensor = GNUNET_CONTAINER_multihashmap_get (sensors, &key); | ||
519 | if (NULL == local_sensor) | ||
520 | return GNUNET_YES; | ||
521 | if (GNUNET_SENSOR_version_compare | ||
522 | (local_sensor->version_major, local_sensor->version_minor, | ||
523 | sensorversion_major, sensorversion_minor) < 0) | ||
524 | return GNUNET_YES; | ||
525 | return GNUNET_NO; | ||
526 | } | ||
527 | |||
528 | |||
529 | /** | ||
530 | * Handler of a sensor list message received from an update point. | ||
531 | * | ||
532 | * @param cls Closure (unused). | ||
533 | * @param channel Connection to the other end. | ||
534 | * @param channel_ctx Place to store local state associated with the channel. | ||
535 | * @param message The actual message. | ||
536 | * @return #GNUNET_OK to keep the channel open, | ||
537 | * #GNUNET_SYSERR to close it (signal serious error). | ||
538 | */ | ||
539 | static int | ||
540 | handle_sensor_brief (void *cls, struct GNUNET_CADET_Channel *channel, | ||
541 | void **channel_ctx, | ||
542 | const struct GNUNET_MessageHeader *message) | ||
543 | { | ||
544 | struct GNUNET_SENSOR_SensorBriefMessage *sbm; | ||
545 | struct GNUNET_MessageHeader *pull_req; | ||
546 | uint16_t version_major; | ||
547 | uint16_t version_minor; | ||
548 | uint16_t msg_size; | ||
549 | |||
550 | GNUNET_assert (*channel_ctx == up_default); | ||
551 | if (GNUNET_YES != up_default->expecting_sensor_list) | ||
552 | { | ||
553 | GNUNET_break_op (0); | ||
554 | fail (); | ||
555 | return GNUNET_OK; | ||
556 | } | ||
557 | if (GNUNET_MESSAGE_TYPE_SENSOR_END == ntohs (message->type)) | ||
558 | { | ||
559 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
560 | "Received end of sensor list msg. We already requested %d updates.\n", | ||
561 | up_default->expected_sensor_updates); | ||
562 | up_default->expecting_sensor_list = GNUNET_NO; | ||
563 | if (0 == up_default->expected_sensor_updates) | ||
564 | { | ||
565 | updating = GNUNET_NO; | ||
566 | cleanup_updatepoint (up_default); | ||
567 | return GNUNET_OK; | ||
568 | } | ||
569 | } | ||
570 | else | ||
571 | { | ||
572 | sbm = (struct GNUNET_SENSOR_SensorBriefMessage *) message; | ||
573 | version_major = ntohs (sbm->version_major); | ||
574 | version_minor = ntohs (sbm->version_minor); | ||
575 | if (GNUNET_YES == | ||
576 | update_required ((char *) &sbm[1], version_major, version_minor)) | ||
577 | { | ||
578 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
579 | "Requesting sensor %s %d.%d from update point.\n", &sbm[1], | ||
580 | version_major, version_minor); | ||
581 | /* We duplicate the same msg received but change the type and send it | ||
582 | * back to update point to ask for full sensor information. */ | ||
583 | msg_size = ntohs (message->size); | ||
584 | pull_req = GNUNET_malloc (msg_size); | ||
585 | memcpy (pull_req, message, msg_size); | ||
586 | pull_req->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_FULL_REQ); | ||
587 | queue_msg (pull_req); | ||
588 | up_default->expected_sensor_updates++; | ||
589 | } | ||
590 | } | ||
591 | GNUNET_CADET_receive_done (channel); | ||
592 | return GNUNET_OK; | ||
593 | } | ||
594 | |||
595 | |||
596 | /** | ||
597 | * Update local sensor definitions with a sensor retrieved from an update point. | ||
598 | * | ||
599 | * @param sensorname Sensor name | ||
600 | * @param sensorfile Buffer containing the sensor definition file | ||
601 | * @param sensorfile_size Size of @e sensorfile | ||
602 | * @param scriptname Name of associated script file, NULL if no script | ||
603 | * @param scriptfile Buffer containing the script file, NULL if no script | ||
604 | * @param scriptfile_size Size of @e scriptfile, 0 if no script | ||
605 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
606 | */ | ||
607 | static int | ||
608 | update_sensor (char *sensorname, void *sensorfile, uint16_t sensorfile_size, | ||
609 | char *scriptname, void *scriptfile, uint16_t scriptfile_size) | ||
610 | { | ||
611 | char *sensor_path; | ||
612 | char *script_path; | ||
613 | |||
614 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
615 | "Received new sensor information:\n" "Name: %s\n" | ||
616 | "Sensor file size: %d\n" "Script name: %s\n" "Script file size: %d.\n", | ||
617 | sensorname, sensorfile_size, (NULL == scriptname) ? "None" : scriptname, | ||
618 | scriptfile_size); | ||
619 | GNUNET_asprintf (&sensor_path, "%s%s", sensor_dir, sensorname); | ||
620 | GNUNET_DISK_fn_write (sensor_path, sensorfile, sensorfile_size, | ||
621 | GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_GROUP_READ | ||
622 | | GNUNET_DISK_PERM_OTHER_READ | | ||
623 | GNUNET_DISK_PERM_USER_WRITE); | ||
624 | if (NULL != scriptname) | ||
625 | { | ||
626 | GNUNET_asprintf (&script_path, "%s-files%s%s", sensor_path, | ||
627 | DIR_SEPARATOR_STR, scriptname); | ||
628 | GNUNET_DISK_fn_write (script_path, scriptfile, scriptfile_size, | ||
629 | GNUNET_DISK_PERM_USER_READ | | ||
630 | GNUNET_DISK_PERM_GROUP_READ | | ||
631 | GNUNET_DISK_PERM_OTHER_READ | | ||
632 | GNUNET_DISK_PERM_USER_WRITE | | ||
633 | GNUNET_DISK_PERM_GROUP_WRITE | | ||
634 | GNUNET_DISK_PERM_USER_EXEC | | ||
635 | GNUNET_DISK_PERM_GROUP_EXEC); | ||
636 | GNUNET_free (script_path); | ||
637 | } | ||
638 | GNUNET_free (sensor_path); | ||
639 | return GNUNET_OK; | ||
640 | } | ||
641 | |||
642 | |||
643 | /** | ||
644 | * Resets the service after we are done with an update. | ||
645 | * | ||
646 | * @param cls unused | ||
647 | * @param tc unused | ||
648 | */ | ||
649 | static void | ||
650 | reset (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
651 | { | ||
652 | reset_cb (); | ||
653 | } | ||
654 | |||
655 | |||
656 | /** | ||
657 | * Handler of a sensor list message received from an update point. | ||
658 | * | ||
659 | * @param cls Closure (unused). | ||
660 | * @param channel Connection to the other end. | ||
661 | * @param channel_ctx Place to store local state associated with the channel. | ||
662 | * @param message The actual message. | ||
663 | * @return #GNUNET_OK to keep the channel open, | ||
664 | * #GNUNET_SYSERR to close it (signal serious error). | ||
665 | */ | ||
666 | static int | ||
667 | handle_sensor_full (void *cls, struct GNUNET_CADET_Channel *channel, | ||
668 | void **channel_ctx, | ||
669 | const struct GNUNET_MessageHeader *message) | ||
670 | { | ||
671 | struct GNUNET_SENSOR_SensorFullMessage *sfm; | ||
672 | uint16_t msg_size; | ||
673 | uint16_t sensorfile_size; | ||
674 | uint16_t scriptfile_size; | ||
675 | char *sensorname_ptr; | ||
676 | void *sensorfile_ptr; | ||
677 | char *scriptname_ptr; | ||
678 | void *scriptfile_ptr; | ||
679 | |||
680 | /* error check */ | ||
681 | GNUNET_assert (*channel_ctx == up_default); | ||
682 | msg_size = ntohs (message->size); | ||
683 | if (up_default->expected_sensor_updates <= 0 || | ||
684 | msg_size < sizeof (struct GNUNET_SENSOR_SensorFullMessage)) | ||
685 | { | ||
686 | GNUNET_break_op (0); | ||
687 | fail (); | ||
688 | return GNUNET_OK; | ||
689 | } | ||
690 | /* parse received msg */ | ||
691 | sfm = (struct GNUNET_SENSOR_SensorFullMessage *) message; | ||
692 | sensorname_ptr = (char *) &sfm[1]; | ||
693 | sensorfile_ptr = sensorname_ptr + ntohs (sfm->sensorname_size); | ||
694 | sensorfile_size = ntohs (sfm->sensorfile_size); | ||
695 | scriptfile_size = ntohs (sfm->scriptfile_size); | ||
696 | if (scriptfile_size > 0) | ||
697 | { | ||
698 | scriptname_ptr = sensorfile_ptr + sensorfile_size; | ||
699 | scriptfile_ptr = scriptname_ptr + ntohs (sfm->scriptname_size); | ||
700 | } | ||
701 | else | ||
702 | { | ||
703 | scriptname_ptr = NULL; | ||
704 | scriptfile_ptr = NULL; | ||
705 | } | ||
706 | update_sensor ((char *) &sfm[1], sensorfile_ptr, sensorfile_size, | ||
707 | scriptname_ptr, scriptfile_ptr, scriptfile_size); | ||
708 | up_default->expected_sensor_updates--; | ||
709 | if (0 == up_default->expected_sensor_updates) | ||
710 | { | ||
711 | updating = GNUNET_NO; | ||
712 | cleanup_updatepoint (up_default); | ||
713 | GNUNET_SCHEDULER_add_now (&reset, NULL); | ||
714 | } | ||
715 | else | ||
716 | GNUNET_CADET_receive_done (channel); | ||
717 | return GNUNET_OK; | ||
718 | } | ||
719 | |||
720 | |||
721 | /** | ||
722 | * Function called whenever a channel is destroyed. Should clean up | ||
723 | * any associated state. | ||
724 | * | ||
725 | * It must NOT call #GNUNET_CADET_channel_destroy on the channel. | ||
726 | * | ||
727 | * @param cls closure (set from #GNUNET_CADET_connect) | ||
728 | * @param channel connection to the other end (henceforth invalid) | ||
729 | * @param channel_ctx place where local state associated | ||
730 | * with the channel is stored | ||
731 | */ | ||
732 | static void | ||
733 | cadet_channel_destroyed (void *cls, const struct GNUNET_CADET_Channel *channel, | ||
734 | void *channel_ctx) | ||
735 | { | ||
736 | struct UpdatePoint *up = channel_ctx; | ||
737 | |||
738 | up->ch = NULL; | ||
739 | if (GNUNET_YES == updating) | ||
740 | { | ||
741 | fail (); | ||
742 | return; | ||
743 | } | ||
744 | cleanup_updatepoint (up); | ||
745 | } | ||
746 | |||
747 | |||
748 | /** | ||
749 | * Start the sensor update module | ||
750 | * | ||
751 | * @param c our service configuration | ||
752 | * @param s multihashmap of loaded sensors | ||
753 | * @param cb callback to reset service components when we have new updates | ||
754 | * @return #GNUNET_OK if started successfully, #GNUNET_SYSERR otherwise | ||
755 | */ | ||
756 | int | ||
757 | SENSOR_update_start (const struct GNUNET_CONFIGURATION_Handle *c, | ||
758 | struct GNUNET_CONTAINER_MultiHashMap *s, void (*cb) ()) | ||
759 | { | ||
760 | static struct GNUNET_CADET_MessageHandler cadet_handlers[] = { | ||
761 | {&handle_sensor_brief, GNUNET_MESSAGE_TYPE_SENSOR_BRIEF, 0}, | ||
762 | {&handle_sensor_brief, GNUNET_MESSAGE_TYPE_SENSOR_END, 0}, | ||
763 | {&handle_sensor_full, GNUNET_MESSAGE_TYPE_SENSOR_FULL, 0}, | ||
764 | {NULL, 0, 0} | ||
765 | }; | ||
766 | int up_count; | ||
767 | |||
768 | GNUNET_assert (NULL != s); | ||
769 | cfg = c; | ||
770 | sensors = s; | ||
771 | reset_cb = cb; | ||
772 | if (GNUNET_OK != | ||
773 | GNUNET_CONFIGURATION_get_value_filename (cfg, "SENSOR", "SENSOR_DIR", | ||
774 | &sensor_dir)) | ||
775 | sensor_dir = GNUNET_SENSOR_get_default_sensor_dir (); | ||
776 | cadet = | ||
777 | GNUNET_CADET_connect (cfg, NULL, NULL, &cadet_channel_destroyed, | ||
778 | cadet_handlers, NULL); | ||
779 | if (NULL == cadet) | ||
780 | { | ||
781 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to CADET service.\n")); | ||
782 | SENSOR_update_stop (); | ||
783 | return GNUNET_SYSERR; | ||
784 | } | ||
785 | up_count = load_update_points (); | ||
786 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Loaded %d update points.\n", up_count); | ||
787 | if (0 == up_count) | ||
788 | { | ||
789 | SENSOR_update_stop (); | ||
790 | return GNUNET_SYSERR; | ||
791 | } | ||
792 | up_default = up_head; | ||
793 | updating = GNUNET_NO; | ||
794 | update_task = | ||
795 | GNUNET_SCHEDULER_add_delayed (SENSOR_UPDATE_CHECK_INTERVAL, | ||
796 | &check_for_updates, NULL); | ||
797 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Sensor update module started.\n"); | ||
798 | return GNUNET_OK; | ||
799 | } | ||
800 | |||
801 | /* end of gnunet-service-sensor_update.c */ | ||
diff --git a/src/sensor/gnunet_sensor_model_plugin.h b/src/sensor/gnunet_sensor_model_plugin.h deleted file mode 100644 index 6c8e7fc7c..000000000 --- a/src/sensor/gnunet_sensor_model_plugin.h +++ /dev/null | |||
@@ -1,86 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2012, 2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensor/gnunet_sensor_model_plugin.h | ||
23 | * @brief plugin API for sensor analysis models | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | #ifndef GNUNET_SENSOR_MODEL_PLUGIN_H | ||
27 | #define GNUNET_SENSOR_MODEL_PLUGIN_H | ||
28 | |||
29 | #include "gnunet_util_lib.h" | ||
30 | |||
31 | #ifdef __cplusplus | ||
32 | extern "C" | ||
33 | { | ||
34 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
35 | } | ||
36 | #endif | ||
37 | #endif | ||
38 | |||
39 | |||
40 | /** | ||
41 | * API for a sensor analysis model | ||
42 | */ | ||
43 | struct GNUNET_SENSOR_ModelFunctions | ||
44 | { | ||
45 | |||
46 | /** | ||
47 | * Closure to pass to all plugin functions. | ||
48 | */ | ||
49 | void *cls; | ||
50 | |||
51 | /* | ||
52 | * Create a model instance | ||
53 | * | ||
54 | * @param cls closure (plugin state) | ||
55 | * @return model state to be used for later calls | ||
56 | */ | ||
57 | void *(*create_model) (void *cls); | ||
58 | |||
59 | /* | ||
60 | * Destroy a model instance | ||
61 | * | ||
62 | * @param cls closure (model state) | ||
63 | */ | ||
64 | void (*destroy_model) (void *cls); | ||
65 | |||
66 | /* | ||
67 | * Feed a new value to a model | ||
68 | * | ||
69 | * @param cls closure (model state) | ||
70 | * @param val value to be fed to the model | ||
71 | * @return #GNUNET_YES in case of a detected outlier, #GNUNET_NO otherwise | ||
72 | */ | ||
73 | int (*feed_model) (void *cls, double val); | ||
74 | |||
75 | }; | ||
76 | |||
77 | |||
78 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
79 | { | ||
80 | #endif | ||
81 | #ifdef __cplusplus | ||
82 | } | ||
83 | #endif | ||
84 | |||
85 | /* end of gnunet_sensor_model_plugin.h */ | ||
86 | #endif | ||
diff --git a/src/sensor/perf_pow_sign.c b/src/sensor/perf_pow_sign.c deleted file mode 100644 index aba8349ec..000000000 --- a/src/sensor/perf_pow_sign.c +++ /dev/null | |||
@@ -1,261 +0,0 @@ | |||
1 | /* | ||
2 | * This file is part of GNUnet. | ||
3 | * Copyright (C) | ||
4 | * | ||
5 | * GNUnet is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published | ||
7 | * by the Free Software Foundation; either version 3, or (at your | ||
8 | * 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 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with GNUnet; see the file COPYING. If not, write to the | ||
17 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | * Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file sensor/perf_pow_sign.c | ||
22 | * @brief Print the average time required to generate pow for each matching bits | ||
23 | */ | ||
24 | #include <inttypes.h> | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include "gnunet_sensor_util_lib.h" | ||
28 | #include "gnunet_testbed_service.h" | ||
29 | #include "gnunet_signatures.h" | ||
30 | |||
31 | /** | ||
32 | * Number of peers to start for the test | ||
33 | */ | ||
34 | #define NUM_PEERS 1 | ||
35 | |||
36 | /** | ||
37 | * Size of the message exchanged | ||
38 | */ | ||
39 | #define MSG_SIZE 1024 | ||
40 | |||
41 | /** | ||
42 | * How many matching bits to start with | ||
43 | */ | ||
44 | #define MATCHING_BITS_START 1 | ||
45 | |||
46 | /** | ||
47 | * How many matching bits to end with | ||
48 | */ | ||
49 | #define MATCHING_BITS_END 20 | ||
50 | |||
51 | /** | ||
52 | * How many readings per matching bits value | ||
53 | */ | ||
54 | #define ITERATIONS 10 | ||
55 | |||
56 | /** | ||
57 | * Test name | ||
58 | */ | ||
59 | static const char *testname = "test_pow_sign"; | ||
60 | |||
61 | /** | ||
62 | * Name of GNUNET config file used in this test | ||
63 | */ | ||
64 | static const char *cfg_filename = "test_pow_sign.conf"; | ||
65 | |||
66 | /** | ||
67 | * Status of the test to be returned by main() | ||
68 | */ | ||
69 | static int ok = 1; | ||
70 | |||
71 | /** | ||
72 | * Task used to shutdown / expire the test | ||
73 | */ | ||
74 | static struct GNUNET_SCHEDULER_Task * shutdown_task; | ||
75 | |||
76 | /** | ||
77 | * Message to be exchanged | ||
78 | */ | ||
79 | static char msg[MSG_SIZE]; | ||
80 | |||
81 | /** | ||
82 | * Private key of sending peer | ||
83 | */ | ||
84 | static struct GNUNET_CRYPTO_EddsaPrivateKey *private_key; | ||
85 | |||
86 | /** | ||
87 | * Public key of sending peer | ||
88 | */ | ||
89 | static struct GNUNET_CRYPTO_EddsaPublicKey *public_key; | ||
90 | |||
91 | /** | ||
92 | * The current matching bits being evaluated | ||
93 | */ | ||
94 | static int current_matching_bits; | ||
95 | |||
96 | /** | ||
97 | * How many iterations performed for this matching bits value | ||
98 | */ | ||
99 | static int performed_iterations; | ||
100 | |||
101 | /** | ||
102 | * Total duration of all iterations | ||
103 | */ | ||
104 | static struct GNUNET_TIME_Relative total_duration; | ||
105 | |||
106 | /** | ||
107 | * Task creating pow block | ||
108 | */ | ||
109 | static struct GNUNET_SENSOR_crypto_pow_context *pow_task; | ||
110 | |||
111 | |||
112 | /** | ||
113 | * Start a new pow calculation | ||
114 | */ | ||
115 | static void | ||
116 | pow_start (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
117 | |||
118 | |||
119 | /** | ||
120 | * Shutdown task | ||
121 | * | ||
122 | * @param cls Closure (unused) | ||
123 | * @param tc Task context (unused) | ||
124 | */ | ||
125 | static void | ||
126 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
127 | { | ||
128 | if (NULL != pow_task) | ||
129 | { | ||
130 | GNUNET_SENSOR_crypto_pow_sign_cancel (pow_task); | ||
131 | pow_task = NULL; | ||
132 | } | ||
133 | if (NULL != private_key) | ||
134 | { | ||
135 | GNUNET_free (private_key); | ||
136 | private_key = NULL; | ||
137 | } | ||
138 | if (NULL != public_key) | ||
139 | { | ||
140 | GNUNET_free (public_key); | ||
141 | public_key = NULL; | ||
142 | } | ||
143 | GNUNET_SCHEDULER_shutdown (); | ||
144 | } | ||
145 | |||
146 | |||
147 | static void | ||
148 | pow_cb (void *cls, struct GNUNET_SENSOR_crypto_pow_block *block) | ||
149 | { | ||
150 | struct GNUNET_TIME_Absolute end_time; | ||
151 | struct GNUNET_TIME_Relative duration; | ||
152 | |||
153 | pow_task = NULL; | ||
154 | end_time = GNUNET_TIME_absolute_get(); | ||
155 | duration = GNUNET_TIME_absolute_get_difference (block->timestamp, end_time); | ||
156 | printf("."); | ||
157 | performed_iterations++; | ||
158 | total_duration = GNUNET_TIME_relative_add (total_duration, duration); | ||
159 | if (ITERATIONS == performed_iterations) | ||
160 | { | ||
161 | total_duration = GNUNET_TIME_relative_divide (total_duration, ITERATIONS); | ||
162 | printf ("Matching bits %d: %s\n", current_matching_bits, | ||
163 | GNUNET_STRINGS_relative_time_to_string(total_duration, GNUNET_NO)); | ||
164 | total_duration = GNUNET_TIME_UNIT_ZERO; | ||
165 | performed_iterations = 0; | ||
166 | if (MATCHING_BITS_END == current_matching_bits) | ||
167 | { | ||
168 | ok = 0; | ||
169 | GNUNET_SCHEDULER_cancel (shutdown_task); | ||
170 | GNUNET_SCHEDULER_add_now (do_shutdown, NULL); | ||
171 | return; | ||
172 | } | ||
173 | current_matching_bits ++; | ||
174 | } | ||
175 | GNUNET_SCHEDULER_add_now (&pow_start, NULL); | ||
176 | } | ||
177 | |||
178 | |||
179 | /** | ||
180 | * Start a new pow calculation | ||
181 | */ | ||
182 | static void | ||
183 | pow_start (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
184 | { | ||
185 | struct GNUNET_TIME_Absolute timestamp; | ||
186 | |||
187 | timestamp = GNUNET_TIME_absolute_get (); | ||
188 | pow_task = GNUNET_SENSOR_crypto_pow_sign (msg, MSG_SIZE, ×tamp, public_key, | ||
189 | private_key, current_matching_bits, &pow_cb, NULL); | ||
190 | } | ||
191 | |||
192 | |||
193 | /** | ||
194 | * Callback to be called when the requested peer information is available | ||
195 | * | ||
196 | * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information() | ||
197 | * @param op the operation this callback corresponds to | ||
198 | * @param pinfo the result; will be NULL if the operation has failed | ||
199 | * @param emsg error message if the operation has failed; will be NULL if the | ||
200 | * operation is successfull | ||
201 | */ | ||
202 | static void | ||
203 | peer_info_cb (void *cb_cls, struct GNUNET_TESTBED_Operation *op, | ||
204 | const struct GNUNET_TESTBED_PeerInformation *pinfo, | ||
205 | const char *emsg) | ||
206 | { | ||
207 | /* generate random data block */ | ||
208 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, msg, MSG_SIZE); | ||
209 | /* get private and public keys */ | ||
210 | private_key = | ||
211 | GNUNET_CRYPTO_eddsa_key_create_from_configuration (pinfo->result.cfg); | ||
212 | GNUNET_assert (NULL != private_key); | ||
213 | public_key = GNUNET_new (struct GNUNET_CRYPTO_EddsaPublicKey); | ||
214 | GNUNET_CRYPTO_eddsa_key_get_public (private_key, public_key); | ||
215 | current_matching_bits = MATCHING_BITS_START; | ||
216 | performed_iterations = 0; | ||
217 | total_duration = GNUNET_TIME_UNIT_ZERO; | ||
218 | GNUNET_TESTBED_operation_done (op); | ||
219 | GNUNET_SCHEDULER_add_now (&pow_start, NULL); | ||
220 | } | ||
221 | |||
222 | |||
223 | /** | ||
224 | * Signature of a main function for a testcase. | ||
225 | * | ||
226 | * @param cls closure | ||
227 | * @param h the run handle | ||
228 | * @param num_peers number of peers in 'peers' | ||
229 | * @param peers handle to peers run in the testbed. NULL upon timeout (see | ||
230 | * GNUNET_TESTBED_test_run()). | ||
231 | * @param links_succeeded the number of overlay link connection attempts that | ||
232 | * succeeded | ||
233 | * @param links_failed the number of overlay link connection attempts that | ||
234 | * failed | ||
235 | * @see GNUNET_TESTBED_test_run() | ||
236 | */ | ||
237 | static void | ||
238 | test_master (void *cls, struct GNUNET_TESTBED_RunHandle *h, | ||
239 | unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers, | ||
240 | unsigned int links_succeeded, unsigned int links_failed) | ||
241 | { | ||
242 | GNUNET_assert (NUM_PEERS == num_peers); | ||
243 | GNUNET_assert (0 == links_failed); | ||
244 | shutdown_task = | ||
245 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_shutdown, NULL); | ||
246 | GNUNET_TESTBED_peer_get_information (peers[0], | ||
247 | GNUNET_TESTBED_PIT_CONFIGURATION, | ||
248 | &peer_info_cb, peers[0]); | ||
249 | } | ||
250 | |||
251 | |||
252 | int | ||
253 | main (int argc, char *argv[]) | ||
254 | { | ||
255 | GNUNET_log_setup (testname, "INFO", NULL); | ||
256 | if (GNUNET_OK == | ||
257 | GNUNET_TESTBED_test_run (testname, cfg_filename, NUM_PEERS, 0, NULL, NULL, | ||
258 | &test_master, NULL)) | ||
259 | return ok; | ||
260 | return 1; | ||
261 | } | ||
diff --git a/src/sensor/plugin_sensor_model_gaussian.c b/src/sensor/plugin_sensor_model_gaussian.c deleted file mode 100644 index b9128946e..000000000 --- a/src/sensor/plugin_sensor_model_gaussian.c +++ /dev/null | |||
@@ -1,263 +0,0 @@ | |||
1 | /* | ||
2 | * This file is part of GNUnet | ||
3 | * Copyright (C) 2013 GNUnet e.V. | ||
4 | * | ||
5 | * GNUnet is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published | ||
7 | * by the Free Software Foundation; either version 3, or (at your | ||
8 | * 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 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with GNUnet; see the file COPYING. If not, write to the | ||
17 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | * Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensor/plugin_sensor_model_gaussian.c | ||
23 | * @brief Gaussian model for sensor analysis | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_sensor_model_plugin.h" | ||
29 | #include "gnunet_sensor_service.h" | ||
30 | #include "sensor.h" | ||
31 | |||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "sensor-model-gaussian", __VA_ARGS__) | ||
33 | |||
34 | /** | ||
35 | * Plugin state information | ||
36 | */ | ||
37 | struct Plugin | ||
38 | { | ||
39 | |||
40 | /** | ||
41 | * Configuration handle | ||
42 | */ | ||
43 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
44 | |||
45 | /** | ||
46 | * Number of initial readings to be used for training only | ||
47 | */ | ||
48 | int training_window; | ||
49 | |||
50 | /** | ||
51 | * Number of standard deviations considered within "normal" | ||
52 | */ | ||
53 | int confidence_interval; | ||
54 | |||
55 | /** | ||
56 | * Increase in weight with each reading | ||
57 | */ | ||
58 | float weight_inc; | ||
59 | |||
60 | }; | ||
61 | |||
62 | /** | ||
63 | * State of single model instance | ||
64 | */ | ||
65 | struct Model | ||
66 | { | ||
67 | |||
68 | /** | ||
69 | * Pointer to the plugin state | ||
70 | */ | ||
71 | struct Plugin *plugin; | ||
72 | |||
73 | /** | ||
74 | * Gaussian sums | ||
75 | */ | ||
76 | long double s[3]; | ||
77 | |||
78 | /** | ||
79 | * Number of readings so far | ||
80 | */ | ||
81 | int n; | ||
82 | |||
83 | /** | ||
84 | * Weight to be used for the next reading | ||
85 | */ | ||
86 | double w; | ||
87 | |||
88 | }; | ||
89 | |||
90 | /** | ||
91 | * Update local sums of model with a new value. | ||
92 | * | ||
93 | * @param model Targe model | ||
94 | * @param val New value | ||
95 | */ | ||
96 | static void | ||
97 | update_sums (struct Model *model, double val) | ||
98 | { | ||
99 | int i; | ||
100 | |||
101 | for (i = 0; i < 3; i++) | ||
102 | model->s[i] += model->w * pow (val, (double) i); | ||
103 | model->w += model->plugin->weight_inc; | ||
104 | model->n++; | ||
105 | } | ||
106 | |||
107 | |||
108 | /** | ||
109 | * Feed a new value to a model | ||
110 | * | ||
111 | * @param cls closure (model state) | ||
112 | * @param val value to be fed to the model | ||
113 | * @return #GNUNET_YES in case of a detected outlier, #GNUNET_NO otherwise | ||
114 | */ | ||
115 | static int | ||
116 | sensor_gaussian_model_feed (void *cls, double val) | ||
117 | { | ||
118 | struct Model *model = cls; | ||
119 | struct Plugin *plugin = model->plugin; | ||
120 | long double mean; | ||
121 | long double stddev; | ||
122 | long double allowed_variance; | ||
123 | |||
124 | if (model->n < plugin->training_window) | ||
125 | { | ||
126 | update_sums (model, val); | ||
127 | return GNUNET_NO; | ||
128 | } | ||
129 | if (model->n == plugin->training_window) | ||
130 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Gaussian model out of training period.\n"); | ||
131 | mean = model->s[1] / model->s[0]; | ||
132 | stddev = | ||
133 | (model->s[0] * model->s[2] - | ||
134 | model->s[1] * model->s[1]) / (model->s[0] * (model->s[0] - 1)); | ||
135 | if (stddev < 0) /* Value can be slightly less than 0 due to rounding errors */ | ||
136 | stddev = 0; | ||
137 | stddev = sqrt (stddev); | ||
138 | allowed_variance = (plugin->confidence_interval * stddev); | ||
139 | if ((val < (mean - allowed_variance)) || (val > (mean + allowed_variance))) | ||
140 | return GNUNET_YES; | ||
141 | update_sums (model, val); | ||
142 | return GNUNET_NO; | ||
143 | } | ||
144 | |||
145 | |||
146 | /** | ||
147 | * Destroy a model instance | ||
148 | * | ||
149 | * @param cls closure (model state) | ||
150 | */ | ||
151 | static void | ||
152 | sensor_gaussian_model_destroy_model (void *cls) | ||
153 | { | ||
154 | struct Model *model = cls; | ||
155 | |||
156 | GNUNET_free (model); | ||
157 | } | ||
158 | |||
159 | |||
160 | /** | ||
161 | * Create a model instance | ||
162 | * | ||
163 | * @param cls closure (plugin state) | ||
164 | * @return model state to be used for later calls | ||
165 | */ | ||
166 | static void * | ||
167 | sensor_gaussian_model_create_model (void *cls) | ||
168 | { | ||
169 | struct Plugin *plugin = cls; | ||
170 | struct Model *model; | ||
171 | |||
172 | model = GNUNET_new (struct Model); | ||
173 | |||
174 | model->plugin = plugin; | ||
175 | model->w = 1; | ||
176 | return model; | ||
177 | } | ||
178 | |||
179 | |||
180 | /** | ||
181 | * Entry point for the plugin. | ||
182 | * | ||
183 | * @param cls The struct GNUNET_CONFIGURATION_Handle. | ||
184 | * @return NULL on error, otherwise the plugin context | ||
185 | */ | ||
186 | void * | ||
187 | libgnunet_plugin_sensor_model_gaussian_init (void *cls) | ||
188 | { | ||
189 | static struct Plugin plugin; | ||
190 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | ||
191 | struct GNUNET_SENSOR_ModelFunctions *api; | ||
192 | unsigned long long num; | ||
193 | |||
194 | if (NULL != plugin.cfg) | ||
195 | return NULL; /* can only initialize once! */ | ||
196 | memset (&plugin, 0, sizeof (struct Plugin)); | ||
197 | plugin.cfg = cfg; | ||
198 | if (GNUNET_OK != | ||
199 | GNUNET_CONFIGURATION_get_value_number (cfg, "sensor-model-gaussian", | ||
200 | "TRAINING_WINDOW", &num)) | ||
201 | { | ||
202 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
203 | _("Missing `TRAINING_WINDOW' value in configuration.\n")); | ||
204 | return NULL; | ||
205 | } | ||
206 | if (num < 1) | ||
207 | { | ||
208 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
209 | "Minimum training window invalid (<1), setting to 1.\n"); | ||
210 | plugin.training_window = 1; | ||
211 | } | ||
212 | else | ||
213 | { | ||
214 | plugin.training_window = (int) num; | ||
215 | } | ||
216 | if (GNUNET_OK != | ||
217 | GNUNET_CONFIGURATION_get_value_number (cfg, "sensor-model-gaussian", | ||
218 | "CONFIDENCE_INTERVAL", &num)) | ||
219 | { | ||
220 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
221 | _("Missing `CONFIDENCE_INTERVAL' value in configuration.\n")); | ||
222 | return NULL; | ||
223 | } | ||
224 | if (GNUNET_OK != | ||
225 | GNUNET_CONFIGURATION_get_value_float (cfg, "sensor-model-gaussian", | ||
226 | "WEIGHT_INC", &plugin.weight_inc)) | ||
227 | { | ||
228 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
229 | _("Missing `WEIGHT_INC' value in configuration.\n")); | ||
230 | return NULL; | ||
231 | } | ||
232 | plugin.confidence_interval = (int) num; | ||
233 | api = GNUNET_new (struct GNUNET_SENSOR_ModelFunctions); | ||
234 | |||
235 | api->cls = &plugin; | ||
236 | api->create_model = &sensor_gaussian_model_create_model; | ||
237 | api->destroy_model = &sensor_gaussian_model_destroy_model; | ||
238 | api->feed_model = &sensor_gaussian_model_feed; | ||
239 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Gaussian model plugin is running.\n"); | ||
240 | return api; | ||
241 | } | ||
242 | |||
243 | |||
244 | /** | ||
245 | * Exit point from the plugin. | ||
246 | * | ||
247 | * @param cls The plugin context (as returned by "init") | ||
248 | * @return Always NULL | ||
249 | */ | ||
250 | void * | ||
251 | libgnunet_plugin_sensor_model_gaussian_done (void *cls) | ||
252 | { | ||
253 | struct GNUNET_SENSOR_ModelFunctions *api = cls; | ||
254 | struct Plugin *plugin = api->cls; | ||
255 | |||
256 | plugin->cfg = NULL; | ||
257 | GNUNET_free (api); | ||
258 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Guassian model plugin is finished\n"); | ||
259 | return NULL; | ||
260 | |||
261 | } | ||
262 | |||
263 | /* end of plugin_sensor_model_gaussian.c */ | ||
diff --git a/src/sensor/profiler.py b/src/sensor/profiler.py deleted file mode 100644 index cdd917284..000000000 --- a/src/sensor/profiler.py +++ /dev/null | |||
@@ -1,175 +0,0 @@ | |||
1 | import argparse | ||
2 | import math | ||
3 | import networkx | ||
4 | import random | ||
5 | import tempfile | ||
6 | import os | ||
7 | import time | ||
8 | import matplotlib.pyplot as plt | ||
9 | from subprocess import Popen, PIPE, STDOUT | ||
10 | |||
11 | node_colors = None | ||
12 | graph = None | ||
13 | pos = None | ||
14 | |||
15 | def get_args(): | ||
16 | parser = argparse.ArgumentParser(description="Sensor profiler") | ||
17 | parser.add_argument('-p', '--peers', action='store', type=int, required=True, | ||
18 | help='Number of peers to run') | ||
19 | parser.add_argument('-l', '--links', action='store', type=int, required=False, | ||
20 | help='Number of links to create') | ||
21 | parser.add_argument('-i', '--sensors-interval', action='store', type=int, | ||
22 | required=False, | ||
23 | help='Change the interval of running sensors to given value') | ||
24 | parser.add_argument('-a', '--anomalous-peers', action='store', type=int, | ||
25 | required=True, | ||
26 | help='Number of peers to simulate anomalies on') | ||
27 | return parser.parse_args() | ||
28 | |||
29 | def generate_topology(peers, links): | ||
30 | global graph | ||
31 | global node_colors | ||
32 | global pos | ||
33 | graph = networkx.empty_graph(peers) | ||
34 | for i in range(0, links): | ||
35 | a = 0 | ||
36 | b = 0 | ||
37 | while a == b: | ||
38 | a = random.randint(0, peers - 1) | ||
39 | b = random.randint(0, peers - 1) | ||
40 | graph.add_edge(a, b) | ||
41 | node_colors = [0] * peers | ||
42 | pos = networkx.layout.spring_layout(graph) | ||
43 | |||
44 | def create_topology_file(): | ||
45 | global graph | ||
46 | nodes = list() | ||
47 | for i in range(len(graph.edge)): | ||
48 | nodes.append(list()) | ||
49 | for e in graph.edges(): | ||
50 | nodes[e[0]].append(e[1]) | ||
51 | print nodes | ||
52 | f = tempfile.NamedTemporaryFile(delete=False) | ||
53 | for i in range(len(nodes)): | ||
54 | if len(nodes[i]) == 0: | ||
55 | continue | ||
56 | f.write('%d:' % i) | ||
57 | f.write('|'.join(map(str, nodes[i]))) | ||
58 | f.write('\n') | ||
59 | # f.close() | ||
60 | return f.name | ||
61 | |||
62 | def draw_graph(): | ||
63 | global graph | ||
64 | global node_colors | ||
65 | global pos | ||
66 | t = int(time.time()) | ||
67 | inc = 2 | ||
68 | name = str(t) + '.png' | ||
69 | while os.path.exists(name): | ||
70 | name = '%d(%d).png' % (t, inc) | ||
71 | inc += 1 | ||
72 | print 'Drawing graph to file: %s' % name | ||
73 | plt.clf() | ||
74 | anomaly_lbls = {} | ||
75 | for i in range(len(graph.node)): | ||
76 | if node_colors[i] >= 1: | ||
77 | anomaly_lbls[i] = '\n\n\n' + str(node_colors[i] - 1) | ||
78 | networkx.draw(graph, pos=pos, node_color=node_colors, with_labels=range(len(graph.node)), cmap=plt.cm.Reds, vmin=0, vmax=2) | ||
79 | networkx.draw_networkx_labels(graph, pos, anomaly_lbls) | ||
80 | plt.savefig(name) | ||
81 | |||
82 | def peers_reconnected(p1, p2): | ||
83 | global graph | ||
84 | if p2 in graph[p1]: | ||
85 | print 'Link already exists' | ||
86 | return | ||
87 | graph.add_edge(p1, p2) | ||
88 | draw_graph() | ||
89 | |||
90 | def peers_disconnected(p1, p2): | ||
91 | global graph | ||
92 | print 'Disconnected peers %d and %d' % (p1, p2) | ||
93 | if p2 not in graph[p1]: | ||
94 | print 'Link does not exist' | ||
95 | return | ||
96 | graph.remove_edge(p1, p2) | ||
97 | draw_graph() | ||
98 | |||
99 | def anomaly_report(report): | ||
100 | global node_colors | ||
101 | if 0 == report['anomalous']: | ||
102 | node_colors[report['peer']] = 0 | ||
103 | else: | ||
104 | clr = 1 + report['neighbors'] | ||
105 | if node_colors[report['peer']] >= clr: | ||
106 | return | ||
107 | node_colors[report['peer']] = clr | ||
108 | draw_graph() | ||
109 | |||
110 | def handle_profiler_line(line): | ||
111 | if not line: | ||
112 | return | ||
113 | print line | ||
114 | if 'Peer disconnection request sent' in line: # Peers disconnected | ||
115 | parts = line.split(':') | ||
116 | peers = parts[-1].split(',') | ||
117 | peers_disconnected(int(peers[0]), int(peers[1])) | ||
118 | return | ||
119 | if 'Anomaly report:' in line: | ||
120 | parts = line.split('Anomaly report:') | ||
121 | anomaly_report(eval(parts[1])) | ||
122 | return | ||
123 | if 'Peer connection request sent' in line: # Peers reconnected | ||
124 | parts = line.split(':') | ||
125 | peers = parts[-1].split(',') | ||
126 | peers_reconnected(int(peers[0]), int(peers[1])) | ||
127 | |||
128 | def run_profiler(peers, topology_file, sensors_interval, anomalous_peers): | ||
129 | cmd1 = "./gnunet-sensor-profiler -p %d -t %s -a %d" % (peers, topology_file, anomalous_peers) | ||
130 | if sensors_interval: | ||
131 | cmd1 += " -i %d" % sensors_interval | ||
132 | cmd2 = "> log 2>&1" | ||
133 | cmd = "%s %s" % (cmd1, cmd2) | ||
134 | print cmd | ||
135 | process = Popen([cmd], shell=True) | ||
136 | time.sleep(0.5) | ||
137 | line = '' | ||
138 | f = open('log') | ||
139 | while process.poll() is None: | ||
140 | for c in f.read(): | ||
141 | if not c or c == '\n': | ||
142 | handle_profiler_line(line) | ||
143 | line = '' | ||
144 | else: | ||
145 | line += c | ||
146 | |||
147 | def main(): | ||
148 | args = vars(get_args()) | ||
149 | num_peers = args['peers'] | ||
150 | if num_peers < 3: | ||
151 | print 'Min number of peers is 3' | ||
152 | return | ||
153 | sensors_interval = None | ||
154 | if 'sensors_interval' in args: | ||
155 | sensors_interval = args['sensors_interval'] | ||
156 | if 'links' in args: | ||
157 | num_links = args['links'] | ||
158 | else: | ||
159 | #num_links = int(math.log(num_peers) * math.log(num_peers) * num_peers / 2) | ||
160 | num_links = int(math.log(num_peers) * num_peers) | ||
161 | # Generate random topology | ||
162 | generate_topology(num_peers, num_links) | ||
163 | print 'Generated random topology with %d peers and %d links' % (num_peers, num_links) | ||
164 | # Create a file with links to cut to split the topology into two | ||
165 | # Create TESTBED topology file | ||
166 | top_file = create_topology_file() | ||
167 | print 'Created TESTBED topology file %s' % top_file | ||
168 | draw_graph() | ||
169 | # Run c profiler | ||
170 | if os.path.isfile('log'): | ||
171 | os.remove('log') | ||
172 | run_profiler(num_peers, top_file, sensors_interval, args['anomalous_peers']) | ||
173 | |||
174 | if __name__ == "__main__": | ||
175 | main() | ||
diff --git a/src/sensor/sensor.conf.in b/src/sensor/sensor.conf.in deleted file mode 100644 index 481d4d148..000000000 --- a/src/sensor/sensor.conf.in +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | [sensor] | ||
2 | AUTOSTART = @AUTOSTART@ | ||
3 | BINARY = gnunet-service-sensor | ||
4 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-sensor.sock | ||
5 | @UNIXONLY@ PORT = 2120 | ||
6 | UNIX_MATCH_UID = NO | ||
7 | UNIX_MATCH_GID = YES | ||
8 | |||
9 | # Which modules to run (default: YES) | ||
10 | START_MONITORING = YES | ||
11 | START_REPORTING = YES | ||
12 | START_ANALYSIS = YES | ||
13 | START_UPDATE = YES | ||
14 | |||
15 | # Path to directory containing sensor definitions. | ||
16 | # If not set, will load from default location. | ||
17 | #SENSOR_DIR = | ||
18 | |||
19 | [sensor-analysis] | ||
20 | MODEL = gaussian | ||
21 | # How many subsequent values required to flip anomaly label. (Default: 1) | ||
22 | CONFIRMATION_COUNT = 1 | ||
23 | |||
24 | [sensor-model-gaussian] | ||
25 | TRAINING_WINDOW = 400 | ||
26 | CONFIDENCE_INTERVAL = 8 | ||
27 | WEIGHT_INC = 0 | ||
28 | |||
29 | [sensor-reporting] | ||
30 | POW_MATCHING_BITS = 15 | ||
31 | |||
32 | [sensor-update] | ||
33 | # Space separated list of trusted peers running update points | ||
34 | UPDATE_POINTS = | ||
diff --git a/src/sensor/sensor.h b/src/sensor/sensor.h deleted file mode 100644 index 59442d5eb..000000000 --- a/src/sensor/sensor.h +++ /dev/null | |||
@@ -1,172 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2012-2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file sensor/sensor.h | ||
22 | * @brief IPC messages and private service declarations | ||
23 | * @author Omar Tarabai | ||
24 | */ | ||
25 | |||
26 | #include "gnunet_sensor_service.h" | ||
27 | #include "gnunet_sensor_util_lib.h" | ||
28 | |||
29 | |||
30 | GNUNET_NETWORK_STRUCT_BEGIN | ||
31 | /** | ||
32 | * Carries a summary of a sensor | ||
33 | * | ||
34 | */ | ||
35 | struct SensorInfoMessage | ||
36 | { | ||
37 | /** | ||
38 | * Message header | ||
39 | */ | ||
40 | struct GNUNET_MessageHeader header; | ||
41 | |||
42 | /** | ||
43 | * Length of sensor name. Allocated at position 0 after this struct. | ||
44 | */ | ||
45 | uint16_t name_len; | ||
46 | |||
47 | /** | ||
48 | * First part of version number | ||
49 | */ | ||
50 | uint16_t version_major; | ||
51 | |||
52 | /** | ||
53 | * Second part of version number | ||
54 | */ | ||
55 | uint16_t version_minor; | ||
56 | |||
57 | /** | ||
58 | * Length of sensor description. Allocated at position 1 after this struct. | ||
59 | */ | ||
60 | uint16_t description_len; | ||
61 | }; | ||
62 | |||
63 | /** | ||
64 | * A message sent to the sensor service to force an anomaly status on a sensor. | ||
65 | */ | ||
66 | struct ForceAnomalyMessage | ||
67 | { | ||
68 | |||
69 | /** | ||
70 | * Message header | ||
71 | */ | ||
72 | struct GNUNET_MessageHeader header; | ||
73 | |||
74 | /** | ||
75 | * Hash of the sensor name | ||
76 | */ | ||
77 | struct GNUNET_HashCode sensor_name_hash; | ||
78 | |||
79 | /** | ||
80 | * New status | ||
81 | */ | ||
82 | uint16_t anomalous; | ||
83 | |||
84 | }; | ||
85 | |||
86 | GNUNET_NETWORK_STRUCT_END | ||
87 | /** | ||
88 | * Stop the sensor analysis module | ||
89 | */ | ||
90 | void | ||
91 | SENSOR_analysis_stop (); | ||
92 | |||
93 | |||
94 | /** | ||
95 | * Start the sensor analysis module | ||
96 | * | ||
97 | * @param c our service configuration | ||
98 | * @param sensors multihashmap of loaded sensors | ||
99 | * @return #GNUNET_OK if started successfully, #GNUNET_SYSERR otherwise | ||
100 | */ | ||
101 | int | ||
102 | SENSOR_analysis_start (const struct GNUNET_CONFIGURATION_Handle *c, | ||
103 | struct GNUNET_CONTAINER_MultiHashMap *s); | ||
104 | |||
105 | |||
106 | /** | ||
107 | * Stop sensor anomaly reporting module | ||
108 | */ | ||
109 | void | ||
110 | SENSOR_reporting_stop (); | ||
111 | |||
112 | /** | ||
113 | * Used by the analysis module to tell the reporting module about a change in | ||
114 | * the anomaly status of a sensor. | ||
115 | * | ||
116 | * @param sensor Related sensor | ||
117 | * @param anomalous The new sensor anomalous status | ||
118 | */ | ||
119 | void | ||
120 | SENSOR_reporting_anomaly_update (struct GNUNET_SENSOR_SensorInfo *sensor, | ||
121 | int anomalous); | ||
122 | |||
123 | |||
124 | /** | ||
125 | * Start the sensor anomaly reporting module | ||
126 | * | ||
127 | * @param c our service configuration | ||
128 | * @param s multihashmap of loaded sensors | ||
129 | * @return #GNUNET_OK if started successfully, #GNUNET_SYSERR otherwise | ||
130 | */ | ||
131 | int | ||
132 | SENSOR_reporting_start (const struct GNUNET_CONFIGURATION_Handle *c, | ||
133 | struct GNUNET_CONTAINER_MultiHashMap *s); | ||
134 | |||
135 | |||
136 | /** | ||
137 | * Stop the sensor update module | ||
138 | */ | ||
139 | void | ||
140 | SENSOR_update_stop (); | ||
141 | |||
142 | |||
143 | /** | ||
144 | * Start the sensor update module | ||
145 | * | ||
146 | * @param c our service configuration | ||
147 | * @param s multihashmap of loaded sensors | ||
148 | * @param cb callback to reset service components when we have new updates | ||
149 | * @return #GNUNET_OK if started successfully, #GNUNET_SYSERR otherwise | ||
150 | */ | ||
151 | int | ||
152 | SENSOR_update_start (const struct GNUNET_CONFIGURATION_Handle *c, | ||
153 | struct GNUNET_CONTAINER_MultiHashMap *s, void (*cb) ()); | ||
154 | |||
155 | |||
156 | /** | ||
157 | * Stop the sensor monitoring module | ||
158 | */ | ||
159 | void | ||
160 | SENSOR_monitoring_stop (); | ||
161 | |||
162 | |||
163 | /** | ||
164 | * Start the sensor monitoring module | ||
165 | * | ||
166 | * @param c our service configuration | ||
167 | * @param sensors multihashmap of loaded sensors | ||
168 | * @return #GNUNET_OK if started successfully, #GNUNET_SYSERR otherwise | ||
169 | */ | ||
170 | int | ||
171 | SENSOR_monitoring_start (const struct GNUNET_CONFIGURATION_Handle *c, | ||
172 | struct GNUNET_CONTAINER_MultiHashMap *s); | ||
diff --git a/src/sensor/sensor_api.c b/src/sensor/sensor_api.c deleted file mode 100644 index 3aa263c5c..000000000 --- a/src/sensor/sensor_api.c +++ /dev/null | |||
@@ -1,566 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensor/sensor_api.c | ||
23 | * @brief API for sensor service | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "sensor.h" | ||
29 | |||
30 | #define LOG(kind,...) GNUNET_log_from (kind, "sensor-api",__VA_ARGS__) | ||
31 | |||
32 | /** | ||
33 | * Handle to the sensor service. | ||
34 | */ | ||
35 | struct GNUNET_SENSOR_Handle | ||
36 | { | ||
37 | |||
38 | /** | ||
39 | * Our configuration. | ||
40 | */ | ||
41 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
42 | |||
43 | /** | ||
44 | * Connection to the service. | ||
45 | */ | ||
46 | struct GNUNET_CLIENT_Connection *client; | ||
47 | |||
48 | /** | ||
49 | * Head of iteration requests DLL. | ||
50 | */ | ||
51 | struct GNUNET_SENSOR_IterateContext *ic_head; | ||
52 | |||
53 | /** | ||
54 | * Tail of iteration requests DLL. | ||
55 | */ | ||
56 | struct GNUNET_SENSOR_IterateContext *ic_tail; | ||
57 | |||
58 | /** | ||
59 | * Head of force anomaly requests | ||
60 | */ | ||
61 | struct GNUNET_SENSOR_ForceAnomalyContext *fa_head; | ||
62 | |||
63 | /** | ||
64 | * Tail of force anomaly requests | ||
65 | */ | ||
66 | struct GNUNET_SENSOR_ForceAnomalyContext *fa_tail; | ||
67 | |||
68 | /** | ||
69 | * Message queue used to send data to service | ||
70 | */ | ||
71 | struct GNUNET_MQ_Handle *mq; | ||
72 | |||
73 | }; | ||
74 | |||
75 | /** | ||
76 | * Context for an iteration request. | ||
77 | */ | ||
78 | struct GNUNET_SENSOR_IterateContext | ||
79 | { | ||
80 | |||
81 | /** | ||
82 | * Kept in a DLL. | ||
83 | */ | ||
84 | struct GNUNET_SENSOR_IterateContext *next; | ||
85 | |||
86 | /** | ||
87 | * Kept in a DLL. | ||
88 | */ | ||
89 | struct GNUNET_SENSOR_IterateContext *prev; | ||
90 | |||
91 | /** | ||
92 | * Handle to the SENSOR service. | ||
93 | */ | ||
94 | struct GNUNET_SENSOR_Handle *h; | ||
95 | |||
96 | /** | ||
97 | * Function to call with the results. | ||
98 | */ | ||
99 | GNUNET_SENSOR_SensorIterateCB callback; | ||
100 | |||
101 | /** | ||
102 | * Closure for 'callback'. | ||
103 | */ | ||
104 | void *callback_cls; | ||
105 | |||
106 | /** | ||
107 | * Envelope containing iterate request. | ||
108 | */ | ||
109 | struct GNUNET_MQ_Envelope *ev; | ||
110 | |||
111 | /** | ||
112 | * Is the request already sent? If yes, cannot be canceled. | ||
113 | */ | ||
114 | int request_sent; | ||
115 | |||
116 | /** | ||
117 | * Are we expecting records from service? | ||
118 | */ | ||
119 | int receiving; | ||
120 | |||
121 | /** | ||
122 | * Task responsible for timeout. | ||
123 | */ | ||
124 | struct GNUNET_SCHEDULER_Task * timeout_task; | ||
125 | |||
126 | }; | ||
127 | |||
128 | /** | ||
129 | * Context of a force anomaly request | ||
130 | */ | ||
131 | struct GNUNET_SENSOR_ForceAnomalyContext | ||
132 | { | ||
133 | |||
134 | /** | ||
135 | * DLL | ||
136 | */ | ||
137 | struct GNUNET_SENSOR_ForceAnomalyContext *next; | ||
138 | |||
139 | /** | ||
140 | * DLL | ||
141 | */ | ||
142 | struct GNUNET_SENSOR_ForceAnomalyContext *prev; | ||
143 | |||
144 | /** | ||
145 | * Handle to the SENSOR service. | ||
146 | */ | ||
147 | struct GNUNET_SENSOR_Handle *h; | ||
148 | |||
149 | /** | ||
150 | * Envelope containing iterate request. | ||
151 | */ | ||
152 | struct GNUNET_MQ_Envelope *ev; | ||
153 | |||
154 | /** | ||
155 | * User continuation function | ||
156 | */ | ||
157 | GNUNET_SENSOR_Continuation cont; | ||
158 | |||
159 | /** | ||
160 | * Closure for cont | ||
161 | */ | ||
162 | void *cont_cls; | ||
163 | |||
164 | }; | ||
165 | |||
166 | |||
167 | /** | ||
168 | * Notifier of an error encountered by MQ. | ||
169 | * | ||
170 | * @param cls Closure, service handle | ||
171 | * @param error MQ error type | ||
172 | */ | ||
173 | static void | ||
174 | mq_error_handler (void *cls, enum GNUNET_MQ_Error error) | ||
175 | { | ||
176 | struct GNUNET_SENSOR_Handle *h = cls; | ||
177 | |||
178 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
179 | _("Received an error notification from MQ of type: %d\n"), error); | ||
180 | GNUNET_SENSOR_disconnect (h); //TODO: try to reconnect | ||
181 | } | ||
182 | |||
183 | |||
184 | /** | ||
185 | * Handler to a message of type: #GNUNET_MESSAGE_TYPE_SENSOR_END | ||
186 | * | ||
187 | * @param cls Closure, service handle | ||
188 | * @param msg Message received | ||
189 | */ | ||
190 | static void | ||
191 | handle_end (void *cls, const struct GNUNET_MessageHeader *msg) | ||
192 | { | ||
193 | struct GNUNET_SENSOR_Handle *h = cls; | ||
194 | struct GNUNET_SENSOR_IterateContext *ic; | ||
195 | GNUNET_SENSOR_SensorIterateCB cb; | ||
196 | void *cb_cls; | ||
197 | |||
198 | if (NULL == h->ic_head) | ||
199 | { | ||
200 | GNUNET_break_op (0); | ||
201 | //TODO: reconnect | ||
202 | return; | ||
203 | } | ||
204 | ic = h->ic_head; | ||
205 | cb = ic->callback; | ||
206 | cb_cls = ic->callback_cls; | ||
207 | ic->receiving = GNUNET_NO; | ||
208 | GNUNET_SENSOR_iterate_cancel (ic); | ||
209 | if (NULL != cb) | ||
210 | cb (cb_cls, NULL, NULL); | ||
211 | } | ||
212 | |||
213 | |||
214 | /** | ||
215 | * Handler to a message of type: #GNUNET_MESSAGE_TYPE_SENSOR_INFO | ||
216 | * | ||
217 | * @param cls Closure, service handle | ||
218 | * @param msg Message received | ||
219 | */ | ||
220 | static void | ||
221 | handle_sensor_info (void *cls, const struct GNUNET_MessageHeader *msg) | ||
222 | { | ||
223 | struct GNUNET_SENSOR_Handle *h = cls; | ||
224 | struct GNUNET_SENSOR_IterateContext *ic; | ||
225 | uint16_t msg_size; | ||
226 | struct SensorInfoMessage *sensor_msg; | ||
227 | uint16_t sensor_name_len; | ||
228 | uint16_t sensor_desc_len; | ||
229 | struct SensorInfoShort *sensor; | ||
230 | void *dummy; | ||
231 | |||
232 | if (NULL == h->ic_head) | ||
233 | { | ||
234 | GNUNET_break_op (0); | ||
235 | //TODO: reconnect | ||
236 | return; | ||
237 | } | ||
238 | ic = h->ic_head; | ||
239 | if (NULL == ic->callback) /* no need to parse message */ | ||
240 | return; | ||
241 | msg_size = ntohs (msg->size); | ||
242 | if (msg_size < sizeof (struct SensorInfoMessage)) | ||
243 | { | ||
244 | GNUNET_break_op (0); | ||
245 | //TODO: reconnect | ||
246 | return; | ||
247 | } | ||
248 | sensor_msg = (struct SensorInfoMessage *) msg; | ||
249 | sensor_name_len = ntohs (sensor_msg->name_len); | ||
250 | sensor_desc_len = ntohs (sensor_msg->description_len); | ||
251 | if (msg_size != | ||
252 | sizeof (struct SensorInfoMessage) + sensor_name_len + sensor_desc_len) | ||
253 | { | ||
254 | GNUNET_break_op (0); | ||
255 | //TODO: reconnect | ||
256 | return; | ||
257 | } | ||
258 | sensor = GNUNET_new (struct SensorInfoShort); | ||
259 | sensor->version_major = ntohs (sensor_msg->version_major); | ||
260 | sensor->version_minor = ntohs (sensor_msg->version_minor); | ||
261 | dummy = &sensor_msg[1]; | ||
262 | sensor->name = GNUNET_strndup (dummy, sensor_name_len); | ||
263 | dummy += sensor_name_len; | ||
264 | sensor->description = GNUNET_strndup (dummy, sensor_desc_len); | ||
265 | ic->callback (ic->callback_cls, sensor, NULL); | ||
266 | GNUNET_free (sensor->name); | ||
267 | GNUNET_free (sensor->description); | ||
268 | GNUNET_free (sensor); | ||
269 | } | ||
270 | |||
271 | |||
272 | /** | ||
273 | * Disconnect from the sensor service. | ||
274 | * Please disconnect only when all requests sent are complete or canceled. | ||
275 | * | ||
276 | * @param h handle to disconnect | ||
277 | */ | ||
278 | void | ||
279 | GNUNET_SENSOR_disconnect (struct GNUNET_SENSOR_Handle *h) | ||
280 | { | ||
281 | struct GNUNET_SENSOR_IterateContext *ic; | ||
282 | GNUNET_SENSOR_SensorIterateCB ic_callback; | ||
283 | void *ic_callback_cls; | ||
284 | struct GNUNET_SENSOR_ForceAnomalyContext *fa; | ||
285 | GNUNET_SENSOR_Continuation fa_cont; | ||
286 | void *fa_cont_cls; | ||
287 | |||
288 | ic = h->ic_head; | ||
289 | while (NULL != ic) | ||
290 | { | ||
291 | ic_callback = ic->callback; | ||
292 | ic_callback_cls = ic->callback_cls; | ||
293 | GNUNET_SENSOR_iterate_cancel (ic); | ||
294 | if (NULL != ic_callback) | ||
295 | ic_callback (ic_callback_cls, NULL, | ||
296 | _("Iterate request canceled due to disconnection.\n")); | ||
297 | ic = h->ic_head; | ||
298 | } | ||
299 | fa = h->fa_head; | ||
300 | while (NULL != fa) | ||
301 | { | ||
302 | fa_cont = fa->cont; | ||
303 | fa_cont_cls = fa->cont_cls; | ||
304 | GNUNET_SENSOR_force_anomaly_cancel (fa); | ||
305 | if (NULL != fa_cont) | ||
306 | fa_cont (fa_cont_cls, | ||
307 | _("Force anomaly request canceled due to disconnection.\n")); | ||
308 | fa = h->fa_head; | ||
309 | } | ||
310 | if (NULL != h->mq) | ||
311 | { | ||
312 | GNUNET_MQ_destroy (h->mq); | ||
313 | h->mq = NULL; | ||
314 | } | ||
315 | if (NULL != h->client) | ||
316 | { | ||
317 | GNUNET_CLIENT_disconnect (h->client); | ||
318 | h->client = NULL; | ||
319 | } | ||
320 | GNUNET_free (h); | ||
321 | } | ||
322 | |||
323 | |||
324 | /** | ||
325 | * Connect to the sensor service. | ||
326 | * | ||
327 | * @return NULL on error | ||
328 | */ | ||
329 | struct GNUNET_SENSOR_Handle * | ||
330 | GNUNET_SENSOR_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
331 | { | ||
332 | struct GNUNET_CLIENT_Connection *client; | ||
333 | struct GNUNET_SENSOR_Handle *h; | ||
334 | |||
335 | static const struct GNUNET_MQ_MessageHandler mq_handlers[] = { | ||
336 | {&handle_sensor_info, GNUNET_MESSAGE_TYPE_SENSOR_INFO, 0}, | ||
337 | {&handle_end, GNUNET_MESSAGE_TYPE_SENSOR_END, 0}, | ||
338 | GNUNET_MQ_HANDLERS_END | ||
339 | }; | ||
340 | |||
341 | client = GNUNET_CLIENT_connect ("sensor", cfg); | ||
342 | if (NULL == client) | ||
343 | return NULL; | ||
344 | h = GNUNET_new (struct GNUNET_SENSOR_Handle); | ||
345 | h->client = client; | ||
346 | h->cfg = cfg; | ||
347 | h->mq = | ||
348 | GNUNET_MQ_queue_for_connection_client (h->client, mq_handlers, | ||
349 | &mq_error_handler, h); | ||
350 | return h; | ||
351 | } | ||
352 | |||
353 | |||
354 | /** | ||
355 | * Iteration request has timed out. | ||
356 | * | ||
357 | * @param cls the 'struct GNUNET_SENSOR_SensorIteratorContext*' | ||
358 | * @param tc scheduler context | ||
359 | */ | ||
360 | static void | ||
361 | signal_sensor_iteration_timeout (void *cls, | ||
362 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
363 | { | ||
364 | struct GNUNET_SENSOR_IterateContext *ic = cls; | ||
365 | GNUNET_SENSOR_SensorIterateCB cb; | ||
366 | void *cb_cls; | ||
367 | |||
368 | ic->timeout_task = NULL; | ||
369 | cb = ic->callback; | ||
370 | cb_cls = ic->callback_cls; | ||
371 | GNUNET_SENSOR_iterate_cancel (ic); | ||
372 | if (NULL != cb) | ||
373 | cb (cb_cls, NULL, | ||
374 | _("Timeout transmitting iteration request to `SENSOR' service.")); | ||
375 | } | ||
376 | |||
377 | |||
378 | /** | ||
379 | * Callback from MQ when the request has already been sent to the service. | ||
380 | * Now it can not be canelled. | ||
381 | * | ||
382 | * @param cls closure | ||
383 | */ | ||
384 | static void | ||
385 | iterate_request_sent (void *cls) | ||
386 | { | ||
387 | struct GNUNET_SENSOR_IterateContext *ic = cls; | ||
388 | |||
389 | ic->request_sent = GNUNET_YES; | ||
390 | ic->ev = NULL; | ||
391 | ic->receiving = GNUNET_YES; | ||
392 | } | ||
393 | |||
394 | |||
395 | /** | ||
396 | * Cancel an iteration request. | ||
397 | * This should be called before the iterate callback is called with a NULL value. | ||
398 | * | ||
399 | * @param ic context of the iterator to cancel | ||
400 | */ | ||
401 | void | ||
402 | GNUNET_SENSOR_iterate_cancel (struct GNUNET_SENSOR_IterateContext *ic) | ||
403 | { | ||
404 | struct GNUNET_SENSOR_Handle *h; | ||
405 | |||
406 | h = ic->h; | ||
407 | if (GNUNET_NO == ic->request_sent) | ||
408 | { | ||
409 | GNUNET_MQ_send_cancel (ic->ev); | ||
410 | ic->ev = NULL; | ||
411 | ic->request_sent = GNUNET_YES; | ||
412 | } | ||
413 | if (GNUNET_YES == ic->receiving) | ||
414 | { | ||
415 | /* don't remove since we are still expecting records */ | ||
416 | ic->callback = NULL; | ||
417 | ic->callback_cls = NULL; | ||
418 | return; | ||
419 | } | ||
420 | if (NULL != ic->timeout_task) | ||
421 | { | ||
422 | GNUNET_SCHEDULER_cancel (ic->timeout_task); | ||
423 | ic->timeout_task = NULL; | ||
424 | } | ||
425 | GNUNET_CONTAINER_DLL_remove (h->ic_head, h->ic_tail, ic); | ||
426 | GNUNET_free (ic); | ||
427 | } | ||
428 | |||
429 | |||
430 | /** | ||
431 | * Get one or all sensors loaded by the sensor service. | ||
432 | * The callback will be called with each sensor received and once with a NULL | ||
433 | * value to signal end of iteration. | ||
434 | * | ||
435 | * @param h Handle to SENSOR service | ||
436 | * @param timeout how long to wait until timing out | ||
437 | * @param sensorname Name of the required sensor, NULL to get all | ||
438 | * @param callback the function to call for each sensor | ||
439 | * @param callback_cls closure for callback | ||
440 | * @return iterator context | ||
441 | */ | ||
442 | struct GNUNET_SENSOR_IterateContext * | ||
443 | GNUNET_SENSOR_iterate (struct GNUNET_SENSOR_Handle *h, | ||
444 | struct GNUNET_TIME_Relative timeout, | ||
445 | const char *sensor_name, | ||
446 | GNUNET_SENSOR_SensorIterateCB callback, | ||
447 | void *callback_cls) | ||
448 | { | ||
449 | struct GNUNET_SENSOR_IterateContext *ic; | ||
450 | struct GNUNET_MessageHeader *msg; | ||
451 | struct GNUNET_MQ_Envelope *ev; | ||
452 | size_t sensor_name_len; | ||
453 | |||
454 | if (NULL == sensor_name) | ||
455 | { | ||
456 | ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SENSOR_GETALL); | ||
457 | } | ||
458 | else | ||
459 | { | ||
460 | sensor_name_len = strlen (sensor_name) + 1; | ||
461 | ev = GNUNET_MQ_msg_extra (msg, sensor_name_len, | ||
462 | GNUNET_MESSAGE_TYPE_SENSOR_GET); | ||
463 | memcpy (&msg[1], sensor_name, sensor_name_len); | ||
464 | } | ||
465 | GNUNET_MQ_send (h->mq, ev); | ||
466 | ic = GNUNET_new (struct GNUNET_SENSOR_IterateContext); | ||
467 | |||
468 | ic->h = h; | ||
469 | ic->ev = ev; | ||
470 | ic->request_sent = GNUNET_NO; | ||
471 | ic->receiving = GNUNET_NO; | ||
472 | ic->callback = callback; | ||
473 | ic->callback_cls = callback_cls; | ||
474 | ic->timeout_task = | ||
475 | GNUNET_SCHEDULER_add_delayed (timeout, &signal_sensor_iteration_timeout, | ||
476 | ic); | ||
477 | GNUNET_MQ_notify_sent (ev, &iterate_request_sent, ic); | ||
478 | GNUNET_CONTAINER_DLL_insert_tail (h->ic_head, h->ic_tail, ic); | ||
479 | return ic; | ||
480 | } | ||
481 | |||
482 | |||
483 | /** | ||
484 | * Callback from MQ when the request has already been sent to the service. | ||
485 | * Now it can not be canelled. | ||
486 | * | ||
487 | * @param cls closure | ||
488 | */ | ||
489 | static void | ||
490 | force_anomaly_sent (void *cls) | ||
491 | { | ||
492 | struct GNUNET_SENSOR_ForceAnomalyContext *fa = cls; | ||
493 | GNUNET_SENSOR_Continuation cont; | ||
494 | void *cont_cls; | ||
495 | |||
496 | fa->ev = NULL; | ||
497 | cont = fa->cont; | ||
498 | cont_cls = fa->cont_cls; | ||
499 | GNUNET_SENSOR_force_anomaly_cancel (fa); | ||
500 | if (NULL != cont) | ||
501 | cont (cont_cls, NULL); | ||
502 | } | ||
503 | |||
504 | |||
505 | /** | ||
506 | * Cancel a force anomaly request. | ||
507 | * | ||
508 | * @param fa Force anomaly context returned by GNUNET_SENSOR_force_anomaly() | ||
509 | */ | ||
510 | void | ||
511 | GNUNET_SENSOR_force_anomaly_cancel (struct GNUNET_SENSOR_ForceAnomalyContext | ||
512 | *fa) | ||
513 | { | ||
514 | struct GNUNET_SENSOR_Handle *h = fa->h; | ||
515 | |||
516 | if (NULL != fa->ev) | ||
517 | { | ||
518 | GNUNET_MQ_send_cancel (fa->ev); | ||
519 | fa->ev = NULL; | ||
520 | } | ||
521 | GNUNET_CONTAINER_DLL_remove (h->fa_head, h->fa_tail, fa); | ||
522 | GNUNET_free (fa); | ||
523 | } | ||
524 | |||
525 | |||
526 | /** | ||
527 | * Force an anomaly status change on a given sensor. If the sensor reporting | ||
528 | * module is running, this will trigger the usual reporting logic, therefore, | ||
529 | * please only use this in a test environment. | ||
530 | * | ||
531 | * Also, if the sensor analysis module is running, it might conflict and cause | ||
532 | * undefined behaviour if it detects a real anomaly. | ||
533 | * | ||
534 | * @param h Service handle | ||
535 | * @param sensor_name Sensor name to set the anomaly status | ||
536 | * @param anomalous The desired status: #GNUNET_YES / #GNUNET_NO | ||
537 | * @param cont Continuation function to be called after the request is sent | ||
538 | * @param cont_cls Closure for cont | ||
539 | */ | ||
540 | struct GNUNET_SENSOR_ForceAnomalyContext * | ||
541 | GNUNET_SENSOR_force_anomaly (struct GNUNET_SENSOR_Handle *h, char *sensor_name, | ||
542 | int anomalous, GNUNET_SENSOR_Continuation cont, | ||
543 | void *cont_cls) | ||
544 | { | ||
545 | struct ForceAnomalyMessage *msg; | ||
546 | struct GNUNET_MQ_Envelope *ev; | ||
547 | struct GNUNET_SENSOR_ForceAnomalyContext *fa; | ||
548 | |||
549 | ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_FORCE); | ||
550 | GNUNET_CRYPTO_hash (sensor_name, strlen (sensor_name) + 1, | ||
551 | &msg->sensor_name_hash); | ||
552 | msg->anomalous = htons (anomalous); | ||
553 | GNUNET_MQ_send (h->mq, ev); | ||
554 | fa = GNUNET_new (struct GNUNET_SENSOR_ForceAnomalyContext); | ||
555 | |||
556 | fa->h = h; | ||
557 | fa->cont = cont; | ||
558 | fa->cont_cls = cont_cls; | ||
559 | fa->ev = ev; | ||
560 | GNUNET_CONTAINER_DLL_insert_tail (h->fa_head, h->fa_tail, fa); | ||
561 | GNUNET_MQ_notify_sent (ev, &force_anomaly_sent, fa); | ||
562 | return fa; | ||
563 | } | ||
564 | |||
565 | |||
566 | /* end of sensor_api.c */ | ||
diff --git a/src/sensor/sensor_util_lib.c b/src/sensor/sensor_util_lib.c deleted file mode 100644 index 806d41fc5..000000000 --- a/src/sensor/sensor_util_lib.c +++ /dev/null | |||
@@ -1,535 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensor/sensor_util_lib.c | ||
23 | * @brief sensor utilities | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | #include <inttypes.h> | ||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_sensor_util_lib.h" | ||
30 | #include "gnunet_statistics_service.h" | ||
31 | |||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "sensor-util",__VA_ARGS__) | ||
33 | |||
34 | /** | ||
35 | * Supported sources of sensor information | ||
36 | */ | ||
37 | static const char *sources[] = { "gnunet-statistics", "process", NULL }; | ||
38 | |||
39 | /** | ||
40 | * Supported datatypes of sensor information | ||
41 | */ | ||
42 | static const char *datatypes[] = { "numeric", "string", NULL }; | ||
43 | |||
44 | /** | ||
45 | * Parses a version number string into major and minor | ||
46 | * | ||
47 | * @param version full version string | ||
48 | * @param major pointer to parsed major value | ||
49 | * @param minor pointer to parsed minor value | ||
50 | * @return #GNUNET_OK if parsing went ok, #GNUNET_SYSERR in case of error | ||
51 | */ | ||
52 | static int | ||
53 | version_parse (char *version, uint16_t * major, uint16_t * minor) | ||
54 | { | ||
55 | int majorval = 0; | ||
56 | int minorval = 0; | ||
57 | |||
58 | for (; isdigit (*version); version++) | ||
59 | { | ||
60 | majorval *= 10; | ||
61 | majorval += *version - '0'; | ||
62 | } | ||
63 | if (*version != '.') | ||
64 | return GNUNET_SYSERR; | ||
65 | version++; | ||
66 | for (; isdigit (*version); version++) | ||
67 | { | ||
68 | minorval *= 10; | ||
69 | minorval += *version - '0'; | ||
70 | } | ||
71 | if (*version != 0) | ||
72 | return GNUNET_SYSERR; | ||
73 | *major = majorval; | ||
74 | *minor = minorval; | ||
75 | |||
76 | return GNUNET_OK; | ||
77 | } | ||
78 | |||
79 | |||
80 | /** | ||
81 | * Load sensor definition from configuration | ||
82 | * | ||
83 | * @param cfg configuration handle | ||
84 | * @param sectionname configuration section containing definition | ||
85 | */ | ||
86 | static struct GNUNET_SENSOR_SensorInfo * | ||
87 | load_sensor_from_cfg (struct GNUNET_CONFIGURATION_Handle *cfg, | ||
88 | const char *sectionname) | ||
89 | { | ||
90 | struct GNUNET_SENSOR_SensorInfo *sensor; | ||
91 | char *version_str; | ||
92 | char *starttime_str; | ||
93 | char *endtime_str; | ||
94 | unsigned long long time_sec; | ||
95 | char *dummy; | ||
96 | struct GNUNET_CRYPTO_EddsaPublicKey public_key; | ||
97 | |||
98 | sensor = GNUNET_new (struct GNUNET_SENSOR_SensorInfo); | ||
99 | |||
100 | //name | ||
101 | sensor->name = GNUNET_strdup (sectionname); | ||
102 | //version | ||
103 | if (GNUNET_OK != | ||
104 | GNUNET_CONFIGURATION_get_value_string (cfg, sectionname, "VERSION", | ||
105 | &version_str)) | ||
106 | { | ||
107 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Error reading sensor version\n")); | ||
108 | GNUNET_free (sensor); | ||
109 | return NULL; | ||
110 | } | ||
111 | if (GNUNET_OK != | ||
112 | version_parse (version_str, &(sensor->version_major), | ||
113 | &(sensor->version_minor))) | ||
114 | { | ||
115 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
116 | _("Invalid sensor version number, format should be major.minor\n")); | ||
117 | GNUNET_free (sensor); | ||
118 | GNUNET_free (version_str); | ||
119 | return NULL; | ||
120 | } | ||
121 | GNUNET_free (version_str); | ||
122 | //description | ||
123 | GNUNET_CONFIGURATION_get_value_string (cfg, sectionname, "DESCRIPTION", | ||
124 | &sensor->description); | ||
125 | //category | ||
126 | if (GNUNET_OK != | ||
127 | GNUNET_CONFIGURATION_get_value_string (cfg, sectionname, "CATEGORY", | ||
128 | &sensor->category) || | ||
129 | NULL == sensor->category) | ||
130 | { | ||
131 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Error reading sensor category\n")); | ||
132 | GNUNET_free (sensor); | ||
133 | return NULL; | ||
134 | } | ||
135 | //enabled | ||
136 | if (GNUNET_NO == | ||
137 | GNUNET_CONFIGURATION_get_value_yesno (cfg, sectionname, "ENABLED")) | ||
138 | sensor->enabled = GNUNET_NO; | ||
139 | else | ||
140 | sensor->enabled = GNUNET_YES; | ||
141 | //start time | ||
142 | sensor->start_time = NULL; | ||
143 | if (GNUNET_OK == | ||
144 | GNUNET_CONFIGURATION_get_value_string (cfg, sectionname, "START_TIME", | ||
145 | &starttime_str)) | ||
146 | { | ||
147 | GNUNET_STRINGS_fancy_time_to_absolute (starttime_str, sensor->start_time); | ||
148 | GNUNET_free (starttime_str); | ||
149 | } | ||
150 | //end time | ||
151 | sensor->end_time = NULL; | ||
152 | if (GNUNET_OK == | ||
153 | GNUNET_CONFIGURATION_get_value_string (cfg, sectionname, "END_TIME", | ||
154 | &endtime_str)) | ||
155 | { | ||
156 | GNUNET_STRINGS_fancy_time_to_absolute (endtime_str, sensor->end_time); | ||
157 | GNUNET_free (endtime_str); | ||
158 | } | ||
159 | //interval | ||
160 | if (GNUNET_OK != | ||
161 | GNUNET_CONFIGURATION_get_value_number (cfg, sectionname, "INTERVAL", | ||
162 | &time_sec)) | ||
163 | { | ||
164 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Error reading sensor run interval\n")); | ||
165 | GNUNET_free (sensor); | ||
166 | return NULL; | ||
167 | } | ||
168 | sensor->interval = | ||
169 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, time_sec); | ||
170 | //lifetime | ||
171 | if (GNUNET_OK == | ||
172 | GNUNET_CONFIGURATION_get_value_number (cfg, sectionname, "LIFETIME", | ||
173 | &time_sec)) | ||
174 | { | ||
175 | sensor->lifetime = | ||
176 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, time_sec); | ||
177 | if (sensor->lifetime.rel_value_us < sensor->interval.rel_value_us) | ||
178 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
179 | "Lifetime of sensor data is preferred to be higher than interval for sensor `%s'.\n", | ||
180 | sensor->name); | ||
181 | } | ||
182 | else | ||
183 | sensor->lifetime = GNUNET_TIME_UNIT_FOREVER_REL; | ||
184 | //capabilities TODO | ||
185 | //source | ||
186 | if (GNUNET_OK != | ||
187 | GNUNET_CONFIGURATION_get_value_choice (cfg, sectionname, "SOURCE", | ||
188 | sources, | ||
189 | (const char **) &sensor->source)) | ||
190 | { | ||
191 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Error reading sensor source\n")); | ||
192 | GNUNET_free (sensor); | ||
193 | return NULL; | ||
194 | } | ||
195 | if (sources[0] == sensor->source) //gnunet-statistics | ||
196 | { | ||
197 | if (GNUNET_OK != | ||
198 | GNUNET_CONFIGURATION_get_value_string (cfg, sectionname, | ||
199 | "GNUNET_STAT_SERVICE", | ||
200 | &sensor->gnunet_stat_service) || | ||
201 | GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, sectionname, | ||
202 | "GNUNET_STAT_NAME", | ||
203 | &sensor->gnunet_stat_name)) | ||
204 | { | ||
205 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
206 | _("Error reading sensor gnunet-statistics source information\n")); | ||
207 | GNUNET_free (sensor); | ||
208 | return NULL; | ||
209 | } | ||
210 | sensor->gnunet_stat_get_handle = NULL; | ||
211 | } | ||
212 | else if (sources[1] == sensor->source) //process | ||
213 | { | ||
214 | if (GNUNET_OK != | ||
215 | GNUNET_CONFIGURATION_get_value_string (cfg, sectionname, "EXT_PROCESS", | ||
216 | &sensor->ext_process)) | ||
217 | { | ||
218 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Error reading sensor process name\n")); | ||
219 | GNUNET_free (sensor); | ||
220 | return NULL; | ||
221 | } | ||
222 | GNUNET_CONFIGURATION_get_value_string (cfg, sectionname, "EXT_ARGS", | ||
223 | &sensor->ext_args); | ||
224 | } | ||
225 | //expected datatype | ||
226 | if (GNUNET_OK != | ||
227 | GNUNET_CONFIGURATION_get_value_choice (cfg, sectionname, | ||
228 | "EXPECTED_DATATYPE", datatypes, | ||
229 | (const char **) | ||
230 | &sensor->expected_datatype)) | ||
231 | { | ||
232 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
233 | _("Error reading sensor expected datatype\n")); | ||
234 | GNUNET_free (sensor); | ||
235 | return NULL; | ||
236 | } | ||
237 | if (sources[0] == sensor->source && datatypes[0] != sensor->expected_datatype) | ||
238 | { | ||
239 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
240 | _ | ||
241 | ("Invalid expected datatype, gnunet-statistics returns uint64 values\n")); | ||
242 | GNUNET_free (sensor); | ||
243 | return NULL; | ||
244 | } | ||
245 | //reporting | ||
246 | sensor->collection_point = NULL; | ||
247 | sensor->report_values = GNUNET_NO; | ||
248 | sensor->report_anomalies = GNUNET_NO; | ||
249 | if (GNUNET_OK == | ||
250 | GNUNET_CONFIGURATION_get_value_string (cfg, sectionname, | ||
251 | "COLLECTION_POINT", &dummy)) | ||
252 | { | ||
253 | if (GNUNET_OK == | ||
254 | GNUNET_CRYPTO_eddsa_public_key_from_string (dummy, strlen (dummy), | ||
255 | &public_key)) | ||
256 | { | ||
257 | sensor->collection_point = GNUNET_new (struct GNUNET_PeerIdentity); | ||
258 | |||
259 | sensor->collection_point->public_key = public_key; | ||
260 | if (GNUNET_OK == | ||
261 | GNUNET_CONFIGURATION_get_value_number (cfg, sectionname, | ||
262 | "VALUE_COLLECTION_INTERVAL", | ||
263 | &time_sec)) | ||
264 | { | ||
265 | sensor->report_values = GNUNET_YES; | ||
266 | sensor->value_reporting_interval = | ||
267 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, time_sec); | ||
268 | } | ||
269 | if (GNUNET_YES == | ||
270 | GNUNET_CONFIGURATION_get_value_yesno (cfg, sectionname, | ||
271 | "REPORT_ANOMALIES")) | ||
272 | sensor->report_anomalies = GNUNET_YES; | ||
273 | } | ||
274 | GNUNET_free (dummy); | ||
275 | } | ||
276 | //execution task | ||
277 | sensor->execution_task = NULL; | ||
278 | //running | ||
279 | sensor->running = GNUNET_NO; | ||
280 | return sensor; | ||
281 | } | ||
282 | |||
283 | |||
284 | /** | ||
285 | * Load sensor definition from file | ||
286 | * | ||
287 | * @param filename full path to file containing sensor definition | ||
288 | */ | ||
289 | static struct GNUNET_SENSOR_SensorInfo * | ||
290 | load_sensor_from_file (const char *filename) | ||
291 | { | ||
292 | struct GNUNET_CONFIGURATION_Handle *sensorcfg; | ||
293 | const char *filebasename; | ||
294 | struct GNUNET_SENSOR_SensorInfo *sensor; | ||
295 | |||
296 | //test file | ||
297 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
298 | { | ||
299 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to access sensor file: %s\n"), | ||
300 | filename); | ||
301 | return NULL; | ||
302 | } | ||
303 | //load file as configuration | ||
304 | sensorcfg = GNUNET_CONFIGURATION_create (); | ||
305 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_parse (sensorcfg, filename)) | ||
306 | { | ||
307 | GNUNET_CONFIGURATION_destroy (sensorcfg); | ||
308 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to load sensor definition: %s\n"), | ||
309 | filename); | ||
310 | return NULL; | ||
311 | } | ||
312 | //configuration section should be the same as filename | ||
313 | filebasename = GNUNET_STRINGS_get_short_name (filename); | ||
314 | sensor = load_sensor_from_cfg (sensorcfg, filebasename); | ||
315 | if (NULL == sensor) | ||
316 | { | ||
317 | GNUNET_CONFIGURATION_destroy (sensorcfg); | ||
318 | return NULL; | ||
319 | } | ||
320 | sensor->def_file = GNUNET_strdup (filename); | ||
321 | sensor->cfg = sensorcfg; | ||
322 | return sensor; | ||
323 | } | ||
324 | |||
325 | |||
326 | /** | ||
327 | * Given two version numbers as major and minor, compare them. | ||
328 | * | ||
329 | * @param v1_major First part of first version number | ||
330 | * @param v1_minor Second part of first version number | ||
331 | * @param v2_major First part of second version number | ||
332 | * @param v2_minor Second part of second version number | ||
333 | */ | ||
334 | int | ||
335 | GNUNET_SENSOR_version_compare (uint16_t v1_major, uint16_t v1_minor, | ||
336 | uint16_t v2_major, uint16_t v2_minor) | ||
337 | { | ||
338 | if (v1_major == v2_major) | ||
339 | return (v1_minor < v2_minor) ? -1 : (v1_minor > v2_minor); | ||
340 | else | ||
341 | return (v1_major < v2_major) ? -1 : (v1_major > v2_major); | ||
342 | } | ||
343 | |||
344 | |||
345 | /** | ||
346 | * Adds a new sensor to given hashmap. | ||
347 | * If the same name exist, compares versions and update if old. | ||
348 | * | ||
349 | * @param sensor Sensor structure to add | ||
350 | * @param map Hashmap to add to | ||
351 | * @return #GNUNET_YES if added | ||
352 | * #GNUNET_NO if not added which is not necessarily an error | ||
353 | */ | ||
354 | static int | ||
355 | add_sensor_to_hashmap (struct GNUNET_SENSOR_SensorInfo *sensor, | ||
356 | struct GNUNET_CONTAINER_MultiHashMap *map) | ||
357 | { | ||
358 | struct GNUNET_HashCode key; | ||
359 | struct GNUNET_SENSOR_SensorInfo *existing; | ||
360 | |||
361 | GNUNET_CRYPTO_hash (sensor->name, strlen (sensor->name) + 1, &key); | ||
362 | existing = GNUNET_CONTAINER_multihashmap_get (map, &key); | ||
363 | if (NULL != existing) //sensor with same name already exists | ||
364 | { | ||
365 | if (GNUNET_SENSOR_version_compare | ||
366 | (existing->version_major, existing->version_minor, | ||
367 | sensor->version_major, sensor->version_minor) >= 0) | ||
368 | { | ||
369 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
370 | _("Sensor `%s' already exists with same or newer version\n"), | ||
371 | sensor->name); | ||
372 | return GNUNET_NO; | ||
373 | } | ||
374 | else | ||
375 | { | ||
376 | GNUNET_CONTAINER_multihashmap_remove (map, &key, existing); //remove the old version | ||
377 | GNUNET_free (existing); | ||
378 | LOG (GNUNET_ERROR_TYPE_INFO, "Upgrading sensor `%s' to a newer version\n", | ||
379 | sensor->name); | ||
380 | } | ||
381 | } | ||
382 | if (GNUNET_SYSERR == | ||
383 | GNUNET_CONTAINER_multihashmap_put (map, &key, sensor, | ||
384 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
385 | { | ||
386 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
387 | _("Error adding new sensor `%s' to global hashmap.\n"), sensor->name); | ||
388 | return GNUNET_NO; | ||
389 | } | ||
390 | return GNUNET_YES; | ||
391 | } | ||
392 | |||
393 | |||
394 | /** | ||
395 | * Iterating over files in sensors directory | ||
396 | * | ||
397 | * @param cls closure | ||
398 | * @param filename complete filename (absolute path) | ||
399 | * @return #GNUNET_OK to continue to iterate | ||
400 | */ | ||
401 | static int | ||
402 | reload_sensors_dir_cb (void *cls, const char *filename) | ||
403 | { | ||
404 | struct GNUNET_CONTAINER_MultiHashMap *sensors = cls; | ||
405 | struct GNUNET_SENSOR_SensorInfo *sensor; | ||
406 | |||
407 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
408 | return GNUNET_OK; | ||
409 | sensor = load_sensor_from_file (filename); | ||
410 | if (NULL == sensor) | ||
411 | { | ||
412 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Error loading sensor from file: %s\n"), | ||
413 | filename); | ||
414 | return GNUNET_OK; | ||
415 | } | ||
416 | if (GNUNET_YES != add_sensor_to_hashmap (sensor, sensors)) | ||
417 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
418 | "Could not add sensor `%s' to global hashmap\n", sensor->name); | ||
419 | return GNUNET_OK; | ||
420 | } | ||
421 | |||
422 | |||
423 | /** | ||
424 | * Get path to the default directory containing the sensor definition files with | ||
425 | * a trailing directory separator. | ||
426 | * | ||
427 | * @return Default sensor files directory full path | ||
428 | */ | ||
429 | char * | ||
430 | GNUNET_SENSOR_get_default_sensor_dir () | ||
431 | { | ||
432 | char *datadir; | ||
433 | char *sensordir; | ||
434 | |||
435 | datadir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); | ||
436 | GNUNET_asprintf (&sensordir, "%ssensors%s", datadir, DIR_SEPARATOR_STR); | ||
437 | GNUNET_free (datadir); | ||
438 | return sensordir; | ||
439 | } | ||
440 | |||
441 | |||
442 | /** | ||
443 | * Reads sensor definitions from given sensor directory. | ||
444 | * | ||
445 | * @param sensordir Path to sensor directory. | ||
446 | * @return a multihashmap of loaded sensors | ||
447 | */ | ||
448 | struct GNUNET_CONTAINER_MultiHashMap * | ||
449 | GNUNET_SENSOR_load_all_sensors (char *sensor_dir) | ||
450 | { | ||
451 | struct GNUNET_CONTAINER_MultiHashMap *sensors; | ||
452 | |||
453 | GNUNET_assert (NULL != sensor_dir); | ||
454 | sensors = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); | ||
455 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
456 | "Loading sensor definitions from directory `%s'\n", sensor_dir); | ||
457 | GNUNET_assert (GNUNET_YES == | ||
458 | GNUNET_DISK_directory_test (sensor_dir, GNUNET_YES)); | ||
459 | /* read all files in sensors directory */ | ||
460 | GNUNET_DISK_directory_scan (sensor_dir, &reload_sensors_dir_cb, sensors); | ||
461 | LOG (GNUNET_ERROR_TYPE_INFO, "Loaded %d sensors from directory `%s'\n", | ||
462 | GNUNET_CONTAINER_multihashmap_size (sensors), sensor_dir); | ||
463 | return sensors; | ||
464 | } | ||
465 | |||
466 | |||
467 | /** | ||
468 | * Remove sensor execution from scheduler | ||
469 | * | ||
470 | * @param cls unused | ||
471 | * @param key hash of sensor name, key to hashmap | ||
472 | * @param value a `struct GNUNET_SENSOR_SensorInfo *` | ||
473 | * @return #GNUNET_YES if we should continue to | ||
474 | * iterate, | ||
475 | * #GNUNET_NO if not. | ||
476 | */ | ||
477 | static int | ||
478 | destroy_sensor (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
479 | { | ||
480 | struct GNUNET_SENSOR_SensorInfo *sensor = value; | ||
481 | |||
482 | if (NULL != sensor->execution_task) | ||
483 | { | ||
484 | GNUNET_SCHEDULER_cancel (sensor->execution_task); | ||
485 | sensor->execution_task = NULL; | ||
486 | } | ||
487 | if (NULL != sensor->gnunet_stat_get_handle) | ||
488 | { | ||
489 | GNUNET_STATISTICS_get_cancel (sensor->gnunet_stat_get_handle); | ||
490 | sensor->gnunet_stat_get_handle = NULL; | ||
491 | } | ||
492 | if (NULL != sensor->ext_cmd) | ||
493 | { | ||
494 | GNUNET_OS_command_stop (sensor->ext_cmd); | ||
495 | sensor->ext_cmd = NULL; | ||
496 | } | ||
497 | if (NULL != sensor->cfg) | ||
498 | GNUNET_CONFIGURATION_destroy (sensor->cfg); | ||
499 | if (NULL != sensor->name) | ||
500 | GNUNET_free (sensor->name); | ||
501 | if (NULL != sensor->def_file) | ||
502 | GNUNET_free (sensor->def_file); | ||
503 | if (NULL != sensor->description) | ||
504 | GNUNET_free (sensor->description); | ||
505 | if (NULL != sensor->category) | ||
506 | GNUNET_free (sensor->category); | ||
507 | if (NULL != sensor->capabilities) | ||
508 | GNUNET_free (sensor->capabilities); | ||
509 | if (NULL != sensor->gnunet_stat_service) | ||
510 | GNUNET_free (sensor->gnunet_stat_service); | ||
511 | if (NULL != sensor->gnunet_stat_name) | ||
512 | GNUNET_free (sensor->gnunet_stat_name); | ||
513 | if (NULL != sensor->ext_process) | ||
514 | GNUNET_free (sensor->ext_process); | ||
515 | if (NULL != sensor->ext_args) | ||
516 | GNUNET_free (sensor->ext_args); | ||
517 | if (NULL != sensor->collection_point) | ||
518 | GNUNET_free (sensor->collection_point); | ||
519 | GNUNET_free (sensor); | ||
520 | return GNUNET_YES; | ||
521 | } | ||
522 | |||
523 | |||
524 | /** | ||
525 | * Destroys a group of sensors in a hashmap and the hashmap itself | ||
526 | * | ||
527 | * @param sensors hashmap containing the sensors | ||
528 | */ | ||
529 | void | ||
530 | GNUNET_SENSOR_destroy_sensors (struct GNUNET_CONTAINER_MultiHashMap *sensors) | ||
531 | { | ||
532 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying sensor list.\n"); | ||
533 | GNUNET_CONTAINER_multihashmap_iterate (sensors, &destroy_sensor, NULL); | ||
534 | GNUNET_CONTAINER_multihashmap_destroy (sensors); | ||
535 | } | ||
diff --git a/src/sensor/sensor_util_lib_crypto.c b/src/sensor/sensor_util_lib_crypto.c deleted file mode 100644 index 0586879c7..000000000 --- a/src/sensor/sensor_util_lib_crypto.c +++ /dev/null | |||
@@ -1,301 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensor/sensor_util_lib_crypto.c | ||
23 | * @brief senor utilities - crpyto related functions | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | #include <inttypes.h> | ||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_sensor_util_lib.h" | ||
30 | #include "gnunet_signatures.h" | ||
31 | |||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "sensor-util-crypto",__VA_ARGS__) | ||
33 | |||
34 | /** | ||
35 | * Context of an operation performed by #GNUNET_SENSOR_crypto_pow_sign() | ||
36 | */ | ||
37 | struct GNUNET_SENSOR_crypto_pow_context | ||
38 | { | ||
39 | |||
40 | /** | ||
41 | * Proof-of-work value | ||
42 | */ | ||
43 | uint64_t pow; | ||
44 | |||
45 | /** | ||
46 | * Private key to be used for signing | ||
47 | */ | ||
48 | struct GNUNET_CRYPTO_EddsaPrivateKey private_key; | ||
49 | |||
50 | /** | ||
51 | * Number of leading zeros required in the result hash | ||
52 | */ | ||
53 | int matching_bits; | ||
54 | |||
55 | /** | ||
56 | * Callback function to call with the result | ||
57 | */ | ||
58 | GNUNET_SENSOR_UTIL_pow_callback callback; | ||
59 | |||
60 | /** | ||
61 | * Closure for callback | ||
62 | */ | ||
63 | void *callback_cls; | ||
64 | |||
65 | /** | ||
66 | * Task that calculates the proof-of-work | ||
67 | */ | ||
68 | struct GNUNET_SCHEDULER_Task * calculate_pow_task; | ||
69 | |||
70 | /** | ||
71 | * Size of msg (allocated after this struct) | ||
72 | */ | ||
73 | size_t msg_size; | ||
74 | |||
75 | /** | ||
76 | * Timestamp of the message | ||
77 | */ | ||
78 | struct GNUNET_TIME_Absolute timestamp; | ||
79 | |||
80 | /** | ||
81 | * Public key of the peer sending this message | ||
82 | */ | ||
83 | struct GNUNET_CRYPTO_EddsaPublicKey public_key; | ||
84 | |||
85 | }; | ||
86 | |||
87 | |||
88 | /** | ||
89 | * Calculate the scrypt hash | ||
90 | */ | ||
91 | static void | ||
92 | pow_hash (const void *buf, size_t buf_len, struct GNUNET_HashCode *result) | ||
93 | { | ||
94 | GNUNET_break (0 == | ||
95 | gcry_kdf_derive (buf, buf_len, GCRY_KDF_SCRYPT, | ||
96 | 1 /* subalgo */ , | ||
97 | "gnunet-sensor-util-proof-of-work", | ||
98 | strlen ("gnunet-sensor-util-proof-of-work"), 2 | ||
99 | /* iterations; keep cost of individual op small */ | ||
100 | , sizeof (struct GNUNET_HashCode), result)); | ||
101 | } | ||
102 | |||
103 | |||
104 | /** | ||
105 | * Count the leading zeroes in hash. | ||
106 | * | ||
107 | * @param hash to count leading zeros in | ||
108 | * @return the number of leading zero bits. | ||
109 | */ | ||
110 | static unsigned int | ||
111 | count_leading_zeroes (const struct GNUNET_HashCode *hash) | ||
112 | { | ||
113 | unsigned int hash_count; | ||
114 | |||
115 | hash_count = 0; | ||
116 | while ((0 == GNUNET_CRYPTO_hash_get_bit (hash, hash_count))) | ||
117 | hash_count++; | ||
118 | return hash_count; | ||
119 | } | ||
120 | |||
121 | |||
122 | /** | ||
123 | * Check if the given proof-of-work is valid | ||
124 | */ | ||
125 | static int | ||
126 | check_pow (void *msg, size_t msg_size, uint64_t pow, int matching_bits) | ||
127 | { | ||
128 | char buf[msg_size + sizeof (pow)] GNUNET_ALIGN; | ||
129 | struct GNUNET_HashCode result; | ||
130 | |||
131 | memcpy (buf, &pow, sizeof (pow)); | ||
132 | memcpy (&buf[sizeof (pow)], msg, msg_size); | ||
133 | pow_hash (buf, sizeof (buf), &result); | ||
134 | return (count_leading_zeroes (&result) >= | ||
135 | matching_bits) ? GNUNET_YES : GNUNET_NO; | ||
136 | } | ||
137 | |||
138 | |||
139 | /** | ||
140 | * Task that checks if pow is correct, otherwise increments and reschedules itself | ||
141 | */ | ||
142 | static void | ||
143 | calculate_pow (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
144 | { | ||
145 | struct GNUNET_SENSOR_crypto_pow_context *cx = cls; | ||
146 | struct GNUNET_SENSOR_crypto_pow_block *result_block; | ||
147 | GNUNET_SENSOR_UTIL_pow_callback callback; | ||
148 | void *callback_cls; | ||
149 | int sign_result; | ||
150 | |||
151 | if (0 == cx->pow % 1000) | ||
152 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Checking pow %" PRIu64 ".\n", cx->pow); | ||
153 | if (GNUNET_YES == | ||
154 | check_pow (&cx->timestamp, | ||
155 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) + | ||
156 | sizeof (struct GNUNET_TIME_Absolute) + cx->msg_size, cx->pow, | ||
157 | cx->matching_bits)) | ||
158 | { | ||
159 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Found pow %" PRIu64 ".\n", cx->pow); | ||
160 | cx->calculate_pow_task = NULL; | ||
161 | result_block = | ||
162 | GNUNET_malloc (sizeof (struct GNUNET_SENSOR_crypto_pow_block) + | ||
163 | cx->msg_size); | ||
164 | result_block->msg_size = cx->msg_size; | ||
165 | result_block->pow = cx->pow; | ||
166 | result_block->timestamp = cx->timestamp; | ||
167 | result_block->public_key = cx->public_key; | ||
168 | result_block->purpose.purpose = | ||
169 | htonl (GNUNET_SIGNATURE_PURPOSE_SENSOR_ANOMALY_REPORT); | ||
170 | result_block->purpose.size = | ||
171 | htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | ||
172 | sizeof (struct GNUNET_TIME_Absolute) + | ||
173 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) + cx->msg_size); | ||
174 | memcpy (&result_block[1], &cx[1], cx->msg_size); | ||
175 | sign_result = | ||
176 | GNUNET_CRYPTO_eddsa_sign (&cx->private_key, &result_block->purpose, | ||
177 | &result_block->signature); | ||
178 | callback = cx->callback; | ||
179 | callback_cls = cx->callback_cls; | ||
180 | GNUNET_SENSOR_crypto_pow_sign_cancel (cx); | ||
181 | if (NULL != callback) | ||
182 | callback (callback_cls, (GNUNET_OK == sign_result) ? result_block : NULL); | ||
183 | GNUNET_free (result_block); | ||
184 | return; | ||
185 | } | ||
186 | cx->pow++; | ||
187 | cx->calculate_pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, cx); | ||
188 | } | ||
189 | |||
190 | |||
191 | /** | ||
192 | * Cancel an operation started by #GNUNET_SENSOR_crypto_pow_sign(). | ||
193 | * Call only before callback function passed to #GNUNET_SENSOR_crypto_pow_sign() | ||
194 | * is called with the result. | ||
195 | */ | ||
196 | void | ||
197 | GNUNET_SENSOR_crypto_pow_sign_cancel (struct GNUNET_SENSOR_crypto_pow_context | ||
198 | *cx) | ||
199 | { | ||
200 | if (NULL != cx->calculate_pow_task) | ||
201 | { | ||
202 | GNUNET_SCHEDULER_cancel (cx->calculate_pow_task); | ||
203 | cx->calculate_pow_task = NULL; | ||
204 | } | ||
205 | GNUNET_free (cx); | ||
206 | cx = NULL; | ||
207 | } | ||
208 | |||
209 | |||
210 | /** | ||
211 | * Calculate proof-of-work and sign a message. | ||
212 | * The result of all operations will be returned via the callback passed to this | ||
213 | * function. Note that the payload (msg) is copied to the result block. | ||
214 | * | ||
215 | * @param msg Message to calculate pow and sign | ||
216 | * @param msg_size size of msg | ||
217 | * @param timestamp Timestamp to add to the message to protect against replay attacks | ||
218 | * @param public_key Public key of the origin peer, to protect against redirect attacks | ||
219 | * @param private_key Private key of the origin peer to sign the result | ||
220 | * @param matching_bits Number of leading zeros required in the result hash | ||
221 | * @param callback Callback function to call with the result | ||
222 | * @param callback_cls Closure for callback | ||
223 | * @return Operation context | ||
224 | */ | ||
225 | struct GNUNET_SENSOR_crypto_pow_context * | ||
226 | GNUNET_SENSOR_crypto_pow_sign (void *msg, size_t msg_size, | ||
227 | struct GNUNET_TIME_Absolute *timestamp, | ||
228 | struct GNUNET_CRYPTO_EddsaPublicKey *public_key, | ||
229 | struct GNUNET_CRYPTO_EddsaPrivateKey | ||
230 | *private_key, int matching_bits, | ||
231 | GNUNET_SENSOR_UTIL_pow_callback callback, | ||
232 | void *callback_cls) | ||
233 | { | ||
234 | struct GNUNET_SENSOR_crypto_pow_context *cx; | ||
235 | |||
236 | cx = GNUNET_malloc (sizeof (struct GNUNET_SENSOR_crypto_pow_context) + | ||
237 | msg_size); | ||
238 | |||
239 | cx->timestamp = *timestamp; | ||
240 | cx->public_key = *public_key; | ||
241 | cx->msg_size = msg_size; | ||
242 | memcpy (&cx[1], msg, msg_size); | ||
243 | cx->pow = 0; | ||
244 | cx->private_key = *private_key; | ||
245 | cx->matching_bits = matching_bits; | ||
246 | cx->callback = callback; | ||
247 | cx->callback_cls = callback_cls; | ||
248 | cx->calculate_pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, cx); | ||
249 | return cx; | ||
250 | } | ||
251 | |||
252 | |||
253 | /** | ||
254 | * Verify that proof-of-work and signature in the given block are valid. | ||
255 | * If all valid, a pointer to the payload within the block is set and the size | ||
256 | * of the payload is returned. | ||
257 | * | ||
258 | * **VERY IMPORTANT** : You will still need to verify the timestamp yourself. | ||
259 | * | ||
260 | * @param block The block received and needs to be verified | ||
261 | * @param matching_bits Number of leading zeros in the hash used to verify pow | ||
262 | * @param public_key Public key of the peer that sent this block | ||
263 | * @param payload Where to store the pointer to the payload | ||
264 | * @return Size of the payload, 0 on error | ||
265 | */ | ||
266 | size_t | ||
267 | GNUNET_SENSOR_crypto_verify_pow_sign (struct GNUNET_SENSOR_crypto_pow_block * | ||
268 | block, int matching_bits, | ||
269 | struct GNUNET_CRYPTO_EddsaPublicKey * | ||
270 | public_key, void **payload) | ||
271 | { | ||
272 | /* Check public key */ | ||
273 | if (0 != | ||
274 | memcmp (public_key, &block->public_key, | ||
275 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey))) | ||
276 | { | ||
277 | LOG (GNUNET_ERROR_TYPE_WARNING, "Public key mismatch.\n"); | ||
278 | return 0; | ||
279 | } | ||
280 | /* Check signature */ | ||
281 | if (GNUNET_OK != | ||
282 | GNUNET_CRYPTO_eddsa_verify | ||
283 | (GNUNET_SIGNATURE_PURPOSE_SENSOR_ANOMALY_REPORT, &block->purpose, | ||
284 | &block->signature, public_key)) | ||
285 | { | ||
286 | LOG (GNUNET_ERROR_TYPE_WARNING, "Invalid signature.\n"); | ||
287 | return 0; | ||
288 | } | ||
289 | /* Check pow */ | ||
290 | if (GNUNET_NO == | ||
291 | check_pow (&block->timestamp, | ||
292 | sizeof (struct GNUNET_TIME_Absolute) + | ||
293 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) + block->msg_size, | ||
294 | block->pow, matching_bits)) | ||
295 | { | ||
296 | LOG (GNUNET_ERROR_TYPE_WARNING, "Invalid proof-of-work.\n"); | ||
297 | return 0; | ||
298 | } | ||
299 | *payload = &block[1]; | ||
300 | return block->msg_size; | ||
301 | } | ||
diff --git a/src/sensor/sensors/average-ping-rtt b/src/sensor/sensors/average-ping-rtt deleted file mode 100644 index 7a4b5ca67..000000000 --- a/src/sensor/sensors/average-ping-rtt +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [average-ping-rtt] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Calculate average ping latency to gnunet.org | ||
5 | CATEGORY = Underlay | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = process | ||
18 | |||
19 | #GNUNET_STAT_SERVICE = | ||
20 | #GNUNET_STAT_NAME = | ||
21 | |||
22 | EXT_PROCESS = avgping.sh | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 7200 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/average-ping-rtt-files/avgping.sh b/src/sensor/sensors/average-ping-rtt-files/avgping.sh deleted file mode 100755 index 35e585b77..000000000 --- a/src/sensor/sensors/average-ping-rtt-files/avgping.sh +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | ping -c 10 gnunet.org | awk -F/ '/^rtt/ { print $5 }' | ||
diff --git a/src/sensor/sensors/core-peers-connected b/src/sensor/sensors/core-peers-connected deleted file mode 100644 index 51bf7f7d3..000000000 --- a/src/sensor/sensors/core-peers-connected +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [core-peers-connected] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Gets the number of peers connected to core service | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = gnunet-statistics | ||
18 | |||
19 | GNUNET_STAT_SERVICE = core | ||
20 | GNUNET_STAT_NAME = # peers connected | ||
21 | |||
22 | #EXT_PROCESS = | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/datacache-bytes-stored b/src/sensor/sensors/datacache-bytes-stored deleted file mode 100644 index 9601f5280..000000000 --- a/src/sensor/sensors/datacache-bytes-stored +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [datacache-bytes-stored] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Bytes stored by GNUnet datacache service | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = gnunet-statistics | ||
18 | |||
19 | GNUNET_STAT_SERVICE = datacache | ||
20 | GNUNET_STAT_NAME = # bytes stored | ||
21 | |||
22 | #EXT_PROCESS = | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/dht-peers-connected b/src/sensor/sensors/dht-peers-connected deleted file mode 100644 index 6e4d448ae..000000000 --- a/src/sensor/sensors/dht-peers-connected +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [dht-peers-connected] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Gets the number of peers connected to dht service | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = gnunet-statistics | ||
18 | |||
19 | GNUNET_STAT_SERVICE = dht | ||
20 | GNUNET_STAT_NAME = # peers connected | ||
21 | |||
22 | #EXT_PROCESS = | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/fs-peers-connected b/src/sensor/sensors/fs-peers-connected deleted file mode 100644 index 1a3cb127b..000000000 --- a/src/sensor/sensors/fs-peers-connected +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [fs-peers-connected] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Gets the number of peers connected to fs service | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = gnunet-statistics | ||
18 | |||
19 | GNUNET_STAT_SERVICE = fs | ||
20 | GNUNET_STAT_NAME = # peers connected | ||
21 | |||
22 | #EXT_PROCESS = | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/gnunet-version b/src/sensor/sensors/gnunet-version deleted file mode 100644 index 271b738d4..000000000 --- a/src/sensor/sensors/gnunet-version +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [gnunet-version] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Gets gnunet version number | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 86400 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = process | ||
18 | |||
19 | #GNUNET_STAT_SERVICE = | ||
20 | #GNUNET_STAT_NAME = | ||
21 | |||
22 | EXT_PROCESS = gnunet-arm | ||
23 | EXT_ARGS = -v | ||
24 | |||
25 | EXPECTED_DATATYPE = string | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/known-peers b/src/sensor/sensors/known-peers deleted file mode 100644 index fda106330..000000000 --- a/src/sensor/sensors/known-peers +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [known-peers] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Gets the number of known peers | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = gnunet-statistics | ||
18 | |||
19 | GNUNET_STAT_SERVICE = peerinfo | ||
20 | GNUNET_STAT_NAME = # peers known | ||
21 | |||
22 | #EXT_PROCESS = | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/nse b/src/sensor/sensors/nse deleted file mode 100644 index 8cede34cb..000000000 --- a/src/sensor/sensors/nse +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [nse] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = GNUnet network size estimate | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = gnunet-statistics | ||
18 | |||
19 | GNUNET_STAT_SERVICE = nse | ||
20 | GNUNET_STAT_NAME = # nodes in the network (estimate) | ||
21 | |||
22 | #EXT_PROCESS = | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/peerstore-memory b/src/sensor/sensors/peerstore-memory deleted file mode 100644 index 0a60866ad..000000000 --- a/src/sensor/sensors/peerstore-memory +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [peerstore-memory] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Memory consumption of GNUnet peerstore service | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = process | ||
18 | |||
19 | #GNUNET_STAT_SERVICE = | ||
20 | #GNUNET_STAT_NAME = | ||
21 | |||
22 | EXT_PROCESS = peerstore-memory.sh | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/peerstore-memory-files/peerstore-memory.sh b/src/sensor/sensors/peerstore-memory-files/peerstore-memory.sh deleted file mode 100755 index 069a9972d..000000000 --- a/src/sensor/sensors/peerstore-memory-files/peerstore-memory.sh +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | ps aux | grep 'gnunet-service-peerstore' | grep -v grep | awk '{ print $6 }' | ||
diff --git a/src/sensor/sensors/transport-bytes-received b/src/sensor/sensors/transport-bytes-received deleted file mode 100644 index d247f6572..000000000 --- a/src/sensor/sensors/transport-bytes-received +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [transport-bytes-received] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Number of bytes received by GNUnet transport service | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = gnunet-statistics | ||
18 | |||
19 | GNUNET_STAT_SERVICE = transport | ||
20 | GNUNET_STAT_NAME = # bytes total received | ||
21 | |||
22 | #EXT_PROCESS = | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/transport-http-connections b/src/sensor/sensors/transport-http-connections deleted file mode 100644 index 6d8d7d95a..000000000 --- a/src/sensor/sensors/transport-http-connections +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [transport-http-connections] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Gets the number of transport HTTP connections | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = gnunet-statistics | ||
18 | |||
19 | GNUNET_STAT_SERVICE = transport | ||
20 | GNUNET_STAT_NAME = # HTTP client connections | ||
21 | |||
22 | #EXT_PROCESS = | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/transport-https-connections b/src/sensor/sensors/transport-https-connections deleted file mode 100644 index 44af29b4b..000000000 --- a/src/sensor/sensors/transport-https-connections +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [transport-https-connections] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Gets the number of transport HTTPS connections | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = gnunet-statistics | ||
18 | |||
19 | GNUNET_STAT_SERVICE = transport | ||
20 | GNUNET_STAT_NAME = # HTTPS client connections | ||
21 | |||
22 | #EXT_PROCESS = | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/transport-peers-connected b/src/sensor/sensors/transport-peers-connected deleted file mode 100644 index fd18919ba..000000000 --- a/src/sensor/sensors/transport-peers-connected +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [transport-peers-connected] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Gets the number of peers connected to transport service | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = gnunet-statistics | ||
18 | |||
19 | GNUNET_STAT_SERVICE = transport | ||
20 | GNUNET_STAT_NAME = # peers connected | ||
21 | |||
22 | #EXT_PROCESS = | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/transport-tcp-bytes-transmitted b/src/sensor/sensors/transport-tcp-bytes-transmitted deleted file mode 100644 index 4a75ac3fb..000000000 --- a/src/sensor/sensors/transport-tcp-bytes-transmitted +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [transport-tcp-bytes-transmitted] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Number of GNUnet transport TCP bytes transmitted | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = gnunet-statistics | ||
18 | |||
19 | GNUNET_STAT_SERVICE = transport | ||
20 | GNUNET_STAT_NAME = # bytes transmitted via TCP | ||
21 | |||
22 | #EXT_PROCESS = | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/sensors/transport-tcp-sessions-active b/src/sensor/sensors/transport-tcp-sessions-active deleted file mode 100644 index 5dd9c6d35..000000000 --- a/src/sensor/sensors/transport-tcp-sessions-active +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [transport-tcp-sessions-active] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Number of GNUnet transport service active TCP sessions | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = gnunet-statistics | ||
18 | |||
19 | GNUNET_STAT_SERVICE = transport | ||
20 | GNUNET_STAT_NAME = # TCP sessions active | ||
21 | |||
22 | #EXT_PROCESS = | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensor/test_gnunet-service-sensor_reporting.c b/src/sensor/test_gnunet-service-sensor_reporting.c deleted file mode 100644 index d8302751e..000000000 --- a/src/sensor/test_gnunet-service-sensor_reporting.c +++ /dev/null | |||
@@ -1,552 +0,0 @@ | |||
1 | /* | ||
2 | * This file is part of GNUnet. | ||
3 | * Copyright (C) | ||
4 | * | ||
5 | * GNUnet is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published | ||
7 | * by the Free Software Foundation; either version 3, or (at your | ||
8 | * 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 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with GNUnet; see the file COPYING. If not, write to the | ||
17 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | * Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file sensor/test_gnunet-service-sensor_reporting.c | ||
22 | * @brief testcase for gnunet-service-sensor_reporting.c | ||
23 | */ | ||
24 | #include "platform.h" | ||
25 | #include "gnunet_util_lib.h" | ||
26 | #include "gnunet_testbed_service.h" | ||
27 | #include "gnunet_sensor_util_lib.h" | ||
28 | #include "sensor.h" | ||
29 | #include "gnunet_peerstore_service.h" | ||
30 | #include "gnunet_sensor_service.h" | ||
31 | |||
32 | /** | ||
33 | * Number of peers to start for the test | ||
34 | */ | ||
35 | #define NUM_PEERS 2 | ||
36 | |||
37 | /** | ||
38 | * Test timeout | ||
39 | */ | ||
40 | #define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1) | ||
41 | |||
42 | /** | ||
43 | * How long to wait between starting everything and forcing anomalies to give | ||
44 | * the peer enough time to stabilize. | ||
45 | */ | ||
46 | #define ANOMALY_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3) | ||
47 | |||
48 | /** | ||
49 | * Information about a test peer | ||
50 | */ | ||
51 | struct TestPeer | ||
52 | { | ||
53 | |||
54 | /** | ||
55 | * DLL | ||
56 | */ | ||
57 | struct TestPeer *prev; | ||
58 | |||
59 | /** | ||
60 | * DLL | ||
61 | */ | ||
62 | struct TestPeer *next; | ||
63 | |||
64 | /** | ||
65 | * TESTBED information about the peer | ||
66 | */ | ||
67 | struct GNUNET_TESTBED_Peer *testbed_peer; | ||
68 | |||
69 | /** | ||
70 | * Peer indentity | ||
71 | */ | ||
72 | struct GNUNET_PeerIdentity peer_id; | ||
73 | |||
74 | /** | ||
75 | * Peerstore watch context for this peer's anomaly reports | ||
76 | */ | ||
77 | struct GNUNET_PEERSTORE_WatchContext *wc; | ||
78 | |||
79 | /** | ||
80 | * TESTBED operation connecting us to sensor service | ||
81 | */ | ||
82 | struct GNUNET_TESTBED_Operation *sensor_op; | ||
83 | |||
84 | /** | ||
85 | * Sensor service handle | ||
86 | */ | ||
87 | struct GNUNET_SENSOR_Handle *sensor; | ||
88 | |||
89 | /** | ||
90 | * GNUNET scheduler task that forces the anomaly after a stabilization delay | ||
91 | */ | ||
92 | struct GNUNET_SCHEDULER_Task * delay_task; | ||
93 | |||
94 | }; | ||
95 | |||
96 | /** | ||
97 | * Test name | ||
98 | */ | ||
99 | static const char *testname = "test_gnunet-service-sensor_reporting"; | ||
100 | |||
101 | /** | ||
102 | * Name of GNUNET config file used in this test | ||
103 | */ | ||
104 | static const char *cfg_filename = "test_gnunet-service-sensor_reporting.conf"; | ||
105 | |||
106 | /** | ||
107 | * Test sensor name | ||
108 | */ | ||
109 | static const char *sensor_name = "test-sensor-statistics"; | ||
110 | |||
111 | /** | ||
112 | * Path to read test sensor from | ||
113 | */ | ||
114 | static const char *sensor_path_src = "test_sensors/test-sensor-statistics"; | ||
115 | |||
116 | /** | ||
117 | * Path to write new test sensor to | ||
118 | */ | ||
119 | static const char *sensor_path_dest = | ||
120 | "/tmp/test-gnunet-service-sensor-reporting/test-sensor-statistics"; | ||
121 | |||
122 | /** | ||
123 | * Head of DLL of peers | ||
124 | */ | ||
125 | static struct TestPeer *peer_head; | ||
126 | |||
127 | /** | ||
128 | * Tail of DLL of peers | ||
129 | */ | ||
130 | static struct TestPeer *peer_tail; | ||
131 | |||
132 | /** | ||
133 | * Number of peers started and got information for | ||
134 | */ | ||
135 | static int started_peers = 0; | ||
136 | |||
137 | /** | ||
138 | * Number of peers reported anomalies with full list of anomalous neighbors | ||
139 | */ | ||
140 | static int reported_peers = 0; | ||
141 | |||
142 | /** | ||
143 | * TESTBED operation connecting us to peerstore service | ||
144 | */ | ||
145 | static struct GNUNET_TESTBED_Operation *peerstore_op; | ||
146 | |||
147 | /** | ||
148 | * Handle to the peerstore service | ||
149 | */ | ||
150 | static struct GNUNET_PEERSTORE_Handle *peerstore; | ||
151 | |||
152 | /** | ||
153 | * Task used to shutdown / expire the test | ||
154 | */ | ||
155 | static struct GNUNET_SCHEDULER_Task * shutdown_task; | ||
156 | |||
157 | /** | ||
158 | * Status of the test to be returned by main() | ||
159 | */ | ||
160 | static int ok = 1; | ||
161 | |||
162 | |||
163 | static void | ||
164 | destroy_peer (struct TestPeer *peer) | ||
165 | { | ||
166 | if (NULL != peer->delay_task) | ||
167 | { | ||
168 | GNUNET_SCHEDULER_cancel (peer->delay_task); | ||
169 | peer->delay_task = NULL; | ||
170 | } | ||
171 | if (NULL != peer->sensor_op) | ||
172 | { | ||
173 | GNUNET_TESTBED_operation_done (peer->sensor_op); | ||
174 | peer->sensor_op = NULL; | ||
175 | } | ||
176 | if (NULL != peer->wc) | ||
177 | { | ||
178 | GNUNET_PEERSTORE_watch_cancel (peer->wc); | ||
179 | peer->wc = NULL; | ||
180 | } | ||
181 | GNUNET_free (peer); | ||
182 | } | ||
183 | |||
184 | |||
185 | /** | ||
186 | * Shutdown task | ||
187 | * | ||
188 | * @param cls Closure (unused) | ||
189 | * @param tc Task context (unused) | ||
190 | */ | ||
191 | static void | ||
192 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
193 | { | ||
194 | struct TestPeer *peer; | ||
195 | |||
196 | peer = peer_head; | ||
197 | while (NULL != peer) | ||
198 | { | ||
199 | GNUNET_CONTAINER_DLL_remove (peer_head, peer_tail, peer); | ||
200 | destroy_peer (peer); | ||
201 | peer = peer_head; | ||
202 | } | ||
203 | if (NULL != peerstore_op) | ||
204 | { | ||
205 | GNUNET_TESTBED_operation_done (peerstore_op); | ||
206 | peerstore_op = NULL; | ||
207 | } | ||
208 | GNUNET_SCHEDULER_shutdown (); | ||
209 | } | ||
210 | |||
211 | |||
212 | /** | ||
213 | * Write new temp sensor directory with a sensor updated with collection point | ||
214 | * peer id | ||
215 | */ | ||
216 | static void | ||
217 | write_new_sensor_dir (struct TestPeer *cp_peer) | ||
218 | { | ||
219 | struct GNUNET_CONFIGURATION_Handle *sensorcfg; | ||
220 | |||
221 | GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_test (sensor_path_src)); | ||
222 | sensorcfg = GNUNET_CONFIGURATION_create (); | ||
223 | GNUNET_assert (GNUNET_SYSERR != | ||
224 | GNUNET_CONFIGURATION_parse (sensorcfg, sensor_path_src)); | ||
225 | GNUNET_CONFIGURATION_set_value_string (sensorcfg, sensor_name, | ||
226 | "COLLECTION_POINT", | ||
227 | GNUNET_i2s_full (&cp_peer->peer_id)); | ||
228 | GNUNET_assert (GNUNET_OK == | ||
229 | GNUNET_DISK_directory_create_for_file (sensor_path_dest)); | ||
230 | GNUNET_CONFIGURATION_write (sensorcfg, sensor_path_dest); | ||
231 | GNUNET_CONFIGURATION_destroy (sensorcfg); | ||
232 | } | ||
233 | |||
234 | |||
235 | /** | ||
236 | * Function called by PEERSTORE for each matching record. | ||
237 | * | ||
238 | * @param cls closure | ||
239 | * @param record peerstore record information | ||
240 | * @param emsg error message, or NULL if no errors | ||
241 | * @return #GNUNET_YES to continue iterating, #GNUNET_NO to stop | ||
242 | */ | ||
243 | static int | ||
244 | peerstore_watch_cb (void *cls, | ||
245 | const struct GNUNET_PEERSTORE_Record *record, | ||
246 | const char *emsg) | ||
247 | { | ||
248 | struct TestPeer *peer = cls; | ||
249 | struct GNUNET_SENSOR_DashboardAnomalyEntry *anomaly; | ||
250 | |||
251 | GNUNET_assert (NULL != record); | ||
252 | GNUNET_assert (record->value_size == | ||
253 | sizeof (struct GNUNET_SENSOR_DashboardAnomalyEntry)); | ||
254 | anomaly = record->value; | ||
255 | GNUNET_assert (0 == | ||
256 | GNUNET_CRYPTO_cmp_peer_identity (&peer->peer_id, | ||
257 | record->peer)); | ||
258 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
259 | "Peerstore watch got an anomaly report from peer `%s':\n" | ||
260 | "Anomalous: %d\n" "Anomalous neigbors: %f.\n", | ||
261 | GNUNET_i2s (&peer->peer_id), anomaly->anomalous, | ||
262 | anomaly->anomalous_neighbors); | ||
263 | if (1 == anomaly->anomalous_neighbors) | ||
264 | reported_peers++; | ||
265 | if (reported_peers == NUM_PEERS) | ||
266 | { | ||
267 | ok = 0; | ||
268 | GNUNET_SCHEDULER_cancel (shutdown_task); | ||
269 | shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
270 | } | ||
271 | return GNUNET_YES; | ||
272 | } | ||
273 | |||
274 | |||
275 | /** | ||
276 | * Task that pushes fake anomalies to running peers | ||
277 | */ | ||
278 | static void | ||
279 | force_anomaly_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
280 | { | ||
281 | struct TestPeer *peer = cls; | ||
282 | |||
283 | peer->delay_task = NULL; | ||
284 | GNUNET_SENSOR_force_anomaly (peer->sensor, (char *) sensor_name, GNUNET_YES, | ||
285 | NULL, NULL); | ||
286 | } | ||
287 | |||
288 | |||
289 | /** | ||
290 | * Callback to be called when sensor service connect operation is completed | ||
291 | * | ||
292 | * @param cls the callback closure from functions generating an operation | ||
293 | * @param op the operation that has been finished | ||
294 | * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() | ||
295 | * @param emsg error message in case the operation has failed; will be NULL if | ||
296 | * operation has executed successfully. | ||
297 | */ | ||
298 | static void | ||
299 | sensor_connect_cb (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
300 | void *ca_result, const char *emsg) | ||
301 | { | ||
302 | struct TestPeer *peer = cls; | ||
303 | struct GNUNET_SENSOR_Handle *sensor = ca_result; | ||
304 | |||
305 | peer->sensor = sensor; | ||
306 | peer->delay_task = | ||
307 | GNUNET_SCHEDULER_add_delayed (ANOMALY_DELAY, &force_anomaly_task, peer); | ||
308 | } | ||
309 | |||
310 | |||
311 | /** | ||
312 | * Adapter function called to establish a connection to sensor service. | ||
313 | * | ||
314 | * @param cls closure | ||
315 | * @param cfg configuration of the peer to connect to; will be available until | ||
316 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
317 | * from GNUNET_TESTBED_service_connect() | ||
318 | * @return service handle to return in 'op_result', NULL on error | ||
319 | */ | ||
320 | static void * | ||
321 | sensor_connect_adapter (void *cls, | ||
322 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
323 | { | ||
324 | struct GNUNET_SENSOR_Handle *sensor; | ||
325 | |||
326 | sensor = GNUNET_SENSOR_connect (cfg); | ||
327 | return sensor; | ||
328 | } | ||
329 | |||
330 | |||
331 | /** | ||
332 | * Adapter function called to destroy a connection to sensor service. | ||
333 | * | ||
334 | * @param cls closure | ||
335 | * @param op_result service handle returned from the connect adapter | ||
336 | */ | ||
337 | static void | ||
338 | sensor_disconnect_adapter (void *cls, void *op_result) | ||
339 | { | ||
340 | struct GNUNET_SENSOR_Handle *sensor = op_result; | ||
341 | |||
342 | GNUNET_SENSOR_disconnect (sensor); | ||
343 | } | ||
344 | |||
345 | |||
346 | /** | ||
347 | * Callback to be called when sensor service is started | ||
348 | * | ||
349 | * @param cls the callback closure from functions generating an operation | ||
350 | * @param op the operation that has been finished | ||
351 | * @param emsg error message in case the operation has failed; will be NULL if | ||
352 | * operation has executed successfully. | ||
353 | */ | ||
354 | static void | ||
355 | sensor_service_started (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
356 | const char *emsg) | ||
357 | { | ||
358 | struct TestPeer *peer = cls; | ||
359 | |||
360 | if (NULL != emsg) | ||
361 | { | ||
362 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ERROR: %s.\n", emsg); | ||
363 | GNUNET_assert (0); | ||
364 | } | ||
365 | peer->sensor_op = | ||
366 | GNUNET_TESTBED_service_connect (NULL, peer->testbed_peer, "sensor", | ||
367 | &sensor_connect_cb, peer, | ||
368 | &sensor_connect_adapter, | ||
369 | &sensor_disconnect_adapter, NULL); | ||
370 | GNUNET_TESTBED_operation_done (op); | ||
371 | } | ||
372 | |||
373 | |||
374 | /** | ||
375 | * Callback to be called when peerstore service connect operation is completed | ||
376 | * | ||
377 | * @param cls the callback closure from functions generating an operation | ||
378 | * @param op the operation that has been finished | ||
379 | * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() | ||
380 | * @param emsg error message in case the operation has failed; will be NULL if | ||
381 | * operation has executed successfully. | ||
382 | */ | ||
383 | static void | ||
384 | peerstore_connect_cb (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
385 | void *ca_result, const char *emsg) | ||
386 | { | ||
387 | struct TestPeer *peer; | ||
388 | |||
389 | peer = peer_head; | ||
390 | while (NULL != peer) | ||
391 | { | ||
392 | GNUNET_PEERSTORE_watch (peerstore, "sensordashboard-anomalies", | ||
393 | &peer->peer_id, sensor_name, &peerstore_watch_cb, | ||
394 | peer); | ||
395 | /* Start sensor service */ | ||
396 | GNUNET_TESTBED_peer_manage_service (NULL, peer->testbed_peer, "sensor", | ||
397 | &sensor_service_started, peer, 1); | ||
398 | peer = peer->next; | ||
399 | } | ||
400 | } | ||
401 | |||
402 | |||
403 | /** | ||
404 | * Adapter function called to establish a connection to peerstore service. | ||
405 | * | ||
406 | * @param cls closure | ||
407 | * @param cfg configuration of the peer to connect to; will be available until | ||
408 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
409 | * from GNUNET_TESTBED_service_connect() | ||
410 | * @return service handle to return in 'op_result', NULL on error | ||
411 | */ | ||
412 | static void * | ||
413 | peerstore_connect_adapter (void *cls, | ||
414 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
415 | { | ||
416 | peerstore = GNUNET_PEERSTORE_connect (cfg); | ||
417 | GNUNET_assert (NULL != peerstore); | ||
418 | return peerstore; | ||
419 | } | ||
420 | |||
421 | |||
422 | /** | ||
423 | * Adapter function called to destroy a connection to peerstore service. | ||
424 | * | ||
425 | * @param cls closure | ||
426 | * @param op_result service handle returned from the connect adapter | ||
427 | */ | ||
428 | static void | ||
429 | peerstore_disconnect_adapter (void *cls, void *op_result) | ||
430 | { | ||
431 | GNUNET_PEERSTORE_disconnect (peerstore, GNUNET_NO); | ||
432 | peerstore = NULL; | ||
433 | peerstore_op = NULL; | ||
434 | } | ||
435 | |||
436 | |||
437 | /** | ||
438 | * Callback to be called when dashboard service is started | ||
439 | * | ||
440 | * @param cls the callback closure from functions generating an operation | ||
441 | * @param op the operation that has been finished | ||
442 | * @param emsg error message in case the operation has failed; will be NULL if | ||
443 | * operation has executed successfully. | ||
444 | */ | ||
445 | static void | ||
446 | dashboard_started (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
447 | const char *emsg) | ||
448 | { | ||
449 | if (NULL != emsg) | ||
450 | { | ||
451 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ERROR: %s.\n", emsg); | ||
452 | GNUNET_assert (0); | ||
453 | } | ||
454 | GNUNET_TESTBED_operation_done (op); | ||
455 | /* Connect to peerstore service on first peer */ | ||
456 | peerstore_op = | ||
457 | GNUNET_TESTBED_service_connect (NULL, peer_head->testbed_peer, | ||
458 | "peerstore", &peerstore_connect_cb, NULL, | ||
459 | &peerstore_connect_adapter, | ||
460 | &peerstore_disconnect_adapter, NULL); | ||
461 | } | ||
462 | |||
463 | |||
464 | /** | ||
465 | * Callback to be called when the requested peer information is available | ||
466 | * | ||
467 | * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information() | ||
468 | * @param op the operation this callback corresponds to | ||
469 | * @param pinfo the result; will be NULL if the operation has failed | ||
470 | * @param emsg error message if the operation has failed; will be NULL if the | ||
471 | * operation is successfull | ||
472 | */ | ||
473 | static void | ||
474 | peer_info_cb (void *cb_cls, struct GNUNET_TESTBED_Operation *op, | ||
475 | const struct GNUNET_TESTBED_PeerInformation *pinfo, | ||
476 | const char *emsg) | ||
477 | { | ||
478 | struct GNUNET_TESTBED_Peer *testbed_peer = cb_cls; | ||
479 | struct TestPeer *peer; | ||
480 | |||
481 | peer = GNUNET_new (struct TestPeer); | ||
482 | |||
483 | peer->testbed_peer = testbed_peer; | ||
484 | peer->delay_task = NULL; | ||
485 | GNUNET_CRYPTO_get_peer_identity (pinfo->result.cfg, &peer->peer_id); | ||
486 | if (NULL == peer_head) /* First peer (collection point) */ | ||
487 | { | ||
488 | /* Rewrite sensor with collection point peer id */ | ||
489 | write_new_sensor_dir (peer); | ||
490 | } | ||
491 | GNUNET_CONTAINER_DLL_insert_tail (peer_head, peer_tail, peer); | ||
492 | started_peers++; | ||
493 | if (NUM_PEERS == started_peers) | ||
494 | { | ||
495 | /* Start dashboard service on first peer */ | ||
496 | GNUNET_TESTBED_peer_manage_service (NULL, peer_head->testbed_peer, | ||
497 | "sensordashboard", &dashboard_started, | ||
498 | NULL, 1); | ||
499 | } | ||
500 | GNUNET_TESTBED_operation_done (op); | ||
501 | } | ||
502 | |||
503 | |||
504 | /** | ||
505 | * Signature of a main function for a testcase. | ||
506 | * | ||
507 | * @param cls closure | ||
508 | * @param h the run handle | ||
509 | * @param num_peers number of peers in 'peers' | ||
510 | * @param peers handle to peers run in the testbed. NULL upon timeout (see | ||
511 | * GNUNET_TESTBED_test_run()). | ||
512 | * @param links_succeeded the number of overlay link connection attempts that | ||
513 | * succeeded | ||
514 | * @param links_failed the number of overlay link connection attempts that | ||
515 | * failed | ||
516 | * @see GNUNET_TESTBED_test_run() | ||
517 | */ | ||
518 | static void | ||
519 | test_master (void *cls, struct GNUNET_TESTBED_RunHandle *h, | ||
520 | unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers, | ||
521 | unsigned int links_succeeded, unsigned int links_failed) | ||
522 | { | ||
523 | int i; | ||
524 | |||
525 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
526 | "%d peers started. %d links succeeded. %d links failed.\n", | ||
527 | num_peers, links_succeeded, links_failed); | ||
528 | GNUNET_assert (NUM_PEERS == num_peers); | ||
529 | GNUNET_assert (0 == links_failed); | ||
530 | /* Schedule test timeout */ | ||
531 | shutdown_task = | ||
532 | GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, &do_shutdown, NULL); | ||
533 | /* Collect peer information */ | ||
534 | for (i = 0; i < num_peers; i++) | ||
535 | { | ||
536 | GNUNET_TESTBED_peer_get_information (peers[i], | ||
537 | GNUNET_TESTBED_PIT_CONFIGURATION, | ||
538 | &peer_info_cb, peers[i]); | ||
539 | } | ||
540 | } | ||
541 | |||
542 | |||
543 | int | ||
544 | main (int argc, char *argv[]) | ||
545 | { | ||
546 | GNUNET_log_setup (testname, "INFO", NULL); | ||
547 | if (GNUNET_OK == | ||
548 | GNUNET_TESTBED_test_run (testname, cfg_filename, NUM_PEERS, 0, NULL, NULL, | ||
549 | &test_master, NULL)) | ||
550 | return ok; | ||
551 | return 1; | ||
552 | } | ||
diff --git a/src/sensor/test_gnunet-service-sensor_reporting.conf b/src/sensor/test_gnunet-service-sensor_reporting.conf deleted file mode 100644 index 119191f01..000000000 --- a/src/sensor/test_gnunet-service-sensor_reporting.conf +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | [testbed] | ||
2 | OVERLAY_TOPOLOGY = CLIQUE | ||
3 | |||
4 | [sensor] | ||
5 | #PREFIX = valgrind --leak-check=full | ||
6 | SENSOR_DIR = /tmp/test-gnunet-service-sensor-reporting/ | ||
7 | |||
8 | START_MONITORING = NO | ||
9 | START_REPORTING = YES | ||
10 | START_ANALYSIS = NO | ||
11 | START_UPDATE = NO | ||
12 | |||
13 | [sensor-reporting] | ||
14 | POW_MATCHING_BITS = 2 | ||
15 | |||
16 | [transport] | ||
17 | PLUGINS = unix | ||
18 | |||
19 | [nat] | ||
20 | USE_LOCALADDR = YES | ||
diff --git a/src/sensor/test_pow_sign.c b/src/sensor/test_pow_sign.c deleted file mode 100644 index 7f6689e72..000000000 --- a/src/sensor/test_pow_sign.c +++ /dev/null | |||
@@ -1,214 +0,0 @@ | |||
1 | /* | ||
2 | * This file is part of GNUnet. | ||
3 | * Copyright (C) | ||
4 | * | ||
5 | * GNUnet is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published | ||
7 | * by the Free Software Foundation; either version 3, or (at your | ||
8 | * 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 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with GNUnet; see the file COPYING. If not, write to the | ||
17 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | * Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file sensor/test_pow_sign.c | ||
22 | * @brief testcase for proof-of-work and signature library functions | ||
23 | */ | ||
24 | #include <inttypes.h> | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include "gnunet_sensor_util_lib.h" | ||
28 | #include "gnunet_testbed_service.h" | ||
29 | #include "gnunet_signatures.h" | ||
30 | |||
31 | /** | ||
32 | * Number of peers to start for the test | ||
33 | */ | ||
34 | #define NUM_PEERS 1 | ||
35 | |||
36 | /** | ||
37 | * Size of the message exchanged | ||
38 | */ | ||
39 | #define MSG_SIZE 1024 | ||
40 | |||
41 | /** | ||
42 | * Number of matching bits to use for generating proof-of-work | ||
43 | */ | ||
44 | #define MATCHING_BITS 5 | ||
45 | |||
46 | /** | ||
47 | * Test timeout | ||
48 | */ | ||
49 | #define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1) | ||
50 | |||
51 | /** | ||
52 | * Test name | ||
53 | */ | ||
54 | static const char *testname = "test_pow_sign"; | ||
55 | |||
56 | /** | ||
57 | * Name of GNUNET config file used in this test | ||
58 | */ | ||
59 | static const char *cfg_filename = "test_pow_sign.conf"; | ||
60 | |||
61 | /** | ||
62 | * Status of the test to be returned by main() | ||
63 | */ | ||
64 | static int ok = 1; | ||
65 | |||
66 | /** | ||
67 | * Task used to shutdown / expire the test | ||
68 | */ | ||
69 | static struct GNUNET_SCHEDULER_Task * shutdown_task; | ||
70 | |||
71 | /** | ||
72 | * Message to be exchanged | ||
73 | */ | ||
74 | static char msg[MSG_SIZE]; | ||
75 | |||
76 | /** | ||
77 | * Private key of sending peer | ||
78 | */ | ||
79 | static struct GNUNET_CRYPTO_EddsaPrivateKey *private_key; | ||
80 | |||
81 | /** | ||
82 | * Public key of sending peer | ||
83 | */ | ||
84 | static struct GNUNET_CRYPTO_EddsaPublicKey *public_key; | ||
85 | |||
86 | |||
87 | /** | ||
88 | * Shutdown task | ||
89 | * | ||
90 | * @param cls Closure (unused) | ||
91 | * @param tc Task context (unused) | ||
92 | */ | ||
93 | static void | ||
94 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
95 | { | ||
96 | if (NULL != private_key) | ||
97 | { | ||
98 | GNUNET_free (private_key); | ||
99 | private_key = NULL; | ||
100 | } | ||
101 | if (NULL != public_key) | ||
102 | { | ||
103 | GNUNET_free (public_key); | ||
104 | public_key = NULL; | ||
105 | } | ||
106 | GNUNET_SCHEDULER_shutdown (); | ||
107 | } | ||
108 | |||
109 | |||
110 | static void | ||
111 | pow_cb (void *cls, struct GNUNET_SENSOR_crypto_pow_block *block) | ||
112 | { | ||
113 | void *response; | ||
114 | struct GNUNET_TIME_Absolute end_time; | ||
115 | struct GNUNET_TIME_Relative duration; | ||
116 | |||
117 | end_time = GNUNET_TIME_absolute_get(); | ||
118 | duration = GNUNET_TIME_absolute_get_difference (block->timestamp, end_time); | ||
119 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
120 | "Received block:\n" "pow: %" PRIu64 ".\n", block->pow); | ||
121 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Block generation toke %s.\n", | ||
122 | GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_NO)); | ||
123 | /* Test that the block is valid */ | ||
124 | GNUNET_assert (MSG_SIZE == | ||
125 | GNUNET_SENSOR_crypto_verify_pow_sign (block, MATCHING_BITS, | ||
126 | public_key, &response)); | ||
127 | GNUNET_assert (0 == memcmp (msg, response, MSG_SIZE)); | ||
128 | /* Modify the payload and test that verification returns invalid */ | ||
129 | block->pow++; | ||
130 | GNUNET_assert (0 == | ||
131 | GNUNET_SENSOR_crypto_verify_pow_sign (block, MATCHING_BITS, | ||
132 | public_key, &response)); | ||
133 | ok = 0; | ||
134 | GNUNET_SCHEDULER_cancel (shutdown_task); | ||
135 | GNUNET_SCHEDULER_add_now (do_shutdown, NULL); | ||
136 | } | ||
137 | |||
138 | |||
139 | /** | ||
140 | * Callback to be called when the requested peer information is available | ||
141 | * | ||
142 | * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information() | ||
143 | * @param op the operation this callback corresponds to | ||
144 | * @param pinfo the result; will be NULL if the operation has failed | ||
145 | * @param emsg error message if the operation has failed; will be NULL if the | ||
146 | * operation is successfull | ||
147 | */ | ||
148 | static void | ||
149 | peer_info_cb (void *cb_cls, struct GNUNET_TESTBED_Operation *op, | ||
150 | const struct GNUNET_TESTBED_PeerInformation *pinfo, | ||
151 | const char *emsg) | ||
152 | { | ||
153 | struct GNUNET_TIME_Absolute timestamp; | ||
154 | |||
155 | /* generate random data block */ | ||
156 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, msg, MSG_SIZE); | ||
157 | /* get private and public keys */ | ||
158 | private_key = | ||
159 | GNUNET_CRYPTO_eddsa_key_create_from_configuration (pinfo->result.cfg); | ||
160 | GNUNET_assert (NULL != private_key); | ||
161 | public_key = GNUNET_new (struct GNUNET_CRYPTO_EddsaPublicKey); | ||
162 | |||
163 | GNUNET_CRYPTO_eddsa_key_get_public (private_key, public_key); | ||
164 | /* create pow and sign */ | ||
165 | timestamp = GNUNET_TIME_absolute_get (); | ||
166 | GNUNET_SENSOR_crypto_pow_sign (msg, MSG_SIZE, ×tamp, public_key, | ||
167 | private_key, MATCHING_BITS, &pow_cb, NULL); | ||
168 | GNUNET_TESTBED_operation_done (op); | ||
169 | } | ||
170 | |||
171 | |||
172 | /** | ||
173 | * Signature of a main function for a testcase. | ||
174 | * | ||
175 | * @param cls closure | ||
176 | * @param h the run handle | ||
177 | * @param num_peers number of peers in 'peers' | ||
178 | * @param peers handle to peers run in the testbed. NULL upon timeout (see | ||
179 | * GNUNET_TESTBED_test_run()). | ||
180 | * @param links_succeeded the number of overlay link connection attempts that | ||
181 | * succeeded | ||
182 | * @param links_failed the number of overlay link connection attempts that | ||
183 | * failed | ||
184 | * @see GNUNET_TESTBED_test_run() | ||
185 | */ | ||
186 | static void | ||
187 | test_master (void *cls, struct GNUNET_TESTBED_RunHandle *h, | ||
188 | unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers, | ||
189 | unsigned int links_succeeded, unsigned int links_failed) | ||
190 | { | ||
191 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
192 | "%d peers started. %d links succeeded. %d links failed.\n", | ||
193 | num_peers, links_succeeded, links_failed); | ||
194 | GNUNET_assert (NUM_PEERS == num_peers); | ||
195 | GNUNET_assert (0 == links_failed); | ||
196 | /* Schedule test timeout */ | ||
197 | shutdown_task = | ||
198 | GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, &do_shutdown, NULL); | ||
199 | GNUNET_TESTBED_peer_get_information (peers[0], | ||
200 | GNUNET_TESTBED_PIT_CONFIGURATION, | ||
201 | &peer_info_cb, peers[0]); | ||
202 | } | ||
203 | |||
204 | |||
205 | int | ||
206 | main (int argc, char *argv[]) | ||
207 | { | ||
208 | GNUNET_log_setup (testname, "INFO", NULL); | ||
209 | if (GNUNET_OK == | ||
210 | GNUNET_TESTBED_test_run (testname, cfg_filename, NUM_PEERS, 0, NULL, NULL, | ||
211 | &test_master, NULL)) | ||
212 | return ok; | ||
213 | return 1; | ||
214 | } | ||
diff --git a/src/sensor/test_pow_sign.conf b/src/sensor/test_pow_sign.conf deleted file mode 100644 index e69de29bb..000000000 --- a/src/sensor/test_pow_sign.conf +++ /dev/null | |||
diff --git a/src/sensor/test_sensor_api.c b/src/sensor/test_sensor_api.c deleted file mode 100644 index 8f7dbd598..000000000 --- a/src/sensor/test_sensor_api.c +++ /dev/null | |||
@@ -1,82 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file sensor/test_sensor_api.c | ||
22 | * @brief testcase for sensor_api.c | ||
23 | */ | ||
24 | #include "platform.h" | ||
25 | #include "gnunet_util_lib.h" | ||
26 | #include "gnunet_sensor_service.h" | ||
27 | |||
28 | //FIXME: | ||
29 | static int ok = 1; | ||
30 | |||
31 | |||
32 | static void | ||
33 | run (void *cls, char *const *args, const char *cfgfile, | ||
34 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
35 | { | ||
36 | ok = 0; | ||
37 | } | ||
38 | |||
39 | |||
40 | static int | ||
41 | check () | ||
42 | { | ||
43 | char *const argv[] = { "test-sensor-api", NULL }; | ||
44 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
45 | GNUNET_GETOPT_OPTION_END | ||
46 | }; | ||
47 | struct GNUNET_OS_Process *proc; | ||
48 | char *path = GNUNET_OS_get_libexec_binary_path ("gnunet-service-sensor"); | ||
49 | |||
50 | if (NULL == path) | ||
51 | { | ||
52 | fprintf (stderr, "Service executable not found `%s'\n", | ||
53 | "gnunet-service-sensor"); | ||
54 | return -1; | ||
55 | } | ||
56 | |||
57 | proc = | ||
58 | GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL, NULL, | ||
59 | NULL, path, "gnunet-service-sensor", NULL); | ||
60 | |||
61 | GNUNET_free (path); | ||
62 | GNUNET_assert (NULL != proc); | ||
63 | GNUNET_PROGRAM_run (1, argv, "test-sensor-api", "nohelp", options, &run, &ok); | ||
64 | if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) | ||
65 | { | ||
66 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | ||
67 | ok = 1; | ||
68 | } | ||
69 | GNUNET_OS_process_wait (proc); | ||
70 | GNUNET_OS_process_destroy (proc); | ||
71 | return ok; | ||
72 | } | ||
73 | |||
74 | |||
75 | int | ||
76 | main (int argc, char *argv[]) | ||
77 | { | ||
78 | GNUNET_log_setup ("test_statistics_api", "WARNING", NULL); | ||
79 | return check (); | ||
80 | } | ||
81 | |||
82 | /* end of test_sensor_api.c */ | ||
diff --git a/src/sensor/test_sensors/test-sensor-statistics b/src/sensor/test_sensors/test-sensor-statistics deleted file mode 100644 index 578907e67..000000000 --- a/src/sensor/test_sensors/test-sensor-statistics +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | [test-sensor-statistics] | ||
2 | |||
3 | VERSION = 1.0 | ||
4 | DESCRIPTION = Test sensor for collecting data from gnunet-statistics | ||
5 | CATEGORY = GNUnet | ||
6 | ENABLED = YES | ||
7 | |||
8 | # Start and end time format: %Y-%m-%d %H:%M:%S | ||
9 | #START_TIME = | ||
10 | #END_TIME = | ||
11 | #Interval in seconds | ||
12 | INTERVAL = 60 | ||
13 | #LIFETIME = | ||
14 | |||
15 | #CAPABILITIES = | ||
16 | |||
17 | SOURCE = gnunet-statistics | ||
18 | |||
19 | GNUNET_STAT_SERVICE = test-sensor | ||
20 | GNUNET_STAT_NAME = test-statistic | ||
21 | |||
22 | #EXT_PROCESS = | ||
23 | #EXT_ARGS = | ||
24 | |||
25 | EXPECTED_DATATYPE = numeric | ||
26 | |||
27 | # Reporting: | ||
28 | #COLLECTION_POINT = NCEKA096482PC84GFTG61EHAVXY3BQDTPB5FANATQD5CDADJ2HP0 | ||
29 | # Comment or remove next line to disable reporting sensor values to collection point | ||
30 | #VALUE_COLLECTION_INTERVAL = 120 | ||
31 | REPORT_ANOMALIES = YES | ||
diff --git a/src/sensordashboard/Makefile.am b/src/sensordashboard/Makefile.am deleted file mode 100644 index 563dfdab5..000000000 --- a/src/sensordashboard/Makefile.am +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | # 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 | dist_pkgcfg_DATA = \ | ||
9 | sensordashboard.conf | ||
10 | |||
11 | if MINGW | ||
12 | WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols | ||
13 | endif | ||
14 | |||
15 | if USE_COVERAGE | ||
16 | AM_CFLAGS = -fprofile-arcs -ftest-coverage | ||
17 | endif | ||
18 | |||
19 | bin_PROGRAMS = \ | ||
20 | gnunet-sensordashboard | ||
21 | |||
22 | libexec_PROGRAMS = \ | ||
23 | gnunet-service-sensordashboard | ||
24 | |||
25 | gnunet_sensordashboard_SOURCES = \ | ||
26 | gnunet-sensordashboard.c | ||
27 | gnunet_sensordashboard_LDADD = \ | ||
28 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
29 | $(GN_LIBINTL) | ||
30 | |||
31 | gnunet_service_sensordashboard_SOURCES = \ | ||
32 | gnunet-service-sensordashboard.c | ||
33 | gnunet_service_sensordashboard_LDADD = \ | ||
34 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
35 | $(top_builddir)/src/cadet/libgnunetcadet.la \ | ||
36 | $(top_builddir)/src/sensor/libgnunetsensorutil.la \ | ||
37 | $(top_builddir)/src/peerstore/libgnunetpeerstore.la \ | ||
38 | $(GN_LIBINTL) | ||
39 | |||
40 | |||
41 | check_PROGRAMS = \ | ||
42 | test_sensordashboard_api | ||
43 | |||
44 | if ENABLE_TEST_RUN | ||
45 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; | ||
46 | TESTS = $(check_PROGRAMS) | ||
47 | endif | ||
48 | |||
49 | test_sensordashboard_api_SOURCES = \ | ||
50 | test_sensordashboard_api.c | ||
51 | test_sensordashboard_api_LDADD = \ | ||
52 | $(top_builddir)/src/util/libgnunetutil.la | ||
53 | |||
diff --git a/src/sensordashboard/gnunet-sensordashboard.c b/src/sensordashboard/gnunet-sensordashboard.c deleted file mode 100644 index 9f85a25e4..000000000 --- a/src/sensordashboard/gnunet-sensordashboard.c +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensordashboard/gnunet-sensordashboard.c | ||
23 | * @brief sensor dashboard tool | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | |||
29 | /** | ||
30 | * Final status code. | ||
31 | */ | ||
32 | static int ret; | ||
33 | |||
34 | /** | ||
35 | * Main function that will be run by the scheduler. | ||
36 | * | ||
37 | * @param cls closure | ||
38 | * @param args remaining command-line arguments | ||
39 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
40 | * @param cfg configuration | ||
41 | */ | ||
42 | static void | ||
43 | run (void *cls, char *const *args, const char *cfgfile, | ||
44 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
45 | { | ||
46 | /* main code here */ | ||
47 | } | ||
48 | |||
49 | |||
50 | /** | ||
51 | * The main function. | ||
52 | * | ||
53 | * @param argc number of arguments from the command line | ||
54 | * @param argv command line arguments | ||
55 | * @return 0 ok, 1 on error | ||
56 | */ | ||
57 | int | ||
58 | main (int argc, char *const *argv) | ||
59 | { | ||
60 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
61 | /* FIMXE: add options here */ | ||
62 | GNUNET_GETOPT_OPTION_END | ||
63 | }; | ||
64 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | ||
65 | return 2; | ||
66 | |||
67 | ret = | ||
68 | (GNUNET_OK == | ||
69 | GNUNET_PROGRAM_run (argc, argv, "gnunet-sensordashboard", | ||
70 | gettext_noop ("help text"), options, &run, | ||
71 | NULL)) ? ret : 1; | ||
72 | GNUNET_free ((void *) argv); | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | /* end of gnunet-sensordashboard.c */ | ||
diff --git a/src/sensordashboard/gnunet-service-sensordashboard.c b/src/sensordashboard/gnunet-service-sensordashboard.c deleted file mode 100644 index 3b15aaff3..000000000 --- a/src/sensordashboard/gnunet-service-sensordashboard.c +++ /dev/null | |||
@@ -1,897 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file sensordashboard/gnunet-service-sensordashboard.c | ||
23 | * @brief Service collecting sensor readings from peers | ||
24 | * @author Omar Tarabai | ||
25 | */ | ||
26 | #include <inttypes.h> | ||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_applications.h" | ||
30 | #include "sensordashboard.h" | ||
31 | #include "gnunet_cadet_service.h" | ||
32 | #include "gnunet_sensor_util_lib.h" | ||
33 | #include "gnunet_peerstore_service.h" | ||
34 | |||
35 | |||
36 | /** | ||
37 | * Context of a connected client peer | ||
38 | */ | ||
39 | struct ClientPeerContext | ||
40 | { | ||
41 | |||
42 | /** | ||
43 | * DLL | ||
44 | */ | ||
45 | struct ClientPeerContext *prev; | ||
46 | |||
47 | /* | ||
48 | * DLL | ||
49 | */ | ||
50 | struct ClientPeerContext *next; | ||
51 | |||
52 | /** | ||
53 | * GNUnet Peer identity | ||
54 | */ | ||
55 | struct GNUNET_PeerIdentity peerid; | ||
56 | |||
57 | /** | ||
58 | * Handle to the cadet channel | ||
59 | */ | ||
60 | struct GNUNET_CADET_Channel *ch; | ||
61 | |||
62 | /** | ||
63 | * CADET transmit handle if we requested a transmission | ||
64 | */ | ||
65 | struct GNUNET_CADET_TransmitHandle *th; | ||
66 | |||
67 | /** | ||
68 | * Head of DLL of pending messages to be sent to client | ||
69 | */ | ||
70 | struct PendingMessage *pm_head; | ||
71 | |||
72 | /** | ||
73 | * Tail of DLL of pending messages to be sent to client | ||
74 | */ | ||
75 | struct PendingMessage *pm_tail; | ||
76 | |||
77 | /** | ||
78 | * Are we in the process of destroying this context? | ||
79 | */ | ||
80 | int destroying; | ||
81 | |||
82 | }; | ||
83 | |||
84 | /** | ||
85 | * Message queued to be sent to a client stored in a DLL | ||
86 | */ | ||
87 | struct PendingMessage | ||
88 | { | ||
89 | |||
90 | /** | ||
91 | * DLL | ||
92 | */ | ||
93 | struct PendingMessage *prev; | ||
94 | |||
95 | /** | ||
96 | * DLL | ||
97 | */ | ||
98 | struct PendingMessage *next; | ||
99 | |||
100 | /** | ||
101 | * Actual queued message | ||
102 | */ | ||
103 | struct GNUNET_MessageHeader *msg; | ||
104 | |||
105 | }; | ||
106 | |||
107 | /** | ||
108 | * Carries a single reading from a sensor | ||
109 | */ | ||
110 | struct ClientSensorReading | ||
111 | { | ||
112 | |||
113 | /** | ||
114 | * Sensor this reading is related to | ||
115 | */ | ||
116 | struct GNUNET_SENSOR_SensorInfo *sensor; | ||
117 | |||
118 | /** | ||
119 | * Timestamp of taking the reading | ||
120 | */ | ||
121 | struct GNUNET_TIME_Absolute timestamp; | ||
122 | |||
123 | /** | ||
124 | * Reading value | ||
125 | */ | ||
126 | void *value; | ||
127 | |||
128 | /** | ||
129 | * Size of @e value | ||
130 | */ | ||
131 | uint16_t value_size; | ||
132 | |||
133 | }; | ||
134 | |||
135 | |||
136 | /** | ||
137 | * Path to sensor definition directory | ||
138 | */ | ||
139 | static char *sensor_dir; | ||
140 | |||
141 | /** | ||
142 | * Global hashmap of defined sensors | ||
143 | */ | ||
144 | static struct GNUNET_CONTAINER_MultiHashMap *sensors; | ||
145 | |||
146 | /** | ||
147 | * Handle to CADET service | ||
148 | */ | ||
149 | static struct GNUNET_CADET_Handle *cadet; | ||
150 | |||
151 | /** | ||
152 | * Handle to the peerstore service connection | ||
153 | */ | ||
154 | static struct GNUNET_PEERSTORE_Handle *peerstore; | ||
155 | |||
156 | /** | ||
157 | * Name of the subsystem used to store sensor values received from remote peers | ||
158 | * in PEERSTORE | ||
159 | */ | ||
160 | static char *values_subsystem = "sensordashboard-values"; | ||
161 | |||
162 | /** | ||
163 | * Name of the subsystem used to store anomaly reports received from remote | ||
164 | * peers in PEERSTORE | ||
165 | */ | ||
166 | static char *anomalies_subsystem = "sensordashboard-anomalies"; | ||
167 | |||
168 | /** | ||
169 | * Head of a DLL of all connected client peers | ||
170 | */ | ||
171 | static struct ClientPeerContext *cp_head; | ||
172 | |||
173 | /** | ||
174 | * Tail of a DLL of all connected client peers | ||
175 | */ | ||
176 | static struct ClientPeerContext *cp_tail; | ||
177 | |||
178 | /** | ||
179 | * Parameter that defines the complexity of the proof-of-work | ||
180 | */ | ||
181 | static long long unsigned int pow_matching_bits; | ||
182 | |||
183 | |||
184 | /** | ||
185 | * Trigger sending next pending message to the given client peer if any. | ||
186 | * | ||
187 | * @param cp client peer context struct | ||
188 | */ | ||
189 | static void | ||
190 | trigger_send_next_msg (struct ClientPeerContext *cp); | ||
191 | |||
192 | |||
193 | /** | ||
194 | * Destroy a given client peer context | ||
195 | * | ||
196 | * @param cp client peer context | ||
197 | */ | ||
198 | static void | ||
199 | destroy_clientpeer (struct ClientPeerContext *cp) | ||
200 | { | ||
201 | struct PendingMessage *pm; | ||
202 | |||
203 | cp->destroying = GNUNET_YES; | ||
204 | if (NULL != cp->th) | ||
205 | { | ||
206 | GNUNET_CADET_notify_transmit_ready_cancel (cp->th); | ||
207 | cp->th = NULL; | ||
208 | } | ||
209 | pm = cp->pm_head; | ||
210 | while (NULL != pm) | ||
211 | { | ||
212 | GNUNET_CONTAINER_DLL_remove (cp->pm_head, cp->pm_tail, pm); | ||
213 | GNUNET_free (pm->msg); | ||
214 | GNUNET_free (pm); | ||
215 | pm = cp->pm_head; | ||
216 | } | ||
217 | if (NULL != cp->ch) | ||
218 | { | ||
219 | GNUNET_CADET_channel_destroy (cp->ch); | ||
220 | cp->ch = NULL; | ||
221 | } | ||
222 | GNUNET_free (cp); | ||
223 | } | ||
224 | |||
225 | |||
226 | /** | ||
227 | * Task run during shutdown. | ||
228 | * | ||
229 | * @param cls unused | ||
230 | * @param tc unused | ||
231 | */ | ||
232 | static void | ||
233 | cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
234 | { | ||
235 | struct ClientPeerContext *cp; | ||
236 | |||
237 | cp = cp_head; | ||
238 | while (NULL != cp) | ||
239 | { | ||
240 | GNUNET_CONTAINER_DLL_remove (cp_head, cp_tail, cp); | ||
241 | destroy_clientpeer (cp); | ||
242 | cp = cp_head; | ||
243 | } | ||
244 | if (NULL != cadet) | ||
245 | { | ||
246 | GNUNET_CADET_disconnect (cadet); | ||
247 | cadet = NULL; | ||
248 | } | ||
249 | if (NULL != peerstore) | ||
250 | { | ||
251 | GNUNET_PEERSTORE_disconnect (peerstore, GNUNET_YES); | ||
252 | peerstore = NULL; | ||
253 | } | ||
254 | GNUNET_SENSOR_destroy_sensors (sensors); | ||
255 | if (NULL != sensor_dir) | ||
256 | { | ||
257 | GNUNET_free (sensor_dir); | ||
258 | sensor_dir = NULL; | ||
259 | } | ||
260 | GNUNET_SCHEDULER_shutdown (); | ||
261 | } | ||
262 | |||
263 | |||
264 | /** | ||
265 | * Function called whenever a channel is destroyed. Should clean up | ||
266 | * any associated state. | ||
267 | * | ||
268 | * It must NOT call #GNUNET_CADET_channel_destroy on the channel. | ||
269 | * | ||
270 | * @param cls closure (set from #GNUNET_CADET_connect) | ||
271 | * @param channel connection to the other end (henceforth invalid) | ||
272 | * @param channel_ctx place where local state associated | ||
273 | * with the channel is stored | ||
274 | */ | ||
275 | static void | ||
276 | cadet_channel_destroyed (void *cls, const struct GNUNET_CADET_Channel *channel, | ||
277 | void *channel_ctx) | ||
278 | { | ||
279 | struct ClientPeerContext *cp = channel_ctx; | ||
280 | |||
281 | if (GNUNET_YES == cp->destroying) | ||
282 | return; | ||
283 | cp->ch = NULL; | ||
284 | GNUNET_CONTAINER_DLL_remove (cp_head, cp_tail, cp); | ||
285 | destroy_clientpeer (cp); | ||
286 | } | ||
287 | |||
288 | |||
289 | /** | ||
290 | * Method called whenever another peer has added us to a channel | ||
291 | * the other peer initiated. | ||
292 | * Only called (once) upon reception of data with a message type which was | ||
293 | * subscribed to in #GNUNET_CADET_connect. | ||
294 | * | ||
295 | * A call to #GNUNET_CADET_channel_destroy causes the channel to be ignored. In | ||
296 | * this case the handler MUST return NULL. | ||
297 | * | ||
298 | * @param cls closure | ||
299 | * @param channel new handle to the channel | ||
300 | * @param initiator peer that started the channel | ||
301 | * @param port Port this channel is for. | ||
302 | * @param options CadetOption flag field, with all active option bits set to 1. | ||
303 | * | ||
304 | * @return initial channel context for the channel | ||
305 | * (can be NULL -- that's not an error) | ||
306 | */ | ||
307 | static void * | ||
308 | cadet_channel_created (void *cls, struct GNUNET_CADET_Channel *channel, | ||
309 | const struct GNUNET_PeerIdentity *initiator, | ||
310 | uint32_t port, enum GNUNET_CADET_ChannelOption options) | ||
311 | { | ||
312 | struct ClientPeerContext *cp; | ||
313 | |||
314 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
315 | "Received a channel connection from peer `%s'.\n", | ||
316 | GNUNET_i2s (initiator)); | ||
317 | cp = GNUNET_new (struct ClientPeerContext); | ||
318 | |||
319 | cp->peerid = *initiator; | ||
320 | cp->ch = channel; | ||
321 | cp->destroying = GNUNET_NO; | ||
322 | GNUNET_CONTAINER_DLL_insert (cp_head, cp_tail, cp); | ||
323 | return cp; | ||
324 | } | ||
325 | |||
326 | |||
327 | /** | ||
328 | * Function called to notify a client about the connection begin ready | ||
329 | * to queue more data. @a buf will be NULL and @a size zero if the | ||
330 | * connection was closed for writing in the meantime. | ||
331 | * | ||
332 | * Perform the actual sending of the message to client peer. | ||
333 | * | ||
334 | * @param cls closure, a `struct ClientPeerContext *` | ||
335 | * @param size number of bytes available in @a buf | ||
336 | * @param buf where the callee should write the message | ||
337 | * @return number of bytes written to @a buf | ||
338 | */ | ||
339 | static size_t | ||
340 | do_send_msg (void *cls, size_t size, void *buf) | ||
341 | { | ||
342 | struct ClientPeerContext *cp = cls; | ||
343 | struct PendingMessage *pm; | ||
344 | size_t msg_size; | ||
345 | |||
346 | cp->th = NULL; | ||
347 | pm = cp->pm_head; | ||
348 | msg_size = ntohs (pm->msg->size); | ||
349 | GNUNET_CONTAINER_DLL_remove (cp->pm_head, cp->pm_tail, pm); | ||
350 | if (NULL == buf || size < msg_size) | ||
351 | { | ||
352 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
353 | _("Error trying to send a message to peer `%s'.\n"), | ||
354 | GNUNET_i2s (&cp->peerid)); | ||
355 | return 0; | ||
356 | } | ||
357 | memcpy (buf, pm->msg, msg_size); | ||
358 | GNUNET_free (pm->msg); | ||
359 | GNUNET_free (pm); | ||
360 | trigger_send_next_msg (cp); | ||
361 | return msg_size; | ||
362 | } | ||
363 | |||
364 | |||
365 | /** | ||
366 | * Trigger sending next pending message to the given client peer if any. | ||
367 | * | ||
368 | * @param cp client peer context struct | ||
369 | */ | ||
370 | static void | ||
371 | trigger_send_next_msg (struct ClientPeerContext *cp) | ||
372 | { | ||
373 | struct PendingMessage *pm; | ||
374 | |||
375 | if (NULL == cp->pm_head) | ||
376 | return; | ||
377 | if (NULL != cp->th) | ||
378 | return; | ||
379 | pm = cp->pm_head; | ||
380 | cp->th = | ||
381 | GNUNET_CADET_notify_transmit_ready (cp->ch, GNUNET_YES, | ||
382 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
383 | ntohs (pm->msg->size), &do_send_msg, | ||
384 | cp); | ||
385 | } | ||
386 | |||
387 | |||
388 | /** | ||
389 | * Add a new message to the queue to be sent to the given client peer. | ||
390 | * | ||
391 | * @param msg Message to be queued | ||
392 | * @param cp Client peer context | ||
393 | */ | ||
394 | static void | ||
395 | queue_msg (struct GNUNET_MessageHeader *msg, struct ClientPeerContext *cp) | ||
396 | { | ||
397 | struct PendingMessage *pm; | ||
398 | |||
399 | pm = GNUNET_new (struct PendingMessage); | ||
400 | |||
401 | pm->msg = msg; | ||
402 | GNUNET_CONTAINER_DLL_insert_tail (cp->pm_head, cp->pm_tail, pm); | ||
403 | trigger_send_next_msg (cp); | ||
404 | } | ||
405 | |||
406 | |||
407 | /** | ||
408 | * Called with any anomaly report received from a peer. | ||
409 | * | ||
410 | * Each time the function must call #GNUNET_CADET_receive_done on the channel | ||
411 | * in order to receive the next message. This doesn't need to be immediate: | ||
412 | * can be delayed if some processing is done on the message. | ||
413 | * | ||
414 | * @param cls Closure (set from #GNUNET_CADET_connect). | ||
415 | * @param channel Connection to the other end. | ||
416 | * @param channel_ctx Place to store local state associated with the channel. | ||
417 | * @param message The actual message. | ||
418 | * @return #GNUNET_OK to keep the channel open, | ||
419 | * #GNUNET_SYSERR to close it (signal serious error). | ||
420 | */ | ||
421 | static int | ||
422 | handle_anomaly_report (void *cls, struct GNUNET_CADET_Channel *channel, | ||
423 | void **channel_ctx, | ||
424 | const struct GNUNET_MessageHeader *message) | ||
425 | { | ||
426 | struct ClientPeerContext *cp = *channel_ctx; | ||
427 | struct GNUNET_SENSOR_crypto_pow_block *report_block; | ||
428 | struct GNUNET_SENSOR_AnomalyReportMessage *anomaly_msg; | ||
429 | struct GNUNET_SENSOR_SensorInfo *sensor; | ||
430 | struct GNUNET_SENSOR_DashboardAnomalyEntry *anomaly_entry; | ||
431 | struct GNUNET_TIME_Absolute expiry; | ||
432 | |||
433 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
434 | "Received an anomaly report message from peer `%s'.\n", | ||
435 | GNUNET_i2s (&cp->peerid)); | ||
436 | report_block = (struct GNUNET_SENSOR_crypto_pow_block *) &message[1]; | ||
437 | if (sizeof (struct GNUNET_SENSOR_AnomalyReportMessage) != | ||
438 | GNUNET_SENSOR_crypto_verify_pow_sign (report_block, pow_matching_bits, | ||
439 | &cp->peerid.public_key, | ||
440 | (void **) &anomaly_msg)) | ||
441 | { | ||
442 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
443 | "Received invalid anomaly report from peer `%s'.\n", | ||
444 | GNUNET_i2s (&cp->peerid)); | ||
445 | GNUNET_break_op (0); | ||
446 | return GNUNET_SYSERR; | ||
447 | } | ||
448 | sensor = | ||
449 | GNUNET_CONTAINER_multihashmap_get (sensors, | ||
450 | &anomaly_msg->sensorname_hash); | ||
451 | if (NULL == sensor) | ||
452 | { | ||
453 | GNUNET_break_op (0); | ||
454 | return GNUNET_SYSERR; | ||
455 | } | ||
456 | anomaly_entry = GNUNET_new (struct GNUNET_SENSOR_DashboardAnomalyEntry); | ||
457 | anomaly_entry->anomalous = ntohs (anomaly_msg->anomalous); | ||
458 | anomaly_entry->anomalous_neighbors = anomaly_msg->anomalous_neighbors; | ||
459 | expiry = | ||
460 | (GNUNET_YES == | ||
461 | anomaly_entry->anomalous) ? GNUNET_TIME_UNIT_FOREVER_ABS : | ||
462 | GNUNET_TIME_absolute_get (); | ||
463 | GNUNET_PEERSTORE_store (peerstore, anomalies_subsystem, &cp->peerid, | ||
464 | sensor->name, anomaly_entry, | ||
465 | sizeof (struct GNUNET_SENSOR_DashboardAnomalyEntry), | ||
466 | expiry, GNUNET_PEERSTORE_STOREOPTION_REPLACE, NULL, | ||
467 | NULL); | ||
468 | GNUNET_free (anomaly_entry); | ||
469 | GNUNET_CADET_receive_done (channel); | ||
470 | return GNUNET_OK; | ||
471 | } | ||
472 | |||
473 | |||
474 | /** | ||
475 | * Iterate over defined sensors, creates and sends brief sensor information to | ||
476 | * given client peer over CADET. | ||
477 | * | ||
478 | * @param cls closure, the client peer | ||
479 | * @param key sensor key | ||
480 | * @param value sensor value | ||
481 | * @return #GNUNET_YES to continue iteration | ||
482 | */ | ||
483 | static int | ||
484 | send_sensor_brief (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
485 | { | ||
486 | struct ClientPeerContext *cp = cls; | ||
487 | struct GNUNET_SENSOR_SensorInfo *sensor = value; | ||
488 | struct GNUNET_SENSOR_SensorBriefMessage *msg; | ||
489 | uint16_t sensorname_size; | ||
490 | uint16_t total_size; | ||
491 | |||
492 | /* Create message struct */ | ||
493 | sensorname_size = strlen (sensor->name) + 1; | ||
494 | total_size = | ||
495 | sizeof (struct GNUNET_SENSOR_SensorBriefMessage) + sensorname_size; | ||
496 | msg = GNUNET_malloc (total_size); | ||
497 | msg->header.size = htons (total_size); | ||
498 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_BRIEF); | ||
499 | msg->name_size = htons (sensorname_size); | ||
500 | msg->version_major = htons (sensor->version_major); | ||
501 | msg->version_minor = htons (sensor->version_minor); | ||
502 | memcpy (&msg[1], sensor->name, sensorname_size); | ||
503 | /* Queue the msg */ | ||
504 | queue_msg ((struct GNUNET_MessageHeader *) msg, cp); | ||
505 | return GNUNET_YES; | ||
506 | } | ||
507 | |||
508 | |||
509 | /** | ||
510 | * Called with any sensor list request received. | ||
511 | * | ||
512 | * Each time the function must call #GNUNET_CADET_receive_done on the channel | ||
513 | * in order to receive the next message. This doesn't need to be immediate: | ||
514 | * can be delayed if some processing is done on the message. | ||
515 | * | ||
516 | * @param cls Closure (set from #GNUNET_CADET_connect). | ||
517 | * @param channel Connection to the other end. | ||
518 | * @param channel_ctx Place to store local state associated with the channel. | ||
519 | * @param message The actual message. | ||
520 | * @return #GNUNET_OK to keep the channel open, | ||
521 | * #GNUNET_SYSERR to close it (signal serious error). | ||
522 | */ | ||
523 | static int | ||
524 | handle_sensor_list_req (void *cls, struct GNUNET_CADET_Channel *channel, | ||
525 | void **channel_ctx, | ||
526 | const struct GNUNET_MessageHeader *message) | ||
527 | { | ||
528 | struct ClientPeerContext *cp = *channel_ctx; | ||
529 | struct GNUNET_MessageHeader *end_msg; | ||
530 | |||
531 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
532 | "Received a sensor list request from peer `%s'.\n", | ||
533 | GNUNET_i2s (&cp->peerid)); | ||
534 | GNUNET_CONTAINER_multihashmap_iterate (sensors, &send_sensor_brief, cp); | ||
535 | end_msg = GNUNET_new (struct GNUNET_MessageHeader); | ||
536 | |||
537 | end_msg->size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
538 | end_msg->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_END); | ||
539 | queue_msg (end_msg, cp); | ||
540 | GNUNET_CADET_receive_done (channel); | ||
541 | return GNUNET_OK; | ||
542 | } | ||
543 | |||
544 | |||
545 | /** | ||
546 | * Parses a sensor reading message struct | ||
547 | * | ||
548 | * @param msg message header received | ||
549 | * @param sensors multihashmap of loaded sensors | ||
550 | * @return sensor reading struct or NULL if error | ||
551 | */ | ||
552 | static struct ClientSensorReading * | ||
553 | parse_reading_message (const struct GNUNET_MessageHeader *msg, | ||
554 | struct GNUNET_CONTAINER_MultiHashMap *sensors) | ||
555 | { | ||
556 | uint16_t msg_size; | ||
557 | uint16_t value_size; | ||
558 | struct GNUNET_SENSOR_ValueMessage *vm; | ||
559 | struct GNUNET_SENSOR_SensorInfo *sensor; | ||
560 | struct ClientSensorReading *reading; | ||
561 | |||
562 | msg_size = ntohs (msg->size); | ||
563 | if (msg_size < sizeof (struct GNUNET_SENSOR_ValueMessage)) | ||
564 | { | ||
565 | GNUNET_break_op (0); | ||
566 | return NULL; | ||
567 | } | ||
568 | vm = (struct GNUNET_SENSOR_ValueMessage *) msg; | ||
569 | value_size = ntohs (vm->value_size); | ||
570 | if ((sizeof (struct GNUNET_SENSOR_ValueMessage) + value_size) != msg_size) | ||
571 | { | ||
572 | GNUNET_break_op (0); | ||
573 | return NULL; | ||
574 | } | ||
575 | sensor = GNUNET_CONTAINER_multihashmap_get (sensors, &vm->sensorname_hash); | ||
576 | if (NULL == sensor) | ||
577 | { | ||
578 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
579 | "Unknown sensor name in reading message.\n"); | ||
580 | return NULL; | ||
581 | } | ||
582 | if ((sensor->version_minor != ntohs (vm->sensorversion_minor)) || | ||
583 | (sensor->version_major != ntohs (vm->sensorversion_major))) | ||
584 | { | ||
585 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
586 | "Sensor version mismatch in reading message.\n"); | ||
587 | return NULL; | ||
588 | } | ||
589 | if (0 == strcmp (sensor->expected_datatype, "numeric") && | ||
590 | sizeof (double) != value_size) | ||
591 | { | ||
592 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
593 | "Invalid value size for a numerical sensor.\n"); | ||
594 | return NULL; | ||
595 | } | ||
596 | reading = GNUNET_new (struct ClientSensorReading); | ||
597 | reading->sensor = sensor; | ||
598 | reading->timestamp = vm->timestamp; | ||
599 | reading->value_size = value_size; | ||
600 | reading->value = GNUNET_memdup (&vm[1], value_size); | ||
601 | return reading; | ||
602 | } | ||
603 | |||
604 | |||
605 | /** | ||
606 | * Called with any sensor reading messages received from CADET. | ||
607 | * | ||
608 | * Each time the function must call #GNUNET_CADET_receive_done on the channel | ||
609 | * in order to receive the next message. This doesn't need to be immediate: | ||
610 | * can be delayed if some processing is done on the message. | ||
611 | * | ||
612 | * @param cls Closure (set from #GNUNET_CADET_connect). | ||
613 | * @param channel Connection to the other end. | ||
614 | * @param channel_ctx Place to store local state associated with the channel. | ||
615 | * @param message The actual message. | ||
616 | * @return #GNUNET_OK to keep the channel open, | ||
617 | * #GNUNET_SYSERR to close it (signal serious error). | ||
618 | */ | ||
619 | static int | ||
620 | handle_sensor_reading (void *cls, struct GNUNET_CADET_Channel *channel, | ||
621 | void **channel_ctx, | ||
622 | const struct GNUNET_MessageHeader *message) | ||
623 | { | ||
624 | struct ClientPeerContext *cp = *channel_ctx; | ||
625 | struct ClientSensorReading *reading; | ||
626 | |||
627 | reading = parse_reading_message (message, sensors); | ||
628 | if (NULL == reading) | ||
629 | { | ||
630 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
631 | "Received an invalid sensor reading from peer `%s'.\n", | ||
632 | GNUNET_i2s (&cp->peerid)); | ||
633 | return GNUNET_SYSERR; | ||
634 | } | ||
635 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
636 | "Received a sensor reading from peer `%s':\n" | ||
637 | "# Sensor name: `%s'\n" "# Timestamp: %" PRIu64 "\n" | ||
638 | "# Value size: %" PRIu64 ".\n", GNUNET_i2s (&cp->peerid), | ||
639 | reading->sensor->name, reading->timestamp, reading->value_size); | ||
640 | GNUNET_PEERSTORE_store (peerstore, values_subsystem, &cp->peerid, | ||
641 | reading->sensor->name, reading->value, | ||
642 | reading->value_size, GNUNET_TIME_UNIT_FOREVER_ABS, | ||
643 | GNUNET_PEERSTORE_STOREOPTION_MULTIPLE, NULL, NULL); | ||
644 | GNUNET_free (reading->value); | ||
645 | GNUNET_free (reading); | ||
646 | GNUNET_CADET_receive_done (channel); | ||
647 | return GNUNET_OK; | ||
648 | } | ||
649 | |||
650 | |||
651 | /** | ||
652 | * Create a message with full information about sensor | ||
653 | * | ||
654 | * @param sensorname Name of sensor requested | ||
655 | * @return Message ready to be sent to client or NULL on error | ||
656 | */ | ||
657 | static struct GNUNET_SENSOR_SensorFullMessage * | ||
658 | create_full_sensor_msg (char *sensorname) | ||
659 | { | ||
660 | struct GNUNET_HashCode key; | ||
661 | struct GNUNET_SENSOR_SensorInfo *sensor; | ||
662 | struct GNUNET_SENSOR_SensorFullMessage *msg; | ||
663 | char *sensor_path; | ||
664 | char *sensorscript_path; | ||
665 | uint64_t sensorname_size; | ||
666 | uint64_t sensorfile_size; | ||
667 | uint64_t sensorscriptname_size; | ||
668 | uint64_t sensorscript_size; | ||
669 | uint64_t total_size; | ||
670 | void *dummy; | ||
671 | |||
672 | GNUNET_CRYPTO_hash (sensorname, strlen (sensorname) + 1, &key); | ||
673 | sensor = GNUNET_CONTAINER_multihashmap_get (sensors, &key); | ||
674 | if (NULL == sensor) | ||
675 | return NULL; | ||
676 | GNUNET_asprintf (&sensor_path, | ||
677 | "%s%s", | ||
678 | sensor_dir, | ||
679 | sensorname); | ||
680 | if (GNUNET_OK != | ||
681 | GNUNET_DISK_file_size (sensor_path, | ||
682 | &sensorfile_size, | ||
683 | GNUNET_NO, | ||
684 | GNUNET_YES)) | ||
685 | { | ||
686 | GNUNET_free (sensor_dir); | ||
687 | GNUNET_free (sensor_path); | ||
688 | return NULL; | ||
689 | } | ||
690 | sensorname_size = strlen (sensorname) + 1; | ||
691 | sensorscript_path = NULL; | ||
692 | sensorscript_size = 0; | ||
693 | sensorscriptname_size = 0; | ||
694 | /* Test if there is an associated script */ | ||
695 | if (NULL != sensor->ext_process) | ||
696 | { | ||
697 | GNUNET_asprintf (&sensorscript_path, | ||
698 | "%s%s-files%s%s", | ||
699 | sensor_dir, | ||
700 | sensor->name, | ||
701 | DIR_SEPARATOR_STR, | ||
702 | sensor->ext_process); | ||
703 | if (GNUNET_OK == | ||
704 | GNUNET_DISK_file_size (sensorscript_path, | ||
705 | &sensorscript_size, | ||
706 | GNUNET_NO, | ||
707 | GNUNET_YES)) | ||
708 | sensorscriptname_size = strlen (sensor->ext_process) + 1; | ||
709 | } | ||
710 | /* Construct the msg */ | ||
711 | total_size = | ||
712 | sizeof (struct GNUNET_SENSOR_SensorFullMessage) + sensorname_size + | ||
713 | sensorfile_size + sensorscriptname_size + sensorscript_size; | ||
714 | msg = GNUNET_malloc (total_size); | ||
715 | msg->header.size = htons (total_size); | ||
716 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_FULL); | ||
717 | msg->sensorname_size = htons (sensorname_size); | ||
718 | msg->sensorfile_size = htons (sensorfile_size); | ||
719 | msg->scriptname_size = htons (sensorscriptname_size); | ||
720 | msg->scriptfile_size = htons (sensorscript_size); | ||
721 | dummy = &msg[1]; | ||
722 | memcpy (dummy, sensorname, sensorname_size); | ||
723 | dummy += sensorname_size; | ||
724 | GNUNET_DISK_fn_read (sensor_path, dummy, sensorfile_size); | ||
725 | dummy += sensorfile_size; | ||
726 | if (sensorscriptname_size > 0) | ||
727 | { | ||
728 | memcpy (dummy, sensor->ext_process, sensorscriptname_size); | ||
729 | dummy += sensorscriptname_size; | ||
730 | GNUNET_DISK_fn_read (sensorscript_path, dummy, sensorscript_size); | ||
731 | } | ||
732 | GNUNET_free_non_null (sensorscript_path); | ||
733 | GNUNET_free (sensor_path); | ||
734 | return msg; | ||
735 | } | ||
736 | |||
737 | |||
738 | /** | ||
739 | * Called with any request for full sensor information. | ||
740 | * | ||
741 | * Each time the function must call #GNUNET_CADET_receive_done on the channel | ||
742 | * in order to receive the next message. This doesn't need to be immediate: | ||
743 | * can be delayed if some processing is done on the message. | ||
744 | * | ||
745 | * @param cls Closure (set from #GNUNET_CADET_connect). | ||
746 | * @param channel Connection to the other end. | ||
747 | * @param channel_ctx Place to store local state associated with the channel. | ||
748 | * @param message The actual message. | ||
749 | * @return #GNUNET_OK to keep the channel open, | ||
750 | * #GNUNET_SYSERR to close it (signal serious error). | ||
751 | */ | ||
752 | static int | ||
753 | handle_sensor_full_req (void *cls, struct GNUNET_CADET_Channel *channel, | ||
754 | void **channel_ctx, | ||
755 | const struct GNUNET_MessageHeader *message) | ||
756 | { | ||
757 | struct ClientPeerContext *cp = *channel_ctx; | ||
758 | struct GNUNET_SENSOR_SensorBriefMessage *sbm = NULL; | ||
759 | struct GNUNET_SENSOR_SensorFullMessage *sfm; | ||
760 | uint16_t msg_size; | ||
761 | uint16_t sensorname_size; | ||
762 | |||
763 | msg_size = ntohs (message->size); | ||
764 | /* parse & error check */ | ||
765 | if (msg_size > sizeof (struct GNUNET_SENSOR_SensorBriefMessage)) | ||
766 | { | ||
767 | sbm = (struct GNUNET_SENSOR_SensorBriefMessage *) message; | ||
768 | sensorname_size = ntohs (sbm->name_size); | ||
769 | if (msg_size != | ||
770 | sizeof (struct GNUNET_SENSOR_SensorBriefMessage) + sensorname_size) | ||
771 | sbm = NULL; | ||
772 | } | ||
773 | if (NULL == sbm) | ||
774 | { | ||
775 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
776 | "Received an invalid full sensor request from peer `%s'.\n", | ||
777 | GNUNET_i2s (&cp->peerid)); | ||
778 | return GNUNET_SYSERR; | ||
779 | } | ||
780 | /* Create and send msg with full sensor info */ | ||
781 | sfm = create_full_sensor_msg ((char *) &sbm[1]); | ||
782 | if (NULL == sfm) | ||
783 | { | ||
784 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
785 | "Error creating full sensor info msg for sensor `%s'.\n", | ||
786 | (char *) &sbm[1]); | ||
787 | return GNUNET_SYSERR; | ||
788 | } | ||
789 | queue_msg ((struct GNUNET_MessageHeader *) sfm, cp); | ||
790 | GNUNET_CADET_receive_done (channel); | ||
791 | return GNUNET_OK; | ||
792 | } | ||
793 | |||
794 | |||
795 | /** | ||
796 | * Process sensordashboard requests. | ||
797 | * | ||
798 | * @param cls closure | ||
799 | * @param server the initialized server | ||
800 | * @param cfg configuration to use | ||
801 | */ | ||
802 | static void | ||
803 | run (void *cls, struct GNUNET_SERVER_Handle *server, | ||
804 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
805 | { | ||
806 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | ||
807 | {NULL, NULL, 0, 0} | ||
808 | }; | ||
809 | static struct GNUNET_CADET_MessageHandler cadet_handlers[] = { | ||
810 | {&handle_sensor_reading, | ||
811 | GNUNET_MESSAGE_TYPE_SENSOR_READING, 0}, | ||
812 | {&handle_sensor_list_req, | ||
813 | GNUNET_MESSAGE_TYPE_SENSOR_LIST_REQ, | ||
814 | sizeof (struct GNUNET_MessageHeader)}, | ||
815 | {&handle_sensor_full_req, | ||
816 | GNUNET_MESSAGE_TYPE_SENSOR_FULL_REQ, | ||
817 | sizeof (struct GNUNET_MessageHeader)}, | ||
818 | {&handle_anomaly_report, | ||
819 | GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_REPORT, | ||
820 | sizeof (struct GNUNET_MessageHeader) + | ||
821 | sizeof (struct GNUNET_SENSOR_crypto_pow_block) + | ||
822 | sizeof (struct GNUNET_SENSOR_AnomalyReportMessage)}, | ||
823 | {NULL, 0, 0} | ||
824 | }; | ||
825 | static uint32_t cadet_ports[] = { | ||
826 | GNUNET_APPLICATION_TYPE_SENSORDASHBOARD, | ||
827 | GNUNET_APPLICATION_TYPE_SENSORUPDATE, | ||
828 | GNUNET_APPLICATION_TYPE_END | ||
829 | }; | ||
830 | |||
831 | if (GNUNET_OK != | ||
832 | GNUNET_CONFIGURATION_get_value_filename (cfg, "SENSOR", "SENSOR_DIR", | ||
833 | &sensor_dir)) | ||
834 | sensor_dir = GNUNET_SENSOR_get_default_sensor_dir (); | ||
835 | sensors = GNUNET_SENSOR_load_all_sensors (sensor_dir); | ||
836 | GNUNET_assert (NULL != sensors); | ||
837 | |||
838 | if (GNUNET_OK != | ||
839 | GNUNET_CONFIGURATION_get_value_number (cfg, "sensor-reporting", | ||
840 | "POW_MATCHING_BITS", | ||
841 | &pow_matching_bits)) | ||
842 | { | ||
843 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "sensor-reporting", | ||
844 | "POW_MATCHING_BITS"); | ||
845 | GNUNET_SCHEDULER_add_now (&cleanup_task, NULL); | ||
846 | return; | ||
847 | } | ||
848 | if (pow_matching_bits > sizeof (struct GNUNET_HashCode)) | ||
849 | { | ||
850 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
851 | "Matching bits value too large (%d > %d).\n", pow_matching_bits, | ||
852 | sizeof (struct GNUNET_HashCode)); | ||
853 | GNUNET_SCHEDULER_add_now (&cleanup_task, NULL); | ||
854 | return; | ||
855 | } | ||
856 | |||
857 | cadet = | ||
858 | GNUNET_CADET_connect (cfg, NULL, &cadet_channel_created, | ||
859 | &cadet_channel_destroyed, cadet_handlers, | ||
860 | cadet_ports); | ||
861 | if (NULL == cadet) | ||
862 | { | ||
863 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
864 | _("Failed to connect to `%s' service.\n"), "CADET"); | ||
865 | GNUNET_SCHEDULER_add_now (&cleanup_task, NULL); | ||
866 | return; | ||
867 | } | ||
868 | peerstore = GNUNET_PEERSTORE_connect (cfg); | ||
869 | if (NULL == peerstore) | ||
870 | { | ||
871 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
872 | _("Failed to connect to `%s' service.\n"), "PEERSTORE"); | ||
873 | GNUNET_SCHEDULER_add_now (&cleanup_task, NULL); | ||
874 | return; | ||
875 | } | ||
876 | GNUNET_SERVER_add_handlers (server, handlers); | ||
877 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, | ||
878 | NULL); | ||
879 | } | ||
880 | |||
881 | |||
882 | /** | ||
883 | * The main function for the sensordashboard service. | ||
884 | * | ||
885 | * @param argc number of arguments from the command line | ||
886 | * @param argv command line arguments | ||
887 | * @return 0 ok, 1 on error | ||
888 | */ | ||
889 | int | ||
890 | main (int argc, char *const *argv) | ||
891 | { | ||
892 | return (GNUNET_OK == | ||
893 | GNUNET_SERVICE_run (argc, argv, "sensordashboard", | ||
894 | GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1; | ||
895 | } | ||
896 | |||
897 | /* end of gnunet-service-sensordashboard.c */ | ||
diff --git a/src/sensordashboard/sensordashboard.conf.in b/src/sensordashboard/sensordashboard.conf.in deleted file mode 100644 index e0772df1c..000000000 --- a/src/sensordashboard/sensordashboard.conf.in +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | [sensordashboard] | ||
2 | AUTOSTART = @AUTOSTART@ | ||
3 | BINARY = gnunet-service-sensordashboard | ||
4 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-sensordashboard.sock | ||
5 | @UNIXONLY@ PORT = 2121 | ||
6 | UNIX_MATCH_UID = NO | ||
7 | UNIX_MATCH_GID = YES | ||
diff --git a/src/sensordashboard/sensordashboard.h b/src/sensordashboard/sensordashboard.h deleted file mode 100644 index 3c3def494..000000000 --- a/src/sensordashboard/sensordashboard.h +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2012-2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file sensordashboard/sensordashboard.h | ||
22 | * @brief IPC messages and private service declarations | ||
23 | * @author Omar Tarabai | ||
24 | */ | ||
25 | |||
26 | #include "gnunet_sensordashboard_service.h" | ||
27 | |||
28 | GNUNET_NETWORK_STRUCT_BEGIN GNUNET_NETWORK_STRUCT_END | ||
diff --git a/src/sensordashboard/test_sensordashboard_api.c b/src/sensordashboard/test_sensordashboard_api.c deleted file mode 100644 index 326361291..000000000 --- a/src/sensordashboard/test_sensordashboard_api.c +++ /dev/null | |||
@@ -1,42 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file template/test_template_api.c | ||
22 | * @brief testcase for template.c | ||
23 | */ | ||
24 | #include "platform.h" | ||
25 | |||
26 | static int | ||
27 | check () | ||
28 | { | ||
29 | return 0; | ||
30 | } | ||
31 | |||
32 | int | ||
33 | main (int argc, char *argv[]) | ||
34 | { | ||
35 | int ret; | ||
36 | |||
37 | ret = check (); | ||
38 | |||
39 | return ret; | ||
40 | } | ||
41 | |||
42 | /* end of test_template_api.c */ | ||