WiP
[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  * STRUCTURE:
27  * - MESH NETWORK MESSAGES
28  * - DATA STRUCTURES
29  * - GLOBAL VARIABLES
30  * - MESH NETWORK HANDLES
31  * - MESH LOCAL HANDLES
32  * - MAIN FUNCTIONS (main & run)
33  * 
34  * TODO:
35  * - soft stateing (keep-alive (CHANGE?) / timeout / disconnect) -- not a message issue
36  * - error reporting (CREATE/CHANGE/ADD/DEL?) -- new message!
37  * - partial disconnect reporting -- same as error reporting?
38  * - add vs create? change vs. keep-alive? same msg or different ones? -- thinking...
39  * - speed requirement specification (change?) in mesh API -- API call
40  */
41
42 #include "platform.h"
43 #include "gnunet_common.h"
44 #include "gnunet_util_lib.h"
45 #include "gnunet_peer_lib.h"
46 #include "gnunet_core_service.h"
47 #include "gnunet_protocols.h"
48 #include "mesh.h"
49
50
51 /******************************************************************************/
52 /********************      MESH NETWORK MESSAGES     **************************/
53 /******************************************************************************/
54
55 /**
56  * Message for mesh path management
57  */
58 struct GNUNET_MESH_ManipulatePath
59 {
60     /**
61      * Type: GNUNET_MESSAGE_TYPE_MESH_PATH_[CREATE|CHANGE|ADD|DEL]
62      *
63      * Size: sizeof(struct GNUNET_MESH_ManipulatePath) +
64      *       path_length * sizeof (struct GNUNET_PeerIdentity)
65      */
66     struct GNUNET_MessageHeader header;
67
68     /**
69      * Global id of the tunnel this path belongs to,
70      * unique in conjunction with the origin.
71      */
72     uint32_t tid GNUNET_PACKED;
73
74     /**
75      * Information about speed requirements.  If the tunnel cannot sustain the 
76      * minimum bandwidth, packets are to be dropped.
77      */
78     uint32_t speed_min GNUNET_PACKED;
79
80     /**
81      * 64-bit alignment.
82      */
83     uint32_t reserved GNUNET_PACKED;
84
85     /**
86      * path_length structs defining the *whole* path from the origin [0] to the
87      * final destination [path_length-1].
88      */
89     /* struct GNUNET_PeerIdentity peers[path_length]; */
90 };
91
92 /**
93  * Message for mesh data traffic to all tunnel targets.
94  */
95 struct GNUNET_MESH_OriginMulticast
96 {
97     /**
98      * Type: GNUNET_MESSAGE_TYPE_DATA_MULTICAST
99      */
100     struct GNUNET_MessageHeader header;
101
102     /**
103      * TID of the tunnel
104      */
105     uint32_t tid GNUNET_PACKED;
106
107     /**
108      * OID of the tunnel
109      */
110     struct GNUNET_PeerIdentity oid;
111
112     /**
113      * Payload follows
114      */
115 };
116
117
118 /**
119  * Message for mesh data traffic to a particular destination from origin.
120  */
121 struct GNUNET_MESH_DataMessageFromOrigin
122 {
123     /**
124      * Type: GNUNET_MESSAGE_TYPE_DATA_MESSAGE_FROM_ORIGIN
125      */
126     struct GNUNET_MessageHeader header;
127
128     /**
129      * TID of the tunnel
130      */
131     uint32_t tid GNUNET_PACKED;
132
133     /**
134      * OID of the tunnel
135      */
136     struct GNUNET_PeerIdentity oid;
137
138     /**
139      * Destination.
140      */
141     struct GNUNET_PeerIdentity destination;
142
143     /**
144      * Payload follows
145      */
146 };
147
148
149 /**
150  * Message for mesh data traffic from a tunnel participant to origin.
151  */
152 struct GNUNET_MESH_DataMessageToOrigin
153 {
154     /**
155      * Type: GNUNET_MESSAGE_TYPE_DATA_MESSAGE_TO_ORIGIN
156      */
157     struct GNUNET_MessageHeader header;
158
159     /**
160      * TID of the tunnel
161      */
162     uint32_t tid GNUNET_PACKED;
163
164     /**
165      * OID of the tunnel
166      */
167     struct GNUNET_PeerIdentity oid;
168
169     /**
170      * Sender of the message.
171      */
172     struct GNUNET_PeerIdentity sender;
173
174     /**
175      * Payload follows
176      */
177 };
178
179 /**
180  * Message for mesh flow control
181  */
182 struct GNUNET_MESH_SpeedNotify
183 {
184     /**
185      * Type: GNUNET_MESSAGE_TYPE_DATA_SPEED_NOTIFY
186      */
187     struct GNUNET_MessageHeader header;
188
189     /**
190      * TID of the tunnel
191      */
192     uint32_t tid GNUNET_PACKED;
193
194     /**
195      * OID of the tunnel
196      */
197     struct GNUNET_PeerIdentity oid;
198
199     /**
200      * Slowest link down the path (above minimum speed requirement).
201      */
202     uint32_t speed_min;
203
204 };
205
206 /******************************************************************************/
207 /************************      DATA STRUCTURES     ****************************/
208 /******************************************************************************/
209
210 /**
211  * All the states a peer participating in a tunnel can be in.
212  */
213 enum PeerState
214 {
215     /**
216      * Request sent, not yet answered.
217      */
218     MESH_PEER_WAITING,
219
220     /**
221      * Peer connected and ready to accept data
222      */
223     MESH_PEER_READY,
224
225     /**
226      * Peer connected previosly but not responding
227      */
228     MESH_PEER_RECONNECTING,
229
230 };
231
232 /**
233  * Struct containing all information regarding a given peer
234  */
235 struct PeerInfo
236 {
237     /**
238      * ID of the peer
239      */
240     GNUNET_PEER_Id              id;
241
242     /**
243      * Is the peer reachable? Is the peer even connected?
244      */
245     enum PeerState              state;
246
247     /**
248      * Who to send the data to --- FIXME what about multiple (alternate) paths?
249      */
250     GNUNET_PEER_Id              first_hop;
251
252     /**
253      * Max data rate to this peer
254      */
255     uint32_t                    max_speed;
256 };
257
258
259 typedef uint32_t MESH_PathID;
260 /**
261  * Information regarding a path
262  */
263 struct Path
264 {
265     /**
266      * Double linked list
267      */
268     struct Path                 *next;
269     struct Path                 *prev;
270
271     /**
272      * Id of the path, in case it's needed
273      */
274     MESH_PathID                 id;
275
276     /**
277      * Whether the path is serving traffic in a tunnel or is a backup
278      */
279     int                         in_use;
280
281     /**
282      * List of all the peers that form the path from origin to target
283      */
284     GNUNET_PEER_Id              *peers;
285 };
286
287 struct MESH_queue
288 {
289     /**
290      * Double linked list
291      */
292     struct MESH_queue          *next;
293     struct MESH_queue          *prev;
294
295     /**
296      * Size of the message to transmit
297      */
298     unsigned int                size;
299     
300     /**
301      * How old is the data?
302      */
303     struct GNUNET_TIME_Absolute timestamp;
304     
305     /**
306      * Data itself
307      */
308     struct GNUNET_MessageHeader *data;
309 };
310
311
312 struct Client; /* FWD declaration */
313 /**
314  * Struct containing all information regarding a tunnel
315  * For an intermediate node the improtant info used will be:
316  * - OID        \ To identify
317  * - TID        / the tunnel
318  * - paths[0]   | To know where to send it next
319  * - metainfo: ready, speeds, accounting
320  * For an end node more fields will be needed (client-handling)
321  */
322 struct MESH_tunnel
323 {
324
325     /**
326      * Double linked list
327      */
328     struct MESH_tunnel          *next;
329     struct MESH_tunnel          *prev;
330
331     /**
332      * Origin ID: Node that created the tunnel
333      */
334     GNUNET_PEER_Id              oid;
335
336     /**
337      * Tunnel number (unique for a given oid)
338      */
339     MESH_TunnelID               tid;
340
341     /**
342      * Minimal speed for this tunnel in kb/s
343      */
344     uint32_t                    speed_min;
345
346     /**
347      * Maximal speed for this tunnel in kb/s
348      */
349     uint32_t                    speed_max;
350
351     /**
352      * Last time the tunnel was used
353      */
354     struct GNUNET_TIME_Absolute timestamp;
355
356     /**
357      * Peers in the tunnel, for future optimizations
358      */
359     struct PeerInfo             *peers_head;
360     struct PeerInfo             *peers_tail;
361
362     /**
363      * Number of peers that are connected and potentially ready to receive data
364      */
365     unsigned int                peers_ready;
366
367     /**
368      * Number of peers that have been added to the tunnel
369      */
370     unsigned int                peers_total;
371
372     /**
373      * Paths (used and backup)
374      */
375     struct Path                 *paths_head;
376     struct Path                 *paths_tail;
377
378     /**
379      * If this tunnel was created by a local client, what's its handle?
380      */
381     struct Client               *client;
382
383     /**
384      * Messages ready to transmit
385      */
386     struct MESH_queue           *out_head;
387     struct MESH_queue           *out_tail;
388
389     /**
390      * Messages received and not processed
391      */
392     struct MESH_queue           *in_head;
393     struct MESH_queue           *in_tail;
394
395 };
396
397 /**
398  * Struct containing information about a client of the service
399  */
400 struct Client
401 {
402     /**
403      * Double linked list
404      */
405     struct Client               *next;
406     struct Client               *prev;
407
408     /**
409      * Tunnels that belong to this client, for convenience on disconnect
410      */
411     struct MESH_tunnel          *tunnels_head;
412     struct MESH_tunnel          *tunnels_tail;
413
414     /**
415      * Handle to communicate with the client
416      */
417     struct GNUNET_SERVER_Client *handle;
418
419     /**
420      * Messages that this client has declared interest in
421      */
422     GNUNET_MESH_ApplicationType *messages_subscribed;
423     unsigned int                subscription_counter;
424
425 };
426
427 /******************************************************************************/
428 /***********************      GLOBAL VARIABLES     ****************************/
429 /******************************************************************************/
430
431 /**
432  * All the clients
433  */
434 static struct Client            *clients_head;
435 static struct Client            *clients_tail;
436
437 /**
438  * All the tunnels
439  */
440 static struct MESH_tunnel       *tunnels_head;
441 static struct MESH_tunnel       *tunnels_tail;
442
443 /**
444  * All the paths (for future path optimization)
445  */
446 // static struct Path             *paths_head;
447 // static struct Path             *paths_tail;
448
449 /******************************************************************************/
450 /********************      MESH NETWORK HANDLERS     **************************/
451 /******************************************************************************/
452
453 /**
454  * Core handler for path creation
455  * struct GNUNET_CORE_MessageHandler
456  *
457  * @param cls closure
458  * @param message message
459  * @param peer peer identity this notification is about
460  * @param atsi performance data
461  * @return GNUNET_OK to keep the connection open,
462  *         GNUNET_SYSERR to close it (signal serious error)
463  *
464  */
465 static int
466 handle_mesh_path_create (void *cls,
467                               const struct GNUNET_PeerIdentity *peer,
468                               const struct GNUNET_MessageHeader *message,
469                               const struct GNUNET_TRANSPORT_ATS_Information
470                               *atsi)
471 {
472   /*
473    * EXAMPLE OF USING THE API
474    * NOT ACTUAL CODE!!!!!
475    */
476   /*client *c;
477   tunnel *t;
478
479   t = new;
480   GNUNET_CONTAINER_DLL_insert (c->my_tunnels_head,
481                                c->my_tunnels_tail,
482                                t);
483
484   while (NULL != (t = c->my_tunnels_head))
485     {
486       GNUNET_CONTAINER_DLL_remove (c->my_tunnels_head,
487                                    c->my_tunnels_tail,
488                                    t);
489       GNUNET_free (t);
490     }
491   */
492
493
494     /* Extract path */
495     /* Find origin & self */
496     /* Search for origin in local tunnels */
497     /* Create tunnel / add path */
498     /* Retransmit to next link in chain, if any (core_notify + callback) */
499     return GNUNET_OK;
500 }
501
502 /**
503  * Core handler for mesh network traffic
504  *
505  * @param cls closure
506  * @param message message
507  * @param peer peer identity this notification is about
508  * @param atsi performance data
509  * @return GNUNET_OK to keep the connection open,
510  *         GNUNET_SYSERR to close it (signal serious error)
511  */
512 static int
513 handle_mesh_network_traffic (void *cls,
514                              const struct GNUNET_PeerIdentity *peer,
515                              const struct GNUNET_MessageHeader *message,
516                              const struct GNUNET_TRANSPORT_ATS_Information
517                              *atsi)
518 {
519     if(GNUNET_MESSAGE_TYPE_MESH_DATA_GO == ntohs(message->type)) {
520         /* Retransmit to next in path of tunnel identified by message */
521         return GNUNET_OK;
522     } else { /* GNUNET_MESSAGE_TYPE_MESH_DATA_BACK */
523         /* Retransmit to previous in path of tunnel identified by message */
524         return GNUNET_OK;
525     }
526 }
527
528 /**
529  * Functions to handle messages from core
530  */
531 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
532   {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
533   {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_GO, 0},
534   {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_BACK, 0},
535   {NULL, 0, 0}
536 };
537
538
539
540 /******************************************************************************/
541 /*********************       MESH LOCAL HANDLES      **************************/
542 /******************************************************************************/
543
544 /**
545  * Client exisits
546  * @param client the client to check
547  * @return non-zero if client exists in the global DLL
548  */
549 int
550 client_exists (struct GNUNET_SERVER_Client *client) {
551     struct Client       *c;
552     for (c = clients_head; c != clients_head; c = c->next) {
553         if(c->handle == client) return 1;
554     }
555     return 0;
556 }
557
558 /**
559  * Handler for client disconnection
560  *
561  * @param cls closure
562  * @param client identification of the client; NULL
563  *        for the last call when the server is destroyed
564  */
565 static void
566 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
567 {
568     struct Client       *c, *next;
569     struct MESH_tunnel  *t;
570
571     /* If there are no clients registered, something is wrong... or is it?
572      * FIXME: what happens if a client connects, doesn't send a MESH_Connect
573      * and disconnects? Does the service get a disconnect notification anyway?
574      */
575     GNUNET_assert(NULL != clients_head);
576     for (c = clients_head; c != clients_head; c = next) {
577         if (c->handle == client) {
578             GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, c);
579             while (NULL != (t = c->tunnels_head)) {
580                 GNUNET_CONTAINER_DLL_remove (c->tunnels_head, c->tunnels_tail, t);
581                 GNUNET_CONTAINER_DLL_remove (tunnels_head, tunnels_tail, t);
582                 /* TODO free paths and other tunnel dynamic structures */
583                 GNUNET_free (t);
584             }
585             GNUNET_free (c->messages_subscribed);
586             next = c->next;
587             GNUNET_free (c);
588         } else {
589             next = c->next;
590         }
591     }
592
593     return;
594 }
595
596 /**
597  * Handler for new clients
598  * 
599  * @param cls closure
600  * @param client identification of the client
601  * @param message the actual message, which includes messages the client wants
602  */
603 static void
604 handle_local_new_client (void *cls,
605                          struct GNUNET_SERVER_Client *client,
606                          const struct GNUNET_MessageHeader *message)
607 {
608     struct Client               *c;
609     unsigned int                payload_size;
610
611     /* Check data sanity */
612     payload_size = message->size - sizeof(struct GNUNET_MessageHeader);
613     if (0 != payload_size % sizeof(GNUNET_MESH_ApplicationType)) {
614         GNUNET_break(0);
615         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
616         return;
617     }
618
619     /* Create new client structure */
620     c = GNUNET_malloc(sizeof(struct Client));
621     c->handle = client;
622     c->tunnels_head = NULL;
623     c->tunnels_tail = NULL;
624     if(payload_size != 0) {
625         c->messages_subscribed = GNUNET_malloc(payload_size);
626         memcpy(c->messages_subscribed, &message[1], payload_size);
627     } else {
628         c->messages_subscribed = NULL;
629     }
630     c->subscription_counter = payload_size/sizeof(GNUNET_MESH_ApplicationType);
631
632     /* Insert new client in DLL */
633     GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c);
634
635     GNUNET_SERVER_receive_done(client, GNUNET_OK);
636 }
637
638 /**
639  * Handler for requests of new tunnels
640  * 
641  * @param cls closure
642  * @param client identification of the client
643  * @param message the actual message
644  */
645 static void
646 handle_local_tunnel_create (void *cls,
647                             struct GNUNET_SERVER_Client *client,
648                             const struct GNUNET_MessageHeader *message)
649 {
650     struct GNUNET_MESH_TunnelMessage    *tunnel_msg;
651     struct MESH_tunnel                  *t;
652
653     /* Sanity check for client registration */
654     if(!client_exists(client)) {
655         GNUNET_break(0);
656         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
657         return;
658     }
659
660     /* Message sanity check */
661     if(sizeof(struct GNUNET_MESH_TunnelMessage) != ntohs(message->size)) {
662         GNUNET_break(0);
663         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
664         return;
665     }
666
667     tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
668     /* Sanity check for tunnel numbering */
669     if(0 == (ntohl(tunnel_msg->tunnel_id) & 0x80000000)) {
670             GNUNET_break(0);
671             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
672             return;
673         }
674     /* Sanity check for duplicate tunnel IDs */
675     for (t = tunnels_head; t != tunnels_head; t = t->next) {
676         if(t->tid == ntohl(tunnel_msg->tunnel_id)) {
677             GNUNET_break(0);
678             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
679             return;
680         }
681     }
682     /* FIXME: calloc? is NULL != 0 on any platform? */
683     t = GNUNET_malloc(sizeof(struct MESH_tunnel));
684     t->tid = ntohl(tunnel_msg->tunnel_id);
685     /* FIXME: t->oid = selfid;*/
686     t->peers_ready = 0;
687     t->peers_total = 0;
688     t->peers_head = NULL;
689     t->peers_tail = NULL;
690     t->paths_head = NULL;
691     t->paths_tail = NULL;
692     t->in_head = NULL;
693     t->in_tail = NULL;
694     t->out_head = NULL;
695     t->out_tail = NULL;
696
697     GNUNET_SERVER_receive_done(client, GNUNET_OK);
698     return;
699 }
700
701 /**
702  * Handler for requests of deleting tunnels
703  * 
704  * @param cls closure
705  * @param client identification of the client
706  * @param message the actual message
707  */
708 static void
709 handle_local_tunnel_destroy (void *cls,
710                              struct GNUNET_SERVER_Client *client,
711                              const struct GNUNET_MessageHeader *message)
712 {
713     /* Sanity check for client registration */
714     if(!client_exists(client)) {
715         GNUNET_break(0);
716         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
717         return;
718     }
719     return;
720 }
721
722 /**
723  * Handler for connection requests to new peers
724  * 
725  * @param cls closure
726  * @param client identification of the client
727  * @param message the actual message (PeerControl)
728  */
729 static void
730 handle_local_connect_add (void *cls,
731                           struct GNUNET_SERVER_Client *client,
732                           const struct GNUNET_MessageHeader *message)
733 {
734     /* Sanity check for client registration */
735     if(!client_exists(client)) {
736         GNUNET_break(0);
737         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
738         return;
739     }
740     return;
741 }
742
743
744 /**
745  * Handler for disconnection requests of peers in a tunnel
746  * 
747  * @param cls closure
748  * @param client identification of the client
749  * @param message the actual message (PeerControl)
750  */
751 static void
752 handle_local_connect_del (void *cls,
753                           struct GNUNET_SERVER_Client *client,
754                           const struct GNUNET_MessageHeader *message)
755 {
756     return;
757 }
758
759
760 /**
761  * Handler for connection requests to new peers by type
762  * 
763  * @param cls closure
764  * @param client identification of the client
765  * @param message the actual message (ConnectPeerByType)
766  */
767 static void
768 handle_local_connect_by_type (void *cls,
769                               struct GNUNET_SERVER_Client *client,
770                               const struct GNUNET_MessageHeader *message)
771 {
772     return;
773 }
774
775
776 /**
777  * Handler for client traffic
778  * 
779  * @param cls closure
780  * @param client identification of the client
781  * @param message the actual message
782  */
783 static void
784 handle_local_network_traffic (void *cls,
785                          struct GNUNET_SERVER_Client *client,
786                          const struct GNUNET_MessageHeader *message)
787 {
788     return;
789 }
790
791 /**
792  * Functions to handle messages from clients
793  */
794 static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
795   {&handle_local_new_client, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
796   {&handle_local_tunnel_create, NULL,
797    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE, 0},
798   {&handle_local_tunnel_destroy, NULL,
799    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY, 0},
800   {&handle_local_connect_add, NULL,
801    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_ADD, 0},
802   {&handle_local_connect_del, NULL,
803    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_DEL, 0},
804   {&handle_local_connect_by_type, NULL,
805    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_BY_TYPE,
806    sizeof(struct GNUNET_MESH_ConnectPeerByType)},
807   {&handle_local_network_traffic, NULL,
808    GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA, 0}, /* FIXME needed? */
809   {&handle_local_network_traffic, NULL,
810    GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA_BROADCAST, 0}, /* FIXME needed? */
811   {NULL, NULL, 0, 0}
812 };
813
814
815 /**
816  * To be called on core init/fail.
817  *
818  * @param cls service closure
819  * @param server handle to the server for this service
820  * @param identity the public identity of this peer
821  * @param publicKey the public key of this peer
822  */
823 static void
824 core_init (void *cls,
825            struct GNUNET_CORE_Handle *server,
826            const struct GNUNET_PeerIdentity *identity,
827            const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
828 {
829     return;
830 }
831
832 /**
833  * Method called whenever a given peer connects.
834  *
835  * @param cls closure
836  * @param peer peer identity this notification is about
837  * @param atsi performance data for the connection
838  */
839 static void
840 core_connect (void *cls,
841               const struct GNUNET_PeerIdentity *peer,
842               const struct GNUNET_TRANSPORT_ATS_Information *atsi)
843 {
844     return;
845 }
846
847 /**
848  * Method called whenever a peer disconnects.
849  *
850  * @param cls closure
851  * @param peer peer identity this notification is about
852  */
853 static void
854 core_disconnect (void *cls,
855                 const struct
856                 GNUNET_PeerIdentity *peer)
857 {
858     return;
859 }
860
861 /******************************************************************************/
862 /************************      MAIN FUNCTIONS      ****************************/
863 /******************************************************************************/
864
865 /**
866  * Process mesh requests. FIXME NON FUNCTIONAL, SKELETON
867  *
868  * @param cls closure
869  * @param server the initialized server
870  * @param c configuration to use
871  */
872 static void
873 run (void *cls,
874      struct GNUNET_SERVER_Handle *server,
875      const struct GNUNET_CONFIGURATION_Handle *c)
876 {
877   struct GNUNET_CORE_Handle *core;
878
879   GNUNET_SERVER_add_handlers (server, plugin_handlers);
880   GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
881   core = GNUNET_CORE_connect (c,                        /* Main configuration */
882                             32,                                 /* queue size */
883                             NULL,         /* Closure passed to MESH functions */
884                             &core_init,      /* Call core_init once connected */
885                             &core_connect,                 /* Handle connects */
886                             &core_disconnect,  /* remove peers on disconnects */
887                             NULL,       /* Do we care about "status" updates? */
888                             NULL, /* Don't notify about all incoming messages */
889                             GNUNET_NO,     /* For header only in notification */
890                             NULL, /* Don't notify about all outbound messages */
891                             GNUNET_NO,    /* For header-only out notification */
892                             core_handlers);        /* Register these handlers */
893
894   if (core == NULL)
895     return;
896 }
897
898 /**
899  * The main function for the mesh service.
900  *
901  * @param argc number of arguments from the command line
902  * @param argv command line arguments
903  * @return 0 ok, 1 on error
904  */
905 int
906 main (int argc, char *const *argv)
907 {
908     int ret;
909
910     ret = (GNUNET_OK ==
911            GNUNET_SERVICE_run (argc,
912                                argv,
913                                "mesh",
914                                GNUNET_SERVICE_OPTION_NONE,
915                                &run, NULL)) ? 0 : 1;
916     return ret;
917     }