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      * Tunnel this peer belongs to
251      */
252     struct MESH_tunnel          *t;
253
254     /**
255      * Is the peer reachable? Is the peer even connected?
256      */
257     enum PeerState              state;
258
259     /**
260      * When to try to establish contact again?
261      */
262     struct GNUNET_TIME_Absolute next_reconnect_attempt;
263
264     /**
265      * Who to send the data to --- FIXME what about multiple (alternate) paths?
266      */
267     GNUNET_PEER_Id              first_hop;
268
269     /**
270      * Max data rate to this peer
271      */
272     uint32_t                    max_speed;
273
274     /**
275      * Handle to stop the DHT search for a path to this peer
276      */
277     struct GNUNET_DHT_GetHandle        *dhtget;
278 };
279
280
281 typedef uint32_t MESH_PathID;
282
283
284 /**
285  * Information regarding a path
286  */
287 struct Path
288 {
289     /**
290      * Double linked list
291      */
292     struct Path                 *next;
293     struct Path                 *prev;
294
295     /**
296      * Id of the path, in case it's needed
297      */
298     MESH_PathID                 id;
299
300     /**
301      * Whether the path is serving traffic in a tunnel or is a backup
302      */
303     int                         in_use;
304
305     /**
306      * List of all the peers that form the path from origin to target
307      */
308     GNUNET_PEER_Id              *peers;
309     int                         length;
310 };
311
312 /**
313  * Data scheduled to transmit (to local client or remote peer)
314  */
315 struct MESH_queue
316 {
317     /**
318      * Double linked list
319      */
320     struct MESH_queue          *next;
321     struct MESH_queue          *prev;
322
323     /**
324      * Size of the message to transmit
325      */
326     unsigned int                size;
327
328     /**
329      * How old is the data?
330      */
331     struct GNUNET_TIME_Absolute timestamp;
332
333     /**
334      * Data itself
335      */
336     struct GNUNET_MessageHeader *data;
337 };
338
339
340 struct Client; /* FWD declaration */
341 /**
342  * Struct containing all information regarding a tunnel
343  * For an intermediate node the improtant info used will be:
344  * - OID        \ To identify
345  * - TID        / the tunnel
346  * - paths[0]   | To know where to send it next
347  * - metainfo: ready, speeds, accounting
348  * For an end node more fields will be needed (client-handling)
349  */
350 struct MESH_tunnel
351 {
352
353     /**
354      * Double linked list
355      */
356     struct MESH_tunnel          *next;
357     struct MESH_tunnel          *prev;
358
359     /**
360      * Origin ID: Node that created the tunnel
361      */
362     GNUNET_PEER_Id              oid;
363
364     /**
365      * Tunnel number (unique for a given oid)
366      */
367     MESH_TunnelID               tid;
368
369     /**
370      * Minimal speed for this tunnel in kb/s
371      */
372     uint32_t                    speed_min;
373
374     /**
375      * Maximal speed for this tunnel in kb/s
376      */
377     uint32_t                    speed_max;
378
379     /**
380      * Last time the tunnel was used
381      */
382     struct GNUNET_TIME_Absolute timestamp;
383
384     /**
385      * Peers in the tunnel, for future optimizations
386      */
387     struct PeerInfo             *peers_head;
388     struct PeerInfo             *peers_tail;
389
390     /**
391      * Number of peers that are connected and potentially ready to receive data
392      */
393     unsigned int                peers_ready;
394
395     /**
396      * Number of peers that have been added to the tunnel
397      */
398     unsigned int                peers_total;
399
400     /**
401      * Paths (used and backup)
402      */
403     struct Path                 *paths_head;
404     struct Path                 *paths_tail;
405
406     /**
407      * If this tunnel was created by a local client, what's its handle?
408      */
409     struct Client               *client;
410
411     /**
412      * Messages ready to transmit
413      */
414     struct MESH_queue           *out_head;
415     struct MESH_queue           *out_tail;
416
417     /**
418      * Messages received and not processed
419      */
420     struct MESH_queue           *in_head;
421     struct MESH_queue           *in_tail;
422
423 };
424
425 /**
426  * Struct containing information about a client of the service
427  */
428 struct Client
429 {
430     /**
431      * Double linked list
432      */
433     struct Client               *next;
434     struct Client               *prev;
435
436     /**
437      * Tunnels that belong to this client, for convenience on disconnect
438      */
439     struct MESH_tunnel          *tunnels_head;
440     struct MESH_tunnel          *tunnels_tail;
441
442     /**
443      * Handle to communicate with the client
444      */
445     struct GNUNET_SERVER_Client *handle;
446
447     /**
448      * Messages that this client has declared interest in
449      */
450     GNUNET_MESH_ApplicationType *messages_subscribed;
451     unsigned int                subscription_counter;
452
453 };
454
455 /******************************************************************************/
456 /***********************      GLOBAL VARIABLES     ****************************/
457 /******************************************************************************/
458
459 /**
460  * All the clients
461  */
462 static struct Client                    *clients_head;
463 static struct Client                    *clients_tail;
464
465 /**
466  * Tunnels not owned by this node
467  */
468 // static struct MESH_Tunnel               *tunnels_head;
469 // static struct MESH_Tunnel               *tunnels_tail;
470
471 /**
472  * Handle to communicate with core
473  */
474 static struct GNUNET_CORE_Handle        *core_handle;
475
476 /**
477  * Handle to use DHT
478  */
479 static struct GNUNET_DHT_Handle         *dht_handle;
480
481 /**
482  * Local peer own ID (memory efficient handle)
483  */
484 static GNUNET_PEER_Id                   myid;
485
486 /******************************************************************************/
487 /********************      MESH NETWORK HANDLERS     **************************/
488 /******************************************************************************/
489
490 /**
491  * Core handler for path creation
492  * struct GNUNET_CORE_MessageHandler
493  *
494  * @param cls closure
495  * @param message message
496  * @param peer peer identity this notification is about
497  * @param atsi performance data
498  * @return GNUNET_OK to keep the connection open,
499  *         GNUNET_SYSERR to close it (signal serious error)
500  *
501  */
502 static int
503 handle_mesh_path_create (void *cls,
504                               const struct GNUNET_PeerIdentity *peer,
505                               const struct GNUNET_MessageHeader *message,
506                               const struct GNUNET_TRANSPORT_ATS_Information
507                               *atsi)
508 {
509     /* Extract path */
510     /* Find origin & self */
511     /* Search for origin in local tunnels */
512     /* Create tunnel / add path */
513     /* Retransmit to next link in chain, if any (core_notify + callback) */
514     return GNUNET_OK;
515 }
516
517 /**
518  * Core handler for mesh network traffic
519  *
520  * @param cls closure
521  * @param message message
522  * @param peer peer identity this notification is about
523  * @param atsi performance data
524  * @return GNUNET_OK to keep the connection open,
525  *         GNUNET_SYSERR to close it (signal serious error)
526  */
527 static int
528 handle_mesh_network_traffic (void *cls,
529                              const struct GNUNET_PeerIdentity *peer,
530                              const struct GNUNET_MessageHeader *message,
531                              const struct GNUNET_TRANSPORT_ATS_Information
532                              *atsi)
533 {
534     if(GNUNET_MESSAGE_TYPE_MESH_DATA_GO == ntohs(message->type)) {
535         /* Retransmit to next in path of tunnel identified by message */
536         return GNUNET_OK;
537     } else { /* GNUNET_MESSAGE_TYPE_MESH_DATA_BACK */
538         /* Retransmit to previous in path of tunnel identified by message */
539         return GNUNET_OK;
540     }
541 }
542
543 /**
544  * Functions to handle messages from core
545  */
546 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
547   {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
548   {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_GO, 0},
549   {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_BACK, 0},
550   {NULL, 0, 0}
551 };
552
553
554
555 /******************************************************************************/
556 /*********************       MESH LOCAL HANDLES      **************************/
557 /******************************************************************************/
558
559 /**
560  * Check if client has registered with the service and has not disconnected
561  * @param client the client to check
562  * @return non-NULL if client exists in the global DLL
563  */
564 struct Client *
565 client_retrieve (struct GNUNET_SERVER_Client *client) {
566     struct Client       *c;
567     c = clients_head; 
568     while(NULL != c) {
569         if(c->handle == client) return c;
570         if(c == clients_tail)
571             return NULL;
572         else
573             c = c->next;
574     }
575     return NULL;
576 }
577
578 /**
579  * Iterator called on each result obtained for a DHT
580  * operation that expects a reply
581  *
582  * @param cls closure
583  * @param exp when will this value expire
584  * @param key key of the result
585  * @param get_path NULL-terminated array of pointers
586  *                 to the peers on reverse GET path (or NULL if not recorded)
587  * @param put_path NULL-terminated array of pointers
588  *                 to the peers on the PUT path (or NULL if not recorded)
589  * @param type type of the result
590  * @param size number of bytes in data
591  * @param data pointer to the result data
592  */
593 void dht_get_response_handler(void *cls,
594                                 struct GNUNET_TIME_Absolute exp,
595                                 const GNUNET_HashCode * key,
596                                 const struct GNUNET_PeerIdentity * const *get_path,
597                                 const struct GNUNET_PeerIdentity * const *put_path,
598                                 enum GNUNET_BLOCK_Type type,
599                                 size_t size,
600                                 const void *data)
601 {
602     struct PeerInfo             *peer_info;
603     struct MESH_tunnel          *t;
604     struct Path                 *p;
605
606     peer_info = (struct PeerInfo *)cls;
607     t = peer_info->t;
608     p = GNUNET_malloc(sizeof(struct Path));
609     GNUNET_CONTAINER_DLL_insert(t->paths_head, t->paths_tail, p);
610     return;
611 }
612
613 /**
614  * Handler for client disconnection
615  *
616  * @param cls closure
617  * @param client identification of the client; NULL
618  *        for the last call when the server is destroyed
619  */
620 static void
621 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
622 {
623     struct Client       *c, *next;
624     struct MESH_tunnel  *t;
625
626     c = clients_head;
627     while(NULL != c) {
628         if (c->handle == client) {
629             GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, c);
630             while (NULL != (t = c->tunnels_head)) {
631                 GNUNET_CONTAINER_DLL_remove (c->tunnels_head, c->tunnels_tail, t);
632                 /* TODO free paths and other tunnel dynamic structures */
633                 GNUNET_free (t);
634             }
635             GNUNET_free (c->messages_subscribed);
636             next = c->next;
637             GNUNET_free (c);
638             c = next;
639         } else {
640             c = c->next;
641         }
642         if(c == clients_head) return; /* Tail already processed? */
643     }
644     return;
645 }
646
647 /**
648  * Handler for new clients
649  * 
650  * @param cls closure
651  * @param client identification of the client
652  * @param message the actual message, which includes messages the client wants
653  */
654 static void
655 handle_local_new_client (void *cls,
656                          struct GNUNET_SERVER_Client *client,
657                          const struct GNUNET_MessageHeader *message)
658 {
659     struct Client               *c;
660     unsigned int                payload_size;
661
662     /* Check data sanity */
663     payload_size = message->size - sizeof(struct GNUNET_MessageHeader);
664     if (0 != payload_size % sizeof(GNUNET_MESH_ApplicationType)) {
665         GNUNET_break(0);
666         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
667         return;
668     }
669
670     /* Create new client structure */
671     c = GNUNET_malloc(sizeof(struct Client));
672     c->handle = client;
673     c->tunnels_head = NULL;
674     c->tunnels_tail = NULL;
675     if(payload_size != 0) {
676         c->messages_subscribed = GNUNET_malloc(payload_size);
677         memcpy(c->messages_subscribed, &message[1], payload_size);
678     } else {
679         c->messages_subscribed = NULL;
680     }
681     c->subscription_counter = payload_size/sizeof(GNUNET_MESH_ApplicationType);
682
683     /* Insert new client in DLL */
684     GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c);
685
686     GNUNET_SERVER_receive_done(client, GNUNET_OK);
687 }
688
689 /**
690  * Handler for requests of new tunnels
691  * 
692  * @param cls closure
693  * @param client identification of the client
694  * @param message the actual message
695  */
696 static void
697 handle_local_tunnel_create (void *cls,
698                             struct GNUNET_SERVER_Client *client,
699                             const struct GNUNET_MessageHeader *message)
700 {
701     struct GNUNET_MESH_TunnelMessage    *tunnel_msg;
702     struct MESH_tunnel                  *t;
703     struct Client                       *c;
704
705     /* Sanity check for client registration */
706     if(NULL == (c = client_retrieve(client))) {
707         GNUNET_break(0);
708         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
709         return;
710     }
711
712     /* Message sanity check */
713     if(sizeof(struct GNUNET_MESH_TunnelMessage) != ntohs(message->size)) {
714         GNUNET_break(0);
715         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
716         return;
717     }
718
719     tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
720     /* Sanity check for tunnel numbering */
721     if(0 == (ntohl(tunnel_msg->tunnel_id) & 0x80000000)) {
722         GNUNET_break(0);
723         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
724         return;
725     }
726     /* Sanity check for duplicate tunnel IDs */
727     t = c->tunnels_head;
728     while(NULL != t) {
729         if(t->tid == ntohl(tunnel_msg->tunnel_id)) {
730             GNUNET_break(0);
731             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
732             return;
733         }
734         if(t == c->tunnels_tail) break;
735         t = t->next;
736     }
737     /* FIXME: calloc? Is NULL != 0 on any platform? */
738     t = GNUNET_malloc(sizeof(struct MESH_tunnel));
739     t->tid = ntohl(tunnel_msg->tunnel_id);
740     t->oid = myid;
741     t->peers_ready = 0;
742     t->peers_total = 0;
743     t->peers_head = NULL;
744     t->peers_tail = NULL;
745     t->paths_head = NULL;
746     t->paths_tail = NULL;
747     t->in_head = NULL;
748     t->in_tail = NULL;
749     t->out_head = NULL;
750     t->out_tail = NULL;
751     t->client = c;
752
753     GNUNET_CONTAINER_DLL_insert(c->tunnels_head, c->tunnels_tail, t);
754
755     GNUNET_SERVER_receive_done(client, GNUNET_OK);
756     return;
757 }
758
759 /**
760  * Handler for requests of deleting tunnels
761  * 
762  * @param cls closure
763  * @param client identification of the client
764  * @param message the actual message
765  */
766 static void
767 handle_local_tunnel_destroy (void *cls,
768                              struct GNUNET_SERVER_Client *client,
769                              const struct GNUNET_MessageHeader *message)
770 {
771     struct GNUNET_MESH_TunnelMessage    *tunnel_msg;
772     struct Client                       *c;
773     struct MESH_tunnel                  *t;
774     MESH_TunnelID                       tid;
775     struct PeerInfo                     *pi;
776
777     /* Sanity check for client registration */
778     if(NULL == (c = client_retrieve(client))) {
779         GNUNET_break(0);
780         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
781         return;
782     }
783     /* Message sanity check */
784     if(sizeof(struct GNUNET_MESH_TunnelMessage) != ntohs(message->size)) {
785         GNUNET_break(0);
786         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
787         return;
788     }
789
790     tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
791
792     /* Tunnel exists? */
793     tid = ntohl(tunnel_msg->tunnel_id);
794     if(NULL == (t = c->tunnels_head)) {
795         GNUNET_break(0);
796         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
797         return;
798     }
799     while(NULL != t) {
800         if(t->tid == tid) {
801             break;
802         }
803         if(t == c->tunnels_tail) {
804             GNUNET_break(0);
805             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
806             return;
807         }
808         t = t->next;
809     }
810
811     GNUNET_CONTAINER_DLL_remove(c->tunnels_head, c->tunnels_tail, t);
812
813     for(pi = t->peers_head; pi != NULL; pi = t->peers_head) {
814         GNUNET_PEER_change_rc(pi->id, -1);
815         GNUNET_CONTAINER_DLL_remove(t->peers_head, t->peers_tail, pi);
816         GNUNET_free(pi);
817     }
818     GNUNET_free(t);
819
820     GNUNET_SERVER_receive_done(client, GNUNET_OK);
821     return;
822 }
823
824 /**
825  * Handler for connection requests to new peers
826  * 
827  * @param cls closure
828  * @param client identification of the client
829  * @param message the actual message (PeerControl)
830  */
831 static void
832 handle_local_connect_add (void *cls,
833                           struct GNUNET_SERVER_Client *client,
834                           const struct GNUNET_MessageHeader *message)
835 {
836     struct GNUNET_MESH_PeerControl      *peer_msg;
837     struct Client                       *c;
838     struct MESH_tunnel                  *t;
839     MESH_TunnelID                       tid;
840     struct PeerInfo                     *peer_info;
841
842     GNUNET_HashCode                     key;
843
844
845     /* Sanity check for client registration */
846     if(NULL == (c = client_retrieve(client))) {
847         GNUNET_break(0);
848         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
849         return;
850     }
851
852     peer_msg = (struct GNUNET_MESH_PeerControl *)message;
853     /* Sanity check for message size */
854     if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(peer_msg->header.size)) {
855         GNUNET_break(0);
856         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
857         return;
858     }
859
860     /* Tunnel exists? */
861     tid = ntohl(peer_msg->tunnel_id);
862     if(NULL == (t = c->tunnels_head)) {
863         GNUNET_break(0);
864         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
865         return;
866     }
867     while(NULL != t) {
868         if(t->tid == tid) {
869             break;
870         }
871         if(t == c->tunnels_tail) {
872             GNUNET_break(0);
873             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
874             return;
875         }
876         t = t->next;
877     }
878
879     /* Does client own tunnel? */
880     if(t->client->handle != client) {
881         GNUNET_break(0);
882         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
883         return;
884     }
885
886     /* Ok, add peer to tunnel */
887     peer_info = (struct PeerInfo *) GNUNET_malloc(sizeof(struct PeerInfo));
888     peer_info->id = GNUNET_PEER_intern(&peer_msg->peer);
889     peer_info->state = MESH_PEER_WAITING;
890     peer_info->t = t;
891     t->peers_total++;
892     GNUNET_CONTAINER_DLL_insert(t->peers_head, t->peers_tail, peer_info);
893     /* start dht search */
894     // FIXME key = hash (peerid + salt);
895     peer_info->dhtget = GNUNET_DHT_get_start(dht_handle,
896                                             GNUNET_TIME_relative_get_forever(),
897                                             GNUNET_BLOCK_TYPE_ANY,
898                                             &key,
899                                             4,    /* replication level */
900                                             GNUNET_DHT_RO_RECORD_ROUTE,
901                                             NULL, /* bloom filter */
902                                             0,    /* mutator */
903                                             NULL, /* xquery */
904                                             0,    /* xquery bits */
905                                             dht_get_response_handler,
906                                             (void *)peer_info);
907
908     GNUNET_SERVER_receive_done(client, GNUNET_OK);
909     return;
910 }
911
912
913 /**
914  * Handler for disconnection requests of peers in a tunnel
915  * 
916  * @param cls closure
917  * @param client identification of the client
918  * @param message the actual message (PeerControl)
919  */
920 static void
921 handle_local_connect_del (void *cls,
922                           struct GNUNET_SERVER_Client *client,
923                           const struct GNUNET_MessageHeader *message)
924 {
925     struct GNUNET_MESH_PeerControl      *peer_msg;
926     struct Client                       *c;
927     struct MESH_tunnel                  *t;
928     struct Path                         *p;
929     struct Path                         *aux_path;
930     MESH_TunnelID                       tid;
931     GNUNET_PEER_Id                      peer_id;
932     struct PeerInfo                     *peer_info;
933     struct PeerInfo                     *aux_peer_info;
934
935     /* Sanity check for client registration */
936     if(NULL == (c = client_retrieve(client))) {
937         GNUNET_break(0);
938         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
939         return;
940     }
941     peer_msg = (struct GNUNET_MESH_PeerControl *)message;
942     /* Sanity check for message size */
943     if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(peer_msg->header.size)) {
944         GNUNET_break(0);
945         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
946         return;
947     }
948
949     /* Tunnel exists? */
950     tid = ntohl(peer_msg->tunnel_id);
951     if(NULL == (t = c->tunnels_head)) {
952         GNUNET_break(0);
953         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
954         return;
955     }
956     while(NULL != t) {
957         if(t->tid == tid) {
958             break;
959         }
960         if(t == c->tunnels_tail) {
961             GNUNET_break(0);
962             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
963             return;
964         }
965         t = t->next;
966     }
967
968     /* Does client own tunnel? */
969     if(t->client->handle != client) {
970         GNUNET_break(0);
971         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
972         return;
973     }
974
975     /* Ok, delete peer from tunnel */
976     peer_id = GNUNET_PEER_intern(&peer_msg->peer);
977
978     /* Delete paths */
979     p = t->paths_head;
980     while(p != NULL) {
981         if(p->peers[p->length-1] == peer_id) { /* one path per destination */
982             GNUNET_CONTAINER_DLL_remove(t->paths_head, t->paths_tail, p);
983             GNUNET_PEER_decrement_rcs(p->peers, p->length);
984             aux_path = p;
985             p = p->next;
986             GNUNET_free(aux_path);
987         } else {
988             p = p->next;
989         }
990         if(p == t->paths_head) {
991             break;
992         }
993     }
994
995     /*Delete peer info */
996     peer_info = t->peers_head;
997     while(peer_info != NULL) {
998         if(peer_info->id == peer_id) {
999             GNUNET_CONTAINER_DLL_remove(t->peers_head,
1000                                         t->peers_tail,
1001                                         peer_info);
1002             aux_peer_info = peer_info;
1003             peer_info = peer_info->next;
1004             GNUNET_free(aux_peer_info);
1005         } else {
1006             peer_info = peer_info->next;
1007         }
1008         if(peer_info == t->peers_head) {
1009             break;
1010         }
1011     }
1012
1013     GNUNET_PEER_change_rc(peer_id, -1);
1014
1015     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1016     return;
1017 }
1018
1019
1020 /**
1021  * Handler for connection requests to new peers by type
1022  * 
1023  * @param cls closure
1024  * @param client identification of the client
1025  * @param message the actual message (ConnectPeerByType)
1026  */
1027 static void
1028 handle_local_connect_by_type (void *cls,
1029                               struct GNUNET_SERVER_Client *client,
1030                               const struct GNUNET_MessageHeader *message)
1031 {
1032     struct GNUNET_MESH_ConnectPeerByType        *connect_msg;
1033     MESH_TunnelID                               tid;
1034     GNUNET_MESH_ApplicationType                 application;
1035     struct Client                               *c;
1036     struct MESH_tunnel                          *t;
1037
1038     /* Sanity check for client registration */
1039     if(NULL == (c = client_retrieve(client))) {
1040         GNUNET_break(0);
1041         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1042         return;
1043     }
1044
1045     connect_msg = (struct GNUNET_MESH_ConnectPeerByType *)message;
1046     /* Sanity check for message size */
1047     if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(connect_msg->header.size)) {
1048         GNUNET_break(0);
1049         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1050         return;
1051     }
1052
1053     /* Tunnel exists? */
1054     tid = ntohl(connect_msg->tunnel_id);
1055     if(NULL == (t = c->tunnels_head)) {
1056         GNUNET_break(0);
1057         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1058         return;
1059     }
1060     while(NULL != t) {
1061         if(t->tid == tid) {
1062             break;
1063         }
1064         if(t == c->tunnels_tail) {
1065             GNUNET_break(0);
1066             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1067             return;
1068         }
1069         t = t->next;
1070     }
1071
1072     /* Does client own tunnel? */
1073     if(t->client->handle != client) {
1074         GNUNET_break(0);
1075         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1076         return;
1077     }
1078
1079     /* Ok, lets find a peer offering the service */
1080     application = ntohl(connect_msg->type);
1081     application++; // FIXME silence warnings
1082
1083     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1084     return;
1085 }
1086
1087
1088 /**
1089  * Handler for client traffic directed to one peer
1090  * 
1091  * @param cls closure
1092  * @param client identification of the client
1093  * @param message the actual message
1094  */
1095 static void
1096 handle_local_network_traffic (void *cls,
1097                          struct GNUNET_SERVER_Client *client,
1098                          const struct GNUNET_MessageHeader *message)
1099 {
1100     struct Client                               *c;
1101     struct MESH_tunnel                          *t;
1102     struct GNUNET_MESH_Data                     *data_msg;
1103     MESH_TunnelID                               tid;
1104
1105     /* Sanity check for client registration */
1106     if(NULL == (c = client_retrieve(client))) {
1107         GNUNET_break(0);
1108         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1109         return;
1110     }
1111     data_msg = (struct GNUNET_MESH_Data *)message;
1112     /* Sanity check for message size */
1113     if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(data_msg->header.size)) {
1114         GNUNET_break(0);
1115         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1116         return;
1117     }
1118
1119     /* Tunnel exists? */
1120     tid = ntohl(data_msg->tunnel_id);
1121     if(NULL == (t = c->tunnels_head)) {
1122         GNUNET_break(0);
1123         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1124         return;
1125     }
1126     while(NULL != t) {
1127         if(t->tid == tid) {
1128             break;
1129         }
1130         if(t == c->tunnels_tail) {
1131             GNUNET_break(0);
1132             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1133             return;
1134         }
1135         t = t->next;
1136     }
1137
1138     /* Does client own tunnel? */
1139     if(t->client->handle != client) {
1140         GNUNET_break(0);
1141         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1142         return;
1143     }
1144
1145     /* TODO */
1146
1147     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1148     return;
1149 }
1150
1151 /**
1152  * Handler for client traffic directed to all peers in a tunnel
1153  * 
1154  * @param cls closure
1155  * @param client identification of the client
1156  * @param message the actual message
1157  */
1158 static void
1159 handle_local_network_traffic_bcast (void *cls,
1160                                     struct GNUNET_SERVER_Client *client,
1161                                     const struct GNUNET_MessageHeader *message)
1162 {
1163     struct Client                               *c;
1164     struct MESH_tunnel                          *t;
1165     struct GNUNET_MESH_DataBroadcast            *data_msg;
1166     MESH_TunnelID                               tid;
1167
1168     /* Sanity check for client registration */
1169     if(NULL == (c = client_retrieve(client))) {
1170         GNUNET_break(0);
1171         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1172         return;
1173     }
1174     data_msg = (struct GNUNET_MESH_DataBroadcast *)message;
1175     /* Sanity check for message size */
1176     if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(data_msg->header.size)) {
1177         GNUNET_break(0);
1178         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1179         return;
1180     }
1181
1182     /* Tunnel exists? */
1183     tid = ntohl(data_msg->tunnel_id);
1184     if(NULL == (t = c->tunnels_head)) {
1185         GNUNET_break(0);
1186         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1187         return;
1188     }
1189     while(NULL != t) {
1190         if(t->tid == tid) {
1191             break;
1192         }
1193         if(t == c->tunnels_tail) {
1194             GNUNET_break(0);
1195             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1196             return;
1197         }
1198         t = t->next;
1199     }
1200
1201     /* Does client own tunnel? */
1202     if(t->client->handle != client) {
1203         GNUNET_break(0);
1204         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1205         return;
1206     }
1207
1208     /*  TODO */
1209
1210     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1211     return;
1212 }
1213
1214 /**
1215  * Functions to handle messages from clients
1216  */
1217 static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
1218   {&handle_local_new_client, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
1219   {&handle_local_tunnel_create, NULL,
1220    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE, 0},
1221   {&handle_local_tunnel_destroy, NULL,
1222    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY, 0},
1223   {&handle_local_connect_add, NULL,
1224    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_ADD, 0},
1225   {&handle_local_connect_del, NULL,
1226    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_DEL, 0},
1227   {&handle_local_connect_by_type, NULL,
1228    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_BY_TYPE,
1229    sizeof(struct GNUNET_MESH_ConnectPeerByType)},
1230   {&handle_local_network_traffic, NULL,
1231    GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA, 0},
1232   {&handle_local_network_traffic_bcast, NULL,
1233    GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA_BROADCAST, 0},
1234   {NULL, NULL, 0, 0}
1235 };
1236
1237
1238 /**
1239  * To be called on core init/fail.
1240  *
1241  * @param cls service closure
1242  * @param server handle to the server for this service
1243  * @param identity the public identity of this peer
1244  * @param publicKey the public key of this peer
1245  */
1246 static void
1247 core_init (void *cls,
1248            struct GNUNET_CORE_Handle *server,
1249            const struct GNUNET_PeerIdentity *identity,
1250            const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
1251 {
1252     core_handle = server;
1253     myid = GNUNET_PEER_intern(identity);
1254     return;
1255 }
1256
1257 /**
1258  * Method called whenever a given peer connects.
1259  *
1260  * @param cls closure
1261  * @param peer peer identity this notification is about
1262  * @param atsi performance data for the connection
1263  */
1264 static void
1265 core_connect (void *cls,
1266               const struct GNUNET_PeerIdentity *peer,
1267               const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1268 {
1269     return;
1270 }
1271
1272 /**
1273  * Method called whenever a peer disconnects.
1274  *
1275  * @param cls closure
1276  * @param peer peer identity this notification is about
1277  */
1278 static void
1279 core_disconnect (void *cls,
1280                 const struct
1281                 GNUNET_PeerIdentity *peer)
1282 {
1283     return;
1284 }
1285
1286 /******************************************************************************/
1287 /************************      MAIN FUNCTIONS      ****************************/
1288 /******************************************************************************/
1289
1290 /**
1291  * Process mesh requests. FIXME NON FUNCTIONAL, SKELETON
1292  *
1293  * @param cls closure
1294  * @param server the initialized server
1295  * @param c configuration to use
1296  */
1297 static void
1298 run (void *cls,
1299      struct GNUNET_SERVER_Handle *server,
1300      const struct GNUNET_CONFIGURATION_Handle *c)
1301 {
1302
1303     GNUNET_SERVER_add_handlers (server, plugin_handlers);
1304     GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
1305     core_handle = GNUNET_CORE_connect (c,               /* Main configuration */
1306                             32,                                 /* queue size */
1307                             NULL,         /* Closure passed to MESH functions */
1308                             &core_init,      /* Call core_init once connected */
1309                             &core_connect,                 /* Handle connects */
1310                             &core_disconnect,  /* remove peers on disconnects */
1311                             NULL,       /* Do we care about "status" updates? */
1312                             NULL, /* Don't notify about all incoming messages */
1313                             GNUNET_NO,     /* For header only in notification */
1314                             NULL, /* Don't notify about all outbound messages */
1315                             GNUNET_NO,    /* For header-only out notification */
1316                             core_handlers);        /* Register these handlers */
1317
1318     if (core_handle == NULL) {
1319         GNUNET_break(0);
1320     }
1321
1322     dht_handle = GNUNET_DHT_connect(c, 100); /* FIXME ht len correct size? */
1323     if (dht_handle == NULL) {
1324         GNUNET_break(0);
1325     }
1326 }
1327
1328 /**
1329  * The main function for the mesh service.
1330  *
1331  * @param argc number of arguments from the command line
1332  * @param argv command line arguments
1333  * @return 0 ok, 1 on error
1334  */
1335 int
1336 main (int argc, char *const *argv)
1337 {
1338     int ret;
1339
1340     ret = (GNUNET_OK ==
1341            GNUNET_SERVICE_run (argc,
1342                                argv,
1343                                "mesh",
1344                                GNUNET_SERVICE_OPTION_NONE,
1345                                &run, NULL)) ? 0 : 1;
1346     return ret;
1347     }