Fixed compiling error
[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  * Function called to notify a client about the socket
492  * begin ready to queue more data.  "buf" will be
493  * NULL and "size" zero if the socket was closed for
494  * writing in the meantime.
495  *
496  * @param cls closure
497  * @param size number of bytes available in buf
498  * @param buf where the callee should write the message
499  * @return number of bytes written to buf
500  */
501 size_t feed_data_to_core (void *cls, size_t size, void *buf) {
502     size_t              size_used;
503     struct PeerInfo     *peer_info;
504
505     if(0 == size && NULL == buf) {
506         // FIXME retry? cancel?
507     }
508     size_used = 0;
509     peer_info = (struct PeerInfo *)cls;
510
511     return size_used;
512 }
513
514
515 /**
516  * Core handler for path creation
517  * struct GNUNET_CORE_MessageHandler
518  *
519  * @param cls closure
520  * @param message message
521  * @param peer peer identity this notification is about
522  * @param atsi performance data
523  * @return GNUNET_OK to keep the connection open,
524  *         GNUNET_SYSERR to close it (signal serious error)
525  *
526  */
527 static int
528 handle_mesh_path_create (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     /* Extract path */
535     /* Find origin & self */
536     /* Search for origin in local tunnels */
537     /* Create tunnel / add path */
538     /* Retransmit to next link in chain, if any (core_notify + callback) */
539     return GNUNET_OK;
540 }
541
542 /**
543  * Core handler for mesh network traffic
544  *
545  * @param cls closure
546  * @param message message
547  * @param peer peer identity this notification is about
548  * @param atsi performance data
549  * @return GNUNET_OK to keep the connection open,
550  *         GNUNET_SYSERR to close it (signal serious error)
551  */
552 static int
553 handle_mesh_network_traffic (void *cls,
554                              const struct GNUNET_PeerIdentity *peer,
555                              const struct GNUNET_MessageHeader *message,
556                              const struct GNUNET_TRANSPORT_ATS_Information
557                              *atsi)
558 {
559     if(GNUNET_MESSAGE_TYPE_MESH_DATA_GO == ntohs(message->type)) {
560         /* Retransmit to next in path of tunnel identified by message */
561         return GNUNET_OK;
562     } else { /* GNUNET_MESSAGE_TYPE_MESH_DATA_BACK */
563         /* Retransmit to previous in path of tunnel identified by message */
564         return GNUNET_OK;
565     }
566 }
567
568 /**
569  * Functions to handle messages from core
570  */
571 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
572   {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
573   {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_GO, 0},
574   {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_BACK, 0},
575   {NULL, 0, 0}
576 };
577
578
579
580 /******************************************************************************/
581 /*********************       MESH LOCAL HANDLES      **************************/
582 /******************************************************************************/
583
584 /**
585  * Check if client has registered with the service and has not disconnected
586  * @param client the client to check
587  * @return non-NULL if client exists in the global DLL
588  */
589 struct Client *
590 client_retrieve (struct GNUNET_SERVER_Client *client) {
591     struct Client       *c;
592     c = clients_head; 
593     while(NULL != c) {
594         if(c->handle == client) return c;
595         if(c == clients_tail)
596             return NULL;
597         else
598             c = c->next;
599     }
600     return NULL;
601 }
602
603 /**
604  * Iterator called on each result obtained for a DHT
605  * operation that expects a reply
606  *
607  * @param cls closure
608  * @param exp when will this value expire
609  * @param key key of the result
610  * @param get_path NULL-terminated array of pointers
611  *                 to the peers on reverse GET path (or NULL if not recorded)
612  * @param put_path NULL-terminated array of pointers
613  *                 to the peers on the PUT path (or NULL if not recorded)
614  * @param type type of the result
615  * @param size number of bytes in data
616  * @param data pointer to the result data
617  */
618 void dht_get_response_handler(void *cls,
619                             struct GNUNET_TIME_Absolute exp,
620                             const GNUNET_HashCode * key,
621                             const struct GNUNET_PeerIdentity * const *get_path,
622                             const struct GNUNET_PeerIdentity * const *put_path,
623                             enum GNUNET_BLOCK_Type type,
624                             size_t size,
625                             const void *data)
626 {
627     struct PeerInfo             *peer_info;
628     struct MESH_tunnel          *t;
629     struct Path                 *p;
630     int                         i;
631
632     peer_info = (struct PeerInfo *)cls;
633     t = peer_info->t;
634     p = GNUNET_malloc(sizeof(struct Path));
635     GNUNET_CONTAINER_DLL_insert(t->paths_head, t->paths_tail, p);
636     for(i = 0; get_path[i] != NULL; i++) {
637         p->peers = GNUNET_realloc(p->peers,
638                                    sizeof(GNUNET_PEER_Id) * (p->length + 1));
639         p->peers[p->length] = GNUNET_PEER_intern(get_path[i]);
640         p->length++;
641     }
642     for(i = 0; put_path[i] != NULL; i++) {
643         p->peers = GNUNET_realloc(p->peers,
644                                   sizeof(GNUNET_PEER_Id) * (p->length + 1));
645         p->peers[p->length] = GNUNET_PEER_intern(put_path[i]);
646         p->length++;
647     }
648     // p->id = 0; // FIXME generate ID or remove field
649     p->in_use = 0;
650     // peer_info->first_hop = p->peers[1]; // FIXME do this on path completion
651     GNUNET_CORE_notify_transmit_ready(core_handle,
652                                       0,
653                                       0,
654                                       GNUNET_TIME_relative_get_forever(),
655                                       get_path[1],
656                                       sizeof(struct GNUNET_MESH_ManipulatePath)
657                                         + (p->length
658                                         * sizeof (struct GNUNET_PeerIdentity)),
659                                       feed_data_to_core,
660                                       peer_info
661                                      );
662     return;
663 }
664
665 /**
666  * Handler for client disconnection
667  *
668  * @param cls closure
669  * @param client identification of the client; NULL
670  *        for the last call when the server is destroyed
671  */
672 static void
673 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
674 {
675     struct Client       *c, *next;
676     struct MESH_tunnel  *t;
677
678     c = clients_head;
679     while(NULL != c) {
680         if (c->handle == client) {
681             GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, c);
682             while (NULL != (t = c->tunnels_head)) {
683                 GNUNET_CONTAINER_DLL_remove (c->tunnels_head,
684                                              c->tunnels_tail,
685                                              t);
686                 /* TODO free paths and other tunnel dynamic structures */
687                 GNUNET_free (t);
688             }
689             GNUNET_free (c->messages_subscribed);
690             next = c->next;
691             GNUNET_free (c);
692             c = next;
693         } else {
694             c = c->next;
695         }
696         if(c == clients_head) return; /* Tail already processed? */
697     }
698     return;
699 }
700
701 /**
702  * Handler for new clients
703  * 
704  * @param cls closure
705  * @param client identification of the client
706  * @param message the actual message, which includes messages the client wants
707  */
708 static void
709 handle_local_new_client (void *cls,
710                          struct GNUNET_SERVER_Client *client,
711                          const struct GNUNET_MessageHeader *message)
712 {
713     struct Client               *c;
714     unsigned int                payload_size;
715
716     /* Check data sanity */
717     payload_size = message->size - sizeof(struct GNUNET_MessageHeader);
718     if (0 != payload_size % sizeof(GNUNET_MESH_ApplicationType)) {
719         GNUNET_break(0);
720         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
721         return;
722     }
723
724     /* Create new client structure */
725     c = GNUNET_malloc(sizeof(struct Client));
726     c->handle = client;
727     c->tunnels_head = NULL;
728     c->tunnels_tail = NULL;
729     if(payload_size != 0) {
730         c->messages_subscribed = GNUNET_malloc(payload_size);
731         memcpy(c->messages_subscribed, &message[1], payload_size);
732     } else {
733         c->messages_subscribed = NULL;
734     }
735     c->subscription_counter = payload_size/sizeof(GNUNET_MESH_ApplicationType);
736
737     /* Insert new client in DLL */
738     GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c);
739
740     GNUNET_SERVER_receive_done(client, GNUNET_OK);
741 }
742
743 /**
744  * Handler for requests of new tunnels
745  * 
746  * @param cls closure
747  * @param client identification of the client
748  * @param message the actual message
749  */
750 static void
751 handle_local_tunnel_create (void *cls,
752                             struct GNUNET_SERVER_Client *client,
753                             const struct GNUNET_MessageHeader *message)
754 {
755     struct GNUNET_MESH_TunnelMessage    *tunnel_msg;
756     struct MESH_tunnel                  *t;
757     struct Client                       *c;
758
759     /* Sanity check for client registration */
760     if(NULL == (c = client_retrieve(client))) {
761         GNUNET_break(0);
762         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
763         return;
764     }
765
766     /* Message sanity check */
767     if(sizeof(struct GNUNET_MESH_TunnelMessage) != ntohs(message->size)) {
768         GNUNET_break(0);
769         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
770         return;
771     }
772
773     tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
774     /* Sanity check for tunnel numbering */
775     if(0 == (ntohl(tunnel_msg->tunnel_id) & 0x80000000)) {
776         GNUNET_break(0);
777         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
778         return;
779     }
780     /* Sanity check for duplicate tunnel IDs */
781     t = c->tunnels_head;
782     while(NULL != t) {
783         if(t->tid == ntohl(tunnel_msg->tunnel_id)) {
784             GNUNET_break(0);
785             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
786             return;
787         }
788         if(t == c->tunnels_tail) break;
789         t = t->next;
790     }
791     /* FIXME: calloc? Is NULL != 0 on any platform? */
792     t = GNUNET_malloc(sizeof(struct MESH_tunnel));
793     t->tid = ntohl(tunnel_msg->tunnel_id);
794     t->oid = myid;
795     t->peers_ready = 0;
796     t->peers_total = 0;
797     t->peers_head = NULL;
798     t->peers_tail = NULL;
799     t->paths_head = NULL;
800     t->paths_tail = NULL;
801     t->in_head = NULL;
802     t->in_tail = NULL;
803     t->out_head = NULL;
804     t->out_tail = NULL;
805     t->client = c;
806
807     GNUNET_CONTAINER_DLL_insert(c->tunnels_head, c->tunnels_tail, t);
808
809     GNUNET_SERVER_receive_done(client, GNUNET_OK);
810     return;
811 }
812
813 /**
814  * Handler for requests of deleting tunnels
815  * 
816  * @param cls closure
817  * @param client identification of the client
818  * @param message the actual message
819  */
820 static void
821 handle_local_tunnel_destroy (void *cls,
822                              struct GNUNET_SERVER_Client *client,
823                              const struct GNUNET_MessageHeader *message)
824 {
825     struct GNUNET_MESH_TunnelMessage    *tunnel_msg;
826     struct Client                       *c;
827     struct MESH_tunnel                  *t;
828     MESH_TunnelID                       tid;
829     struct PeerInfo                     *pi;
830
831     /* Sanity check for client registration */
832     if(NULL == (c = client_retrieve(client))) {
833         GNUNET_break(0);
834         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
835         return;
836     }
837     /* Message sanity check */
838     if(sizeof(struct GNUNET_MESH_TunnelMessage) != ntohs(message->size)) {
839         GNUNET_break(0);
840         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
841         return;
842     }
843
844     tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
845
846     /* Tunnel exists? */
847     tid = ntohl(tunnel_msg->tunnel_id);
848     if(NULL == (t = c->tunnels_head)) {
849         GNUNET_break(0);
850         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
851         return;
852     }
853     while(NULL != t) {
854         if(t->tid == tid) {
855             break;
856         }
857         if(t == c->tunnels_tail) {
858             GNUNET_break(0);
859             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
860             return;
861         }
862         t = t->next;
863     }
864
865     GNUNET_CONTAINER_DLL_remove(c->tunnels_head, c->tunnels_tail, t);
866
867     for(pi = t->peers_head; pi != NULL; pi = t->peers_head) {
868         GNUNET_PEER_change_rc(pi->id, -1);
869         GNUNET_CONTAINER_DLL_remove(t->peers_head, t->peers_tail, pi);
870         GNUNET_free(pi);
871     }
872     GNUNET_free(t);
873
874     GNUNET_SERVER_receive_done(client, GNUNET_OK);
875     return;
876 }
877
878 /**
879  * Handler for connection requests to new peers
880  * 
881  * @param cls closure
882  * @param client identification of the client
883  * @param message the actual message (PeerControl)
884  */
885 static void
886 handle_local_connect_add (void *cls,
887                           struct GNUNET_SERVER_Client *client,
888                           const struct GNUNET_MessageHeader *message)
889 {
890     struct GNUNET_MESH_PeerControl      *peer_msg;
891     struct Client                       *c;
892     struct MESH_tunnel                  *t;
893     MESH_TunnelID                       tid;
894     struct PeerInfo                     *peer_info;
895
896     GNUNET_HashCode                     key;
897
898
899     /* Sanity check for client registration */
900     if(NULL == (c = client_retrieve(client))) {
901         GNUNET_break(0);
902         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
903         return;
904     }
905
906     peer_msg = (struct GNUNET_MESH_PeerControl *)message;
907     /* Sanity check for message size */
908     if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(peer_msg->header.size)) {
909         GNUNET_break(0);
910         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
911         return;
912     }
913
914     /* Tunnel exists? */
915     tid = ntohl(peer_msg->tunnel_id);
916     if(NULL == (t = c->tunnels_head)) {
917         GNUNET_break(0);
918         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
919         return;
920     }
921     while(NULL != t) {
922         if(t->tid == tid) {
923             break;
924         }
925         if(t == c->tunnels_tail) {
926             GNUNET_break(0);
927             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
928             return;
929         }
930         t = t->next;
931     }
932
933     /* Does client own tunnel? */
934     if(t->client->handle != client) {
935         GNUNET_break(0);
936         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
937         return;
938     }
939
940     /* Ok, add peer to tunnel */
941     peer_info = (struct PeerInfo *) GNUNET_malloc(sizeof(struct PeerInfo));
942     peer_info->id = GNUNET_PEER_intern(&peer_msg->peer);
943     peer_info->state = MESH_PEER_WAITING;
944     peer_info->t = t;
945     t->peers_total++;
946     GNUNET_CONTAINER_DLL_insert(t->peers_head, t->peers_tail, peer_info);
947     /* start dht search */
948     // FIXME key = hash (peerid + salt);
949     peer_info->dhtget = GNUNET_DHT_get_start(dht_handle,
950                                             GNUNET_TIME_relative_get_forever(),
951                                             GNUNET_BLOCK_TYPE_ANY,
952                                             &key,
953                                             4,    /* replication level */
954                                             GNUNET_DHT_RO_RECORD_ROUTE,
955                                             NULL, /* bloom filter */
956                                             0,    /* mutator */
957                                             NULL, /* xquery */
958                                             0,    /* xquery bits */
959                                             dht_get_response_handler,
960                                             (void *)peer_info);
961
962     GNUNET_SERVER_receive_done(client, GNUNET_OK);
963     return;
964 }
965
966
967 /**
968  * Handler for disconnection requests of peers in a tunnel
969  * 
970  * @param cls closure
971  * @param client identification of the client
972  * @param message the actual message (PeerControl)
973  */
974 static void
975 handle_local_connect_del (void *cls,
976                           struct GNUNET_SERVER_Client *client,
977                           const struct GNUNET_MessageHeader *message)
978 {
979     struct GNUNET_MESH_PeerControl      *peer_msg;
980     struct Client                       *c;
981     struct MESH_tunnel                  *t;
982     struct Path                         *p;
983     struct Path                         *aux_path;
984     MESH_TunnelID                       tid;
985     GNUNET_PEER_Id                      peer_id;
986     struct PeerInfo                     *peer_info;
987     struct PeerInfo                     *aux_peer_info;
988
989     /* Sanity check for client registration */
990     if(NULL == (c = client_retrieve(client))) {
991         GNUNET_break(0);
992         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
993         return;
994     }
995     peer_msg = (struct GNUNET_MESH_PeerControl *)message;
996     /* Sanity check for message size */
997     if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(peer_msg->header.size)) {
998         GNUNET_break(0);
999         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1000         return;
1001     }
1002
1003     /* Tunnel exists? */
1004     tid = ntohl(peer_msg->tunnel_id);
1005     if(NULL == (t = c->tunnels_head)) {
1006         GNUNET_break(0);
1007         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1008         return;
1009     }
1010     while(NULL != t) {
1011         if(t->tid == tid) {
1012             break;
1013         }
1014         if(t == c->tunnels_tail) {
1015             GNUNET_break(0);
1016             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1017             return;
1018         }
1019         t = t->next;
1020     }
1021
1022     /* Does client own tunnel? */
1023     if(t->client->handle != client) {
1024         GNUNET_break(0);
1025         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1026         return;
1027     }
1028
1029     /* Ok, delete peer from tunnel */
1030     peer_id = GNUNET_PEER_intern(&peer_msg->peer);
1031
1032     /* Delete paths */
1033     p = t->paths_head;
1034     while(p != NULL) {
1035         if(p->peers[p->length-1] == peer_id) { /* one path per destination */
1036             GNUNET_CONTAINER_DLL_remove(t->paths_head, t->paths_tail, p);
1037             GNUNET_PEER_decrement_rcs(p->peers, p->length);
1038             aux_path = p;
1039             p = p->next;
1040             GNUNET_free(aux_path);
1041         } else {
1042             p = p->next;
1043         }
1044         if(p == t->paths_head) {
1045             break;
1046         }
1047     }
1048
1049     /*Delete peer info */
1050     peer_info = t->peers_head;
1051     while(peer_info != NULL) {
1052         if(peer_info->id == peer_id) {
1053             GNUNET_CONTAINER_DLL_remove(t->peers_head,
1054                                         t->peers_tail,
1055                                         peer_info);
1056             aux_peer_info = peer_info;
1057             peer_info = peer_info->next;
1058             GNUNET_free(aux_peer_info);
1059         } else {
1060             peer_info = peer_info->next;
1061         }
1062         if(peer_info == t->peers_head) {
1063             break;
1064         }
1065     }
1066
1067     GNUNET_PEER_change_rc(peer_id, -1);
1068
1069     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1070     return;
1071 }
1072
1073
1074 /**
1075  * Handler for connection requests to new peers by type
1076  * 
1077  * @param cls closure
1078  * @param client identification of the client
1079  * @param message the actual message (ConnectPeerByType)
1080  */
1081 static void
1082 handle_local_connect_by_type (void *cls,
1083                               struct GNUNET_SERVER_Client *client,
1084                               const struct GNUNET_MessageHeader *message)
1085 {
1086     struct GNUNET_MESH_ConnectPeerByType        *connect_msg;
1087     MESH_TunnelID                               tid;
1088     GNUNET_MESH_ApplicationType                 application;
1089     struct Client                               *c;
1090     struct MESH_tunnel                          *t;
1091
1092     /* Sanity check for client registration */
1093     if(NULL == (c = client_retrieve(client))) {
1094         GNUNET_break(0);
1095         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1096         return;
1097     }
1098
1099     connect_msg = (struct GNUNET_MESH_ConnectPeerByType *)message;
1100     /* Sanity check for message size */
1101     if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(connect_msg->header.size)) {
1102         GNUNET_break(0);
1103         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1104         return;
1105     }
1106
1107     /* Tunnel exists? */
1108     tid = ntohl(connect_msg->tunnel_id);
1109     if(NULL == (t = c->tunnels_head)) {
1110         GNUNET_break(0);
1111         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1112         return;
1113     }
1114     while(NULL != t) {
1115         if(t->tid == tid) {
1116             break;
1117         }
1118         if(t == c->tunnels_tail) {
1119             GNUNET_break(0);
1120             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1121             return;
1122         }
1123         t = t->next;
1124     }
1125
1126     /* Does client own tunnel? */
1127     if(t->client->handle != client) {
1128         GNUNET_break(0);
1129         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1130         return;
1131     }
1132
1133     /* Ok, lets find a peer offering the service */
1134     application = ntohl(connect_msg->type);
1135     application++; // FIXME silence warnings
1136
1137     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1138     return;
1139 }
1140
1141
1142 /**
1143  * Handler for client traffic directed to one peer
1144  * 
1145  * @param cls closure
1146  * @param client identification of the client
1147  * @param message the actual message
1148  */
1149 static void
1150 handle_local_network_traffic (void *cls,
1151                          struct GNUNET_SERVER_Client *client,
1152                          const struct GNUNET_MessageHeader *message)
1153 {
1154     struct Client                               *c;
1155     struct MESH_tunnel                          *t;
1156     struct GNUNET_MESH_Data                     *data_msg;
1157     MESH_TunnelID                               tid;
1158
1159     /* Sanity check for client registration */
1160     if(NULL == (c = client_retrieve(client))) {
1161         GNUNET_break(0);
1162         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1163         return;
1164     }
1165     data_msg = (struct GNUNET_MESH_Data *)message;
1166     /* Sanity check for message size */
1167     if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(data_msg->header.size)) {
1168         GNUNET_break(0);
1169         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1170         return;
1171     }
1172
1173     /* Tunnel exists? */
1174     tid = ntohl(data_msg->tunnel_id);
1175     if(NULL == (t = c->tunnels_head)) {
1176         GNUNET_break(0);
1177         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1178         return;
1179     }
1180     while(NULL != t) {
1181         if(t->tid == tid) {
1182             break;
1183         }
1184         if(t == c->tunnels_tail) {
1185             GNUNET_break(0);
1186             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1187             return;
1188         }
1189         t = t->next;
1190     }
1191
1192     /* Does client own tunnel? */
1193     if(t->client->handle != client) {
1194         GNUNET_break(0);
1195         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1196         return;
1197     }
1198
1199     /* TODO */
1200
1201     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1202     return;
1203 }
1204
1205 /**
1206  * Handler for client traffic directed to all peers in a tunnel
1207  * 
1208  * @param cls closure
1209  * @param client identification of the client
1210  * @param message the actual message
1211  */
1212 static void
1213 handle_local_network_traffic_bcast (void *cls,
1214                                     struct GNUNET_SERVER_Client *client,
1215                                     const struct GNUNET_MessageHeader *message)
1216 {
1217     struct Client                               *c;
1218     struct MESH_tunnel                          *t;
1219     struct GNUNET_MESH_DataBroadcast            *data_msg;
1220     MESH_TunnelID                               tid;
1221
1222     /* Sanity check for client registration */
1223     if(NULL == (c = client_retrieve(client))) {
1224         GNUNET_break(0);
1225         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1226         return;
1227     }
1228     data_msg = (struct GNUNET_MESH_DataBroadcast *)message;
1229     /* Sanity check for message size */
1230     if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(data_msg->header.size)) {
1231         GNUNET_break(0);
1232         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1233         return;
1234     }
1235
1236     /* Tunnel exists? */
1237     tid = ntohl(data_msg->tunnel_id);
1238     if(NULL == (t = c->tunnels_head)) {
1239         GNUNET_break(0);
1240         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1241         return;
1242     }
1243     while(NULL != t) {
1244         if(t->tid == tid) {
1245             break;
1246         }
1247         if(t == c->tunnels_tail) {
1248             GNUNET_break(0);
1249             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1250             return;
1251         }
1252         t = t->next;
1253     }
1254
1255     /* Does client own tunnel? */
1256     if(t->client->handle != client) {
1257         GNUNET_break(0);
1258         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1259         return;
1260     }
1261
1262     /*  TODO */
1263
1264     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1265     return;
1266 }
1267
1268 /**
1269  * Functions to handle messages from clients
1270  */
1271 static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
1272   {&handle_local_new_client, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
1273   {&handle_local_tunnel_create, NULL,
1274    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE, 0},
1275   {&handle_local_tunnel_destroy, NULL,
1276    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY, 0},
1277   {&handle_local_connect_add, NULL,
1278    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_ADD, 0},
1279   {&handle_local_connect_del, NULL,
1280    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_DEL, 0},
1281   {&handle_local_connect_by_type, NULL,
1282    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_BY_TYPE,
1283    sizeof(struct GNUNET_MESH_ConnectPeerByType)},
1284   {&handle_local_network_traffic, NULL,
1285    GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA, 0},
1286   {&handle_local_network_traffic_bcast, NULL,
1287    GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA_BROADCAST, 0},
1288   {NULL, NULL, 0, 0}
1289 };
1290
1291
1292 /**
1293  * To be called on core init/fail.
1294  *
1295  * @param cls service closure
1296  * @param server handle to the server for this service
1297  * @param identity the public identity of this peer
1298  * @param publicKey the public key of this peer
1299  */
1300 static void
1301 core_init (void *cls,
1302            struct GNUNET_CORE_Handle *server,
1303            const struct GNUNET_PeerIdentity *identity,
1304            const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
1305 {
1306     core_handle = server;
1307     myid = GNUNET_PEER_intern(identity);
1308     return;
1309 }
1310
1311 /**
1312  * Method called whenever a given peer connects.
1313  *
1314  * @param cls closure
1315  * @param peer peer identity this notification is about
1316  * @param atsi performance data for the connection
1317  */
1318 static void
1319 core_connect (void *cls,
1320               const struct GNUNET_PeerIdentity *peer,
1321               const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1322 {
1323     return;
1324 }
1325
1326 /**
1327  * Method called whenever a peer disconnects.
1328  *
1329  * @param cls closure
1330  * @param peer peer identity this notification is about
1331  */
1332 static void
1333 core_disconnect (void *cls,
1334                 const struct
1335                 GNUNET_PeerIdentity *peer)
1336 {
1337     return;
1338 }
1339
1340 /******************************************************************************/
1341 /************************      MAIN FUNCTIONS      ****************************/
1342 /******************************************************************************/
1343
1344 /**
1345  * Process mesh requests.
1346  *
1347  * @param cls closure
1348  * @param server the initialized server
1349  * @param c configuration to use
1350  */
1351 static void
1352 run (void *cls,
1353      struct GNUNET_SERVER_Handle *server,
1354      const struct GNUNET_CONFIGURATION_Handle *c)
1355 {
1356
1357     GNUNET_SERVER_add_handlers (server, plugin_handlers);
1358     GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
1359     core_handle = GNUNET_CORE_connect (c,               /* Main configuration */
1360                             32,                                 /* queue size */
1361                             NULL,         /* Closure passed to MESH functions */
1362                             &core_init,      /* Call core_init once connected */
1363                             &core_connect,                 /* Handle connects */
1364                             &core_disconnect,  /* remove peers on disconnects */
1365                             NULL,       /* Do we care about "status" updates? */
1366                             NULL, /* Don't notify about all incoming messages */
1367                             GNUNET_NO,     /* For header only in notification */
1368                             NULL, /* Don't notify about all outbound messages */
1369                             GNUNET_NO,    /* For header-only out notification */
1370                             core_handlers);        /* Register these handlers */
1371
1372     if (core_handle == NULL) {
1373         GNUNET_break(0);
1374     }
1375
1376     dht_handle = GNUNET_DHT_connect(c, 100); /* FIXME ht len correct size? */
1377     if (dht_handle == NULL) {
1378         GNUNET_break(0);
1379     }
1380 }
1381
1382 /**
1383  * The main function for the mesh service.
1384  *
1385  * @param argc number of arguments from the command line
1386  * @param argv command line arguments
1387  * @return 0 ok, 1 on error
1388  */
1389 int
1390 main (int argc, char *const *argv)
1391 {
1392     int ret;
1393
1394     ret = (GNUNET_OK ==
1395            GNUNET_SERVICE_run (argc,
1396                                argv,
1397                                "mesh",
1398                                GNUNET_SERVICE_OPTION_NONE,
1399                                &run, NULL)) ? 0 : 1;
1400     return ret;
1401     }