760545021359861967c87617df5a792870927cab
[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  * All the tunnels
451  */
452 static struct MESH_tunnel               *tunnels_head;
453 static struct MESH_tunnel               *tunnels_tail;
454
455 /**
456  * All the paths (for future path optimization)
457  */
458 // static struct Path                   *paths_head;
459 // static struct Path                   *paths_tail;
460
461 /**
462  * Handle to communicate with core
463  */
464 static struct GNUNET_CORE_Handle        *core_handle;
465
466 /**
467  * Handle to use DHT
468  */
469 static struct GNUNET_DHT_Handle         *dht_handle;
470
471 /**
472  * Local peer own ID (memory efficient handle)
473  */
474 static GNUNET_PEER_Id                   myid;
475
476 /******************************************************************************/
477 /********************      MESH NETWORK HANDLERS     **************************/
478 /******************************************************************************/
479
480 /**
481  * Core handler for path creation
482  * struct GNUNET_CORE_MessageHandler
483  *
484  * @param cls closure
485  * @param message message
486  * @param peer peer identity this notification is about
487  * @param atsi performance data
488  * @return GNUNET_OK to keep the connection open,
489  *         GNUNET_SYSERR to close it (signal serious error)
490  *
491  */
492 static int
493 handle_mesh_path_create (void *cls,
494                               const struct GNUNET_PeerIdentity *peer,
495                               const struct GNUNET_MessageHeader *message,
496                               const struct GNUNET_TRANSPORT_ATS_Information
497                               *atsi)
498 {
499     /* Extract path */
500     /* Find origin & self */
501     /* Search for origin in local tunnels */
502     /* Create tunnel / add path */
503     /* Retransmit to next link in chain, if any (core_notify + callback) */
504     return GNUNET_OK;
505 }
506
507 /**
508  * Core handler for mesh network traffic
509  *
510  * @param cls closure
511  * @param message message
512  * @param peer peer identity this notification is about
513  * @param atsi performance data
514  * @return GNUNET_OK to keep the connection open,
515  *         GNUNET_SYSERR to close it (signal serious error)
516  */
517 static int
518 handle_mesh_network_traffic (void *cls,
519                              const struct GNUNET_PeerIdentity *peer,
520                              const struct GNUNET_MessageHeader *message,
521                              const struct GNUNET_TRANSPORT_ATS_Information
522                              *atsi)
523 {
524     if(GNUNET_MESSAGE_TYPE_MESH_DATA_GO == ntohs(message->type)) {
525         /* Retransmit to next in path of tunnel identified by message */
526         return GNUNET_OK;
527     } else { /* GNUNET_MESSAGE_TYPE_MESH_DATA_BACK */
528         /* Retransmit to previous in path of tunnel identified by message */
529         return GNUNET_OK;
530     }
531 }
532
533 /**
534  * Functions to handle messages from core
535  */
536 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
537   {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
538   {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_GO, 0},
539   {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_BACK, 0},
540   {NULL, 0, 0}
541 };
542
543
544
545 /******************************************************************************/
546 /*********************       MESH LOCAL HANDLES      **************************/
547 /******************************************************************************/
548
549 /**
550  * Check if client has registered with the service and has not disconnected
551  * @param client the client to check
552  * @return non-NULL if client exists in the global DLL
553  */
554 struct Client *
555 client_retrieve (struct GNUNET_SERVER_Client *client) {
556     struct Client       *c;
557     for (c = clients_head; c != clients_head; c = c->next) {
558         if(c->handle == client) return c;
559     }
560     return NULL;
561 }
562
563 /**
564  * Handler for client disconnection
565  *
566  * @param cls closure
567  * @param client identification of the client; NULL
568  *        for the last call when the server is destroyed
569  */
570 static void
571 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
572 {
573     struct Client       *c, *next;
574     struct MESH_tunnel  *t;
575
576     /* If there are no clients registered, something is wrong... or is it?
577      * FIXME: what happens if a client connects, doesn't send a MESH_Connect
578      * and disconnects? Does the service get a disconnect notification anyway?
579      */
580     GNUNET_assert(NULL != clients_head);
581     for (c = clients_head; c != clients_head; c = next) {
582         if (c->handle == client) {
583             GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, c);
584             while (NULL != (t = c->tunnels_head)) {
585                 GNUNET_CONTAINER_DLL_remove (c->tunnels_head, c->tunnels_tail, t);
586                 GNUNET_CONTAINER_DLL_remove (tunnels_head, tunnels_tail, t);
587                 /* TODO free paths and other tunnel dynamic structures */
588                 GNUNET_free (t);
589             }
590             GNUNET_free (c->messages_subscribed);
591             next = c->next;
592             GNUNET_free (c);
593         } else {
594             next = c->next;
595         }
596     }
597
598     return;
599 }
600
601 /**
602  * Handler for new clients
603  * 
604  * @param cls closure
605  * @param client identification of the client
606  * @param message the actual message, which includes messages the client wants
607  */
608 static void
609 handle_local_new_client (void *cls,
610                          struct GNUNET_SERVER_Client *client,
611                          const struct GNUNET_MessageHeader *message)
612 {
613     struct Client               *c;
614     unsigned int                payload_size;
615
616     /* Check data sanity */
617     payload_size = message->size - sizeof(struct GNUNET_MessageHeader);
618     if (0 != payload_size % sizeof(GNUNET_MESH_ApplicationType)) {
619         GNUNET_break(0);
620         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
621         return;
622     }
623
624     /* Create new client structure */
625     c = GNUNET_malloc(sizeof(struct Client));
626     c->handle = client;
627     c->tunnels_head = NULL;
628     c->tunnels_tail = NULL;
629     if(payload_size != 0) {
630         c->messages_subscribed = GNUNET_malloc(payload_size);
631         memcpy(c->messages_subscribed, &message[1], payload_size);
632     } else {
633         c->messages_subscribed = NULL;
634     }
635     c->subscription_counter = payload_size/sizeof(GNUNET_MESH_ApplicationType);
636
637     /* Insert new client in DLL */
638     GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c);
639
640     GNUNET_SERVER_receive_done(client, GNUNET_OK);
641 }
642
643 /**
644  * Handler for requests of new tunnels
645  * 
646  * @param cls closure
647  * @param client identification of the client
648  * @param message the actual message
649  */
650 static void
651 handle_local_tunnel_create (void *cls,
652                             struct GNUNET_SERVER_Client *client,
653                             const struct GNUNET_MessageHeader *message)
654 {
655     struct GNUNET_MESH_TunnelMessage    *tunnel_msg;
656     struct MESH_tunnel                  *t;
657     struct Client                       *c;
658
659     /* Sanity check for client registration */
660     if(NULL == (c = client_retrieve(client))) {
661         GNUNET_break(0);
662         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
663         return;
664     }
665
666     /* Message sanity check */
667     if(sizeof(struct GNUNET_MESH_TunnelMessage) != ntohs(message->size)) {
668         GNUNET_break(0);
669         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
670         return;
671     }
672
673     tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
674     /* Sanity check for tunnel numbering */
675     if(0 == (ntohl(tunnel_msg->tunnel_id) & 0x80000000)) {
676         GNUNET_break(0);
677         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
678         return;
679     }
680     /* Sanity check for duplicate tunnel IDs */
681     for (t = tunnels_head; t != tunnels_head; t = t->next) {
682         if(t->tid == ntohl(tunnel_msg->tunnel_id)) {
683             GNUNET_break(0);
684             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
685             return;
686         }
687     }
688     /* FIXME: calloc? Is NULL != 0 on any platform? */
689     t = GNUNET_malloc(sizeof(struct MESH_tunnel));
690     t->tid = ntohl(tunnel_msg->tunnel_id);
691     t->oid = myid;
692     t->peers_ready = 0;
693     t->peers_total = 0;
694     t->peers_head = NULL;
695     t->peers_tail = NULL;
696     t->paths_head = NULL;
697     t->paths_tail = NULL;
698     t->in_head = NULL;
699     t->in_tail = NULL;
700     t->out_head = NULL;
701     t->out_tail = NULL;
702     t->client = c;
703
704     GNUNET_CONTAINER_DLL_insert(tunnels_head, tunnels_tail, t);
705     GNUNET_CONTAINER_DLL_insert(c->tunnels_head, c->tunnels_tail, t);
706
707     GNUNET_SERVER_receive_done(client, GNUNET_OK);
708     return;
709 }
710
711 /**
712  * Handler for requests of deleting tunnels
713  * 
714  * @param cls closure
715  * @param client identification of the client
716  * @param message the actual message
717  */
718 static void
719 handle_local_tunnel_destroy (void *cls,
720                              struct GNUNET_SERVER_Client *client,
721                              const struct GNUNET_MessageHeader *message)
722 {
723     struct GNUNET_MESH_TunnelMessage    *tunnel_msg;
724     struct Client                       *c;
725     struct MESH_tunnel                  *t;
726     MESH_TunnelID                       tid;
727     struct PeerInfo                     *pi;
728
729     /* Sanity check for client registration */
730     if(NULL == (c = client_retrieve(client))) {
731         GNUNET_break(0);
732         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
733         return;
734     }
735     /* Message sanity check */
736     if(sizeof(struct GNUNET_MESH_TunnelMessage) != ntohs(message->size)) {
737         GNUNET_break(0);
738         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
739         return;
740     }
741
742     /* Tunnel exists? */
743     tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
744     tid = ntohl(tunnel_msg->tunnel_id);
745     for (t = tunnels_head; t != tunnels_head; t = t->next) {
746         if(t->tid == tid) {
747             break;
748         }
749     }
750     if(t->tid != tid) {
751         GNUNET_break(0);
752         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
753         return;
754     }
755
756     GNUNET_CONTAINER_DLL_remove(tunnels_head, tunnels_tail, t);
757     GNUNET_CONTAINER_DLL_remove(c->tunnels_head, c->tunnels_tail, t);
758
759     for(pi = t->peers_head; pi != t->peers_tail; pi = t->peers_head) {
760         GNUNET_PEER_change_rc(pi->id, -1);
761         GNUNET_CONTAINER_DLL_remove(t->peers_head, t->peers_tail, pi);
762         GNUNET_free(pi);
763     }
764     GNUNET_free(t);
765
766     GNUNET_SERVER_receive_done(client, GNUNET_OK);
767     return;
768 }
769
770 /**
771  * Handler for connection requests to new peers
772  * 
773  * @param cls closure
774  * @param client identification of the client
775  * @param message the actual message (PeerControl)
776  */
777 static void
778 handle_local_connect_add (void *cls,
779                           struct GNUNET_SERVER_Client *client,
780                           const struct GNUNET_MessageHeader *message)
781 {
782     struct GNUNET_MESH_PeerControl      *peer_msg;
783     struct Client                       *c;
784     struct MESH_tunnel                  *t;
785     MESH_TunnelID                       tid;
786     struct PeerInfo                     *peer_info;
787
788
789     /* Sanity check for client registration */
790     if(NULL == (c = client_retrieve(client))) {
791         GNUNET_break(0);
792         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
793         return;
794     }
795
796     peer_msg = (struct GNUNET_MESH_PeerControl *)message;
797     /* Sanity check for message size */
798     if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(peer_msg->header.size)) {
799         GNUNET_break(0);
800         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
801         return;
802     }
803
804     /* Does tunnel exist? */
805     tid = ntohl(peer_msg->tunnel_id);
806     for(t = c->tunnels_head; t != c->tunnels_head; t = t->next) {
807         if(t->tid == tid) {
808             break;
809         }
810     }
811     if(NULL == t) {
812         GNUNET_break(0);
813         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
814         return;
815     } else {
816         if(t->tid != tid) {
817             GNUNET_break(0);
818             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
819             return;
820         }
821     }
822
823     /* Does client own tunnel? */
824     if(t->client->handle != client) {
825         GNUNET_break(0);
826         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
827         return;
828     }
829
830     /* Ok, add peer to tunnel */
831     peer_info = (struct PeerInfo *) GNUNET_malloc(sizeof(struct PeerInfo));
832     peer_info->id = GNUNET_PEER_intern(&peer_msg->peer);
833     peer_info->state = MESH_PEER_WAITING;
834     t->peers_total++;
835     GNUNET_CONTAINER_DLL_insert(t->peers_head, t->peers_tail, peer_info);
836     /* TODO MESH SEARCH FOR PEER */
837
838     GNUNET_SERVER_receive_done(client, GNUNET_OK);
839     return;
840 }
841
842
843 /**
844  * Handler for disconnection requests of peers in a tunnel
845  * 
846  * @param cls closure
847  * @param client identification of the client
848  * @param message the actual message (PeerControl)
849  */
850 static void
851 handle_local_connect_del (void *cls,
852                           struct GNUNET_SERVER_Client *client,
853                           const struct GNUNET_MessageHeader *message)
854 {
855     /* Sanity check for client registration */
856     if(NULL == client_retrieve(client)) {
857         GNUNET_break(0);
858         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
859         return;
860     }
861     GNUNET_SERVER_receive_done(client, GNUNET_OK);
862     return;
863 }
864
865
866 /**
867  * Handler for connection requests to new peers by type
868  * 
869  * @param cls closure
870  * @param client identification of the client
871  * @param message the actual message (ConnectPeerByType)
872  */
873 static void
874 handle_local_connect_by_type (void *cls,
875                               struct GNUNET_SERVER_Client *client,
876                               const struct GNUNET_MessageHeader *message)
877 {
878     /* Sanity check for client registration */
879     if(NULL == client_retrieve(client)) {
880         GNUNET_break(0);
881         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
882         return;
883     }
884     GNUNET_SERVER_receive_done(client, GNUNET_OK);
885     return;
886 }
887
888
889 /**
890  * Handler for client traffic directed to one peer
891  * 
892  * @param cls closure
893  * @param client identification of the client
894  * @param message the actual message
895  */
896 static void
897 handle_local_network_traffic (void *cls,
898                          struct GNUNET_SERVER_Client *client,
899                          const struct GNUNET_MessageHeader *message)
900 {
901     /* Sanity check for client registration */
902     if(NULL == client_retrieve(client)) {
903         GNUNET_break(0);
904         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
905         return;
906     }
907     GNUNET_SERVER_receive_done(client, GNUNET_OK);
908     return;
909 }
910
911 /**
912  * Handler for client traffic directed to all peers in a tunnel
913  * 
914  * @param cls closure
915  * @param client identification of the client
916  * @param message the actual message
917  */
918 static void
919 handle_local_network_traffic_bcast (void *cls,
920                                     struct GNUNET_SERVER_Client *client,
921                                     const struct GNUNET_MessageHeader *message)
922 {
923     /* Sanity check for client registration */
924     if(NULL == client_retrieve(client)) {
925         GNUNET_break(0);
926         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
927         return;
928     }
929     GNUNET_SERVER_receive_done(client, GNUNET_OK);
930     return;
931 }
932
933 /**
934  * Functions to handle messages from clients
935  */
936 static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
937   {&handle_local_new_client, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
938   {&handle_local_tunnel_create, NULL,
939    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE, 0},
940   {&handle_local_tunnel_destroy, NULL,
941    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY, 0},
942   {&handle_local_connect_add, NULL,
943    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_ADD, 0},
944   {&handle_local_connect_del, NULL,
945    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_DEL, 0},
946   {&handle_local_connect_by_type, NULL,
947    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_BY_TYPE,
948    sizeof(struct GNUNET_MESH_ConnectPeerByType)},
949   {&handle_local_network_traffic, NULL,
950    GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA, 0},
951   {&handle_local_network_traffic_bcast, NULL,
952    GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA_BROADCAST, 0},
953   {NULL, NULL, 0, 0}
954 };
955
956
957 /**
958  * To be called on core init/fail.
959  *
960  * @param cls service closure
961  * @param server handle to the server for this service
962  * @param identity the public identity of this peer
963  * @param publicKey the public key of this peer
964  */
965 static void
966 core_init (void *cls,
967            struct GNUNET_CORE_Handle *server,
968            const struct GNUNET_PeerIdentity *identity,
969            const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
970 {
971     core_handle = server;
972     myid = GNUNET_PEER_intern(identity);
973     return;
974 }
975
976 /**
977  * Method called whenever a given peer connects.
978  *
979  * @param cls closure
980  * @param peer peer identity this notification is about
981  * @param atsi performance data for the connection
982  */
983 static void
984 core_connect (void *cls,
985               const struct GNUNET_PeerIdentity *peer,
986               const struct GNUNET_TRANSPORT_ATS_Information *atsi)
987 {
988     return;
989 }
990
991 /**
992  * Method called whenever a peer disconnects.
993  *
994  * @param cls closure
995  * @param peer peer identity this notification is about
996  */
997 static void
998 core_disconnect (void *cls,
999                 const struct
1000                 GNUNET_PeerIdentity *peer)
1001 {
1002     return;
1003 }
1004
1005 /******************************************************************************/
1006 /************************      MAIN FUNCTIONS      ****************************/
1007 /******************************************************************************/
1008
1009 /**
1010  * Process mesh requests. FIXME NON FUNCTIONAL, SKELETON
1011  *
1012  * @param cls closure
1013  * @param server the initialized server
1014  * @param c configuration to use
1015  */
1016 static void
1017 run (void *cls,
1018      struct GNUNET_SERVER_Handle *server,
1019      const struct GNUNET_CONFIGURATION_Handle *c)
1020 {
1021
1022   GNUNET_SERVER_add_handlers (server, plugin_handlers);
1023   GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
1024   core_handle = GNUNET_CORE_connect (c,                 /* Main configuration */
1025                             32,                                 /* queue size */
1026                             NULL,         /* Closure passed to MESH functions */
1027                             &core_init,      /* Call core_init once connected */
1028                             &core_connect,                 /* Handle connects */
1029                             &core_disconnect,  /* remove peers on disconnects */
1030                             NULL,       /* Do we care about "status" updates? */
1031                             NULL, /* Don't notify about all incoming messages */
1032                             GNUNET_NO,     /* For header only in notification */
1033                             NULL, /* Don't notify about all outbound messages */
1034                             GNUNET_NO,    /* For header-only out notification */
1035                             core_handlers);        /* Register these handlers */
1036
1037   if (core_handle == NULL) {
1038       GNUNET_break(0);
1039   }
1040   
1041   dht_handle = GNUNET_DHT_connect(c, 100); /* FIXME ht len correct size? */
1042   if (dht_handle == NULL) {
1043       GNUNET_break(0);
1044   }
1045 }
1046
1047 /**
1048  * The main function for the mesh service.
1049  *
1050  * @param argc number of arguments from the command line
1051  * @param argv command line arguments
1052  * @return 0 ok, 1 on error
1053  */
1054 int
1055 main (int argc, char *const *argv)
1056 {
1057     int ret;
1058
1059     ret = (GNUNET_OK ==
1060            GNUNET_SERVICE_run (argc,
1061                                argv,
1062                                "mesh",
1063                                GNUNET_SERVICE_OPTION_NONE,
1064                                &run, NULL)) ? 0 : 1;
1065     return ret;
1066     }