6c70d9684c4abb31aa29f9bc2df0250ef9ef3043
[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     int                         length;
298 };
299
300 struct MESH_queue
301 {
302     /**
303      * Double linked list
304      */
305     struct MESH_queue          *next;
306     struct MESH_queue          *prev;
307
308     /**
309      * Size of the message to transmit
310      */
311     unsigned int                size;
312
313     /**
314      * How old is the data?
315      */
316     struct GNUNET_TIME_Absolute timestamp;
317
318     /**
319      * Data itself
320      */
321     struct GNUNET_MessageHeader *data;
322 };
323
324
325 struct Client; /* FWD declaration */
326 /**
327  * Struct containing all information regarding a tunnel
328  * For an intermediate node the improtant info used will be:
329  * - OID        \ To identify
330  * - TID        / the tunnel
331  * - paths[0]   | To know where to send it next
332  * - metainfo: ready, speeds, accounting
333  * For an end node more fields will be needed (client-handling)
334  */
335 struct MESH_tunnel
336 {
337
338     /**
339      * Double linked list
340      */
341     struct MESH_tunnel          *next;
342     struct MESH_tunnel          *prev;
343
344     /**
345      * Origin ID: Node that created the tunnel
346      */
347     GNUNET_PEER_Id              oid;
348
349     /**
350      * Tunnel number (unique for a given oid)
351      */
352     MESH_TunnelID               tid;
353
354     /**
355      * Minimal speed for this tunnel in kb/s
356      */
357     uint32_t                    speed_min;
358
359     /**
360      * Maximal speed for this tunnel in kb/s
361      */
362     uint32_t                    speed_max;
363
364     /**
365      * Last time the tunnel was used
366      */
367     struct GNUNET_TIME_Absolute timestamp;
368
369     /**
370      * Peers in the tunnel, for future optimizations
371      */
372     struct PeerInfo             *peers_head;
373     struct PeerInfo             *peers_tail;
374
375     /**
376      * Number of peers that are connected and potentially ready to receive data
377      */
378     unsigned int                peers_ready;
379
380     /**
381      * Number of peers that have been added to the tunnel
382      */
383     unsigned int                peers_total;
384
385     /**
386      * Paths (used and backup)
387      */
388     struct Path                 *paths_head;
389     struct Path                 *paths_tail;
390
391     /**
392      * If this tunnel was created by a local client, what's its handle?
393      */
394     struct Client               *client;
395
396     /**
397      * Messages ready to transmit
398      */
399     struct MESH_queue           *out_head;
400     struct MESH_queue           *out_tail;
401
402     /**
403      * Messages received and not processed
404      */
405     struct MESH_queue           *in_head;
406     struct MESH_queue           *in_tail;
407
408 };
409
410 /**
411  * Struct containing information about a client of the service
412  */
413 struct Client
414 {
415     /**
416      * Double linked list
417      */
418     struct Client               *next;
419     struct Client               *prev;
420
421     /**
422      * Tunnels that belong to this client, for convenience on disconnect
423      */
424     struct MESH_tunnel          *tunnels_head;
425     struct MESH_tunnel          *tunnels_tail;
426
427     /**
428      * Handle to communicate with the client
429      */
430     struct GNUNET_SERVER_Client *handle;
431
432     /**
433      * Messages that this client has declared interest in
434      */
435     GNUNET_MESH_ApplicationType *messages_subscribed;
436     unsigned int                subscription_counter;
437
438 };
439
440 /******************************************************************************/
441 /***********************      GLOBAL VARIABLES     ****************************/
442 /******************************************************************************/
443
444 /**
445  * All the clients
446  */
447 static struct Client                    *clients_head;
448 static struct Client                    *clients_tail;
449
450 /**
451  * Handle to communicate with core
452  */
453 static struct GNUNET_CORE_Handle        *core_handle;
454
455 /**
456  * Handle to use DHT
457  */
458 static struct GNUNET_DHT_Handle         *dht_handle;
459
460 /**
461  * Local peer own ID (memory efficient handle)
462  */
463 static GNUNET_PEER_Id                   myid;
464
465 /******************************************************************************/
466 /********************      MESH NETWORK HANDLERS     **************************/
467 /******************************************************************************/
468
469 /**
470  * Core handler for path creation
471  * struct GNUNET_CORE_MessageHandler
472  *
473  * @param cls closure
474  * @param message message
475  * @param peer peer identity this notification is about
476  * @param atsi performance data
477  * @return GNUNET_OK to keep the connection open,
478  *         GNUNET_SYSERR to close it (signal serious error)
479  *
480  */
481 static int
482 handle_mesh_path_create (void *cls,
483                               const struct GNUNET_PeerIdentity *peer,
484                               const struct GNUNET_MessageHeader *message,
485                               const struct GNUNET_TRANSPORT_ATS_Information
486                               *atsi)
487 {
488     /* Extract path */
489     /* Find origin & self */
490     /* Search for origin in local tunnels */
491     /* Create tunnel / add path */
492     /* Retransmit to next link in chain, if any (core_notify + callback) */
493     return GNUNET_OK;
494 }
495
496 /**
497  * Core handler for mesh network traffic
498  *
499  * @param cls closure
500  * @param message message
501  * @param peer peer identity this notification is about
502  * @param atsi performance data
503  * @return GNUNET_OK to keep the connection open,
504  *         GNUNET_SYSERR to close it (signal serious error)
505  */
506 static int
507 handle_mesh_network_traffic (void *cls,
508                              const struct GNUNET_PeerIdentity *peer,
509                              const struct GNUNET_MessageHeader *message,
510                              const struct GNUNET_TRANSPORT_ATS_Information
511                              *atsi)
512 {
513     if(GNUNET_MESSAGE_TYPE_MESH_DATA_GO == ntohs(message->type)) {
514         /* Retransmit to next in path of tunnel identified by message */
515         return GNUNET_OK;
516     } else { /* GNUNET_MESSAGE_TYPE_MESH_DATA_BACK */
517         /* Retransmit to previous in path of tunnel identified by message */
518         return GNUNET_OK;
519     }
520 }
521
522 /**
523  * Functions to handle messages from core
524  */
525 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
526   {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
527   {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_GO, 0},
528   {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_BACK, 0},
529   {NULL, 0, 0}
530 };
531
532
533
534 /******************************************************************************/
535 /*********************       MESH LOCAL HANDLES      **************************/
536 /******************************************************************************/
537
538 /**
539  * Check if client has registered with the service and has not disconnected
540  * @param client the client to check
541  * @return non-NULL if client exists in the global DLL
542  */
543 struct Client *
544 client_retrieve (struct GNUNET_SERVER_Client *client) {
545     struct Client       *c;
546     c = clients_head; 
547     while(NULL != c) {
548         if(c->handle == client) return c;
549         if(c == clients_tail)
550             return NULL;
551         else
552             c = c->next;
553     }
554     return NULL;
555 }
556
557 /**
558  * Handler for client disconnection
559  *
560  * @param cls closure
561  * @param client identification of the client; NULL
562  *        for the last call when the server is destroyed
563  */
564 static void
565 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
566 {
567     struct Client       *c, *next;
568     struct MESH_tunnel  *t;
569
570     /* If there are no clients registered, something is wrong... or is it?
571      * FIXME: what happens if a client connects, doesn't send a MESH_Connect
572      * and disconnects? Does the service get a disconnect notification anyway?
573      */
574     GNUNET_assert(NULL != clients_head);
575     c = clients_head;
576     while(NULL != c) {
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                 /* TODO free paths and other tunnel dynamic structures */
582                 GNUNET_free (t);
583             }
584             GNUNET_free (c->messages_subscribed);
585             next = c->next;
586             GNUNET_free (c);
587             c = next;
588         } else {
589             c = c->next;
590         }
591         if(c == clients_head) return; /* Tail already processed? */
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     struct Client                       *c;
653
654     /* Sanity check for client registration */
655     if(NULL == (c = client_retrieve(client))) {
656         GNUNET_break(0);
657         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
658         return;
659     }
660
661     /* Message sanity check */
662     if(sizeof(struct GNUNET_MESH_TunnelMessage) != ntohs(message->size)) {
663         GNUNET_break(0);
664         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
665         return;
666     }
667
668     tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
669     /* Sanity check for tunnel numbering */
670     if(0 == (ntohl(tunnel_msg->tunnel_id) & 0x80000000)) {
671         GNUNET_break(0);
672         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
673         return;
674     }
675     /* Sanity check for duplicate tunnel IDs */
676     t = c->tunnels_head;
677     while(NULL != t) {
678         if(t->tid == ntohl(tunnel_msg->tunnel_id)) {
679             GNUNET_break(0);
680             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
681             return;
682         }
683         if(t == c->tunnels_tail) break;
684         t = t->next;
685     }
686     /* FIXME: calloc? Is NULL != 0 on any platform? */
687     t = GNUNET_malloc(sizeof(struct MESH_tunnel));
688     t->tid = ntohl(tunnel_msg->tunnel_id);
689     t->oid = myid;
690     t->peers_ready = 0;
691     t->peers_total = 0;
692     t->peers_head = NULL;
693     t->peers_tail = NULL;
694     t->paths_head = NULL;
695     t->paths_tail = NULL;
696     t->in_head = NULL;
697     t->in_tail = NULL;
698     t->out_head = NULL;
699     t->out_tail = NULL;
700     t->client = c;
701
702     GNUNET_CONTAINER_DLL_insert(c->tunnels_head, c->tunnels_tail, t);
703
704     GNUNET_SERVER_receive_done(client, GNUNET_OK);
705     return;
706 }
707
708 /**
709  * Handler for requests of deleting tunnels
710  * 
711  * @param cls closure
712  * @param client identification of the client
713  * @param message the actual message
714  */
715 static void
716 handle_local_tunnel_destroy (void *cls,
717                              struct GNUNET_SERVER_Client *client,
718                              const struct GNUNET_MessageHeader *message)
719 {
720     struct GNUNET_MESH_TunnelMessage    *tunnel_msg;
721     struct Client                       *c;
722     struct MESH_tunnel                  *t;
723     MESH_TunnelID                       tid;
724     struct PeerInfo                     *pi;
725
726     /* Sanity check for client registration */
727     if(NULL == (c = client_retrieve(client))) {
728         GNUNET_break(0);
729         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
730         return;
731     }
732     /* Message sanity check */
733     if(sizeof(struct GNUNET_MESH_TunnelMessage) != ntohs(message->size)) {
734         GNUNET_break(0);
735         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
736         return;
737     }
738
739     tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
740
741     /* Tunnel exists? */
742     tid = ntohl(tunnel_msg->tunnel_id);
743     if(NULL == (t = c->tunnels_head)) {
744         GNUNET_break(0);
745         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
746         return;
747     }
748     while(NULL != t) {
749         if(t->tid == tid) {
750             break;
751         }
752         if(t == c->tunnels_tail) {
753             GNUNET_break(0);
754             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
755             return;
756         }
757         t = t->next;
758     }
759
760     GNUNET_CONTAINER_DLL_remove(c->tunnels_head, c->tunnels_tail, t);
761
762     for(pi = t->peers_head; pi != NULL; pi = t->peers_head) {
763         GNUNET_PEER_change_rc(pi->id, -1);
764         GNUNET_CONTAINER_DLL_remove(t->peers_head, t->peers_tail, pi);
765         GNUNET_free(pi);
766     }
767     GNUNET_free(t);
768
769     GNUNET_SERVER_receive_done(client, GNUNET_OK);
770     return;
771 }
772
773 /**
774  * Handler for connection requests to new peers
775  * 
776  * @param cls closure
777  * @param client identification of the client
778  * @param message the actual message (PeerControl)
779  */
780 static void
781 handle_local_connect_add (void *cls,
782                           struct GNUNET_SERVER_Client *client,
783                           const struct GNUNET_MessageHeader *message)
784 {
785     struct GNUNET_MESH_PeerControl      *peer_msg;
786     struct Client                       *c;
787     struct MESH_tunnel                  *t;
788     MESH_TunnelID                       tid;
789     struct PeerInfo                     *peer_info;
790
791
792     /* Sanity check for client registration */
793     if(NULL == (c = client_retrieve(client))) {
794         GNUNET_break(0);
795         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
796         return;
797     }
798
799     peer_msg = (struct GNUNET_MESH_PeerControl *)message;
800     /* Sanity check for message size */
801     if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(peer_msg->header.size)) {
802         GNUNET_break(0);
803         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
804         return;
805     }
806
807     /* Tunnel exists? */
808     tid = ntohl(peer_msg->tunnel_id);
809     if(NULL == (t = c->tunnels_head)) {
810         GNUNET_break(0);
811         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
812         return;
813     }
814     while(NULL != t) {
815         if(t->tid == tid) {
816             break;
817         }
818         if(t == c->tunnels_tail) {
819             GNUNET_break(0);
820             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
821             return;
822         }
823         t = t->next;
824     }
825
826     /* Does client own tunnel? */
827     if(t->client->handle != client) {
828         GNUNET_break(0);
829         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
830         return;
831     }
832
833     /* Ok, add peer to tunnel */
834     peer_info = (struct PeerInfo *) GNUNET_malloc(sizeof(struct PeerInfo));
835     peer_info->id = GNUNET_PEER_intern(&peer_msg->peer);
836     peer_info->state = MESH_PEER_WAITING;
837     t->peers_total++;
838     GNUNET_CONTAINER_DLL_insert(t->peers_head, t->peers_tail, peer_info);
839     /* TODO MESH SEARCH FOR PEER */
840
841     GNUNET_SERVER_receive_done(client, GNUNET_OK);
842     return;
843 }
844
845
846 /**
847  * Handler for disconnection requests of peers in a tunnel
848  * 
849  * @param cls closure
850  * @param client identification of the client
851  * @param message the actual message (PeerControl)
852  */
853 static void
854 handle_local_connect_del (void *cls,
855                           struct GNUNET_SERVER_Client *client,
856                           const struct GNUNET_MessageHeader *message)
857 {
858     struct GNUNET_MESH_PeerControl      *peer_msg;
859     struct Client                       *c;
860     struct MESH_tunnel                  *t;
861     struct Path                         *p;
862     struct Path                         *aux_path;
863     MESH_TunnelID                       tid;
864     GNUNET_PEER_Id                      peer_id;
865     struct PeerInfo                     *peer_info;
866     struct PeerInfo                     *aux_peer_info;
867
868     /* Sanity check for client registration */
869     if(NULL == (c = client_retrieve(client))) {
870         GNUNET_break(0);
871         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
872         return;
873     }
874     peer_msg = (struct GNUNET_MESH_PeerControl *)message;
875     /* Sanity check for message size */
876     if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(peer_msg->header.size)) {
877         GNUNET_break(0);
878         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
879         return;
880     }
881
882     /* Tunnel exists? */
883     tid = ntohl(peer_msg->tunnel_id);
884     if(NULL == (t = c->tunnels_head)) {
885         GNUNET_break(0);
886         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
887         return;
888     }
889     while(NULL != t) {
890         if(t->tid == tid) {
891             break;
892         }
893         if(t == c->tunnels_tail) {
894             GNUNET_break(0);
895             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
896             return;
897         }
898         t = t->next;
899     }
900
901     /* Does client own tunnel? */
902     if(t->client->handle != client) {
903         GNUNET_break(0);
904         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
905         return;
906     }
907
908     /* Ok, delete peer from tunnel */
909     p = t->paths_head;
910     peer_id = GNUNET_PEER_intern(&peer_msg->peer);
911
912     /* Delete paths */
913     while(p != NULL) {
914         if(p->peers[p->length-1] == peer_id) {
915             GNUNET_CONTAINER_DLL_remove(t->paths_head, t->paths_tail, p);
916             GNUNET_PEER_decrement_rcs(p->peers, p->length);
917             aux_path = p;
918             p = p->next;
919             GNUNET_free(aux_path);
920         } else {
921             p = p->next;
922         }
923         if(p == t->paths_head) {
924             break;
925         }
926     }
927
928     /*Delete peer info */
929     peer_info = t->peers_head;
930     while(peer_info != NULL) {
931         if(peer_info->id == peer_id) {
932             GNUNET_CONTAINER_DLL_remove(t->peers_head,
933                                         t->peers_tail,
934                                         peer_info);
935             aux_peer_info = peer_info;
936             peer_info = peer_info->next;
937             GNUNET_free(aux_peer_info);
938         } else {
939             peer_info = peer_info->next;
940         }
941         if(peer_info == t->peers_head) {
942             break;
943         }
944     }
945
946     GNUNET_PEER_change_rc(peer_id, -1);
947
948     GNUNET_SERVER_receive_done(client, GNUNET_OK);
949     return;
950 }
951
952
953 /**
954  * Handler for connection requests to new peers by type
955  * 
956  * @param cls closure
957  * @param client identification of the client
958  * @param message the actual message (ConnectPeerByType)
959  */
960 static void
961 handle_local_connect_by_type (void *cls,
962                               struct GNUNET_SERVER_Client *client,
963                               const struct GNUNET_MessageHeader *message)
964 {
965     /* Sanity check for client registration */
966     if(NULL == client_retrieve(client)) {
967         GNUNET_break(0);
968         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
969         return;
970     }
971     GNUNET_SERVER_receive_done(client, GNUNET_OK);
972     return;
973 }
974
975
976 /**
977  * Handler for client traffic directed to one peer
978  * 
979  * @param cls closure
980  * @param client identification of the client
981  * @param message the actual message
982  */
983 static void
984 handle_local_network_traffic (void *cls,
985                          struct GNUNET_SERVER_Client *client,
986                          const struct GNUNET_MessageHeader *message)
987 {
988     /* Sanity check for client registration */
989     if(NULL == client_retrieve(client)) {
990         GNUNET_break(0);
991         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
992         return;
993     }
994     GNUNET_SERVER_receive_done(client, GNUNET_OK);
995     return;
996 }
997
998 /**
999  * Handler for client traffic directed to all peers in a tunnel
1000  * 
1001  * @param cls closure
1002  * @param client identification of the client
1003  * @param message the actual message
1004  */
1005 static void
1006 handle_local_network_traffic_bcast (void *cls,
1007                                     struct GNUNET_SERVER_Client *client,
1008                                     const struct GNUNET_MessageHeader *message)
1009 {
1010     /* Sanity check for client registration */
1011     if(NULL == client_retrieve(client)) {
1012         GNUNET_break(0);
1013         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1014         return;
1015     }
1016     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1017     return;
1018 }
1019
1020 /**
1021  * Functions to handle messages from clients
1022  */
1023 static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
1024   {&handle_local_new_client, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
1025   {&handle_local_tunnel_create, NULL,
1026    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE, 0},
1027   {&handle_local_tunnel_destroy, NULL,
1028    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY, 0},
1029   {&handle_local_connect_add, NULL,
1030    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_ADD, 0},
1031   {&handle_local_connect_del, NULL,
1032    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_DEL, 0},
1033   {&handle_local_connect_by_type, NULL,
1034    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_BY_TYPE,
1035    sizeof(struct GNUNET_MESH_ConnectPeerByType)},
1036   {&handle_local_network_traffic, NULL,
1037    GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA, 0},
1038   {&handle_local_network_traffic_bcast, NULL,
1039    GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA_BROADCAST, 0},
1040   {NULL, NULL, 0, 0}
1041 };
1042
1043
1044 /**
1045  * To be called on core init/fail.
1046  *
1047  * @param cls service closure
1048  * @param server handle to the server for this service
1049  * @param identity the public identity of this peer
1050  * @param publicKey the public key of this peer
1051  */
1052 static void
1053 core_init (void *cls,
1054            struct GNUNET_CORE_Handle *server,
1055            const struct GNUNET_PeerIdentity *identity,
1056            const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
1057 {
1058     core_handle = server;
1059     myid = GNUNET_PEER_intern(identity);
1060     return;
1061 }
1062
1063 /**
1064  * Method called whenever a given peer connects.
1065  *
1066  * @param cls closure
1067  * @param peer peer identity this notification is about
1068  * @param atsi performance data for the connection
1069  */
1070 static void
1071 core_connect (void *cls,
1072               const struct GNUNET_PeerIdentity *peer,
1073               const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1074 {
1075     return;
1076 }
1077
1078 /**
1079  * Method called whenever a peer disconnects.
1080  *
1081  * @param cls closure
1082  * @param peer peer identity this notification is about
1083  */
1084 static void
1085 core_disconnect (void *cls,
1086                 const struct
1087                 GNUNET_PeerIdentity *peer)
1088 {
1089     return;
1090 }
1091
1092 /******************************************************************************/
1093 /************************      MAIN FUNCTIONS      ****************************/
1094 /******************************************************************************/
1095
1096 /**
1097  * Process mesh requests. FIXME NON FUNCTIONAL, SKELETON
1098  *
1099  * @param cls closure
1100  * @param server the initialized server
1101  * @param c configuration to use
1102  */
1103 static void
1104 run (void *cls,
1105      struct GNUNET_SERVER_Handle *server,
1106      const struct GNUNET_CONFIGURATION_Handle *c)
1107 {
1108
1109   GNUNET_SERVER_add_handlers (server, plugin_handlers);
1110   GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
1111   core_handle = GNUNET_CORE_connect (c,                 /* Main configuration */
1112                             32,                                 /* queue size */
1113                             NULL,         /* Closure passed to MESH functions */
1114                             &core_init,      /* Call core_init once connected */
1115                             &core_connect,                 /* Handle connects */
1116                             &core_disconnect,  /* remove peers on disconnects */
1117                             NULL,       /* Do we care about "status" updates? */
1118                             NULL, /* Don't notify about all incoming messages */
1119                             GNUNET_NO,     /* For header only in notification */
1120                             NULL, /* Don't notify about all outbound messages */
1121                             GNUNET_NO,    /* For header-only out notification */
1122                             core_handlers);        /* Register these handlers */
1123
1124   if (core_handle == NULL) {
1125       GNUNET_break(0);
1126   }
1127   
1128   dht_handle = GNUNET_DHT_connect(c, 100); /* FIXME ht len correct size? */
1129   if (dht_handle == NULL) {
1130       GNUNET_break(0);
1131   }
1132 }
1133
1134 /**
1135  * The main function for the mesh service.
1136  *
1137  * @param argc number of arguments from the command line
1138  * @param argv command line arguments
1139  * @return 0 ok, 1 on error
1140  */
1141 int
1142 main (int argc, char *const *argv)
1143 {
1144     int ret;
1145
1146     ret = (GNUNET_OK ==
1147            GNUNET_SERVICE_run (argc,
1148                                argv,
1149                                "mesh",
1150                                GNUNET_SERVICE_OPTION_NONE,
1151                                &run, NULL)) ? 0 : 1;
1152     return ret;
1153     }