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