aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-04-09 19:39:17 +0000
committerChristian Grothoff <christian@grothoff.org>2016-04-09 19:39:17 +0000
commit26852f8f658a38a7e3a5f47e5eb2057080eec3b8 (patch)
tree41e659fc5944a16aa98b6a764f79447a720911ce
parenta59b71b601cc302a77309dcb8c3db33993117097 (diff)
downloadgnunet-26852f8f658a38a7e3a5f47e5eb2057080eec3b8.tar.gz
gnunet-26852f8f658a38a7e3a5f47e5eb2057080eec3b8.zip
killing untested, unmaintained, unused sensor/sensordashboard code
-rw-r--r--configure.ac4
-rw-r--r--src/Makefile.am6
-rw-r--r--src/sensor/Makefile.am140
-rw-r--r--src/sensor/gnunet-sensor-profiler.c801
-rw-r--r--src/sensor/gnunet-sensor-profiler.conf16
-rw-r--r--src/sensor/gnunet-sensor.c179
-rw-r--r--src/sensor/gnunet-service-sensor.c385
-rw-r--r--src/sensor/gnunet-service-sensor_analysis.c326
-rw-r--r--src/sensor/gnunet-service-sensor_monitoring.c477
-rw-r--r--src/sensor/gnunet-service-sensor_reporting.c1437
-rw-r--r--src/sensor/gnunet-service-sensor_update.c801
-rw-r--r--src/sensor/gnunet_sensor_model_plugin.h86
-rw-r--r--src/sensor/perf_pow_sign.c261
-rw-r--r--src/sensor/plugin_sensor_model_gaussian.c263
-rw-r--r--src/sensor/profiler.py175
-rw-r--r--src/sensor/sensor.conf.in34
-rw-r--r--src/sensor/sensor.h172
-rw-r--r--src/sensor/sensor_api.c566
-rw-r--r--src/sensor/sensor_util_lib.c535
-rw-r--r--src/sensor/sensor_util_lib_crypto.c301
-rw-r--r--src/sensor/sensors/average-ping-rtt31
-rwxr-xr-xsrc/sensor/sensors/average-ping-rtt-files/avgping.sh3
-rw-r--r--src/sensor/sensors/core-peers-connected31
-rw-r--r--src/sensor/sensors/datacache-bytes-stored31
-rw-r--r--src/sensor/sensors/dht-peers-connected31
-rw-r--r--src/sensor/sensors/fs-peers-connected31
-rw-r--r--src/sensor/sensors/gnunet-version31
-rw-r--r--src/sensor/sensors/known-peers31
-rw-r--r--src/sensor/sensors/nse31
-rw-r--r--src/sensor/sensors/peerstore-memory31
-rwxr-xr-xsrc/sensor/sensors/peerstore-memory-files/peerstore-memory.sh3
-rw-r--r--src/sensor/sensors/transport-bytes-received31
-rw-r--r--src/sensor/sensors/transport-http-connections31
-rw-r--r--src/sensor/sensors/transport-https-connections31
-rw-r--r--src/sensor/sensors/transport-peers-connected31
-rw-r--r--src/sensor/sensors/transport-tcp-bytes-transmitted31
-rw-r--r--src/sensor/sensors/transport-tcp-sessions-active31
-rw-r--r--src/sensor/test_gnunet-service-sensor_reporting.c552
-rw-r--r--src/sensor/test_gnunet-service-sensor_reporting.conf20
-rw-r--r--src/sensor/test_pow_sign.c214
-rw-r--r--src/sensor/test_pow_sign.conf0
-rw-r--r--src/sensor/test_sensor_api.c82
-rw-r--r--src/sensor/test_sensors/test-sensor-statistics31
-rw-r--r--src/sensordashboard/Makefile.am53
-rw-r--r--src/sensordashboard/gnunet-sensordashboard.c76
-rw-r--r--src/sensordashboard/gnunet-service-sensordashboard.c897
-rw-r--r--src/sensordashboard/sensordashboard.conf.in7
-rw-r--r--src/sensordashboard/sensordashboard.h28
-rw-r--r--src/sensordashboard/test_sensordashboard_api.c42
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
1589src/rps/rps.conf 1589src/rps/rps.conf
1590src/secretsharing/Makefile 1590src/secretsharing/Makefile
1591src/secretsharing/secretsharing.conf 1591src/secretsharing/secretsharing.conf
1592src/sensor/Makefile
1593src/sensor/sensor.conf
1594src/sensordashboard/Makefile
1595src/sensordashboard/sensordashboard.conf
1596src/scalarproduct/Makefile 1592src/scalarproduct/Makefile
1597src/scalarproduct/scalarproduct.conf 1593src/scalarproduct/scalarproduct.conf
1598src/set/Makefile 1594src/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
13endif 11endif
14 12
15if HAVE_EXPERIMENTAL 13if 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)
28endif 24endif
29 25
30if HAVE_REST 26if 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
2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3
4pkgcfgdir= $(pkgdatadir)/config.d/
5
6libexecdir= $(pkglibdir)/libexec/
7
8plugindir = $(libdir)/gnunet
9
10dist_pkgcfg_DATA = \
11 sensor.conf
12
13if MINGW
14 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
15endif
16
17if USE_COVERAGE
18 AM_CFLAGS = -fprofile-arcs -ftest-coverage
19endif
20
21bin_PROGRAMS = \
22 gnunet-sensor
23
24noinst_PROGRAMS = \
25 gnunet-sensor-profiler \
26 perf-pow-sign
27
28libexec_PROGRAMS = \
29 gnunet-service-sensor
30
31lib_LTLIBRARIES = \
32 libgnunetsensor.la \
33 libgnunetsensorutil.la
34
35gnunet_sensor_SOURCES = \
36 gnunet-sensor.c
37gnunet_sensor_LDADD = \
38 $(top_builddir)/src/util/libgnunetutil.la \
39 libgnunetsensor.la \
40 $(GN_LIBINTL)
41
42gnunet_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
48gnunet_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
57libgnunetsensor_la_SOURCES = \
58 sensor_api.c
59libgnunetsensor_la_LIBADD = \
60 $(top_builddir)/src/util/libgnunetutil.la
61libgnunetsensor_la_LDFLAGS = \
62 $(GN_LIB_LDFLAGS)
63
64libgnunetsensorutil_la_SOURCES = \
65 sensor_util_lib.c \
66 sensor_util_lib_crypto.c
67libgnunetsensorutil_la_LIBADD = \
68 $(top_builddir)/src/util/libgnunetutil.la \
69 $(top_builddir)/src/statistics/libgnunetstatistics.la
70libgnunetsensorutil_la_LDFLAGS = \
71 $(GN_LIB_LDFLAGS)
72
73plugin_LTLIBRARIES = \
74 libgnunet_plugin_sensor_model_gaussian.la
75
76libgnunet_plugin_sensor_model_gaussian_la_SOURCES = \
77 plugin_sensor_model_gaussian.c
78libgnunet_plugin_sensor_model_gaussian_la_LIBADD = \
79 libgnunetsensor.la \
80 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
81 $(LTLIBINTL)
82libgnunet_plugin_sensor_model_gaussian_la_LDFLAGS = \
83 $(GN_PLUGIN_LDFLAGS)
84
85check_PROGRAMS = \
86 test_sensor_api \
87 test_gnunet-service-sensor_reporting \
88 test_pow_sign
89
90if ENABLE_TEST_RUN
91AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;
92TESTS = $(check_PROGRAMS)
93endif
94
95test_sensor_api_SOURCES = \
96 test_sensor_api.c
97test_sensor_api_LDADD = \
98 $(top_builddir)/src/util/libgnunetutil.la
99
100test_gnunet_service_sensor_reporting_SOURCES = \
101 test_gnunet-service-sensor_reporting.c
102test_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
109test_pow_sign_SOURCES = \
110 test_pow_sign.c
111test_pow_sign_LDADD = \
112 $(top_builddir)/src/util/libgnunetutil.la \
113 $(top_builddir)/src/testbed/libgnunettestbed.la \
114 libgnunetsensorutil.la
115
116gnunet_sensor_profiler_SOURCES = \
117 gnunet-sensor-profiler.c
118gnunet_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
125perf_pow_sign_SOURCES = \
126 perf_pow_sign.c
127perf_pow_sign_LDADD = \
128 $(top_builddir)/src/util/libgnunetutil.la \
129 $(top_builddir)/src/testbed/libgnunettestbed.la \
130 libgnunetsensorutil.la
131
132EXTRA_DIST = sensors
133pkgsensordir = sensors
134
135install-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 */
42struct 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 */
75static const char *cfg_filename = "gnunet-sensor-profiler.conf";
76
77/**
78 * Directory to read sensor definitions from
79 */
80static const char *sensor_src_dir = "sensors";
81
82/**
83 * Directory to write new sensor definitions to
84 */
85static const char *sensor_dst_dir = "/tmp/gnunet-sensor-profiler";
86
87/**
88 * Scheduled task to shutdown
89 */
90static struct GNUNET_SCHEDULER_Task * shutdown_task = NULL;
91
92/**
93 * GNUnet configuration
94 */
95static struct GNUNET_CONFIGURATION_Handle *cfg;
96
97/**
98 * Number of peers to run (Option -p)
99 */
100static unsigned int num_peers = 0;
101
102/**
103 * Set sensors running interval to this value (Option -i)
104 */
105static unsigned int sensors_interval = 0;
106
107/**
108 * Path to topology file (Option -t)
109 */
110static char *topology_file;
111
112/**
113 * Number of peers to simulate anomalies on (Option -a)
114 */
115static unsigned int anomalous_peers = 0;
116
117/**
118 * Array of peer info for all peers
119 */
120static struct PeerInfo *all_peers_info;
121
122/**
123 * Number of peers that we already collected and start their info
124 */
125static int peers_known = 0;
126
127/**
128 * TESTBED operation connecting us to peerstore service on collection point
129 */
130static struct GNUNET_TESTBED_Operation *peerstore_op;
131
132/**
133 * Handle to peerstore service on collection point
134 */
135static struct GNUNET_PEERSTORE_Handle *peerstore;
136
137/**
138 * Dashboard service on collection point started?
139 */
140static int dashboard_service_started = GNUNET_NO;
141
142/**
143 * Number of peers started the sensor service successfully
144 */
145static int sensor_services_started = 0;
146
147/**
148 * Array of sensor names to be used for watching peerstore records
149 */
150static char **sensor_names;
151
152/**
153 * Size of 'sensor_names' array
154 */
155static unsigned int sensor_names_size = 0;
156
157/**
158 * Task run after any waiting period
159 */
160static 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 */
170static int
171copy_dir (const char *src, const char *dst);
172
173
174/**
175 * Do clean up and shutdown scheduler
176 */
177static void
178do_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 */
229static int
230copy_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 */
260static int
261copy_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, &copy_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 */
281static int
282sensor_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 */
326static void
327rewrite_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 */
344static void
345dashboard_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 */
367static int
368peerstore_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 */
404static void
405peerstore_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 */
441static void *
442peerstore_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 */
457static void
458peerstore_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 */
475static void
476statistics_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 */
501static void *
502statistics_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 */
519static void
520statistics_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 */
532static void
533simulate_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 */
569static void
570peers_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 */
605static void
606sensor_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 */
639static void
640peer_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 */
694static void
695test_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 */
722static int
723verify_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 */
751static void
752run (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 */
778int
779main (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]
2OVERLAY_TOPOLOGY = FROM_FILE
3
4[sensor]
5SENSOR_DIR = /tmp/gnunet-sensor-profiler/
6
7START_MONITORING = YES
8START_REPORTING = YES
9START_ANALYSIS = YES
10START_UPDATE = NO
11
12[transport]
13PLUGINS = unix
14
15[nat]
16USE_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
30static int ret;
31
32/**
33 * option '-a'
34 */
35static int get_all;
36
37/**
38 * option '-g'
39 */
40static char *get_sensor;
41
42/**
43 * option '-f'
44 */
45static char *force_anomaly;
46
47/*
48 * Handle to sensor service
49 */
50static struct GNUNET_SENSOR_Handle *sensor_handle;
51
52/**
53 * Run on shutdown
54 *
55 * @param cls unused
56 * @param tc scheduler context
57 */
58static void
59shutdown_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 */
76void
77print_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 */
105void
106force_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 */
122static void
123run (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 */
157int
158main (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 */
33static const struct GNUNET_CONFIGURATION_Handle *cfg;
34
35/**
36 * Path to sensor definitions directory
37 */
38static char *sensor_dir;
39
40/**
41 * Hashmap of loaded sensor definitions
42 */
43static struct GNUNET_CONTAINER_MultiHashMap *sensors;
44
45/**
46 * Start the monitoring module ?
47 */
48static int start_monitoring;
49
50/**
51 * Start the analysis module ?
52 */
53static int start_analysis;
54
55/**
56 * Start the reporting module ?
57 */
58static int start_reporting;
59
60/**
61 * Start the update module ?
62 */
63static 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 */
70static void
71reset ();
72
73
74/**
75 * Stops components and destroys sensors
76 */
77static void
78stop ()
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 */
98static void
99shutdown_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 */
118static void
119handle_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 */
147static struct SensorInfoMessage *
148create_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 */
192static void
193handle_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 */
240static int
241add_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 */
264static void
265handle_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 */
283static void
284start ()
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 */
305static void
306run (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 */
362static void
363reset ()
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 */
377int
378main (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 */
38struct 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 */
87static const struct GNUNET_CONFIGURATION_Handle *cfg;
88
89/**
90 * Hashmap of loaded sensors
91 */
92static struct GNUNET_CONTAINER_MultiHashMap *sensors;
93
94/*
95 * Model library name
96 */
97static char *model_lib_name;
98
99/**
100 * Model handle
101 */
102static struct GNUNET_SENSOR_ModelFunctions *model_api;
103
104/**
105 * Handle to peerstore service
106 */
107static struct GNUNET_PEERSTORE_Handle *peerstore;
108
109/**
110 * Head of DLL of created models
111 */
112static struct SensorModel *models_head;
113
114/**
115 * Tail of DLL of created models
116 */
117static struct SensorModel *models_tail;
118
119/**
120 * My peer id
121 */
122static 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 */
128static unsigned long long confirmation_count;
129
130/**
131 * Destroy a created model
132 */
133static void
134destroy_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 */
157void
158SENSOR_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 */
191static int
192sensor_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 */
250static int
251init_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 */
281int
282SENSOR_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 */
38static const struct GNUNET_CONFIGURATION_Handle *cfg;
39
40/**
41 * Hashmap of loaded sensor definitions
42 */
43static struct GNUNET_CONTAINER_MultiHashMap *sensors;
44
45/**
46 * Path to sensor definitions directory
47 */
48static char *sensor_dir;
49
50/**
51 * Handle to statistics service
52 */
53static struct GNUNET_STATISTICS_Handle *statistics;
54
55/**
56 * Handle to peerstore service
57 */
58static struct GNUNET_PEERSTORE_Handle *peerstore;
59
60/**
61 * My peer id
62 */
63static struct GNUNET_PeerIdentity peerid;
64
65
66/**
67 * Stop the sensor monitoring module
68 */
69void
70SENSOR_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 */
97static void
98set_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 */
115static int
116should_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 */
157static int
158sensor_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 */
183static void
184end_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 */
202static size_t
203parse_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 */
244static void
245sensor_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 */
288static int
289is_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 */
310static void
311sensor_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 */
405static int
406schedule_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 */
432static void
433schedule_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 */
446int
447SENSOR_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 */
46struct 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
71struct 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
121struct 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 */
176struct 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 */
204struct 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 */
253static const struct GNUNET_CONFIGURATION_Handle *cfg;
254
255/**
256 * Multihashmap of loaded sensors
257 */
258static struct GNUNET_CONTAINER_MultiHashMap *sensors;
259
260/**
261 * Handle to peerstore service
262 */
263static struct GNUNET_PEERSTORE_Handle *peerstore;
264
265/**
266 * Handle to core service
267 */
268static struct GNUNET_CORE_Handle *core;
269
270/**
271 * Handle to CADET service
272 */
273static struct GNUNET_CADET_Handle *cadet;
274
275/**
276 * My peer id
277 */
278static struct GNUNET_PeerIdentity mypeerid;
279
280/**
281 * My private key
282 */
283static struct GNUNET_CRYPTO_EddsaPrivateKey *private_key;
284
285/**
286 * Head of DLL of anomaly info structs
287 */
288static struct AnomalyInfo *ai_head;
289
290/**
291 * Tail of DLL of anomaly info structs
292 */
293static struct AnomalyInfo *ai_tail;
294
295/**
296 * Head of DLL of value info structs
297 */
298static struct ValueInfo *vi_head;
299
300/**
301 * Tail of DLL of value info structs
302 */
303static struct ValueInfo *vi_tail;
304
305/**
306 * Head of DLL of CORE peers
307 */
308static struct CorePeer *corep_head;
309
310/**
311 * Tail of DLL of CORE peers
312 */
313static struct CorePeer *corep_tail;
314
315/**
316 * Head of DLL of CADET peers
317 */
318static struct CadetPeer *cadetp_head;
319
320/**
321 * Tail of DLL of CADET peers
322 */
323static struct CadetPeer *cadetp_tail;
324
325/**
326 * Is the module started?
327 */
328static int module_running = GNUNET_NO;
329
330/**
331 * Number of known neighborhood peers
332 */
333static int neighborhood;
334
335/**
336 * Parameter that defines the complexity of the proof-of-work
337 */
338static long long unsigned int pow_matching_bits;
339
340
341
342/**
343 * Try reconnecting to collection point and send last queued message
344 */
345static void
346cp_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 */
358static void
359destroy_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 */
395static void
396destroy_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 */
422static void
423destroy_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 */
462static void
463destroy_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 */
488void
489SENSOR_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 */
560static struct AnomalyInfo *
561get_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 */
589static size_t
590cp_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 */
619static void
620cp_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 */
650static void
651cp_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 */
684static void
685cp_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 */
706static struct GNUNET_MQ_Handle *
707cp_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 */
721static struct CadetPeer *
722get_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 */
757static void
758do_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 */
784static void
785send_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 */
818static void
819report_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 */
861static void
862update_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 &timestamp, &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 */
911static struct GNUNET_MQ_Envelope *
912create_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 */
944static int
945handle_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 */
1037static int
1038value_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 */
1073static void
1074core_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 */
1103static void
1104core_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 */
1146static void
1147core_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 */
1180static void
1181cadet_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 */
1212void
1213SENSOR_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 */
1262static void
1263report_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 */
1308static int
1309init_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 */
1357int
1358SENSOR_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 */
49struct 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 */
72struct 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 */
131static const struct GNUNET_CONFIGURATION_Handle *cfg;
132
133/**
134 * Path to sensor definition directory
135 */
136static char *sensor_dir;
137
138/**
139 * Hashmap of known sensors
140 */
141static struct GNUNET_CONTAINER_MultiHashMap *sensors;
142
143/**
144 * Head of update points DLL.
145 */
146static struct UpdatePoint *up_head;
147
148/**
149 * Tail of update points DLL.
150 */
151static struct UpdatePoint *up_tail;
152
153/**
154 * The current default update point to use.
155 */
156static struct UpdatePoint *up_default;
157
158/**
159 * Handle to CADET service
160 */
161static struct GNUNET_CADET_Handle *cadet;
162
163/**
164 * Are we in the process of checking and updating sensors?
165 */
166static int updating;
167
168/**
169 * GNUnet scheduler task that starts the update check process.
170 */
171static struct GNUNET_SCHEDULER_Task * update_task;
172
173/**
174 * Pointer to service reset function called when we have new sensor updates.
175 */
176static 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 */
185static void
186check_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 */
193static void
194trigger_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 */
202static void
203cleanup_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 */
233void
234SENSOR_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 */
271static void
272fail ()
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 */
314static size_t
315do_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 */
344static void
345trigger_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 */
367static void
368queue_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 */
387static void
388check_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 */
442static int
443load_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 */
510static int
511update_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 */
539static int
540handle_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 */
607static int
608update_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 */
649static void
650reset (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 */
666static int
667handle_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 */
732static void
733cadet_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 */
756int
757SENSOR_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
32extern "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 */
43struct 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 */
59static const char *testname = "test_pow_sign";
60
61/**
62 * Name of GNUNET config file used in this test
63 */
64static const char *cfg_filename = "test_pow_sign.conf";
65
66/**
67 * Status of the test to be returned by main()
68 */
69static int ok = 1;
70
71/**
72 * Task used to shutdown / expire the test
73 */
74static struct GNUNET_SCHEDULER_Task * shutdown_task;
75
76/**
77 * Message to be exchanged
78 */
79static char msg[MSG_SIZE];
80
81/**
82 * Private key of sending peer
83 */
84static struct GNUNET_CRYPTO_EddsaPrivateKey *private_key;
85
86/**
87 * Public key of sending peer
88 */
89static struct GNUNET_CRYPTO_EddsaPublicKey *public_key;
90
91/**
92 * The current matching bits being evaluated
93 */
94static int current_matching_bits;
95
96/**
97 * How many iterations performed for this matching bits value
98 */
99static int performed_iterations;
100
101/**
102 * Total duration of all iterations
103 */
104static struct GNUNET_TIME_Relative total_duration;
105
106/**
107 * Task creating pow block
108 */
109static struct GNUNET_SENSOR_crypto_pow_context *pow_task;
110
111
112/**
113 * Start a new pow calculation
114 */
115static void
116pow_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 */
125static void
126do_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
147static void
148pow_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 */
182static void
183pow_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, &timestamp, 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 */
202static void
203peer_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 */
237static void
238test_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
252int
253main (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 */
37struct 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 */
65struct 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 */
96static void
97update_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 */
115static int
116sensor_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 */
151static void
152sensor_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 */
166static void *
167sensor_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 */
186void *
187libgnunet_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 */
250void *
251libgnunet_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 @@
1import argparse
2import math
3import networkx
4import random
5import tempfile
6import os
7import time
8import matplotlib.pyplot as plt
9from subprocess import Popen, PIPE, STDOUT
10
11node_colors = None
12graph = None
13pos = None
14
15def 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
29def 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
44def 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
62def 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
82def 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
90def 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
99def 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
110def 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
128def 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
147def 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
174if __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]
2AUTOSTART = @AUTOSTART@
3BINARY = gnunet-service-sensor
4UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-sensor.sock
5@UNIXONLY@ PORT = 2120
6UNIX_MATCH_UID = NO
7UNIX_MATCH_GID = YES
8
9# Which modules to run (default: YES)
10START_MONITORING = YES
11START_REPORTING = YES
12START_ANALYSIS = YES
13START_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]
20MODEL = gaussian
21# How many subsequent values required to flip anomaly label. (Default: 1)
22CONFIRMATION_COUNT = 1
23
24[sensor-model-gaussian]
25TRAINING_WINDOW = 400
26CONFIDENCE_INTERVAL = 8
27WEIGHT_INC = 0
28
29[sensor-reporting]
30POW_MATCHING_BITS = 15
31
32[sensor-update]
33# Space separated list of trusted peers running update points
34UPDATE_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
30GNUNET_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 */
66struct 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
86GNUNET_NETWORK_STRUCT_END
87/**
88 * Stop the sensor analysis module
89 */
90 void
91SENSOR_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 */
101int
102SENSOR_analysis_start (const struct GNUNET_CONFIGURATION_Handle *c,
103 struct GNUNET_CONTAINER_MultiHashMap *s);
104
105
106/**
107 * Stop sensor anomaly reporting module
108 */
109void
110SENSOR_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 */
119void
120SENSOR_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 */
131int
132SENSOR_reporting_start (const struct GNUNET_CONFIGURATION_Handle *c,
133 struct GNUNET_CONTAINER_MultiHashMap *s);
134
135
136/**
137 * Stop the sensor update module
138 */
139void
140SENSOR_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 */
151int
152SENSOR_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 */
159void
160SENSOR_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 */
170int
171SENSOR_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 */
35struct 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 */
78struct 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 */
131struct 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 */
173static void
174mq_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 */
190static void
191handle_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 */
220static void
221handle_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 */
278void
279GNUNET_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 */
329struct GNUNET_SENSOR_Handle *
330GNUNET_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 */
360static void
361signal_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 */
384static void
385iterate_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 */
401void
402GNUNET_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 */
442struct GNUNET_SENSOR_IterateContext *
443GNUNET_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 */
489static void
490force_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 */
510void
511GNUNET_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 */
540struct GNUNET_SENSOR_ForceAnomalyContext *
541GNUNET_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 */
37static const char *sources[] = { "gnunet-statistics", "process", NULL };
38
39/**
40 * Supported datatypes of sensor information
41 */
42static 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 */
52static int
53version_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 */
86static struct GNUNET_SENSOR_SensorInfo *
87load_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 */
289static struct GNUNET_SENSOR_SensorInfo *
290load_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 */
334int
335GNUNET_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 */
354static int
355add_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 */
401static int
402reload_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 */
429char *
430GNUNET_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 */
448struct GNUNET_CONTAINER_MultiHashMap *
449GNUNET_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 */
477static int
478destroy_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 */
529void
530GNUNET_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 */
37struct 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 */
91static void
92pow_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 */
110static unsigned int
111count_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 */
125static int
126check_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 */
142static void
143calculate_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 */
196void
197GNUNET_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 */
225struct GNUNET_SENSOR_crypto_pow_context *
226GNUNET_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 */
266size_t
267GNUNET_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
3VERSION = 1.0
4DESCRIPTION = Calculate average ping latency to gnunet.org
5CATEGORY = Underlay
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = process
18
19#GNUNET_STAT_SERVICE =
20#GNUNET_STAT_NAME =
21
22EXT_PROCESS = avgping.sh
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
3ping -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
3VERSION = 1.0
4DESCRIPTION = Gets the number of peers connected to core service
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = gnunet-statistics
18
19GNUNET_STAT_SERVICE = core
20GNUNET_STAT_NAME = # peers connected
21
22#EXT_PROCESS =
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
3VERSION = 1.0
4DESCRIPTION = Bytes stored by GNUnet datacache service
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = gnunet-statistics
18
19GNUNET_STAT_SERVICE = datacache
20GNUNET_STAT_NAME = # bytes stored
21
22#EXT_PROCESS =
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
3VERSION = 1.0
4DESCRIPTION = Gets the number of peers connected to dht service
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = gnunet-statistics
18
19GNUNET_STAT_SERVICE = dht
20GNUNET_STAT_NAME = # peers connected
21
22#EXT_PROCESS =
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
3VERSION = 1.0
4DESCRIPTION = Gets the number of peers connected to fs service
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = gnunet-statistics
18
19GNUNET_STAT_SERVICE = fs
20GNUNET_STAT_NAME = # peers connected
21
22#EXT_PROCESS =
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
3VERSION = 1.0
4DESCRIPTION = Gets gnunet version number
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 86400
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = process
18
19#GNUNET_STAT_SERVICE =
20#GNUNET_STAT_NAME =
21
22EXT_PROCESS = gnunet-arm
23EXT_ARGS = -v
24
25EXPECTED_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
31REPORT_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
3VERSION = 1.0
4DESCRIPTION = Gets the number of known peers
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = gnunet-statistics
18
19GNUNET_STAT_SERVICE = peerinfo
20GNUNET_STAT_NAME = # peers known
21
22#EXT_PROCESS =
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
3VERSION = 1.0
4DESCRIPTION = GNUnet network size estimate
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = gnunet-statistics
18
19GNUNET_STAT_SERVICE = nse
20GNUNET_STAT_NAME = # nodes in the network (estimate)
21
22#EXT_PROCESS =
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
3VERSION = 1.0
4DESCRIPTION = Memory consumption of GNUnet peerstore service
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = process
18
19#GNUNET_STAT_SERVICE =
20#GNUNET_STAT_NAME =
21
22EXT_PROCESS = peerstore-memory.sh
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
3ps 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
3VERSION = 1.0
4DESCRIPTION = Number of bytes received by GNUnet transport service
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = gnunet-statistics
18
19GNUNET_STAT_SERVICE = transport
20GNUNET_STAT_NAME = # bytes total received
21
22#EXT_PROCESS =
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
3VERSION = 1.0
4DESCRIPTION = Gets the number of transport HTTP connections
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = gnunet-statistics
18
19GNUNET_STAT_SERVICE = transport
20GNUNET_STAT_NAME = # HTTP client connections
21
22#EXT_PROCESS =
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
3VERSION = 1.0
4DESCRIPTION = Gets the number of transport HTTPS connections
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = gnunet-statistics
18
19GNUNET_STAT_SERVICE = transport
20GNUNET_STAT_NAME = # HTTPS client connections
21
22#EXT_PROCESS =
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
3VERSION = 1.0
4DESCRIPTION = Gets the number of peers connected to transport service
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = gnunet-statistics
18
19GNUNET_STAT_SERVICE = transport
20GNUNET_STAT_NAME = # peers connected
21
22#EXT_PROCESS =
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
3VERSION = 1.0
4DESCRIPTION = Number of GNUnet transport TCP bytes transmitted
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = gnunet-statistics
18
19GNUNET_STAT_SERVICE = transport
20GNUNET_STAT_NAME = # bytes transmitted via TCP
21
22#EXT_PROCESS =
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
3VERSION = 1.0
4DESCRIPTION = Number of GNUnet transport service active TCP sessions
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = gnunet-statistics
18
19GNUNET_STAT_SERVICE = transport
20GNUNET_STAT_NAME = # TCP sessions active
21
22#EXT_PROCESS =
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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 */
51struct 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 */
99static const char *testname = "test_gnunet-service-sensor_reporting";
100
101/**
102 * Name of GNUNET config file used in this test
103 */
104static const char *cfg_filename = "test_gnunet-service-sensor_reporting.conf";
105
106/**
107 * Test sensor name
108 */
109static const char *sensor_name = "test-sensor-statistics";
110
111/**
112 * Path to read test sensor from
113 */
114static const char *sensor_path_src = "test_sensors/test-sensor-statistics";
115
116/**
117 * Path to write new test sensor to
118 */
119static const char *sensor_path_dest =
120 "/tmp/test-gnunet-service-sensor-reporting/test-sensor-statistics";
121
122/**
123 * Head of DLL of peers
124 */
125static struct TestPeer *peer_head;
126
127/**
128 * Tail of DLL of peers
129 */
130static struct TestPeer *peer_tail;
131
132/**
133 * Number of peers started and got information for
134 */
135static int started_peers = 0;
136
137/**
138 * Number of peers reported anomalies with full list of anomalous neighbors
139 */
140static int reported_peers = 0;
141
142/**
143 * TESTBED operation connecting us to peerstore service
144 */
145static struct GNUNET_TESTBED_Operation *peerstore_op;
146
147/**
148 * Handle to the peerstore service
149 */
150static struct GNUNET_PEERSTORE_Handle *peerstore;
151
152/**
153 * Task used to shutdown / expire the test
154 */
155static struct GNUNET_SCHEDULER_Task * shutdown_task;
156
157/**
158 * Status of the test to be returned by main()
159 */
160static int ok = 1;
161
162
163static void
164destroy_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 */
191static void
192do_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 */
216static void
217write_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 */
243static int
244peerstore_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 */
278static void
279force_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 */
298static void
299sensor_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 */
320static void *
321sensor_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 */
337static void
338sensor_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 */
354static void
355sensor_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 */
383static void
384peerstore_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 */
412static void *
413peerstore_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 */
428static void
429peerstore_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 */
445static void
446dashboard_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 */
473static void
474peer_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 */
518static void
519test_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
543int
544main (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]
2OVERLAY_TOPOLOGY = CLIQUE
3
4[sensor]
5#PREFIX = valgrind --leak-check=full
6SENSOR_DIR = /tmp/test-gnunet-service-sensor-reporting/
7
8START_MONITORING = NO
9START_REPORTING = YES
10START_ANALYSIS = NO
11START_UPDATE = NO
12
13[sensor-reporting]
14POW_MATCHING_BITS = 2
15
16[transport]
17PLUGINS = unix
18
19[nat]
20USE_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 */
54static const char *testname = "test_pow_sign";
55
56/**
57 * Name of GNUNET config file used in this test
58 */
59static const char *cfg_filename = "test_pow_sign.conf";
60
61/**
62 * Status of the test to be returned by main()
63 */
64static int ok = 1;
65
66/**
67 * Task used to shutdown / expire the test
68 */
69static struct GNUNET_SCHEDULER_Task * shutdown_task;
70
71/**
72 * Message to be exchanged
73 */
74static char msg[MSG_SIZE];
75
76/**
77 * Private key of sending peer
78 */
79static struct GNUNET_CRYPTO_EddsaPrivateKey *private_key;
80
81/**
82 * Public key of sending peer
83 */
84static 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 */
93static void
94do_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
110static void
111pow_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 */
148static void
149peer_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, &timestamp, 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 */
186static void
187test_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
205int
206main (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:
29static int ok = 1;
30
31
32static void
33run (void *cls, char *const *args, const char *cfgfile,
34 const struct GNUNET_CONFIGURATION_Handle *cfg)
35{
36 ok = 0;
37}
38
39
40static int
41check ()
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
75int
76main (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
3VERSION = 1.0
4DESCRIPTION = Test sensor for collecting data from gnunet-statistics
5CATEGORY = GNUnet
6ENABLED = YES
7
8# Start and end time format: %Y-%m-%d %H:%M:%S
9#START_TIME =
10#END_TIME =
11#Interval in seconds
12INTERVAL = 60
13#LIFETIME =
14
15#CAPABILITIES =
16
17SOURCE = gnunet-statistics
18
19GNUNET_STAT_SERVICE = test-sensor
20GNUNET_STAT_NAME = test-statistic
21
22#EXT_PROCESS =
23#EXT_ARGS =
24
25EXPECTED_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
31REPORT_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
2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3
4pkgcfgdir= $(pkgdatadir)/config.d/
5
6libexecdir= $(pkglibdir)/libexec/
7
8dist_pkgcfg_DATA = \
9 sensordashboard.conf
10
11if MINGW
12 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
13endif
14
15if USE_COVERAGE
16 AM_CFLAGS = -fprofile-arcs -ftest-coverage
17endif
18
19bin_PROGRAMS = \
20 gnunet-sensordashboard
21
22libexec_PROGRAMS = \
23 gnunet-service-sensordashboard
24
25gnunet_sensordashboard_SOURCES = \
26 gnunet-sensordashboard.c
27gnunet_sensordashboard_LDADD = \
28 $(top_builddir)/src/util/libgnunetutil.la \
29 $(GN_LIBINTL)
30
31gnunet_service_sensordashboard_SOURCES = \
32 gnunet-service-sensordashboard.c
33gnunet_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
41check_PROGRAMS = \
42 test_sensordashboard_api
43
44if ENABLE_TEST_RUN
45AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;
46TESTS = $(check_PROGRAMS)
47endif
48
49test_sensordashboard_api_SOURCES = \
50 test_sensordashboard_api.c
51test_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 */
32static 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 */
42static void
43run (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 */
57int
58main (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 */
39struct 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 */
87struct 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 */
110struct 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 */
139static char *sensor_dir;
140
141/**
142 * Global hashmap of defined sensors
143 */
144static struct GNUNET_CONTAINER_MultiHashMap *sensors;
145
146/**
147 * Handle to CADET service
148 */
149static struct GNUNET_CADET_Handle *cadet;
150
151/**
152 * Handle to the peerstore service connection
153 */
154static 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 */
160static 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 */
166static char *anomalies_subsystem = "sensordashboard-anomalies";
167
168/**
169 * Head of a DLL of all connected client peers
170 */
171static struct ClientPeerContext *cp_head;
172
173/**
174 * Tail of a DLL of all connected client peers
175 */
176static struct ClientPeerContext *cp_tail;
177
178/**
179 * Parameter that defines the complexity of the proof-of-work
180 */
181static 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 */
189static void
190trigger_send_next_msg (struct ClientPeerContext *cp);
191
192
193/**
194 * Destroy a given client peer context
195 *
196 * @param cp client peer context
197 */
198static void
199destroy_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 */
232static void
233cleanup_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 */
275static void
276cadet_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 */
307static void *
308cadet_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 */
339static size_t
340do_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 */
370static void
371trigger_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 */
394static void
395queue_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 */
421static int
422handle_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 */
483static int
484send_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 */
523static int
524handle_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 */
552static struct ClientSensorReading *
553parse_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 */
619static int
620handle_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 */
657static struct GNUNET_SENSOR_SensorFullMessage *
658create_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 */
752static int
753handle_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 */
802static void
803run (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 */
889int
890main (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]
2AUTOSTART = @AUTOSTART@
3BINARY = gnunet-service-sensordashboard
4UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-sensordashboard.sock
5@UNIXONLY@ PORT = 2121
6UNIX_MATCH_UID = NO
7UNIX_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
28GNUNET_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
26static int
27check ()
28{
29 return 0;
30}
31
32int
33main (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 */