92f5c96aadbc424eeabb0ae17affdbdc9d9583e2
[oweals/gnunet.git] / src / dv / gnunet-service-dv.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009 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 dv/gnunet-service-dv.c
23  * @brief the distance vector service, primarily handles gossip of nearby
24  * peers and sending/receiving DV messages from core and decapsulating
25  * them
26  *
27  * @author Christian Grothoff
28  * @author Nathan Evans
29  *
30  */
31 #include "platform.h"
32 #include "gnunet_client_lib.h"
33 #include "gnunet_getopt_lib.h"
34 #include "gnunet_os_lib.h"
35 #include "gnunet_protocols.h"
36 #include "gnunet_service_lib.h"
37 #include "gnunet_core_service.h"
38 #include "gnunet_signal_lib.h"
39 #include "dv.h"
40
41 /**
42  * DV Service Context stuff goes here...
43  */
44 static struct GNUNET_CORE_Handle *coreAPI;
45
46 static struct GNUNET_PeerIdentity *my_identity;
47
48 const struct GNUNET_CONFIGURATION_Handle *cfg;
49
50 struct GNUNET_SCHEDULER_Handle *sched;
51
52 GNUNET_SCHEDULER_TaskIdentifier cleanup_task;
53
54 /**
55  * Core handler for dv data messages.  Whatever this message
56  * contains all we really have to do is rip it out of its
57  * DV layering and give it to our pal the DV plugin to report
58  * in with.
59  *
60  * @param cls closure
61  * @param client identification of the client
62  * @param message the actual message
63  */
64 void handle_dv_data_message (void *cls,
65                              struct GNUNET_SERVER_Client *
66                              client,
67                              const struct
68                              GNUNET_MessageHeader *
69                              message)
70 {
71 #if DEBUG_DV
72   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
73               "%s: Receives %s message!\n", "dv", "DV DATA");
74 #endif
75 }
76
77 /**
78  * Core handler for dv gossip messages.  These will be used
79  * by us to create a HELLO message for the newly peer containing
80  * which direct peer we can connect through, and what the cost
81  * is.  This HELLO will then be scheduled for validation by the
82  * transport service so that it can be used by all others.
83  *
84  * @param cls closure
85  * @param client identification of the client
86  * @param message the actual message
87  */
88 void handle_dv_gossip_message (void *cls,
89                                struct GNUNET_SERVER_Client *
90                                client,
91                                const struct GNUNET_MessageHeader *
92                                message)
93 {
94 #if DEBUG_DV
95   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
96               "%s: Receives %s message!\n", "dv", "DV GOSSIP");
97 #endif
98 }
99
100
101 /**
102  * Service server's handler for message send requests (which come
103  * bubbling up to us through the DV plugin).
104  *
105  * @param cls closure
106  * @param client identification of the client
107  * @param message the actual message
108  */
109 void send_dv_message (void *cls,
110                       struct GNUNET_SERVER_Client * client,
111                       const struct GNUNET_MessageHeader * message)
112 {
113 #if DEBUG_DV
114   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
115               "%s: Receives %s message!\n", "dv", "SEND");
116 #endif
117 }
118
119 /**
120  * List of handlers for the messages understood by this
121  * service.
122  *
123  * Hmm... will we need to register some handlers with core and
124  * some handlers with our server here?  Because core should be
125  * getting the incoming DV messages (from whichever lower level
126  * transport) and then our server should be getting messages
127  * from the dv_plugin, right?
128  */
129 static struct GNUNET_SERVER_MessageHandler core_handlers[] = {
130   {&handle_dv_data_message, NULL, GNUNET_MESSAGE_TYPE_DV_DATA, 0},
131   {&handle_dv_gossip_message, NULL, GNUNET_MESSAGE_TYPE_DV_GOSSIP, 0},
132   {NULL, NULL, 0, 0}
133 };
134
135 static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
136   {&send_dv_message, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND, 0},
137   {NULL, NULL, 0, 0}
138 };
139
140
141 /**
142  * Task run during shutdown.
143  *
144  * @param cls unused
145  * @param tc unused
146  */
147 static void
148 shutdown_task (void *cls,
149                const struct GNUNET_SCHEDULER_TaskContext *tc)
150 {
151
152   GNUNET_CORE_disconnect (coreAPI);
153 }
154
155 /**
156  * To be called on core init/fail.
157  */
158 void core_init (void *cls,
159                 struct GNUNET_CORE_Handle * server,
160                 const struct GNUNET_PeerIdentity *my_identity,
161                 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded * publicKey)
162 {
163
164   if (server == NULL)
165     {
166       GNUNET_SCHEDULER_cancel(sched, cleanup_task);
167       GNUNET_SCHEDULER_add_now(sched, &shutdown_task, NULL);
168     }
169 #if DEBUG_DV
170   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
171               "%s: Core initialized, I am peer: %s\n", "dv", GNUNET_i2s(my_identity));
172 #endif
173   coreAPI = server;
174 }
175
176 /**
177  * Method called whenever a given peer either connects.
178  *
179  * @param cls closure
180  * @param peer peer identity this notification is about
181  * @param latency reported latency of the connection with 'other'
182  * @param distance reported distance (DV) to 'other'
183  */
184 void handle_core_connect (void *cls,
185                           const struct GNUNET_PeerIdentity * peer,
186                           struct GNUNET_TIME_Relative latency,
187                           uint32_t distance)
188 {
189
190 #if DEBUG_DV
191   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
192               "%s: Receives core connect message!\n", "dv");
193 #endif
194 }
195
196 /**
197  * Method called whenever a given peer either connects.
198  *
199  * @param cls closure
200  * @param peer peer identity this notification is about
201  * @param latency reported latency of the connection with 'other'
202  * @param distance reported distance (DV) to 'other'
203  */
204 void handle_core_disconnect (void *cls,
205                              const struct GNUNET_PeerIdentity * peer,
206                              struct GNUNET_TIME_Relative latency,
207                              uint32_t distance)
208 {
209 #if DEBUG_DV
210   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
211               "%s: Receives core disconnect message!\n", "dv");
212 #endif
213 }
214
215
216 /**
217  * Process dv requests.
218  *
219  * @param cls closure
220  * @param sched scheduler to use
221  * @param server the initialized server
222  * @param c configuration to use
223  */
224 static void
225 run (void *cls,
226      struct GNUNET_SCHEDULER_Handle *scheduler,
227      struct GNUNET_SERVER_Handle *server,
228      const struct GNUNET_CONFIGURATION_Handle *c)
229 {
230   struct GNUNET_TIME_Relative timeout;
231   sched = scheduler;
232   cfg = c;
233   GNUNET_SERVER_add_handlers (server, plugin_handlers);
234   coreAPI =
235   GNUNET_CORE_connect (sched,
236                        cfg,
237                        timeout,
238                        NULL, /* FIXME: anything we want to pass around? */
239                        &core_init,
240                        NULL, /* Don't care about pre-connects */
241                        &handle_core_connect,
242                        &handle_core_disconnect,
243                        NULL,
244                        NULL,
245                        NULL,
246                        NULL,
247                        core_handlers);
248
249   if (coreAPI == NULL)
250     return;
251   /* load (server); Huh? */
252
253   /* Scheduled the task to clean up when shutdown is called */
254
255   cleanup_task = GNUNET_SCHEDULER_add_delayed (sched,
256                                 GNUNET_TIME_UNIT_FOREVER_REL,
257                                 &shutdown_task,
258                                 NULL);
259 }
260
261
262 /**
263  * The main function for the dv service.
264  *
265  * @param argc number of arguments from the command line
266  * @param argv command line arguments
267  * @return 0 ok, 1 on error
268  */
269 int
270 main (int argc, char *const *argv)
271 {
272   return (GNUNET_OK ==
273           GNUNET_SERVICE_run (argc,
274                               argv,
275                               "dv",
276                               GNUNET_SERVICE_OPTION_NONE,
277                               &run, NULL)) ? 0 : 1;
278 }