dht api, shell dht service, base of future test case.... not yet working
[oweals/gnunet.git] / src / dht / gnunet-service-dht.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009, 2010 Christian Grothoff (and other contributing authors)
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 2, 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 dht/gnunet_dht_service.c
23  * @brief main DHT service shell, building block for DHT implementations
24  * @author Christian Grothoff
25  * @author Nathan Evans
26  */
27
28 #include "platform.h"
29 #include "gnunet_client_lib.h"
30 #include "gnunet_getopt_lib.h"
31 #include "gnunet_os_lib.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_service_lib.h"
34 #include "gnunet_core_service.h"
35 #include "gnunet_signal_lib.h"
36 #include "gnunet_util_lib.h"
37 #include "gnunet_datastore_service.h"
38 #include "dht.h"
39
40 /**
41  * Handle to the datastore service (for inserting/retrieving data)
42  */
43 static struct GNUNET_DATASTORE_Handle *datastore;
44
45 /**
46  * The main scheduler to use for the DHT service
47  */
48 static struct GNUNET_SCHEDULER_Handle *sched;
49
50 /**
51  * The configuration the DHT service is running with
52  */
53 static const struct GNUNET_CONFIGURATION_Handle *cfg;
54
55 /**
56  * Timeout for transmissions to clients
57  */
58 static struct GNUNET_TIME_Relative client_transmit_timeout;
59
60 /**
61  * Handle to the core service
62  */
63 static struct GNUNET_CORE_Handle *coreAPI;
64
65 /**
66  * The identity of our peer.
67  */
68 static struct GNUNET_PeerIdentity my_identity;
69
70 /**
71  * Task to run when we shut down, cleaning up all our trash
72  */
73 static GNUNET_SCHEDULER_TaskIdentifier cleanup_task;
74
75 struct ClientList
76 {
77   /**
78    * This is a linked list
79    */
80   struct ClientList *next;
81
82   /**
83    * The client in question
84    */
85   struct GNUNET_SERVER_Client *client;
86 };
87
88 /**
89  * Server handler for initiating local dht get requests
90  */
91 static void handle_dht_get (void *cls, struct GNUNET_SERVER_Client * client,
92                      const struct GNUNET_MessageHeader *message);
93
94 /**
95  * Server handler for stopping local dht get requests
96  */
97 static void handle_dht_get_stop (void *cls, struct GNUNET_SERVER_Client * client,
98                      const struct GNUNET_MessageHeader *message);
99
100 /**
101  * Server handler for initiating local dht find peer requests
102  */
103 static void handle_dht_find_peer (void *cls, struct GNUNET_SERVER_Client *
104                            client, const struct GNUNET_MessageHeader *
105                            message);
106
107 /**
108  * Server handler for stopping local dht find peer requests
109  */
110 static void handle_dht_find_peer_stop (void *cls, struct GNUNET_SERVER_Client *
111                            client, const struct GNUNET_MessageHeader *
112                            message);
113
114 /**
115  * Server handler for initiating local dht put requests
116  */
117 static void handle_dht_put (void *cls, struct GNUNET_SERVER_Client * client,
118                      const struct GNUNET_MessageHeader *message);
119
120
121 static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
122   {&handle_dht_get, NULL, GNUNET_MESSAGE_TYPE_DHT_GET, 0},
123   {&handle_dht_get_stop, NULL, GNUNET_MESSAGE_TYPE_DHT_GET_STOP, 0},
124   {&handle_dht_put, NULL, GNUNET_MESSAGE_TYPE_DHT_PUT, 0},
125   {&handle_dht_find_peer, NULL, GNUNET_MESSAGE_TYPE_DHT_FIND_PEER, 0},
126   {&handle_dht_find_peer_stop, NULL, GNUNET_MESSAGE_TYPE_DHT_FIND_PEER_STOP, 0},
127   {NULL, NULL, 0, 0}
128 };
129
130
131 /**
132  * Core handler for p2p dht get requests.
133  */
134 static int handle_dht_p2p_get (void *cls,
135                              const struct GNUNET_PeerIdentity * peer,
136                              const struct GNUNET_MessageHeader * message,
137                              struct GNUNET_TIME_Relative latency,
138                              uint32_t distance);
139
140 /**
141  * Core handler for p2p dht put requests.
142  */
143 static int handle_dht_p2p_put (void *cls,
144                              const struct GNUNET_PeerIdentity * peer,
145                              const struct GNUNET_MessageHeader * message,
146                              struct GNUNET_TIME_Relative latency,
147                              uint32_t distance);
148
149 /**
150  * Core handler for p2p dht find peer requests.
151  */
152 static int handle_dht_p2p_find_peer (void *cls,
153                              const struct GNUNET_PeerIdentity * peer,
154                              const struct GNUNET_MessageHeader * message,
155                              struct GNUNET_TIME_Relative latency,
156                              uint32_t distance);
157
158 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
159   {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_GET, 0},
160   {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_PUT, 0},
161   {&handle_dht_p2p_find_peer, GNUNET_MESSAGE_TYPE_DHT_PUT, 0},
162   {NULL, 0, 0}
163 };
164
165
166 /**
167  * Server handler for initiating local dht get requests
168  */
169 static void handle_dht_get (void *cls, struct GNUNET_SERVER_Client * client,
170                      const struct GNUNET_MessageHeader *message)
171 {
172 #if DEBUG_DHT
173   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
174               "`%s': Received `%s' request from client\n", "DHT", "GET");
175 #endif
176
177 }
178
179 /**
180  * Server handler for stopping local dht get requests
181  */
182 static void handle_dht_get_stop (void *cls, struct GNUNET_SERVER_Client * client,
183                           const struct GNUNET_MessageHeader *message)
184 {
185 #if DEBUG_DHT
186   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
187               "`%s': Received `%s' request from client\n", "DHT", "GET STOP");
188 #endif
189
190 }
191
192 /**
193  * Server handler for initiating local dht find peer requests
194  */
195 static void handle_dht_find_peer (void *cls, struct GNUNET_SERVER_Client *
196                            client, const struct GNUNET_MessageHeader *
197                            message)
198 {
199 #if DEBUG_DHT
200   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
201               "`%s': Received `%s' request from client\n", "DHT", "FIND PEER");
202 #endif
203
204 }
205
206 /**
207  * Server handler for stopping local dht find peer requests
208  */
209 static void handle_dht_find_peer_stop (void *cls, struct GNUNET_SERVER_Client *
210                            client, const struct GNUNET_MessageHeader *
211                            message)
212 {
213 #if DEBUG_DHT
214   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
215               "`%s': Received `%s' request from client\n", "DHT", "FIND PEER STOP");
216 #endif
217
218 }
219
220 /**
221  * Server handler for initiating local dht put requests
222  */
223 static void handle_dht_put (void *cls, struct GNUNET_SERVER_Client * client,
224                      const struct GNUNET_MessageHeader *message)
225 {
226 #if DEBUG_DHT
227   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
228               "`%s': Received `%s' request from client\n", "DHT", "PUT");
229 #endif
230
231 }
232
233 /**
234  * Core handler for p2p dht get requests.
235  */
236 static int handle_dht_p2p_get (void *cls,
237                              const struct GNUNET_PeerIdentity * peer,
238                              const struct GNUNET_MessageHeader * message,
239                              struct GNUNET_TIME_Relative latency,
240                              uint32_t distance)
241 {
242 #if DEBUG_DHT
243   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
244               "`%s': Received `%s' request from another peer\n", "DHT", "GET");
245 #endif
246
247   return GNUNET_YES;
248 }
249
250 /**
251  * Core handler for p2p dht put requests.
252  */
253 static int handle_dht_p2p_put (void *cls,
254                              const struct GNUNET_PeerIdentity * peer,
255                              const struct GNUNET_MessageHeader * message,
256                              struct GNUNET_TIME_Relative latency,
257                              uint32_t distance)
258 {
259 #if DEBUG_DHT
260   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
261               "`%s': Received `%s' request from another peer\n", "DHT", "PUT");
262 #endif
263
264   return GNUNET_YES;
265 }
266
267 /**
268  * Core handler for p2p dht find peer requests.
269  */
270 static int handle_dht_p2p_find_peer (void *cls,
271                              const struct GNUNET_PeerIdentity * peer,
272                              const struct GNUNET_MessageHeader * message,
273                              struct GNUNET_TIME_Relative latency,
274                              uint32_t distance)
275 {
276 #if DEBUG_DHT
277   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
278               "`%s': Received `%s' request from another peer\n", "DHT", "FIND PEER");
279 #endif
280
281   return GNUNET_YES;
282 }
283
284 /**
285  * Task run during shutdown.
286  *
287  * @param cls unused
288  * @param tc unused
289  */
290 static void
291 shutdown_task (void *cls,
292                const struct GNUNET_SCHEDULER_TaskContext *tc)
293 {
294   GNUNET_CORE_disconnect (coreAPI);
295 }
296
297 /**
298  * To be called on core init/fail.
299  */
300 void core_init (void *cls,
301                 struct GNUNET_CORE_Handle * server,
302                 const struct GNUNET_PeerIdentity *identity,
303                 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded * publicKey)
304 {
305
306   if (server == NULL)
307     {
308       GNUNET_SCHEDULER_cancel(sched, cleanup_task);
309       GNUNET_SCHEDULER_add_now(sched, &shutdown_task, NULL);
310       return;
311     }
312 #if DEBUG_DHT
313   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
314               "%s: Core connection initialized, I am peer: %s\n", "dht", GNUNET_i2s(identity));
315 #endif
316   memcpy(&my_identity, identity, sizeof(struct GNUNET_PeerIdentity));
317   coreAPI = server;
318 }
319
320 /**
321  * Process dht requests.
322  *
323  * @param cls closure
324  * @param scheduler scheduler to use
325  * @param server the initialized server
326  * @param c configuration to use
327  */
328 static void
329 run (void *cls,
330      struct GNUNET_SCHEDULER_Handle *scheduler,
331      struct GNUNET_SERVER_Handle *server,
332      const struct GNUNET_CONFIGURATION_Handle *c)
333 {
334   sched = scheduler;
335   cfg = c;
336
337   datastore = GNUNET_DATASTORE_connect(c, scheduler);
338
339   client_transmit_timeout = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5);
340   GNUNET_SERVER_add_handlers (server, plugin_handlers);
341
342   coreAPI =
343   GNUNET_CORE_connect (sched,
344                        cfg,
345                        client_transmit_timeout,
346                        NULL, /* FIXME: anything we want to pass around? */
347                        &core_init,
348                        NULL, /* Don't care about pre-connects */
349                        NULL, /* Don't care about connects */
350                        NULL, /* Don't care about disconnects */
351                        NULL,
352                        GNUNET_NO,
353                        NULL,
354                        GNUNET_NO,
355                        core_handlers);
356
357   if (coreAPI == NULL)
358     return;
359   /* load (server); Huh? */
360
361   /* Scheduled the task to clean up when shutdown is called */
362   cleanup_task = GNUNET_SCHEDULER_add_delayed (sched,
363                                 GNUNET_TIME_UNIT_FOREVER_REL,
364                                 &shutdown_task,
365                                 NULL);
366 }
367
368
369 /**
370  * The main function for the dv service.
371  *
372  * @param argc number of arguments from the command line
373  * @param argv command line arguments
374  * @return 0 ok, 1 on error
375  */
376 int
377 main (int argc, char *const *argv)
378 {
379   return (GNUNET_OK ==
380           GNUNET_SERVICE_run (argc,
381                               argv,
382                               "dht",
383                               GNUNET_SERVICE_OPTION_NONE,
384                               &run, NULL)) ? 0 : 1;
385 }