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