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