sensor: towards anomaly reporting
[oweals/gnunet.git] / src / sensor / gnunet-service-sensor_reporting_anomaly.c
1 /*
2      This file is part of GNUnet.
3      (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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file sensor/gnunet-service-sensor_reporting_anomaly.c
23  * @brief sensor service anomaly 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
32 #define LOG(kind,...) GNUNET_log_from (kind, "sensor-reporting-anomaly",__VA_ARGS__)
33
34 struct AnomalyReportingContext
35 {
36
37   /**
38    * DLL
39    */
40   struct AnomalyReportingContext *prev;
41
42   /**
43    * DLL
44    */
45   struct AnomalyReportingContext *next;
46
47   /**
48    * Sensor information
49    */
50   struct GNUNET_SENSOR_SensorInfo *sensor;
51
52 };
53
54 /**
55  * Context of a connection to a peer through CORE
56  */
57 struct CorePeerContext
58 {
59
60   /**
61    * DLL
62    */
63   struct CorePeerContext *prev;
64
65   /**
66    * DLL
67    */
68   struct CorePeerContext *next;
69
70   /**
71    * Peer identity of connected peer
72    */
73   struct GNUNET_PeerIdentity *peerid;
74
75 };
76
77
78 /**
79  * Our configuration.
80  */
81 static const struct GNUNET_CONFIGURATION_Handle *cfg;
82
83 /**
84  * Handle to core service
85  */
86 static struct GNUNET_CORE_Handle *core;
87
88 /**
89  * My peer id
90  */
91 static struct GNUNET_PeerIdentity mypeerid;
92
93 /**
94  * Head of DLL of anomaly reporting contexts
95  */
96 static struct AnomalyReportingContext *arc_head;
97
98 /**
99  * Tail of DLL of anomaly reporting contexts
100  */
101 static struct AnomalyReportingContext *arc_tail;
102
103 /**
104  * Head of DLL of CORE peer contexts
105  */
106 static struct CorePeerContext *cp_head;
107
108 /**
109  * Tail of DLL of CORE peer contexts
110  */
111 static struct CorePeerContext *cp_tail;
112
113
114 /**
115  * Destroy anomaly reporting context struct
116  *
117  * @param arc struct to destroy
118  */
119 static void
120 destroy_anomaly_reporting_context (struct AnomalyReportingContext *arc)
121 {
122   GNUNET_free (arc);
123 }
124
125
126 /**
127  * Stop sensor anomaly reporting module
128  */
129 void
130 SENSOR_reporting_anomaly_stop ()
131 {
132   struct AnomalyReportingContext *arc;
133
134   LOG (GNUNET_ERROR_TYPE_DEBUG, "Stopping sensor anomaly reporting module.\n");
135   //TODO: destroy core peer contexts
136   //TODO: destroy core connection
137   arc = arc_head;
138   while (NULL != arc)
139   {
140     GNUNET_CONTAINER_DLL_remove (arc_head, arc_tail, arc);
141     destroy_anomaly_reporting_context (arc);
142     arc = arc_head;
143   }
144 }
145
146
147 /**
148  * Iterator for defined sensors
149  * Watches sensors for anomaly status change to report
150  *
151  * @param cls unused
152  * @param key unused
153  * @param value a `struct GNUNET_SENSOR_SensorInfo *` with sensor information
154  * @return #GNUNET_YES to continue iterations
155  */
156 static int
157 init_sensor_reporting (void *cls, const struct GNUNET_HashCode *key,
158                        void *value)
159 {
160   struct GNUNET_SENSOR_SensorInfo *sensor = value;
161   struct AnomalyReportingContext *arc;
162
163   if (NULL == sensor->collection_point)
164     return GNUNET_YES;
165   LOG (GNUNET_ERROR_TYPE_INFO,
166        "Reporting sensor `%s' anomalies to collection point `%s'.\n",
167        sensor->name, GNUNET_i2s_full (sensor->collection_point));
168   arc = GNUNET_new (struct AnomalyReportingContext);
169   arc->sensor = sensor;
170   GNUNET_CONTAINER_DLL_insert (arc_head, arc_tail, arc);
171   //TODO
172   return GNUNET_YES;
173 }
174
175
176 /**
177  * Function called after #GNUNET_CORE_connect has succeeded (or failed
178  * for good).  Note that the private key of the peer is intentionally
179  * not exposed here; if you need it, your process should try to read
180  * the private key file directly (which should work if you are
181  * authorized...).  Implementations of this function must not call
182  * #GNUNET_CORE_disconnect (other than by scheduling a new task to
183  * do this later).
184  *
185  * @param cls closure (unused)
186  * @param my_identity ID of this peer, NULL if we failed
187  */
188 static void
189 core_startup_cb (void *cls, const struct GNUNET_PeerIdentity *my_identity)
190 {
191   if (NULL == my_identity)
192   {
193     LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to CORE service.\n"));
194     SENSOR_reporting_anomaly_stop ();
195     return;
196   }
197   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&mypeerid, my_identity))
198   {
199     LOG (GNUNET_ERROR_TYPE_ERROR,
200          _("Peer identity received from CORE doesn't match ours.\n"));
201     SENSOR_reporting_anomaly_stop ();
202     return;
203   }
204 }
205
206
207 /**
208  * Method called whenever a given peer connects through CORE.
209  *
210  * @param cls closure (unused)
211  * @param peer peer identity this notification is about
212  */
213 static void
214 core_connect_cb (void *cls, const struct GNUNET_PeerIdentity *peer)
215 {
216   struct CorePeerContext *cp;
217
218   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&mypeerid, peer))
219     return;
220   cp = GNUNET_new (struct CorePeerContext);
221   cp->peerid = (struct GNUNET_PeerIdentity *)peer;
222   GNUNET_CONTAINER_DLL_insert (cp_head, cp_tail, cp);
223   //TODO: report to peer your anomaly status
224 }
225
226
227 /**
228  * Method called whenever a CORE peer disconnects.
229  *
230  * @param cls closure (unused)
231  * @param peer peer identity this notification is about
232  */
233 static void
234 core_disconnect_cb (void *cls, const struct GNUNET_PeerIdentity *peer)
235 {
236   struct CorePeerContext *cp;
237
238   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&mypeerid, peer))
239     return;
240   cp = cp_head;
241   while (NULL != cp)
242   {
243     if (peer == cp->peerid)
244     {
245       GNUNET_CONTAINER_DLL_remove (cp_head, cp_tail, cp);
246       //TODO: call peer context destroy function
247       return;
248     }
249   }
250   LOG (GNUNET_ERROR_TYPE_ERROR,
251        _("Received disconnect notification from CORE"
252          " for a peer we didn't know about.\n"));
253 }
254
255
256 /**
257  * An inbound message is received from a peer through CORE.
258  *
259  * @param cls closure (unused)
260  * @param peer the other peer involved
261  * @param message the actual message
262  * @return #GNUNET_OK to keep the connection open,
263  *         #GNUNET_SYSERR to close connection to the peer (signal serious error)
264  */
265 static int
266 core_inbound_cb (void *cls,
267     const struct GNUNET_PeerIdentity *other,
268     const struct GNUNET_MessageHeader *message)
269 {
270   //TODO
271   return GNUNET_OK;
272 }
273
274
275 /**
276  * Start the sensor anomaly reporting module
277  *
278  * @param c our service configuration
279  * @param sensors multihashmap of loaded sensors
280  * @return #GNUNET_OK if started successfully, #GNUNET_SYSERR otherwise
281  */
282 int
283 SENSOR_reporting_anomaly_start (const struct GNUNET_CONFIGURATION_Handle *c,
284                                 struct GNUNET_CONTAINER_MultiHashMap *sensors)
285 {
286   static struct GNUNET_CORE_MessageHandler core_handlers[] = {
287     {NULL, 0, 0}                //TODO
288   };
289
290   LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting sensor anomaly reporting module.\n");
291   GNUNET_assert (NULL != sensors);
292   cfg = c;
293   core =
294       GNUNET_CORE_connect (cfg, NULL, &core_startup_cb, core_connect_cb,
295                            &core_disconnect_cb, core_inbound_cb, GNUNET_NO,
296                            NULL, GNUNET_YES, core_handlers);
297   GNUNET_CRYPTO_get_peer_identity (cfg, &mypeerid);
298   GNUNET_CONTAINER_multihashmap_iterate (sensors, &init_sensor_reporting, NULL);
299   return GNUNET_OK;
300 }
301
302 /* end of gnunet-service-sensor_reporting_anomaly.c */