nowarn
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh.c
1 /*
2      This file is part of GNUnet.
3      (C) 2001 - 2011 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 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 mesh/gnunet-service-mesh.c
23  * @brief GNUnet MESH service
24  * @author Bartlomiej Polot
25  *
26  * TODO:
27  * - soft stateing (keep-alive (CHANGE?) / timeout / disconnect) -- not a message issue
28  * - error reporting (CREATE/CHANGE/ADD/DEL?) -- new message!
29  * - partial disconnect reporting -- same as error reporting?
30  * - add vs create? change vs. keep-alive? same msg or different ones? -- thinking...
31  * - speed requirement specification (change?) in mesh API -- API call
32  */
33
34 #include "platform.h"
35 #include "gnunet_common.h"
36 #include "gnunet_util_lib.h"
37 #include "gnunet_peer_lib.h"
38 #include "gnunet_core_service.h"
39 #include "gnunet_protocols.h"
40 #include "mesh.h"
41
42
43 /******************************************************************************/
44 /********************      MESH NETWORK MESSAGES     **************************/
45 /******************************************************************************/
46
47 /**
48  * Message for mesh path management
49  */
50 struct GNUNET_MESH_ManipulatePath
51 {
52     /**
53      * Type: GNUNET_MESSAGE_TYPE_MESH_PATH_[CREATE|CHANGE|ADD|DEL]
54      *
55      * Size: sizeof(struct GNUNET_MESH_ManipulatePath) + path_length * sizeof (struct GNUNET_PeerIdentity)
56      */
57     struct GNUNET_MessageHeader header;
58
59     /**
60      * (global) Id of the tunnel this path belongs to, unique in conjunction with the origin.
61      */
62     uint32_t tid GNUNET_PACKED;
63
64     /**
65      * Information about speed requirements.  If the tunnel cannot sustain the 
66      * minimum bandwidth, packets are to be dropped.
67      */
68     uint32_t speed_min GNUNET_PACKED;
69
70     /**
71      * 64-bit alignment.
72      */
73     uint32_t reserved GNUNET_PACKED;
74
75     /**
76      * path_length structs defining the *whole* path from the origin [0] to the
77      * final destination [path_length-1].
78      */
79   // struct GNUNET_PeerIdentity peers[path_length];
80 };
81
82 /**
83  * Message for mesh data traffic to all tunnel targets.
84  */
85 struct GNUNET_MESH_OriginMulticast
86 {
87     /**
88      * Type: GNUNET_MESSAGE_TYPE_DATA_MULTICAST
89      */
90     struct GNUNET_MessageHeader header;
91
92     /**
93      * TID of the tunnel
94      */
95     uint32_t tid GNUNET_PACKED;
96
97     /**
98      * OID of the tunnel
99      */
100     struct GNUNET_PeerIdentity oid;
101
102     /**
103      * Payload follows
104      */
105 };
106
107
108 /**
109  * Message for mesh data traffic to a particular destination from origin.
110  */
111 struct GNUNET_MESH_DataMessageFromOrigin
112 {
113     /**
114      * Type: GNUNET_MESSAGE_TYPE_DATA_MESSAGE_FROM_ORIGIN
115      */
116     struct GNUNET_MessageHeader header;
117
118     /**
119      * TID of the tunnel
120      */
121     uint32_t tid GNUNET_PACKED;
122
123     /**
124      * OID of the tunnel
125      */
126     struct GNUNET_PeerIdentity oid;
127
128     /**
129      * Destination.
130      */
131     struct GNUNET_PeerIdentity destination;
132
133     /**
134      * Payload follows
135      */
136 };
137
138
139 /**
140  * Message for mesh data traffic from a tunnel participant to origin.
141  */
142 struct GNUNET_MESH_DataMessageToOrigin
143 {
144     /**
145      * Type: GNUNET_MESSAGE_TYPE_DATA_MESSAGE_TO_ORIGIN
146      */
147     struct GNUNET_MessageHeader header;
148
149     /**
150      * TID of the tunnel
151      */
152     uint32_t tid GNUNET_PACKED;
153
154     /**
155      * OID of the tunnel
156      */
157     struct GNUNET_PeerIdentity oid;
158
159     /**
160      * Sender of the message.
161      */
162     struct GNUNET_PeerIdentity sender;
163
164     /**
165      * Payload follows
166      */
167 };
168
169 /**
170  * Message for mesh flow control
171  */
172 struct GNUNET_MESH_SpeedNotify
173 {
174     /**
175      * Type: GNUNET_MESSAGE_TYPE_DATA_SPEED_NOTIFY
176      */
177     struct GNUNET_MessageHeader header;
178
179     /**
180      * TID of the tunnel
181      */
182     uint32_t tid GNUNET_PACKED;
183
184     /**
185      * OID of the tunnel
186      */
187     struct GNUNET_PeerIdentity oid;
188
189     /**
190      * Slowest link down the path (above minimum speed requirement).
191      */
192     uint32_t speed_min;
193
194 };
195
196 /******************************************************************************/
197 /************************      DATA STRUCTURES     ****************************/
198 /******************************************************************************/
199
200 /**
201  * All the states a peer participating in a tunnel can be in.
202  */
203 enum PeerState
204 {
205     /**
206      * Request sent, not yet answered.
207      */
208     MESH_PEER_WAITING,
209
210     /**
211      * Peer connected and ready to accept data
212      */
213     MESH_PEER_READY,
214
215     /**
216      * Peer connected previosly but not responding
217      */
218     MESH_PEER_UNAVAILABLE,
219
220     /**
221      * Peer requested but not ever connected
222      */
223     MESH_PEER_UNREACHABLE
224 };
225
226 /**
227  * Struct containing all information regarding a given peer
228  */
229 struct PeerInfo
230 {
231     /**
232      * ID of the peer
233      */
234     GNUNET_PEER_Id id;
235
236     /**
237      * Is the peer reachable? Is the peer even connected?
238      */
239     enum PeerState state;
240
241     /**
242      * Who to send the data to --- what about multiple (alternate) paths?
243      */
244     GNUNET_PEER_Id first_hop;
245
246     /**
247      * Max data rate to this peer
248      */
249     uint32_t max_speed;
250 };
251
252 /**
253  * Information regarding a path
254  */
255 struct Path
256 {
257     /**
258      * Id of the path, in case it's needed
259      */
260     uint32_t id;
261
262     /**
263      * Whether the path is serving traffic in a tunnel or is a backup
264      */
265     int in_use;
266
267     /**
268      * List of all the peers that form the path from origin to target
269      */
270     GNUNET_PEER_Id *peers;
271 };
272
273 /**
274  * Struct containing all information regarding a tunnel
275  * For an intermediate node the improtant info used will be:
276  * - OID        \ To identify
277  * - TID        / the tunnel
278  * - paths[0]   | To know where to send it next
279  * - metainfo: ready, speeds, accounting
280  * For an end node more fields will be needed (client-handling)
281  */
282 struct MESH_tunnel
283 {
284
285   struct MESH_tunnel *next;
286
287   struct MESH_tunnel *prev;
288
289     /**
290      * Origin ID: Node that created the tunnel
291      */
292     GNUNET_PEER_Id oid;
293
294     /**
295      * Tunnel number (unique for a given oid)
296      */
297     uint32_t tid;
298
299     /**
300      * Whether the tunnel is in  a state to transmit data
301      */
302     int ready;
303
304     /**
305      * Minimal speed for this tunnel in kb/s
306      */
307     uint32_t speed_min;
308
309     /**
310      * Maximal speed for this tunnel in kb/s
311      */
312     uint32_t speed_max;
313
314     /**
315      * Last time the tunnel was used
316      */
317     struct GNUNET_TIME_Absolute timestamp;
318
319     /**
320      * Peers in the tunnel, for future optimizations
321      */
322     struct PeerInfo *peers;
323
324     /**
325      * Paths (used and backup)
326      */
327     struct Path *paths;
328
329     /**
330      * Messages ready to transmit??? -- real queues needed
331      */
332     struct GNUNET_MessageHeader *msg_out;
333
334     /**
335      * Messages received and not processed??? -- real queues needed
336      */
337     struct GNUNET_MessageHeader *msg_in;
338
339     /**
340      * If this tunnel was created by a local client, what's its handle?
341      */
342     struct GNUNET_SERVER_Client *initiator;
343 };
344
345 /**
346  * So, I'm an endpoint. Why am I receiveing traffic?
347  * Who is interested in this? How to communicate with them?
348  */
349 struct Client
350 {
351
352   struct Client *next;
353
354   struct Client *prev;
355
356   struct MESH_tunnel *my_tunnels_head;
357
358   struct MESH_tunnel *my_tunnels_tail;
359
360     /**
361      * If this tunnel was created by a local client, what's its handle?
362      */
363     struct GNUNET_SERVER_Client *handle;
364
365   unsigned int messages_subscribed_counter;
366
367   uint16_t *messages_subscribed;
368
369 };
370
371
372 // static struct MESH_tunnel *tunnel_participation_head;
373
374 // static struct MESH_tunnel *tunnel_participation_tail;
375
376
377
378
379 /******************************************************************************/
380 /********************      MESH NETWORK HANDLERS     **************************/
381 /******************************************************************************/
382
383 /**
384  * Core handler for path creation
385  * struct GNUNET_CORE_MessageHandler
386  *
387  * @param cls closure
388  * @param message message
389  * @param peer peer identity this notification is about
390  * @param atsi performance data
391  * @return GNUNET_OK to keep the connection open,
392  *         GNUNET_SYSERR to close it (signal serious error)
393  *
394  */
395 static int
396 handle_mesh_path_create (void *cls,
397                               const struct GNUNET_PeerIdentity *peer,
398                               const struct GNUNET_MessageHeader *message,
399                               const struct GNUNET_TRANSPORT_ATS_Information
400                               *atsi)
401 {
402   /*
403    * EXAMPLE OF USING THE API
404    * NOT ACTUAL CODE!!!!!
405    */
406   /*client *c;
407   tunnel *t;
408
409   t = new;
410   GNUNET_CONTAINER_DLL_insert (c->my_tunnels_head,
411                                c->my_tunnels_tail,
412                                t);
413
414   while (NULL != (t = c->my_tunnels_head))
415     {
416       GNUNET_CONTAINER_DLL_remove (c->my_tunnels_head,
417                                    c->my_tunnels_tail,
418                                    t);
419       GNUNET_free (t);
420     }
421   */
422
423
424     /* Extract path */
425     /* Find origin & self */
426     /* Search for origin in local tunnels */
427     /* Create tunnel / add path */
428     /* Retransmit to next link in chain, if any (core_notify + callback) */
429     return GNUNET_OK;
430 }
431
432 /**
433  * Core handler for mesh network traffic
434  *
435  * @param cls closure
436  * @param message message
437  * @param peer peer identity this notification is about
438  * @param atsi performance data
439  * @return GNUNET_OK to keep the connection open,
440  *         GNUNET_SYSERR to close it (signal serious error)
441  */
442 static int
443 handle_mesh_network_traffic (void *cls,
444                              const struct GNUNET_PeerIdentity *peer,
445                              const struct GNUNET_MessageHeader *message,
446                              const struct GNUNET_TRANSPORT_ATS_Information
447                              *atsi)
448 {
449     if(GNUNET_MESSAGE_TYPE_MESH_DATA_GO == ntohs(message->type)) {
450         /* Retransmit to next in path of tunnel identified by message */
451         return GNUNET_OK;
452     } else { /* GNUNET_MESSAGE_TYPE_MESH_DATA_BACK */
453         /* Retransmit to previous in path of tunnel identified by message */
454         return GNUNET_OK;
455     }
456 }
457
458 /**
459  * Functions to handle messages from core
460  */
461 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
462   {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
463   {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_GO, 0},
464   {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_BACK, 0},
465   {NULL, 0, 0}
466 };
467
468
469
470 /******************************************************************************/
471 /*********************       MESH LOCAL HANDLES      **************************/
472 /******************************************************************************/
473
474 /**
475  * Handler for client disconnection
476  *
477  * @param cls closure
478  * @param client identification of the client; NULL
479  *        for the last call when the server is destroyed
480  */
481 static void
482 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
483 {
484     /* Remove client from list, delete all timers and queues associated */
485     return;
486 }
487
488 /**
489  * Handler for new clients
490  * 
491  * @param cls closure
492  * @param client identification of the client
493  * @param message the actual message, which includes messages the client wants
494  */
495 static void
496 handle_local_new_client (void *cls,
497                          struct GNUNET_SERVER_Client *client,
498                          const struct GNUNET_MessageHeader *message)
499 {
500     return;
501 }
502
503 /**
504  * Handler for connection requests
505  * 
506  * @param cls closure
507  * @param client identification of the client
508  * @param message the actual message
509  */
510 static void
511 handle_local_connect (void *cls,
512                          struct GNUNET_SERVER_Client *client,
513                          const struct GNUNET_MessageHeader *message)
514 {
515     return;
516 }
517
518 /**
519  * Handler for client traffic
520  * 
521  * @param cls closure
522  * @param client identification of the client
523  * @param message the actual message
524  */
525 static void
526 handle_local_network_traffic (void *cls,
527                          struct GNUNET_SERVER_Client *client,
528                          const struct GNUNET_MessageHeader *message)
529 {
530     return;
531 }
532
533 /**
534  * Functions to handle messages from clients
535  */
536 /* MESSAGES DEFINED:
537 #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT              272
538 #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_ANY     273
539 #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_ALL     274
540 #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_ADD     275
541 #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_DEL     276
542 #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_BY_TYPE 277
543 #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_CANCEL  278
544 #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_TRANSMIT_READY       279
545 #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATED       280
546 #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROYED     281
547 #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA                 282
548 #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA_BROADCAST       283
549  */
550 static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
551   {&handle_local_new_client, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
552   {&handle_local_connect, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_ANY, 0},
553   {&handle_local_connect, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_ALL, 0},
554   {&handle_local_connect, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_ADD, 0},
555   {&handle_local_connect, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_DEL, 0},
556   {&handle_local_connect, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_BY_TYPE, sizeof(struct GNUNET_MESH_ConnectPeerByType)},
557   {&handle_local_connect, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_CANCEL, 0},
558   {&handle_local_network_traffic, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_TRANSMIT_READY, 0},
559   {&handle_local_network_traffic, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA, 0}, /* FIXME needed? */
560   {&handle_local_network_traffic, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA_BROADCAST, 0}, /* FIXME needed? */
561   {NULL, NULL, 0, 0}
562 };
563
564
565 /**
566  * To be called on core init/fail.
567  *
568  * @param cls service closure
569  * @param server handle to the server for this service
570  * @param identity the public identity of this peer
571  * @param publicKey the public key of this peer
572  */
573 static void
574 core_init (void *cls,
575            struct GNUNET_CORE_Handle *server,
576            const struct GNUNET_PeerIdentity *identity,
577            const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
578 {
579     return;
580 }
581
582 /**
583  * Method called whenever a given peer connects.
584  *
585  * @param cls closure
586  * @param peer peer identity this notification is about
587  * @param atsi performance data for the connection
588  */
589 static void
590 core_connect (void *cls,
591               const struct GNUNET_PeerIdentity *peer,
592               const struct GNUNET_TRANSPORT_ATS_Information *atsi)
593 {
594     return;
595 }
596
597 /**
598  * Method called whenever a peer disconnects.
599  *
600  * @param cls closure
601  * @param peer peer identity this notification is about
602  */
603 static void
604 core_disconnect (void *cls,
605                 const struct
606                 GNUNET_PeerIdentity *peer)
607 {
608     return;
609 }
610
611 /**
612  * Process mesh requests. FIXME NON FUNCTIONAL, SKELETON
613  *
614  * @param cls closure
615  * @param server the initialized server
616  * @param c configuration to use
617  */
618 static void
619 run (void *cls,
620      struct GNUNET_SERVER_Handle *server,
621      const struct GNUNET_CONFIGURATION_Handle *c)
622 {
623   struct GNUNET_CORE_Handle *core;
624
625   GNUNET_SERVER_add_handlers (server, plugin_handlers);
626   GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
627   core = GNUNET_CORE_connect (c,   /* Main configuration */
628                             32,       /* queue size */
629                             NULL,  /* Closure passed to MESH functions */
630                             &core_init,    /* Call core_init once connected */
631                             &core_connect,  /* Handle connects */
632                             &core_disconnect,       /* remove peers on disconnects */
633                             NULL,  /* Do we care about "status" updates? */
634                             NULL,  /* Don't want notified about all incoming messages */
635                             GNUNET_NO,     /* For header only inbound notification */
636                             NULL,  /* Don't want notified about all outbound messages */
637                             GNUNET_NO,     /* For header only outbound notification */
638                             core_handlers);        /* Register these handlers */
639
640   if (core == NULL)
641     return;
642 }
643
644 /**
645  * The main function for the mesh service.
646  *
647  * @param argc number of arguments from the command line
648  * @param argv command line arguments
649  * @return 0 ok, 1 on error
650  */
651 int
652 main (int argc, char *const *argv)
653 {
654   int ret;
655
656   ret = (GNUNET_OK ==
657          GNUNET_SERVICE_run (argc,
658                              argv,
659                              "mesh",
660                              GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
661   return ret;
662 }